mesa: Make gl_vertex_array contain pointers to first order VAO members.

Instead of keeping a copy of the vertex array content in
struct gl_vertex_array only keep pointers to the first order
information originaly in the VAO.
For that represent the current values by struct gl_array_attributes
and struct gl_vertex_buffer_binding.

v2: Change comments.
    Remove gl... prefix from variables except in the i965 directory where
    it was like that before. Reindent because of that.

Reviewed-by: Brian Paul <brianp@vmware.com>
Signed-off-by: Mathias Fröhlich <Mathias.Froehlich@web.de>
This commit is contained in:
Mathias Fröhlich 2018-03-04 18:15:53 +01:00
parent d62f0df354
commit 64d2a20480
27 changed files with 478 additions and 435 deletions

View file

@ -1459,7 +1459,7 @@ gl_clip_plane *brw_select_clip_planes(struct gl_context *ctx);
/* brw_draw_upload.c */
unsigned brw_get_vertex_surface_type(struct brw_context *brw,
const struct gl_vertex_array *glarray);
const struct gl_array_attributes *glattr);
static inline unsigned
brw_get_index_type(unsigned index_size)

View file

@ -277,7 +277,7 @@ brw_emit_prim(struct brw_context *brw,
static void
brw_merge_inputs(struct brw_context *brw,
const struct gl_vertex_array *arrays[])
const struct gl_vertex_array *arrays)
{
const struct gen_device_info *devinfo = &brw->screen->devinfo;
const struct gl_context *ctx = &brw->ctx;
@ -291,7 +291,7 @@ brw_merge_inputs(struct brw_context *brw,
for (i = 0; i < VERT_ATTRIB_MAX; i++) {
brw->vb.inputs[i].buffer = -1;
brw->vb.inputs[i].glarray = arrays[i];
brw->vb.inputs[i].glarray = &arrays[i];
}
if (devinfo->gen < 8 && !devinfo->is_haswell) {
@ -300,14 +300,16 @@ brw_merge_inputs(struct brw_context *brw,
* 2_10_10_10_REV vertex formats. Set appropriate workaround flags.
*/
while (mask) {
const struct gl_array_attributes *glattrib;
uint8_t wa_flags = 0;
i = u_bit_scan64(&mask);
glattrib = brw->vb.inputs[i].glarray->VertexAttrib;
switch (brw->vb.inputs[i].glarray->Type) {
switch (glattrib->Type) {
case GL_FIXED:
wa_flags = brw->vb.inputs[i].glarray->Size;
wa_flags = glattrib->Size;
break;
case GL_INT_2_10_10_10_REV:
@ -315,12 +317,12 @@ brw_merge_inputs(struct brw_context *brw,
/* fallthough */
case GL_UNSIGNED_INT_2_10_10_10_REV:
if (brw->vb.inputs[i].glarray->Format == GL_BGRA)
if (glattrib->Format == GL_BGRA)
wa_flags |= BRW_ATTRIB_WA_BGRA;
if (brw->vb.inputs[i].glarray->Normalized)
if (glattrib->Normalized)
wa_flags |= BRW_ATTRIB_WA_NORMALIZE;
else if (!brw->vb.inputs[i].glarray->Integer)
else if (!glattrib->Integer)
wa_flags |= BRW_ATTRIB_WA_SCALE;
break;
@ -689,7 +691,7 @@ brw_postdraw_reconcile_align_wa_slices(struct brw_context *brw)
static void
brw_prepare_drawing(struct gl_context *ctx,
const struct gl_vertex_array *arrays[],
const struct gl_vertex_array *arrays,
const struct _mesa_index_buffer *ib,
bool index_bounds_valid,
GLuint min_index,
@ -776,7 +778,7 @@ brw_finish_drawing(struct gl_context *ctx)
*/
static void
brw_draw_single_prim(struct gl_context *ctx,
const struct gl_vertex_array *arrays[],
const struct gl_vertex_array *arrays,
const struct _mesa_prim *prim,
unsigned prim_id,
struct brw_transform_feedback_object *xfb_obj,
@ -911,13 +913,13 @@ retry:
static bool
all_varyings_in_vbos(const struct gl_vertex_array *arrays[])
all_varyings_in_vbos(const struct gl_vertex_array *arrays)
{
GLuint i;
for (i = 0; i < VERT_ATTRIB_MAX; i++)
if (arrays[i]->StrideB &&
arrays[i]->BufferObj->Name == 0)
if (arrays[i].BufferBinding->Stride &&
arrays[i].BufferBinding->BufferObj->Name == 0)
return false;
return true;
@ -939,7 +941,7 @@ brw_draw_prims(struct gl_context *ctx,
{
unsigned i;
struct brw_context *brw = brw_context(ctx);
const struct gl_vertex_array **arrays = ctx->Array._DrawArrays;
const struct gl_vertex_array *arrays = ctx->Array._DrawArrays;
int predicate_state = brw->predicate.state;
struct brw_transform_feedback_object *xfb_obj =
(struct brw_transform_feedback_object *) gl_xfb_obj;

View file

@ -249,21 +249,21 @@ double_types(struct brw_context *brw,
*/
unsigned
brw_get_vertex_surface_type(struct brw_context *brw,
const struct gl_vertex_array *glarray)
const struct gl_array_attributes *glattrib)
{
int size = glarray->Size;
int size = glattrib->Size;
const struct gen_device_info *devinfo = &brw->screen->devinfo;
const bool is_ivybridge_or_older =
devinfo->gen <= 7 && !devinfo->is_baytrail && !devinfo->is_haswell;
if (unlikely(INTEL_DEBUG & DEBUG_VERTS))
fprintf(stderr, "type %s size %d normalized %d\n",
_mesa_enum_to_string(glarray->Type),
glarray->Size, glarray->Normalized);
_mesa_enum_to_string(glattrib->Type),
glattrib->Size, glattrib->Normalized);
if (glarray->Integer) {
assert(glarray->Format == GL_RGBA); /* sanity check */
switch (glarray->Type) {
if (glattrib->Integer) {
assert(glattrib->Format == GL_RGBA); /* sanity check */
switch (glattrib->Type) {
case GL_INT: return int_types_direct[size];
case GL_SHORT:
if (is_ivybridge_or_older && size == 3)
@ -288,11 +288,11 @@ brw_get_vertex_surface_type(struct brw_context *brw,
return ubyte_types_direct[size];
default: unreachable("not reached");
}
} else if (glarray->Type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
} else if (glattrib->Type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
return ISL_FORMAT_R11G11B10_FLOAT;
} else if (glarray->Normalized) {
switch (glarray->Type) {
case GL_DOUBLE: return double_types(brw, size, glarray->Doubles);
} else if (glattrib->Normalized) {
switch (glattrib->Type) {
case GL_DOUBLE: return double_types(brw, size, glattrib->Doubles);
case GL_FLOAT: return float_types[size];
case GL_HALF_FLOAT:
case GL_HALF_FLOAT_OES:
@ -306,7 +306,7 @@ brw_get_vertex_surface_type(struct brw_context *brw,
case GL_UNSIGNED_INT: return uint_types_norm[size];
case GL_UNSIGNED_SHORT: return ushort_types_norm[size];
case GL_UNSIGNED_BYTE:
if (glarray->Format == GL_BGRA) {
if (glattrib->Format == GL_BGRA) {
/* See GL_EXT_vertex_array_bgra */
assert(size == 4);
return ISL_FORMAT_B8G8R8A8_UNORM;
@ -330,7 +330,7 @@ brw_get_vertex_surface_type(struct brw_context *brw,
case GL_INT_2_10_10_10_REV:
assert(size == 4);
if (devinfo->gen >= 8 || devinfo->is_haswell) {
return glarray->Format == GL_BGRA
return glattrib->Format == GL_BGRA
? ISL_FORMAT_B10G10R10A2_SNORM
: ISL_FORMAT_R10G10B10A2_SNORM;
}
@ -338,7 +338,7 @@ brw_get_vertex_surface_type(struct brw_context *brw,
case GL_UNSIGNED_INT_2_10_10_10_REV:
assert(size == 4);
if (devinfo->gen >= 8 || devinfo->is_haswell) {
return glarray->Format == GL_BGRA
return glattrib->Format == GL_BGRA
? ISL_FORMAT_B10G10R10A2_UNORM
: ISL_FORMAT_R10G10B10A2_UNORM;
}
@ -352,26 +352,26 @@ brw_get_vertex_surface_type(struct brw_context *brw,
* like to use here, so upload everything as UINT and fix
* it in the shader
*/
if (glarray->Type == GL_INT_2_10_10_10_REV) {
if (glattrib->Type == GL_INT_2_10_10_10_REV) {
assert(size == 4);
if (devinfo->gen >= 8 || devinfo->is_haswell) {
return glarray->Format == GL_BGRA
return glattrib->Format == GL_BGRA
? ISL_FORMAT_B10G10R10A2_SSCALED
: ISL_FORMAT_R10G10B10A2_SSCALED;
}
return ISL_FORMAT_R10G10B10A2_UINT;
} else if (glarray->Type == GL_UNSIGNED_INT_2_10_10_10_REV) {
} else if (glattrib->Type == GL_UNSIGNED_INT_2_10_10_10_REV) {
assert(size == 4);
if (devinfo->gen >= 8 || devinfo->is_haswell) {
return glarray->Format == GL_BGRA
return glattrib->Format == GL_BGRA
? ISL_FORMAT_B10G10R10A2_USCALED
: ISL_FORMAT_R10G10B10A2_USCALED;
}
return ISL_FORMAT_R10G10B10A2_UINT;
}
assert(glarray->Format == GL_RGBA); /* sanity check */
switch (glarray->Type) {
case GL_DOUBLE: return double_types(brw, size, glarray->Doubles);
assert(glattrib->Format == GL_RGBA); /* sanity check */
switch (glattrib->Type) {
case GL_DOUBLE: return double_types(brw, size, glattrib->Doubles);
case GL_FLOAT: return float_types[size];
case GL_HALF_FLOAT:
case GL_HALF_FLOAT_OES:
@ -405,24 +405,25 @@ copy_array_to_vbo_array(struct brw_context *brw,
struct brw_vertex_buffer *buffer,
GLuint dst_stride)
{
const int src_stride = element->glarray->StrideB;
const struct gl_vertex_array *glarray = element->glarray;
const struct gl_vertex_buffer_binding *glbinding = glarray->BufferBinding;
const struct gl_array_attributes *glattrib = glarray->VertexAttrib;
const int src_stride = glbinding->Stride;
/* If the source stride is zero, we just want to upload the current
* attribute once and set the buffer's stride to 0. There's no need
* to replicate it out.
*/
if (src_stride == 0) {
brw_upload_data(&brw->upload, element->glarray->Ptr,
element->glarray->_ElementSize,
element->glarray->_ElementSize,
&buffer->bo, &buffer->offset);
brw_upload_data(&brw->upload, glattrib->Ptr, glattrib->_ElementSize,
glattrib->_ElementSize, &buffer->bo, &buffer->offset);
buffer->stride = 0;
buffer->size = element->glarray->_ElementSize;
buffer->size = glattrib->_ElementSize;
return;
}
const unsigned char *src = element->glarray->Ptr + min * src_stride;
const unsigned char *src = glattrib->Ptr + min * src_stride;
int count = max - min + 1;
GLuint size = count * dst_stride;
uint8_t *dst = brw_upload_space(&brw->upload, size, dst_stride,
@ -514,28 +515,30 @@ brw_prepare_vertices(struct brw_context *brw)
for (i = j = 0; i < brw->vb.nr_enabled; i++) {
struct brw_vertex_element *input = brw->vb.enabled[i];
const struct gl_vertex_array *glarray = input->glarray;
const struct gl_vertex_buffer_binding *glbinding = glarray->BufferBinding;
const struct gl_array_attributes *glattrib = glarray->VertexAttrib;
if (_mesa_is_bufferobj(glarray->BufferObj)) {
if (_mesa_is_bufferobj(glbinding->BufferObj)) {
struct intel_buffer_object *intel_buffer =
intel_buffer_object(glarray->BufferObj);
intel_buffer_object(glbinding->BufferObj);
const uint32_t offset = (uintptr_t)glarray->Ptr;
const uint32_t offset = glbinding->Offset + glattrib->RelativeOffset;
/* Start with the worst case */
uint32_t start = 0;
uint32_t range = intel_buffer->Base.Size;
if (glarray->InstanceDivisor) {
if (glbinding->InstanceDivisor) {
if (brw->num_instances) {
start = offset + glarray->StrideB * brw->baseinstance;
range = (glarray->StrideB * ((brw->num_instances - 1) /
glarray->InstanceDivisor) +
glarray->_ElementSize);
start = offset + glbinding->Stride * brw->baseinstance;
range = (glbinding->Stride * ((brw->num_instances - 1) /
glbinding->InstanceDivisor) +
glattrib->_ElementSize);
}
} else {
if (brw->vb.index_bounds_valid) {
start = offset + min_index * glarray->StrideB;
range = (glarray->StrideB * (max_index - min_index) +
glarray->_ElementSize);
start = offset + min_index * glbinding->Stride;
range = (glbinding->Stride * (max_index - min_index) +
glattrib->_ElementSize);
}
}
@ -546,13 +549,16 @@ brw_prepare_vertices(struct brw_context *brw)
unsigned k;
for (k = 0; k < i; k++) {
const struct gl_vertex_array *other = brw->vb.enabled[k]->glarray;
if (glarray->BufferObj == other->BufferObj &&
glarray->StrideB == other->StrideB &&
glarray->InstanceDivisor == other->InstanceDivisor &&
(uintptr_t)(glarray->Ptr - other->Ptr) < glarray->StrideB)
const struct gl_vertex_buffer_binding *obind = other->BufferBinding;
const struct gl_array_attributes *oattrib = other->VertexAttrib;
const uint32_t ooffset = obind->Offset + oattrib->RelativeOffset;
if (glbinding->BufferObj == obind->BufferObj &&
glbinding->Stride == obind->Stride &&
glbinding->InstanceDivisor == obind->InstanceDivisor &&
(offset - ooffset) < glbinding->Stride)
{
input->buffer = brw->vb.enabled[k]->buffer;
input->offset = glarray->Ptr - other->Ptr;
input->offset = offset - ooffset;
buffer_range_start[input->buffer] =
MIN2(buffer_range_start[input->buffer], start);
@ -566,9 +572,9 @@ brw_prepare_vertices(struct brw_context *brw)
/* Named buffer object: Just reference its contents directly. */
buffer->offset = offset;
buffer->stride = glarray->StrideB;
buffer->step_rate = glarray->InstanceDivisor;
buffer->size = glarray->BufferObj->Size - offset;
buffer->stride = glbinding->Stride;
buffer->step_rate = glbinding->InstanceDivisor;
buffer->size = glbinding->BufferObj->Size - offset;
enabled_buffer[j] = intel_buffer;
buffer_range_start[j] = start;
@ -582,13 +588,13 @@ brw_prepare_vertices(struct brw_context *brw)
* when we've decided if we're doing interleaved or not.
*/
if (nr_uploads == 0) {
interleaved = glarray->StrideB;
ptr = glarray->Ptr;
interleaved = glbinding->Stride;
ptr = glattrib->Ptr;
}
else if (interleaved != glarray->StrideB ||
glarray->InstanceDivisor != 0 ||
glarray->Ptr < ptr ||
(uintptr_t)(glarray->Ptr - ptr) + glarray->_ElementSize > interleaved)
else if (interleaved != glbinding->Stride ||
glbinding->InstanceDivisor != 0 ||
glattrib->Ptr < ptr ||
(uintptr_t)(glattrib->Ptr - ptr) + glattrib->_ElementSize > interleaved)
{
/* If our stride is different from the first attribute's stride,
* or if we are using an instance divisor or if the first
@ -654,9 +660,10 @@ brw_prepare_vertices(struct brw_context *brw)
buffer->step_rate = 0;
for (i = 0; i < nr_uploads; i++) {
const struct gl_vertex_array *glarray = upload[i]->glarray;
const struct gl_array_attributes *glattrib = glarray->VertexAttrib;
/* Then, just point upload[i] at upload[0]'s buffer. */
upload[i]->offset =
((const unsigned char *)upload[i]->glarray->Ptr - ptr);
upload[i]->offset = ((const unsigned char *)glattrib->Ptr - ptr);
upload[i]->buffer = j;
}
j++;
@ -667,22 +674,25 @@ brw_prepare_vertices(struct brw_context *brw)
/* Upload non-interleaved arrays */
for (i = 0; i < nr_uploads; i++) {
struct brw_vertex_buffer *buffer = &brw->vb.buffers[j];
if (upload[i]->glarray->InstanceDivisor == 0) {
const struct gl_vertex_array *glarray = upload[i]->glarray;
const struct gl_vertex_buffer_binding *glbinding = glarray->BufferBinding;
const struct gl_array_attributes *glattrib = glarray->VertexAttrib;
if (glbinding->InstanceDivisor == 0) {
copy_array_to_vbo_array(brw, upload[i], min_index, max_index,
buffer, upload[i]->glarray->_ElementSize);
buffer, glattrib->_ElementSize);
} else {
/* This is an instanced attribute, since its InstanceDivisor
* is not zero. Therefore, its data will be stepped after the
* instanced draw has been run InstanceDivisor times.
*/
uint32_t instanced_attr_max_index =
(brw->num_instances - 1) / upload[i]->glarray->InstanceDivisor;
(brw->num_instances - 1) / glbinding->InstanceDivisor;
copy_array_to_vbo_array(brw, upload[i], 0, instanced_attr_max_index,
buffer, upload[i]->glarray->_ElementSize);
buffer, glattrib->_ElementSize);
}
buffer->offset -= delta * buffer->stride;
buffer->size += delta * buffer->stride;
buffer->step_rate = upload[i]->glarray->InstanceDivisor;
buffer->step_rate = glbinding->InstanceDivisor;
upload[i]->buffer = j++;
upload[i]->offset = 0;
}

View file

@ -553,7 +553,9 @@ genX(emit_vertices)(struct brw_context *brw)
*/
for (unsigned i = 0; i < brw->vb.nr_enabled; i++) {
struct brw_vertex_element *input = brw->vb.enabled[i];
uint32_t format = brw_get_vertex_surface_type(brw, input->glarray);
const struct gl_vertex_array *glarray = input->glarray;
const struct gl_array_attributes *glattrib = glarray->VertexAttrib;
uint32_t format = brw_get_vertex_surface_type(brw, glattrib);
if (uploads_needed(format, input->is_dual_slot) > 1)
nr_elements++;
@ -646,7 +648,9 @@ genX(emit_vertices)(struct brw_context *brw)
unsigned i;
for (i = 0; i < brw->vb.nr_enabled; i++) {
const struct brw_vertex_element *input = brw->vb.enabled[i];
uint32_t format = brw_get_vertex_surface_type(brw, input->glarray);
const struct gl_vertex_array *glarray = input->glarray;
const struct gl_array_attributes *glattrib = glarray->VertexAttrib;
uint32_t format = brw_get_vertex_surface_type(brw, glattrib);
uint32_t comp0 = VFCOMP_STORE_SRC;
uint32_t comp1 = VFCOMP_STORE_SRC;
uint32_t comp2 = VFCOMP_STORE_SRC;
@ -687,17 +691,19 @@ genX(emit_vertices)(struct brw_context *brw)
* entry. */
const unsigned offset = input->offset + c * 16;
const struct gl_vertex_array *glarray = input->glarray;
const struct gl_array_attributes *glattrib = glarray->VertexAttrib;
const int size = (GEN_GEN < 8 && is_passthru_format(format)) ?
upload_format_size(upload_format) : input->glarray->Size;
upload_format_size(upload_format) : glattrib->Size;
switch (size) {
case 0: comp0 = VFCOMP_STORE_0;
case 1: comp1 = VFCOMP_STORE_0;
case 2: comp2 = VFCOMP_STORE_0;
case 3:
if (GEN_GEN >= 8 && input->glarray->Doubles) {
if (GEN_GEN >= 8 && glattrib->Doubles) {
comp3 = VFCOMP_STORE_0;
} else if (input->glarray->Integer) {
} else if (glattrib->Integer) {
comp3 = VFCOMP_STORE_1_INT;
} else {
comp3 = VFCOMP_STORE_1_FP;
@ -722,7 +728,7 @@ genX(emit_vertices)(struct brw_context *brw)
* to be specified as VFCOMP_STORE_0 in order to output a 256-bit
* vertex element."
*/
if (input->glarray->Doubles && !input->is_dual_slot) {
if (glattrib->Doubles && !input->is_dual_slot) {
/* Store vertex elements which correspond to double and dvec2 vertex
* shader inputs as 128-bit vertex elements, instead of 256-bits.
*/
@ -810,8 +816,9 @@ genX(emit_vertices)(struct brw_context *brw)
#if GEN_GEN >= 6
if (gen6_edgeflag_input) {
const uint32_t format =
brw_get_vertex_surface_type(brw, gen6_edgeflag_input->glarray);
const struct gl_vertex_array *glarray = gen6_edgeflag_input->glarray;
const struct gl_array_attributes *glattrib = glarray->VertexAttrib;
const uint32_t format = brw_get_vertex_surface_type(brw, glattrib);
struct GENX(VERTEX_ELEMENT_STATE) elem_state = {
.Valid = true,

View file

@ -30,6 +30,7 @@
#include "main/bufferobj.h"
#include "main/glformats.h"
#include "main/varray.h"
#include "main/image.h"
/* Arbitrary pushbuf length we can assume we can get with a single
@ -43,17 +44,20 @@ static int
get_array_stride(struct gl_context *ctx, const struct gl_vertex_array *a)
{
struct nouveau_render_state *render = to_render_state(ctx);
const struct gl_vertex_buffer_binding *binding = a->BufferBinding;
if (render->mode == VBO && !_mesa_is_bufferobj(a->BufferObj))
if (render->mode == VBO && !_mesa_is_bufferobj(binding->BufferObj)) {
const struct gl_array_attributes *attrib = a->VertexAttrib;
/* Pack client buffers. */
return align(_mesa_sizeof_type(a->Type) * a->Size, 4);
else
return a->StrideB;
return align(_mesa_sizeof_type(attrib->Type) * attrib->Size, 4);
} else {
return binding->Stride;
}
}
static void
vbo_init_arrays(struct gl_context *ctx, const struct _mesa_index_buffer *ib,
const struct gl_vertex_array **arrays)
const struct gl_vertex_array *arrays)
{
struct nouveau_render_state *render = to_render_state(ctx);
GLboolean imm = (render->mode == IMM);
@ -74,19 +78,23 @@ vbo_init_arrays(struct gl_context *ctx, const struct _mesa_index_buffer *ib,
}
FOR_EACH_BOUND_ATTR(render, i, attr) {
const struct gl_vertex_array *array = arrays[attr];
const struct gl_vertex_array *array = &arrays[attr];
const struct gl_vertex_buffer_binding *binding =
array->BufferBinding;
const struct gl_array_attributes *attrib = array->VertexAttrib;
const GLubyte *p = _mesa_vertex_attrib_address(attrib, binding);
nouveau_init_array(&render->attrs[attr], attr,
get_array_stride(ctx, array),
array->Size, array->Type,
imm ? array->BufferObj : NULL,
array->Ptr, imm, ctx);
attrib->Size, attrib->Type,
imm ? binding->BufferObj : NULL,
p, imm, ctx);
}
}
static void
vbo_deinit_arrays(struct gl_context *ctx, const struct _mesa_index_buffer *ib,
const struct gl_vertex_array **arrays)
const struct gl_vertex_array *arrays)
{
struct nouveau_render_state *render = to_render_state(ctx);
int i, attr;
@ -110,7 +118,7 @@ vbo_deinit_arrays(struct gl_context *ctx, const struct _mesa_index_buffer *ib,
/* Make some rendering decisions from the GL context. */
static void
vbo_choose_render_mode(struct gl_context *ctx, const struct gl_vertex_array **arrays)
vbo_choose_render_mode(struct gl_context *ctx, const struct gl_vertex_array *arrays)
{
struct nouveau_render_state *render = to_render_state(ctx);
int i;
@ -119,7 +127,7 @@ vbo_choose_render_mode(struct gl_context *ctx, const struct gl_vertex_array **ar
if (ctx->Light.Enabled) {
for (i = 0; i < VERT_ATTRIB_MAT_MAX; i++) {
if (arrays[VERT_ATTRIB_MAT(i)]->StrideB) {
if (arrays[VERT_ATTRIB_MAT(i)].BufferBinding->Stride) {
render->mode = IMM;
break;
}
@ -128,23 +136,26 @@ vbo_choose_render_mode(struct gl_context *ctx, const struct gl_vertex_array **ar
}
static void
vbo_emit_attr(struct gl_context *ctx, const struct gl_vertex_array **arrays,
vbo_emit_attr(struct gl_context *ctx, const struct gl_vertex_array *arrays,
int attr)
{
struct nouveau_pushbuf *push = context_push(ctx);
struct nouveau_render_state *render = to_render_state(ctx);
const struct gl_vertex_array *array = arrays[attr];
const struct gl_vertex_array *array = &arrays[attr];
const struct gl_vertex_buffer_binding *binding = array->BufferBinding;
const struct gl_array_attributes *attrib = array->VertexAttrib;
const GLubyte *p = _mesa_vertex_attrib_address(attrib, binding);
struct nouveau_array *a = &render->attrs[attr];
RENDER_LOCALS(ctx);
if (!array->StrideB) {
if (!binding->Stride) {
if (attr >= VERT_ATTRIB_MAT(0))
/* nouveau_update_state takes care of materials. */
return;
/* Constant attribute. */
nouveau_init_array(a, attr, array->StrideB, array->Size,
array->Type, array->BufferObj, array->Ptr,
nouveau_init_array(a, attr, binding->Stride, attrib->Size,
attrib->Type, binding->BufferObj, p,
GL_TRUE, ctx);
EMIT_IMM(ctx, a, 0);
nouveau_deinit_array(a);
@ -155,7 +166,7 @@ vbo_emit_attr(struct gl_context *ctx, const struct gl_vertex_array **arrays,
if (render->mode == VBO) {
render->map[info->vbo_index] = attr;
render->vertex_size += array->_ElementSize;
render->vertex_size += attrib->_ElementSize;
render->attr_count = MAX2(render->attr_count,
info->vbo_index + 1);
} else {
@ -168,7 +179,7 @@ vbo_emit_attr(struct gl_context *ctx, const struct gl_vertex_array **arrays,
#define MAT(a) VERT_ATTRIB_MAT(MAT_ATTRIB_##a)
static void
vbo_choose_attrs(struct gl_context *ctx, const struct gl_vertex_array **arrays)
vbo_choose_attrs(struct gl_context *ctx, const struct gl_vertex_array *arrays)
{
struct nouveau_render_state *render = to_render_state(ctx);
int i;
@ -211,15 +222,15 @@ vbo_choose_attrs(struct gl_context *ctx, const struct gl_vertex_array **arrays)
}
static int
get_max_client_stride(struct gl_context *ctx, const struct gl_vertex_array **arrays)
get_max_client_stride(struct gl_context *ctx, const struct gl_vertex_array *arrays)
{
struct nouveau_render_state *render = to_render_state(ctx);
int i, attr, s = 0;
FOR_EACH_BOUND_ATTR(render, i, attr) {
const struct gl_vertex_array *a = arrays[attr];
const struct gl_vertex_array *a = &arrays[attr];
if (!_mesa_is_bufferobj(a->BufferObj))
if (!_mesa_is_bufferobj(a->BufferBinding->BufferObj))
s = MAX2(s, get_array_stride(ctx, a));
}
@ -237,7 +248,7 @@ TAG(vbo_render_prims)(struct gl_context *ctx,
struct gl_buffer_object *indirect);
static GLboolean
vbo_maybe_split(struct gl_context *ctx, const struct gl_vertex_array **arrays,
vbo_maybe_split(struct gl_context *ctx, const struct gl_vertex_array *arrays,
const struct _mesa_prim *prims, GLuint nr_prims,
const struct _mesa_index_buffer *ib,
GLuint min_index, GLuint max_index)
@ -297,7 +308,7 @@ check_update_array(struct nouveau_array *a, unsigned offset,
}
static void
vbo_bind_vertices(struct gl_context *ctx, const struct gl_vertex_array **arrays,
vbo_bind_vertices(struct gl_context *ctx, const struct gl_vertex_array *arrays,
int base, unsigned min_index, unsigned max_index, int *pdelta)
{
struct nouveau_render_state *render = to_render_state(ctx);
@ -311,22 +322,26 @@ vbo_bind_vertices(struct gl_context *ctx, const struct gl_vertex_array **arrays,
*pdelta = -1;
FOR_EACH_BOUND_ATTR(render, i, attr) {
const struct gl_vertex_array *array = arrays[attr];
struct gl_buffer_object *obj = array->BufferObj;
const struct gl_vertex_array *array = &arrays[attr];
const struct gl_vertex_buffer_binding *binding =
array->BufferBinding;
const struct gl_array_attributes *attrib = array->VertexAttrib;
const GLubyte *p = _mesa_vertex_attrib_address(attrib, binding);
struct gl_buffer_object *obj = binding->BufferObj;
struct nouveau_array *a = &render->attrs[attr];
unsigned delta = (base + min_index) * array->StrideB;
unsigned delta = (base + min_index) * binding->Stride;
bo[i] = NULL;
if (nouveau_bufferobj_hw(obj)) {
/* Array in a buffer obj. */
nouveau_bo_ref(to_nouveau_bufferobj(obj)->bo, &bo[i]);
offset[i] = delta + (intptr_t)array->Ptr;
offset[i] = delta + (intptr_t)p;
} else {
int n = max_index - min_index + 1;
char *sp = (char *)ADD_POINTERS(
nouveau_bufferobj_sys(obj), array->Ptr) + delta;
nouveau_bufferobj_sys(obj), p) + delta;
char *dp = nouveau_get_scratch(ctx, n * a->stride,
&bo[i], &offset[i]);
@ -334,7 +349,7 @@ vbo_bind_vertices(struct gl_context *ctx, const struct gl_vertex_array **arrays,
* scratch buffer obj. */
for (j = 0; j < n; j++)
memcpy(dp + j * a->stride,
sp + j * array->StrideB,
sp + j * binding->Stride,
a->stride);
}
@ -365,7 +380,7 @@ vbo_bind_vertices(struct gl_context *ctx, const struct gl_vertex_array **arrays,
}
static void
vbo_draw_vbo(struct gl_context *ctx, const struct gl_vertex_array **arrays,
vbo_draw_vbo(struct gl_context *ctx, const struct gl_vertex_array *arrays,
const struct _mesa_prim *prims, GLuint nr_prims,
const struct _mesa_index_buffer *ib, GLuint min_index,
GLuint max_index)
@ -415,7 +430,7 @@ extract_id(struct nouveau_array *a, int i, int j)
}
static void
vbo_draw_imm(struct gl_context *ctx, const struct gl_vertex_array **arrays,
vbo_draw_imm(struct gl_context *ctx, const struct gl_vertex_array *arrays,
const struct _mesa_prim *prims, GLuint nr_prims,
const struct _mesa_index_buffer *ib, GLuint min_index,
GLuint max_index)
@ -470,7 +485,7 @@ TAG(vbo_render_prims)(struct gl_context *ctx,
struct gl_buffer_object *indirect)
{
struct nouveau_render_state *render = to_render_state(ctx);
const struct gl_vertex_array **arrays = ctx->Array._DrawArrays;
const struct gl_vertex_array *arrays = ctx->Array._DrawArrays;
if (!index_bounds_valid)
vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index,

View file

@ -284,9 +284,6 @@ unbind_array_object_vbos(struct gl_context *ctx, struct gl_vertex_array_object *
for (i = 0; i < ARRAY_SIZE(obj->BufferBinding); i++)
_mesa_reference_buffer_object(ctx, &obj->BufferBinding[i].BufferObj, NULL);
for (i = 0; i < ARRAY_SIZE(obj->_VertexArray); i++)
_mesa_reference_buffer_object(ctx, &obj->_VertexArray[i].BufferObj, NULL);
}
@ -462,21 +459,8 @@ void
_mesa_update_vao_derived_arrays(struct gl_context *ctx,
struct gl_vertex_array_object *vao)
{
GLbitfield arrays = vao->NewArrays;
/* Make sure we do not run into problems with shared objects */
assert(!vao->SharedAndImmutable || vao->NewArrays == 0);
while (arrays) {
const int attrib = u_bit_scan(&arrays);
struct gl_vertex_array *array = &vao->_VertexArray[attrib];
const struct gl_array_attributes *attribs =
&vao->VertexAttrib[attrib];
const struct gl_vertex_buffer_binding *buffer_binding =
&vao->BufferBinding[attribs->BufferBindingIndex];
_mesa_update_vertex_array(ctx, array, attribs, buffer_binding);
}
}

View file

@ -1507,7 +1507,6 @@ copy_array_object(struct gl_context *ctx,
/* skip RefCount */
for (i = 0; i < ARRAY_SIZE(src->VertexAttrib); i++) {
_mesa_copy_vertex_array(ctx, &dest->_VertexArray[i], &src->_VertexArray[i]);
_mesa_copy_vertex_attrib_array(ctx, &dest->VertexAttrib[i], &src->VertexAttrib[i]);
_mesa_copy_vertex_buffer_binding(ctx, &dest->BufferBinding[i], &src->BufferBinding[i]);
}

View file

@ -1503,29 +1503,6 @@ struct gl_pixelstore_attrib
};
/**
* Vertex array information which is derived from gl_array_attributes
* and gl_vertex_buffer_binding information. Used by the VBO module and
* device drivers.
*/
struct gl_vertex_array
{
/** if NULL, vertex data are in user memory */
struct gl_buffer_object *BufferObj;
/** Pointer into user memory, or offset into the BufferObj */
const GLubyte *Ptr;
GLsizei StrideB; /**< actual stride in bytes */
GLuint InstanceDivisor; /**< GL_ARB_instanced_arrays */
GLenum16 Type; /**< datatype: GL_FLOAT, GL_INT, etc */
GLenum16 Format; /**< default: GL_RGBA, but may be GL_BGRA */
unsigned Size:4; /**< components per element (1,2,3,4) */
unsigned _ElementSize:8; /**< in bytes, up to 4*sizeof(GLdouble) */
unsigned Normalized:1; /**< GL_ARB_vertex_program */
unsigned Integer:1; /**< Integer-valued? */
unsigned Doubles:1; /**< doubles not converted to floats */
};
/**
* Enum for defining the mapping for the position/generic0 attribute.
*
@ -1589,6 +1566,20 @@ struct gl_vertex_buffer_binding
};
/**
* Vertex array information which is derived from gl_array_attributes
* and gl_vertex_buffer_binding information. Used by the VBO module and
* device drivers.
*/
struct gl_vertex_array
{
/** Vertex attribute array */
const struct gl_array_attributes *VertexAttrib;
/** Vertex buffer binding */
const struct gl_vertex_buffer_binding *BufferBinding;
};
/**
* A representation of "Vertex Array Objects" (VAOs) from OpenGL 3.1+ /
* the GL_ARB_vertex_array_object extension.
@ -1614,14 +1605,6 @@ struct gl_vertex_array_object
*/
bool SharedAndImmutable;
/**
* Derived vertex attribute arrays
*
* This is a legacy data structure created from gl_array_attributes and
* gl_vertex_buffer_binding, only used by the VBO module at this time.
*/
struct gl_vertex_array _VertexArray[VERT_ATTRIB_MAX];
/** Vertex attribute arrays */
struct gl_array_attributes VertexAttrib[VERT_ATTRIB_MAX];
@ -1724,7 +1707,7 @@ struct gl_array_attrib
* Vertex arrays as consumed by a driver.
* The array pointer is set up only by the VBO module.
*/
const struct gl_vertex_array **_DrawArrays; /**< 0..VERT_ATTRIB_MAX-1 */
const struct gl_vertex_array *_DrawArrays; /**< 0..VERT_ATTRIB_MAX-1 */
/** Legal array datatypes and the API for which they have been computed */
GLbitfield LegalTypesMask;

View file

@ -2845,27 +2845,6 @@ _mesa_VertexArrayBindingDivisor(GLuint vaobj, GLuint bindingIndex,
}
/**
* Copy one vertex array to another.
*/
void
_mesa_copy_vertex_array(struct gl_context *ctx,
struct gl_vertex_array *dst,
struct gl_vertex_array *src)
{
dst->Size = src->Size;
dst->Type = src->Type;
dst->Format = src->Format;
dst->StrideB = src->StrideB;
dst->Ptr = src->Ptr;
dst->Normalized = src->Normalized;
dst->Integer = src->Integer;
dst->Doubles = src->Doubles;
dst->InstanceDivisor = src->InstanceDivisor;
dst->_ElementSize = src->_ElementSize;
_mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
}
void
_mesa_copy_vertex_attrib_array(struct gl_context *ctx,
struct gl_array_attributes *dst,

View file

@ -48,37 +48,6 @@ _mesa_vertex_attrib_address(const struct gl_array_attributes *array,
}
/**
* Sets the fields in a gl_vertex_array to values derived from a
* gl_array_attributes and a gl_vertex_buffer_binding.
*/
static inline void
_mesa_update_vertex_array(struct gl_context *ctx,
struct gl_vertex_array *dst,
const struct gl_array_attributes *attribs,
const struct gl_vertex_buffer_binding *binding)
{
if (attribs->Enabled) {
dst->Size = attribs->Size;
dst->Type = attribs->Type;
dst->Format = attribs->Format;
dst->StrideB = binding->Stride;
dst->Ptr = _mesa_vertex_attrib_address(attribs, binding);
dst->Normalized = attribs->Normalized;
dst->Integer = attribs->Integer;
dst->Doubles = attribs->Doubles;
dst->InstanceDivisor = binding->InstanceDivisor;
dst->_ElementSize = attribs->_ElementSize;
_mesa_reference_buffer_object(ctx, &dst->BufferObj, binding->BufferObj);
} else {
/* Disabled arrays shall not be consumed */
dst->Size = 0;
dst->Ptr = NULL;
_mesa_reference_buffer_object(ctx, &dst->BufferObj, NULL);
}
}
static inline bool
_mesa_attr_zero_aliases_vertex(const struct gl_context *ctx)
{
@ -91,7 +60,7 @@ _mesa_attr_zero_aliases_vertex(const struct gl_context *ctx)
*/
static inline void
_mesa_set_drawing_arrays(struct gl_context *ctx,
const struct gl_vertex_array **arrays)
const struct gl_vertex_array *arrays)
{
if (ctx->Array._DrawArrays != arrays) {
ctx->Array._DrawArrays = arrays;
@ -495,10 +464,18 @@ extern void GLAPIENTRY
_mesa_VertexArrayBindingDivisor(GLuint vaobj, GLuint bindingIndex,
GLuint divisor);
extern void
_mesa_copy_vertex_array(struct gl_context *ctx,
struct gl_vertex_array *dst,
struct gl_vertex_array *src);
/**
* Shallow copy one vertex array to another.
*/
static inline void
_mesa_copy_vertex_array(struct gl_vertex_array *dst,
const struct gl_vertex_array *src)
{
dst->VertexAttrib = src->VertexAttrib;
dst->BufferBinding = src->BufferBinding;
}
extern void
_mesa_copy_vertex_attrib_array(struct gl_context *ctx,

View file

@ -138,7 +138,8 @@ static void check_program_state( struct st_context *st )
static void check_attrib_edgeflag(struct st_context *st)
{
const struct gl_vertex_array **arrays = st->ctx->Array._DrawArrays;
const struct gl_vertex_array *arrays = st->ctx->Array._DrawArrays;
const struct gl_vertex_buffer_binding *binding;
GLboolean vertdata_edgeflags, edgeflag_culls_prims, edgeflags_enabled;
struct gl_program *vp = st->ctx->VertexProgram._Current;
@ -148,8 +149,8 @@ static void check_attrib_edgeflag(struct st_context *st)
edgeflags_enabled = st->ctx->Polygon.FrontMode != GL_FILL ||
st->ctx->Polygon.BackMode != GL_FILL;
vertdata_edgeflags = edgeflags_enabled &&
arrays[VERT_ATTRIB_EDGEFLAG]->StrideB != 0;
binding = arrays[VERT_ATTRIB_EDGEFLAG].BufferBinding;
vertdata_edgeflags = edgeflags_enabled && binding->Stride != 0;
if (vertdata_edgeflags != st->vertdata_edgeflags) {
st->vertdata_edgeflags = vertdata_edgeflags;
if (vp)

View file

@ -47,6 +47,7 @@
#include "util/u_upload_mgr.h"
#include "main/bufferobj.h"
#include "main/glformats.h"
#include "main/varray.h"
/* vertex_formats[gltype - GL_BYTE][integer*2 + normalized][size - 1] */
static const uint16_t vertex_formats[][4][4] = {
@ -301,13 +302,13 @@ st_pipe_vertex_format(GLenum type, GLuint size, GLenum format,
}
static const struct gl_vertex_array *
get_client_array(const struct gl_vertex_array **arrays,
get_client_array(const struct gl_vertex_array *arrays,
unsigned mesaAttr)
{
/* st_program uses 0xffffffff to denote a double placeholder attribute */
if (mesaAttr == ST_DOUBLE_ATTRIB_PLACEHOLDER)
return NULL;
return arrays[mesaAttr];
return &arrays[mesaAttr];
}
/**
@ -316,7 +317,7 @@ get_client_array(const struct gl_vertex_array **arrays,
*/
static GLboolean
is_interleaved_arrays(const struct st_vertex_program *vp,
const struct gl_vertex_array **arrays,
const struct gl_vertex_array *arrays,
unsigned num_inputs)
{
GLuint attr;
@ -327,6 +328,9 @@ is_interleaved_arrays(const struct st_vertex_program *vp,
for (attr = 0; attr < num_inputs; attr++) {
const struct gl_vertex_array *array;
const struct gl_vertex_buffer_binding *binding;
const struct gl_array_attributes *attrib;
const GLubyte *ptr;
const struct gl_buffer_object *bufObj;
GLsizei stride;
@ -334,19 +338,22 @@ is_interleaved_arrays(const struct st_vertex_program *vp,
if (!array)
continue;
stride = array->StrideB; /* in bytes */
binding = array->BufferBinding;
attrib = array->VertexAttrib;
stride = binding->Stride; /* in bytes */
ptr = _mesa_vertex_attrib_address(attrib, binding);
/* To keep things simple, don't allow interleaved zero-stride attribs. */
if (stride == 0)
return false;
bufObj = array->BufferObj;
bufObj = binding->BufferObj;
if (attr == 0) {
/* save info about the first array */
firstStride = stride;
firstPtr = array->Ptr;
firstPtr = ptr;
firstBufObj = bufObj;
userSpaceBuffer = !bufObj || !bufObj->Name;
userSpaceBuffer = !_mesa_is_bufferobj(bufObj);
}
else {
/* check if other arrays interleave with the first, in same buffer */
@ -356,7 +363,7 @@ is_interleaved_arrays(const struct st_vertex_program *vp,
if (bufObj != firstBufObj)
return GL_FALSE; /* arrays in different VBOs */
if (llabs(array->Ptr - firstPtr) > firstStride)
if (llabs(ptr - firstPtr) > firstStride)
return GL_FALSE; /* arrays start too far apart */
if ((!_mesa_is_bufferobj(bufObj)) != userSpaceBuffer)
@ -454,7 +461,7 @@ set_vertex_attribs(struct st_context *st,
static void
setup_interleaved_attribs(struct st_context *st,
const struct st_vertex_program *vp,
const struct gl_vertex_array **arrays,
const struct gl_vertex_array *arrays,
unsigned num_inputs)
{
struct pipe_vertex_buffer vbuffer;
@ -470,25 +477,32 @@ setup_interleaved_attribs(struct st_context *st,
*/
if (num_inputs) {
const struct gl_vertex_array *array;
const struct gl_vertex_buffer_binding *binding;
const struct gl_array_attributes *attrib;
array = get_client_array(arrays, vp->index_to_input[0]);
assert(array);
binding = array->BufferBinding;
attrib = array->VertexAttrib;
/* Since we're doing interleaved arrays, we know there'll be at most
* one buffer object and the stride will be the same for all arrays.
* Grab them now.
*/
bufobj = array->BufferObj;
stride = array->StrideB;
bufobj = binding->BufferObj;
stride = binding->Stride;
low_addr = arrays[vp->index_to_input[0]]->Ptr;
low_addr = _mesa_vertex_attrib_address(attrib, binding);
for (attr = 1; attr < num_inputs; attr++) {
const GLubyte *start;
array = get_client_array(arrays, vp->index_to_input[attr]);
if (!array)
continue;
start = array->Ptr;
binding = array->BufferBinding;
attrib = array->VertexAttrib;
start = _mesa_vertex_attrib_address(attrib, binding);
low_addr = MIN2(low_addr, start);
}
}
@ -504,25 +518,32 @@ setup_interleaved_attribs(struct st_context *st,
for (attr = 0; attr < num_inputs;) {
const struct gl_vertex_array *array;
const struct gl_vertex_buffer_binding *binding;
const struct gl_array_attributes *attrib;
const GLubyte *ptr;
unsigned src_offset;
unsigned src_format;
array = get_client_array(arrays, vp->index_to_input[attr]);
assert(array);
src_offset = (unsigned) (array->Ptr - low_addr);
assert(array->_ElementSize ==
_mesa_bytes_per_vertex_attrib(array->Size, array->Type));
binding = array->BufferBinding;
attrib = array->VertexAttrib;
ptr = _mesa_vertex_attrib_address(attrib, binding);
src_format = st_pipe_vertex_format(array->Type,
array->Size,
array->Format,
array->Normalized,
array->Integer);
src_offset = (unsigned) (ptr - low_addr);
assert(attrib->_ElementSize ==
_mesa_bytes_per_vertex_attrib(attrib->Size, attrib->Type));
src_format = st_pipe_vertex_format(attrib->Type,
attrib->Size,
attrib->Format,
attrib->Normalized,
attrib->Integer);
init_velement_lowered(vp, velements, src_offset, src_format,
array->InstanceDivisor, 0,
array->Size, array->Doubles, &attr);
binding->InstanceDivisor, 0,
attrib->Size, attrib->Doubles, &attr);
}
/*
@ -573,7 +594,7 @@ setup_interleaved_attribs(struct st_context *st,
static void
setup_non_interleaved_attribs(struct st_context *st,
const struct st_vertex_program *vp,
const struct gl_vertex_array **arrays,
const struct gl_vertex_array *arrays,
unsigned num_inputs)
{
struct gl_context *ctx = st->ctx;
@ -586,6 +607,8 @@ setup_non_interleaved_attribs(struct st_context *st,
for (attr = 0; attr < num_inputs;) {
const unsigned mesaAttr = vp->index_to_input[attr];
const struct gl_vertex_array *array;
const struct gl_vertex_buffer_binding *binding;
const struct gl_array_attributes *attrib;
struct gl_buffer_object *bufobj;
GLsizei stride;
unsigned src_format;
@ -596,10 +619,12 @@ setup_non_interleaved_attribs(struct st_context *st,
bufidx = num_vbuffers++;
stride = array->StrideB;
bufobj = array->BufferObj;
assert(array->_ElementSize ==
_mesa_bytes_per_vertex_attrib(array->Size, array->Type));
binding = array->BufferBinding;
attrib = array->VertexAttrib;
stride = binding->Stride;
bufobj = binding->BufferObj;
assert(attrib->_ElementSize ==
_mesa_bytes_per_vertex_attrib(attrib->Size, attrib->Type));
if (_mesa_is_bufferobj(bufobj)) {
/* Attribute data is in a VBO.
@ -615,17 +640,21 @@ setup_non_interleaved_attribs(struct st_context *st,
vbuffer[bufidx].buffer.resource = stobj->buffer;
vbuffer[bufidx].is_user_buffer = false;
vbuffer[bufidx].buffer_offset = pointer_to_offset(array->Ptr);
vbuffer[bufidx].buffer_offset =
binding->Offset + attrib->RelativeOffset;
}
else {
if (stride == 0) {
unsigned size = array->_ElementSize;
unsigned size = attrib->_ElementSize;
/* This is optimal for GPU cache line usage if the upload size
* is <= cache line size.
*/
unsigned alignment = util_next_power_of_two(size);
void *ptr = array->Ptr ? (void*)array->Ptr :
(void*)ctx->Current.Attrib[mesaAttr];
assert(attrib->Ptr);
vbuffer[bufidx].buffer.user = attrib->Ptr;
void *ptr = attrib->Ptr ? (void*)attrib->Ptr :
(void*)ctx->Current.Attrib[mesaAttr];
vbuffer[bufidx].is_user_buffer = false;
vbuffer[bufidx].buffer.resource = NULL;
@ -646,12 +675,12 @@ setup_non_interleaved_attribs(struct st_context *st,
&vbuffer[bufidx].buffer.resource);
unref_buffers |= 1u << bufidx;
} else {
assert(array->Ptr);
vbuffer[bufidx].buffer.user = array->Ptr;
assert(attrib->Ptr);
vbuffer[bufidx].buffer.user = attrib->Ptr;
vbuffer[bufidx].is_user_buffer = true;
vbuffer[bufidx].buffer_offset = 0;
if (!array->InstanceDivisor)
if (!binding->InstanceDivisor)
st->draw_needs_minmax_index = true;
}
}
@ -659,15 +688,15 @@ setup_non_interleaved_attribs(struct st_context *st,
/* common-case setup */
vbuffer[bufidx].stride = stride; /* in bytes */
src_format = st_pipe_vertex_format(array->Type,
array->Size,
array->Format,
array->Normalized,
array->Integer);
src_format = st_pipe_vertex_format(attrib->Type,
attrib->Size,
attrib->Format,
attrib->Normalized,
attrib->Integer);
init_velement_lowered(vp, velements, 0, src_format,
array->InstanceDivisor, bufidx,
array->Size, array->Doubles, &attr);
binding->InstanceDivisor, bufidx,
attrib->Size, attrib->Doubles, &attr);
}
if (!ctx->Const.AllowMappedBuffersDuringExecution) {
@ -686,7 +715,7 @@ setup_non_interleaved_attribs(struct st_context *st,
void st_update_array(struct st_context *st)
{
struct gl_context *ctx = st->ctx;
const struct gl_vertex_array **arrays = ctx->Array._DrawArrays;
const struct gl_vertex_array *arrays = ctx->Array._DrawArrays;
const struct st_vertex_program *vp;
unsigned num_inputs;

View file

@ -60,8 +60,9 @@ struct rastpos_stage
struct gl_context *ctx; /**< Rendering context */
/* vertex attrib info we can setup once and re-use */
struct gl_vertex_buffer_binding binding;
struct gl_array_attributes attrib[VERT_ATTRIB_MAX];
struct gl_vertex_array array[VERT_ATTRIB_MAX];
const struct gl_vertex_array *arrays[VERT_ATTRIB_MAX];
struct _mesa_prim prim;
};
@ -193,15 +194,16 @@ new_draw_rastpos_stage(struct gl_context *ctx, struct draw_context *draw)
rs->stage.destroy = rastpos_destroy;
rs->ctx = ctx;
rs->binding.Stride = 0;
rs->binding.BufferObj = NULL;
for (i = 0; i < ARRAY_SIZE(rs->array); i++) {
rs->array[i].Size = 4;
rs->array[i].Type = GL_FLOAT;
rs->array[i].Format = GL_RGBA;
rs->array[i].StrideB = 0;
rs->array[i].Ptr = (GLubyte *) ctx->Current.Attrib[i];
rs->array[i].Normalized = GL_TRUE;
rs->array[i].BufferObj = NULL;
rs->arrays[i] = &rs->array[i];
rs->attrib[i].Size = 4;
rs->attrib[i].Type = GL_FLOAT;
rs->attrib[i].Format = GL_RGBA;
rs->attrib[i].Ptr = (GLubyte *) ctx->Current.Attrib[i];
rs->attrib[i].Normalized = GL_TRUE;
rs->array[i].BufferBinding = &rs->binding;
rs->array[i].VertexAttrib = &rs->attrib[i];
}
rs->prim.mode = GL_POINTS;
@ -222,7 +224,7 @@ st_RasterPos(struct gl_context *ctx, const GLfloat v[4])
struct st_context *st = st_context(ctx);
struct draw_context *draw = st_get_draw_context(st);
struct rastpos_stage *rs;
const struct gl_vertex_array **saved_arrays = ctx->Array._DrawArrays;
const struct gl_vertex_array *saved_arrays = ctx->Array._DrawArrays;
if (!st->draw)
return;
@ -258,13 +260,13 @@ st_RasterPos(struct gl_context *ctx, const GLfloat v[4])
/* All vertex attribs but position were previously initialized above.
* Just plug in position pointer now.
*/
rs->array[0].Ptr = (GLubyte *) v;
rs->attrib[0].Ptr = (GLubyte *) v;
/* Draw the point.
*
* Don't set DriverFlags.NewArray.
* st_feedback_draw_vbo doesn't check for that flag. */
ctx->Array._DrawArrays = rs->arrays;
ctx->Array._DrawArrays = rs->array;
st_feedback_draw_vbo(ctx, &rs->prim, 1, NULL, GL_TRUE, 0, 1,
NULL, 0, NULL);
ctx->Array._DrawArrays = saved_arrays;

View file

@ -28,6 +28,7 @@
#include "main/imports.h"
#include "main/image.h"
#include "main/macros.h"
#include "main/varray.h"
#include "vbo/vbo.h"
@ -130,7 +131,7 @@ st_feedback_draw_vbo(struct gl_context *ctx,
struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {NULL};
struct pipe_transfer *ib_transfer = NULL;
const struct gl_vertex_array **arrays = ctx->Array._DrawArrays;
const struct gl_vertex_array *arrays = ctx->Array._DrawArrays;
GLuint attr, i;
const GLubyte *low_addr = NULL;
const void *mapped_indices = NULL;
@ -169,10 +170,21 @@ st_feedback_draw_vbo(struct gl_context *ctx,
/* Find the lowest address of the arrays we're drawing */
if (vp->num_inputs) {
low_addr = arrays[vp->index_to_input[0]]->Ptr;
const struct gl_vertex_array *array;
const struct gl_vertex_buffer_binding *binding;
const struct gl_array_attributes *attrib;
array = &arrays[vp->index_to_input[0]];
binding = array->BufferBinding;
attrib = array->VertexAttrib;
low_addr = _mesa_vertex_attrib_address(attrib, binding);
for (attr = 1; attr < vp->num_inputs; attr++) {
const GLubyte *start = arrays[vp->index_to_input[attr]]->Ptr;
const GLubyte *start;
array = &arrays[vp->index_to_input[attr]];
binding = array->BufferBinding;
attrib = array->VertexAttrib;
start = _mesa_vertex_attrib_address(attrib, binding);
low_addr = MIN2(low_addr, start);
}
}
@ -182,9 +194,16 @@ st_feedback_draw_vbo(struct gl_context *ctx,
*/
for (attr = 0; attr < vp->num_inputs; attr++) {
const GLuint mesaAttr = vp->index_to_input[attr];
struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj;
const struct gl_vertex_array *array = &arrays[mesaAttr];
const struct gl_vertex_buffer_binding *binding;
const struct gl_array_attributes *attrib;
struct gl_buffer_object *bufobj;
void *map;
binding = array->BufferBinding;
attrib = array->VertexAttrib;
bufobj = binding->BufferObj;
if (bufobj && bufobj->Name) {
/* Attribute data is in a VBO.
* Recall that for VBOs, the gl_vertex_array->Ptr field is
@ -197,7 +216,8 @@ st_feedback_draw_vbo(struct gl_context *ctx,
vbuffers[attr].is_user_buffer = false;
pipe_resource_reference(&vbuffers[attr].buffer.resource, stobj->buffer);
vbuffers[attr].buffer_offset = pointer_to_offset(low_addr);
velements[attr].src_offset = arrays[mesaAttr]->Ptr - low_addr;
velements[attr].src_offset = binding->Offset
+ attrib->RelativeOffset - pointer_to_offset(low_addr);
/* map the attrib buffer */
map = pipe_buffer_map(pipe, vbuffers[attr].buffer.resource,
@ -207,7 +227,7 @@ st_feedback_draw_vbo(struct gl_context *ctx,
vbuffers[attr].buffer.resource->width0);
}
else {
vbuffers[attr].buffer.user = arrays[mesaAttr]->Ptr;
vbuffers[attr].buffer.user = attrib->Ptr;
vbuffers[attr].is_user_buffer = true;
vbuffers[attr].buffer_offset = 0;
velements[attr].src_offset = 0;
@ -217,15 +237,15 @@ st_feedback_draw_vbo(struct gl_context *ctx,
}
/* common-case setup */
vbuffers[attr].stride = arrays[mesaAttr]->StrideB; /* in bytes */
vbuffers[attr].stride = binding->Stride; /* in bytes */
velements[attr].instance_divisor = 0;
velements[attr].vertex_buffer_index = attr;
velements[attr].src_format =
st_pipe_vertex_format(arrays[mesaAttr]->Type,
arrays[mesaAttr]->Size,
arrays[mesaAttr]->Format,
arrays[mesaAttr]->Normalized,
arrays[mesaAttr]->Integer);
velements[attr].src_format =
st_pipe_vertex_format(attrib->Type,
attrib->Size,
attrib->Format,
attrib->Normalized,
attrib->Integer);
assert(velements[attr].src_format);
/* tell draw about this attribute */

View file

@ -68,14 +68,14 @@ static void free_space(struct gl_context *ctx)
*/
#define CONVERT( TYPE, MACRO ) do { \
GLuint i, j; \
if (input->Normalized) { \
if (attrib->Normalized) { \
for (i = 0; i < count; i++) { \
const TYPE *in = (TYPE *)ptr; \
for (j = 0; j < sz; j++) { \
*fptr++ = MACRO(*in); \
in++; \
} \
ptr += input->StrideB; \
ptr += binding->Stride; \
} \
} else { \
for (i = 0; i < count; i++) { \
@ -84,7 +84,7 @@ static void free_space(struct gl_context *ctx)
*fptr++ = (GLfloat)(*in); \
in++; \
} \
ptr += input->StrideB; \
ptr += binding->Stride; \
} \
} \
} while (0)
@ -96,25 +96,27 @@ static void free_space(struct gl_context *ctx)
* \param fptr output/float array
*/
static void
convert_bgra_to_float(const struct gl_vertex_array *input,
convert_bgra_to_float(const struct gl_vertex_buffer_binding *binding,
const struct gl_array_attributes *attrib,
const GLubyte *ptr, GLfloat *fptr,
GLuint count )
{
GLuint i;
assert(input->Normalized);
assert(input->Size == 4);
assert(attrib->Normalized);
assert(attrib->Size == 4);
for (i = 0; i < count; i++) {
const GLubyte *in = (GLubyte *) ptr; /* in is in BGRA order */
*fptr++ = UBYTE_TO_FLOAT(in[2]); /* red */
*fptr++ = UBYTE_TO_FLOAT(in[1]); /* green */
*fptr++ = UBYTE_TO_FLOAT(in[0]); /* blue */
*fptr++ = UBYTE_TO_FLOAT(in[3]); /* alpha */
ptr += input->StrideB;
ptr += binding->Stride;
}
}
static void
convert_half_to_float(const struct gl_vertex_array *input,
convert_half_to_float(const struct gl_vertex_buffer_binding *binding,
const struct gl_array_attributes *attrib,
const GLubyte *ptr, GLfloat *fptr,
GLuint count, GLuint sz)
{
@ -126,7 +128,7 @@ convert_half_to_float(const struct gl_vertex_array *input,
for (j = 0; j < sz; j++) {
*fptr++ = _mesa_half_to_float(in[j]);
}
ptr += input->StrideB;
ptr += binding->Stride;
}
}
@ -141,21 +143,22 @@ convert_half_to_float(const struct gl_vertex_array *input,
* is used to map the fixed-point numbers into the range [-1, 1].
*/
static void
convert_fixed_to_float(const struct gl_vertex_array *input,
convert_fixed_to_float(const struct gl_vertex_buffer_binding *binding,
const struct gl_array_attributes *attrib,
const GLubyte *ptr, GLfloat *fptr,
GLuint count)
{
GLuint i;
GLint j;
const GLint size = input->Size;
const GLint size = attrib->Size;
if (input->Normalized) {
if (attrib->Normalized) {
for (i = 0; i < count; ++i) {
const GLfixed *in = (GLfixed *) ptr;
for (j = 0; j < size; ++j) {
*fptr++ = (GLfloat) (2 * in[j] + 1) / (GLfloat) ((1 << 16) - 1);
}
ptr += input->StrideB;
ptr += binding->Stride;
}
} else {
for (i = 0; i < count; ++i) {
@ -163,7 +166,7 @@ convert_fixed_to_float(const struct gl_vertex_array *input,
for (j = 0; j < size; ++j) {
*fptr++ = in[j] / (GLfloat) (1 << 16);
}
ptr += input->StrideB;
ptr += binding->Stride;
}
}
}
@ -172,28 +175,29 @@ convert_fixed_to_float(const struct gl_vertex_array *input,
* floating point, populate VB->AttribPtr[].
*/
static void _tnl_import_array( struct gl_context *ctx,
GLuint attrib,
GLuint attr,
GLuint count,
const struct gl_vertex_array *input,
const struct gl_vertex_buffer_binding *binding,
const struct gl_array_attributes *attrib,
const GLubyte *ptr )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLuint stride = input->StrideB;
GLuint stride = binding->Stride;
if (input->Type != GL_FLOAT) {
const GLuint sz = input->Size;
if (attrib->Type != GL_FLOAT) {
const GLuint sz = attrib->Size;
GLubyte *buf = get_space(ctx, count * sz * sizeof(GLfloat));
GLfloat *fptr = (GLfloat *)buf;
switch (input->Type) {
switch (attrib->Type) {
case GL_BYTE:
CONVERT(GLbyte, BYTE_TO_FLOAT);
break;
case GL_UNSIGNED_BYTE:
if (input->Format == GL_BGRA) {
if (attrib->Format == GL_BGRA) {
/* See GL_EXT_vertex_array_bgra */
convert_bgra_to_float(input, ptr, fptr, count);
convert_bgra_to_float(binding, attrib, ptr, fptr, count);
}
else {
CONVERT(GLubyte, UBYTE_TO_FLOAT);
@ -215,10 +219,10 @@ static void _tnl_import_array( struct gl_context *ctx,
CONVERT(GLdouble, (GLfloat));
break;
case GL_HALF_FLOAT:
convert_half_to_float(input, ptr, fptr, count, sz);
convert_half_to_float(binding, attrib, ptr, fptr, count, sz);
break;
case GL_FIXED:
convert_fixed_to_float(input, ptr, fptr, count);
convert_fixed_to_float(binding, attrib, ptr, fptr, count);
break;
default:
assert(0);
@ -229,20 +233,20 @@ static void _tnl_import_array( struct gl_context *ctx,
stride = sz * sizeof(GLfloat);
}
VB->AttribPtr[attrib] = &tnl->tmp_inputs[attrib];
VB->AttribPtr[attrib]->data = (GLfloat (*)[4])ptr;
VB->AttribPtr[attrib]->start = (GLfloat *)ptr;
VB->AttribPtr[attrib]->count = count;
VB->AttribPtr[attrib]->stride = stride;
VB->AttribPtr[attrib]->size = input->Size;
VB->AttribPtr[attr] = &tnl->tmp_inputs[attr];
VB->AttribPtr[attr]->data = (GLfloat (*)[4])ptr;
VB->AttribPtr[attr]->start = (GLfloat *)ptr;
VB->AttribPtr[attr]->count = count;
VB->AttribPtr[attr]->stride = stride;
VB->AttribPtr[attr]->size = attrib->Size;
/* This should die, but so should the whole GLvector4f concept:
*/
VB->AttribPtr[attrib]->flags = (((1<<input->Size)-1) |
VB->AttribPtr[attr]->flags = (((1<<attrib->Size)-1) |
VEC_NOT_WRITEABLE |
(stride == 4*sizeof(GLfloat) ? 0 : VEC_BAD_STRIDE));
VB->AttribPtr[attrib]->storage = NULL;
VB->AttribPtr[attr]->storage = NULL;
}
#define CLIPVERTS ((6 + MAX_CLIP_PLANES) * 2)
@ -268,7 +272,7 @@ static GLboolean *_tnl_import_edgeflag( struct gl_context *ctx,
static void bind_inputs( struct gl_context *ctx,
const struct gl_vertex_array *inputs[],
const struct gl_vertex_array *inputs,
GLint count,
struct gl_buffer_object **bo,
GLuint *nr_bo )
@ -280,25 +284,28 @@ static void bind_inputs( struct gl_context *ctx,
/* Map all the VBOs
*/
for (i = 0; i < VERT_ATTRIB_MAX; i++) {
const struct gl_vertex_array *array = &inputs[i];
const struct gl_vertex_buffer_binding *binding = array->BufferBinding;
const struct gl_array_attributes *attrib = array->VertexAttrib;
const void *ptr;
if (inputs[i]->BufferObj->Name) {
if (!inputs[i]->BufferObj->Mappings[MAP_INTERNAL].Pointer) {
bo[*nr_bo] = inputs[i]->BufferObj;
if (_mesa_is_bufferobj(binding->BufferObj)) {
if (!binding->BufferObj->Mappings[MAP_INTERNAL].Pointer) {
bo[*nr_bo] = binding->BufferObj;
(*nr_bo)++;
ctx->Driver.MapBufferRange(ctx, 0, inputs[i]->BufferObj->Size,
ctx->Driver.MapBufferRange(ctx, 0, binding->BufferObj->Size,
GL_MAP_READ_BIT,
inputs[i]->BufferObj,
binding->BufferObj,
MAP_INTERNAL);
assert(inputs[i]->BufferObj->Mappings[MAP_INTERNAL].Pointer);
assert(binding->BufferObj->Mappings[MAP_INTERNAL].Pointer);
}
ptr = ADD_POINTERS(inputs[i]->BufferObj->Mappings[MAP_INTERNAL].Pointer,
inputs[i]->Ptr);
ptr = ADD_POINTERS(binding->BufferObj->Mappings[MAP_INTERNAL].Pointer,
binding->Offset + attrib->RelativeOffset);
}
else
ptr = inputs[i]->Ptr;
ptr = attrib->Ptr;
/* Just make sure the array is floating point, otherwise convert to
* temporary storage.
@ -306,7 +313,7 @@ static void bind_inputs( struct gl_context *ctx,
* XXX: remove the GLvector4f type at some stage and just use
* client arrays.
*/
_tnl_import_array(ctx, i, count, inputs[i], ptr);
_tnl_import_array(ctx, i, count, binding, attrib, ptr);
}
/* We process only the vertices between min & max index:
@ -431,7 +438,7 @@ void _tnl_draw_prims(struct gl_context *ctx,
struct gl_buffer_object *indirect)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
const struct gl_vertex_array **arrays = ctx->Array._DrawArrays;
const struct gl_vertex_array *arrays = ctx->Array._DrawArrays;
const GLuint TEST_SPLIT = 0;
const GLint max = TEST_SPLIT ? 8 : tnl->vb.Size - MAX_CLIPPED_VERTICES;
GLint max_basevertex = prim->basevertex;

View file

@ -47,6 +47,7 @@
*/
#include <stdio.h>
#include "main/bufferobj.h"
#include "main/glheader.h"
#include "main/imports.h"
#include "main/mtypes.h"
@ -101,7 +102,7 @@ REBASE(GLubyte)
* all or nothing.
*/
void t_rebase_prims( struct gl_context *ctx,
const struct gl_vertex_array *arrays[],
const struct gl_vertex_array *arrays,
const struct _mesa_prim *prim,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
@ -109,12 +110,12 @@ void t_rebase_prims( struct gl_context *ctx,
GLuint max_index,
vbo_draw_func draw )
{
struct gl_array_attributes tmp_attribs[VERT_ATTRIB_MAX];
struct gl_vertex_array tmp_arrays[VERT_ATTRIB_MAX];
const struct gl_vertex_array *tmp_array_pointers[VERT_ATTRIB_MAX];
struct _mesa_index_buffer tmp_ib;
struct _mesa_prim *tmp_prims = NULL;
const struct gl_vertex_array **saved_arrays = ctx->Array._DrawArrays;
const struct gl_vertex_array *saved_arrays = ctx->Array._DrawArrays;
void *tmp_indices = NULL;
GLuint i;
@ -220,14 +221,19 @@ void t_rebase_prims( struct gl_context *ctx,
* are forced to, eg non-VBO indexed rendering with start != 0.
*/
for (i = 0; i < VERT_ATTRIB_MAX; i++) {
tmp_arrays[i] = *arrays[i];
tmp_arrays[i].Ptr += min_index * tmp_arrays[i].StrideB;
tmp_array_pointers[i] = &tmp_arrays[i];
tmp_attribs[i] = *(arrays[i].VertexAttrib);
tmp_arrays[i].BufferBinding = arrays[i].BufferBinding;
tmp_arrays[i].VertexAttrib = &tmp_attribs[i];
if (_mesa_is_bufferobj(arrays[i].BufferBinding->BufferObj))
tmp_attribs[i].RelativeOffset +=
min_index * arrays[i].BufferBinding->Stride;
else
tmp_attribs[i].Ptr += min_index * arrays[i].BufferBinding->Stride;
}
/* Re-issue the draw call.
*/
ctx->Array._DrawArrays = tmp_array_pointers;
ctx->Array._DrawArrays = tmp_arrays;
ctx->NewDriverState |= ctx->DriverFlags.NewArray;
draw( ctx,

View file

@ -28,7 +28,7 @@
#include "vbo/vbo.h"
void t_rebase_prims( struct gl_context *ctx,
const struct gl_vertex_array *arrays[],
const struct gl_vertex_array *arrays,
const struct _mesa_prim *prim,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,

View file

@ -216,7 +216,7 @@ struct split_limits
void
vbo_split_prims(struct gl_context *ctx,
const struct gl_vertex_array *arrays[],
const struct gl_vertex_array *arrays,
const struct _mesa_prim *prim,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
@ -266,7 +266,7 @@ struct vbo_inputs
* current values. The array of pointers is updated incrementally
* based on the current and vertex_processing_mode values below.
*/
const struct gl_vertex_array *inputs[VERT_ATTRIB_MAX];
struct gl_vertex_array inputs[VERT_ATTRIB_MAX];
/** Those VERT_BIT_'s where the inputs array point to current values. */
GLbitfield current;
/** Store which aliasing current values - generics or materials - are set. */

View file

@ -53,20 +53,17 @@ check_size(const GLfloat *attr)
* Helper for initializing a vertex array.
*/
static void
init_array(struct gl_context *ctx, struct gl_vertex_array *array,
init_array(struct gl_context *ctx, struct gl_array_attributes *attrib,
unsigned size, const void *pointer)
{
memset(array, 0, sizeof(*array));
memset(attrib, 0, sizeof(*attrib));
array->Size = size;
array->Type = GL_FLOAT;
array->Format = GL_RGBA;
array->StrideB = 0;
array->_ElementSize = array->Size * sizeof(GLfloat);
array->Ptr = pointer;
_mesa_reference_buffer_object(ctx, &array->BufferObj,
ctx->Shared->NullBufferObj);
attrib->Size = size;
attrib->Type = GL_FLOAT;
attrib->Format = GL_RGBA;
attrib->Stride = 0;
attrib->_ElementSize = size * sizeof(GLfloat);
attrib->Ptr = pointer;
}
@ -80,15 +77,15 @@ init_legacy_currval(struct gl_context *ctx)
struct vbo_context *vbo = vbo_context(ctx);
GLuint i;
/* Set up a constant (StrideB == 0) array for each current
/* Set up a constant (Stride == 0) array for each current
* attribute:
*/
for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) {
struct gl_vertex_array *array = &vbo->currval[VERT_ATTRIB_FF(i)];
const unsigned attr = VERT_ATTRIB_FF(i);
struct gl_array_attributes *attrib = &vbo->current[attr];
init_array(ctx, array,
check_size(ctx->Current.Attrib[i]),
ctx->Current.Attrib[i]);
init_array(ctx, attrib, check_size(ctx->Current.Attrib[attr]),
ctx->Current.Attrib[attr]);
}
}
@ -100,9 +97,10 @@ init_generic_currval(struct gl_context *ctx)
GLuint i;
for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) {
struct gl_vertex_array *array = &vbo->currval[VBO_ATTRIB_GENERIC0 + i];
const unsigned attr = VBO_ATTRIB_GENERIC0 + i;
struct gl_array_attributes *attrib = &vbo->current[attr];
init_array(ctx, array, 1, ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + i]);
init_array(ctx, attrib, 1, ctx->Current.Attrib[attr]);
}
}
@ -117,8 +115,8 @@ init_mat_currval(struct gl_context *ctx)
* attribute:
*/
for (i = 0; i < MAT_ATTRIB_MAX; i++) {
struct gl_vertex_array *array =
&vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT + i];
const unsigned attr = VBO_ATTRIB_MAT_FRONT_AMBIENT + i;
struct gl_array_attributes *attrib = &vbo->current[attr];
unsigned size;
/* Size is fixed for the material attributes, for others will
@ -138,7 +136,7 @@ init_mat_currval(struct gl_context *ctx)
break;
}
init_array(ctx, array, size, ctx->Light.Material.Attrib[i]);
init_array(ctx, attrib, size, ctx->Light.Material.Attrib[i]);
}
}
@ -237,6 +235,11 @@ _vbo_CreateContext(struct gl_context *ctx)
return GL_FALSE;
}
vbo->binding.Offset = 0;
vbo->binding.Stride = 0;
vbo->binding.InstanceDivisor = 0;
_mesa_reference_buffer_object(ctx, &vbo->binding.BufferObj,
ctx->Shared->NullBufferObj);
init_legacy_currval(ctx);
init_generic_currval(ctx);
init_mat_currval(ctx);
@ -276,11 +279,8 @@ _vbo_DestroyContext(struct gl_context *ctx)
}
if (vbo) {
GLuint i;
for (i = 0; i < VBO_ATTRIB_MAX; i++) {
_mesa_reference_buffer_object(ctx, &vbo->currval[i].BufferObj, NULL);
}
_mesa_reference_buffer_object(ctx, &vbo->binding.BufferObj, NULL);
vbo_exec_destroy(ctx);
if (ctx->API == API_OPENGL_COMPAT)

View file

@ -267,11 +267,14 @@ update_vao_inputs(struct gl_context *ctx,
/* Fill in the client arrays from the VAO */
const GLubyte *const map = _mesa_vao_attribute_map[vao->_AttributeMapMode];
const struct gl_vertex_array *array = vao->_VertexArray;
const struct gl_vertex_array **iarray = &inputs->inputs[0];
const struct gl_array_attributes *attribs = &vao->VertexAttrib[0];
const struct gl_vertex_buffer_binding *bindings = &vao->BufferBinding[0];
while (enable) {
const int attr = u_bit_scan(&enable);
iarray[attr] = &array[map[attr]];
struct gl_vertex_array *input = &inputs->inputs[attr];
const struct gl_array_attributes *attrib = &attribs[map[attr]];
input->VertexAttrib = attrib;
input->BufferBinding = &bindings[attrib->BufferBindingIndex];
}
}
@ -294,12 +297,13 @@ update_current_inputs(struct gl_context *ctx,
mask |= current & VERT_BIT_MAT_ALL;
struct vbo_context *vbo = vbo_context(ctx);
const struct gl_vertex_array *const currval = &vbo->currval[0];
const struct gl_vertex_array **iarray = &inputs->inputs[0];
const struct gl_array_attributes *const currval = &vbo->current[0];
const GLubyte *const map = _vbo_attribute_alias_map[mode];
while (mask) {
const int attr = u_bit_scan(&mask);
iarray[attr] = &currval[map[attr]];
struct gl_vertex_array *input = &inputs->inputs[attr];
input->VertexAttrib = &currval[map[attr]];
input->BufferBinding = &vbo->binding;
}
inputs->current = current;

View file

@ -174,7 +174,7 @@ vbo_exec_copy_to_current(struct vbo_exec_context *exec)
/* Note: the exec->vtx.current[i] pointers point into the
* ctx->Current.Attrib and ctx->Light.Material.Attrib arrays.
*/
GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;
GLfloat *current = (GLfloat *)vbo->current[i].Ptr;
fi_type tmp[8]; /* space for doubles */
int dmul = 1;
@ -195,7 +195,7 @@ vbo_exec_copy_to_current(struct vbo_exec_context *exec)
exec->vtx.attrtype[i]);
}
if (exec->vtx.attrtype[i] != vbo->currval[i].Type ||
if (exec->vtx.attrtype[i] != vbo->current[i].Type ||
memcmp(current, tmp, 4 * sizeof(GLfloat) * dmul) != 0) {
memcpy(current, tmp, 4 * sizeof(GLfloat) * dmul);
@ -205,13 +205,13 @@ vbo_exec_copy_to_current(struct vbo_exec_context *exec)
* directly.
*/
/* Size here is in components - not bytes */
vbo->currval[i].Size = exec->vtx.attrsz[i] / dmul;
vbo->currval[i]._ElementSize =
vbo->currval[i].Size * sizeof(GLfloat) * dmul;
vbo->currval[i].Type = exec->vtx.attrtype[i];
vbo->currval[i].Integer =
vbo->current[i].Size = exec->vtx.attrsz[i] / dmul;
vbo->current[i]._ElementSize =
vbo->current[i].Size * sizeof(GLfloat) * dmul;
vbo->current[i].Type = exec->vtx.attrtype[i];
vbo->current[i].Integer =
vbo_attrtype_to_integer_flag(exec->vtx.attrtype[i]);
vbo->currval[i].Doubles =
vbo->current[i].Doubles =
vbo_attrtype_to_double_flag(exec->vtx.attrtype[i]);
/* This triggers rather too much recalculation of Mesa state
@ -248,10 +248,10 @@ vbo_exec_copy_from_current(struct vbo_exec_context *exec)
for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) {
if (exec->vtx.attrtype[i] == GL_DOUBLE ||
exec->vtx.attrtype[i] == GL_UNSIGNED_INT64_ARB) {
memcpy(exec->vtx.attrptr[i], vbo->currval[i].Ptr,
memcpy(exec->vtx.attrptr[i], vbo->current[i].Ptr,
exec->vtx.attrsz[i] * sizeof(GLfloat));
} else {
const fi_type *current = (fi_type *) vbo->currval[i].Ptr;
const fi_type *current = (fi_type *) vbo->current[i].Ptr;
switch (exec->vtx.attrsz[i]) {
case 4: exec->vtx.attrptr[i][3] = current[3];
case 3: exec->vtx.attrptr[i][2] = current[2];
@ -379,7 +379,7 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
exec->vtx.attrtype[j]);
COPY_SZ_4V(dest + new_offset, newSize, tmp);
} else {
fi_type *current = (fi_type *)vbo->currval[j].Ptr;
fi_type *current = (fi_type *)vbo->current[j].Ptr;
COPY_SZ_4V(dest + new_offset, sz, current);
}
}

View file

@ -44,7 +44,8 @@ struct _mesa_prim;
struct vbo_context {
struct gl_vertex_array currval[VBO_ATTRIB_MAX];
struct gl_vertex_buffer_binding binding;
struct gl_array_attributes current[VBO_ATTRIB_MAX];
/* The array of inputs used for _DrawVAO draws. */
struct vbo_inputs draw_arrays;

View file

@ -52,7 +52,7 @@ copy_vao(struct gl_context *ctx, const struct gl_vertex_array_object *vao,
while (mask) {
const int i = u_bit_scan(&mask);
const struct gl_array_attributes *attrib = &vao->VertexAttrib[i];
struct gl_vertex_array *currval = &vbo->currval[shift + i];
struct gl_array_attributes *currval = &vbo->current[shift + i];
const GLubyte size = attrib->Size;
const GLenum16 type = attrib->Type;
fi_type tmp[4];

View file

@ -100,7 +100,7 @@ split_prim_inplace(GLenum mode, GLuint *first, GLuint *incr)
void
vbo_split_prims(struct gl_context *ctx,
const struct gl_vertex_array *arrays[],
const struct gl_vertex_array arrays[],
const struct _mesa_prim *prim,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,

View file

@ -51,7 +51,7 @@ split_prim_inplace(GLenum mode, GLuint *first, GLuint *incr);
void
vbo_split_inplace(struct gl_context *ctx,
const struct gl_vertex_array *arrays[],
const struct gl_vertex_array arrays[],
const struct _mesa_prim *prim,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
@ -64,7 +64,7 @@ vbo_split_inplace(struct gl_context *ctx,
*/
void
vbo_split_copy(struct gl_context *ctx,
const struct gl_vertex_array *arrays[],
const struct gl_vertex_array arrays[],
const struct _mesa_prim *prim,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,

View file

@ -37,6 +37,7 @@
#include "main/glformats.h"
#include "main/macros.h"
#include "main/mtypes.h"
#include "main/varray.h"
#include "vbo_split.h"
#include "vbo.h"
@ -51,7 +52,7 @@
*/
struct copy_context {
struct gl_context *ctx;
const struct gl_vertex_array **array;
const struct gl_vertex_array *array;
const struct _mesa_prim *prim;
GLuint nr_prims;
const struct _mesa_index_buffer *ib;
@ -62,15 +63,15 @@ struct copy_context {
struct {
GLuint attr;
GLuint size;
const struct gl_vertex_array *array;
const GLubyte *src_ptr;
struct gl_vertex_array dstarray;
struct gl_vertex_buffer_binding dstbinding;
struct gl_array_attributes dstattribs;
} varying[VERT_ATTRIB_MAX];
GLuint nr_varying;
const struct gl_vertex_array *dstarray_ptr[VERT_ATTRIB_MAX];
struct gl_vertex_array dstarray[VERT_ATTRIB_MAX];
struct _mesa_index_buffer dstib;
GLuint *translated_elt_buf;
@ -103,9 +104,9 @@ struct copy_context {
static GLuint
attr_size(const struct gl_vertex_array *array)
attr_size(const struct gl_array_attributes *attrib)
{
return array->Size * _mesa_sizeof_type(array->Type);
return attrib->Size * _mesa_sizeof_type(attrib->Type);
}
@ -139,7 +140,7 @@ check_flush(struct copy_context *copy)
*/
static void
dump_draw_info(struct gl_context *ctx,
const struct gl_vertex_array **arrays,
const struct gl_vertex_array *arrays,
const struct _mesa_prim *prims,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
@ -154,13 +155,17 @@ dump_draw_info(struct gl_context *ctx,
printf(" Prim mode 0x%x\n", prims[i].mode);
printf(" IB: %p\n", (void*) ib);
for (j = 0; j < VERT_ATTRIB_MAX; j++) {
printf(" array %d at %p:\n", j, (void*) arrays[j]);
const struct gl_vertex_array *array = &arrays[j];
const struct gl_vertex_buffer_binding *binding
= array->BufferBinding;
const struct gl_array_attributes *attrib = array->VertexAttrib;
const GLubyte *ptr = _mesa_vertex_attrib_address(attrib, binding);
printf(" array %d at %p:\n", j, (void*) &arrays[j]);
printf(" ptr %p, size %d, type 0x%x, stride %d\n",
arrays[j]->Ptr,
arrays[j]->Size, arrays[j]->Type, arrays[j]->StrideB);
ptr, attrib->Size, attrib->Type, binding->Stride);
if (0) {
GLint k = prims[i].start + prims[i].count - 1;
GLfloat *last = (GLfloat *) (arrays[j]->Ptr + arrays[j]->StrideB * k);
GLfloat *last = (GLfloat *) (ptr + binding->Stride * k);
printf(" last: %f %f %f\n",
last[0], last[1], last[2]);
}
@ -173,7 +178,7 @@ static void
flush(struct copy_context *copy)
{
struct gl_context *ctx = copy->ctx;
const struct gl_vertex_array **saved_arrays = ctx->Array._DrawArrays;
const struct gl_vertex_array *saved_arrays = ctx->Array._DrawArrays;
GLuint i;
/* Set some counters:
@ -182,7 +187,7 @@ flush(struct copy_context *copy)
#if 0
dump_draw_info(copy->ctx,
copy->dstarray_ptr,
copy->dstarray,
copy->dstprim,
copy->dstprim_nr,
&copy->dstib,
@ -192,7 +197,7 @@ flush(struct copy_context *copy)
(void) dump_draw_info;
#endif
ctx->Array._DrawArrays = copy->dstarray_ptr;
ctx->Array._DrawArrays = copy->dstarray;
ctx->NewDriverState |= ctx->DriverFlags.NewArray;
copy->draw(ctx,
@ -253,8 +258,11 @@ elt(struct copy_context *copy, GLuint elt_idx)
GLuint i;
for (i = 0; i < copy->nr_varying; i++) {
const struct gl_vertex_array *srcarray = copy->varying[i].array;
const GLubyte *srcptr = copy->varying[i].src_ptr + elt * srcarray->StrideB;
const struct gl_vertex_array *srcarray = &copy->array[i];
const struct gl_vertex_buffer_binding* srcbinding
= srcarray->BufferBinding;
const GLubyte *srcptr
= copy->varying[i].src_ptr + elt * srcbinding->Stride;
memcpy(csr, srcptr, copy->varying[i].size);
csr += copy->varying[i].size;
@ -428,18 +436,21 @@ replay_init(struct copy_context *copy)
*/
copy->vertex_size = 0;
for (i = 0; i < VERT_ATTRIB_MAX; i++) {
struct gl_buffer_object *vbo = copy->array[i]->BufferObj;
const struct gl_vertex_array *array = &copy->array[i];
const struct gl_vertex_buffer_binding *binding = array->BufferBinding;
if (copy->array[i]->StrideB == 0) {
copy->dstarray_ptr[i] = copy->array[i];
if (binding->Stride == 0) {
_mesa_copy_vertex_array(&copy->dstarray[i], array);
}
else {
const struct gl_array_attributes *attrib = array->VertexAttrib;
struct gl_buffer_object *vbo = binding->BufferObj;
const GLubyte *ptr = _mesa_vertex_attrib_address(attrib, binding);
GLuint j = copy->nr_varying++;
copy->varying[j].attr = i;
copy->varying[j].array = copy->array[i];
copy->varying[j].size = attr_size(copy->array[i]);
copy->vertex_size += attr_size(copy->array[i]);
copy->varying[j].size = attr_size(attrib);
copy->vertex_size += attr_size(attrib);
if (_mesa_is_bufferobj(vbo) &&
!_mesa_bufferobj_mapped(vbo, MAP_INTERNAL))
@ -447,10 +458,10 @@ replay_init(struct copy_context *copy)
MAP_INTERNAL);
copy->varying[j].src_ptr =
ADD_POINTERS(vbo->Mappings[MAP_INTERNAL].Pointer,
copy->array[i]->Ptr);
ADD_POINTERS(vbo->Mappings[MAP_INTERNAL].Pointer, ptr);
copy->dstarray_ptr[i] = &copy->varying[j].dstarray;
copy->dstarray[i].VertexAttrib = &copy->varying[j].dstattribs;
copy->dstarray[i].BufferBinding = &copy->varying[j].dstbinding;
}
}
@ -509,19 +520,24 @@ replay_init(struct copy_context *copy)
/* Setup new vertex arrays to point into the output buffer:
*/
for (offset = 0, i = 0; i < copy->nr_varying; i++) {
const struct gl_vertex_array *src = copy->varying[i].array;
struct gl_vertex_array *dst = &copy->varying[i].dstarray;
const struct gl_vertex_array *src = &copy->array[i];
const struct gl_array_attributes *srcattr = src->VertexAttrib;
struct gl_vertex_array *dst = &copy->dstarray[i];
struct gl_vertex_buffer_binding *dstbind = &copy->varying[i].dstbinding;
struct gl_array_attributes *dstattr = &copy->varying[i].dstattribs;
dst->Size = src->Size;
dst->Type = src->Type;
dst->Format = GL_RGBA;
dst->StrideB = copy->vertex_size;
dst->Ptr = copy->dstbuf + offset;
dst->Normalized = src->Normalized;
dst->Integer = src->Integer;
dst->Doubles = src->Doubles;
dst->BufferObj = ctx->Shared->NullBufferObj;
dst->_ElementSize = src->_ElementSize;
dstattr->Size = srcattr->Size;
dstattr->Type = srcattr->Type;
dstattr->Format = GL_RGBA;
dstbind->Stride = copy->vertex_size;
dstattr->Ptr = copy->dstbuf + offset;
dstattr->Normalized = srcattr->Normalized;
dstattr->Integer = srcattr->Integer;
dstattr->Doubles = srcattr->Doubles;
dstbind->BufferObj = ctx->Shared->NullBufferObj;
dstattr->_ElementSize = srcattr->_ElementSize;
dst->BufferBinding = dstbind;
dst->VertexAttrib = dstattr;
offset += copy->varying[i].size;
}
@ -559,7 +575,8 @@ replay_finish(struct copy_context *copy)
/* Unmap VBO's */
for (i = 0; i < copy->nr_varying; i++) {
struct gl_buffer_object *vbo = copy->varying[i].array->BufferObj;
struct gl_buffer_object *vbo =
copy->array[i].BufferBinding->BufferObj;
if (_mesa_is_bufferobj(vbo) && _mesa_bufferobj_mapped(vbo, MAP_INTERNAL))
ctx->Driver.UnmapBuffer(ctx, vbo, MAP_INTERNAL);
}
@ -577,7 +594,7 @@ replay_finish(struct copy_context *copy)
*/
void
vbo_split_copy(struct gl_context *ctx,
const struct gl_vertex_array *arrays[],
const struct gl_vertex_array *arrays,
const struct _mesa_prim *prim,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,

View file

@ -41,7 +41,7 @@
*/
struct split_context {
struct gl_context *ctx;
const struct gl_vertex_array **array;
const struct gl_vertex_array *array;
const struct _mesa_prim *prim;
GLuint nr_prims;
const struct _mesa_index_buffer *ib;
@ -63,7 +63,7 @@ static void
flush_vertex( struct split_context *split)
{
struct gl_context *ctx = split->ctx;
const struct gl_vertex_array **saved_arrays = ctx->Array._DrawArrays;
const struct gl_vertex_array *saved_arrays = ctx->Array._DrawArrays;
struct _mesa_index_buffer ib;
GLuint i;
@ -268,7 +268,7 @@ split_prims(struct split_context *split)
void
vbo_split_inplace(struct gl_context *ctx,
const struct gl_vertex_array *arrays[],
const struct gl_vertex_array *arrays,
const struct _mesa_prim *prim,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,