From c4254ee526145ce9bab227264226f5d6f741ff0e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 20 Feb 2015 11:41:01 +1000 Subject: 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 Reviewed-by: Ian Romanick Signed-off-by: Dave Airlie --- src/mesa/main/api_arrayelt.c | 79 ++++++++++++++++++++++++++++++++++++++++++-- src/mesa/main/api_loopback.c | 23 +++++++++++++ src/mesa/main/arrayobj.c | 1 + src/mesa/main/dd.h | 13 ++++++++ src/mesa/main/mtypes.h | 5 ++- src/mesa/main/varray.c | 64 +++++++++++++++++++++++++---------- src/mesa/main/varray.h | 1 + src/mesa/main/vtxfmt.c | 12 +++++++ 8 files changed, 178 insertions(+), 20 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/api_arrayelt.c b/src/mesa/main/api_arrayelt.c index ea015fd65bf..92d8238f431 100644 --- a/src/mesa/main/api_arrayelt.c +++ b/src/mesa/main/api_arrayelt.c @@ -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; diff --git a/src/mesa/main/api_loopback.c b/src/mesa/main/api_loopback.c index 9a597795c15..9932a837336 100644 --- a/src/mesa/main/api_loopback.c +++ b/src/mesa/main/api_loopback.c @@ -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); } } diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index 3c8ffb5a422..8147f6a3c7e 100644 --- a/src/mesa/main/arrayobj.c +++ b/src/mesa/main/arrayobj.c @@ -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; diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index a329d9c5340..d783e34222f 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -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; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index ad772e56f31..dddbba5a44d 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -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 */ }; diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index 69c70a870f7..d003c6dd840 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -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; diff --git a/src/mesa/main/varray.h b/src/mesa/main/varray.h index dd06fbf209c..c70545a2f5b 100644 --- a/src/mesa/main/varray.h +++ b/src/mesa/main/varray.h @@ -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); diff --git a/src/mesa/main/vtxfmt.c b/src/mesa/main/vtxfmt.c index fc0a01edf86..d7ef7e278cd 100644 --- a/src/mesa/main/vtxfmt.c +++ b/src/mesa/main/vtxfmt.c @@ -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); + } } -- cgit v1.2.3