From: Mathias Fröhlich Date: Sun, 4 Mar 2018 17:15:53 +0000 (+0100) Subject: mesa: Make gl_vertex_array contain pointers to first order VAO members. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=64d2a20480547d5897fd9d7b8fd306f2625138cb;p=mesa.git 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 Signed-off-by: Mathias Fröhlich --- diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index d3e7c71207b..177273c3645 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -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) diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 299e7f929e7..0d1ae8982cb 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -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; diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index c058064403e..4ede33aea17 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -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; } diff --git a/src/mesa/drivers/dri/i965/genX_state_upload.c b/src/mesa/drivers/dri/i965/genX_state_upload.c index 211fae58e9d..a69a496f1db 100644 --- a/src/mesa/drivers/dri/i965/genX_state_upload.c +++ b/src/mesa/drivers/dri/i965/genX_state_upload.c @@ -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, diff --git a/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c b/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c index b9145e6851a..a7b911c50ea 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c @@ -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, diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index 2526404fda3..7cb98337198 100644 --- a/src/mesa/main/arrayobj.c +++ b/src/mesa/main/arrayobj.c @@ -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); - } } diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index dd6b98ce043..9d3aa728a13 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -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]); } diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 2df2288899d..734fefc97f4 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -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; diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index c6cacf426c0..69a08a646f8 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -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, diff --git a/src/mesa/main/varray.h b/src/mesa/main/varray.h index b65b82cea7d..77027be8002 100644 --- a/src/mesa/main/varray.h +++ b/src/mesa/main/varray.h @@ -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, diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c index b597c62632e..45a45960a30 100644 --- a/src/mesa/state_tracker/st_atom.c +++ b/src/mesa/state_tracker/st_atom.c @@ -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) diff --git a/src/mesa/state_tracker/st_atom_array.c b/src/mesa/state_tracker/st_atom_array.c index 6af1355ee17..ff7a5d07467 100644 --- a/src/mesa/state_tracker/st_atom_array.c +++ b/src/mesa/state_tracker/st_atom_array.c @@ -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_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); } /* @@ -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; diff --git a/src/mesa/state_tracker/st_cb_rasterpos.c b/src/mesa/state_tracker/st_cb_rasterpos.c index e266296a775..4e5417baada 100644 --- a/src/mesa/state_tracker/st_cb_rasterpos.c +++ b/src/mesa/state_tracker/st_cb_rasterpos.c @@ -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; diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index 987a1564e28..46a12848c0d 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -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 */ diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c index c19d77d6418..b3142788892 100644 --- a/src/mesa/tnl/t_draw.c +++ b/src/mesa/tnl/t_draw.c @@ -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<Size)-1) | + VB->AttribPtr[attr]->flags = (((1<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; diff --git a/src/mesa/tnl/t_rebase.c b/src/mesa/tnl/t_rebase.c index b781781cb0a..0fcee03b24b 100644 --- a/src/mesa/tnl/t_rebase.c +++ b/src/mesa/tnl/t_rebase.c @@ -47,6 +47,7 @@ */ #include +#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, diff --git a/src/mesa/tnl/t_rebase.h b/src/mesa/tnl/t_rebase.h index 35175868d5d..16a3a2b5a33 100644 --- a/src/mesa/tnl/t_rebase.h +++ b/src/mesa/tnl/t_rebase.h @@ -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, diff --git a/src/mesa/vbo/vbo.h b/src/mesa/vbo/vbo.h index 345aa6b0d23..d6cf8e2afe5 100644 --- a/src/mesa/vbo/vbo.h +++ b/src/mesa/vbo/vbo.h @@ -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. */ diff --git a/src/mesa/vbo/vbo_context.c b/src/mesa/vbo/vbo_context.c index 3dc3222c0db..acb28d02938 100644 --- a/src/mesa/vbo/vbo_context.c +++ b/src/mesa/vbo/vbo_context.c @@ -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)); - - 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; } @@ -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) diff --git a/src/mesa/vbo/vbo_exec.c b/src/mesa/vbo/vbo_exec.c index 69a150c78b7..c0b0a11fe51 100644 --- a/src/mesa/vbo/vbo_exec.c +++ b/src/mesa/vbo/vbo_exec.c @@ -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; diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c index 317fc43d1c5..b3971715b57 100644 --- a/src/mesa/vbo/vbo_exec_api.c +++ b/src/mesa/vbo/vbo_exec_api.c @@ -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); } } diff --git a/src/mesa/vbo/vbo_private.h b/src/mesa/vbo/vbo_private.h index 1f3d31f577a..112a4605c7b 100644 --- a/src/mesa/vbo/vbo_private.h +++ b/src/mesa/vbo/vbo_private.h @@ -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; diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index 137fb6e3fd1..69d28312d3f 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -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]; diff --git a/src/mesa/vbo/vbo_split.c b/src/mesa/vbo/vbo_split.c index 974a708dcb6..ffe1d67489a 100644 --- a/src/mesa/vbo/vbo_split.c +++ b/src/mesa/vbo/vbo_split.c @@ -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, diff --git a/src/mesa/vbo/vbo_split.h b/src/mesa/vbo/vbo_split.h index dbd629979db..fea2b48aecc 100644 --- a/src/mesa/vbo/vbo_split.h +++ b/src/mesa/vbo/vbo_split.h @@ -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, diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c index 2de909f512f..09b5b3b6511 100644 --- a/src/mesa/vbo/vbo_split_copy.c +++ b/src/mesa/vbo/vbo_split_copy.c @@ -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, ©->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 = ©->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 = ©->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)) @@ -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] = ©->varying[j].dstarray; + copy->dstarray[i].VertexAttrib = ©->varying[j].dstattribs; + copy->dstarray[i].BufferBinding = ©->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 = ©->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; } @@ -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, diff --git a/src/mesa/vbo/vbo_split_inplace.c b/src/mesa/vbo/vbo_split_inplace.c index 2c363c27767..971c52a078c 100644 --- a/src/mesa/vbo/vbo_split_inplace.c +++ b/src/mesa/vbo/vbo_split_inplace.c @@ -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,