From c04a7f8929d674971a472ffa4d3a31200c22aa5a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 15 Feb 2008 09:31:22 +0000 Subject: gallium: reorganize fragment shader execution, unbreak sse This is probably going to get further reworked in the near future. Right now there's a new interface wrapped around each shader execution mode - exec, sse2, llvm. The llvm code was disabled already and has just been moved as-is to a new file, whereas the sse2 and exec code is actually enabled. The way the interfaces has turned out suggests to me that the correct approach is to actually have each shader include a pointer to a quad stage which will do a better job of encapsulating the execution environment than what I have here -- that's a second step however. --- src/mesa/pipe/softpipe/Makefile | 3 + src/mesa/pipe/softpipe/sp_context.h | 8 +- src/mesa/pipe/softpipe/sp_fs_exec.c | 112 ++++++++++++++++++++ src/mesa/pipe/softpipe/sp_fs_llvm.c | 200 +++++++++++++++++++++++++++++++++++ src/mesa/pipe/softpipe/sp_fs_sse.c | 192 +++++++++++++++++++++++++++++++++ src/mesa/pipe/softpipe/sp_quad_fs.c | 200 ++--------------------------------- src/mesa/pipe/softpipe/sp_state.h | 37 ++++--- src/mesa/pipe/softpipe/sp_state_fs.c | 69 ++++-------- 8 files changed, 565 insertions(+), 256 deletions(-) create mode 100644 src/mesa/pipe/softpipe/sp_fs_exec.c create mode 100644 src/mesa/pipe/softpipe/sp_fs_llvm.c create mode 100644 src/mesa/pipe/softpipe/sp_fs_sse.c (limited to 'src/mesa/pipe/softpipe') diff --git a/src/mesa/pipe/softpipe/Makefile b/src/mesa/pipe/softpipe/Makefile index 31438a882e6..304632abb28 100644 --- a/src/mesa/pipe/softpipe/Makefile +++ b/src/mesa/pipe/softpipe/Makefile @@ -5,6 +5,9 @@ include $(TOP)/configs/current LIBNAME = softpipe DRIVER_SOURCES = \ + sp_fs_exec.c \ + sp_fs_sse.c \ + sp_fs_llvm.c \ sp_clear.c \ sp_flush.c \ sp_query.c \ diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h index aff8c2cc5dc..5e24baf9386 100644 --- a/src/mesa/pipe/softpipe/sp_context.h +++ b/src/mesa/pipe/softpipe/sp_context.h @@ -44,8 +44,8 @@ struct softpipe_vbuf_render; struct draw_context; struct draw_stage; struct softpipe_tile_cache; -struct sp_fragment_shader_state; -struct sp_vertex_shader_state; +struct sp_fragment_shader; +struct sp_vertex_shader; struct softpipe_context { @@ -59,8 +59,8 @@ struct softpipe_context { const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS]; const struct pipe_depth_stencil_alpha_state *depth_stencil; const struct pipe_rasterizer_state *rasterizer; - const struct sp_fragment_shader_state *fs; - const struct sp_vertex_shader_state *vs; + const struct sp_fragment_shader *fs; + const struct sp_vertex_shader *vs; struct pipe_blend_color blend_color; struct pipe_clip_state clip; diff --git a/src/mesa/pipe/softpipe/sp_fs_exec.c b/src/mesa/pipe/softpipe/sp_fs_exec.c new file mode 100644 index 00000000000..b949492e090 --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_fs_exec.c @@ -0,0 +1,112 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "sp_context.h" +#include "sp_state.h" +#include "sp_fs.h" +#include "sp_headers.h" + + +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/tgsi/exec/tgsi_exec.h" + +struct sp_exec_fragment_shader { + struct sp_fragment_shader base; +}; + + + + +static void +exec_prepare( struct sp_fragment_shader *base, + struct tgsi_exec_machine *machine, + struct tgsi_sampler *samplers ) +{ + tgsi_exec_machine_bind_shader( machine, + base->shader.tokens, + PIPE_MAX_SAMPLERS, + samplers ); +} + + + + +/* TODO: hide the machine struct in here somewhere, remove from this + * interface: + */ +static unsigned +exec_run( struct sp_fragment_shader *base, + struct tgsi_exec_machine *machine, + struct quad_header *quad ) +{ + + /* Compute X, Y, Z, W vals for this quad */ + sp_setup_pos_vector(quad->posCoef, + (float)quad->x0, (float)quad->y0, + &machine->QuadPos); + + return tgsi_exec_machine_run( machine ); +} + + + +static void +exec_delete( struct sp_fragment_shader *base ) +{ + FREE(base); +} + + + + + +struct sp_fragment_shader * +softpipe_create_fs_exec(struct softpipe_context *softpipe, + const struct pipe_shader_state *templ) +{ + struct sp_exec_fragment_shader *shader; + + /* Decide whether we'll be codegenerating this shader and if so do + * that now. + */ + + shader = CALLOC_STRUCT(sp_exec_fragment_shader); + if (!shader) + return NULL; + + shader->base.shader = *templ; + shader->base.prepare = exec_prepare; + shader->base.run = exec_run; + shader->base.delete = exec_delete; + + return &shader->base; +} + diff --git a/src/mesa/pipe/softpipe/sp_fs_llvm.c b/src/mesa/pipe/softpipe/sp_fs_llvm.c new file mode 100644 index 00000000000..9237c1fbda0 --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_fs_llvm.c @@ -0,0 +1,200 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: + * Zack Rusin + */ + +#include "sp_context.h" +#include "sp_state.h" +#include "sp_fs.h" + + +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/tgsi/exec/tgsi_sse2.h" + +#if 0 + +struct sp_llvm_fragment_shader { + struct sp_fragment_shader base; + struct gallivm_prog *llvm_prog; +}; + +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; + float dests[4][16][4] ALIGN16_ATTRIB; + float inputs[4][16][4] ALIGN16_ATTRIB; + const float fx = (float) quad->x0; + const float fy = (float) quad->y0; + struct gallivm_prog *llvm = qss->llvm_prog; + + inputs[0][0][0] = fx; + inputs[1][0][0] = fx + 1.0f; + inputs[2][0][0] = fx; + inputs[3][0][0] = fx + 1.0f; + + inputs[0][0][1] = fy; + inputs[1][0][1] = fy; + inputs[2][0][1] = fy + 1.0f; + inputs[3][0][1] = fy + 1.0f; + + + gallivm_prog_inputs_interpolate(llvm, inputs, quad->coef); + +#if DLLVM + debug_printf("MASK = %d\n", quad->mask); + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 2; ++j) { + debug_printf("IN(%d,%d) [%f %f %f %f]\n", i, j, + inputs[i][j][0], inputs[i][j][1], inputs[i][j][2], inputs[i][j][3]); + } + } +#endif + + quad->mask &= + gallivm_fragment_shader_exec(llvm, fx, fy, dests, inputs, + softpipe->mapped_constants[PIPE_SHADER_FRAGMENT], + qss->samplers); +#if DLLVM + debug_printf("OUT LLVM = 1[%f %f %f %f], 2[%f %f %f %f]\n", + dests[0][0][0], dests[0][0][1], dests[0][0][2], dests[0][0][3], + dests[0][1][0], dests[0][1][1], dests[0][1][2], dests[0][1][3]); +#endif + + /* store result color */ + if (qss->colorOutSlot >= 0) { + unsigned i; + /* XXX need to handle multiple color outputs someday */ + allvmrt(qss->stage.softpipe->fs->shader.output_semantic_name[qss->colorOutSlot] + == TGSI_SEMANTIC_COLOR); + for (i = 0; i < QUAD_SIZE; ++i) { + quad->outputs.color[0][i] = dests[i][qss->colorOutSlot][0]; + quad->outputs.color[1][i] = dests[i][qss->colorOutSlot][1]; + quad->outputs.color[2][i] = dests[i][qss->colorOutSlot][2]; + quad->outputs.color[3][i] = dests[i][qss->colorOutSlot][3]; + } + } +#if DLLVM + for (int i = 0; i < QUAD_SIZE; ++i) { + debug_printf("QLLVM%d(%d) [%f, %f, %f, %f]\n", i, qss->colorOutSlot, + quad->outputs.color[0][i], + quad->outputs.color[1][i], + quad->outputs.color[2][i], + quad->outputs.color[3][i]); + } +#endif + + /* store result Z */ + if (qss->depthOutSlot >= 0) { + /* output[slot] is new Z */ + uint i; + for (i = 0; i < 4; i++) { + quad->outputs.depth[i] = dests[i][0][2]; + } + } + 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] = inputs[i][0][2]; + } + } +#if DLLVM + debug_printf("D [%f, %f, %f, %f] mask = %d\n", + quad->outputs.depth[0], + quad->outputs.depth[1], + quad->outputs.depth[2], + quad->outputs.depth[3], quad->mask); +#endif + + /* shader may cull fragments */ + if( quad->mask ) { + qs->next->run( qs->next, quad ); + } +} + + +unsigned +run_llvm_fs( struct sp_fragment_shader *base, + struct foo *machine ) +{ +} + + +void +delete_llvm_fs( struct sp_fragment_shader *base ) +{ + FREE(base); +} + + +struct sp_fragment_shader * +softpipe_create_fs_llvm(struct softpipe_context *softpipe, + const struct pipe_shader_state *templ) +{ + struct sp_llvm_fragment_shader *shader = NULL; + + /* LLVM fragment shaders currently disabled: + */ + state = CALLOC_STRUCT(sp_llvm_shader_state); + if (!state) + return NULL; + + state->llvm_prog = 0; + + if (!gallivm_global_cpu_engine()) { + gallivm_cpu_engine_create(state->llvm_prog); + } + else + gallivm_cpu_jit_compile(gallivm_global_cpu_engine(), state->llvm_prog); + + if (shader) { + shader->base.run = run_llvm_fs; + shader->base.delete = delete_llvm_fs; + } + + return shader; +} + + +#else + +struct sp_fragment_shader * +softpipe_create_fs_llvm(struct softpipe_context *softpipe, + const struct pipe_shader_state *templ) +{ + return NULL; +} + +#endif diff --git a/src/mesa/pipe/softpipe/sp_fs_sse.c b/src/mesa/pipe/softpipe/sp_fs_sse.c new file mode 100644 index 00000000000..713ece369ef --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_fs_sse.c @@ -0,0 +1,192 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "sp_context.h" +#include "sp_state.h" +#include "sp_fs.h" +#include "sp_headers.h" + + +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/tgsi/exec/tgsi_exec.h" +#include "pipe/tgsi/exec/tgsi_sse2.h" + + +#if defined(__i386__) || defined(__386__) + +#include "x86/rtasm/x86sse.h" + +/* Surely this should be defined somewhere in a tgsi header: + */ +typedef void (XSTDCALL *codegen_function)( + const struct tgsi_exec_vector *input, + struct tgsi_exec_vector *output, + float (*constant)[4], + struct tgsi_exec_vector *temporary, + const struct tgsi_interp_coef *coef + //, const struct tgsi_exec_vector *quadPos + ); + + +struct sp_sse_fragment_shader { + struct sp_fragment_shader base; + struct x86_function sse2_program; + codegen_function func; +}; + + +/** + * Compute quad X,Y,Z,W for the four fragments in a quad. + * + * This should really be part of the compiled shader. + */ +void +sp_setup_pos_vector(const struct tgsi_interp_coef *coef, + float x, float y, + struct tgsi_exec_vector *quadpos) +{ + uint chan; + /* do X */ + quadpos->xyzw[0].f[0] = x; + quadpos->xyzw[0].f[1] = x + 1; + quadpos->xyzw[0].f[2] = x; + quadpos->xyzw[0].f[3] = x + 1; + + /* do Y */ + quadpos->xyzw[1].f[0] = y; + quadpos->xyzw[1].f[1] = y; + quadpos->xyzw[1].f[2] = y + 1; + quadpos->xyzw[1].f[3] = y + 1; + + /* do Z and W for all fragments in the quad */ + for (chan = 2; chan < 4; chan++) { + const float dadx = coef->dadx[chan]; + const float dady = coef->dady[chan]; + const float a0 = coef->a0[chan] + dadx * x + dady * y; + quadpos->xyzw[chan].f[0] = a0; + quadpos->xyzw[chan].f[1] = a0 + dadx; + quadpos->xyzw[chan].f[2] = a0 + dady; + quadpos->xyzw[chan].f[3] = a0 + dadx + dady; + } +} + + +static void +sse_prepare( struct sp_fragment_shader *base, + struct tgsi_exec_machine *machine, + struct tgsi_sampler *samplers ) +{ +} + + +/* TODO: codegenerate the whole run function, skip this wrapper. + * TODO: break dependency on tgsi_exec_machine struct + * TODO: push Position calculation into the generated shader + * TODO: process >1 quad at a time + */ +static unsigned +sse_run( struct sp_fragment_shader *base, + struct tgsi_exec_machine *machine, + struct quad_header *quad ) +{ + struct sp_sse_fragment_shader *shader = (struct sp_sse_fragment_shader *) base; + + /* Compute X, Y, Z, W vals for this quad -- place in temp[0] for now */ + sp_setup_pos_vector(quad->posCoef, + (float)quad->x0, (float)quad->y0, + machine->Temps); + + shader->func( machine->Inputs, + machine->Outputs, + machine->Consts, + machine->Temps, + machine->InterpCoefs + // , &machine->QuadPos + ); + + return ~(machine->Temps[TGSI_EXEC_TEMP_KILMASK_I].xyzw[TGSI_EXEC_TEMP_KILMASK_C].u[0]); +} + + +static void +sse_delete( struct sp_fragment_shader *base ) +{ + struct sp_sse_fragment_shader *shader = (struct sp_sse_fragment_shader *) base; + + x86_release_func( &shader->sse2_program ); + FREE(shader); +} + + +struct sp_fragment_shader * +softpipe_create_fs_sse(struct softpipe_context *softpipe, + const struct pipe_shader_state *templ) +{ + struct sp_sse_fragment_shader *shader; + + if (!softpipe->use_sse) + return NULL; + + shader = CALLOC_STRUCT(sp_sse_fragment_shader); + if (!shader) + return NULL; + + x86_init_func( &shader->sse2_program ); + + if (!tgsi_emit_sse2_fs( templ->tokens, &shader->sse2_program )) { + FREE(shader); + return NULL; + } + + shader->func = (codegen_function) x86_get_func( &shader->sse2_program ); + assert(shader->func); + + shader->base.shader = *templ; + shader->base.prepare = sse_prepare; + shader->base.run = sse_run; + shader->base.delete = sse_delete; + + return &shader->base; +} + + +#else + +/* Maybe put this varient in the header file. + */ +struct sp_fragment_shader * +softpipe_create_fs_sse(struct softpipe_context *softpipe, + const struct pipe_shader_state *templ) +{ + return NULL; +} + +#endif diff --git a/src/mesa/pipe/softpipe/sp_quad_fs.c b/src/mesa/pipe/softpipe/sp_quad_fs.c index 33168584137..cf1b1eff75c 100644 --- a/src/mesa/pipe/softpipe/sp_quad_fs.c +++ b/src/mesa/pipe/softpipe/sp_quad_fs.c @@ -39,12 +39,6 @@ #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" -#include "x86/rtasm/x86sse.h" - -#ifdef MESA_LLVM -#include "pipe/llvm/gallivm.h" -#endif - #include "sp_context.h" #include "sp_state.h" #include "sp_headers.h" @@ -60,9 +54,6 @@ struct quad_shade_stage struct tgsi_exec_machine machine; struct tgsi_exec_vector *inputs, *outputs; int colorOutSlot, depthOutSlot; -#ifdef MESA_LLVM - struct gallivm_prog *llvm_prog; -#endif }; @@ -74,46 +65,6 @@ quad_shade_stage(struct quad_stage *qs) } -/** - * Compute quad X,Y,Z,W for the four fragments in a quad. - * Note that we only need to "compute" X and Y for the upper-left fragment. - * We could do less work if we're not depth testing, or there's no - * perspective-corrected attributes, but that's seldom. - */ -static void -setup_pos_vector(const struct tgsi_interp_coef *coef, - float x, float y, - struct tgsi_exec_vector *quadpos) -{ - uint chan; - /* do X */ - quadpos->xyzw[0].f[0] = x; - /* do Y */ - quadpos->xyzw[1].f[0] = y; - /* do Z and W for all fragments in the quad */ - for (chan = 2; chan < 4; chan++) { - const float dadx = coef->dadx[chan]; - const float dady = coef->dady[chan]; - const float a0 = coef->a0[chan] + dadx * x + dady * y; - quadpos->xyzw[chan].f[0] = a0; - quadpos->xyzw[chan].f[1] = a0 + dadx; - quadpos->xyzw[chan].f[2] = a0 + dady; - quadpos->xyzw[chan].f[3] = a0 + dadx + dady; - } -} - - -typedef void (XSTDCALL *codegen_function)( - const struct tgsi_exec_vector *input, - struct tgsi_exec_vector *output, - float (*constant)[4], - struct tgsi_exec_vector *temporary, - const struct tgsi_interp_coef *coef -#if 0 - ,const struct tgsi_exec_vector *quadPos -#endif - ); - /** * Execute fragment shader for the four fragments in the quad. @@ -132,30 +83,10 @@ shade_quad( machine->InterpCoefs = quad->coef; - /* Compute X, Y, Z, W vals for this quad */ - setup_pos_vector(quad->posCoef, (float) quad->x0, (float) quad->y0, &machine->QuadPos); - /* run shader */ -#if defined(__i386__) || defined(__386__) - if( softpipe->use_sse ) { - codegen_function func = (codegen_function) x86_get_func( &softpipe->fs->sse2_program ); - func( - machine->Inputs, - machine->Outputs, - machine->Consts, - machine->Temps, - machine->InterpCoefs -#if 0 - ,machine->QuadPos -#endif - ); - quad->mask &= ~(machine->Temps[TGSI_EXEC_TEMP_KILMASK_I].xyzw[TGSI_EXEC_TEMP_KILMASK_C].u[0]); - } - else -#endif - { - quad->mask &= tgsi_exec_machine_run( machine ); - } + quad->mask &= softpipe->fs->run( softpipe->fs, + &qss->machine, + quad ); /* store result color */ if (qss->colorOutSlot >= 0) { @@ -199,107 +130,6 @@ shade_quad( } } -#if 0 -#ifdef MESA_LLVM -#define DLLVM 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; - float dests[4][16][4] ALIGN16_ATTRIB; - float inputs[4][16][4] ALIGN16_ATTRIB; - const float fx = (float) quad->x0; - const float fy = (float) quad->y0; - struct gallivm_prog *llvm = qss->llvm_prog; - - inputs[0][0][0] = fx; - inputs[1][0][0] = fx + 1.0f; - inputs[2][0][0] = fx; - inputs[3][0][0] = fx + 1.0f; - - inputs[0][0][1] = fy; - inputs[1][0][1] = fy; - inputs[2][0][1] = fy + 1.0f; - inputs[3][0][1] = fy + 1.0f; -#if DLLVM - debug_printf("MASK = %d\n", quad->mask); -#endif - gallivm_prog_inputs_interpolate(llvm, inputs, quad->coef); -#if DLLVM - for (int i = 0; i < 4; ++i) { - for (int j = 0; j < 2; ++j) { - debug_printf("IN(%d,%d) [%f %f %f %f]\n", i, j, - inputs[i][j][0], inputs[i][j][1], inputs[i][j][2], inputs[i][j][3]); - } - } -#endif - - quad->mask &= - gallivm_fragment_shader_exec(llvm, fx, fy, dests, inputs, - softpipe->mapped_constants[PIPE_SHADER_FRAGMENT], - qss->samplers); -#if DLLVM - debug_printf("OUT LLVM = 1[%f %f %f %f], 2[%f %f %f %f]\n", - dests[0][0][0], dests[0][0][1], dests[0][0][2], dests[0][0][3], - dests[0][1][0], dests[0][1][1], dests[0][1][2], dests[0][1][3]); -#endif - - /* store result color */ - if (qss->colorOutSlot >= 0) { - unsigned i; - /* XXX need to handle multiple color outputs someday */ - assert(qss->stage.softpipe->fs->shader.output_semantic_name[qss->colorOutSlot] - == TGSI_SEMANTIC_COLOR); - for (i = 0; i < QUAD_SIZE; ++i) { - quad->outputs.color[0][i] = dests[i][qss->colorOutSlot][0]; - quad->outputs.color[1][i] = dests[i][qss->colorOutSlot][1]; - quad->outputs.color[2][i] = dests[i][qss->colorOutSlot][2]; - quad->outputs.color[3][i] = dests[i][qss->colorOutSlot][3]; - } - } -#if DLLVM - for (int i = 0; i < QUAD_SIZE; ++i) { - debug_printf("QLLVM%d(%d) [%f, %f, %f, %f]\n", i, qss->colorOutSlot, - quad->outputs.color[0][i], - quad->outputs.color[1][i], - quad->outputs.color[2][i], - quad->outputs.color[3][i]); - } -#endif - - /* store result Z */ - if (qss->depthOutSlot >= 0) { - /* output[slot] is new Z */ - uint i; - for (i = 0; i < 4; i++) { - quad->outputs.depth[i] = dests[i][0][2]; - } - } - 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] = inputs[i][0][2]; - } - } -#if DLLVM - debug_printf("D [%f, %f, %f, %f] mask = %d\n", - quad->outputs.depth[0], - quad->outputs.depth[1], - quad->outputs.depth[2], - quad->outputs.depth[3], quad->mask); -#endif - - /* shader may cull fragments */ - if( quad->mask ) { - qs->next->run( qs->next, quad ); - } -} -#endif /*MESA_LLVM*/ -#endif - /** * Per-primitive (or per-begin?) setup */ @@ -315,15 +145,6 @@ static void shade_begin(struct quad_stage *qs) qss->samplers[i].texture = &softpipe->texture[i]->base; } -#ifdef MESA_LLVM - qss->llvm_prog = softpipe->fs->llvm_prog; -#endif - /* XXX only do this if the fragment shader changes... */ - tgsi_exec_machine_init(&qss->machine, - softpipe->fs->shader.tokens, - PIPE_MAX_SAMPLERS, - qss->samplers ); - /* find output slots for depth, color */ qss->colorOutSlot = -1; qss->depthOutSlot = -1; @@ -337,6 +158,10 @@ static void shade_begin(struct quad_stage *qs) break; } } + + softpipe->fs->prepare( softpipe->fs, + &qss->machine, + qss->samplers ); qs->next->begin(qs->next); } @@ -366,16 +191,7 @@ struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe ) qss->stage.softpipe = softpipe; qss->stage.begin = shade_begin; -#ifdef MESA_LLVM - /* disable until ported to accept - * x/y and soa layout - qss->stage.run = shade_quad_llvm; - */ - softpipe->use_sse = FALSE; - qss->stage.run = shade_quad; -#else qss->stage.run = shade_quad; -#endif qss->stage.destroy = shade_destroy; /* set TGSI sampler state that's constant */ @@ -386,5 +202,7 @@ struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe ) qss->samplers[i].cache = softpipe->tex_cache[i]; } + tgsi_exec_machine_init( &qss->machine ); + return &qss->stage; } diff --git a/src/mesa/pipe/softpipe/sp_state.h b/src/mesa/pipe/softpipe/sp_state.h index af955c1e17b..431952f1aac 100644 --- a/src/mesa/pipe/softpipe/sp_state.h +++ b/src/mesa/pipe/softpipe/sp_state.h @@ -33,8 +33,6 @@ #include "pipe/p_state.h" -#include "x86/rtasm/x86sse.h" - #define SP_NEW_VIEWPORT 0x1 #define SP_NEW_RASTERIZER 0x2 @@ -53,27 +51,36 @@ #define SP_NEW_QUERY 0x4000 +struct tgsi_sampler; +struct tgsi_interp_coef; +struct tgsi_exec_machine; -#ifdef MESA_LLVM -struct gallivm_prog; -#endif +/** Subclass of pipe_shader_state (though it doesn't really need to be). + * + * This is starting to look an awful lot like a quad pipeline stage... + */ +struct sp_fragment_shader { + struct pipe_shader_state shader; + void (*prepare)( struct sp_fragment_shader *shader, + struct tgsi_exec_machine *machine, + struct tgsi_sampler *samplers); -/** Subclass of pipe_shader_state */ -struct sp_fragment_shader_state { - struct pipe_shader_state shader; -#if defined(__i386__) || defined(__386__) - struct x86_function sse2_program; -#endif -#ifdef MESA_LLVM - struct gallivm_prog *llvm_prog; -#endif + /* Run the shader - this interface will get cleaned up in the + * future: + */ + unsigned (*run)( struct sp_fragment_shader *shader, + struct tgsi_exec_machine *machine, + struct quad_header *quad ); + + + void (*delete)( struct sp_fragment_shader * ); }; /** Subclass of pipe_shader_state */ -struct sp_vertex_shader_state { +struct sp_vertex_shader { struct pipe_shader_state shader; struct draw_vertex_shader *draw_data; }; diff --git a/src/mesa/pipe/softpipe/sp_state_fs.c b/src/mesa/pipe/softpipe/sp_state_fs.c index 0b814fc2847..c43f28583ee 100644 --- a/src/mesa/pipe/softpipe/sp_state_fs.c +++ b/src/mesa/pipe/softpipe/sp_state_fs.c @@ -27,16 +27,15 @@ #include "sp_context.h" #include "sp_state.h" +#include "sp_fs.h" #include "pipe/p_defines.h" #include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" -#include "pipe/draw/draw_context.h" #include "pipe/p_shader_tokens.h" -#include "pipe/llvm/gallivm.h" +#include "pipe/draw/draw_context.h" #include "pipe/tgsi/util/tgsi_dump.h" -#include "pipe/tgsi/exec/tgsi_sse2.h" void * @@ -44,40 +43,22 @@ softpipe_create_fs_state(struct pipe_context *pipe, const struct pipe_shader_state *templ) { struct softpipe_context *softpipe = softpipe_context(pipe); - struct sp_fragment_shader_state *state; + struct sp_fragment_shader *state; - /* Decide whether we'll be codegenerating this shader and if so do - * that now. - */ - - state = CALLOC_STRUCT(sp_fragment_shader_state); - if (!state) - return NULL; + if (softpipe->dump_fs) + tgsi_dump(templ->tokens, 0); - state->shader = *templ; - - if (softpipe->dump_fs) { - tgsi_dump(state->shader.tokens, 0); - } + state = softpipe_create_fs_llvm( softpipe, templ ); + if (state) + return state; + + state = softpipe_create_fs_sse( softpipe, templ ); + if (state) + return state; -#ifdef MESA_LLVM - state->llvm_prog = 0; - -#if 0 - if (!gallivm_global_cpu_engine()) { - gallivm_cpu_engine_create(state->llvm_prog); - } - else - gallivm_cpu_jit_compile(gallivm_global_cpu_engine(), state->llvm_prog); -#endif - -#elif defined(__i386__) || defined(__386__) - if (softpipe->use_sse) { - x86_init_func( &state->sse2_program ); - tgsi_emit_sse2_fs( state->shader.tokens, &state->sse2_program ); - } -#endif + state = softpipe_create_fs_exec( softpipe, templ ); + assert(state); return state; } @@ -87,7 +68,7 @@ softpipe_bind_fs_state(struct pipe_context *pipe, void *fs) { struct softpipe_context *softpipe = softpipe_context(pipe); - softpipe->fs = (struct sp_fragment_shader_state *) fs; + softpipe->fs = (struct sp_fragment_shader *) fs; softpipe->dirty |= SP_NEW_FS; } @@ -96,13 +77,9 @@ softpipe_bind_fs_state(struct pipe_context *pipe, void *fs) void softpipe_delete_fs_state(struct pipe_context *pipe, void *fs) { - struct sp_fragment_shader_state *state = fs; - -#if defined(__i386__) || defined(__386__) - x86_release_func( &state->sse2_program ); -#endif - - FREE( state ); + struct sp_fragment_shader *state = fs; + + state->delete( state ); } @@ -111,9 +88,9 @@ softpipe_create_vs_state(struct pipe_context *pipe, const struct pipe_shader_state *templ) { struct softpipe_context *softpipe = softpipe_context(pipe); - struct sp_vertex_shader_state *state; + struct sp_vertex_shader *state; - state = CALLOC_STRUCT(sp_vertex_shader_state); + state = CALLOC_STRUCT(sp_vertex_shader); if (state == NULL ) { return NULL; } @@ -136,7 +113,7 @@ softpipe_bind_vs_state(struct pipe_context *pipe, void *vs) { struct softpipe_context *softpipe = softpipe_context(pipe); - softpipe->vs = (const struct sp_vertex_shader_state *)vs; + softpipe->vs = (const struct sp_vertex_shader *)vs; draw_bind_vertex_shader(softpipe->draw, softpipe->vs->draw_data); @@ -149,8 +126,8 @@ softpipe_delete_vs_state(struct pipe_context *pipe, void *vs) { struct softpipe_context *softpipe = softpipe_context(pipe); - struct sp_vertex_shader_state *state = - (struct sp_vertex_shader_state *)vs; + struct sp_vertex_shader *state = + (struct sp_vertex_shader *)vs; draw_delete_vertex_shader(softpipe->draw, state->draw_data); FREE( state ); -- cgit v1.2.3