mesa: Add support for ARB_draw_elements_base_vertex.
This commit is contained in:
@@ -62,6 +62,7 @@
|
||||
#define need_GL_SGI_color_table
|
||||
|
||||
/* sw extensions not associated with some GL version */
|
||||
#define need_GL_ARB_draw_elements_base_vertex
|
||||
#define need_GL_ARB_shader_objects
|
||||
#define need_GL_ARB_vertex_array_object
|
||||
#define need_GL_ARB_vertex_program
|
||||
@@ -96,6 +97,7 @@ const struct dri_extension card_extensions[] =
|
||||
{ "GL_SGI_color_table", GL_SGI_color_table_functions },
|
||||
|
||||
{ "GL_ARB_depth_clamp", NULL },
|
||||
{ "GL_ARB_draw_elements_base_vertex", GL_ARB_draw_elements_base_vertex_functions },
|
||||
{ "GL_ARB_shader_objects", GL_ARB_shader_objects_functions },
|
||||
{ "GL_ARB_vertex_array_object", GL_ARB_vertex_array_object_functions },
|
||||
{ "GL_ARB_vertex_program", GL_ARB_vertex_program_functions },
|
||||
|
@@ -1317,6 +1317,7 @@ xmesa_convert_from_x_visual_type( int visualType )
|
||||
#define need_GL_SGI_color_table
|
||||
|
||||
/* sw extensions not associated with some GL version */
|
||||
#define need_GL_ARB_draw_elements_base_vertex
|
||||
#define need_GL_ARB_shader_objects
|
||||
#define need_GL_ARB_sync
|
||||
#define need_GL_ARB_vertex_program
|
||||
@@ -1348,6 +1349,7 @@ const struct dri_extension card_extensions[] =
|
||||
{ "GL_SGI_color_table", GL_SGI_color_table_functions },
|
||||
|
||||
{ "GL_ARB_depth_clamp", NULL },
|
||||
{ "GL_ARB_draw_elements_base_vertex", GL_ARB_draw_elements_base_vertex_functions },
|
||||
{ "GL_ARB_shader_objects", GL_ARB_shader_objects_functions },
|
||||
{ "GL_ARB_sync", GL_ARB_sync_functions },
|
||||
{ "GL_ARB_vertex_program", GL_ARB_vertex_program_functions },
|
||||
|
@@ -731,7 +731,7 @@ _mesa_noop_DrawElements(GLenum mode, GLsizei count, GLenum type,
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
GLint i;
|
||||
|
||||
if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
|
||||
if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, 0 ))
|
||||
return;
|
||||
|
||||
CALL_Begin(GET_DISPATCH(), (mode));
|
||||
@@ -757,6 +757,43 @@ _mesa_noop_DrawElements(GLenum mode, GLsizei count, GLenum type,
|
||||
CALL_End(GET_DISPATCH(), ());
|
||||
}
|
||||
|
||||
static void GLAPIENTRY
|
||||
_mesa_noop_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
|
||||
const GLvoid *indices, GLint basevertex)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
GLint i;
|
||||
|
||||
if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices,
|
||||
basevertex ))
|
||||
return;
|
||||
|
||||
CALL_Begin(GET_DISPATCH(), (mode));
|
||||
|
||||
switch (type) {
|
||||
case GL_UNSIGNED_BYTE:
|
||||
for (i = 0 ; i < count ; i++)
|
||||
CALL_ArrayElement(GET_DISPATCH(), ( ((GLubyte *)indices)[i] +
|
||||
basevertex));
|
||||
break;
|
||||
case GL_UNSIGNED_SHORT:
|
||||
for (i = 0 ; i < count ; i++)
|
||||
CALL_ArrayElement(GET_DISPATCH(), ( ((GLushort *)indices)[i] +
|
||||
basevertex ));
|
||||
break;
|
||||
case GL_UNSIGNED_INT:
|
||||
for (i = 0 ; i < count ; i++)
|
||||
CALL_ArrayElement(GET_DISPATCH(), ( ((GLuint *)indices)[i] +
|
||||
basevertex ));
|
||||
break;
|
||||
default:
|
||||
_mesa_error( ctx, GL_INVALID_ENUM, "glDrawElementsBaseVertex(type)" );
|
||||
break;
|
||||
}
|
||||
|
||||
CALL_End(GET_DISPATCH(), ());
|
||||
}
|
||||
|
||||
|
||||
static void GLAPIENTRY
|
||||
_mesa_noop_DrawRangeElements(GLenum mode,
|
||||
@@ -768,7 +805,7 @@ _mesa_noop_DrawRangeElements(GLenum mode,
|
||||
|
||||
if (_mesa_validate_DrawRangeElements( ctx, mode,
|
||||
start, end,
|
||||
count, type, indices ))
|
||||
count, type, indices, 0 ))
|
||||
CALL_DrawElements(GET_DISPATCH(), (mode, count, type, indices));
|
||||
}
|
||||
|
||||
@@ -786,6 +823,40 @@ _mesa_noop_MultiDrawElements(GLenum mode, const GLsizei *count, GLenum type,
|
||||
}
|
||||
}
|
||||
|
||||
static void GLAPIENTRY
|
||||
_mesa_noop_DrawRangeElementsBaseVertex(GLenum mode,
|
||||
GLuint start, GLuint end,
|
||||
GLsizei count, GLenum type,
|
||||
const GLvoid *indices, GLint basevertex)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
|
||||
if (_mesa_validate_DrawRangeElements( ctx, mode,
|
||||
start, end,
|
||||
count, type, indices, basevertex ))
|
||||
CALL_DrawElementsBaseVertex(GET_DISPATCH(), (mode, count, type, indices,
|
||||
basevertex));
|
||||
}
|
||||
|
||||
/* GL_EXT_multi_draw_arrays */
|
||||
void GLAPIENTRY
|
||||
_mesa_noop_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count,
|
||||
GLenum type,
|
||||
const GLvoid **indices,
|
||||
GLsizei primcount,
|
||||
const GLint *basevertex)
|
||||
{
|
||||
GLsizei i;
|
||||
|
||||
for (i = 0; i < primcount; i++) {
|
||||
if (count[i] > 0) {
|
||||
CALL_DrawElementsBaseVertex(GET_DISPATCH(), (mode, count[i], type,
|
||||
indices[i],
|
||||
basevertex[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Eval Mesh
|
||||
*/
|
||||
@@ -995,6 +1066,9 @@ _mesa_noop_vtxfmt_init( GLvertexformat *vfmt )
|
||||
vfmt->DrawElements = _mesa_noop_DrawElements;
|
||||
vfmt->DrawRangeElements = _mesa_noop_DrawRangeElements;
|
||||
vfmt->MultiDrawElementsEXT = _mesa_noop_MultiDrawElements;
|
||||
vfmt->DrawElementsBaseVertex = _mesa_noop_DrawElementsBaseVertex;
|
||||
vfmt->DrawRangeElementsBaseVertex = _mesa_noop_DrawRangeElementsBaseVertex;
|
||||
vfmt->MultiDrawElementsBaseVertex = _mesa_noop_MultiDrawElementsBaseVertex;
|
||||
vfmt->EvalMesh1 = _mesa_noop_EvalMesh1;
|
||||
vfmt->EvalMesh2 = _mesa_noop_EvalMesh2;
|
||||
}
|
||||
|
@@ -44,6 +44,13 @@ extern void GLAPIENTRY
|
||||
_mesa_noop_MultiDrawElements(GLenum mode, const GLsizei *count, GLenum type,
|
||||
const GLvoid **indices, GLsizei primcount);
|
||||
|
||||
extern void GLAPIENTRY
|
||||
_mesa_noop_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count,
|
||||
GLenum type,
|
||||
const GLvoid **indices,
|
||||
GLsizei primcount,
|
||||
const GLint *basevertex);
|
||||
|
||||
extern void
|
||||
_mesa_noop_vtxfmt_init(GLvertexformat *vfmt);
|
||||
|
||||
|
@@ -29,7 +29,7 @@
|
||||
#include "imports.h"
|
||||
#include "mtypes.h"
|
||||
#include "state.h"
|
||||
|
||||
#include "vbo/vbo.h"
|
||||
|
||||
|
||||
/**
|
||||
@@ -51,51 +51,6 @@ index_bytes(GLenum type, GLsizei count)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find the max index in the given element/index buffer
|
||||
*/
|
||||
static GLuint
|
||||
max_buffer_index(GLcontext *ctx, GLuint count, GLenum type,
|
||||
const void *indices,
|
||||
struct gl_buffer_object *elementBuf)
|
||||
{
|
||||
const GLubyte *map = NULL;
|
||||
GLuint max = 0;
|
||||
GLuint i;
|
||||
|
||||
if (_mesa_is_bufferobj(elementBuf)) {
|
||||
/* elements are in a user-defined buffer object. need to map it */
|
||||
map = ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER,
|
||||
GL_READ_ONLY, elementBuf);
|
||||
/* Actual address is the sum of pointers */
|
||||
indices = (const GLvoid *) ADD_POINTERS(map, (const GLubyte *) indices);
|
||||
}
|
||||
|
||||
if (type == GL_UNSIGNED_INT) {
|
||||
for (i = 0; i < count; i++)
|
||||
if (((GLuint *) indices)[i] > max)
|
||||
max = ((GLuint *) indices)[i];
|
||||
}
|
||||
else if (type == GL_UNSIGNED_SHORT) {
|
||||
for (i = 0; i < count; i++)
|
||||
if (((GLushort *) indices)[i] > max)
|
||||
max = ((GLushort *) indices)[i];
|
||||
}
|
||||
else {
|
||||
ASSERT(type == GL_UNSIGNED_BYTE);
|
||||
for (i = 0; i < count; i++)
|
||||
if (((GLubyte *) indices)[i] > max)
|
||||
max = ((GLubyte *) indices)[i];
|
||||
}
|
||||
|
||||
if (map) {
|
||||
ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, elementBuf);
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if OK to draw arrays/elements.
|
||||
*/
|
||||
@@ -124,6 +79,40 @@ check_valid_to_render(GLcontext *ctx, const char *function)
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
check_index_bounds(GLcontext *ctx, GLsizei count, GLenum type,
|
||||
const GLvoid *indices, GLint basevertex)
|
||||
{
|
||||
struct _mesa_prim prim;
|
||||
struct _mesa_index_buffer ib;
|
||||
GLuint min, max;
|
||||
|
||||
/* Only the X Server needs to do this -- otherwise, accessing outside
|
||||
* array/BO bounds allows application termination.
|
||||
*/
|
||||
if (!ctx->Const.CheckArrayBounds)
|
||||
return GL_TRUE;
|
||||
|
||||
memset(&prim, 0, sizeof(prim));
|
||||
prim.count = count;
|
||||
|
||||
memset(&ib, 0, sizeof(ib));
|
||||
ib.type = type;
|
||||
ib.ptr = indices;
|
||||
ib.obj = ctx->Array.ElementArrayBufferObj;
|
||||
|
||||
vbo_get_minmax_index(ctx, &prim, &ib, &min, &max);
|
||||
|
||||
if (min + basevertex < 0 ||
|
||||
max + basevertex > ctx->Array.ArrayObj->_MaxElement) {
|
||||
/* the max element is out of bounds of one or more enabled arrays */
|
||||
_mesa_warning(ctx, "glDrawElements() index=%u is "
|
||||
"out of bounds (max=%u)", max, ctx->Array.ArrayObj->_MaxElement);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Error checking for glDrawElements(). Includes parameter checking
|
||||
@@ -133,7 +122,7 @@ check_valid_to_render(GLcontext *ctx, const char *function)
|
||||
GLboolean
|
||||
_mesa_validate_DrawElements(GLcontext *ctx,
|
||||
GLenum mode, GLsizei count, GLenum type,
|
||||
const GLvoid *indices)
|
||||
const GLvoid *indices, GLint basevertex)
|
||||
{
|
||||
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
|
||||
|
||||
@@ -177,17 +166,8 @@ _mesa_validate_DrawElements(GLcontext *ctx,
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
if (ctx->Const.CheckArrayBounds) {
|
||||
/* find max array index */
|
||||
GLuint max = max_buffer_index(ctx, count, type, indices,
|
||||
ctx->Array.ElementArrayBufferObj);
|
||||
if (max >= ctx->Array.ArrayObj->_MaxElement) {
|
||||
/* the max element is out of bounds of one or more enabled arrays */
|
||||
_mesa_warning(ctx, "glDrawElements() index=%u is "
|
||||
"out of bounds (max=%u)", max, ctx->Array.ArrayObj->_MaxElement);
|
||||
if (!check_index_bounds(ctx, count, type, indices, basevertex))
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
@@ -202,7 +182,7 @@ GLboolean
|
||||
_mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode,
|
||||
GLuint start, GLuint end,
|
||||
GLsizei count, GLenum type,
|
||||
const GLvoid *indices)
|
||||
const GLvoid *indices, GLint basevertex)
|
||||
{
|
||||
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
|
||||
|
||||
@@ -250,14 +230,8 @@ _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode,
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
if (ctx->Const.CheckArrayBounds) {
|
||||
GLuint max = max_buffer_index(ctx, count, type, indices,
|
||||
ctx->Array.ElementArrayBufferObj);
|
||||
if (max >= ctx->Array.ArrayObj->_MaxElement) {
|
||||
/* the max element is out of bounds of one or more enabled arrays */
|
||||
if (!check_index_bounds(ctx, count, type, indices, basevertex))
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
@@ -37,13 +37,13 @@ _mesa_validate_DrawArrays(GLcontext *ctx,
|
||||
extern GLboolean
|
||||
_mesa_validate_DrawElements(GLcontext *ctx,
|
||||
GLenum mode, GLsizei count, GLenum type,
|
||||
const GLvoid *indices);
|
||||
const GLvoid *indices, GLint basevertex);
|
||||
|
||||
extern GLboolean
|
||||
_mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode,
|
||||
GLuint start, GLuint end,
|
||||
GLsizei count, GLenum type,
|
||||
const GLvoid *indices);
|
||||
const GLvoid *indices, GLint basevertex);
|
||||
|
||||
|
||||
#endif
|
||||
|
@@ -1172,6 +1172,21 @@ typedef struct {
|
||||
GLenum type,
|
||||
const GLvoid **indices,
|
||||
GLsizei primcount);
|
||||
void (GLAPIENTRYP DrawElementsBaseVertex)( GLenum mode, GLsizei count,
|
||||
GLenum type,
|
||||
const GLvoid *indices,
|
||||
GLint basevertex );
|
||||
void (GLAPIENTRYP DrawRangeElementsBaseVertex)( GLenum mode, GLuint start,
|
||||
GLuint end, GLsizei count,
|
||||
GLenum type,
|
||||
const GLvoid *indices,
|
||||
GLint basevertex);
|
||||
void (GLAPIENTRYP MultiDrawElementsBaseVertex)( GLenum mode,
|
||||
const GLsizei *count,
|
||||
GLenum type,
|
||||
const GLvoid **indices,
|
||||
GLsizei primcount,
|
||||
const GLint *basevertex);
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
|
@@ -8711,6 +8711,9 @@ _mesa_save_vtxfmt_init(GLvertexformat * vfmt)
|
||||
vfmt->DrawElements = 0;
|
||||
vfmt->DrawRangeElements = 0;
|
||||
vfmt->MultiDrawElemementsEXT = 0;
|
||||
vfmt->DrawElementsBaseVertex = 0;
|
||||
vfmt->DrawRangeElementsBaseVertex = 0;
|
||||
vfmt->MultiDrawElemementsBaseVertex = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -49,6 +49,7 @@ static const struct {
|
||||
{ OFF, "GL_ARB_depth_texture", F(ARB_depth_texture) },
|
||||
{ OFF, "GL_ARB_depth_clamp", F(ARB_depth_clamp) },
|
||||
{ ON, "GL_ARB_draw_buffers", F(ARB_draw_buffers) },
|
||||
{ OFF, "GL_ARB_draw_elements_base_vertex", F(ARB_draw_elements_base_vertex) },
|
||||
{ OFF, "GL_ARB_fragment_program", F(ARB_fragment_program) },
|
||||
{ OFF, "GL_ARB_fragment_program_shadow", F(ARB_fragment_program_shadow) },
|
||||
{ OFF, "GL_ARB_fragment_shader", F(ARB_fragment_shader) },
|
||||
@@ -197,6 +198,7 @@ _mesa_enable_sw_extensions(GLcontext *ctx)
|
||||
ctx->Extensions.ARB_depth_clamp = GL_TRUE;
|
||||
ctx->Extensions.ARB_depth_texture = GL_TRUE;
|
||||
/*ctx->Extensions.ARB_draw_buffers = GL_TRUE;*/
|
||||
ctx->Extensions.ARB_draw_elements_base_vertex = GL_TRUE;
|
||||
#if FEATURE_ARB_fragment_program
|
||||
ctx->Extensions.ARB_fragment_program = GL_TRUE;
|
||||
ctx->Extensions.ARB_fragment_program_shadow = GL_TRUE;
|
||||
|
@@ -2478,6 +2478,7 @@ struct gl_extensions
|
||||
GLboolean ARB_depth_texture;
|
||||
GLboolean ARB_depth_clamp;
|
||||
GLboolean ARB_draw_buffers;
|
||||
GLboolean ARB_draw_elements_base_vertex;
|
||||
GLboolean ARB_fragment_program;
|
||||
GLboolean ARB_fragment_program_shadow;
|
||||
GLboolean ARB_fragment_shader;
|
||||
|
@@ -129,6 +129,11 @@ extern void GLAPIENTRY
|
||||
_mesa_MultiDrawElementsEXT( GLenum mode, const GLsizei *count, GLenum type,
|
||||
const GLvoid **indices, GLsizei primcount );
|
||||
|
||||
extern void GLAPIENTRY
|
||||
_mesa_MultiDrawElementsBaseVertex( GLenum mode,
|
||||
const GLsizei *count, GLenum type,
|
||||
const GLvoid **indices, GLsizei primcount,
|
||||
const GLint *basevertex);
|
||||
|
||||
extern void GLAPIENTRY
|
||||
_mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
|
||||
@@ -159,6 +164,16 @@ extern void GLAPIENTRY
|
||||
_mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,
|
||||
GLenum type, const GLvoid *indices);
|
||||
|
||||
extern void GLAPIENTRY
|
||||
_mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
|
||||
const GLvoid *indices, GLint basevertex);
|
||||
|
||||
extern void GLAPIENTRY
|
||||
_mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
|
||||
GLsizei count, GLenum type,
|
||||
const GLvoid *indices,
|
||||
GLint basevertex);
|
||||
|
||||
|
||||
extern void
|
||||
_mesa_copy_client_array(GLcontext *ctx,
|
||||
|
@@ -134,6 +134,9 @@ install_vtxfmt( struct _glapi_table *tab, const GLvertexformat *vfmt )
|
||||
SET_DrawElements(tab, vfmt->DrawElements);
|
||||
SET_DrawRangeElements(tab, vfmt->DrawRangeElements);
|
||||
SET_MultiDrawElementsEXT(tab, vfmt->MultiDrawElementsEXT);
|
||||
SET_DrawElementsBaseVertex(tab, vfmt->DrawElementsBaseVertex);
|
||||
SET_DrawRangeElementsBaseVertex(tab, vfmt->DrawRangeElementsBaseVertex);
|
||||
SET_MultiDrawElementsBaseVertex(tab, vfmt->MultiDrawElementsBaseVertex);
|
||||
SET_EvalMesh1(tab, vfmt->EvalMesh1);
|
||||
SET_EvalMesh2(tab, vfmt->EvalMesh2);
|
||||
ASSERT(tab->EvalMesh2);
|
||||
|
@@ -354,6 +354,44 @@ static void GLAPIENTRY TAG(DrawRangeElements)( GLenum mode, GLuint start,
|
||||
CALL_DrawRangeElements(GET_DISPATCH(), ( mode, start, end, count, type, indices ));
|
||||
}
|
||||
|
||||
static void GLAPIENTRY TAG(DrawElementsBaseVertex)( GLenum mode,
|
||||
GLsizei count,
|
||||
GLenum type,
|
||||
const GLvoid *indices,
|
||||
GLint basevertex)
|
||||
{
|
||||
PRE_LOOPBACK( DrawElementsBaseVertex );
|
||||
CALL_DrawElementsBaseVertex(GET_DISPATCH(), ( mode, count, type,
|
||||
indices, basevertex ));
|
||||
}
|
||||
|
||||
static void GLAPIENTRY TAG(DrawRangeElementsBaseVertex)( GLenum mode,
|
||||
GLuint start,
|
||||
GLuint end,
|
||||
GLsizei count,
|
||||
GLenum type,
|
||||
const GLvoid *indices,
|
||||
GLint basevertex)
|
||||
{
|
||||
PRE_LOOPBACK( DrawRangeElementsBaseVertex );
|
||||
CALL_DrawRangeElementsBaseVertex(GET_DISPATCH(), ( mode, start, end,
|
||||
count, type, indices,
|
||||
basevertex ));
|
||||
}
|
||||
|
||||
static void GLAPIENTRY TAG(MultiDrawElementsBaseVertex)( GLenum mode,
|
||||
const GLsizei *count,
|
||||
GLenum type,
|
||||
const GLvoid **indices,
|
||||
GLsizei primcount,
|
||||
const GLint *basevertex)
|
||||
{
|
||||
PRE_LOOPBACK( MultiDrawElementsBaseVertex );
|
||||
CALL_MultiDrawElementsBaseVertex(GET_DISPATCH(), ( mode, count, type,
|
||||
indices,
|
||||
primcount, basevertex ));
|
||||
}
|
||||
|
||||
static void GLAPIENTRY TAG(EvalMesh1)( GLenum mode, GLint i1, GLint i2 )
|
||||
{
|
||||
PRE_LOOPBACK( EvalMesh1 );
|
||||
@@ -534,6 +572,9 @@ static GLvertexformat TAG(vtxfmt) = {
|
||||
TAG(DrawElements),
|
||||
TAG(DrawRangeElements),
|
||||
TAG(MultiDrawElementsEXT),
|
||||
TAG(DrawElementsBaseVertex),
|
||||
TAG(DrawRangeElementsBaseVertex),
|
||||
TAG(MultiDrawElementsBaseVertex),
|
||||
TAG(EvalMesh1),
|
||||
TAG(EvalMesh2)
|
||||
};
|
||||
|
@@ -316,22 +316,27 @@ static void bind_indices( GLcontext *ctx,
|
||||
|
||||
ptr = ADD_POINTERS(ib->obj->Pointer, ib->ptr);
|
||||
|
||||
if (ib->type == GL_UNSIGNED_INT) {
|
||||
if (ib->type == GL_UNSIGNED_INT && VB->Primitive[0].basevertex == 0) {
|
||||
VB->Elts = (GLuint *) ptr;
|
||||
}
|
||||
else {
|
||||
GLuint *elts = (GLuint *)get_space(ctx, ib->count * sizeof(GLuint));
|
||||
VB->Elts = elts;
|
||||
|
||||
if (ib->type == GL_UNSIGNED_SHORT) {
|
||||
if (ib->type == GL_UNSIGNED_INT) {
|
||||
const GLuint *in = (GLuint *)ptr;
|
||||
for (i = 0; i < ib->count; i++)
|
||||
*elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex;
|
||||
}
|
||||
else if (ib->type == GL_UNSIGNED_SHORT) {
|
||||
const GLushort *in = (GLushort *)ptr;
|
||||
for (i = 0; i < ib->count; i++)
|
||||
*elts++ = (GLuint)(*in++);
|
||||
*elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex;
|
||||
}
|
||||
else {
|
||||
const GLubyte *in = (GLubyte *)ptr;
|
||||
for (i = 0; i < ib->count; i++)
|
||||
*elts++ = (GLuint)(*in++);
|
||||
*elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -390,10 +395,14 @@ void _tnl_draw_prims( GLcontext *ctx,
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
const GLuint TEST_SPLIT = 0;
|
||||
const GLint max = TEST_SPLIT ? 8 : tnl->vb.Size - MAX_CLIPPED_VERTICES;
|
||||
GLuint max_basevertex = prim->basevertex;
|
||||
GLuint i;
|
||||
|
||||
for (i = 1; i < nr_prims; i++)
|
||||
max_basevertex = MAX2(max_basevertex, prim[i].basevertex);
|
||||
|
||||
if (0)
|
||||
{
|
||||
GLuint i;
|
||||
_mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
|
||||
for (i = 0; i < nr_prims; i++)
|
||||
_mesa_printf("prim %d: %s start %d count %d\n", i,
|
||||
@@ -410,7 +419,7 @@ void _tnl_draw_prims( GLcontext *ctx,
|
||||
_tnl_vbo_draw_prims );
|
||||
return;
|
||||
}
|
||||
else if (max_index > max) {
|
||||
else if (max_index + max_basevertex > max) {
|
||||
/* The software TNL pipeline has a fixed amount of storage for
|
||||
* vertices and it is necessary to split incoming drawing commands
|
||||
* if they exceed that limit.
|
||||
@@ -424,7 +433,7 @@ void _tnl_draw_prims( GLcontext *ctx,
|
||||
* recursively call back into this function.
|
||||
*/
|
||||
vbo_split_prims( ctx, arrays, prim, nr_prims, ib,
|
||||
0, max_index,
|
||||
0, max_index + prim->basevertex,
|
||||
_tnl_vbo_draw_prims,
|
||||
&limits );
|
||||
}
|
||||
@@ -435,17 +444,34 @@ void _tnl_draw_prims( GLcontext *ctx,
|
||||
struct gl_buffer_object *bo[VERT_ATTRIB_MAX + 1];
|
||||
GLuint nr_bo = 0;
|
||||
|
||||
for (i = 0; i < nr_prims;) {
|
||||
GLuint this_nr_prims;
|
||||
|
||||
/* Our SW TNL pipeline doesn't handle basevertex yet, so bind_indices
|
||||
* will rebase the elements to the basevertex, and we'll only
|
||||
* emit strings of prims with the same basevertex in one draw call.
|
||||
*/
|
||||
for (this_nr_prims = 1; i + this_nr_prims < nr_prims;
|
||||
this_nr_prims++) {
|
||||
if (prim[i].basevertex != prim[i + this_nr_prims].basevertex)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Binding inputs may imply mapping some vertex buffer objects.
|
||||
* They will need to be unmapped below.
|
||||
*/
|
||||
bind_inputs(ctx, arrays, max_index+1, bo, &nr_bo);
|
||||
bind_prims(ctx, &prim[i], this_nr_prims);
|
||||
bind_inputs(ctx, arrays, max_index + prim[i].basevertex + 1,
|
||||
bo, &nr_bo);
|
||||
bind_indices(ctx, ib, bo, &nr_bo);
|
||||
bind_prims(ctx, prim, nr_prims );
|
||||
|
||||
TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx);
|
||||
|
||||
unmap_vbos(ctx, bo, nr_bo);
|
||||
free_space(ctx);
|
||||
|
||||
i += this_nr_prims;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -44,6 +44,7 @@ struct _mesa_prim {
|
||||
|
||||
GLuint start;
|
||||
GLuint count;
|
||||
GLint basevertex;
|
||||
};
|
||||
|
||||
/* Would like to call this a "vbo_index_buffer", but this would be
|
||||
|
@@ -181,7 +181,7 @@ unmap_array_buffer(GLcontext *ctx, struct gl_client_array *array)
|
||||
*/
|
||||
static void
|
||||
check_draw_elements_data(GLcontext *ctx, GLsizei count, GLenum elemType,
|
||||
const void *elements)
|
||||
const void *elements, GLint basevertex)
|
||||
{
|
||||
struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
|
||||
const void *elemMap;
|
||||
@@ -518,6 +518,7 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
|
||||
prim[0].start = start;
|
||||
prim[0].count = count;
|
||||
prim[0].indexed = 0;
|
||||
prim[0].basevertex = 0;
|
||||
|
||||
vbo->draw_prims( ctx, exec->array.inputs, prim, 1, NULL,
|
||||
GL_TRUE, start, start + count - 1 );
|
||||
@@ -592,7 +593,8 @@ vbo_validated_drawrangeelements(GLcontext *ctx, GLenum mode,
|
||||
GLboolean index_bounds_valid,
|
||||
GLuint start, GLuint end,
|
||||
GLsizei count, GLenum type,
|
||||
const GLvoid *indices)
|
||||
const GLvoid *indices,
|
||||
GLint basevertex)
|
||||
{
|
||||
struct vbo_context *vbo = vbo_context(ctx);
|
||||
struct vbo_exec_context *exec = &vbo->exec;
|
||||
@@ -626,6 +628,7 @@ vbo_validated_drawrangeelements(GLcontext *ctx, GLenum mode,
|
||||
prim[0].start = 0;
|
||||
prim[0].count = count;
|
||||
prim[0].indexed = 1;
|
||||
prim[0].basevertex = basevertex;
|
||||
|
||||
/* Need to give special consideration to rendering a range of
|
||||
* indices starting somewhere above zero. Typically the
|
||||
@@ -663,23 +666,25 @@ vbo_validated_drawrangeelements(GLcontext *ctx, GLenum mode,
|
||||
}
|
||||
|
||||
static void GLAPIENTRY
|
||||
vbo_exec_DrawRangeElements(GLenum mode,
|
||||
vbo_exec_DrawRangeElementsBaseVertex(GLenum mode,
|
||||
GLuint start, GLuint end,
|
||||
GLsizei count, GLenum type, const GLvoid *indices)
|
||||
GLsizei count, GLenum type,
|
||||
const GLvoid *indices,
|
||||
GLint basevertex)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
|
||||
if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count,
|
||||
type, indices ))
|
||||
type, indices, basevertex ))
|
||||
return;
|
||||
|
||||
if (end >= ctx->Array.ArrayObj->_MaxElement) {
|
||||
/* the max element is out of bounds of one or more enabled arrays */
|
||||
_mesa_warning(ctx, "glDraw[Range]Elements(start %u, end %u, count %d, "
|
||||
"type 0x%x, indices=%p)\n"
|
||||
_mesa_warning(ctx, "glDraw[Range]Elements{,BaseVertex}(start %u, end %u, "
|
||||
"count %d, type 0x%x, indices=%p, base=%d)\n"
|
||||
"\tindex=%u is out of bounds (max=%u) "
|
||||
"Element Buffer %u (size %d)",
|
||||
start, end, count, type, indices, end,
|
||||
start, end, count, type, indices, end, basevertex,
|
||||
ctx->Array.ArrayObj->_MaxElement - 1,
|
||||
ctx->Array.ElementArrayBufferObj->Name,
|
||||
ctx->Array.ElementArrayBufferObj->Size);
|
||||
@@ -692,10 +697,12 @@ vbo_exec_DrawRangeElements(GLenum mode,
|
||||
return;
|
||||
}
|
||||
else if (0) {
|
||||
_mesa_printf("glDraw[Range]Elements"
|
||||
"(start %u, end %u, type 0x%x, count %d) ElemBuf %u\n",
|
||||
_mesa_printf("glDraw[Range]Elements{,BaseVertex}"
|
||||
"(start %u, end %u, type 0x%x, count %d) ElemBuf %u, "
|
||||
"base %d\n",
|
||||
start, end, type, count,
|
||||
ctx->Array.ElementArrayBufferObj->Name);
|
||||
ctx->Array.ElementArrayBufferObj->Name,
|
||||
basevertex);
|
||||
}
|
||||
|
||||
#if 0
|
||||
@@ -705,7 +712,17 @@ vbo_exec_DrawRangeElements(GLenum mode,
|
||||
#endif
|
||||
|
||||
vbo_validated_drawrangeelements(ctx, mode, GL_TRUE, start, end,
|
||||
count, type, indices);
|
||||
count, type, indices, basevertex);
|
||||
}
|
||||
|
||||
static void GLAPIENTRY
|
||||
vbo_exec_DrawRangeElements(GLenum mode,
|
||||
GLuint start, GLuint end,
|
||||
GLsizei count, GLenum type,
|
||||
const GLvoid *indices)
|
||||
{
|
||||
vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type,
|
||||
indices, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -715,18 +732,33 @@ vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type,
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
|
||||
if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
|
||||
if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, 0 ))
|
||||
return;
|
||||
|
||||
vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
|
||||
count, type, indices);
|
||||
count, type, indices, 0);
|
||||
}
|
||||
|
||||
static void GLAPIENTRY
|
||||
vbo_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
|
||||
const GLvoid *indices, GLint basevertex)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
|
||||
if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices,
|
||||
basevertex ))
|
||||
return;
|
||||
|
||||
vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
|
||||
count, type, indices, basevertex);
|
||||
}
|
||||
|
||||
/* Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements */
|
||||
static void
|
||||
vbo_validated_multidrawelements(GLcontext *ctx, GLenum mode,
|
||||
const GLsizei *count, GLenum type,
|
||||
const GLvoid **indices, GLsizei primcount)
|
||||
const GLvoid **indices, GLsizei primcount,
|
||||
const GLint *basevertex)
|
||||
{
|
||||
struct vbo_context *vbo = vbo_context(ctx);
|
||||
struct vbo_exec_context *exec = &vbo->exec;
|
||||
@@ -820,6 +852,10 @@ vbo_validated_multidrawelements(GLcontext *ctx, GLenum mode,
|
||||
prim[i].start = ((uintptr_t)indices[i] - min_index_ptr) / index_type_size;
|
||||
prim[i].count = count[i];
|
||||
prim[i].indexed = 1;
|
||||
if (basevertex != NULL)
|
||||
prim[i].basevertex = basevertex[i];
|
||||
else
|
||||
prim[i].basevertex = 0;
|
||||
}
|
||||
|
||||
vbo->draw_prims(ctx, exec->array.inputs, prim, primcount, &ib,
|
||||
@@ -840,6 +876,10 @@ vbo_validated_multidrawelements(GLcontext *ctx, GLenum mode,
|
||||
prim[0].start = 0;
|
||||
prim[0].count = count[i];
|
||||
prim[0].indexed = 1;
|
||||
if (basevertex != NULL)
|
||||
prim[0].basevertex = basevertex[i];
|
||||
else
|
||||
prim[0].basevertex = 0;
|
||||
}
|
||||
|
||||
vbo->draw_prims(ctx, exec->array.inputs, prim, 1, &ib,
|
||||
@@ -860,13 +900,36 @@ vbo_exec_MultiDrawElements(GLenum mode,
|
||||
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
|
||||
|
||||
for (i = 0; i < primcount; i++) {
|
||||
if (!_mesa_validate_DrawElements( ctx, mode, count[i], type, indices[i] ))
|
||||
if (!_mesa_validate_DrawElements(ctx, mode, count[i], type, indices[i],
|
||||
0))
|
||||
return;
|
||||
}
|
||||
|
||||
vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount);
|
||||
vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void GLAPIENTRY
|
||||
vbo_exec_MultiDrawElementsBaseVertex(GLenum mode,
|
||||
const GLsizei *count, GLenum type,
|
||||
const GLvoid **indices,
|
||||
GLsizei primcount,
|
||||
const GLsizei *basevertex)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
GLint i;
|
||||
|
||||
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
|
||||
|
||||
for (i = 0; i < primcount; i++) {
|
||||
if (!_mesa_validate_DrawElements(ctx, mode, count[i], type, indices[i],
|
||||
basevertex[i]))
|
||||
return;
|
||||
}
|
||||
|
||||
vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
|
||||
basevertex);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
@@ -881,11 +944,17 @@ vbo_exec_array_init( struct vbo_exec_context *exec )
|
||||
exec->vtxfmt.DrawElements = vbo_exec_DrawElements;
|
||||
exec->vtxfmt.DrawRangeElements = vbo_exec_DrawRangeElements;
|
||||
exec->vtxfmt.MultiDrawElementsEXT = vbo_exec_MultiDrawElements;
|
||||
exec->vtxfmt.DrawElementsBaseVertex = vbo_exec_DrawElementsBaseVertex;
|
||||
exec->vtxfmt.DrawRangeElementsBaseVertex = vbo_exec_DrawRangeElementsBaseVertex;
|
||||
exec->vtxfmt.MultiDrawElementsBaseVertex = vbo_exec_MultiDrawElementsBaseVertex;
|
||||
#else
|
||||
exec->vtxfmt.DrawArrays = _mesa_noop_DrawArrays;
|
||||
exec->vtxfmt.DrawElements = _mesa_noop_DrawElements;
|
||||
exec->vtxfmt.DrawRangeElements = _mesa_noop_DrawRangeElements;
|
||||
exec->vtxfmt.MultiDrawElementsEXT = _mesa_noop_MultiDrawElements;
|
||||
exec->vtxfmt.DrawElementsBaseVertex = _mesa_noop_DrawElementsBaseVertex;
|
||||
exec->vtxfmt.DrawRangeElementsBaseVertex = _mesa_noop_DrawRangeElementsBaseVertex;
|
||||
exec->vtxfmt.MultiDrawElementsBaseVertex = _mesa_noop_MultiDrawElementsBaseVertex;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -913,6 +982,13 @@ _mesa_DrawElements(GLenum mode, GLsizei count, GLenum type,
|
||||
vbo_exec_DrawElements(mode, count, type, indices);
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
|
||||
const GLvoid *indices, GLint basevertex)
|
||||
{
|
||||
vbo_exec_DrawElementsBaseVertex(mode, count, type, indices, basevertex);
|
||||
}
|
||||
|
||||
|
||||
/* This API entrypoint is not ordinarily used */
|
||||
void GLAPIENTRY
|
||||
@@ -922,6 +998,15 @@ _mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,
|
||||
vbo_exec_DrawRangeElements(mode, start, end, count, type, indices);
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
|
||||
GLsizei count, GLenum type,
|
||||
const GLvoid *indices, GLint basevertex)
|
||||
{
|
||||
vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type,
|
||||
indices, basevertex);
|
||||
}
|
||||
|
||||
/* GL_EXT_multi_draw_arrays */
|
||||
void GLAPIENTRY
|
||||
_mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type,
|
||||
@@ -929,3 +1014,13 @@ _mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type,
|
||||
{
|
||||
vbo_exec_MultiDrawElements(mode, count, type, indices, primcount);
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_MultiDrawElementsBaseVertex(GLenum mode,
|
||||
const GLsizei *count, GLenum type,
|
||||
const GLvoid **indices, GLsizei primcount,
|
||||
const GLint *basevertex)
|
||||
{
|
||||
vbo_exec_MultiDrawElementsBaseVertex(mode, count, type, indices,
|
||||
primcount, basevertex);
|
||||
}
|
||||
|
@@ -126,7 +126,20 @@ void vbo_rebase_prims( GLcontext *ctx,
|
||||
if (0)
|
||||
_mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
|
||||
|
||||
if (ib) {
|
||||
|
||||
if (ib && ctx->Extensions.ARB_draw_elements_base_vertex) {
|
||||
/* If we can just tell the hardware or the TNL to interpret our
|
||||
* indices with a different base, do so.
|
||||
*/
|
||||
tmp_prims = (struct _mesa_prim *)_mesa_malloc(sizeof(*prim) * nr_prims);
|
||||
|
||||
for (i = 0; i < nr_prims; i++) {
|
||||
tmp_prims[i] = prim[i];
|
||||
tmp_prims[i].basevertex -= min_index;
|
||||
}
|
||||
|
||||
prim = tmp_prims;
|
||||
} else if (ib) {
|
||||
/* Unfortunately need to adjust each index individually.
|
||||
*/
|
||||
GLboolean map_ib = ib->obj->Name && !ib->obj->Pointer;
|
||||
|
@@ -826,6 +826,33 @@ static void GLAPIENTRY _save_DrawRangeElements(GLenum mode,
|
||||
_mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawRangeElements" );
|
||||
}
|
||||
|
||||
static void GLAPIENTRY _save_DrawElementsBaseVertex(GLenum mode,
|
||||
GLsizei count,
|
||||
GLenum type,
|
||||
const GLvoid *indices,
|
||||
GLint basevertex)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
(void) mode; (void) count; (void) type; (void) indices; (void)basevertex;
|
||||
|
||||
_mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawElements" );
|
||||
}
|
||||
|
||||
static void GLAPIENTRY _save_DrawRangeElementsBaseVertex(GLenum mode,
|
||||
GLuint start,
|
||||
GLuint end,
|
||||
GLsizei count,
|
||||
GLenum type,
|
||||
const GLvoid *indices,
|
||||
GLint basevertex)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
(void) mode; (void) start; (void) end; (void) count; (void) type;
|
||||
(void) indices; (void)basevertex;
|
||||
|
||||
_mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawRangeElements" );
|
||||
}
|
||||
|
||||
static void GLAPIENTRY _save_DrawArrays(GLenum mode, GLint start, GLsizei count)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
@@ -907,7 +934,7 @@ static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
GLint i;
|
||||
|
||||
if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
|
||||
if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, 0 ))
|
||||
return;
|
||||
|
||||
_ae_map_vbos( ctx );
|
||||
@@ -948,7 +975,7 @@ static void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode,
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
if (_mesa_validate_DrawRangeElements( ctx, mode,
|
||||
start, end,
|
||||
count, type, indices ))
|
||||
count, type, indices, 0 ))
|
||||
_save_OBE_DrawElements( mode, count, type, indices );
|
||||
}
|
||||
|
||||
@@ -1039,9 +1066,11 @@ static void _save_vtxfmt_init( GLcontext *ctx )
|
||||
vfmt->DrawArrays = _save_DrawArrays;
|
||||
vfmt->DrawElements = _save_DrawElements;
|
||||
vfmt->DrawRangeElements = _save_DrawRangeElements;
|
||||
vfmt->DrawElementsBaseVertex = _save_DrawElementsBaseVertex;
|
||||
vfmt->DrawRangeElementsBaseVertex = _save_DrawRangeElementsBaseVertex;
|
||||
/* Loops back into vfmt->DrawElements */
|
||||
vfmt->MultiDrawElementsEXT = _mesa_noop_MultiDrawElements;
|
||||
|
||||
vfmt->MultiDrawElementsBaseVertex = _mesa_noop_MultiDrawElementsBaseVertex;
|
||||
}
|
||||
|
||||
|
||||
@@ -1233,6 +1262,7 @@ void vbo_save_api_init( struct vbo_save_context *save )
|
||||
ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements;
|
||||
/* loops back into _save_OBE_DrawElements */
|
||||
ctx->ListState.ListVtxfmt.MultiDrawElementsEXT = _mesa_noop_MultiDrawElements;
|
||||
ctx->ListState.ListVtxfmt.MultiDrawElementsBaseVertex = _mesa_noop_MultiDrawElementsBaseVertex;
|
||||
_mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
|
||||
}
|
||||
|
||||
|
@@ -50,6 +50,7 @@
|
||||
#include "main/glheader.h"
|
||||
#include "main/imports.h"
|
||||
#include "main/mtypes.h"
|
||||
#include "main/macros.h"
|
||||
|
||||
#include "vbo_split.h"
|
||||
#include "vbo.h"
|
||||
@@ -107,6 +108,11 @@ void vbo_split_prims( GLcontext *ctx,
|
||||
vbo_draw_func draw,
|
||||
const struct split_limits *limits )
|
||||
{
|
||||
GLuint max_basevertex = prim->basevertex;
|
||||
GLuint i;
|
||||
|
||||
for (i = 1; i < nr_prims; i++)
|
||||
max_basevertex = MAX2(max_basevertex, prim[i].basevertex);
|
||||
|
||||
if (ib) {
|
||||
if (limits->max_indices == 0) {
|
||||
|
@@ -589,7 +589,18 @@ void vbo_split_copy( GLcontext *ctx,
|
||||
const struct split_limits *limits )
|
||||
{
|
||||
struct copy_context copy;
|
||||
GLuint i;
|
||||
GLuint i, this_nr_prims;
|
||||
|
||||
for (i = 0; i < nr_prims;) {
|
||||
/* Our SW TNL pipeline doesn't handle basevertex yet, so bind_indices
|
||||
* will rebase the elements to the basevertex, and we'll only
|
||||
* emit strings of prims with the same basevertex in one draw call.
|
||||
*/
|
||||
for (this_nr_prims = 1; i + this_nr_prims < nr_prims;
|
||||
this_nr_prims++) {
|
||||
if (prim[i].basevertex != prim[i + this_nr_prims].basevertex)
|
||||
break;
|
||||
}
|
||||
|
||||
memset(©, 0, sizeof(copy));
|
||||
|
||||
@@ -599,8 +610,8 @@ void vbo_split_copy( GLcontext *ctx,
|
||||
|
||||
copy.ctx = ctx;
|
||||
copy.array = arrays;
|
||||
copy.prim = prim;
|
||||
copy.nr_prims = nr_prims;
|
||||
copy.prim = &prim[i];
|
||||
copy.nr_prims = this_nr_prims;
|
||||
copy.ib = ib;
|
||||
copy.draw = draw;
|
||||
copy.limits = limits;
|
||||
@@ -614,3 +625,4 @@ void vbo_split_copy( GLcontext *ctx,
|
||||
replay_elts(©);
|
||||
replay_finish(©);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user