X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fmesa%2Fstate_tracker%2Fst_draw.c;h=7f45e3f5484c2832808e4c7491df4ecd99ccf4f6;hb=275c4bd3643d773210780cb8d578ca84f2604684;hp=68bc76b572397ce0a758673f6613af113446b23d;hpb=650e02003fbb5511ec758d993b7ec0a302ee2235;p=mesa.git diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 68bc76b5723..7f45e3f5484 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -55,7 +55,9 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" +#include "util/u_format.h" +#include "cso_cache/cso_context.h" static GLuint double_types[4] = { @@ -217,59 +219,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 +229,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 +239,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,8 +272,9 @@ is_interleaved_arrays(const struct st_vertex_program *vp, } } - *userSpace = (num_client_arrays == vp->num_inputs); - /* printf("user space: %d (%d %d)\n", (int) *userSpace,num_client_arrays,vp->num_inputs); */ + *userSpace = (num_client_arrays == vpv->num_inputs); + /* debug_printf("user space: %s (%d arrays, %d inputs)\n", + (int)*userSpace ? "Yes" : "No", num_client_arrays, vp->num_inputs); */ return GL_TRUE; } @@ -333,15 +285,18 @@ 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++) { + /* debug_printf("get_arrays_bounds: Handling %u attrs\n", vpv->num_inputs); */ + + 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; @@ -349,6 +304,9 @@ get_arrays_bounds(const struct st_vertex_program *vp, _mesa_sizeof_type(arrays[mesaAttr]->Type)); const GLubyte *end = start + (max_index * stride) + sz; + /* debug_printf("attr %u: stride %d size %u start %p end %p\n", + attr, stride, sz, start, end); */ + if (attr == 0) { low_addr = start; high_addr = end; @@ -373,6 +331,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, @@ -381,9 +340,9 @@ setup_interleaved_attribs(GLcontext *ctx, { struct pipe_context *pipe = ctx->st->pipe; GLuint attr; - const GLubyte *offset0; + 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,8 +353,9 @@ setup_interleaved_attribs(GLcontext *ctx, if (attr == 0) { const GLubyte *low, *high; - get_arrays_bounds(vp, arrays, max_index, &low, &high); - /*printf("buffer range: %p %p %d\n", low, high, high-low);*/ + get_arrays_bounds(vp, vpv, arrays, max_index, &low, &high); + /* debug_printf("buffer range: %p %p range %d max index %u\n", + low, high, high - low, max_index); */ offset0 = low; if (userSpace) { @@ -414,8 +374,8 @@ setup_interleaved_attribs(GLcontext *ctx, velements[attr].src_offset = (unsigned) (arrays[mesaAttr]->Ptr - offset0); + velements[attr].instance_divisor = 0; velements[attr].vertex_buffer_index = 0; - velements[attr].nr_components = arrays[mesaAttr]->Size; velements[attr].src_format = st_pipe_vertex_format(arrays[mesaAttr]->Type, arrays[mesaAttr]->Size, @@ -435,6 +395,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 +405,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; @@ -502,8 +463,8 @@ setup_non_interleaved_attribs(GLcontext *ctx, /* common-case setup */ vbuffer[attr].stride = stride; /* in bytes */ vbuffer[attr].max_index = max_index; + velements[attr].instance_divisor = 0; velements[attr].vertex_buffer_index = attr; - velements[attr].nr_components = arrays[mesaAttr]->Size; velements[attr].src_format = st_pipe_vertex_format(arrays[mesaAttr]->Type, arrays[mesaAttr]->Size, @@ -538,6 +499,20 @@ check_uniforms(GLcontext *ctx) } +static unsigned translate_prim( GLcontext *ctx, + unsigned prim ) +{ + /* Avoid quadstrips if it's easy to do so: + */ + if (prim == GL_QUAD_STRIP && + ctx->Light.ShadeModel != GL_FLAT && + ctx->Polygon.FrontMode == GL_FILL && + ctx->Polygon.BackMode == GL_FILL) + prim = GL_TRIANGLE_STRIP; + + return prim; +} + /** * This function gets plugged into the VBO module and is called when * we have something to render. @@ -555,25 +530,37 @@ st_draw_vbo(GLcontext *ctx, { struct pipe_context *pipe = ctx->st->pipe; const struct st_vertex_program *vp; - const struct pipe_shader_state *vs; + const struct st_vp_varient *vpv; 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; + GLboolean userSpace = GL_FALSE; + GLboolean vertDataEdgeFlags; + + /* Mesa core state should have been validated already */ + assert(ctx->NewState == 0x0); /* Gallium probably doesn't want this in some cases. */ if (!index_bounds_valid) - vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index); + if (!vbo_all_varyings_in_vbos(arrays)) + vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index); /* 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->state; + vpv = ctx->st->vp_varient; #if 0 if (MESA_VERBOSE & VERBOSE_GLSL) { @@ -583,24 +570,25 @@ st_draw_vbo(GLcontext *ctx, (void) check_uniforms; #endif + memset(velements, 0, sizeof(struct pipe_vertex_element) * vpv->num_inputs); /* * 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 @@ -615,14 +603,13 @@ st_draw_vbo(GLcontext *ctx, for (i = 0; i < num_velements; i++) { printf("vlements[%d].vbuffer_index = %u\n", i, velements[i].vertex_buffer_index); printf("vlements[%d].src_offset = %u\n", i, velements[i].src_offset); - printf("vlements[%d].nr_comps = %u\n", i, velements[i].nr_components); - printf("vlements[%d].format = %s\n", i, pf_name(velements[i].src_format)); + printf("vlements[%d].format = %s\n", i, util_format_name(velements[i].src_format)); } } #endif pipe->set_vertex_buffers(pipe, num_vbuffers, vbuffer); - pipe->set_vertex_elements(pipe, num_velements, velements); + cso_set_vertex_elements(ctx->st->cso_context, num_velements, velements); if (num_vbuffers == 0 || num_velements == 0) return; @@ -633,6 +620,7 @@ st_draw_vbo(GLcontext *ctx, struct gl_buffer_object *bufobj = ib->obj; struct pipe_buffer *indexBuf = NULL; unsigned indexSize, indexOffset, i; + unsigned prim; switch (ib->type) { case GL_UNSIGNED_INT: @@ -664,31 +652,25 @@ st_draw_vbo(GLcontext *ctx, } /* draw */ - if (nr_prims == 1 && pipe->draw_range_elements != NULL) { - i = 0; - + if (pipe->draw_range_elements && min_index != ~0 && max_index != ~0) { /* XXX: exercise temporary path to pass min/max directly * 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, - prims[i].mode, - prims[i].start + indexOffset, prims[i].count); + for (i = 0; i < nr_prims; i++) { + prim = translate_prim( ctx, prims[i].mode ); + + pipe->draw_range_elements(pipe, indexBuf, indexSize, + min_index, max_index, prim, + prims[i].start + indexOffset, prims[i].count); + } } 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, - prims[i].mode, + prim, prims[i].start + indexOffset, prims[i].count); } } @@ -698,12 +680,12 @@ st_draw_vbo(GLcontext *ctx, else { /* non-indexed */ GLuint i; + 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, prims[i].mode, prims[i].start, prims[i].count); + pipe->draw_arrays(pipe, prim, prims[i].start, prims[i].count); } }