X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fdraw.c;h=5bb254e00d2621191b064096518ecca22afca963;hb=e630271e0ec3eee7d921d76d3924873f6ee6b59b;hp=aa4934fdb27b75c02ffb8e0fc5fd480241338830;hpb=e636a062f1a555f8795b3e75d6f32c5042038ab1;p=mesa.git diff --git a/src/mesa/main/draw.c b/src/mesa/main/draw.c index aa4934fdb27..5bb254e00d2 100644 --- a/src/mesa/main/draw.c +++ b/src/mesa/main/draw.c @@ -90,7 +90,7 @@ check_array_data(struct gl_context *ctx, struct gl_vertex_array_object *vao, array->Format.Type, array->Format.Size, binding->Stride); printf(" Address/offset %p in Buffer Object %u\n", - array->Ptr, bo->Name); + array->Ptr, bo ? bo->Name : 0); f[k] = 1.0F; /* XXX replace the bad value! */ } /*assert(!IS_INF_OR_NAN(f[k])); */ @@ -104,21 +104,18 @@ check_array_data(struct gl_context *ctx, struct gl_vertex_array_object *vao, } -static inline int -sizeof_ib_type(GLenum type) +static inline void +get_index_size(GLenum type, struct _mesa_index_buffer *ib) { - switch (type) { - case GL_UNSIGNED_INT: - return sizeof(GLuint); - case GL_UNSIGNED_SHORT: - return sizeof(GLushort); - case GL_UNSIGNED_BYTE: - return sizeof(GLubyte); - default: - assert(!"unsupported index data type"); - /* In case assert is turned off */ - return 0; - } + /* The type is already validated, so use a fast conversion. + * + * GL_UNSIGNED_BYTE - GL_UNSIGNED_BYTE = 0 + * GL_UNSIGNED_SHORT - GL_UNSIGNED_BYTE = 2 + * GL_UNSIGNED_INT - GL_UNSIGNED_BYTE = 4 + * + * Divide by 2 to get 0,1,2. + */ + ib->index_size_shift = (type - GL_UNSIGNED_BYTE) >> 1; } /** @@ -258,7 +255,7 @@ print_draw_arrays(struct gl_context *ctx, "ptr %p Bufobj %u\n", gl_vert_attrib_name((gl_vert_attrib) i), array->Format.Size, binding->Stride, - array->Ptr, bufObj->Name); + array->Ptr, bufObj ? bufObj->Name : 0); if (_mesa_is_bufferobj(bufObj)) { GLubyte *p = bufObj->Mappings[MAP_INTERNAL].Pointer; @@ -657,24 +654,30 @@ _mesa_exec_MultiDrawArrays(GLenum mode, const GLint *first, return; } - for (i = 0; i < primcount; i++) { - if (count[i] > 0) { - if (0) - check_draw_arrays_data(ctx, first[i], count[i]); - - /* The GL_ARB_shader_draw_parameters spec adds the following after the - * pseudo-code describing glMultiDrawArrays: - * - * "The index of the draw ( in the above pseudo-code) may be - * read by a vertex shader as , as described in - * Section 11.1.3.9." - */ - _mesa_draw_arrays(ctx, mode, first[i], count[i], 1, 0, i); + if (skip_validated_draw(ctx)) + return; - if (0) - print_draw_arrays(ctx, mode, first[i], count[i]); - } + struct _mesa_prim *prim; + + ALLOC_PRIMS(prim, primcount, "glMultiDrawElements"); + + for (i = 0; i < primcount; i++) { + prim[i].begin = 1; + prim[i].end = 1; + prim[i].mode = mode; + prim[i].draw_id = i; + prim[i].start = first[i]; + prim[i].count = count[i]; + prim[i].basevertex = 0; } + + ctx->Driver.Draw(ctx, prim, primcount, NULL, GL_FALSE, 0, 0, 1, 0, + NULL, 0); + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) + _mesa_flush(ctx); + + FREE_PRIMS(prim, primcount); } @@ -784,9 +787,9 @@ _mesa_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, return; ib.count = count; - ib.index_size = sizeof_ib_type(type); ib.obj = ctx->Array.VAO->IndexBufferObj; ib.ptr = indices; + get_index_size(type, &ib); prim.begin = 1; prim.end = 1; @@ -1180,7 +1183,6 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode, GLsizei primcount, const GLint *basevertex) { struct _mesa_index_buffer ib; - unsigned int index_type_size = sizeof_ib_type(type); uintptr_t min_index_ptr, max_index_ptr; GLboolean fallback = GL_FALSE; int i; @@ -1188,12 +1190,14 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode, if (primcount == 0) return; + get_index_size(type, &ib); + min_index_ptr = (uintptr_t) indices[0]; max_index_ptr = 0; for (i = 0; i < primcount; i++) { min_index_ptr = MIN2(min_index_ptr, (uintptr_t) indices[i]); max_index_ptr = MAX2(max_index_ptr, (uintptr_t) indices[i] + - index_type_size * count[i]); + (count[i] << ib.index_size_shift)); } /* Check if we can handle this thing as a bunch of index offsets from the @@ -1202,39 +1206,44 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode, * Check that the difference between each prim's indexes is a multiple of * the index/element size. */ - if (index_type_size != 1) { + if (ib.index_size_shift) { for (i = 0; i < primcount; i++) { - if ((((uintptr_t) indices[i] - min_index_ptr) % index_type_size) != - 0) { + if ((((uintptr_t) indices[i] - min_index_ptr) & + ((1 << ib.index_size_shift) - 1)) != 0) { fallback = GL_TRUE; break; } } } - /* If the index buffer isn't in a VBO, then treating the application's - * subranges of the index buffer as one large index buffer may lead to - * us reading unmapped memory. - */ - if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) - fallback = GL_TRUE; + if (ctx->Const.MultiDrawWithUserIndices) { + /* Check whether prim[i].start would overflow. */ + if (((max_index_ptr - min_index_ptr) >> ib.index_size_shift) > UINT_MAX) + fallback = GL_TRUE; + } else { + /* If the index buffer isn't in a VBO, then treating the application's + * subranges of the index buffer as one large index buffer may lead to + * us reading unmapped memory. + */ + if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) + fallback = GL_TRUE; + } if (!fallback) { struct _mesa_prim *prim; ALLOC_PRIMS(prim, primcount, "glMultiDrawElements"); - ib.count = (max_index_ptr - min_index_ptr) / index_type_size; - ib.index_size = sizeof_ib_type(type); + ib.count = (max_index_ptr - min_index_ptr) >> ib.index_size_shift; ib.obj = ctx->Array.VAO->IndexBufferObj; ib.ptr = (void *) min_index_ptr; for (i = 0; i < primcount; i++) { - prim[i].begin = (i == 0); - prim[i].end = (i == primcount - 1); + prim[i].begin = 1; + prim[i].end = 1; prim[i].mode = mode; prim[i].start = - ((uintptr_t) indices[i] - min_index_ptr) / index_type_size; + ((uintptr_t) indices[i] - min_index_ptr) >> ib.index_size_shift; prim[i].count = count[i]; prim[i].draw_id = i; if (basevertex != NULL) @@ -1254,7 +1263,6 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode, continue; ib.count = count[i]; - ib.index_size = sizeof_ib_type(type); ib.obj = ctx->Array.VAO->IndexBufferObj; ib.ptr = indices[i]; @@ -1465,54 +1473,19 @@ _mesa_exec_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name, static void -_mesa_validated_drawarraysindirect(struct gl_context *ctx, - GLenum mode, const GLvoid *indirect) -{ - ctx->Driver.DrawIndirect(ctx, mode, - ctx->DrawIndirectBuffer, (GLsizeiptr) indirect, - 1 /* draw_count */ , 16 /* stride */ , - NULL, 0, NULL); - - if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) - _mesa_flush(ctx); -} - - -static void -_mesa_validated_multidrawarraysindirect(struct gl_context *ctx, - GLenum mode, - const GLvoid *indirect, - GLsizei primcount, GLsizei stride) +_mesa_validated_multidrawarraysindirect(struct gl_context *ctx, GLenum mode, + GLintptr indirect, + GLintptr drawcount_offset, + GLsizei drawcount, GLsizei stride, + struct gl_buffer_object *drawcount_buffer) { - GLsizeiptr offset = (GLsizeiptr) indirect; - - if (primcount == 0) + /* If drawcount_buffer is set, drawcount is the maximum draw count.*/ + if (drawcount == 0) return; - ctx->Driver.DrawIndirect(ctx, mode, ctx->DrawIndirectBuffer, offset, - primcount, stride, NULL, 0, NULL); - - if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) - _mesa_flush(ctx); -} - - -static void -_mesa_validated_drawelementsindirect(struct gl_context *ctx, - GLenum mode, GLenum type, - const GLvoid *indirect) -{ - struct _mesa_index_buffer ib; - - ib.count = 0; /* unknown */ - ib.index_size = sizeof_ib_type(type); - ib.obj = ctx->Array.VAO->IndexBufferObj; - ib.ptr = NULL; - - ctx->Driver.DrawIndirect(ctx, mode, - ctx->DrawIndirectBuffer, (GLsizeiptr) indirect, - 1 /* draw_count */ , 20 /* stride */ , - NULL, 0, &ib); + ctx->Driver.DrawIndirect(ctx, mode, ctx->DrawIndirectBuffer, indirect, + drawcount, stride, drawcount_buffer, + drawcount_offset, NULL); if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) _mesa_flush(ctx); @@ -1522,25 +1495,25 @@ _mesa_validated_drawelementsindirect(struct gl_context *ctx, static void _mesa_validated_multidrawelementsindirect(struct gl_context *ctx, GLenum mode, GLenum type, - const GLvoid *indirect, - GLsizei primcount, GLsizei stride) + GLintptr indirect, + GLintptr drawcount_offset, + GLsizei drawcount, GLsizei stride, + struct gl_buffer_object *drawcount_buffer) { - struct _mesa_index_buffer ib; - GLsizeiptr offset = (GLsizeiptr) indirect; - - if (primcount == 0) + /* If drawcount_buffer is set, drawcount is the maximum draw count.*/ + if (drawcount == 0) return; /* NOTE: IndexBufferObj is guaranteed to be a VBO. */ - + struct _mesa_index_buffer ib; ib.count = 0; /* unknown */ - ib.index_size = sizeof_ib_type(type); ib.obj = ctx->Array.VAO->IndexBufferObj; ib.ptr = NULL; + get_index_size(type, &ib); - ctx->Driver.DrawIndirect(ctx, mode, - ctx->DrawIndirectBuffer, offset, - primcount, stride, NULL, 0, &ib); + ctx->Driver.DrawIndirect(ctx, mode, ctx->DrawIndirectBuffer, indirect, + drawcount, stride, drawcount_buffer, + drawcount_offset, &ib); if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) _mesa_flush(ctx); @@ -1592,7 +1565,8 @@ _mesa_exec_DrawArraysIndirect(GLenum mode, const GLvoid *indirect) if (skip_validated_draw(ctx)) return; - _mesa_validated_drawarraysindirect(ctx, mode, indirect); + _mesa_validated_multidrawarraysindirect(ctx, mode, (GLintptr)indirect, + 0, 1, 16, NULL); } @@ -1658,7 +1632,9 @@ _mesa_exec_DrawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect if (skip_validated_draw(ctx)) return; - _mesa_validated_drawelementsindirect(ctx, mode, type, indirect); + _mesa_validated_multidrawelementsindirect(ctx, mode, type, + (GLintptr)indirect, 0, + 1, 20, NULL); } @@ -1723,8 +1699,8 @@ _mesa_exec_MultiDrawArraysIndirect(GLenum mode, const GLvoid *indirect, if (skip_validated_draw(ctx)) return; - _mesa_validated_multidrawarraysindirect(ctx, mode, indirect, - primcount, stride); + _mesa_validated_multidrawarraysindirect(ctx, mode, (GLintptr)indirect, 0, + primcount, stride, NULL); } @@ -1802,62 +1778,9 @@ _mesa_exec_MultiDrawElementsIndirect(GLenum mode, GLenum type, if (skip_validated_draw(ctx)) return; - _mesa_validated_multidrawelementsindirect(ctx, mode, type, indirect, - primcount, stride); -} - - -static void -_mesa_validated_multidrawarraysindirectcount(struct gl_context *ctx, - GLenum mode, - GLintptr indirect, - GLintptr drawcount_offset, - GLsizei maxdrawcount, - GLsizei stride) -{ - GLsizeiptr offset = indirect; - - if (maxdrawcount == 0) - return; - - ctx->Driver.DrawIndirect(ctx, mode, - ctx->DrawIndirectBuffer, offset, - maxdrawcount, stride, - ctx->ParameterBuffer, drawcount_offset, NULL); - - if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) - _mesa_flush(ctx); -} - - -static void -_mesa_validated_multidrawelementsindirectcount(struct gl_context *ctx, - GLenum mode, GLenum type, - GLintptr indirect, - GLintptr drawcount_offset, - GLsizei maxdrawcount, - GLsizei stride) -{ - struct _mesa_index_buffer ib; - GLsizeiptr offset = (GLsizeiptr) indirect; - - if (maxdrawcount == 0) - return; - - /* NOTE: IndexBufferObj is guaranteed to be a VBO. */ - - ib.count = 0; /* unknown */ - ib.index_size = sizeof_ib_type(type); - ib.obj = ctx->Array.VAO->IndexBufferObj; - ib.ptr = NULL; - - ctx->Driver.DrawIndirect(ctx, mode, - ctx->DrawIndirectBuffer, offset, - maxdrawcount, stride, - ctx->ParameterBuffer, drawcount_offset, &ib); - - if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) - _mesa_flush(ctx); + _mesa_validated_multidrawelementsindirect(ctx, mode, type, + (GLintptr)indirect, 0, primcount, + stride, NULL); } @@ -1897,9 +1820,9 @@ _mesa_exec_MultiDrawArraysIndirectCount(GLenum mode, GLintptr indirect, if (skip_validated_draw(ctx)) return; - _mesa_validated_multidrawarraysindirectcount(ctx, mode, indirect, - drawcount_offset, - maxdrawcount, stride); + _mesa_validated_multidrawarraysindirect(ctx, mode, indirect, + drawcount_offset, maxdrawcount, + stride, ctx->ParameterBuffer); } @@ -1940,9 +1863,9 @@ _mesa_exec_MultiDrawElementsIndirectCount(GLenum mode, GLenum type, if (skip_validated_draw(ctx)) return; - _mesa_validated_multidrawelementsindirectcount(ctx, mode, type, indirect, - drawcount_offset, maxdrawcount, - stride); + _mesa_validated_multidrawelementsindirect(ctx, mode, type, indirect, + drawcount_offset, maxdrawcount, + stride, ctx->ParameterBuffer); }