mesa/vbo: add support for 64-bit vertex attributes. (v1)
This adds support in the vbo and array code to handle double vertex attributes. v0.2: merge code to handle doubles in vbo layer. v1: don't use v0, merge api_array elt code. Acked-by: Ilia Mirkin <imirkin@alum.mit.edu> Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
@@ -1258,12 +1258,37 @@ VertexAttribI4uiv(GLuint index, const GLuint *v)
|
||||
CALL_VertexAttribI4uivEXT(GET_DISPATCH(), (index, v));
|
||||
}
|
||||
|
||||
/* GL_DOUBLE unconverted attributes */
|
||||
|
||||
static void GLAPIENTRY
|
||||
VertexAttribL1dv(GLuint index, const GLdouble *v)
|
||||
{
|
||||
CALL_VertexAttribL1dv(GET_DISPATCH(), (index, v));
|
||||
}
|
||||
|
||||
static void GLAPIENTRY
|
||||
VertexAttribL2dv(GLuint index, const GLdouble *v)
|
||||
{
|
||||
CALL_VertexAttribL2dv(GET_DISPATCH(), (index, v));
|
||||
}
|
||||
|
||||
static void GLAPIENTRY
|
||||
VertexAttribL3dv(GLuint index, const GLdouble *v)
|
||||
{
|
||||
CALL_VertexAttribL3dv(GET_DISPATCH(), (index, v));
|
||||
}
|
||||
|
||||
static void GLAPIENTRY
|
||||
VertexAttribL4dv(GLuint index, const GLdouble *v)
|
||||
{
|
||||
CALL_VertexAttribL4dv(GET_DISPATCH(), (index, v));
|
||||
}
|
||||
|
||||
/*
|
||||
* Array [unnormalized/normalized/integer][size][type] of VertexAttrib
|
||||
* functions
|
||||
*/
|
||||
static attrib_func AttribFuncsARB[3][4][NUM_TYPES] = {
|
||||
static attrib_func AttribFuncsARB[4][4][NUM_TYPES] = {
|
||||
{
|
||||
/* non-normalized */
|
||||
{
|
||||
@@ -1405,7 +1430,55 @@ static attrib_func AttribFuncsARB[3][4][NUM_TYPES] = {
|
||||
NULL, /* GL_FLOAT */
|
||||
NULL /* GL_DOUBLE */
|
||||
}
|
||||
},
|
||||
{
|
||||
/* double-valued */
|
||||
{
|
||||
/* size 1 */
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
(attrib_func) VertexAttribL1dv,
|
||||
},
|
||||
{
|
||||
/* size 2 */
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
(attrib_func) VertexAttribL2dv,
|
||||
},
|
||||
{
|
||||
/* size 3 */
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
(attrib_func) VertexAttribL3dv,
|
||||
},
|
||||
{
|
||||
/* size 4 */
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
(attrib_func) VertexAttribL4dv,
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -1571,7 +1644,9 @@ _ae_update_state(struct gl_context *ctx)
|
||||
* change from one execution of _ae_ArrayElement() to
|
||||
* the next. Doing so caused UT to break.
|
||||
*/
|
||||
if (at->array->Integer)
|
||||
if (at->array->Doubles)
|
||||
intOrNorm = 3;
|
||||
else if (at->array->Integer)
|
||||
intOrNorm = 2;
|
||||
else if (at->array->Normalized)
|
||||
intOrNorm = 1;
|
||||
|
@@ -84,6 +84,10 @@
|
||||
|
||||
#define ATTRIBI_4UI(index,x,y,z,w) CALL_VertexAttribI4uiEXT(GET_DISPATCH(), (index,x,y,z,w))
|
||||
|
||||
#define ATTRIB1_D(index,x) CALL_VertexAttribL1d(GET_DISPATCH(), (index,x))
|
||||
#define ATTRIB2_D(index,x,y) CALL_VertexAttribL2d(GET_DISPATCH(), (index,x,y))
|
||||
#define ATTRIB3_D(index,x,y,z) CALL_VertexAttribL3d(GET_DISPATCH(), (index,x,y,z))
|
||||
#define ATTRIB4_D(index,x,y,z,w) CALL_VertexAttribL4d(GET_DISPATCH(), (index,x,y,z,w))
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_Color3b( GLbyte red, GLbyte green, GLbyte blue )
|
||||
@@ -1493,41 +1497,49 @@ _mesa_VertexAttribI4usv(GLuint index, const GLushort *v)
|
||||
void GLAPIENTRY
|
||||
_mesa_VertexAttribL1d(GLuint index, GLdouble x)
|
||||
{
|
||||
ATTRIB1_D(index, x);
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_VertexAttribL2d(GLuint index, GLdouble x, GLdouble y)
|
||||
{
|
||||
ATTRIB2_D(index, x, y);
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_VertexAttribL3d(GLuint index, GLdouble x, GLdouble y, GLdouble z)
|
||||
{
|
||||
ATTRIB3_D(index, x, y, z);
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_VertexAttribL4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
|
||||
{
|
||||
ATTRIB4_D(index, x, y, z, w);
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_VertexAttribL1dv(GLuint index, const GLdouble *v)
|
||||
{
|
||||
ATTRIB1_D(index, v[0]);
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_VertexAttribL2dv(GLuint index, const GLdouble *v)
|
||||
{
|
||||
ATTRIB2_D(index, v[0], v[1]);
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_VertexAttribL3dv(GLuint index, const GLdouble *v)
|
||||
{
|
||||
ATTRIB3_D(index, v[0], v[1], v[2]);
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_VertexAttribL4dv(GLuint index, const GLdouble *v)
|
||||
{
|
||||
ATTRIB4_D(index, v[0], v[1], v[2], v[3]);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1760,5 +1772,16 @@ _mesa_loopback_init_api_table(const struct gl_context *ctx,
|
||||
SET_VertexAttribI4sv(dest, _mesa_VertexAttribI4sv);
|
||||
SET_VertexAttribI4ubv(dest, _mesa_VertexAttribI4ubv);
|
||||
SET_VertexAttribI4usv(dest, _mesa_VertexAttribI4usv);
|
||||
|
||||
/* GL 4.1 / GL_ARB_vertex_attrib_64bit */
|
||||
SET_VertexAttribL1d(dest, _mesa_VertexAttribL1d);
|
||||
SET_VertexAttribL2d(dest, _mesa_VertexAttribL2d);
|
||||
SET_VertexAttribL3d(dest, _mesa_VertexAttribL3d);
|
||||
SET_VertexAttribL4d(dest, _mesa_VertexAttribL4d);
|
||||
|
||||
SET_VertexAttribL1dv(dest, _mesa_VertexAttribL1dv);
|
||||
SET_VertexAttribL2dv(dest, _mesa_VertexAttribL2dv);
|
||||
SET_VertexAttribL3dv(dest, _mesa_VertexAttribL3dv);
|
||||
SET_VertexAttribL4dv(dest, _mesa_VertexAttribL4dv);
|
||||
}
|
||||
}
|
||||
|
@@ -200,6 +200,7 @@ init_array(struct gl_context *ctx,
|
||||
array->Enabled = GL_FALSE;
|
||||
array->Normalized = GL_FALSE;
|
||||
array->Integer = GL_FALSE;
|
||||
array->Doubles = GL_FALSE;
|
||||
array->_ElementSize = size * _mesa_sizeof_type(type);
|
||||
array->VertexBinding = index;
|
||||
|
||||
|
@@ -1174,6 +1174,19 @@ typedef struct {
|
||||
void (GLAPIENTRYP VertexAttribP4uiv)( GLuint index, GLenum type,
|
||||
GLboolean normalized,
|
||||
const GLuint *value);
|
||||
|
||||
/* GL_ARB_vertex_attrib_64bit / GL 4.1 */
|
||||
void (GLAPIENTRYP VertexAttribL1d)( GLuint index, GLdouble x);
|
||||
void (GLAPIENTRYP VertexAttribL2d)( GLuint index, GLdouble x, GLdouble y);
|
||||
void (GLAPIENTRYP VertexAttribL3d)( GLuint index, GLdouble x, GLdouble y, GLdouble z);
|
||||
void (GLAPIENTRYP VertexAttribL4d)( GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
|
||||
|
||||
|
||||
void (GLAPIENTRYP VertexAttribL1dv)( GLuint index, const GLdouble *v);
|
||||
void (GLAPIENTRYP VertexAttribL2dv)( GLuint index, const GLdouble *v);
|
||||
void (GLAPIENTRYP VertexAttribL3dv)( GLuint index, const GLdouble *v);
|
||||
void (GLAPIENTRYP VertexAttribL4dv)( GLuint index, const GLdouble *v);
|
||||
|
||||
} GLvertexformat;
|
||||
|
||||
|
||||
|
@@ -695,7 +695,8 @@ struct gl_current_attrib
|
||||
* \note Index and Edgeflag current values are stored as floats in the
|
||||
* SIX and SEVEN attribute slots.
|
||||
*/
|
||||
GLfloat Attrib[VERT_ATTRIB_MAX][4]; /**< Position, color, texcoords, etc */
|
||||
/* we need double storage for this for vertex attrib 64bit */
|
||||
GLfloat Attrib[VERT_ATTRIB_MAX][4*2]; /**< Position, color, texcoords, etc */
|
||||
|
||||
/**
|
||||
* \name Current raster position attributes (always valid).
|
||||
@@ -1523,6 +1524,7 @@ struct gl_client_array
|
||||
GLboolean Enabled; /**< Enabled flag is a boolean */
|
||||
GLboolean Normalized; /**< GL_ARB_vertex_program */
|
||||
GLboolean Integer; /**< Integer-valued? */
|
||||
GLboolean Doubles; /**< double precision values are not converted to floats */
|
||||
GLuint InstanceDivisor; /**< GL_ARB_instanced_arrays */
|
||||
|
||||
struct gl_buffer_object *BufferObj;/**< GL_ARB_vertex_buffer_object */
|
||||
@@ -1553,6 +1555,7 @@ struct gl_vertex_attrib_array
|
||||
GLboolean Enabled; /**< Whether the array is enabled */
|
||||
GLboolean Normalized; /**< Fixed-point values are normalized when converted to floats */
|
||||
GLboolean Integer; /**< Fixed-point values are not converted to floats */
|
||||
GLboolean Doubles; /**< double precision values are not converted to floats */
|
||||
GLuint _ElementSize; /**< Size of each element in bytes */
|
||||
GLuint VertexBinding; /**< Vertex buffer binding */
|
||||
};
|
||||
|
@@ -243,6 +243,7 @@ get_legal_types_mask(const struct gl_context *ctx)
|
||||
* \param type Datatype of each component (GL_FLOAT, GL_INT, etc)
|
||||
* \param normalized Whether integer types are converted to floats in [-1, 1]
|
||||
* \param integer Integer-valued values (will not be normalized to [-1, 1])
|
||||
* \param doubles Double values not reduced to floats
|
||||
* \param relativeOffset Offset of the first element relative to the binding offset.
|
||||
*/
|
||||
static bool
|
||||
@@ -251,7 +252,7 @@ update_array_format(struct gl_context *ctx,
|
||||
GLuint attrib, GLbitfield legalTypesMask,
|
||||
GLint sizeMin, GLint sizeMax,
|
||||
GLint size, GLenum type,
|
||||
GLboolean normalized, GLboolean integer,
|
||||
GLboolean normalized, GLboolean integer, GLboolean doubles,
|
||||
GLuint relativeOffset)
|
||||
{
|
||||
struct gl_vertex_attrib_array *array;
|
||||
@@ -368,6 +369,7 @@ update_array_format(struct gl_context *ctx,
|
||||
array->Format = format;
|
||||
array->Normalized = normalized;
|
||||
array->Integer = integer;
|
||||
array->Doubles = doubles;
|
||||
array->RelativeOffset = relativeOffset;
|
||||
array->_ElementSize = elementSize;
|
||||
|
||||
@@ -392,6 +394,7 @@ update_array_format(struct gl_context *ctx,
|
||||
* \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 doubles Double values not reduced to floats
|
||||
* \param ptr the address (or offset inside VBO) of the array data
|
||||
*/
|
||||
static void
|
||||
@@ -400,7 +403,7 @@ update_array(struct gl_context *ctx,
|
||||
GLuint attrib, GLbitfield legalTypesMask,
|
||||
GLint sizeMin, GLint sizeMax,
|
||||
GLint size, GLenum type, GLsizei stride,
|
||||
GLboolean normalized, GLboolean integer,
|
||||
GLboolean normalized, GLboolean integer, GLboolean doubles,
|
||||
const GLvoid *ptr)
|
||||
{
|
||||
struct gl_vertex_attrib_array *array;
|
||||
@@ -454,7 +457,7 @@ update_array(struct gl_context *ctx,
|
||||
}
|
||||
|
||||
if (!update_array_format(ctx, func, attrib, legalTypesMask, sizeMin,
|
||||
sizeMax, size, type, normalized, integer, 0)) {
|
||||
sizeMax, size, type, normalized, integer, doubles, 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -488,7 +491,7 @@ _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
|
||||
|
||||
update_array(ctx, "glVertexPointer", VERT_ATTRIB_POS,
|
||||
legalTypes, 2, 4,
|
||||
size, type, stride, GL_FALSE, GL_FALSE, ptr);
|
||||
size, type, stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -507,7 +510,7 @@ _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
|
||||
|
||||
update_array(ctx, "glNormalPointer", VERT_ATTRIB_NORMAL,
|
||||
legalTypes, 3, 3,
|
||||
3, type, stride, GL_TRUE, GL_FALSE, ptr);
|
||||
3, type, stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -529,7 +532,7 @@ _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
|
||||
|
||||
update_array(ctx, "glColorPointer", VERT_ATTRIB_COLOR0,
|
||||
legalTypes, sizeMin, BGRA_OR_4,
|
||||
size, type, stride, GL_TRUE, GL_FALSE, ptr);
|
||||
size, type, stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -543,7 +546,7 @@ _mesa_FogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
|
||||
|
||||
update_array(ctx, "glFogCoordPointer", VERT_ATTRIB_FOG,
|
||||
legalTypes, 1, 1,
|
||||
1, type, stride, GL_FALSE, GL_FALSE, ptr);
|
||||
1, type, stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -558,7 +561,7 @@ _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
|
||||
|
||||
update_array(ctx, "glIndexPointer", VERT_ATTRIB_COLOR_INDEX,
|
||||
legalTypes, 1, 1,
|
||||
1, type, stride, GL_FALSE, GL_FALSE, ptr);
|
||||
1, type, stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -578,7 +581,7 @@ _mesa_SecondaryColorPointer(GLint size, GLenum type,
|
||||
|
||||
update_array(ctx, "glSecondaryColorPointer", VERT_ATTRIB_COLOR1,
|
||||
legalTypes, 3, BGRA_OR_4,
|
||||
size, type, stride, GL_TRUE, GL_FALSE, ptr);
|
||||
size, type, stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -600,7 +603,7 @@ _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
|
||||
|
||||
update_array(ctx, "glTexCoordPointer", VERT_ATTRIB_TEX(unit),
|
||||
legalTypes, sizeMin, 4,
|
||||
size, type, stride, GL_FALSE, GL_FALSE,
|
||||
size, type, stride, GL_FALSE, GL_FALSE, GL_FALSE,
|
||||
ptr);
|
||||
}
|
||||
|
||||
@@ -617,7 +620,7 @@ _mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr)
|
||||
|
||||
update_array(ctx, "glEdgeFlagPointer", VERT_ATTRIB_EDGEFLAG,
|
||||
legalTypes, 1, 1,
|
||||
1, GL_UNSIGNED_BYTE, stride, GL_FALSE, integer, ptr);
|
||||
1, GL_UNSIGNED_BYTE, stride, GL_FALSE, integer, GL_FALSE, ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -637,7 +640,7 @@ _mesa_PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *ptr)
|
||||
|
||||
update_array(ctx, "glPointSizePointer", VERT_ATTRIB_POINT_SIZE,
|
||||
legalTypes, 1, 1,
|
||||
1, type, stride, GL_FALSE, GL_FALSE, ptr);
|
||||
1, type, stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -668,7 +671,7 @@ _mesa_VertexAttribPointer(GLuint index, GLint size, GLenum type,
|
||||
|
||||
update_array(ctx, "glVertexAttribPointer", VERT_ATTRIB_GENERIC(index),
|
||||
legalTypes, 1, BGRA_OR_4,
|
||||
size, type, stride, normalized, GL_FALSE, ptr);
|
||||
size, type, stride, normalized, GL_FALSE, GL_FALSE, ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -696,13 +699,23 @@ _mesa_VertexAttribIPointer(GLuint index, GLint size, GLenum type,
|
||||
|
||||
update_array(ctx, "glVertexAttribIPointer", VERT_ATTRIB_GENERIC(index),
|
||||
legalTypes, 1, 4,
|
||||
size, type, stride, normalized, integer, ptr);
|
||||
size, type, stride, normalized, integer, GL_FALSE, ptr);
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_VertexAttribLPointer(GLuint index, GLint size, GLenum type,
|
||||
GLsizei stride, const GLvoid *ptr)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
const GLbitfield legalTypes = (DOUBLE_BIT);
|
||||
if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribLPointer(index)");
|
||||
return;
|
||||
}
|
||||
|
||||
update_array(ctx, "glVertexAttribLPointer", VERT_ATTRIB_GENERIC(index),
|
||||
legalTypes, 1, 4,
|
||||
size, type, stride, GL_TRUE, GL_FALSE, GL_TRUE, ptr);
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
@@ -886,6 +899,21 @@ _mesa_GetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params)
|
||||
void GLAPIENTRY
|
||||
_mesa_GetVertexAttribLdv(GLuint index, GLenum pname, GLdouble *params)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
|
||||
if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
|
||||
const GLdouble *v = (const GLdouble *)get_current_attrib(ctx, index, "glGetVertexAttribLdv");
|
||||
if (v != NULL) {
|
||||
params[0] = v[0];
|
||||
params[1] = v[1];
|
||||
params[2] = v[2];
|
||||
params[3] = v[3];
|
||||
}
|
||||
}
|
||||
else {
|
||||
params[0] = (GLdouble) get_vertex_array_attrib(ctx, index, pname,
|
||||
"glGetVertexAttribLdv");
|
||||
}
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
@@ -1671,7 +1699,7 @@ _mesa_VertexAttribFormat(GLuint attribIndex, GLint size, GLenum type,
|
||||
update_array_format(ctx, "glVertexAttribFormat",
|
||||
VERT_ATTRIB_GENERIC(attribIndex),
|
||||
legalTypes, 1, BGRA_OR_4, size, type, normalized,
|
||||
GL_FALSE, relativeOffset);
|
||||
GL_FALSE, GL_FALSE, relativeOffset);
|
||||
}
|
||||
|
||||
|
||||
@@ -1717,7 +1745,7 @@ _mesa_VertexAttribIFormat(GLuint attribIndex, GLint size, GLenum type,
|
||||
|
||||
update_array_format(ctx, "glVertexAttribIFormat",
|
||||
VERT_ATTRIB_GENERIC(attribIndex),
|
||||
legalTypes, 1, 4, size, type, GL_FALSE, GL_TRUE,
|
||||
legalTypes, 1, 4, size, type, GL_FALSE, GL_TRUE, GL_FALSE,
|
||||
relativeOffset);
|
||||
}
|
||||
|
||||
@@ -1765,7 +1793,7 @@ _mesa_VertexAttribLFormat(GLuint attribIndex, GLint size, GLenum type,
|
||||
|
||||
update_array_format(ctx, "glVertexAttribLFormat",
|
||||
VERT_ATTRIB_GENERIC(attribIndex),
|
||||
legalTypes, 1, 4, size, type, GL_FALSE, GL_FALSE,
|
||||
legalTypes, 1, 4, size, type, GL_FALSE, GL_FALSE, GL_TRUE,
|
||||
relativeOffset);
|
||||
}
|
||||
|
||||
@@ -1876,6 +1904,7 @@ _mesa_copy_client_array(struct gl_context *ctx,
|
||||
dst->Enabled = src->Enabled;
|
||||
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);
|
||||
@@ -1893,6 +1922,7 @@ _mesa_copy_vertex_attrib_array(struct gl_context *ctx,
|
||||
dst->RelativeOffset = src->RelativeOffset;
|
||||
dst->Format = src->Format;
|
||||
dst->Integer = src->Integer;
|
||||
dst->Doubles = src->Doubles;
|
||||
dst->Normalized = src->Normalized;
|
||||
dst->Ptr = src->Ptr;
|
||||
dst->Enabled = src->Enabled;
|
||||
|
@@ -68,6 +68,7 @@ _mesa_update_client_array(struct gl_context *ctx,
|
||||
dst->Enabled = src->Enabled;
|
||||
dst->Normalized = src->Normalized;
|
||||
dst->Integer = src->Integer;
|
||||
dst->Doubles = src->Doubles;
|
||||
dst->InstanceDivisor = binding->InstanceDivisor;
|
||||
dst->_ElementSize = src->_ElementSize;
|
||||
_mesa_reference_buffer_object(ctx, &dst->BufferObj, binding->BufferObj);
|
||||
|
@@ -206,6 +206,18 @@ install_vtxfmt(struct gl_context *ctx, struct _glapi_table *tab,
|
||||
SET_VertexAttribP3uiv(tab, vfmt->VertexAttribP3uiv);
|
||||
SET_VertexAttribP4uiv(tab, vfmt->VertexAttribP4uiv);
|
||||
}
|
||||
|
||||
if (_mesa_is_desktop_gl(ctx)) {
|
||||
SET_VertexAttribL1d(tab, vfmt->VertexAttribL1d);
|
||||
SET_VertexAttribL2d(tab, vfmt->VertexAttribL2d);
|
||||
SET_VertexAttribL3d(tab, vfmt->VertexAttribL3d);
|
||||
SET_VertexAttribL4d(tab, vfmt->VertexAttribL4d);
|
||||
|
||||
SET_VertexAttribL1dv(tab, vfmt->VertexAttribL1dv);
|
||||
SET_VertexAttribL2dv(tab, vfmt->VertexAttribL2dv);
|
||||
SET_VertexAttribL3dv(tab, vfmt->VertexAttribL3dv);
|
||||
SET_VertexAttribL4dv(tab, vfmt->VertexAttribL4dv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -31,14 +31,16 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
/* ATTR */
|
||||
#define ATTRI( A, N, V0, V1, V2, V3 ) \
|
||||
ATTR_UNION(A, N, GL_INT, INT_AS_UNION(V0), INT_AS_UNION(V1), \
|
||||
ATTR_UNION(A, N, GL_INT, fi_type, INT_AS_UNION(V0), INT_AS_UNION(V1), \
|
||||
INT_AS_UNION(V2), INT_AS_UNION(V3))
|
||||
#define ATTRUI( A, N, V0, V1, V2, V3 ) \
|
||||
ATTR_UNION(A, N, GL_UNSIGNED_INT, UINT_AS_UNION(V0), UINT_AS_UNION(V1), \
|
||||
ATTR_UNION(A, N, GL_UNSIGNED_INT, fi_type, UINT_AS_UNION(V0), UINT_AS_UNION(V1), \
|
||||
UINT_AS_UNION(V2), UINT_AS_UNION(V3))
|
||||
#define ATTRF( A, N, V0, V1, V2, V3 ) \
|
||||
ATTR_UNION(A, N, GL_FLOAT, FLOAT_AS_UNION(V0), FLOAT_AS_UNION(V1),\
|
||||
ATTR_UNION(A, N, GL_FLOAT, fi_type, FLOAT_AS_UNION(V0), FLOAT_AS_UNION(V1),\
|
||||
FLOAT_AS_UNION(V2), FLOAT_AS_UNION(V3))
|
||||
#define ATTRD( A, N, V0, V1, V2, V3 ) \
|
||||
ATTR_UNION(A, N, GL_DOUBLE, double, V0, V1, V2, V3)
|
||||
|
||||
|
||||
/* float */
|
||||
@@ -232,6 +234,19 @@ static inline float conv_i2_to_norm_float(const struct gl_context *ctx, int i2)
|
||||
ERROR(GL_INVALID_VALUE); \
|
||||
} while(0)
|
||||
|
||||
|
||||
/* Doubles */
|
||||
#define ATTR1DV( A, V ) ATTRD( A, 1, (V)[0], 0, 0, 1 )
|
||||
#define ATTR2DV( A, V ) ATTRD( A, 2, (V)[0], (V)[1], 0, 1 )
|
||||
#define ATTR3DV( A, V ) ATTRD( A, 3, (V)[0], (V)[1], (V)[2], 1 )
|
||||
#define ATTR4DV( A, V ) ATTRD( A, 4, (V)[0], (V)[1], (V)[2], (V)[3] )
|
||||
|
||||
#define ATTR1D( A, X ) ATTRD( A, 1, X, 0, 0, 1 )
|
||||
#define ATTR2D( A, X, Y ) ATTRD( A, 2, X, Y, 0, 1 )
|
||||
#define ATTR3D( A, X, Y, Z ) ATTRD( A, 3, X, Y, Z, 1 )
|
||||
#define ATTR4D( A, X, Y, Z, W ) ATTRD( A, 4, X, Y, Z, W )
|
||||
|
||||
|
||||
static void GLAPIENTRY
|
||||
TAG(Vertex2f)(GLfloat x, GLfloat y)
|
||||
{
|
||||
@@ -1190,6 +1205,104 @@ TAG(VertexAttribP4uiv)(GLuint index, GLenum type, GLboolean normalized,
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void GLAPIENTRY
|
||||
TAG(VertexAttribL1d)(GLuint index, GLdouble x)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
if (index == 0 && _mesa_attr_zero_aliases_vertex(ctx))
|
||||
ATTR1D(0, x);
|
||||
else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
|
||||
ATTR1D(VBO_ATTRIB_GENERIC0 + index, x);
|
||||
else
|
||||
ERROR(GL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
static void GLAPIENTRY
|
||||
TAG(VertexAttribL1dv)(GLuint index, const GLdouble * v)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
if (index == 0 && _mesa_attr_zero_aliases_vertex(ctx))
|
||||
ATTR1DV(0, v);
|
||||
else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
|
||||
ATTR1DV(VBO_ATTRIB_GENERIC0 + index, v);
|
||||
else
|
||||
ERROR(GL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
static void GLAPIENTRY
|
||||
TAG(VertexAttribL2d)(GLuint index, GLdouble x, GLdouble y)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
if (index == 0 && _mesa_attr_zero_aliases_vertex(ctx))
|
||||
ATTR2D(0, x, y);
|
||||
else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
|
||||
ATTR2D(VBO_ATTRIB_GENERIC0 + index, x, y);
|
||||
else
|
||||
ERROR(GL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
static void GLAPIENTRY
|
||||
TAG(VertexAttribL2dv)(GLuint index, const GLdouble * v)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
if (index == 0 && _mesa_attr_zero_aliases_vertex(ctx))
|
||||
ATTR2DV(0, v);
|
||||
else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
|
||||
ATTR2DV(VBO_ATTRIB_GENERIC0 + index, v);
|
||||
else
|
||||
ERROR(GL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
static void GLAPIENTRY
|
||||
TAG(VertexAttribL3d)(GLuint index, GLdouble x, GLdouble y, GLdouble z)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
if (index == 0 && _mesa_attr_zero_aliases_vertex(ctx))
|
||||
ATTR3D(0, x, y, z);
|
||||
else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
|
||||
ATTR3D(VBO_ATTRIB_GENERIC0 + index, x, y, z);
|
||||
else
|
||||
ERROR(GL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
static void GLAPIENTRY
|
||||
TAG(VertexAttribL3dv)(GLuint index, const GLdouble * v)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
if (index == 0 && _mesa_attr_zero_aliases_vertex(ctx))
|
||||
ATTR3DV(0, v);
|
||||
else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
|
||||
ATTR3DV(VBO_ATTRIB_GENERIC0 + index, v);
|
||||
else
|
||||
ERROR(GL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
static void GLAPIENTRY
|
||||
TAG(VertexAttribL4d)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
if (index == 0 && _mesa_attr_zero_aliases_vertex(ctx))
|
||||
ATTR4D(0, x, y, z, w);
|
||||
else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
|
||||
ATTR4D(VBO_ATTRIB_GENERIC0 + index, x, y, z, w);
|
||||
else
|
||||
ERROR(GL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
static void GLAPIENTRY
|
||||
TAG(VertexAttribL4dv)(GLuint index, const GLdouble * v)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
if (index == 0 && _mesa_attr_zero_aliases_vertex(ctx))
|
||||
ATTR4DV(0, v);
|
||||
else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
|
||||
ATTR4DV(VBO_ATTRIB_GENERIC0 + index, v);
|
||||
else
|
||||
ERROR(GL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
|
||||
#undef ATTR1FV
|
||||
#undef ATTR2FV
|
||||
#undef ATTR3FV
|
||||
|
@@ -146,6 +146,7 @@ vbo_attrtype_to_integer_flag(GLenum format)
|
||||
{
|
||||
switch (format) {
|
||||
case GL_FLOAT:
|
||||
case GL_DOUBLE:
|
||||
return GL_FALSE;
|
||||
case GL_INT:
|
||||
case GL_UNSIGNED_INT:
|
||||
@@ -156,6 +157,22 @@ vbo_attrtype_to_integer_flag(GLenum format)
|
||||
}
|
||||
}
|
||||
|
||||
static inline GLboolean
|
||||
vbo_attrtype_to_double_flag(GLenum format)
|
||||
{
|
||||
switch (format) {
|
||||
case GL_FLOAT:
|
||||
case GL_INT:
|
||||
case GL_UNSIGNED_INT:
|
||||
return GL_FALSE;
|
||||
case GL_DOUBLE:
|
||||
return GL_TRUE;
|
||||
default:
|
||||
assert(0);
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return default component values for the given format.
|
||||
* The return type is an array of fi_types, because that's how we declare
|
||||
|
@@ -159,27 +159,36 @@ static void vbo_exec_copy_to_current( struct vbo_exec_context *exec )
|
||||
* ctx->Current.Attrib and ctx->Light.Material.Attrib arrays.
|
||||
*/
|
||||
GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;
|
||||
fi_type tmp[4];
|
||||
fi_type tmp[8]; /* space for doubles */
|
||||
int dmul = exec->vtx.attrtype[i] == GL_DOUBLE ? 2 : 1;
|
||||
|
||||
if (exec->vtx.attrtype[i] == GL_DOUBLE) {
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
memcpy(tmp, exec->vtx.attrptr[i], exec->vtx.attrsz[i] * sizeof(GLfloat));
|
||||
} else {
|
||||
COPY_CLEAN_4V_TYPE_AS_UNION(tmp,
|
||||
exec->vtx.attrsz[i],
|
||||
exec->vtx.attrptr[i],
|
||||
exec->vtx.attrtype[i]);
|
||||
}
|
||||
|
||||
if (exec->vtx.attrtype[i] != vbo->currval[i].Type ||
|
||||
memcmp(current, tmp, sizeof(tmp)) != 0) {
|
||||
memcpy(current, tmp, sizeof(tmp));
|
||||
memcmp(current, tmp, 4 * sizeof(GLfloat) * dmul) != 0) {
|
||||
memcpy(current, tmp, 4 * sizeof(GLfloat) * dmul);
|
||||
|
||||
/* Given that we explicitly state size here, there is no need
|
||||
* for the COPY_CLEAN above, could just copy 16 bytes and be
|
||||
* done. The only problem is when Mesa accesses ctx->Current
|
||||
* directly.
|
||||
*/
|
||||
vbo->currval[i].Size = exec->vtx.attrsz[i];
|
||||
vbo->currval[i]._ElementSize = vbo->currval[i].Size * sizeof(GLfloat);
|
||||
/* 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_attrtype_to_integer_flag(exec->vtx.attrtype[i]);
|
||||
vbo->currval[i].Doubles =
|
||||
vbo_attrtype_to_double_flag(exec->vtx.attrtype[i]);
|
||||
|
||||
/* This triggers rather too much recalculation of Mesa state
|
||||
* that doesn't get used (eg light positions).
|
||||
@@ -214,6 +223,9 @@ vbo_exec_copy_from_current(struct vbo_exec_context *exec)
|
||||
GLint i;
|
||||
|
||||
for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) {
|
||||
if (exec->vtx.attrtype[i] == GL_DOUBLE) {
|
||||
memcpy(exec->vtx.attrptr[i], vbo->currval[i].Ptr, exec->vtx.attrsz[i] * sizeof(GLfloat));
|
||||
} else {
|
||||
const fi_type *current = (fi_type *) vbo->currval[i].Ptr;
|
||||
switch (exec->vtx.attrsz[i]) {
|
||||
case 4: exec->vtx.attrptr[i][3] = current[3];
|
||||
@@ -223,6 +235,7 @@ vbo_exec_copy_from_current(struct vbo_exec_context *exec)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -364,11 +377,11 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
|
||||
* glTexCoord4f() call. We promote the array from size=2 to size=4.
|
||||
*/
|
||||
static void
|
||||
vbo_exec_fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint newSize)
|
||||
vbo_exec_fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint newSize, GLenum newType)
|
||||
{
|
||||
struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
|
||||
|
||||
if (newSize > exec->vtx.attrsz[attr]) {
|
||||
if (newSize > exec->vtx.attrsz[attr] || newType != exec->vtx.attrtype[attr]) {
|
||||
/* New size is larger. Need to flush existing vertices and get
|
||||
* an enlarged vertex format.
|
||||
*/
|
||||
@@ -401,18 +414,19 @@ vbo_exec_fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint newSize)
|
||||
* This macro is used to implement all the glVertex, glColor, glTexCoord,
|
||||
* glVertexAttrib, etc functions.
|
||||
*/
|
||||
#define ATTR_UNION( A, N, T, V0, V1, V2, V3 ) \
|
||||
#define ATTR_UNION( A, N, T, C, V0, V1, V2, V3 ) \
|
||||
do { \
|
||||
struct vbo_exec_context *exec = &vbo_context(ctx)->exec; \
|
||||
\
|
||||
int sz = (sizeof(C) / sizeof(GLfloat)); \
|
||||
if (unlikely(!(ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT))) \
|
||||
ctx->Driver.BeginVertices( ctx ); \
|
||||
\
|
||||
if (unlikely(exec->vtx.active_sz[A] != N)) \
|
||||
vbo_exec_fixup_vertex(ctx, A, N); \
|
||||
if (unlikely(exec->vtx.active_sz[A] != N * sz) || \
|
||||
unlikely(exec->vtx.attrtype[A] != T)) \
|
||||
vbo_exec_fixup_vertex(ctx, A, N * sz, T); \
|
||||
\
|
||||
{ \
|
||||
fi_type *dest = exec->vtx.attrptr[A]; \
|
||||
C *dest = (C *)exec->vtx.attrptr[A]; \
|
||||
if (N>0) dest[0] = V0; \
|
||||
if (N>1) dest[1] = V1; \
|
||||
if (N>2) dest[2] = V2; \
|
||||
@@ -438,7 +452,6 @@ do { \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define ERROR(err) _mesa_error( ctx, err, __func__ )
|
||||
#define TAG(x) vbo_##x
|
||||
|
||||
@@ -575,7 +588,7 @@ static void GLAPIENTRY vbo_exec_EvalCoord1f( GLfloat u )
|
||||
for (i = 0; i <= VBO_ATTRIB_TEX7; i++) {
|
||||
if (exec->eval.map1[i].map)
|
||||
if (exec->vtx.active_sz[i] != exec->eval.map1[i].sz)
|
||||
vbo_exec_fixup_vertex( ctx, i, exec->eval.map1[i].sz );
|
||||
vbo_exec_fixup_vertex( ctx, i, exec->eval.map1[i].sz, GL_FLOAT );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -602,12 +615,12 @@ static void GLAPIENTRY vbo_exec_EvalCoord2f( GLfloat u, GLfloat v )
|
||||
for (i = 0; i <= VBO_ATTRIB_TEX7; i++) {
|
||||
if (exec->eval.map2[i].map)
|
||||
if (exec->vtx.active_sz[i] != exec->eval.map2[i].sz)
|
||||
vbo_exec_fixup_vertex( ctx, i, exec->eval.map2[i].sz );
|
||||
vbo_exec_fixup_vertex( ctx, i, exec->eval.map2[i].sz, GL_FLOAT );
|
||||
}
|
||||
|
||||
if (ctx->Eval.AutoNormal)
|
||||
if (exec->vtx.active_sz[VBO_ATTRIB_NORMAL] != 3)
|
||||
vbo_exec_fixup_vertex( ctx, VBO_ATTRIB_NORMAL, 3 );
|
||||
vbo_exec_fixup_vertex( ctx, VBO_ATTRIB_NORMAL, 3, GL_FLOAT );
|
||||
}
|
||||
|
||||
memcpy( exec->vtx.copied.buffer, exec->vtx.vertex,
|
||||
@@ -968,6 +981,16 @@ static void vbo_exec_vtxfmt_init( struct vbo_exec_context *exec )
|
||||
vfmt->VertexAttribP3uiv = vbo_VertexAttribP3uiv;
|
||||
vfmt->VertexAttribP4ui = vbo_VertexAttribP4ui;
|
||||
vfmt->VertexAttribP4uiv = vbo_VertexAttribP4uiv;
|
||||
|
||||
vfmt->VertexAttribL1d = vbo_VertexAttribL1d;
|
||||
vfmt->VertexAttribL2d = vbo_VertexAttribL2d;
|
||||
vfmt->VertexAttribL3d = vbo_VertexAttribL3d;
|
||||
vfmt->VertexAttribL4d = vbo_VertexAttribL4d;
|
||||
|
||||
vfmt->VertexAttribL1dv = vbo_VertexAttribL1dv;
|
||||
vfmt->VertexAttribL2dv = vbo_VertexAttribL2dv;
|
||||
vfmt->VertexAttribL3dv = vbo_VertexAttribL3dv;
|
||||
vfmt->VertexAttribL4dv = vbo_VertexAttribL4dv;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -772,7 +772,7 @@ _save_reset_vertex(struct gl_context *ctx)
|
||||
* 3f version won't otherwise set color[3] to 1.0 -- this is the job
|
||||
* of the chooser function when switching between Color4f and Color3f.
|
||||
*/
|
||||
#define ATTR_UNION(A, N, T, V0, V1, V2, V3) \
|
||||
#define ATTR_UNION(A, N, T, C, V0, V1, V2, V3) \
|
||||
do { \
|
||||
struct vbo_save_context *save = &vbo_context(ctx)->save; \
|
||||
\
|
||||
@@ -780,7 +780,7 @@ do { \
|
||||
save_fixup_vertex(ctx, A, N); \
|
||||
\
|
||||
{ \
|
||||
fi_type *dest = save->attrptr[A]; \
|
||||
C *dest = (C *)save->attrptr[A]; \
|
||||
if (N>0) dest[0] = V0; \
|
||||
if (N>1) dest[1] = V1; \
|
||||
if (N>2) dest[2] = V2; \
|
||||
@@ -1372,6 +1372,16 @@ _save_vtxfmt_init(struct gl_context *ctx)
|
||||
vfmt->VertexAttribP3uiv = _save_VertexAttribP3uiv;
|
||||
vfmt->VertexAttribP4uiv = _save_VertexAttribP4uiv;
|
||||
|
||||
vfmt->VertexAttribL1d = _save_VertexAttribL1d;
|
||||
vfmt->VertexAttribL2d = _save_VertexAttribL2d;
|
||||
vfmt->VertexAttribL3d = _save_VertexAttribL3d;
|
||||
vfmt->VertexAttribL4d = _save_VertexAttribL4d;
|
||||
|
||||
vfmt->VertexAttribL1dv = _save_VertexAttribL1dv;
|
||||
vfmt->VertexAttribL2dv = _save_VertexAttribL2dv;
|
||||
vfmt->VertexAttribL3dv = _save_VertexAttribL3dv;
|
||||
vfmt->VertexAttribL4dv = _save_VertexAttribL4dv;
|
||||
|
||||
/* This will all require us to fallback to saving the list as opcodes:
|
||||
*/
|
||||
vfmt->CallList = _save_CallList;
|
||||
|
@@ -533,6 +533,7 @@ replay_init( struct copy_context *copy )
|
||||
dst->Enabled = GL_TRUE;
|
||||
dst->Normalized = src->Normalized;
|
||||
dst->Integer = src->Integer;
|
||||
dst->Doubles = src->Doubles;
|
||||
dst->BufferObj = ctx->Shared->NullBufferObj;
|
||||
dst->_ElementSize = src->_ElementSize;
|
||||
|
||||
|
Reference in New Issue
Block a user