#include "main/draw_validate.h"
#include "main/dispatch.h"
#include "util/bitscan.h"
+#include "util/u_memory.h"
#include "vbo_noop.h"
#include "vbo_private.h"
\
assert(sz == 1 || sz == 2); \
\
- /* check if attribute size or type is changing */ \
- if (unlikely(exec->vtx.attr[A].active_size != N * sz || \
- exec->vtx.attr[A].type != T)) { \
- vbo_exec_fixup_vertex(ctx, A, N * sz, T); \
- } \
- \
/* store a copy of the attribute in exec except for glVertex */ \
if ((A) != 0) { \
+ /* Check if attribute size or type is changing. */ \
+ if (unlikely(exec->vtx.attr[A].active_size != N * sz || \
+ exec->vtx.attr[A].type != T)) { \
+ vbo_exec_fixup_vertex(ctx, A, N * sz, T); \
+ } \
+ \
C *dest = (C *)exec->vtx.attrptr[A]; \
if (N>0) dest[0] = V0; \
if (N>1) dest[1] = V1; \
ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
} else { \
/* This is a glVertex call */ \
+ int size = exec->vtx.attr[0].size; \
+ \
+ /* Check if attribute size or type is changing. */ \
+ if (unlikely(size < N * sz || \
+ exec->vtx.attr[0].type != T)) { \
+ vbo_exec_wrap_upgrade_vertex(exec, 0, N * sz, T); \
+ } \
+ \
uint32_t *dst = (uint32_t *)exec->vtx.buffer_ptr; \
uint32_t *src = (uint32_t *)exec->vtx.vertex; \
unsigned vertex_size_no_pos = exec->vtx.vertex_size_no_pos; \
if (N > 1) *dst++ = V1; \
if (N > 2) *dst++ = V2; \
if (N > 3) *dst++ = V3; \
+ \
+ if (unlikely(N < size)) { \
+ if (N < 2 && size >= 2) *dst++ = V1; \
+ if (N < 3 && size >= 3) *dst++ = V2; \
+ if (N < 4 && size >= 4) *dst++ = V3; \
+ } \
} else { \
/* 64 bits: dst can be unaligned, so copy each 4-byte word */ \
/* separately */ \
if (N > 1) SET_64BIT(dst, V1); \
if (N > 2) SET_64BIT(dst, V2); \
if (N > 3) SET_64BIT(dst, V3); \
+ \
+ if (unlikely(N * 2 < size)) { \
+ if (N < 2 && size >= 4) SET_64BIT(dst, V1); \
+ if (N < 3 && size >= 6) SET_64BIT(dst, V2); \
+ if (N < 4 && size >= 8) SET_64BIT(dst, V3); \
+ } \
} \
\
/* dst now points at the beginning of the next vertex */ \
assert(exec->vtx.buffer_ptr);
} else {
/* Use allocated memory for immediate mode. */
- _mesa_reference_buffer_object(ctx,
- &exec->vtx.bufferobj,
- ctx->Shared->NullBufferObj);
-
- exec->vtx.buffer_map = _mesa_align_malloc(VBO_VERT_BUFFER_SIZE, 64);
+ exec->vtx.bufferobj = NULL;
+ exec->vtx.buffer_map =
+ align_malloc(ctx->Const.glBeginEndBufferSize, 64);
exec->vtx.buffer_ptr = exec->vtx.buffer_map;
}
/* True VBOs should already be unmapped
*/
if (exec->vtx.buffer_map) {
- assert(exec->vtx.bufferobj->Name == 0 ||
+ assert(!exec->vtx.bufferobj ||
exec->vtx.bufferobj->Name == IMM_BUFFER_NAME);
- if (exec->vtx.bufferobj->Name == 0) {
- _mesa_align_free(exec->vtx.buffer_map);
+ if (!exec->vtx.bufferobj) {
+ align_free(exec->vtx.buffer_map);
exec->vtx.buffer_map = NULL;
exec->vtx.buffer_ptr = NULL;
}
/* Free the vertex buffer. Unmap first if needed.
*/
- if (_mesa_bufferobj_mapped(exec->vtx.bufferobj, MAP_INTERNAL)) {
+ if (exec->vtx.bufferobj &&
+ _mesa_bufferobj_mapped(exec->vtx.bufferobj, MAP_INTERNAL)) {
ctx->Driver.UnmapBuffer(ctx, exec->vtx.bufferobj, MAP_INTERNAL);
}
_mesa_reference_buffer_object(ctx, &exec->vtx.bufferobj, NULL);