From a08e348a84f57ed5e8bf5888f1ce13934d2ce8fa Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 9 Dec 2009 19:03:10 +0100 Subject: gallium: first steps to treat edgeflags as regular vertex element The idea here is to eliminate the set_edgeflags() call in pipe_context by treating edgeflags as a regular vertex element. Edgeflags provoke special treatment in hardware, which means we need to label them in some way, in this case we'll be passing them through the vertex shader and labelling the vertex shader output with a new TGSI semantic (TGSI_SEMANTIC_EDGEFLAG). --- src/mesa/state_tracker/st_draw.c | 64 ---------------------------------------- 1 file changed, 64 deletions(-) (limited to 'src/mesa/state_tracker/st_draw.c') diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index e13ae57a0ec..773a3f17cdd 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; - } -} /** @@ -671,10 +619,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]); - pipe->draw_range_elements(pipe, indexBuf, indexSize, min_index, max_index, @@ -683,10 +627,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]); - pipe->draw_elements(pipe, indexBuf, indexSize, prims[i].mode, prims[i].start + indexOffset, prims[i].count); @@ -699,10 +639,6 @@ st_draw_vbo(GLcontext *ctx, /* non-indexed */ GLuint i; for (i = 0; i < nr_prims; i++) { - setup_edgeflags(ctx, prims[i].mode, - prims[i].start, prims[i].count, - arrays[VERT_ATTRIB_EDGEFLAG]); - pipe->draw_arrays(pipe, prims[i].mode, prims[i].start, prims[i].count); } } -- cgit v1.2.3 From 50caff5675888c0063c73fa64b88129db7aa11dd Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Wed, 16 Dec 2009 22:12:16 +0100 Subject: gallium: edgeflags change fixes use correct number of vertex inputs fix not running pipeline in case of edgeflags changes to mesa to tgsi translation still very broken --- src/gallium/auxiliary/draw/draw_pt_post_vs.c | 11 +++++--- src/gallium/auxiliary/tgsi/tgsi_dump.c | 3 ++- src/mesa/state_tracker/st_draw.c | 38 ++++++++++++++++------------ src/mesa/state_tracker/st_program.c | 8 +++++- src/mesa/state_tracker/st_program.h | 3 +++ 5 files changed, 41 insertions(+), 22 deletions(-) (limited to 'src/mesa/state_tracker/st_draw.c') diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c index 08d77649a36..9dfb47837e0 100644 --- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c +++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c @@ -156,8 +156,9 @@ post_vs_cliptest_viewport_gl_edgeflag(struct pt_post_vs *pvs, unsigned stride ) { unsigned j; - if (!post_vs_cliptest_viewport_gl( pvs, vertices, count, stride)) - return FALSE; + boolean needpipe; + + needpipe = post_vs_cliptest_viewport_gl( pvs, vertices, count, stride); /* If present, copy edgeflag VS output into vertex header. * Otherwise, leave header as is. @@ -168,10 +169,12 @@ post_vs_cliptest_viewport_gl_edgeflag(struct pt_post_vs *pvs, for (j = 0; j < count; j++) { const float *edgeflag = out->data[ef]; - out->edgeflag = (edgeflag[0] != 1.0f); + out->edgeflag = !(edgeflag[0] != 1.0f); + needpipe |= !out->edgeflag; + out = (struct vertex_header *)( (char *)out + stride ); } } - return TRUE; + return needpipe; } diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c index d09ab925656..d3a5da4b2b0 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c @@ -120,7 +120,8 @@ static const char *semantic_names[] = "PSIZE", "GENERIC", "NORMAL", - "FACE" + "FACE", + "EDGEFLAG" }; static const char *immediate_type_names[] = diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 773a3f17cdd..6b0007a824e 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -227,6 +227,7 @@ st_pipe_vertex_format(GLenum type, GLuint size, GLenum format, */ 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) { @@ -236,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 */ @@ -269,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; @@ -281,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; @@ -321,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, @@ -331,7 +334,7 @@ setup_interleaved_attribs(GLcontext *ctx, GLuint attr; const GLubyte *offset0; - 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); @@ -342,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; @@ -383,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, @@ -392,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; @@ -503,6 +507,7 @@ 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; @@ -521,7 +526,8 @@ st_draw_vbo(GLcontext *ctx, /* 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) { @@ -534,21 +540,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 diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 24f2387429e..45ab8504ae5 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -113,6 +113,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. */ @@ -199,6 +202,8 @@ st_translate_vertex_program(struct st_context *st, if (ureg == NULL) return NULL; + vpv->num_inputs = stvp->num_inputs; + error = st_translate_mesa_program(st->ctx, TGSI_PROCESSOR_VERTEX, @@ -224,7 +229,8 @@ st_translate_vertex_program(struct st_context *st, if (key->passthrough_edgeflags) { ureg_MOV( ureg, ureg_DECL_output( ureg, TGSI_SEMANTIC_EDGEFLAG, 0 ), - ureg_DECL_next_vs_input(ureg)); + ureg_DECL_vs_input( ureg, vpv->num_inputs )); + vpv->num_inputs++; } vpv->state.tokens = ureg_get_tokens( ureg, NULL ); diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index 91392785e55..6b9a9226df5 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -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; }; -- cgit v1.2.3 From 420ff89067515a74c9625a103cadc267d5f64bd4 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Sat, 19 Dec 2009 20:25:43 +0100 Subject: gallium: don't use edgeflags if the app didn't supply them --- src/mesa/state_tracker/st_atom_shader.c | 10 ++++++---- src/mesa/state_tracker/st_context.h | 2 ++ src/mesa/state_tracker/st_draw.c | 8 ++++++++ 3 files changed, 16 insertions(+), 4 deletions(-) (limited to 'src/mesa/state_tracker/st_draw.c') diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c index c2cb72e56ad..46c8cbb3098 100644 --- a/src/mesa/state_tracker/st_atom_shader.c +++ b/src/mesa/state_tracker/st_atom_shader.c @@ -112,10 +112,12 @@ find_translated_vp(struct st_context *st, * 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->ctx->Polygon.FrontMode != GL_FILL || - st->ctx->Polygon.BackMode != GL_FILL); - + 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? @@ -228,7 +230,7 @@ const struct st_tracked_state st_update_vp = { "st_update_vp", /* name */ { /* dirty */ _NEW_POLYGON, /* mesa */ - ST_NEW_VERTEX_PROGRAM /* st */ + 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 6b0007a824e..2d287ef4ef5 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -514,6 +514,7 @@ st_draw_vbo(GLcontext *ctx, struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS]; unsigned num_vbuffers, num_velements; GLboolean userSpace; + GLboolean vertDataEdgeFlags; /* Gallium probably doesn't want this in some cases. */ if (!index_bounds_valid) @@ -522,6 +523,13 @@ 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! */ -- cgit v1.2.3