/* 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)
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;
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) {
* 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:
/* 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;
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,
*/
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,
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;
{
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;
*/
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)
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:
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;
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;
}
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;
}
* 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:
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,
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);
}
}
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);
/* 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;
* 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
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++;
/* 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;
}
*/
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++;
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;
* 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;
* 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.
*/
#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,
#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
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);
}
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;
/* 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;
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;
}
}
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);
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 {
#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;
}
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));
}
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)
}
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);
*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]);
* scratch buffer obj. */
for (j = 0; j < n; j++)
memcpy(dp + j * a->stride,
- sp + j * array->StrideB,
+ sp + j * binding->Stride,
a->stride);
}
}
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)
}
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)
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,
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);
}
_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);
- }
}
/* 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]);
}
};
-/**
- * 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.
*
};
+/**
+ * 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.
*/
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];
* 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;
}
-/**
- * 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,
}
-/**
- * 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)
{
*/
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;
_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,
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;
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)
#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] = {
}
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];
}
/**
*/
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;
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;
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 */
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)
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;
*/
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);
}
}
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_offset = (unsigned) (ptr - low_addr);
+ assert(attrib->_ElementSize ==
+ _mesa_bytes_per_vertex_attrib(attrib->Size, attrib->Type));
- 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, src_offset, src_format,
- array->InstanceDivisor, 0,
- array->Size, array->Doubles, &attr);
+ binding->InstanceDivisor, 0,
+ attrib->Size, attrib->Doubles, &attr);
}
/*
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;
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;
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.
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;
&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;
}
}
/* 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) {
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;
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;
};
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;
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;
/* 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;
#include "main/imports.h"
#include "main/image.h"
#include "main/macros.h"
+#include "main/varray.h"
#include "vbo/vbo.h"
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;
/* 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);
}
}
*/
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
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,
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;
}
/* 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 */
*/
#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++) { \
*fptr++ = (GLfloat)(*in); \
in++; \
} \
- ptr += input->StrideB; \
+ ptr += binding->Stride; \
} \
} \
} while (0)
* \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)
{
for (j = 0; j < sz; j++) {
*fptr++ = _mesa_half_to_float(in[j]);
}
- ptr += input->StrideB;
+ ptr += binding->Stride;
}
}
* 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) {
for (j = 0; j < size; ++j) {
*fptr++ = in[j] / (GLfloat) (1 << 16);
}
- ptr += input->StrideB;
+ ptr += binding->Stride;
}
}
}
* 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);
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);
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)
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 )
/* 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.
* 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:
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;
*/
#include <stdio.h>
+#include "main/bufferobj.h"
#include "main/glheader.h"
#include "main/imports.h"
#include "main/mtypes.h"
* 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,
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;
* 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,
#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,
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,
* 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. */
* 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));
-
- 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);
+ memset(attrib, 0, sizeof(*attrib));
+
+ attrib->Size = size;
+ attrib->Type = GL_FLOAT;
+ attrib->Format = GL_RGBA;
+ attrib->Stride = 0;
+ attrib->_ElementSize = size * sizeof(GLfloat);
+ attrib->Ptr = pointer;
}
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]);
}
}
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]);
}
}
* 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
break;
}
- init_array(ctx, array, size, ctx->Light.Material.Attrib[i]);
+ init_array(ctx, attrib, size, ctx->Light.Material.Attrib[i]);
}
}
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);
}
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)
/* 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];
}
}
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;
/* 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;
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);
* 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
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];
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);
}
}
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;
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];
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,
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,
*/
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,
#include "main/glformats.h"
#include "main/macros.h"
#include "main/mtypes.h"
+#include "main/varray.h"
#include "vbo_split.h"
#include "vbo.h"
*/
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;
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;
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);
}
*/
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,
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]);
}
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:
#if 0
dump_draw_info(copy->ctx,
- copy->dstarray_ptr,
+ copy->dstarray,
copy->dstprim,
copy->dstprim_nr,
©->dstib,
(void) dump_draw_info;
#endif
- ctx->Array._DrawArrays = copy->dstarray_ptr;
+ ctx->Array._DrawArrays = copy->dstarray;
ctx->NewDriverState |= ctx->DriverFlags.NewArray;
copy->draw(ctx,
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 = ©->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;
*/
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 = ©->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(©->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))
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] = ©->varying[j].dstarray;
+ copy->dstarray[i].VertexAttrib = ©->varying[j].dstattribs;
+ copy->dstarray[i].BufferBinding = ©->varying[j].dstbinding;
}
}
/* 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 = ©->varying[i].dstarray;
-
- 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;
+ const struct gl_vertex_array *src = ©->array[i];
+ const struct gl_array_attributes *srcattr = src->VertexAttrib;
+ struct gl_vertex_array *dst = ©->dstarray[i];
+ struct gl_vertex_buffer_binding *dstbind = ©->varying[i].dstbinding;
+ struct gl_array_attributes *dstattr = ©->varying[i].dstattribs;
+
+ 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;
}
/* 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);
}
*/
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,
*/
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;
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;
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,