diff options
| author | Zack Rusin <zack@tungstengraphics.com> | 2007-10-31 12:23:45 -0400 | 
|---|---|---|
| committer | Zack Rusin <zack@tungstengraphics.com> | 2007-11-02 07:15:17 -0400 | 
| commit | 25d91c23ff834a129e537891ec3ad63197d37da5 (patch) | |
| tree | 7c14a496c3095125d4f27e772a7165ac466566cf | |
| parent | 7ff0df6c2bf11a36bc6101e361484bde57595a79 (diff) | |
Add basic entry points for fragment shaders.
| -rw-r--r-- | src/mesa/pipe/draw/draw_vertex_shader.c | 2 | ||||
| -rw-r--r-- | src/mesa/pipe/llvm/gallivm.cpp | 53 | ||||
| -rw-r--r-- | src/mesa/pipe/llvm/gallivm.h | 14 | ||||
| -rw-r--r-- | src/mesa/pipe/llvm/llvm_entry.c | 57 | ||||
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_quad_fs.c | 35 | ||||
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_state_fs.c | 2 | 
6 files changed, 132 insertions, 31 deletions
diff --git a/src/mesa/pipe/draw/draw_vertex_shader.c b/src/mesa/pipe/draw/draw_vertex_shader.c index 7768a62000..529ed288eb 100644 --- a/src/mesa/pipe/draw/draw_vertex_shader.c +++ b/src/mesa/pipe/draw/draw_vertex_shader.c @@ -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); diff --git a/src/mesa/pipe/llvm/gallivm.cpp b/src/mesa/pipe/llvm/gallivm.cpp index b09a2ff8ee..48c7babc45 100644 --- a/src/mesa/pipe/llvm/gallivm.cpp +++ b/src/mesa/pipe/llvm/gallivm.cpp @@ -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() + diff --git a/src/mesa/pipe/llvm/gallivm.h b/src/mesa/pipe/llvm/gallivm.h index b4e98c881b..636a585dae 100644 --- a/src/mesa/pipe/llvm/gallivm.h +++ b/src/mesa/pipe/llvm/gallivm.h @@ -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); diff --git a/src/mesa/pipe/llvm/llvm_entry.c b/src/mesa/pipe/llvm/llvm_entry.c index 67066455ae..99fa64057f 100644 --- a/src/mesa/pipe/llvm/llvm_entry.c +++ b/src/mesa/pipe/llvm/llvm_entry.c @@ -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); +   } +} + diff --git a/src/mesa/pipe/softpipe/sp_quad_fs.c b/src/mesa/pipe/softpipe/sp_quad_fs.c index 4bc604d682..cd8d337044 100644 --- a/src/mesa/pipe/softpipe/sp_quad_fs.c +++ b/src/mesa/pipe/softpipe/sp_quad_fs.c @@ -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) { diff --git a/src/mesa/pipe/softpipe/sp_state_fs.c b/src/mesa/pipe/softpipe/sp_state_fs.c index 92b775ae51..08a7b58a6f 100644 --- a/src/mesa/pipe/softpipe/sp_state_fs.c +++ b/src/mesa/pipe/softpipe/sp_state_fs.c @@ -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);     }  | 
