/** * Set up the vbo->currval arrays to point at the context's current * vertex attributes (with strides = 0). */ static void 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 * attribute: */ for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) { struct gl_vertex_array *cl = &vbo->currval[VERT_ATTRIB_FF(i)]; init_array(ctx, cl, check_size(ctx->Current.Attrib[i]), ctx->Current.Attrib[i]); } }
/** * Set up the vbo->currval arrays to point at the context's current * vertex attributes (with strides = 0). */ static void init_legacy_currval(struct gl_context *ctx) { struct vbo_context *vbo = vbo_context(ctx); GLuint i; /* Set up a constant (Stride == 0) array for each current * attribute: */ for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) { const unsigned attr = VERT_ATTRIB_FF(i); struct gl_array_attributes *attrib = &vbo->current[attr]; init_array(ctx, attrib, check_size(ctx->Current.Attrib[attr]), ctx->Current.Attrib[attr]); } }
/** * Print info/data for glDrawArrays(), for debugging. */ static void print_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, GLsizei count) { struct vbo_context *vbo = vbo_context(ctx); struct vbo_exec_context *exec = &vbo->exec; struct gl_array_object *arrayObj = ctx->Array.ArrayObj; int i; printf("vbo_exec_DrawArrays(mode 0x%x, start %d, count %d):\n", mode, start, count); for (i = 0; i < 32; i++) { struct gl_buffer_object *bufObj = exec->array.inputs[i]->BufferObj; GLuint bufName = bufObj->Name; GLint stride = exec->array.inputs[i]->Stride; printf("attr %2d: size %d stride %d enabled %d " "ptr %p Bufobj %u\n", i, exec->array.inputs[i]->Size, stride, /*exec->array.inputs[i]->Enabled,*/ arrayObj->VertexAttrib[VERT_ATTRIB_FF(i)].Enabled, exec->array.inputs[i]->Ptr, bufName); if (bufName) { GLubyte *p = ctx->Driver.MapBufferRange(ctx, 0, bufObj->Size, GL_MAP_READ_BIT, bufObj); int offset = (int) (GLintptr) exec->array.inputs[i]->Ptr; float *f = (float *) (p + offset); int *k = (int *) f; int i; int n = (count * stride) / 4; if (n > 32) n = 32; printf(" Data at offset %d:\n", offset); for (i = 0; i < n; i++) { printf(" float[%d] = 0x%08x %f\n", i, k[i], f[i]); } ctx->Driver.UnmapBuffer(ctx, bufObj); } } }
/** * Called at context creation time. */ void vbo_save_init( struct gl_context *ctx ) { struct vbo_context *vbo = vbo_context(ctx); struct vbo_save_context *save = &vbo->save; save->ctx = ctx; vbo_save_api_init( save ); vbo_save_callback_init(ctx); { struct gl_client_array *arrays = save->arrays; unsigned i; memcpy(arrays, &vbo->currval[VBO_ATTRIB_POS], VERT_ATTRIB_FF_MAX * sizeof(arrays[0])); for (i = 0; i < VERT_ATTRIB_FF_MAX; ++i) { struct gl_client_array *array; array = &arrays[VERT_ATTRIB_FF(i)]; array->BufferObj = NULL; _mesa_reference_buffer_object(ctx, &arrays->BufferObj, vbo->currval[VBO_ATTRIB_POS+i].BufferObj); } memcpy(arrays + VERT_ATTRIB_GENERIC(0), &vbo->currval[VBO_ATTRIB_GENERIC0], VERT_ATTRIB_GENERIC_MAX * sizeof(arrays[0])); for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; ++i) { struct gl_client_array *array; array = &arrays[VERT_ATTRIB_GENERIC(i)]; array->BufferObj = NULL; _mesa_reference_buffer_object(ctx, &array->BufferObj, vbo->currval[VBO_ATTRIB_GENERIC0+i].BufferObj); } } ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; }
/** * Set the vbo->exec->inputs[] pointers to point to the enabled * vertex arrays. This depends on the current vertex program/shader * being executed because of whether or not generic vertex arrays * alias the conventional vertex arrays. * For arrays that aren't enabled, we set the input[attrib] pointer * to point at a zero-stride current value "array". */ static void recalculate_input_bindings(struct gl_context *ctx) { struct vbo_context *vbo = vbo_context(ctx); struct vbo_exec_context *exec = &vbo->exec; struct gl_client_array *vertexAttrib = ctx->Array.ArrayObj->VertexAttrib; const struct gl_client_array **inputs = &exec->array.inputs[0]; GLbitfield64 const_inputs = 0x0; GLuint i; switch (get_program_mode(ctx)) { case VP_NONE: /* When no vertex program is active (or the vertex program is generated * from fixed-function state). We put the material values into the * generic slots. This is the only situation where material values * are available as per-vertex attributes. */ for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) { if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled) inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)]; else { inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i]; const_inputs |= VERT_BIT(i); } } for (i = 0; i < MAT_ATTRIB_MAX; i++) { inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT+i]; const_inputs |= VERT_BIT_GENERIC(i); } /* Could use just about anything, just to fill in the empty * slots: */ for (i = MAT_ATTRIB_MAX; i < VERT_ATTRIB_GENERIC_MAX; i++) { inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_GENERIC0+i]; const_inputs |= VERT_BIT_GENERIC(i); } break; case VP_ARB: /* GL_ARB_vertex_program or GLSL vertex shader - Only the generic[0] * attribute array aliases and overrides the legacy position array. * * Otherwise, legacy attributes available in the legacy slots, * generic attributes in the generic slots and materials are not * available as per-vertex attributes. */ if (vertexAttrib[VERT_ATTRIB_GENERIC0].Enabled) inputs[0] = &vertexAttrib[VERT_ATTRIB_GENERIC0]; else if (vertexAttrib[VERT_ATTRIB_POS].Enabled) inputs[0] = &vertexAttrib[VERT_ATTRIB_POS]; else { inputs[0] = &vbo->currval[VBO_ATTRIB_POS]; const_inputs |= VERT_BIT_POS; } for (i = 1; i < VERT_ATTRIB_FF_MAX; i++) { if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled) inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)]; else { inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i]; const_inputs |= VERT_BIT_FF(i); } } for (i = 1; i < VERT_ATTRIB_GENERIC_MAX; i++) { if (vertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled) inputs[VERT_ATTRIB_GENERIC(i)] = &vertexAttrib[VERT_ATTRIB_GENERIC(i)]; else { inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_GENERIC0+i]; const_inputs |= VERT_BIT_GENERIC(i); } } inputs[VERT_ATTRIB_GENERIC0] = inputs[0]; break; } _mesa_set_varying_vp_inputs( ctx, VERT_BIT_ALL & (~const_inputs) ); ctx->NewDriverState |= ctx->DriverFlags.NewArray; }
void vbo_exec_vtx_init( struct vbo_exec_context *exec ) { struct gl_context *ctx = exec->ctx; struct vbo_context *vbo = vbo_context(ctx); GLuint i; /* Allocate a buffer object. Will just reuse this object * continuously, unless vbo_use_buffer_objects() is called to enable * use of real VBOs. */ _mesa_reference_buffer_object(ctx, &exec->vtx.bufferobj, ctx->Shared->NullBufferObj); assert(!exec->vtx.buffer_map); exec->vtx.buffer_map = _mesa_align_malloc(VBO_VERT_BUFFER_SIZE, 64); exec->vtx.buffer_ptr = exec->vtx.buffer_map; vbo_exec_vtxfmt_init( exec ); _mesa_noop_vtxfmt_init(&exec->vtxfmt_noop); exec->vtx.enabled = 0; for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) { assert(i < ARRAY_SIZE(exec->vtx.attrsz)); exec->vtx.attrsz[i] = 0; assert(i < ARRAY_SIZE(exec->vtx.attrtype)); exec->vtx.attrtype[i] = GL_FLOAT; assert(i < ARRAY_SIZE(exec->vtx.active_sz)); exec->vtx.active_sz[i] = 0; } for (i = 0 ; i < VERT_ATTRIB_MAX; i++) { assert(i < ARRAY_SIZE(exec->vtx.inputs)); assert(i < ARRAY_SIZE(exec->vtx.arrays)); exec->vtx.inputs[i] = &exec->vtx.arrays[i]; } { struct gl_client_array *arrays = exec->vtx.arrays; unsigned i; memcpy(arrays, &vbo->currval[VBO_ATTRIB_POS], VERT_ATTRIB_FF_MAX * sizeof(arrays[0])); for (i = 0; i < VERT_ATTRIB_FF_MAX; ++i) { struct gl_client_array *array; array = &arrays[VERT_ATTRIB_FF(i)]; array->BufferObj = NULL; _mesa_reference_buffer_object(ctx, &array->BufferObj, vbo->currval[VBO_ATTRIB_POS+i].BufferObj); } memcpy(arrays + VERT_ATTRIB_GENERIC(0), &vbo->currval[VBO_ATTRIB_GENERIC0], VERT_ATTRIB_GENERIC_MAX * sizeof(arrays[0])); for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; ++i) { struct gl_client_array *array; array = &arrays[VERT_ATTRIB_GENERIC(i)]; array->BufferObj = NULL; _mesa_reference_buffer_object(ctx, &array->BufferObj, vbo->currval[VBO_ATTRIB_GENERIC0+i].BufferObj); } } exec->vtx.vertex_size = 0; exec->begin_vertices_flags = FLUSH_UPDATE_CURRENT; }
void vbo_exec_vtx_init( struct vbo_exec_context *exec ) { struct gl_context *ctx = exec->ctx; struct vbo_context *vbo = vbo_context(ctx); GLuint i; /* Allocate a buffer object. Will just reuse this object * continuously, unless vbo_use_buffer_objects() is called to enable * use of real VBOs. */ _mesa_reference_buffer_object(ctx, &exec->vtx.bufferobj, ctx->Shared->NullBufferObj); ASSERT(!exec->vtx.buffer_map); exec->vtx.buffer_map = (GLfloat *)_mesa_align_malloc(VBO_VERT_BUFFER_SIZE, 64); exec->vtx.buffer_ptr = exec->vtx.buffer_map; vbo_exec_vtxfmt_init( exec ); _mesa_noop_vtxfmt_init(&exec->vtxfmt_noop); /* Hook our functions into the dispatch table. */ _mesa_install_exec_vtxfmt( ctx, &exec->vtxfmt ); for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) { ASSERT(i < Elements(exec->vtx.attrsz)); exec->vtx.attrsz[i] = 0; ASSERT(i < Elements(exec->vtx.active_sz)); exec->vtx.active_sz[i] = 0; } for (i = 0 ; i < VERT_ATTRIB_MAX; i++) { ASSERT(i < Elements(exec->vtx.inputs)); ASSERT(i < Elements(exec->vtx.arrays)); exec->vtx.inputs[i] = &exec->vtx.arrays[i]; } { struct gl_client_array *arrays = exec->vtx.arrays; unsigned i; memcpy(arrays, vbo->legacy_currval, VERT_ATTRIB_FF_MAX * sizeof(arrays[0])); for (i = 0; i < VERT_ATTRIB_FF_MAX; ++i) { struct gl_client_array *array; array = &arrays[VERT_ATTRIB_FF(i)]; array->BufferObj = NULL; _mesa_reference_buffer_object(ctx, &arrays->BufferObj, vbo->legacy_currval[i].BufferObj); } memcpy(arrays + VERT_ATTRIB_GENERIC(0), vbo->generic_currval, VERT_ATTRIB_GENERIC_MAX * sizeof(arrays[0])); for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; ++i) { struct gl_client_array *array; array = &arrays[VERT_ATTRIB_GENERIC(i)]; array->BufferObj = NULL; _mesa_reference_buffer_object(ctx, &array->BufferObj, vbo->generic_currval[i].BufferObj); } } exec->vtx.vertex_size = 0; exec->begin_vertices_flags = FLUSH_UPDATE_CURRENT; }