Use new rebase helper. Remove other rebase code.
This commit is contained in:
@@ -198,7 +198,9 @@ static void brw_merge_inputs( struct brw_context *brw,
|
||||
brw->state.dirty.brw |= BRW_NEW_INPUT_VARYING;
|
||||
}
|
||||
|
||||
|
||||
/* XXX: could split the primitive list to fallback only on the
|
||||
* non-conformant primitives.
|
||||
*/
|
||||
static GLboolean check_fallbacks( struct brw_context *brw,
|
||||
const struct _mesa_prim *prim,
|
||||
GLuint nr_prims )
|
||||
@@ -251,7 +253,9 @@ static GLboolean check_fallbacks( struct brw_context *brw,
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* May fail if out of video memory for texture or vbo upload, or on
|
||||
* fallback conditions.
|
||||
*/
|
||||
static GLboolean brw_try_draw_prims( GLcontext *ctx,
|
||||
const struct gl_client_array *arrays[],
|
||||
const struct _mesa_prim *prim,
|
||||
@@ -376,6 +380,33 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx,
|
||||
return retval;
|
||||
}
|
||||
|
||||
static GLboolean brw_need_rebase( GLcontext *ctx,
|
||||
const struct gl_client_array *arrays[],
|
||||
const struct _mesa_index_buffer *ib,
|
||||
GLuint min_index )
|
||||
{
|
||||
if (min_index == 0)
|
||||
return GL_FALSE;
|
||||
|
||||
if (ib) {
|
||||
if (!vbo_all_varyings_in_vbos(arrays))
|
||||
return GL_TRUE;
|
||||
else
|
||||
return GL_FALSE;
|
||||
}
|
||||
else {
|
||||
/* Hmm. This isn't quite what I wanted. BRW can actually
|
||||
* handle the mixed case well enough that we shouldn't need to
|
||||
* rebase. However, it's probably not very common, nor hugely
|
||||
* expensive to do it this way:
|
||||
*/
|
||||
if (!vbo_all_varyings_in_vbos(arrays))
|
||||
return GL_TRUE;
|
||||
else
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void brw_draw_prims( GLcontext *ctx,
|
||||
const struct gl_client_array *arrays[],
|
||||
@@ -388,6 +419,21 @@ void brw_draw_prims( GLcontext *ctx,
|
||||
struct intel_context *intel = intel_context(ctx);
|
||||
GLboolean retval;
|
||||
|
||||
/* Decide if we want to rebase. If so we end up recursing once
|
||||
* only into this function.
|
||||
*/
|
||||
if (brw_need_rebase( ctx, arrays, ib, min_index )) {
|
||||
vbo_rebase_prims( ctx, arrays,
|
||||
prim, nr_prims,
|
||||
ib, min_index, max_index,
|
||||
brw_draw_prims );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Make a first attempt at drawing:
|
||||
*/
|
||||
retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
|
||||
|
||||
|
||||
@@ -440,14 +486,13 @@ void brw_draw_init( struct brw_context *brw )
|
||||
for (i = 0; i < BRW_NR_UPLOAD_BUFS; i++) {
|
||||
brw->vb.upload.vbo[i] = ctx->Driver.NewBufferObject(ctx, 1, GL_ARRAY_BUFFER_ARB);
|
||||
|
||||
/* XXX: Set these to no-backing-store
|
||||
/* NOTE: These are set to no-backing-store.
|
||||
*/
|
||||
bmBufferSetInvalidateCB(&brw->intel,
|
||||
intel_bufferobj_buffer(intel_buffer_object(brw->vb.upload.vbo[i])),
|
||||
brw_invalidate_vbo_cb,
|
||||
&brw->intel,
|
||||
GL_TRUE);
|
||||
|
||||
}
|
||||
|
||||
ctx->Driver.BufferData( ctx,
|
||||
|
@@ -309,7 +309,6 @@ copy_array_to_vbo_array( struct brw_context *brw,
|
||||
GLuint i,
|
||||
const struct gl_client_array *array,
|
||||
GLuint element_size,
|
||||
GLuint min_index,
|
||||
GLuint count)
|
||||
{
|
||||
GLcontext *ctx = &brw->intel.ctx;
|
||||
@@ -347,7 +346,7 @@ copy_array_to_vbo_array( struct brw_context *brw,
|
||||
map += offset;
|
||||
|
||||
copy_strided_array( map,
|
||||
array->Ptr + min_index * array->StrideB,
|
||||
array->Ptr,
|
||||
element_size,
|
||||
array->StrideB,
|
||||
count);
|
||||
@@ -438,10 +437,8 @@ GLboolean brw_upload_vertices( struct brw_context *brw,
|
||||
}
|
||||
|
||||
upload[nr_uploads++] = input;
|
||||
input->vbo_rebase_offset = 0;
|
||||
assert(min_index == 0);
|
||||
}
|
||||
else
|
||||
input->vbo_rebase_offset = min_index * input->glarray->StrideB;
|
||||
}
|
||||
|
||||
/* Upload interleaved arrays if all uploads are interleaved
|
||||
@@ -454,7 +451,6 @@ GLboolean brw_upload_vertices( struct brw_context *brw,
|
||||
input0->glarray = copy_array_to_vbo_array(brw, 0,
|
||||
input0->glarray,
|
||||
interleave,
|
||||
min_index,
|
||||
input0->count);
|
||||
|
||||
for (i = 1; i < nr_uploads; i++) {
|
||||
@@ -472,7 +468,6 @@ GLboolean brw_upload_vertices( struct brw_context *brw,
|
||||
input->glarray = copy_array_to_vbo_array(brw, i,
|
||||
input->glarray,
|
||||
input->element_size,
|
||||
min_index,
|
||||
input->count);
|
||||
|
||||
}
|
||||
@@ -520,9 +515,9 @@ GLboolean brw_upload_vertices( struct brw_context *brw,
|
||||
vbp.vb[i].vb0.bits.pad = 0;
|
||||
vbp.vb[i].vb0.bits.access_type = BRW_VERTEXBUFFER_ACCESS_VERTEXDATA;
|
||||
vbp.vb[i].vb0.bits.vb_index = i;
|
||||
vbp.vb[i].offset = (GLuint)input->glarray->Ptr + input->vbo_rebase_offset;
|
||||
vbp.vb[i].offset = (GLuint)input->glarray->Ptr;
|
||||
vbp.vb[i].buffer = array_buffer(input->glarray);
|
||||
vbp.vb[i].max_index = max_index - min_index;
|
||||
vbp.vb[i].max_index = max_index;
|
||||
}
|
||||
|
||||
|
||||
@@ -563,93 +558,31 @@ static GLuint element_size( GLenum type )
|
||||
|
||||
|
||||
|
||||
|
||||
static void rebase_indices_to_vbo_indices( struct brw_context *brw,
|
||||
const struct _mesa_index_buffer *index_buffer,
|
||||
struct gl_buffer_object **vbo_return,
|
||||
GLuint *offset_return )
|
||||
void brw_upload_indices( struct brw_context *brw,
|
||||
const struct _mesa_index_buffer *index_buffer )
|
||||
{
|
||||
GLcontext *ctx = &brw->intel.ctx;
|
||||
GLuint min_index = index_buffer->rebase;
|
||||
const void *indices = index_buffer->ptr;
|
||||
GLsizei count = index_buffer->count;
|
||||
GLenum type = index_buffer->type;
|
||||
GLuint size = element_size(type) * count;
|
||||
struct gl_buffer_object *bufferobj;
|
||||
GLuint offset;
|
||||
GLuint i;
|
||||
|
||||
get_space(brw, size, &bufferobj, &offset);
|
||||
|
||||
*vbo_return = bufferobj;
|
||||
*offset_return = offset;
|
||||
|
||||
if (min_index == 0) {
|
||||
/* Straight upload
|
||||
*/
|
||||
ctx->Driver.BufferSubData( ctx,
|
||||
GL_ELEMENT_ARRAY_BUFFER_ARB,
|
||||
offset,
|
||||
size,
|
||||
indices,
|
||||
bufferobj);
|
||||
}
|
||||
else {
|
||||
void *map = ctx->Driver.MapBuffer(ctx,
|
||||
GL_ELEMENT_ARRAY_BUFFER_ARB,
|
||||
GL_DYNAMIC_DRAW_ARB,
|
||||
bufferobj);
|
||||
|
||||
map += offset;
|
||||
|
||||
switch (type) {
|
||||
case GL_UNSIGNED_INT: {
|
||||
GLuint *ui_map = (GLuint *)map;
|
||||
const GLuint *ui_indices = (const GLuint *)indices;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
ui_map[i] = ui_indices[i] - min_index;
|
||||
break;
|
||||
}
|
||||
case GL_UNSIGNED_SHORT: {
|
||||
GLushort *us_map = (GLushort *)map;
|
||||
const GLushort *us_indices = (const GLushort *)indices;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
us_map[i] = us_indices[i] - min_index;
|
||||
break;
|
||||
}
|
||||
case GL_UNSIGNED_BYTE: {
|
||||
GLubyte *ub_map = (GLubyte *)map;
|
||||
const GLubyte *ub_indices = (const GLubyte *)indices;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
ub_map[i] = ub_indices[i] - min_index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->Driver.UnmapBuffer(ctx,
|
||||
GL_ELEMENT_ARRAY_BUFFER_ARB,
|
||||
bufferobj);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void brw_upload_indices( struct brw_context *brw,
|
||||
const struct _mesa_index_buffer *index_buffer)
|
||||
{
|
||||
struct intel_context *intel = &brw->intel;
|
||||
GLuint ib_size = get_size(index_buffer->type) * index_buffer->count;
|
||||
struct gl_buffer_object *bufferobj = index_buffer->obj;
|
||||
GLuint offset = (GLuint)index_buffer->ptr;
|
||||
|
||||
/* Already turned into a proper VBO:
|
||||
/* Turn into a proper VBO:
|
||||
*/
|
||||
if (!index_buffer->obj->Name) {
|
||||
rebase_indices_to_vbo_indices(brw, index_buffer, &bufferobj, &offset );
|
||||
if (!bufferobj->Name) {
|
||||
|
||||
/* Get new bufferobj, offset:
|
||||
*/
|
||||
get_space(brw, ib_size, &bufferobj, &offset);
|
||||
|
||||
/* Straight upload
|
||||
*/
|
||||
ctx->Driver.BufferSubData( ctx,
|
||||
GL_ELEMENT_ARRAY_BUFFER_ARB,
|
||||
offset,
|
||||
ib_size,
|
||||
index_buffer->ptr,
|
||||
bufferobj);
|
||||
}
|
||||
|
||||
/* Emit the indexbuffer packet:
|
||||
|
@@ -95,18 +95,14 @@ static void free_space(GLcontext *ctx)
|
||||
*/
|
||||
static void _tnl_import_array( GLcontext *ctx,
|
||||
GLuint attrib,
|
||||
GLuint start,
|
||||
GLuint end,
|
||||
GLuint count,
|
||||
const struct gl_client_array *input,
|
||||
const GLubyte *ptr )
|
||||
{
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
const GLuint count = end - start;
|
||||
GLuint stride = input->StrideB;
|
||||
|
||||
ptr += start * stride;
|
||||
|
||||
if (input->Type != GL_FLOAT) {
|
||||
const GLuint sz = input->Size;
|
||||
GLubyte *buf = get_space(ctx, count * sz * sizeof(GLfloat));
|
||||
@@ -183,7 +179,7 @@ static GLboolean *_tnl_import_edgeflag( GLcontext *ctx,
|
||||
|
||||
static void bind_inputs( GLcontext *ctx,
|
||||
const struct gl_client_array *inputs[],
|
||||
GLint min_index, GLint max_index,
|
||||
GLint count,
|
||||
struct gl_buffer_object **bo,
|
||||
GLuint *nr_bo )
|
||||
{
|
||||
@@ -215,18 +211,17 @@ static void bind_inputs( GLcontext *ctx,
|
||||
ptr = inputs[i]->Ptr;
|
||||
|
||||
/* Just make sure the array is floating point, otherwise convert to
|
||||
* temporary storage. Rebase arrays so that 'min_index' becomes
|
||||
* element zero.
|
||||
* temporary storage.
|
||||
*
|
||||
* XXX: remove the GLvector4f type at some stage and just use
|
||||
* client arrays.
|
||||
*/
|
||||
_tnl_import_array(ctx, i, min_index, max_index, inputs[i], ptr);
|
||||
_tnl_import_array(ctx, i, count, inputs[i], ptr);
|
||||
}
|
||||
|
||||
/* We process only the vertices between min & max index:
|
||||
*/
|
||||
VB->Count = max_index - min_index;
|
||||
VB->Count = count;
|
||||
|
||||
|
||||
/* Legacy pointers -- remove one day.
|
||||
@@ -264,7 +259,6 @@ static void bind_inputs( GLcontext *ctx,
|
||||
*/
|
||||
static void bind_indices( GLcontext *ctx,
|
||||
const struct _mesa_index_buffer *ib,
|
||||
GLuint min_index,
|
||||
struct gl_buffer_object **bo,
|
||||
GLuint *nr_bo)
|
||||
{
|
||||
@@ -273,8 +267,10 @@ static void bind_indices( GLcontext *ctx,
|
||||
GLuint i;
|
||||
void *ptr;
|
||||
|
||||
if (!ib)
|
||||
if (!ib) {
|
||||
VB->Elts = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ib->obj->Name && !ib->obj->Pointer) {
|
||||
bo[*nr_bo] = ib->obj;
|
||||
@@ -289,60 +285,34 @@ static void bind_indices( GLcontext *ctx,
|
||||
|
||||
ptr = ADD_POINTERS(ib->obj->Pointer, ib->ptr);
|
||||
|
||||
if (ib->type == GL_UNSIGNED_INT && min_index == 0) {
|
||||
if (ib->type == GL_UNSIGNED_INT) {
|
||||
VB->Elts = (GLuint *) ptr;
|
||||
VB->Elts += ib->rebase;
|
||||
}
|
||||
else {
|
||||
GLuint *elts = (GLuint *)get_space(ctx, ib->count * sizeof(GLuint));
|
||||
VB->Elts = elts;
|
||||
|
||||
switch (ib->type) {
|
||||
case GL_UNSIGNED_INT: {
|
||||
const GLuint *in = ((GLuint *)ptr) + ib->rebase;
|
||||
if (ib->type == GL_UNSIGNED_SHORT) {
|
||||
const GLushort *in = (GLushort *)ptr;
|
||||
for (i = 0; i < ib->count; i++)
|
||||
*elts++ = *in++ - min_index;
|
||||
break;
|
||||
*elts++ = (GLuint)(*in++);
|
||||
}
|
||||
case GL_UNSIGNED_SHORT: {
|
||||
const GLushort *in = ((GLushort *)ptr) + ib->rebase;
|
||||
else {
|
||||
const GLubyte *in = (GLubyte *)ptr;
|
||||
for (i = 0; i < ib->count; i++)
|
||||
*elts++ = (GLuint)(*in++) - min_index;
|
||||
break;
|
||||
}
|
||||
case GL_UNSIGNED_BYTE: {
|
||||
const GLubyte *in = ((GLubyte *)ptr) + ib->rebase;
|
||||
for (i = 0; i < ib->count; i++)
|
||||
*elts++ = (GLuint)(*in++) - min_index;
|
||||
break;
|
||||
}
|
||||
*elts++ = (GLuint)(*in++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void bind_prims( GLcontext *ctx,
|
||||
const struct _mesa_prim *prim,
|
||||
GLuint nr_prims,
|
||||
GLuint min_index )
|
||||
GLuint nr_prims )
|
||||
{
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
GLuint i;
|
||||
|
||||
if (min_index != 0) {
|
||||
struct _mesa_prim *tmp = (struct _mesa_prim *)get_space(ctx, nr_prims * sizeof(*prim));
|
||||
|
||||
for (i = 0; i < nr_prims; i++) {
|
||||
tmp[i] = prim[i];
|
||||
tmp[i].start -= min_index;
|
||||
}
|
||||
|
||||
VB->Primitive = tmp;
|
||||
}
|
||||
else {
|
||||
VB->Primitive = prim;
|
||||
}
|
||||
|
||||
VB->PrimitiveCount = nr_prims;
|
||||
}
|
||||
|
||||
@@ -373,19 +343,10 @@ void _tnl_draw_prims( GLcontext *ctx,
|
||||
GLuint max_index)
|
||||
{
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
GLint max = VB->Size;
|
||||
const GLuint TEST_SPLIT = 0;
|
||||
const GLint max = TEST_SPLIT ? 8 : tnl->vb.Size - MAX_CLIPPED_VERTICES;
|
||||
|
||||
#ifdef TEST_SPLIT
|
||||
max = 8 + MAX_CLIPPED_VERTICES;
|
||||
#endif
|
||||
|
||||
assert(max_index > min_index);
|
||||
assert(!(max_index & 0x80000000));
|
||||
|
||||
VB->Elts = NULL;
|
||||
|
||||
#if 0
|
||||
if (0)
|
||||
{
|
||||
GLuint i;
|
||||
_mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
|
||||
@@ -395,15 +356,22 @@ void _tnl_draw_prims( GLcontext *ctx,
|
||||
prim[i].start,
|
||||
prim[i].count);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (min_index) {
|
||||
/* We always translate away calls with min_index != 0.
|
||||
*/
|
||||
vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib,
|
||||
min_index, max_index,
|
||||
_tnl_draw_prims );
|
||||
return;
|
||||
}
|
||||
else if (max_index >= 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.
|
||||
*/
|
||||
if (max_index - min_index >= max - MAX_CLIPPED_VERTICES) {
|
||||
struct split_limits limits;
|
||||
limits.max_verts = max - MAX_CLIPPED_VERTICES;
|
||||
limits.max_verts = max;
|
||||
limits.max_vb_size = ~0;
|
||||
limits.max_indices = ~0;
|
||||
|
||||
@@ -411,7 +379,7 @@ void _tnl_draw_prims( GLcontext *ctx,
|
||||
* recursively call back into this function.
|
||||
*/
|
||||
vbo_split_prims( ctx, arrays, prim, nr_prims, ib,
|
||||
min_index, max_index,
|
||||
0, max_index,
|
||||
_tnl_draw_prims,
|
||||
&limits );
|
||||
}
|
||||
@@ -425,9 +393,9 @@ void _tnl_draw_prims( GLcontext *ctx,
|
||||
/* Binding inputs may imply mapping some vertex buffer objects.
|
||||
* They will need to be unmapped below.
|
||||
*/
|
||||
bind_inputs(ctx, arrays, min_index, max_index+1, bo, &nr_bo);
|
||||
bind_indices(ctx, ib, min_index, bo, &nr_bo);
|
||||
bind_prims(ctx, prim, nr_prims, VB->Elts ? 0 : min_index );
|
||||
bind_inputs(ctx, arrays, max_index+1, bo, &nr_bo);
|
||||
bind_indices(ctx, ib, bo, &nr_bo);
|
||||
bind_prims(ctx, prim, nr_prims );
|
||||
|
||||
TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx);
|
||||
|
||||
|
@@ -55,7 +55,6 @@ struct _mesa_index_buffer {
|
||||
GLenum type;
|
||||
struct gl_buffer_object *obj;
|
||||
const void *ptr;
|
||||
GLuint rebase;
|
||||
};
|
||||
|
||||
|
||||
|
@@ -34,45 +34,55 @@
|
||||
|
||||
#include "vbo_context.h"
|
||||
|
||||
static GLuint get_max_index( GLuint count, GLuint type,
|
||||
const GLvoid *indices )
|
||||
/* Compute min and max elements for drawelements calls.
|
||||
*/
|
||||
static void get_minmax_index( GLuint count, GLuint type,
|
||||
const GLvoid *indices,
|
||||
GLuint *min_index,
|
||||
GLuint *max_index)
|
||||
{
|
||||
GLint i;
|
||||
|
||||
/* Compute max element. This is only needed for upload of non-VBO,
|
||||
* non-constant data elements.
|
||||
*
|
||||
* XXX: Postpone this calculation until it is known that it is
|
||||
* needed. Otherwise could scan this pointlessly in the all-vbo
|
||||
* case.
|
||||
*/
|
||||
switch(type) {
|
||||
case GL_UNSIGNED_INT: {
|
||||
const GLuint *ui_indices = (const GLuint *)indices;
|
||||
GLuint max_ui = 0;
|
||||
for (i = 0; i < count; i++)
|
||||
if (ui_indices[i] > max_ui)
|
||||
max_ui = ui_indices[i];
|
||||
return max_ui;
|
||||
GLuint max_ui = ui_indices[0];
|
||||
GLuint min_ui = ui_indices[0];
|
||||
for (i = 1; i < count; i++) {
|
||||
if (ui_indices[i] > max_ui) max_ui = ui_indices[i];
|
||||
if (ui_indices[i] < min_ui) min_ui = ui_indices[i];
|
||||
}
|
||||
*min_index = min_ui;
|
||||
*max_index = max_ui;
|
||||
break;
|
||||
}
|
||||
case GL_UNSIGNED_SHORT: {
|
||||
const GLushort *us_indices = (const GLushort *)indices;
|
||||
GLuint max_us = 0;
|
||||
for (i = 0; i < count; i++)
|
||||
if (us_indices[i] > max_us)
|
||||
max_us = us_indices[i];
|
||||
return max_us;
|
||||
GLuint max_us = us_indices[0];
|
||||
GLuint min_us = us_indices[0];
|
||||
for (i = 1; i < count; i++) {
|
||||
if (us_indices[i] > max_us) max_us = us_indices[i];
|
||||
if (us_indices[i] < min_us) min_us = us_indices[i];
|
||||
}
|
||||
*min_index = min_us;
|
||||
*max_index = max_us;
|
||||
break;
|
||||
}
|
||||
case GL_UNSIGNED_BYTE: {
|
||||
const GLubyte *ub_indices = (const GLubyte *)indices;
|
||||
GLuint max_ub = 0;
|
||||
for (i = 0; i < count; i++)
|
||||
if (ub_indices[i] > max_ub)
|
||||
max_ub = ub_indices[i];
|
||||
return max_ub;
|
||||
GLuint max_ub = ub_indices[0];
|
||||
GLuint min_ub = ub_indices[0];
|
||||
for (i = 1; i < count; i++) {
|
||||
if (ub_indices[i] > max_ub) max_ub = ub_indices[i];
|
||||
if (ub_indices[i] < min_ub) min_ub = ub_indices[i];
|
||||
}
|
||||
*min_index = min_ub;
|
||||
*max_index = max_ub;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,31 +251,12 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
|
||||
prim[0].end = 1;
|
||||
prim[0].weak = 0;
|
||||
prim[0].pad = 0;
|
||||
|
||||
if (exec->array.inputs[0]->BufferObj->Name) {
|
||||
/* Use vertex attribute as a hint to tell us if we expect all
|
||||
* arrays to be in VBO's and if so, don't worry about avoiding
|
||||
* the upload of elements < start.
|
||||
*/
|
||||
prim[0].mode = mode;
|
||||
prim[0].start = start;
|
||||
prim[0].count = count;
|
||||
prim[0].indexed = 0;
|
||||
|
||||
vbo->draw_prims( ctx, exec->array.inputs, prim, 1, NULL, 0, start + count );
|
||||
}
|
||||
else {
|
||||
/* If not using VBO's, we don't want to upload any more elements
|
||||
* than necessary from the arrays as they will not be valid next
|
||||
* time the application tries to draw with them.
|
||||
*/
|
||||
prim[0].mode = mode;
|
||||
prim[0].start = 0;
|
||||
prim[0].count = count;
|
||||
prim[0].indexed = 0;
|
||||
|
||||
vbo->draw_prims( ctx, exec->array.inputs, prim, 1, NULL, start, start + count );
|
||||
}
|
||||
vbo->draw_prims( ctx, exec->array.inputs, prim, 1, NULL, start, start + count - 1 );
|
||||
}
|
||||
|
||||
|
||||
@@ -296,20 +287,6 @@ vbo_exec_DrawRangeElements(GLenum mode,
|
||||
ib.obj = ctx->Array.ElementArrayBufferObj;
|
||||
ib.ptr = indices;
|
||||
|
||||
if (ctx->Array.ElementArrayBufferObj->Name) {
|
||||
/* Use the fact that indices are in a VBO as a hint that the
|
||||
* program has put all the arrays in VBO's and we don't have to
|
||||
* worry about performance implications of start > 0.
|
||||
*
|
||||
* XXX: consider passing start as min_index to draw_prims instead.
|
||||
* XXX: don't rebase because it didn't work.
|
||||
*/
|
||||
ib.rebase = 0;
|
||||
}
|
||||
else {
|
||||
ib.rebase = /*start*/ 0;
|
||||
}
|
||||
|
||||
prim[0].begin = 1;
|
||||
prim[0].end = 1;
|
||||
prim[0].weak = 0;
|
||||
@@ -319,15 +296,46 @@ vbo_exec_DrawRangeElements(GLenum mode,
|
||||
prim[0].count = count;
|
||||
prim[0].indexed = 1;
|
||||
|
||||
vbo->draw_prims( ctx, exec->array.inputs, prim, 1, &ib, /*ib.rebase*/ start, end+1 );
|
||||
}
|
||||
/* Need to give special consideration to rendering a range of
|
||||
* indices starting somewhere above zero. Typically the
|
||||
* application is issuing multiple DrawRangeElements() to draw
|
||||
* successive primitives layed out linearly in the vertex arrays.
|
||||
* Unless the vertex arrays are all in a VBO (or locked as with
|
||||
* CVA), the OpenGL semantics imply that we need to re-read or
|
||||
* re-upload the vertex data on each draw call.
|
||||
*
|
||||
* In the case of hardware tnl, we want to avoid starting the
|
||||
* upload at zero, as it will mean every draw call uploads an
|
||||
* increasing amount of not-used vertex data. Worse - in the
|
||||
* software tnl module, all those vertices might be transformed and
|
||||
* lit but never rendered.
|
||||
*
|
||||
* If we just upload or transform the vertices in start..end,
|
||||
* however, the indices will be incorrect.
|
||||
*
|
||||
* At this level, we don't know exactly what the requirements of
|
||||
* the backend are going to be, though it will likely boil down to
|
||||
* either:
|
||||
*
|
||||
* 1) Do nothing, everything is in a VBO and is processed once
|
||||
* only.
|
||||
*
|
||||
* 2) Adjust the indices and vertex arrays so that start becomes
|
||||
* zero.
|
||||
*
|
||||
* Rather than doing anything here, I'll provide a helper function
|
||||
* for the latter case elsewhere.
|
||||
*/
|
||||
|
||||
vbo->draw_prims( ctx, exec->array.inputs, prim, 1, &ib, start, end );
|
||||
}
|
||||
|
||||
static void GLAPIENTRY
|
||||
vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
GLuint max_index;
|
||||
GLuint min_index = 0;
|
||||
GLuint max_index = 0;
|
||||
|
||||
if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
|
||||
return;
|
||||
@@ -338,17 +346,17 @@ vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *ind
|
||||
GL_READ_ONLY,
|
||||
ctx->Array.ElementArrayBufferObj);
|
||||
|
||||
max_index = get_max_index(count, type, ADD_POINTERS(map, indices));
|
||||
get_minmax_index(count, type, ADD_POINTERS(map, indices), &min_index, &max_index);
|
||||
|
||||
ctx->Driver.UnmapBuffer(ctx,
|
||||
GL_ELEMENT_ARRAY_BUFFER_ARB,
|
||||
ctx->Array.ElementArrayBufferObj);
|
||||
}
|
||||
else {
|
||||
max_index = get_max_index(count, type, indices);
|
||||
get_minmax_index(count, type, indices, &min_index, &max_index);
|
||||
}
|
||||
|
||||
vbo_exec_DrawRangeElements(mode, 0, max_index, count, type, indices);
|
||||
vbo_exec_DrawRangeElements(mode, min_index, max_index, count, type, indices);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -123,6 +123,7 @@ void vbo_rebase_prims( GLcontext *ctx,
|
||||
|
||||
assert(min_index != 0);
|
||||
|
||||
if (0)
|
||||
_mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
|
||||
|
||||
if (ib) {
|
||||
|
@@ -479,7 +479,6 @@ static void replay_init( struct copy_context *copy )
|
||||
copy->dstib.type = GL_UNSIGNED_INT;
|
||||
copy->dstib.obj = ctx->Array.NullBufferObj;
|
||||
copy->dstib.ptr = copy->dstelt;
|
||||
copy->dstib.rebase = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -223,7 +223,6 @@ static void split_prims( struct split_context *split)
|
||||
ib.type = GL_UNSIGNED_INT;
|
||||
ib.obj = split->ctx->Array.NullBufferObj;
|
||||
ib.ptr = elts;
|
||||
ib.rebase = 0; /* ? */
|
||||
|
||||
tmpprim = *prim;
|
||||
tmpprim.indexed = 1;
|
||||
|
Reference in New Issue
Block a user