From 25d91c23ff834a129e537891ec3ad63197d37da5 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Wed, 31 Oct 2007 12:23:45 -0400 Subject: Add basic entry points for fragment shaders. --- src/mesa/pipe/draw/draw_vertex_shader.c | 2 +- src/mesa/pipe/llvm/gallivm.cpp | 53 ++++++++++++++++++++++++++++-- src/mesa/pipe/llvm/gallivm.h | 14 +++++++- src/mesa/pipe/llvm/llvm_entry.c | 57 +++++++++++++++++++++++++++++++++ src/mesa/pipe/softpipe/sp_quad_fs.c | 35 ++++++-------------- src/mesa/pipe/softpipe/sp_state_fs.c | 2 +- 6 files changed, 132 insertions(+), 31 deletions(-) (limited to 'src') 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: " <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(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(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); } -- cgit v1.2.3