summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZack Rusin <zack@tungstengraphics.com>2007-10-31 12:23:45 -0400
committerZack Rusin <zack@tungstengraphics.com>2007-11-02 07:15:17 -0400
commit25d91c23ff834a129e537891ec3ad63197d37da5 (patch)
tree7c14a496c3095125d4f27e772a7165ac466566cf /src
parent7ff0df6c2bf11a36bc6101e361484bde57595a79 (diff)
Add basic entry points for fragment shaders.
Diffstat (limited to 'src')
-rw-r--r--src/mesa/pipe/draw/draw_vertex_shader.c2
-rw-r--r--src/mesa/pipe/llvm/gallivm.cpp53
-rw-r--r--src/mesa/pipe/llvm/gallivm.h14
-rw-r--r--src/mesa/pipe/llvm/llvm_entry.c57
-rw-r--r--src/mesa/pipe/softpipe/sp_quad_fs.c35
-rw-r--r--src/mesa/pipe/softpipe/sp_state_fs.c2
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);
}