/** * \param input one of VERT_ATTRIB_x tokens. */ static struct ureg register_input( struct tnl_program *p, GLuint input ) { assert(input < VERT_ATTRIB_MAX); if (p->state->varying_vp_inputs & VERT_BIT(input)) { p->program->Base.InputsRead |= VERT_BIT(input); return make_ureg(PROGRAM_INPUT, input); } else { return register_param3( p, STATE_INTERNAL, STATE_CURRENT_ATTRIB, input ); } }
/** * See GL_ARB_instanced_arrays. * Note that the instance divisor only applies to generic arrays, not * the legacy vertex arrays. */ void GLAPIENTRY _mesa_VertexAttribDivisor(GLuint index, GLuint divisor) { struct gl_client_array *array; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (!ctx->Extensions.ARB_instanced_arrays) { _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexAttribDivisor()"); return; } if (index >= ctx->Const.VertexProgram.MaxAttribs) { _mesa_error(ctx, GL_INVALID_ENUM, "glVertexAttribDivisor(index = %u)", index); return; } ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib)); array = &ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)]; if (array->InstanceDivisor != divisor) { FLUSH_VERTICES(ctx, _NEW_ARRAY); array->InstanceDivisor = divisor; ctx->Array.ArrayObj->NewArrays |= VERT_BIT(VERT_ATTRIB_GENERIC(index)); } }
/** * Do error checking and update state for glVertex/Color/TexCoord/...Pointer * functions. * * \param func name of calling function used for error reporting * \param attrib the attribute array index to update * \param legalTypes bitmask of *_BIT above indicating legal datatypes * \param sizeMin min allowable size value * \param sizeMax max allowable size value * \param size components per element (1, 2, 3 or 4) * \param type datatype of each component (GL_FLOAT, GL_INT, etc) * \param stride stride between elements, in elements * \param normalized are integer types converted to floats in [-1, 1]? * \param integer integer-valued values (will not be normalized to [-1,1]) * \param ptr the address (or offset inside VBO) of the array data */ static void update_array(struct gl_context *ctx, const char *func, GLuint attrib, GLbitfield legalTypesMask, GLint sizeMin, GLint sizeMax, GLint size, GLenum type, GLsizei stride, GLboolean normalized, GLboolean integer, const GLvoid *ptr) { struct gl_client_array *array; GLbitfield typeBit; GLsizei elementSize; typeBit = type_to_bit(ctx, type); if (typeBit == 0x0 || (typeBit & legalTypesMask) == 0x0) { _mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)", func, _mesa_lookup_enum_by_nr(type)); return; } /* Do size parameter checking. */ if (size < sizeMin || size > sizeMax || size > 4) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", func, size); return; } ASSERT(size <= 4); if (stride < 0) { _mesa_error( ctx, GL_INVALID_VALUE, "%s(stride=%d)", func, stride ); return; } if (ctx->Array.ArrayObj->ARBsemantics && !_mesa_is_bufferobj(ctx->Array.ArrayBufferObj)) { /* GL_ARB_vertex_array_object requires that all arrays reside in VBOs. * Generate GL_INVALID_OPERATION if that's not true. */ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-VBO array)", func); return; } elementSize = _mesa_sizeof_type(type) * size; array = &ctx->Array.ArrayObj->VertexAttrib[attrib]; array->Size = size; array->Type = type; array->Stride = stride; array->StrideB = stride ? stride : elementSize; array->Normalized = normalized; array->Integer = integer; array->Ptr = (const GLubyte *) ptr; array->_ElementSize = elementSize; _mesa_reference_buffer_object(ctx, &array->BufferObj, ctx->Array.ArrayBufferObj); ctx->NewState |= _NEW_ARRAY; ctx->Array.NewState |= VERT_BIT(attrib); }
/** * Do error checking and update state for glVertex/Color/TexCoord/...Pointer * functions. * * \param func name of calling function used for error reporting * \param attrib the attribute array index to update * \param legalTypes bitmask of *_BIT above indicating legal datatypes * \param sizeMin min allowable size value * \param sizeMax max allowable size value * \param size components per element (1, 2, 3 or 4) * \param type datatype of each component (GL_FLOAT, GL_INT, etc) * \param stride stride between elements, in elements * \param normalized are integer types converted to floats in [-1, 1]? * \param integer integer-valued values (will not be normalized to [-1,1]) * \param ptr the address (or offset inside VBO) of the array data */ static void update_array(struct gl_context *ctx, const char *func, GLuint attrib, GLbitfield legalTypesMask, GLint sizeMin, GLint sizeMax, GLint size, GLenum type, GLsizei stride, GLboolean normalized, GLboolean integer, const GLvoid *ptr) { struct gl_client_array *array; GLbitfield typeBit; GLsizei elementSize; typeBit = type_to_bit(ctx, type); if (typeBit == 0x0 || (typeBit & legalTypesMask) == 0x0) { _mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)", func, _mesa_lookup_enum_by_nr(type)); return; } /* Do size parameter checking. */ if (size < sizeMin || size > sizeMax || size > 4) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", func, size); return; } ASSERT(size <= 4); if (stride < 0) { _mesa_error( ctx, GL_INVALID_VALUE, "%s(stride=%d)", func, stride ); return; } elementSize = _mesa_sizeof_type(type) * size; array = &ctx->Array.VertexAttrib[attrib]; array->Size = size; array->Type = type; array->Stride = stride; array->StrideB = stride ? stride : elementSize; array->Normalized = normalized; array->Integer = integer; array->Ptr = (const GLubyte *) ptr; array->_ElementSize = elementSize; ctx->NewState |= _NEW_ARRAY; ctx->Array.NewState |= VERT_BIT(attrib); }
/** * 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; }
/* TODO: populate these as the vertex is defined: */ static void vbo_exec_bind_arrays( struct gl_context *ctx ) { struct vbo_context *vbo = vbo_context(ctx); struct vbo_exec_context *exec = &vbo->exec; struct gl_client_array *arrays = exec->vtx.arrays; const GLuint count = exec->vtx.vert_count; const GLuint *map; GLuint attr; GLbitfield64 varying_inputs = 0x0; /* Install the default (ie Current) attributes first, then overlay * all active ones. */ switch (get_program_mode(exec->ctx)) { case VP_NONE: for (attr = 0; attr < VERT_ATTRIB_FF_MAX; attr++) { exec->vtx.inputs[attr] = &vbo->legacy_currval[attr]; } for (attr = 0; attr < MAT_ATTRIB_MAX; attr++) { ASSERT(VERT_ATTRIB_GENERIC(attr) < Elements(exec->vtx.inputs)); exec->vtx.inputs[VERT_ATTRIB_GENERIC(attr)] = &vbo->mat_currval[attr]; } map = vbo->map_vp_none; break; case VP_NV: case VP_ARB: /* The aliasing of attributes for NV vertex programs has already * occurred. NV vertex programs cannot access material values, * nor attributes greater than VERT_ATTRIB_TEX7. */ for (attr = 0; attr < VERT_ATTRIB_FF_MAX; attr++) { exec->vtx.inputs[attr] = &vbo->legacy_currval[attr]; } for (attr = 0; attr < VERT_ATTRIB_GENERIC_MAX; attr++) { ASSERT(VERT_ATTRIB_GENERIC(attr) < Elements(exec->vtx.inputs)); exec->vtx.inputs[VERT_ATTRIB_GENERIC(attr)] = &vbo->generic_currval[attr]; } map = vbo->map_vp_arb; /* check if VERT_ATTRIB_POS is not read but VERT_BIT_GENERIC0 is read. * In that case we effectively need to route the data from * glVertexAttrib(0, val) calls to feed into the GENERIC0 input. */ if ((ctx->VertexProgram._Current->Base.InputsRead & VERT_BIT_POS) == 0 && (ctx->VertexProgram._Current->Base.InputsRead & VERT_BIT_GENERIC0)) { exec->vtx.inputs[VERT_ATTRIB_GENERIC0] = exec->vtx.inputs[0]; exec->vtx.attrsz[VERT_ATTRIB_GENERIC0] = exec->vtx.attrsz[0]; exec->vtx.attrptr[VERT_ATTRIB_GENERIC0] = exec->vtx.attrptr[0]; exec->vtx.attrsz[0] = 0; } break; default: assert(0); } /* Make all active attributes (including edgeflag) available as * arrays of floats. */ for (attr = 0; attr < VERT_ATTRIB_MAX ; attr++) { const GLuint src = map[attr]; if (exec->vtx.attrsz[src]) { GLsizeiptr offset = (GLbyte *)exec->vtx.attrptr[src] - (GLbyte *)exec->vtx.vertex; /* override the default array set above */ ASSERT(attr < Elements(exec->vtx.inputs)); ASSERT(attr < Elements(exec->vtx.arrays)); /* arrays[] */ exec->vtx.inputs[attr] = &arrays[attr]; if (_mesa_is_bufferobj(exec->vtx.bufferobj)) { /* a real buffer obj: Ptr is an offset, not a pointer*/ assert(exec->vtx.bufferobj->Pointer); /* buf should be mapped */ assert(offset >= 0); arrays[attr].Ptr = (GLubyte *)exec->vtx.bufferobj->Offset + offset; } else { /* Ptr into ordinary app memory */ arrays[attr].Ptr = (GLubyte *)exec->vtx.buffer_map + offset; } arrays[attr].Size = exec->vtx.attrsz[src]; arrays[attr].StrideB = exec->vtx.vertex_size * sizeof(GLfloat); arrays[attr].Stride = exec->vtx.vertex_size * sizeof(GLfloat); arrays[attr].Type = GL_FLOAT; arrays[attr].Format = GL_RGBA; arrays[attr].Enabled = 1; arrays[attr]._ElementSize = arrays[attr].Size * sizeof(GLfloat); _mesa_reference_buffer_object(ctx, &arrays[attr].BufferObj, exec->vtx.bufferobj); arrays[attr]._MaxElement = count; /* ??? */ varying_inputs |= VERT_BIT(attr); ctx->NewState |= _NEW_ARRAY; } } _mesa_set_varying_vp_inputs( ctx, varying_inputs ); }
/** * Treat the vertex storage as a VBO, define vertex arrays pointing * into it: */ static void vbo_bind_vertex_list(struct gl_context *ctx, const struct vbo_save_vertex_list *node) { struct vbo_context *vbo = vbo_context(ctx); struct vbo_save_context *save = &vbo->save; struct gl_client_array *arrays = save->arrays; GLuint buffer_offset = node->buffer_offset; const GLuint *map; GLuint attr; GLubyte node_attrsz[VBO_ATTRIB_MAX]; /* copy of node->attrsz[] */ GLenum node_attrtype[VBO_ATTRIB_MAX]; /* copy of node->attrtype[] */ GLbitfield64 varying_inputs = 0x0; memcpy(node_attrsz, node->attrsz, sizeof(node->attrsz)); memcpy(node_attrtype, node->attrtype, sizeof(node->attrtype)); /* Install the default (ie Current) attributes first, then overlay * all active ones. */ switch (get_program_mode(ctx)) { case VP_NONE: for (attr = 0; attr < VERT_ATTRIB_FF_MAX; attr++) { save->inputs[attr] = &vbo->currval[VBO_ATTRIB_POS+attr]; } for (attr = 0; attr < MAT_ATTRIB_MAX; attr++) { save->inputs[VERT_ATTRIB_GENERIC(attr)] = &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT+attr]; } map = vbo->map_vp_none; break; case VP_ARB: for (attr = 0; attr < VERT_ATTRIB_FF_MAX; attr++) { save->inputs[attr] = &vbo->currval[VBO_ATTRIB_POS+attr]; } for (attr = 0; attr < VERT_ATTRIB_GENERIC_MAX; attr++) { save->inputs[VERT_ATTRIB_GENERIC(attr)] = &vbo->currval[VBO_ATTRIB_GENERIC0+attr]; } map = vbo->map_vp_arb; /* check if VERT_ATTRIB_POS is not read but VERT_BIT_GENERIC0 is read. * In that case we effectively need to route the data from * glVertexAttrib(0, val) calls to feed into the GENERIC0 input. */ if ((ctx->VertexProgram._Current->Base.InputsRead & VERT_BIT_POS) == 0 && (ctx->VertexProgram._Current->Base.InputsRead & VERT_BIT_GENERIC0)) { save->inputs[VERT_ATTRIB_GENERIC0] = save->inputs[0]; node_attrsz[VERT_ATTRIB_GENERIC0] = node_attrsz[0]; node_attrtype[VERT_ATTRIB_GENERIC0] = node_attrtype[0]; node_attrsz[0] = 0; } break; default: assert(0); } for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) { const GLuint src = map[attr]; if (node_attrsz[src]) { /* override the default array set above */ save->inputs[attr] = &arrays[attr]; arrays[attr].Ptr = (const GLubyte *) NULL + buffer_offset; arrays[attr].Size = node_attrsz[src]; arrays[attr].StrideB = node->vertex_size * sizeof(GLfloat); arrays[attr].Type = node_attrtype[src]; arrays[attr].Integer = vbo_attrtype_to_integer_flag(node_attrtype[src]); arrays[attr].Format = GL_RGBA; arrays[attr]._ElementSize = arrays[attr].Size * sizeof(GLfloat); _mesa_reference_buffer_object(ctx, &arrays[attr].BufferObj, node->vertex_store->bufferobj); assert(arrays[attr].BufferObj->Name); buffer_offset += node_attrsz[src] * sizeof(GLfloat); varying_inputs |= VERT_BIT(attr); } } _mesa_set_varying_vp_inputs( ctx, varying_inputs ); ctx->NewDriverState |= ctx->DriverFlags.NewArray; }
/** * Do error checking and update state for glVertex/Color/TexCoord/...Pointer * functions. * * \param func name of calling function used for error reporting * \param attrib the attribute array index to update * \param legalTypes bitmask of *_BIT above indicating legal datatypes * \param sizeMin min allowable size value * \param sizeMax max allowable size value (may also be BGRA_OR_4) * \param size components per element (1, 2, 3 or 4) * \param type datatype of each component (GL_FLOAT, GL_INT, etc) * \param stride stride between elements, in elements * \param normalized are integer types converted to floats in [-1, 1]? * \param integer integer-valued values (will not be normalized to [-1,1]) * \param ptr the address (or offset inside VBO) of the array data */ static void update_array(struct gl_context *ctx, const char *func, GLuint attrib, GLbitfield legalTypesMask, GLint sizeMin, GLint sizeMax, GLint size, GLenum type, GLsizei stride, GLboolean normalized, GLboolean integer, const GLvoid *ptr) { struct gl_client_array *array; GLbitfield typeBit; GLsizei elementSize; GLenum format = GL_RGBA; if (_mesa_is_gles(ctx)) { /* Once Mesa gets support for GL_OES_vertex_half_float this mask will * change. Adding support for this extension isn't quite as trivial as * we'd like because ES uses a different enum value for GL_HALF_FLOAT. */ legalTypesMask &= ~(FIXED_GL_BIT | HALF_BIT | DOUBLE_BIT); /* GL_INT and GL_UNSIGNED_INT data is not allowed in OpenGL ES until * 3.0. The 2_10_10_10 types are added in OpenGL ES 3.0 or * GL_OES_vertex_type_10_10_10_2. */ if (ctx->Version < 30) { legalTypesMask &= ~(UNSIGNED_INT_BIT | INT_BIT | UNSIGNED_INT_2_10_10_10_REV_BIT | INT_2_10_10_10_REV_BIT); } /* BGRA ordering is not supported in ES contexts. */ if (sizeMax == BGRA_OR_4) sizeMax = 4; } else { legalTypesMask &= ~FIXED_ES_BIT; if (!ctx->Extensions.ARB_ES2_compatibility) legalTypesMask &= ~FIXED_GL_BIT; if (!ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) legalTypesMask &= ~(UNSIGNED_INT_2_10_10_10_REV_BIT | INT_2_10_10_10_REV_BIT); } typeBit = type_to_bit(ctx, type); if (typeBit == 0x0 || (typeBit & legalTypesMask) == 0x0) { _mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)", func, _mesa_lookup_enum_by_nr(type)); return; } /* Do size parameter checking. * If sizeMax = BGRA_OR_4 it means that size = GL_BGRA is legal and * must be handled specially. */ if (ctx->Extensions.EXT_vertex_array_bgra && sizeMax == BGRA_OR_4 && size == GL_BGRA) { GLboolean bgra_error = GL_FALSE; if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) { if (type != GL_UNSIGNED_INT_2_10_10_10_REV && type != GL_INT_2_10_10_10_REV && type != GL_UNSIGNED_BYTE) bgra_error = GL_TRUE; } else if (type != GL_UNSIGNED_BYTE) bgra_error = GL_TRUE; if (bgra_error) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(GL_BGRA/GLubyte)", func); return; } format = GL_BGRA; size = 4; } else if (size < sizeMin || size > sizeMax || size > 4) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", func, size); return; } if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev && (type == GL_UNSIGNED_INT_2_10_10_10_REV || type == GL_INT_2_10_10_10_REV) && size != 4) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=%d)", func, size); return; } ASSERT(size <= 4); if (stride < 0) { _mesa_error( ctx, GL_INVALID_VALUE, "%s(stride=%d)", func, stride ); return; } if (ctx->Array.ArrayObj->ARBsemantics && !_mesa_is_bufferobj(ctx->Array.ArrayBufferObj)) { /* GL_ARB_vertex_array_object requires that all arrays reside in VBOs. * Generate GL_INVALID_OPERATION if that's not true. */ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-VBO array)", func); return; } elementSize = _mesa_sizeof_type(type) * size; array = &ctx->Array.ArrayObj->VertexAttrib[attrib]; array->Size = size; array->Type = type; array->Format = format; array->Stride = stride; array->StrideB = stride ? stride : elementSize; array->Normalized = normalized; array->Integer = integer; array->Ptr = (const GLubyte *) ptr; array->_ElementSize = elementSize; _mesa_reference_buffer_object(ctx, &array->BufferObj, ctx->Array.ArrayBufferObj); ctx->NewState |= _NEW_ARRAY; ctx->Array.ArrayObj->NewArrays |= VERT_BIT(attrib); }
/* TODO: populate these as the vertex is defined: */ static void vbo_exec_bind_arrays( struct gl_context *ctx ) { struct vbo_context *vbo = vbo_context(ctx); struct vbo_exec_context *exec = &vbo->exec; struct gl_client_array *arrays = exec->vtx.arrays; const GLuint *map; GLuint attr; GLbitfield64 varying_inputs = 0x0; /* Install the default (ie Current) attributes first, then overlay * all active ones. */ switch (get_program_mode(exec->ctx)) { case VP_NONE: for (attr = 0; attr < VERT_ATTRIB_FF_MAX; attr++) { exec->vtx.inputs[attr] = &vbo->currval[VBO_ATTRIB_POS+attr]; } for (attr = 0; attr < MAT_ATTRIB_MAX; attr++) { ASSERT(VERT_ATTRIB_GENERIC(attr) < Elements(exec->vtx.inputs)); exec->vtx.inputs[VERT_ATTRIB_GENERIC(attr)] = &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT+attr]; } map = vbo->map_vp_none; break; case VP_ARB: for (attr = 0; attr < VERT_ATTRIB_FF_MAX; attr++) { exec->vtx.inputs[attr] = &vbo->currval[VBO_ATTRIB_POS+attr]; } for (attr = 0; attr < VERT_ATTRIB_GENERIC_MAX; attr++) { ASSERT(VERT_ATTRIB_GENERIC(attr) < Elements(exec->vtx.inputs)); exec->vtx.inputs[VERT_ATTRIB_GENERIC(attr)] = &vbo->currval[VBO_ATTRIB_GENERIC0+attr]; } map = vbo->map_vp_arb; /* check if VERT_ATTRIB_POS is not read but VERT_BIT_GENERIC0 is read. * In that case we effectively need to route the data from * glVertexAttrib(0, val) calls to feed into the GENERIC0 input. */ if ((ctx->VertexProgram._Current->Base.InputsRead & VERT_BIT_POS) == 0 && (ctx->VertexProgram._Current->Base.InputsRead & VERT_BIT_GENERIC0)) { exec->vtx.inputs[VERT_ATTRIB_GENERIC0] = exec->vtx.inputs[0]; exec->vtx.attrsz[VERT_ATTRIB_GENERIC0] = exec->vtx.attrsz[0]; exec->vtx.attrptr[VERT_ATTRIB_GENERIC0] = exec->vtx.attrptr[0]; exec->vtx.attrsz[0] = 0; } break; default: assert(0); } for (attr = 0; attr < VERT_ATTRIB_MAX ; attr++) { const GLuint src = map[attr]; if (exec->vtx.attrsz[src]) { GLsizeiptr offset = (GLbyte *)exec->vtx.attrptr[src] - (GLbyte *)exec->vtx.vertex; /* override the default array set above */ ASSERT(attr < Elements(exec->vtx.inputs)); ASSERT(attr < Elements(exec->vtx.arrays)); /* arrays[] */ exec->vtx.inputs[attr] = &arrays[attr]; if (_mesa_is_bufferobj(exec->vtx.bufferobj)) { /* a real buffer obj: Ptr is an offset, not a pointer*/ assert(exec->vtx.bufferobj->Mappings[MAP_INTERNAL].Pointer); assert(offset >= 0); arrays[attr].Ptr = (GLubyte *) exec->vtx.bufferobj->Mappings[MAP_INTERNAL].Offset + offset; } else { /* Ptr into ordinary app memory */ arrays[attr].Ptr = (GLubyte *)exec->vtx.buffer_map + offset; } arrays[attr].Size = exec->vtx.attrsz[src]; arrays[attr].StrideB = exec->vtx.vertex_size * sizeof(GLfloat); arrays[attr].Stride = exec->vtx.vertex_size * sizeof(GLfloat); arrays[attr].Type = exec->vtx.attrtype[src]; arrays[attr].Integer = vbo_attrtype_to_integer_flag(exec->vtx.attrtype[src]); arrays[attr].Format = GL_RGBA; arrays[attr].Enabled = 1; arrays[attr]._ElementSize = arrays[attr].Size * sizeof(GLfloat); _mesa_reference_buffer_object(ctx, &arrays[attr].BufferObj, exec->vtx.bufferobj); varying_inputs |= VERT_BIT(attr); } } _mesa_set_varying_vp_inputs( ctx, varying_inputs ); ctx->NewDriverState |= ctx->DriverFlags.NewArray; }
/** * Do error checking and update state for glVertex/Color/TexCoord/...Pointer * functions. * * \param func name of calling function used for error reporting * \param attrib the attribute array index to update * \param legalTypes bitmask of *_BIT above indicating legal datatypes * \param sizeMin min allowable size value * \param sizeMax max allowable size value (may also be BGRA_OR_4) * \param size components per element (1, 2, 3 or 4) * \param type datatype of each component (GL_FLOAT, GL_INT, etc) * \param stride stride between elements, in elements * \param normalized are integer types converted to floats in [-1, 1]? * \param integer integer-valued values (will not be normalized to [-1,1]) * \param ptr the address (or offset inside VBO) of the array data */ static void update_array(struct gl_context *ctx, const char *func, GLuint attrib, GLbitfield legalTypesMask, GLint sizeMin, GLint sizeMax, GLint size, GLenum type, GLsizei stride, GLboolean normalized, GLboolean integer, const GLvoid *ptr) { struct gl_client_array *array; GLbitfield typeBit; GLsizei elementSize; GLenum format = GL_RGBA; if (ctx->API != API_OPENGLES && ctx->API != API_OPENGLES2) { /* fixed point arrays / data is only allowed with OpenGL ES 1.x/2.0 */ legalTypesMask &= ~FIXED_ES_BIT; } if (!ctx->Extensions.ARB_ES2_compatibility) { legalTypesMask &= ~FIXED_GL_BIT; } if (!ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) { legalTypesMask &= ~(UNSIGNED_INT_2_10_10_10_REV_BIT | INT_2_10_10_10_REV_BIT); } typeBit = type_to_bit(ctx, type); if (typeBit == 0x0 || (typeBit & legalTypesMask) == 0x0) { _mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)", func, _mesa_lookup_enum_by_nr(type)); return; } /* Do size parameter checking. * If sizeMax = BGRA_OR_4 it means that size = GL_BGRA is legal and * must be handled specially. */ if (ctx->Extensions.EXT_vertex_array_bgra && sizeMax == BGRA_OR_4 && size == GL_BGRA) { GLboolean bgra_error = GL_FALSE; if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) { if (type != GL_UNSIGNED_INT_2_10_10_10_REV && type != GL_INT_2_10_10_10_REV && type != GL_UNSIGNED_BYTE) bgra_error = GL_TRUE; } else if (type != GL_UNSIGNED_BYTE) bgra_error = GL_TRUE; if (bgra_error) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(GL_BGRA/GLubyte)", func); return; } format = GL_BGRA; size = 4; } else if (size < sizeMin || size > sizeMax || size > 4) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", func, size); return; } if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev && (type == GL_UNSIGNED_INT_2_10_10_10_REV || type == GL_INT_2_10_10_10_REV) && size != 4) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=%d)", func, size); } ASSERT(size <= 4); if (stride < 0) { _mesa_error( ctx, GL_INVALID_VALUE, "%s(stride=%d)", func, stride ); return; } if (ctx->Array.ArrayObj->ARBsemantics && !_mesa_is_bufferobj(ctx->Array.ArrayBufferObj)) { /* GL_ARB_vertex_array_object requires that all arrays reside in VBOs. * Generate GL_INVALID_OPERATION if that's not true. */ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-VBO array)", func); return; } elementSize = _mesa_sizeof_type(type) * size; array = &ctx->Array.ArrayObj->VertexAttrib[attrib]; array->Size = size; array->Type = type; array->Format = format; array->Stride = stride; array->StrideB = stride ? stride : elementSize; array->Normalized = normalized; array->Integer = integer; array->Ptr = (const GLubyte *) ptr; array->_ElementSize = elementSize; _mesa_reference_buffer_object(ctx, &array->BufferObj, ctx->Array.ArrayBufferObj); ctx->NewState |= _NEW_ARRAY; ctx->Array.NewState |= VERT_BIT(attrib); }