diff options
Diffstat (limited to 'src/mesa/state_tracker')
-rw-r--r-- | src/mesa/state_tracker/st_atom_fs.c | 23 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_atom_vs.c | 46 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_clear.c | 21 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_drawpixels.c | 15 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_draw.c | 103 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_program.h | 17 |
6 files changed, 160 insertions, 65 deletions
diff --git a/src/mesa/state_tracker/st_atom_fs.c b/src/mesa/state_tracker/st_atom_fs.c index dc3e5258d8..3df2c6750a 100644 --- a/src/mesa/state_tracker/st_atom_fs.c +++ b/src/mesa/state_tracker/st_atom_fs.c @@ -42,17 +42,34 @@ #include "st_atom.h" #include "st_program.h" -#define TGSI_DEBUG 0 +#define TGSI_DEBUG 1 static void compile_fs( struct st_context *st ) { + /* Map FRAG_RESULT_COLR to output 1, map FRAG_RESULT_DEPR to output 0 */ + static const GLuint outputMapping[2] = {1, 0}; struct st_fragment_program *fp = st->fp; struct pipe_shader_state fs; struct pipe_shader_state *cached; + GLuint interpMode[16]; /* XXX size? */ + GLuint i; + + for (i = 0; i < 16; i++) { + if (fp->Base.Base.InputsRead & (1 << i)) { + if (i == FRAG_ATTRIB_COL0 || i == FRAG_ATTRIB_COL1) { + interpMode[i] = TGSI_INTERPOLATE_LINEAR; + } + else { + interpMode[i] = TGSI_INTERPOLATE_PERSPECTIVE; + } + } + } /* XXX: fix static allocation of tokens: */ - tgsi_mesa_compile_fp_program( &fp->Base, fp->tokens, ST_FP_MAX_TOKENS ); + tgsi_mesa_compile_fp_program( &fp->Base, NULL, interpMode, + outputMapping, + fp->tokens, ST_FP_MAX_TOKENS ); memset(&fs, 0, sizeof(fs)); fs.inputs_read @@ -64,7 +81,7 @@ static void compile_fs( struct st_context *st ) fp->fsx = cached; if (TGSI_DEBUG) - tgsi_dump( fp->tokens, TGSI_DUMP_VERBOSE ); + tgsi_dump( fp->tokens, 0/*TGSI_DUMP_VERBOSE*/ ); fp->dirty = 0; } diff --git a/src/mesa/state_tracker/st_atom_vs.c b/src/mesa/state_tracker/st_atom_vs.c index 8f1df80a7f..8de19e41ee 100644 --- a/src/mesa/state_tracker/st_atom_vs.c +++ b/src/mesa/state_tracker/st_atom_vs.c @@ -51,25 +51,61 @@ -/* translate shader to TGSI format -*/ +/** + * Translate Mesa shader to TGSI format + */ static void compile_vs( struct st_context *st ) { struct st_vertex_program *vp = st->vp; struct pipe_shader_state vs; struct pipe_shader_state *cached; + GLuint i; + + memset(&vs, 0, sizeof(vs)); + + /* + * Determine how many inputs there are. + * Also, compute two look-up tables that map between Mesa VERT_ATTRIB_x + * values and TGSI generic input indexes. + */ + for (i = 0; i < MAX_VERTEX_PROGRAM_ATTRIBS; i++) { + if (vp->Base.Base.InputsRead & (1 << i)) { + vp->input_to_index[i] = vs.num_inputs; + vp->index_to_input[vs.num_inputs] = i; + vs.num_inputs++; + } + } + + /* + * Determine output register mapping. + */ + for (i = 0; i < VERT_RESULT_MAX; i++) { + if (vp->Base.Base.OutputsWritten & (1 << i)) { + vp->output_to_index[i] = vs.num_outputs; + vp->index_to_output[vs.num_outputs] = i; + vs.num_outputs++; + } + } + + /* XXX: fix static allocation of tokens: */ - tgsi_mesa_compile_vp_program( &vp->Base, vp->tokens, ST_FP_MAX_TOKENS ); + tgsi_mesa_compile_vp_program( &vp->Base, + vp->input_to_index, + vp->output_to_index, + vp->tokens, ST_FP_MAX_TOKENS ); - memset(&vs, 0, sizeof(vs)); +#if 01 vs.inputs_read = tgsi_mesa_translate_vertex_input_mask(vp->Base.Base.InputsRead); +#endif vs.outputs_written = tgsi_mesa_translate_vertex_output_mask(vp->Base.Base.OutputsWritten); + vs.tokens = &vp->tokens[0]; cached = st_cached_shader_state(st, &vs); + vp->vs = cached; if (TGSI_DEBUG) @@ -121,7 +157,7 @@ static void update_vs( struct st_context *st ) const struct st_tracked_state st_update_vs = { .name = "st_update_vs", .dirty = { - .mesa = 0, + .mesa = _NEW_PROGRAM, .st = ST_NEW_VERTEX_PROGRAM, }, .update = update_vs diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index 2ea498663b..65cac9dbde 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -119,12 +119,19 @@ is_depth_stencil_format(GLuint pipeFormat) * Create a simple fragment shader that just passes through the fragment color. */ static struct st_fragment_program * -make_color_shader(struct st_context *st) +make_frag_shader(struct st_context *st) { + static const GLuint outputMapping[] = { 1, 0 }; GLcontext *ctx = st->ctx; struct st_fragment_program *stfp; struct gl_program *p; GLboolean b; + GLuint interpMode[16]; + GLuint i; + + /* XXX temporary */ + for (i = 0; i < 16; i++) + interpMode[i] = TGSI_INTERPOLATE_LINEAR; p = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); if (!p) @@ -151,7 +158,8 @@ make_color_shader(struct st_context *st) stfp = (struct st_fragment_program *) p; /* compile into tgsi format */ - b = tgsi_mesa_compile_fp_program(&stfp->Base, + b = tgsi_mesa_compile_fp_program(&stfp->Base, NULL, interpMode, + outputMapping, stfp->tokens, ST_FP_MAX_TOKENS); assert(b); @@ -166,6 +174,11 @@ make_color_shader(struct st_context *st) static struct st_vertex_program * make_vertex_shader(struct st_context *st) { + /* Map VERT_ATTRIB_POS to 0, VERT_ATTRIB_COLOR0 to 1 */ + static const GLuint inputMapping[4] = { 0, 0, 0, 1 }; + /* Map VERT_RESULT_HPOS to 0, VERT_RESULT_COL0 to 1 */ + static const GLuint outputMapping[2] = { 0, 1 }; + GLcontext *ctx = st->ctx; struct st_vertex_program *stvp; struct gl_program *p; @@ -204,6 +217,8 @@ make_vertex_shader(struct st_context *st) stvp = (struct st_vertex_program *) p; /* compile into tgsi format */ b = tgsi_mesa_compile_vp_program(&stvp->Base, + inputMapping, + outputMapping, stvp->tokens, ST_FP_MAX_TOKENS); assert(b); @@ -349,7 +364,7 @@ clear_with_quad(GLcontext *ctx, struct pipe_shader_state fs; const struct pipe_shader_state *cached; if (!stfp) { - stfp = make_color_shader(st); + stfp = make_frag_shader(st); } memset(&fs, 0, sizeof(fs)); fs.inputs_read = tgsi_mesa_translate_fragment_input_mask(stfp->Base.Base.InputsRead); diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 37e40636f6..731c060c11 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -56,10 +56,17 @@ static struct st_fragment_program * make_fragment_shader(struct st_context *st) { + static const GLuint outputMapping[2] = { 1, 0 }; GLcontext *ctx = st->ctx; struct st_fragment_program *stfp; struct gl_program *p; GLboolean b; + GLuint interpMode[16]; + GLuint i; + + /* XXX temporary */ + for (i = 0; i < 16; i++) + interpMode[i] = TGSI_INTERPOLATE_LINEAR; p = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); if (!p) @@ -88,7 +95,8 @@ make_fragment_shader(struct st_context *st) stfp = (struct st_fragment_program *) p; /* compile into tgsi format */ - b = tgsi_mesa_compile_fp_program(&stfp->Base, + b = tgsi_mesa_compile_fp_program(&stfp->Base, NULL, interpMode, + outputMapping, stfp->tokens, ST_FP_MAX_TOKENS); assert(b); @@ -103,6 +111,8 @@ make_fragment_shader(struct st_context *st) static struct st_vertex_program * make_vertex_shader(struct st_context *st) { + /* Map VERT_RESULT_HPOS to 0, VERT_RESULT_TEX0 to 1 */ + static const GLuint outputMapping[] = { 0, 0, 0, 0, 1 }; GLcontext *ctx = st->ctx; struct st_vertex_program *stvp; struct gl_program *p; @@ -140,7 +150,8 @@ make_vertex_shader(struct st_context *st) stvp = (struct st_vertex_program *) p; /* compile into tgsi format */ - b = tgsi_mesa_compile_vp_program(&stvp->Base, + b = tgsi_mesa_compile_vp_program(&stvp->Base, NULL, + outputMapping, stvp->tokens, ST_FP_MAX_TOKENS); assert(b); diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index ac63a38720..bff0ad7ef7 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -37,10 +37,12 @@ #include "tnl/t_vp_build.h" -#include "st_context.h" #include "st_atom.h" -#include "st_draw.h" +#include "st_context.h" #include "st_cb_bufferobjects.h" +#include "st_draw.h" +#include "st_program.h" + #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_winsys.h" @@ -185,18 +187,22 @@ st_draw_vbo(GLcontext *ctx, GLuint max_index) { struct pipe_context *pipe = ctx->st->pipe; - GLuint attr, i; - GLbitfield attrsNeeded; + const struct st_vertex_program *vp = ctx->st->vp; + const struct pipe_shader_state *vs; const unsigned attr0_offset = (unsigned) arrays[0]->Ptr; + GLboolean needDefaultAttribs = GL_FALSE; + GLuint attr; st_validate_state(ctx->st); - update_default_attribs_buffer(ctx); - /* this must be after state validation */ - attrsNeeded = ctx->st->state.vs->inputs_read; + /* must do this after state validation! */ + vs = ctx->st->state.vs; + + /* loop over TGSI shader inputs */ + for (attr = 0; attr < vs->num_inputs; attr++) { + const GLuint mesaAttr = vp->index_to_input[attr]; + struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj; - /* tell pipe about the vertex array element/attributes */ - for (attr = 0; attr < 16; attr++) { struct pipe_vertex_buffer vbuffer; struct pipe_vertex_element velement; @@ -206,43 +212,40 @@ st_draw_vbo(GLcontext *ctx, velement.vertex_buffer_index = 0; velement.src_format = 0; - if (attrsNeeded & (1 << attr)) { - const GLuint mesaAttr = tgsi_attrib_to_mesa_attrib(attr); - struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj; - - if (bufobj && bufobj->Name) { - struct st_buffer_object *stobj = st_buffer_object(bufobj); - /* Recall that for VBOs, the gl_client_array->Ptr field is - * really an offset from the start of the VBO, not a pointer. - */ - unsigned offset = (unsigned) arrays[mesaAttr]->Ptr; - - assert(stobj->buffer); - - vbuffer.buffer = stobj->buffer; - vbuffer.buffer_offset = attr0_offset; /* in bytes */ - vbuffer.pitch = arrays[mesaAttr]->StrideB; /* in bytes */ - vbuffer.max_index = 0; /* need this? */ - - velement.src_offset = offset - attr0_offset; /* bytes */ - velement.vertex_buffer_index = attr; - velement.dst_offset = 0; /* need this? */ - velement.src_format = pipe_vertex_format(arrays[mesaAttr]->Type, - arrays[mesaAttr]->Size); - assert(velement.src_format); - } - else { - /* use the default attribute buffer */ - vbuffer.buffer = ctx->st->default_attrib_buffer; - vbuffer.buffer_offset = 0; - vbuffer.pitch = 0; /* must be zero! */ - vbuffer.max_index = 1; - - velement.src_offset = attr * 4 * sizeof(GLfloat); - velement.vertex_buffer_index = attr; - velement.dst_offset = 0; - velement.src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - } + if (bufobj && bufobj->Name) { + struct st_buffer_object *stobj = st_buffer_object(bufobj); + /* Recall that for VBOs, the gl_client_array->Ptr field is + * really an offset from the start of the VBO, not a pointer. + */ + unsigned offset = (unsigned) arrays[mesaAttr]->Ptr; + + assert(stobj->buffer); + + vbuffer.buffer = stobj->buffer; + vbuffer.buffer_offset = attr0_offset; /* in bytes */ + vbuffer.pitch = arrays[mesaAttr]->StrideB; /* in bytes */ + vbuffer.max_index = 0; /* need this? */ + + velement.src_offset = offset - attr0_offset; /* bytes */ + velement.vertex_buffer_index = attr; + velement.dst_offset = 0; /* need this? */ + velement.src_format = pipe_vertex_format(arrays[mesaAttr]->Type, + arrays[mesaAttr]->Size); + assert(velement.src_format); + } + else { + /* use the default attribute buffer */ + needDefaultAttribs = GL_TRUE; + + vbuffer.buffer = ctx->st->default_attrib_buffer; + vbuffer.buffer_offset = 0; + vbuffer.pitch = 0; /* must be zero! */ + vbuffer.max_index = 1; + + velement.src_offset = mesaAttr * 4 * sizeof(GLfloat); + velement.vertex_buffer_index = attr; + velement.dst_offset = 0; + velement.src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; } if (attr == 0) @@ -252,12 +255,17 @@ st_draw_vbo(GLcontext *ctx, pipe->set_vertex_element(pipe, attr, &velement); } + if (needDefaultAttribs) { + update_default_attribs_buffer(ctx); + } + + /* do actual drawing */ if (ib) { /* indexed primitive */ struct gl_buffer_object *bufobj = ib->obj; struct pipe_buffer_handle *bh = NULL; - unsigned indexSize; + unsigned indexSize, i; if (bufobj && bufobj->Name) { /* elements/indexes are in a real VBO */ @@ -285,6 +293,7 @@ st_draw_vbo(GLcontext *ctx, } else { /* non-indexed */ + GLuint i; for (i = 0; i < nr_prims; i++) { pipe->draw_arrays(pipe, prims[i].mode, prims[i].start, prims[i].count); } diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index a2f114b1ba..68ceba4d78 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -61,13 +61,20 @@ struct st_fragment_program struct st_vertex_program { - struct gl_vertex_program Base; - GLboolean error; /* If program is malformed for any reason. */ + struct gl_vertex_program Base; /**< The Mesa vertex program */ + GLboolean error; /**< Set if program is malformed for any reason. */ - GLuint id; /* String id, for tracking - * ProgramStringNotify changes. - */ + GLuint id; /**< String id, for tracking ProgramStringNotify changes. */ + + /** maps a Mesa VERT_ATTRIB_x to a packed TGSI input index */ + GLuint input_to_index[MAX_VERTEX_PROGRAM_ATTRIBS]; + /** maps a TGSI input index back to a Mesa VERT_ATTRIB_x */ + GLuint index_to_input[MAX_VERTEX_PROGRAM_ATTRIBS]; + + GLuint output_to_index[MAX_VERTEX_PROGRAM_ATTRIBS]; + GLuint index_to_output[MAX_VERTEX_PROGRAM_ATTRIBS]; + /** The program in TGSI format */ struct tgsi_token tokens[ST_FP_MAX_TOKENS]; GLboolean dirty; |