Ver código fonte

mesa: Add support for ARB_draw_elements_base_vertex.

tags/android-x86-1.6
Eric Anholt 16 anos atrás
pai
commit
92d7ed8a20

+ 2
- 0
src/mesa/drivers/dri/swrast/swrast.c Ver arquivo

@@ -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 },

+ 2
- 0
src/mesa/drivers/x11/xm_api.c Ver arquivo

@@ -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 },

+ 76
- 2
src/mesa/main/api_noop.c Ver arquivo

@@ -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;
}

+ 7
- 0
src/mesa/main/api_noop.h Ver arquivo

@@ -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);


+ 41
- 67
src/mesa/main/api_validate.c Ver arquivo

@@ -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);
return GL_FALSE;
}
}
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 */
return GL_FALSE;
}
}
if (!check_index_bounds(ctx, count, type, indices, basevertex))
return GL_FALSE;

return GL_TRUE;
}

+ 2
- 2
src/mesa/main/api_validate.h Ver arquivo

@@ -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

+ 16
- 1
src/mesa/main/dd.h Ver arquivo

@@ -1172,7 +1172,22 @@ 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);
/*@}*/

/**
* \name Eval

+ 3
- 0
src/mesa/main/dlist.c Ver arquivo

@@ -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
}


+ 2
- 0
src/mesa/main/extensions.c Ver arquivo

@@ -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;

+ 1
- 0
src/mesa/main/mtypes.h Ver arquivo

@@ -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;

+ 15
- 0
src/mesa/main/varray.h Ver arquivo

@@ -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,

+ 3
- 0
src/mesa/main/vtxfmt.c Ver arquivo

@@ -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);

+ 41
- 0
src/mesa/main/vtxfmt_tmp.h Ver arquivo

@@ -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)
};

+ 42
- 16
src/mesa/tnl/t_draw.c Ver arquivo

@@ -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;

/* 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_indices(ctx, ib, bo, &nr_bo);
bind_prims(ctx, prim, nr_prims );
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_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);

TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx);
TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx);

unmap_vbos(ctx, bo, nr_bo);
free_space(ctx);
unmap_vbos(ctx, bo, nr_bo);
free_space(ctx);

i += this_nr_prims;
}
}
}


+ 1
- 0
src/mesa/vbo/vbo.h Ver arquivo

@@ -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

+ 113
- 18
src/mesa/vbo/vbo_exec_array.c Ver arquivo

@@ -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,
GLuint start, GLuint end,
GLsizei count, GLenum type, const GLvoid *indices)
vbo_exec_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 ))
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, 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);
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);
}

+ 14
- 1
src/mesa/vbo/vbo_rebase.c Ver arquivo

@@ -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;

+ 33
- 3
src/mesa/vbo/vbo_save_api.c Ver arquivo

@@ -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 );
}


+ 7
- 1
src/mesa/vbo/vbo_split.c Ver arquivo

@@ -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,7 +108,12 @@ 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) {
/* Could traverse the indices, re-emitting vertices in turn.

+ 32
- 20
src/mesa/vbo/vbo_split_copy.c Ver arquivo

@@ -589,28 +589,40 @@ 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(&copy, 0, sizeof(copy));
memset(&copy, 0, sizeof(copy));

/* Require indexed primitives:
*/
assert(ib);
copy.ctx = ctx;
copy.array = arrays;
copy.prim = prim;
copy.nr_prims = nr_prims;
copy.ib = ib;
copy.draw = draw;
copy.limits = limits;
/* Require indexed primitives:
*/
assert(ib);

/* Clear the vertex cache:
*/
for (i = 0; i < ELT_TABLE_SIZE; i++)
copy.vert_cache[i].in = ~0;
copy.ctx = ctx;
copy.array = arrays;
copy.prim = &prim[i];
copy.nr_prims = this_nr_prims;
copy.ib = ib;
copy.draw = draw;
copy.limits = limits;

replay_init(&copy);
replay_elts(&copy);
replay_finish(&copy);
/* Clear the vertex cache:
*/
for (i = 0; i < ELT_TABLE_SIZE; i++)
copy.vert_cache[i].in = ~0;

replay_init(&copy);
replay_elts(&copy);
replay_finish(&copy);
}
}

Carregando…
Cancelar
Salvar