}
#endif
#ifdef MESA_LLVM
- vs->llvm_prog = gallivm_from_tgsi(shader->tokens);
+ vs->llvm_prog = gallivm_from_tgsi(shader->tokens, GALLIVM_VS);
draw->engine = gallivm_global_cpu_engine();
if (!draw->engine) {
draw->engine = gallivm_cpu_engine_create(vs->llvm_prog);
void *function;
int num_consts;
int id;
+ enum gallivm_shader_type type;
};
struct gallivm_cpu_engine {
with gallivm_prog_exec to run the module on the CPU.
*/
struct gallivm_prog *
-gallivm_from_tgsi(const struct tgsi_token *tokens)
+gallivm_from_tgsi(const struct tgsi_token *tokens, enum gallivm_shader_type type)
{
std::cout << "Creating llvm from: " <<std::endl;
++GLOBAL_ID;
passes.run(*mod);
gallivm->module = mod;
+ gallivm->type = type;
gallivm_prog_dump(gallivm, 0);
return gallivm;
}
+
void gallivm_prog_delete(struct gallivm_prog *prog)
{
llvm::Module *mod = static_cast<llvm::Module*>(prog->module);
return 0;
}
+
+typedef int (*fragment_shader_runner)(float x, float y,
+ float (*dests)[32][4],
+ struct tgsi_interp_coef *coef,
+ float (*consts)[4], int num_consts,
+ struct tgsi_sampler *samplers,
+ int num_samplers);
+int gallivm_fragment_shader_exec(struct gallivm_prog *prog,
+ float x, float y,
+ float (*dests)[32][4],
+ struct tgsi_interp_coef *coef,
+ float (*consts)[4],
+ struct tgsi_sampler *samplers,
+ int num_samplers)
+{
+ fragment_shader_runner runner = reinterpret_cast<fragment_shader_runner>(prog->function);
+ assert(runner);
+ runner(x, y, dests, coef, consts, prog->num_consts, samplers, num_samplers);
+
+ return 0;
+}
+
void gallivm_prog_dump(struct gallivm_prog *prog, const char *file_prefix)
{
llvm::Module *mod;
static struct gallivm_cpu_engine *CPU = 0;
+
+static inline llvm::Function *func_for_shader(struct gallivm_prog *prog)
+{
+ llvm::Module *mod = prog->module;
+ llvm::Function *func = 0;
+
+ switch (prog->type) {
+ case GALLIVM_VS:
+ func = mod->getFunction("run_vertex_shader");
+ break;
+ case GALLIVM_FS:
+ func = mod->getFunction("run_fragment_shader");
+ break;
+ default:
+ assert(!"Unknown shader type!");
+ break;
+ }
+ return func;
+}
+
/*!
This function creates a CPU based execution engine for the given gallivm_prog.
gallivm_cpu_engine should be used as a singleton throughout the library. Before
llvm::ExecutionEngine *ee = llvm::ExecutionEngine::create(mp, false);
cpu->engine = ee;
- llvm::Function *func = mod->getFunction("run_vertex_shader");
+ llvm::Function *func = func_for_shader(prog);
+
prog->function = ee->getPointerToFunctionOrStub(func);
CPU = cpu;
return cpu;
assert(ee);
ee->addModuleProvider(mp);
- llvm::Function *func = mod->getFunction("run_vertex_shader");
+ llvm::Function *func = func_for_shader(prog);
prog->function = ee->getPointerToFunctionOrStub(func);
}
+
struct gallivm_prog;
struct gallivm_cpu_engine;
-struct gallivm_prog *gallivm_from_tgsi(const struct tgsi_token *tokens);
+enum gallivm_shader_type {
+ GALLIVM_VS,
+ GALLIVM_FS
+};
+
+struct gallivm_prog *gallivm_from_tgsi(const struct tgsi_token *tokens, enum gallivm_shader_type type);
void gallivm_prog_delete(struct gallivm_prog *prog);
int gallivm_prog_exec(struct gallivm_prog *prog,
float (*inputs)[PIPE_MAX_SHADER_INPUTS][4],
int num_vertices,
int num_inputs,
int num_attribs);
+int gallivm_fragment_shader_exec(struct gallivm_prog *prog,
+ float x, float y,
+ float (*dests)[4],
+ struct tgsi_interp_coef *coef,
+ float (*consts)[4],
+ struct tgsi_sampler *samplers,
+ int num_samplers);
void gallivm_prog_dump(struct gallivm_prog *prog, const char *file_prefix);
to_array(dests[i], res, num_attribs);
}
}
+
+
+struct pipe_sampler_state;
+struct pipe_mipmap_tree;
+struct softpipe_tile_cache;
+
+#define NUM_CHANNELS 4 /* R,G,B,A */
+#define QUAD_SIZE 4 /* 4 pixel/quad */
+
+struct tgsi_sampler
+{
+ const struct pipe_sampler_state *state;
+ struct pipe_mipmap_tree *texture;
+ /** Get samples for four fragments in a quad */
+ void (*get_samples)(struct tgsi_sampler *sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE]);
+ void *pipe; /*XXX temporary*/
+ struct softpipe_tile_cache *cache;
+};
+
+struct tgsi_interp_coef
+{
+ float a0[NUM_CHANNELS]; /* in an xyzw layout */
+ float dadx[NUM_CHANNELS];
+ float dady[NUM_CHANNELS];
+};
+
+int run_fragment_shader(float x, float y,
+ float (*dests)[32][4],
+ struct tgsi_interp_coef *coef,
+ float (*consts)[4],
+ int num_consts,
+ struct tgsi_sampler *samplers,
+ int num_samplers)
+{
+ float4 inputs[4][16];
+ float4 consts[32];
+ float4 results[4][16];
+ float4 temps[128];//MAX_PROGRAM_TEMPS
+
+ /*printf("XXX LLVM run_vertex_shader vertices = %d, inputs = %d, attribs = %d, consts = %d\n",
+ num_vertices, num_inputs, num_attribs, num_consts);*/
+ //from_array(inputs, ainputs, num_vertices, num_inputs);
+ from_consts(consts, aconsts, num_consts);
+ printf("AAAAAAAAAAAAAAAAAAAAAAA FRAGMENT SHADER %f %f\n", x, y);
+ for (int i = 0; i < 4; ++i) {
+ float4 *in = inputs[i];
+ float4 *res = results[i];
+ //execute_shader(res, in, consts, temps);
+ to_array(dests[i], res, num_attribs);
+ }
+}
+
machine->SamplerUnits = softpipe->sampler_units;
machine->InterpCoefs = quad->coef;
+ printf("COEF = [%f %f %f %f], [%f %f %f %f], [%f %f %f %f] %p\n",
+ quad->coef->a0[0], quad->coef->a0[1], quad->coef->a0[2], quad->coef->a0[3],
+ quad->coef->dadx[0], quad->coef->dadx[1], quad->coef->dadx[2], quad->coef->dadx[3],
+ quad->coef->dady[0], quad->coef->dady[1], quad->coef->dady[2], quad->coef->dady[3],
+ quad->coef);
machine->Inputs[0].xyzw[0].f[0] = fx;
machine->Inputs[0].xyzw[0].f[1] = fx + 1.0f;
struct softpipe_context *softpipe = qs->softpipe;
const float fx = (float) quad->x0;
const float fy = (float) quad->y0;
+ struct gallivm_prog *llvm = qss->llvm_prog;
- /* Consts does not require 16 byte alignment. */
- machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT];
-
- machine->SamplerUnits = softpipe->sampler_units;
- machine->InterpCoefs = quad->coef;
-
- machine->Inputs[0].xyzw[0].f[0] = fx;
- machine->Inputs[0].xyzw[0].f[1] = fx + 1.0f;
- machine->Inputs[0].xyzw[0].f[2] = fx;
- machine->Inputs[0].xyzw[0].f[3] = fx + 1.0f;
-
- machine->Inputs[0].xyzw[1].f[0] = fy;
- machine->Inputs[0].xyzw[1].f[1] = fy;
- machine->Inputs[0].xyzw[1].f[2] = fy + 1.0f;
- machine->Inputs[0].xyzw[1].f[3] = fy + 1.0f;
- /* run shader */
-#if defined(__i386__) || defined(__386__)
- machine->Inputs,
- machine->Outputs,
- machine->Consts,
- machine->Temps,
- machine->InterpCoefs );
- quad->mask &= ~(machine->Temps[TGSI_EXEC_TEMP_KILMASK_I].xyzw[TGSI_EXEC_TEMP_KILMASK_C].u[0]);
-#endif
- ga_llvm_prog_exec(softpipe->fs->llvm_prog);
+ quad->mask = gallivm_fragment_shader_exec(
+ llvm, fx, fy, quad->coef,
+ softpipe->mapped_constants[PIPE_SHADER_FRAGMENT],
+ qss->samplers, softpipe->sampler_units);
/* store result color */
if (qss->colorOutSlot >= 0) {
#ifdef MESA_LLVM
fprintf(stderr, "+++++++++++++++++++++++++++++++++++++++++++++++++\n");
- state->llvm_prog = gallivm_from_tgsi(state->shader.tokens);
+ state->llvm_prog = gallivm_from_tgsi(state->shader.tokens, GALLIVM_FS);
if (!gallivm_global_cpu_engine()) {
gallivm_cpu_engine_create(state->llvm_prog);
}