From c4254ee526145ce9bab227264226f5d6f741ff0e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 20 Feb 2015 11:41:01 +1000 Subject: [PATCH] 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 ++++ src/mesa/vbo/vbo_attrib_tmp.h | 119 +++++++++++++++++++++++++++++++++- src/mesa/vbo/vbo_context.h | 17 +++++ src/mesa/vbo/vbo_exec_api.c | 83 +++++++++++++++--------- src/mesa/vbo/vbo_save_api.c | 14 +++- src/mesa/vbo/vbo_split_copy.c | 1 + 13 files changed, 377 insertions(+), 55 deletions(-) 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); + } } diff --git a/src/mesa/vbo/vbo_attrib_tmp.h b/src/mesa/vbo/vbo_attrib_tmp.h index 17e057836c3..e73b8fb5ff1 100644 --- a/src/mesa/vbo/vbo_attrib_tmp.h +++ b/src/mesa/vbo/vbo_attrib_tmp.h @@ -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 diff --git a/src/mesa/vbo/vbo_context.h b/src/mesa/vbo/vbo_context.h index 6099b56e661..a376efe34a7 100644 --- a/src/mesa/vbo/vbo_context.h +++ b/src/mesa/vbo/vbo_context.h @@ -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 diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c index 48680ec8899..138cd60513d 100644 --- a/src/mesa/vbo/vbo_exec_api.c +++ b/src/mesa/vbo/vbo_exec_api.c @@ -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]); + } - 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,13 +223,17 @@ vbo_exec_copy_from_current(struct vbo_exec_context *exec) GLint i; for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) { - const fi_type *current = (fi_type *) vbo->currval[i].Ptr; - switch (exec->vtx.attrsz[i]) { - case 4: exec->vtx.attrptr[i][3] = current[3]; - case 3: exec->vtx.attrptr[i][2] = current[2]; - case 2: exec->vtx.attrptr[i][1] = current[1]; - case 1: exec->vtx.attrptr[i][0] = current[0]; - break; + 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]; + case 3: exec->vtx.attrptr[i][2] = current[2]; + case 2: exec->vtx.attrptr[i][1] = current[1]; + case 1: exec->vtx.attrptr[i][0] = current[0]; + 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; } diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index 5927beeb33d..29de3d38aaa 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -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; diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c index d1107dd8419..7b1e20b18d2 100644 --- a/src/mesa/vbo/vbo_split_copy.c +++ b/src/mesa/vbo/vbo_split_copy.c @@ -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; -- 2.30.2