fragment shaders through llvm.tags/mesa_20090313
| @@ -22,7 +22,7 @@ INCLUDES = \ | |||
| ##### RULES ##### | |||
| .c.o: | |||
| $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ | |||
| $(CC) -c $(INCLUDES) $(LLVM_CFLAGS) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ | |||
| .S.o: | |||
| $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ | |||
| @@ -39,7 +39,7 @@ | |||
| #include "x86/rtasm/x86sse.h" | |||
| #include "pipe/tgsi/exec/tgsi_core.h" | |||
| #include "pipe/llvm/llvmtgsi.h" | |||
| #include "pipe/llvm/gallivm.h" | |||
| #define DBG_VS 0 | |||
| @@ -240,8 +240,10 @@ draw_create_vertex_shader(struct draw_context *draw, | |||
| #endif | |||
| #ifdef MESA_LLVM | |||
| vs->llvm_prog = gallivm_from_tgsi(shader->tokens); | |||
| if (!draw->engine) | |||
| draw->engine = gallivm_global_cpu_engine(); | |||
| if (!draw->engine) { | |||
| draw->engine = gallivm_cpu_engine_create(vs->llvm_prog); | |||
| } | |||
| else | |||
| gallivm_cpu_jit_compile(draw->engine, vs->llvm_prog); | |||
| #endif | |||
| @@ -37,7 +37,7 @@ | |||
| #ifdef MESA_LLVM | |||
| #include "pipe/llvm/llvmtgsi.h" | |||
| #include "pipe/llvm/gallivm.h" | |||
| #include "pipe/tgsi/exec/tgsi_core.h" | |||
| #define DBG 0 | |||
| @@ -31,7 +31,7 @@ | |||
| */ | |||
| #ifdef MESA_LLVM | |||
| #include "llvmtgsi.h" | |||
| #include "gallivm.h" | |||
| #include "instructions.h" | |||
| #include "storage.h" | |||
| @@ -828,6 +828,7 @@ void gallivm_prog_dump(struct gallivm_prog *prog, const char *file_prefix) | |||
| } | |||
| static struct gallivm_cpu_engine *CPU = 0; | |||
| /*! | |||
| 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 | |||
| @@ -847,6 +848,7 @@ struct gallivm_cpu_engine * gallivm_cpu_engine_create(struct gallivm_prog *prog) | |||
| llvm::Function *func = mod->getFunction("run_vertex_shader"); | |||
| prog->function = ee->getPointerToFunctionOrStub(func); | |||
| CPU = cpu; | |||
| return cpu; | |||
| } | |||
| @@ -874,6 +876,12 @@ void gallivm_cpu_engine_delete(struct gallivm_cpu_engine *cpu) | |||
| free(cpu); | |||
| } | |||
| struct gallivm_cpu_engine * gallivm_global_cpu_engine() | |||
| { | |||
| return CPU; | |||
| } | |||
| #endif /* MESA_LLVM */ | |||
| @@ -59,6 +59,7 @@ void gallivm_prog_dump(struct gallivm_prog *prog, const char *file_prefix); | |||
| struct gallivm_cpu_engine *gallivm_cpu_engine_create(struct gallivm_prog *prog); | |||
| struct gallivm_cpu_engine *gallivm_global_cpu_engine(); | |||
| void gallivm_cpu_jit_compile(struct gallivm_cpu_engine *ee, struct gallivm_prog *prog); | |||
| void gallivm_cpu_engine_delete(struct gallivm_cpu_engine *ee); | |||
| @@ -156,6 +156,76 @@ shade_quad( | |||
| } | |||
| } | |||
| #if 0 | |||
| static void | |||
| shade_quad_llvm(struct quad_stage *qs, | |||
| struct quad_header *quad) | |||
| { | |||
| struct quad_shade_stage *qss = quad_shade_stage(qs); | |||
| struct softpipe_context *softpipe = qs->softpipe; | |||
| const float fx = (float) quad->x0; | |||
| const float fy = (float) quad->y0; | |||
| /* 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); | |||
| /* store result color */ | |||
| if (qss->colorOutSlot >= 0) { | |||
| /* XXX need to handle multiple color outputs someday */ | |||
| assert(qss->stage.softpipe->fs->shader.output_semantic_name[qss->colorOutSlot] | |||
| == TGSI_SEMANTIC_COLOR); | |||
| memcpy( | |||
| quad->outputs.color, | |||
| &machine->Outputs[qss->colorOutSlot].xyzw[0].f[0], | |||
| sizeof( quad->outputs.color ) ); | |||
| } | |||
| /* store result Z */ | |||
| if (qss->depthOutSlot >= 0) { | |||
| /* output[slot] is new Z */ | |||
| uint i; | |||
| for (i = 0; i < 4; i++) { | |||
| quad->outputs.depth[i] = machine->Outputs[0].xyzw[2].f[i]; | |||
| } | |||
| } | |||
| else { | |||
| /* copy input Z (which was interpolated by the executor) to output Z */ | |||
| uint i; | |||
| for (i = 0; i < 4; i++) { | |||
| quad->outputs.depth[i] = machine->Inputs[0].xyzw[2].f[i]; | |||
| } | |||
| } | |||
| /* shader may cull fragments */ | |||
| if( quad->mask ) { | |||
| qs->next->run( qs->next, quad ); | |||
| } | |||
| } | |||
| #endif | |||
| /** | |||
| * Per-primitive (or per-begin?) setup | |||
| @@ -35,6 +35,10 @@ | |||
| #include "x86/rtasm/x86sse.h" | |||
| #ifdef MESA_LLVM | |||
| struct gallivm_prog; | |||
| #endif | |||
| /** | |||
| * Softpipe fs state is derived from pipe_shader_state. | |||
| */ | |||
| @@ -43,6 +47,9 @@ struct sp_fragment_shader_state { | |||
| #if defined(__i386__) || defined(__386__) | |||
| struct x86_function sse2_program; | |||
| #endif | |||
| #ifdef MESA_LLVM | |||
| struct gallivm_prog *llvm_prog; | |||
| #endif | |||
| }; | |||
| void * | |||
| @@ -33,6 +33,7 @@ | |||
| #include "pipe/p_winsys.h" | |||
| #include "pipe/draw/draw_context.h" | |||
| #include "pipe/tgsi/exec/tgsi_core.h" | |||
| #include "pipe/llvm/gallivm.h" | |||
| void * softpipe_create_fs_state(struct pipe_context *pipe, | |||
| @@ -60,6 +61,17 @@ void * softpipe_create_fs_state(struct pipe_context *pipe, | |||
| } | |||
| #endif | |||
| #ifdef MESA_LLVM | |||
| fprintf(stderr, "+++++++++++++++++++++++++++++++++++++++++++++++++\n"); | |||
| state->llvm_prog = gallivm_from_tgsi(state->shader.tokens); | |||
| if (!gallivm_global_cpu_engine()) { | |||
| gallivm_cpu_engine_create(state->llvm_prog); | |||
| } | |||
| else | |||
| gallivm_cpu_jit_compile(gallivm_global_cpu_engine(), state->llvm_prog); | |||
| fprintf(stderr, "+++++++++++++++++++++++++++++++++++++++++++++++++\n"); | |||
| #endif | |||
| return state; | |||
| } | |||
| @@ -189,7 +189,7 @@ TGSIDECO_SOURCES = \ | |||
| LLVMTGSI_SOURCES = \ | |||
| pipe/llvm/llvmtgsi.cpp \ | |||
| pipe/llvm/gallivm.cpp \ | |||
| pipe/llvm/storage.cpp \ | |||
| pipe/llvm/instructions.cpp | |||
| @@ -38,7 +38,6 @@ | |||
| #include "pipe/p_defines.h" | |||
| #include "pipe/draw/draw_context.h" | |||
| #include "pipe/tgsi/exec/tgsi_core.h" | |||
| #include "pipe/llvm/llvmtgsi.h" | |||
| #include "st_context.h" | |||
| #include "st_cache.h" | |||
| @@ -407,9 +406,7 @@ st_translate_fragment_program(struct st_context *st, | |||
| tokensOut, maxTokens); | |||
| fs.tokens = tokensOut; | |||
| #ifdef MESA_LLVM | |||
| /*fs.llvm_prog = gallivm_from_tgsi(st->pipe, fs.tokens);*/ | |||
| #endif | |||
| cso = st_cached_fs_state(st, &fs); | |||
| stfp->fs = cso; | |||