Add basic entry points for fragment shaders.
authorZack Rusin <zack@tungstengraphics.com>
Wed, 31 Oct 2007 16:23:45 +0000 (12:23 -0400)
committerZack Rusin <zack@tungstengraphics.com>
Fri, 2 Nov 2007 11:15:17 +0000 (07:15 -0400)
src/mesa/pipe/draw/draw_vertex_shader.c
src/mesa/pipe/llvm/gallivm.cpp
src/mesa/pipe/llvm/gallivm.h
src/mesa/pipe/llvm/llvm_entry.c
src/mesa/pipe/softpipe/sp_quad_fs.c
src/mesa/pipe/softpipe/sp_state_fs.c

index 7768a62..529ed28 100644 (file)
@@ -239,7 +239,7 @@ draw_create_vertex_shader(struct draw_context *draw,
    }
 #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);
index b09a2ff..48c7bab 100644 (file)
@@ -73,6 +73,7 @@ struct gallivm_prog {
    void *function;
    int   num_consts;
    int   id;
+   enum gallivm_shader_type type;
 };
 
 struct gallivm_cpu_engine {
@@ -722,7 +723,7 @@ tgsi_to_llvm(struct gallivm_prog *prog, const struct tgsi_token *tokens)
   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;
@@ -742,12 +743,14 @@ gallivm_from_tgsi(const struct tgsi_token *tokens)
    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);
@@ -787,6 +790,28 @@ int gallivm_prog_exec(struct gallivm_prog *prog,
    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;
@@ -829,6 +854,26 @@ void gallivm_prog_dump(struct gallivm_prog *prog, const char *file_prefix)
 
 
 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
@@ -846,7 +891,8 @@ struct gallivm_cpu_engine * gallivm_cpu_engine_create(struct gallivm_prog *prog)
    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;
@@ -867,7 +913,7 @@ void gallivm_cpu_jit_compile(struct gallivm_cpu_engine *cpu, struct gallivm_prog
    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);
 }
 
@@ -885,3 +931,4 @@ struct gallivm_cpu_engine * gallivm_global_cpu_engine()
 
 
 
+
index b4e98c8..636a585 100644 (file)
@@ -46,7 +46,12 @@ struct tgsi_token;
 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],
@@ -55,6 +60,13 @@ int gallivm_prog_exec(struct gallivm_prog *prog,
                       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);
 
 
index 6706645..99fa640 100644 (file)
@@ -191,3 +191,60 @@ void run_vertex_shader(float (*ainputs)[16][4],
       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);
+   }
+}
+
index 4bc604d..cd8d337 100644 (file)
@@ -91,6 +91,11 @@ shade_quad(
 
    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;
@@ -165,33 +170,13 @@ shade_quad_llvm(struct quad_stage *qs,
    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) {
index 92b775a..08a7b58 100644 (file)
@@ -63,7 +63,7 @@ void * softpipe_create_fs_state(struct pipe_context *pipe,
 
 #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);
    }