diff options
author | Roland Scheidegger <[email protected]> | 2009-12-22 20:54:26 +0100 |
---|---|---|
committer | Roland Scheidegger <[email protected]> | 2009-12-22 20:54:26 +0100 |
commit | 35e8283c69d80debb44b05ea79dc5f67303a7432 (patch) | |
tree | aacfe7f201094793c3d29ec0ddcc71cb01f7476c /src/mesa | |
parent | 00b463fc30b30911797c5d5eaaeae79b7a36589b (diff) | |
parent | 420ff89067515a74c9625a103cadc267d5f64bd4 (diff) |
Merge branch 'gallium-edgeflags'
Conflicts:
src/mesa/state_tracker/st_draw.c
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/state_tracker/st_atom_shader.c | 17 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_context.h | 2 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_draw.c | 110 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_mesa_to_tgsi.c | 39 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_mesa_to_tgsi.h | 7 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_program.c | 62 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_program.h | 5 |
7 files changed, 130 insertions, 112 deletions
diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c index 09baff875bc..46c8cbb3098 100644 --- a/src/mesa/state_tracker/st_atom_shader.c +++ b/src/mesa/state_tracker/st_atom_shader.c @@ -106,7 +106,18 @@ find_translated_vp(struct st_context *st, /* Nothing in our key yet. This will change: */ memset(&key, 0, sizeof key); - key.dummy = 0; + + /* When this is true, we will add an extra input to the vertex + * shader translation (for edgeflags), an extra output with + * edgeflag semantics, and extend the vertex shader to pass through + * the input to the output. We'll need to use similar logic to set + * up the extra vertex_element input for edgeflags. + * _NEW_POLYGON, ST_NEW_EDGEFLAGS_DATA + */ + key.passthrough_edgeflags = (st->vertdata_edgeflags && ( + st->ctx->Polygon.FrontMode != GL_FILL || + st->ctx->Polygon.BackMode != GL_FILL)); + /* Do we need to throw away old translations after a change in the * GL program string? @@ -218,8 +229,8 @@ update_vp( struct st_context *st ) const struct st_tracked_state st_update_vp = { "st_update_vp", /* name */ { /* dirty */ - 0, /* mesa */ - ST_NEW_VERTEX_PROGRAM /* st */ + _NEW_POLYGON, /* mesa */ + ST_NEW_VERTEX_PROGRAM | ST_NEW_EDGEFLAGS_DATA /* st */ }, update_vp /* update */ }; diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index b7607286583..831909a3f8f 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -55,6 +55,7 @@ struct bitmap_cache; #define ST_NEW_FRAGMENT_PROGRAM 0x2 #define ST_NEW_VERTEX_PROGRAM 0x4 #define ST_NEW_FRAMEBUFFER 0x8 +#define ST_NEW_EDGEFLAGS_DATA 0x10 struct st_state_flags { @@ -120,6 +121,7 @@ struct st_context struct st_state_flags dirty; GLboolean missing_textures; + GLboolean vertdata_edgeflags; /** Mapping from VERT_RESULT_x to post-transformed vertex slot */ const GLuint *vertex_result_to_slot; diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index ec8092d7e9e..e54f21be600 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -217,59 +217,7 @@ st_pipe_vertex_format(GLenum type, GLuint size, GLenum format, } -/* - * If edge flags are needed, setup an bitvector of flags and call - * pipe->set_edgeflags(). - * XXX memleak: need to free the returned pointer at some point - */ -static void * -setup_edgeflags(GLcontext *ctx, GLenum primMode, GLint start, GLint count, - const struct gl_client_array *array) -{ - struct pipe_context *pipe = ctx->st->pipe; - - if ((primMode == GL_TRIANGLES || - primMode == GL_QUADS || - primMode == GL_POLYGON) && - (ctx->Polygon.FrontMode != GL_FILL || - ctx->Polygon.BackMode != GL_FILL)) { - /* need edge flags */ - GLint i; - unsigned *vec; - struct st_buffer_object *stobj = st_buffer_object(array->BufferObj); - ubyte *map; - - if (!stobj || stobj->Base.Name == 0) { - /* edge flags are not in a VBO */ - return NULL; - } - - vec = (unsigned *) _mesa_calloc(sizeof(unsigned) * ((count + 31) / 32)); - if (!vec) - return NULL; - - map = pipe_buffer_map(pipe->screen, stobj->buffer, PIPE_BUFFER_USAGE_CPU_READ); - map = ADD_POINTERS(map, array->Ptr); - - for (i = 0; i < count; i++) { - if (*((float *) map)) - vec[i/32] |= 1 << (i % 32); - - map += array->StrideB; - } - pipe_buffer_unmap(pipe->screen, stobj->buffer); - - pipe->set_edgeflags(pipe, vec); - - return vec; - } - else { - /* edge flags not needed */ - pipe->set_edgeflags(pipe, NULL); - return NULL; - } -} /** @@ -279,6 +227,7 @@ setup_edgeflags(GLcontext *ctx, GLenum primMode, GLint start, GLint count, */ static GLboolean is_interleaved_arrays(const struct st_vertex_program *vp, + const struct st_vp_varient *vpv, const struct gl_client_array **arrays, GLboolean *userSpace) { @@ -288,7 +237,7 @@ is_interleaved_arrays(const struct st_vertex_program *vp, GLuint num_client_arrays = 0; const GLubyte *client_addr = NULL; - for (attr = 0; attr < vp->num_inputs; attr++) { + for (attr = 0; attr < vpv->num_inputs; attr++) { const GLuint mesaAttr = vp->index_to_input[attr]; const struct gl_buffer_object *bufObj = arrays[mesaAttr]->BufferObj; const GLsizei stride = arrays[mesaAttr]->StrideB; /* in bytes */ @@ -321,7 +270,7 @@ is_interleaved_arrays(const struct st_vertex_program *vp, } } - *userSpace = (num_client_arrays == vp->num_inputs); + *userSpace = (num_client_arrays == vpv->num_inputs); /* printf("user space: %d (%d %d)\n", (int) *userSpace,num_client_arrays,vp->num_inputs); */ return GL_TRUE; @@ -333,15 +282,16 @@ is_interleaved_arrays(const struct st_vertex_program *vp, */ static void get_arrays_bounds(const struct st_vertex_program *vp, - const struct gl_client_array **arrays, - GLuint max_index, - const GLubyte **low, const GLubyte **high) + const struct st_vp_varient *vpv, + const struct gl_client_array **arrays, + GLuint max_index, + const GLubyte **low, const GLubyte **high) { const GLubyte *low_addr = NULL; const GLubyte *high_addr = NULL; GLuint attr; - for (attr = 0; attr < vp->num_inputs; attr++) { + for (attr = 0; attr < vpv->num_inputs; attr++) { const GLuint mesaAttr = vp->index_to_input[attr]; const GLint stride = arrays[mesaAttr]->StrideB; const GLubyte *start = arrays[mesaAttr]->Ptr; @@ -373,6 +323,7 @@ get_arrays_bounds(const struct st_vertex_program *vp, static void setup_interleaved_attribs(GLcontext *ctx, const struct st_vertex_program *vp, + const struct st_vp_varient *vpv, const struct gl_client_array **arrays, GLuint max_index, GLboolean userSpace, @@ -383,7 +334,7 @@ setup_interleaved_attribs(GLcontext *ctx, GLuint attr; const GLubyte *offset0 = NULL; - for (attr = 0; attr < vp->num_inputs; attr++) { + for (attr = 0; attr < vpv->num_inputs; attr++) { const GLuint mesaAttr = vp->index_to_input[attr]; struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj; struct st_buffer_object *stobj = st_buffer_object(bufobj); @@ -394,7 +345,7 @@ setup_interleaved_attribs(GLcontext *ctx, if (attr == 0) { const GLubyte *low, *high; - get_arrays_bounds(vp, arrays, max_index, &low, &high); + get_arrays_bounds(vp, vpv, arrays, max_index, &low, &high); /*printf("buffer range: %p %p %d\n", low, high, high-low);*/ offset0 = low; @@ -435,6 +386,7 @@ setup_interleaved_attribs(GLcontext *ctx, static void setup_non_interleaved_attribs(GLcontext *ctx, const struct st_vertex_program *vp, + const struct st_vp_varient *vpv, const struct gl_client_array **arrays, GLuint max_index, GLboolean *userSpace, @@ -444,7 +396,7 @@ setup_non_interleaved_attribs(GLcontext *ctx, struct pipe_context *pipe = ctx->st->pipe; GLuint attr; - for (attr = 0; attr < vp->num_inputs; attr++) { + for (attr = 0; attr < vpv->num_inputs; attr++) { const GLuint mesaAttr = vp->index_to_input[attr]; struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj; GLsizei stride = arrays[mesaAttr]->StrideB; @@ -569,12 +521,14 @@ st_draw_vbo(GLcontext *ctx, { struct pipe_context *pipe = ctx->st->pipe; const struct st_vertex_program *vp; + const struct st_vp_varient *vpv; const struct pipe_shader_state *vs; struct pipe_vertex_buffer vbuffer[PIPE_MAX_SHADER_INPUTS]; GLuint attr; struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS]; unsigned num_vbuffers, num_velements; GLboolean userSpace = GL_FALSE; + GLboolean vertDataEdgeFlags; /* Gallium probably doesn't want this in some cases. */ if (!index_bounds_valid) @@ -584,11 +538,19 @@ st_draw_vbo(GLcontext *ctx, /* sanity check for pointer arithmetic below */ assert(sizeof(arrays[0]->Ptr[0]) == 1); + vertDataEdgeFlags = arrays[VERT_ATTRIB_EDGEFLAG]->BufferObj && + arrays[VERT_ATTRIB_EDGEFLAG]->BufferObj->Name; + if (vertDataEdgeFlags != ctx->st->vertdata_edgeflags) { + ctx->st->vertdata_edgeflags = vertDataEdgeFlags; + ctx->st->dirty.st |= ST_NEW_EDGEFLAGS_DATA; + } + st_validate_state(ctx->st); /* must get these after state validation! */ vp = ctx->st->vp; - vs = &ctx->st->vp_varient->state; + vpv = ctx->st->vp_varient; + vs = &vpv->state; #if 0 if (MESA_VERBOSE & VERBOSE_GLSL) { @@ -601,21 +563,21 @@ st_draw_vbo(GLcontext *ctx, /* * Setup the vbuffer[] and velements[] arrays. */ - if (is_interleaved_arrays(vp, arrays, &userSpace)) { + if (is_interleaved_arrays(vp, vpv, arrays, &userSpace)) { /*printf("Draw interleaved\n");*/ - setup_interleaved_attribs(ctx, vp, arrays, max_index, userSpace, + setup_interleaved_attribs(ctx, vp, vpv, arrays, max_index, userSpace, vbuffer, velements); num_vbuffers = 1; - num_velements = vp->num_inputs; + num_velements = vpv->num_inputs; if (num_velements == 0) num_vbuffers = 0; } else { /*printf("Draw non-interleaved\n");*/ - setup_non_interleaved_attribs(ctx, vp, arrays, max_index, + setup_non_interleaved_attribs(ctx, vp, vpv, arrays, max_index, &userSpace, vbuffer, velements); - num_vbuffers = vp->num_inputs; - num_velements = vp->num_inputs; + num_vbuffers = vpv->num_inputs; + num_velements = vpv->num_inputs; } #if 0 @@ -687,10 +649,6 @@ st_draw_vbo(GLcontext *ctx, * through to driver & draw module. These interfaces still * need a bit of work... */ - setup_edgeflags(ctx, prims[i].mode, - prims[i].start + indexOffset, prims[i].count, - arrays[VERT_ATTRIB_EDGEFLAG]); - prim = translate_prim( ctx, prims[i].mode ); pipe->draw_range_elements(pipe, indexBuf, indexSize, @@ -701,10 +659,6 @@ st_draw_vbo(GLcontext *ctx, } else { for (i = 0; i < nr_prims; i++) { - setup_edgeflags(ctx, prims[i].mode, - prims[i].start + indexOffset, prims[i].count, - arrays[VERT_ATTRIB_EDGEFLAG]); - prim = translate_prim( ctx, prims[i].mode ); pipe->draw_elements(pipe, indexBuf, indexSize, @@ -721,10 +675,6 @@ st_draw_vbo(GLcontext *ctx, GLuint prim; for (i = 0; i < nr_prims; i++) { - setup_edgeflags(ctx, prims[i].mode, - prims[i].start, prims[i].count, - arrays[VERT_ATTRIB_EDGEFLAG]); - prim = translate_prim( ctx, prims[i].mode ); pipe->draw_arrays(pipe, prim, prims[i].start, prims[i].count); diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c index 1611d53e2fe..5c9be46a776 100644 --- a/src/mesa/state_tracker/st_mesa_to_tgsi.c +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c @@ -718,6 +718,16 @@ emit_face_var( struct st_translate *t, t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]] = ureg_src(face_temp); } +static void +emit_edgeflags( struct st_translate *t, + const struct gl_program *program ) +{ + struct ureg_program *ureg = t->ureg; + struct ureg_dst edge_dst = t->outputs[t->outputMapping[VERT_RESULT_EDGE]]; + struct ureg_src edge_src = t->inputs[t->inputMapping[VERT_ATTRIB_EDGEFLAG]]; + + ureg_MOV( ureg, edge_dst, edge_src ); +} /** * Translate Mesa program to TGSI format. @@ -738,10 +748,11 @@ emit_face_var( struct st_translate *t, * * \return array of translated tokens, caller's responsibility to free */ -const struct tgsi_token * +enum pipe_error st_translate_mesa_program( GLcontext *ctx, uint procType, + struct ureg_program *ureg, const struct gl_program *program, GLuint numInputs, const GLuint inputMapping[], @@ -751,11 +762,10 @@ st_translate_mesa_program( GLuint numOutputs, const GLuint outputMapping[], const ubyte outputSemanticName[], - const ubyte outputSemanticIndex[] ) + const ubyte outputSemanticIndex[], + boolean passthrough_edgeflags ) { struct st_translate translate, *t; - struct ureg_program *ureg; - const struct tgsi_token *tokens = NULL; unsigned i; t = &translate; @@ -764,11 +774,7 @@ st_translate_mesa_program( t->procType = procType; t->inputMapping = inputMapping; t->outputMapping = outputMapping; - t->ureg = ureg_create( procType ); - if (t->ureg == NULL) - return NULL; - - ureg = t->ureg; + t->ureg = ureg; /*_mesa_print_program(program);*/ @@ -828,6 +834,8 @@ st_translate_mesa_program( outputSemanticName[i], outputSemanticIndex[i] ); } + if (passthrough_edgeflags) + emit_edgeflags( t, program ); } /* Declare address register. @@ -899,8 +907,7 @@ st_translate_mesa_program( t->insn[t->labels[i].branch_target] ); } - tokens = ureg_get_tokens( ureg, NULL ); - ureg_destroy( ureg ); + return PIPE_OK; out: FREE(t->insn); @@ -909,17 +916,9 @@ out: if (t->error) { debug_printf("%s: translate error flag set\n", __FUNCTION__); - FREE((void *)tokens); - tokens = NULL; - } - - if (!tokens) { - debug_printf("%s: failed to translate Mesa program:\n", __FUNCTION__); - _mesa_print_program(program); - debug_assert(0); } - return tokens; + return PIPE_ERROR_OUT_OF_MEMORY; } diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.h b/src/mesa/state_tracker/st_mesa_to_tgsi.h index dc0362fe790..e3c5bd1d94d 100644 --- a/src/mesa/state_tracker/st_mesa_to_tgsi.h +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.h @@ -30,6 +30,7 @@ #define ST_MESA_TO_TGSI_H #include "main/mtypes.h" +#include "tgsi/tgsi_ureg.h" #if defined __cplusplus @@ -39,10 +40,11 @@ extern "C" { struct tgsi_token; struct gl_program; -const struct tgsi_token * +enum pipe_error st_translate_mesa_program( GLcontext *ctx, uint procType, + struct ureg_program *ureg, const struct gl_program *program, GLuint numInputs, const GLuint inputMapping[], @@ -52,7 +54,8 @@ st_translate_mesa_program( GLuint numOutputs, const GLuint outputMapping[], const ubyte outputSemanticName[], - const ubyte outputSemanticIndex[] ); + const ubyte outputSemanticIndex[], + boolean passthrough_edgeflags ); void st_free_tokens(const struct tgsi_token *tokens); diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index d91ed6806dc..6a869fae904 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -115,6 +115,9 @@ st_prepare_vertex_program(struct st_context *st, stvp->num_inputs++; } } + /* bit of a hack, presetup potentially unused edgeflag input */ + stvp->input_to_index[VERT_ATTRIB_EDGEFLAG] = stvp->num_inputs; + stvp->index_to_input[stvp->num_inputs] = VERT_ATTRIB_EDGEFLAG; /* Compute mapping of vertex program outputs to slots. */ @@ -184,6 +187,10 @@ st_prepare_vertex_program(struct st_context *st, } } } + /* similar hack to above, presetup potentially unused edgeflag output */ + stvp->result_to_output[VERT_RESULT_EDGE] = stvp->num_outputs; + stvp->output_semantic_name[stvp->num_outputs] = TGSI_SEMANTIC_EDGEFLAG; + stvp->output_semantic_index[stvp->num_outputs] = 0; } @@ -194,22 +201,47 @@ st_translate_vertex_program(struct st_context *st, { struct st_vp_varient *vpv = CALLOC_STRUCT(st_vp_varient); struct pipe_context *pipe = st->pipe; + struct ureg_program *ureg; + enum pipe_error error; + unsigned num_outputs; + + ureg = ureg_create( TGSI_PROCESSOR_VERTEX ); + if (ureg == NULL) + return NULL; + + vpv->num_inputs = stvp->num_inputs; + num_outputs = stvp->num_outputs; + if (key->passthrough_edgeflags) { + vpv->num_inputs++; + num_outputs++; + } - vpv->state.tokens = + error = st_translate_mesa_program(st->ctx, TGSI_PROCESSOR_VERTEX, + ureg, &stvp->Base.Base, /* inputs */ - stvp->num_inputs, + vpv->num_inputs, stvp->input_to_index, NULL, /* input semantic name */ NULL, /* input semantic index */ NULL, /* outputs */ - stvp->num_outputs, + num_outputs, stvp->result_to_output, stvp->output_semantic_name, - stvp->output_semantic_index ); + stvp->output_semantic_index, + key->passthrough_edgeflags ); + + if (error) + goto fail; + + vpv->state.tokens = ureg_get_tokens( ureg, NULL ); + if (!vpv->state.tokens) + goto fail; + + ureg_destroy( ureg ); vpv->driver_shader = pipe->create_vs_state(pipe, &vpv->state); @@ -224,6 +256,14 @@ st_translate_vertex_program(struct st_context *st, } return vpv; + +fail: + debug_printf("%s: failed to translate Mesa program:\n", __FUNCTION__); + _mesa_print_program(&stvp->Base.Base); + debug_assert(0); + + ureg_destroy( ureg ); + return NULL; } @@ -244,7 +284,9 @@ st_translate_fragment_program(struct st_context *st, GLuint defaultInputMapping[FRAG_ATTRIB_MAX]; GLuint interpMode[16]; /* XXX size? */ GLuint attr; + enum pipe_error error; const GLbitfield inputsRead = stfp->Base.Base.InputsRead; + struct ureg_program *ureg; GLuint vslot = 0; uint fs_num_inputs = 0; @@ -379,9 +421,15 @@ st_translate_fragment_program(struct st_context *st, if (!inputMapping) inputMapping = defaultInputMapping; - stfp->state.tokens = + ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); + if (ureg == NULL) + return; + + + error = st_translate_mesa_program(st->ctx, TGSI_PROCESSOR_FRAGMENT, + ureg, &stfp->Base.Base, /* inputs */ fs_num_inputs, @@ -393,8 +441,10 @@ st_translate_fragment_program(struct st_context *st, fs_num_outputs, outputMapping, fs_output_semantic_name, - fs_output_semantic_index ); + fs_output_semantic_index, FALSE ); + stfp->state.tokens = ureg_get_tokens( ureg, NULL ); + ureg_destroy( ureg ); stfp->driver_shader = pipe->create_fs_state(pipe, &stfp->state); if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) { diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index 88aadbd7510..6b9a9226df5 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -73,7 +73,7 @@ struct st_fragment_program struct st_vp_varient_key { - char dummy; /* currently unused */ + boolean passthrough_edgeflags; }; @@ -100,6 +100,9 @@ struct st_vp_varient /** Next in linked list */ struct st_vp_varient *next; + + /** similar to that in st_vertex_program, but with information about edgeflags too */ + GLuint num_inputs; }; |