00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifdef MESA_LLVM
00033
00034 #include "gallivm.h"
00035 #include "gallivm_p.h"
00036
00037 #include "instructions.h"
00038 #include "loweringpass.h"
00039 #include "storage.h"
00040 #include "tgsitollvm.h"
00041
00042 #include "pipe/p_context.h"
00043 #include "pipe/p_shader_tokens.h"
00044
00045 #include "tgsi/tgsi_exec.h"
00046 #include "tgsi/tgsi_dump.h"
00047
00048 #include "util/u_memory.h"
00049 #include "util/u_math.h"
00050
00051 #include <llvm/Module.h>
00052 #include <llvm/CallingConv.h>
00053 #include <llvm/Constants.h>
00054 #include <llvm/DerivedTypes.h>
00055 #include <llvm/Instructions.h>
00056 #include <llvm/ModuleProvider.h>
00057 #include <llvm/Pass.h>
00058 #include <llvm/PassManager.h>
00059 #include <llvm/ParameterAttributes.h>
00060 #include <llvm/Support/PatternMatch.h>
00061 #include <llvm/ExecutionEngine/JIT.h>
00062 #include <llvm/ExecutionEngine/Interpreter.h>
00063 #include <llvm/ExecutionEngine/GenericValue.h>
00064 #include <llvm/Support/MemoryBuffer.h>
00065 #include <llvm/LinkAllPasses.h>
00066 #include <llvm/Analysis/Verifier.h>
00067 #include <llvm/Analysis/LoopPass.h>
00068 #include <llvm/Target/TargetData.h>
00069 #include <llvm/Bitcode/ReaderWriter.h>
00070 #include <llvm/Transforms/Utils/Cloning.h>
00071
00072 #include <sstream>
00073 #include <fstream>
00074 #include <iostream>
00075
00076 struct gallivm_cpu_engine {
00077 llvm::ExecutionEngine *engine;
00078 };
00079
00080 static struct gallivm_cpu_engine *CPU = 0;
00081
00082 typedef int (*fragment_shader_runner)(float x, float y,
00083 float (*dests)[16][4],
00084 float (*inputs)[16][4],
00085 int num_attribs,
00086 float (*consts)[4], int num_consts,
00087 struct tgsi_sampler *samplers);
00088
00089 int gallivm_cpu_fs_exec(struct gallivm_prog *prog,
00090 float fx, float fy,
00091 float (*dests)[16][4],
00092 float (*inputs)[16][4],
00093 float (*consts)[4],
00094 struct tgsi_sampler *samplers)
00095 {
00096 fragment_shader_runner runner = reinterpret_cast<fragment_shader_runner>(prog->function);
00097 assert(runner);
00098
00099 return runner(fx, fy, dests, inputs, prog->num_interp,
00100 consts, prog->num_consts,
00101 samplers);
00102 }
00103
00104 static inline llvm::Function *func_for_shader(struct gallivm_prog *prog)
00105 {
00106 llvm::Module *mod = prog->module;
00107 llvm::Function *func = 0;
00108
00109 switch (prog->type) {
00110 case GALLIVM_VS:
00111 func = mod->getFunction("vs_shader");
00112 break;
00113 case GALLIVM_FS:
00114 func = mod->getFunction("fs_shader");
00115 break;
00116 default:
00117 assert(!"Unknown shader type!");
00118 break;
00119 }
00120 return func;
00121 }
00122
00131 struct gallivm_cpu_engine * gallivm_cpu_engine_create(struct gallivm_prog *prog)
00132 {
00133 struct gallivm_cpu_engine *cpu = (struct gallivm_cpu_engine *)
00134 calloc(1, sizeof(struct gallivm_cpu_engine));
00135 llvm::Module *mod = static_cast<llvm::Module*>(prog->module);
00136 llvm::ExistingModuleProvider *mp = new llvm::ExistingModuleProvider(mod);
00137 llvm::ExecutionEngine *ee = llvm::ExecutionEngine::create(mp, false);
00138 ee->DisableLazyCompilation();
00139 cpu->engine = ee;
00140
00141 llvm::Function *func = func_for_shader(prog);
00142
00143 prog->function = ee->getPointerToFunction(func);
00144 CPU = cpu;
00145 return cpu;
00146 }
00147
00148
00155 void gallivm_cpu_jit_compile(struct gallivm_cpu_engine *cpu, struct gallivm_prog *prog)
00156 {
00157 llvm::Module *mod = static_cast<llvm::Module*>(prog->module);
00158 llvm::ExistingModuleProvider *mp = new llvm::ExistingModuleProvider(mod);
00159 llvm::ExecutionEngine *ee = cpu->engine;
00160 assert(ee);
00161
00162 ee->DisableLazyCompilation();
00163 ee->addModuleProvider(mp);
00164
00165 llvm::Function *func = func_for_shader(prog);
00166 prog->function = ee->getPointerToFunction(func);
00167 }
00168
00169 void gallivm_cpu_engine_delete(struct gallivm_cpu_engine *cpu)
00170 {
00171 free(cpu);
00172 }
00173
00174 struct gallivm_cpu_engine * gallivm_global_cpu_engine()
00175 {
00176 return CPU;
00177 }
00178
00179
00180 typedef void (*vertex_shader_runner)(void *ainputs,
00181 void *dests,
00182 float (*aconsts)[4],
00183 void *temps);
00184
00185 #define MAX_TGSI_VERTICES 4
00186
00191 int gallivm_cpu_vs_exec(struct gallivm_prog *prog,
00192 struct tgsi_exec_machine *machine,
00193 const float (*input)[4],
00194 unsigned num_inputs,
00195 float (*output)[4],
00196 unsigned num_outputs,
00197 const float (*constants)[4],
00198 unsigned count,
00199 unsigned input_stride,
00200 unsigned output_stride )
00201 {
00202 unsigned int i, j;
00203 unsigned slot;
00204 vertex_shader_runner runner = reinterpret_cast<vertex_shader_runner>(prog->function);
00205
00206 assert(runner);
00207
00208 for (i = 0; i < count; i += MAX_TGSI_VERTICES) {
00209 unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i);
00210
00211
00212
00213 for (j = 0; j < max_vertices; j++) {
00214 for (slot = 0; slot < num_inputs; slot++) {
00215 machine->Inputs[slot].xyzw[0].f[j] = input[slot][0];
00216 machine->Inputs[slot].xyzw[1].f[j] = input[slot][1];
00217 machine->Inputs[slot].xyzw[2].f[j] = input[slot][2];
00218 machine->Inputs[slot].xyzw[3].f[j] = input[slot][3];
00219 }
00220
00221 input = (const float (*)[4])((const char *)input + input_stride);
00222 }
00223
00224
00225 runner(machine->Inputs,
00226 machine->Outputs,
00227 (float (*)[4]) constants,
00228 machine->Temps);
00229
00230
00231
00232 for (j = 0; j < max_vertices; j++) {
00233 for (slot = 0; slot < num_outputs; slot++) {
00234 output[slot][0] = machine->Outputs[slot].xyzw[0].f[j];
00235 output[slot][1] = machine->Outputs[slot].xyzw[1].f[j];
00236 output[slot][2] = machine->Outputs[slot].xyzw[2].f[j];
00237 output[slot][3] = machine->Outputs[slot].xyzw[3].f[j];
00238 }
00239 output = (float (*)[4])((char *)output + output_stride);
00240 }
00241 }
00242
00243 return 0;
00244 }
00245
00246 #endif