#include "main/enums.h"
#include "main/eval.h"
#include "main/macros.h"
-#include "main/api_validate.h"
+#include "main/draw_validate.h"
#include "main/api_arrayelt.h"
#include "main/vtxfmt.h"
#include "main/dispatch.h"
return false;
/* If the enabled arrays are not the same we are not equal. */
- if (vao_enabled != vao->_Enabled)
+ if (vao_enabled != vao->Enabled)
return false;
/* Check the buffer binding at 0 */
const struct gl_array_attributes *attrib = &vao->VertexAttrib[attr];
if (attrib->RelativeOffset + vao->BufferBinding[0].Offset != off)
return false;
- if (attrib->Type != tp)
+ if (attrib->Format.Type != tp)
return false;
- if (attrib->Size != size[vbo_attr])
+ if (attrib->Format.Size != size[vbo_attr])
return false;
- assert(attrib->Format == GL_RGBA);
- assert(attrib->Enabled == GL_TRUE);
- assert(attrib->Normalized == GL_FALSE);
- assert(attrib->Integer == vbo_attrtype_to_integer_flag(tp));
- assert(attrib->Doubles == vbo_attrtype_to_double_flag(tp));
+ assert(attrib->Format.Format == GL_RGBA);
+ assert(attrib->Format.Normalized == GL_FALSE);
+ assert(attrib->Format.Integer == vbo_attrtype_to_integer_flag(tp));
+ assert(attrib->Format.Doubles == vbo_attrtype_to_double_flag(tp));
assert(attrib->BufferBindingIndex == 0);
}
_mesa_reference_vao(ctx, vao, NULL);
*vao = _mesa_new_vao(ctx, ~((GLuint)0));
+ /*
+ * assert(stride <= ctx->Const.MaxVertexAttribStride);
+ * MaxVertexAttribStride is not set for drivers that does not
+ * expose GL 44 or GLES 31.
+ */
+
/* Bind the buffer object at binding point 0 */
- _mesa_bind_vertex_buffer(ctx, *vao, 0, bo, buffer_offset, stride, false);
+ _mesa_bind_vertex_buffer(ctx, *vao, 0, bo, buffer_offset, stride);
/* Retrieve the mapping from VBO_ATTRIB to VERT_ATTRIB space
* Note that the position/generic0 aliasing is done in the VAO.
while (mask) {
const int vao_attr = u_bit_scan(&mask);
const GLubyte vbo_attr = vao_to_vbo_map[vao_attr];
+ assert(offset[vbo_attr] <= ctx->Const.MaxVertexAttribRelativeOffset);
_vbo_set_attrib_format(ctx, *vao, vao_attr, buffer_offset,
size[vbo_attr], type[vbo_attr], offset[vbo_attr]);
- _mesa_vertex_attrib_binding(ctx, *vao, vao_attr, 0, false);
- _mesa_enable_vertex_array_attrib(ctx, *vao, vao_attr, false);
+ _mesa_vertex_attrib_binding(ctx, *vao, vao_attr, 0);
}
- assert(vao_enabled == (*vao)->_Enabled);
+ _mesa_enable_vertex_array_attribs(ctx, *vao, vao_enabled);
+ assert(vao_enabled == (*vao)->Enabled);
assert((vao_enabled & ~(*vao)->VertexAttribBufferMask) == 0);
/* Finalize and freeze the VAO */
node->prim_store->refcount++;
- if (node->prims[0].no_current_update) {
+ if (save->no_current_update) {
node->current_data = NULL;
}
else {
struct vbo_save_context *save = &vbo_context(ctx)->save;
GLint i = save->prim_count - 1;
GLenum mode;
- GLboolean weak;
- GLboolean no_current_update;
assert(i < (GLint) save->prim_max);
assert(i >= 0);
*/
save->prims[i].count = (save->vert_count - save->prims[i].start);
mode = save->prims[i].mode;
- weak = save->prims[i].weak;
- no_current_update = save->prims[i].no_current_update;
/* store the copied vertices, and allocate a new list.
*/
/* Restart interrupted primitive
*/
save->prims[0].mode = mode;
- save->prims[0].weak = weak;
- save->prims[0].no_current_update = no_current_update;
save->prims[0].begin = 0;
save->prims[0].end = 0;
save->prims[0].pad = 0;
const int i = u_bit_scan64(&enabled);
assert(save->attrsz[i]);
- save->currentsz[i][0] = save->attrsz[i];
- COPY_CLEAN_4V_TYPE_AS_UNION(save->current[i], save->attrsz[i],
- save->attrptr[i], save->attrtype[i]);
+ if (save->attrtype[i] == GL_DOUBLE ||
+ save->attrtype[i] == GL_UNSIGNED_INT64_ARB)
+ memcpy(save->current[i], save->attrptr[i], save->attrsz[i] * sizeof(GLfloat));
+ else
+ COPY_CLEAN_4V_TYPE_AS_UNION(save->current[i], save->attrsz[i],
+ save->attrptr[i], save->attrtype[i]);
}
}
* get a glTexCoord4f() or glTexCoord1f() call.
*/
static void
-fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint sz)
+fixup_vertex(struct gl_context *ctx, GLuint attr,
+ GLuint sz, GLenum newType)
{
struct vbo_save_context *save = &vbo_context(ctx)->save;
- if (sz > save->attrsz[attr]) {
+ if (sz > save->attrsz[attr] ||
+ newType != save->attrtype[attr]) {
/* New size is larger. Need to flush existing vertices and get
* an enlarged vertex format.
*/
#define ATTR_UNION(A, N, T, C, V0, V1, V2, V3) \
do { \
struct vbo_save_context *save = &vbo_context(ctx)->save; \
+ int sz = (sizeof(C) / sizeof(GLfloat)); \
\
if (save->active_sz[A] != N) \
- fixup_vertex(ctx, A, N); \
+ fixup_vertex(ctx, A, N * sz, T); \
\
{ \
C *dest = (C *)save->attrptr[A]; \
* Updating of ctx->Driver.CurrentSavePrimitive is already taken care of.
*/
void
-vbo_save_NotifyBegin(struct gl_context *ctx, GLenum mode)
+vbo_save_NotifyBegin(struct gl_context *ctx, GLenum mode,
+ bool no_current_update)
{
struct vbo_save_context *save = &vbo_context(ctx)->save;
const GLuint i = save->prim_count++;
save->prims[i].mode = mode & VBO_SAVE_PRIM_MODE_MASK;
save->prims[i].begin = 1;
save->prims[i].end = 0;
- save->prims[i].weak = (mode & VBO_SAVE_PRIM_WEAK) ? 1 : 0;
- save->prims[i].no_current_update =
- (mode & VBO_SAVE_PRIM_NO_CURRENT_UPDATE) ? 1 : 0;
save->prims[i].pad = 0;
save->prims[i].start = save->vert_count;
save->prims[i].count = 0;
save->prims[i].base_instance = 0;
save->prims[i].is_indirect = 0;
+ save->no_current_update = no_current_update;
+
if (save->out_of_memory) {
_mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop);
}
} else {
/* get current primitive mode */
GLenum curPrim = save->prims[save->prim_count - 1].mode;
+ bool no_current_update = save->no_current_update;
/* restart primitive */
CALL_End(GET_DISPATCH(), ());
- vbo_save_NotifyBegin(ctx, curPrim);
+ vbo_save_NotifyBegin(ctx, curPrim, no_current_update);
}
}
_save_OBE_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
{
GET_CURRENT_CONTEXT(ctx);
- vbo_save_NotifyBegin(ctx, GL_QUADS | VBO_SAVE_PRIM_WEAK);
+ vbo_save_NotifyBegin(ctx, GL_QUADS, false);
CALL_Vertex2f(GET_DISPATCH(), (x1, y1));
CALL_Vertex2f(GET_DISPATCH(), (x2, y1));
CALL_Vertex2f(GET_DISPATCH(), (x2, y2));
_ae_map_vbos(ctx);
- vbo_save_NotifyBegin(ctx, (mode | VBO_SAVE_PRIM_WEAK
- | VBO_SAVE_PRIM_NO_CURRENT_UPDATE));
+ vbo_save_NotifyBegin(ctx, mode, true);
for (i = 0; i < count; i++)
- CALL_ArrayElement(GET_DISPATCH(), (start + i));
+ _mesa_array_element(ctx, GET_DISPATCH(), start + i);
CALL_End(GET_DISPATCH(), ());
_ae_unmap_vbos(ctx);
}
+static void
+array_element(struct gl_context *ctx, struct _glapi_table *disp, GLuint elt)
+{
+ /* If PrimitiveRestart is enabled and the index is the RestartIndex
+ * then we call PrimitiveRestartNV and return.
+ */
+ if (ctx->Array.PrimitiveRestart && elt == ctx->Array.RestartIndex) {
+ CALL_PrimitiveRestartNV(disp, ());
+ return;
+ }
+
+ _mesa_array_element(ctx, disp, elt);
+}
+
+
/* Could do better by copying the arrays and element list intact and
* then emitting an indexed prim at runtime.
*/
indices =
ADD_POINTERS(indexbuf->Mappings[MAP_INTERNAL].Pointer, indices);
- vbo_save_NotifyBegin(ctx, (mode | VBO_SAVE_PRIM_WEAK |
- VBO_SAVE_PRIM_NO_CURRENT_UPDATE));
+ vbo_save_NotifyBegin(ctx, mode, true);
switch (type) {
case GL_UNSIGNED_BYTE:
for (i = 0; i < count; i++)
- CALL_ArrayElement(GET_DISPATCH(), (basevertex + ((GLubyte *) indices)[i]));
+ array_element(ctx, GET_DISPATCH(), (basevertex + ((GLubyte *) indices)[i]));
break;
case GL_UNSIGNED_SHORT:
for (i = 0; i < count; i++)
- CALL_ArrayElement(GET_DISPATCH(), (basevertex + ((GLushort *) indices)[i]));
+ array_element(ctx, GET_DISPATCH(), (basevertex + ((GLushort *) indices)[i]));
break;
case GL_UNSIGNED_INT:
for (i = 0; i < count; i++)
- CALL_ArrayElement(GET_DISPATCH(), (basevertex + ((GLuint *) indices)[i]));
+ array_element(ctx, GET_DISPATCH(), (basevertex + ((GLuint *) indices)[i]));
break;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glDrawElements(type)");
{
struct vbo_save_context *save = &vbo_context(ctx)->save;
- if (ctx->ListState.CallDepth == 1) {
- /* This is correct: want to keep only the VBO_SAVE_FALLBACK
- * flag, if it is set:
- */
- save->replay_flags &= VBO_SAVE_FALLBACK;
- }
+ if (ctx->ListState.CallDepth == 1)
+ save->replay_flags = 0;
}
for (i = 0; i < node->prim_count; i++) {
struct _mesa_prim *prim = &node->prims[i];
- fprintf(f, " prim %d: %s%s %d..%d %s %s\n",
+ fprintf(f, " prim %d: %s %d..%d %s %s\n",
i,
_mesa_lookup_prim_by_nr(prim->mode),
- prim->weak ? " (weak)" : "",
prim->start,
prim->start + prim->count,
(prim->begin) ? "BEGIN" : "(wrap)",