From: Pierre-Eric Pelloux-Prayer Date: Tue, 7 May 2019 09:20:51 +0000 (+0200) Subject: mesa: EXT_dsa add selectorless matrix stack functions X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d2906293c432b1b0519612caed0c50f43044966a;p=mesa.git mesa: EXT_dsa add selectorless matrix stack functions Allows the legacy matrix stacks to be manipulated without disturbing the matrix mode selector. Adapted from a patch from Chris Forbes. Reviewed-by: Marek Olšák --- diff --git a/src/mapi/glapi/gen/EXT_direct_state_access.xml b/src/mapi/glapi/gen/EXT_direct_state_access.xml index dd33f928192..76196740b9e 100644 --- a/src/mapi/glapi/gen/EXT_direct_state_access.xml +++ b/src/mapi/glapi/gen/EXT_direct_state_access.xml @@ -16,6 +16,111 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index eb22fcbdb31..0b035aa7b1b 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -557,6 +557,18 @@ typedef enum /* NV_conservative_raster_pre_snap_triangles */ OPCODE_CONSERVATIVE_RASTER_PARAMETER_I, + /* EXT_direct_state_access */ + OPCODE_MATRIX_LOAD, + OPCODE_MATRIX_MULT, + OPCODE_MATRIX_ROTATE, + OPCODE_MATRIX_SCALE, + OPCODE_MATRIX_TRANSLATE, + OPCODE_MATRIX_LOAD_IDENTITY, + OPCODE_MATRIX_ORTHO, + OPCODE_MATRIX_FRUSTUM, + OPCODE_MATRIX_PUSH, + OPCODE_MATRIX_POP, + /* The following three are meta instructions */ OPCODE_ERROR, /* raise compiled-in error */ OPCODE_CONTINUE, @@ -9196,6 +9208,259 @@ save_ConservativeRasterParameteriNV(GLenum pname, GLint param) } } +/** GL_EXT_direct_state_access */ + +static void GLAPIENTRY +save_MatrixLoadfEXT(GLenum matrixMode, const GLfloat *m) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = alloc_instruction(ctx, OPCODE_MATRIX_LOAD, 17); + if (n) { + n[1].e = matrixMode; + for (unsigned i = 0; i < 16; i++) { + n[2 + i].f = m[i]; + } + } + if (ctx->ExecuteFlag) { + CALL_MatrixLoadfEXT(ctx->Exec, (matrixMode, m)); + } +} + +static void GLAPIENTRY +save_MatrixLoaddEXT(GLenum matrixMode, const GLdouble *m) +{ + GLfloat f[16]; + for (unsigned i = 0; i < 16; i++) { + f[i] = (GLfloat) m[i]; + } + save_MatrixLoadfEXT(matrixMode, f); +} + +static void GLAPIENTRY +save_MatrixMultfEXT(GLenum matrixMode, const GLfloat * m) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = alloc_instruction(ctx, OPCODE_MATRIX_MULT, 17); + if (n) { + n[1].e = matrixMode; + for (unsigned i = 0; i < 16; i++) { + n[2 + i].f = m[i]; + } + } + if (ctx->ExecuteFlag) { + CALL_MatrixMultfEXT(ctx->Exec, (matrixMode, m)); + } +} + +static void GLAPIENTRY +save_MatrixMultdEXT(GLenum matrixMode, const GLdouble * m) +{ + GLfloat f[16]; + for (unsigned i = 0; i < 16; i++) { + f[i] = (GLfloat) m[i]; + } + save_MatrixMultfEXT(matrixMode, f); +} + +static void GLAPIENTRY +save_MatrixRotatefEXT(GLenum matrixMode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = alloc_instruction(ctx, OPCODE_MATRIX_ROTATE, 5); + if (n) { + n[1].e = matrixMode; + n[2].f = angle; + n[3].f = x; + n[4].f = y; + n[5].f = z; + } + if (ctx->ExecuteFlag) { + CALL_MatrixRotatefEXT(ctx->Exec, (matrixMode, angle, x, y, z)); + } +} + +static void GLAPIENTRY +save_MatrixRotatedEXT(GLenum matrixMode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z) +{ + save_MatrixRotatefEXT(matrixMode, (GLfloat) angle, (GLfloat) x, (GLfloat) y, (GLfloat) z); +} + +static void GLAPIENTRY +save_MatrixScalefEXT(GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = alloc_instruction(ctx, OPCODE_MATRIX_SCALE, 4); + if (n) { + n[1].e = matrixMode; + n[2].f = x; + n[3].f = y; + n[4].f = z; + } + if (ctx->ExecuteFlag) { + CALL_MatrixScalefEXT(ctx->Exec, (matrixMode, x, y, z)); + } +} + +static void GLAPIENTRY +save_MatrixScaledEXT(GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z) +{ + save_MatrixScalefEXT(matrixMode, (GLfloat) x, (GLfloat) y, (GLfloat) z); +} + +static void GLAPIENTRY +save_MatrixTranslatefEXT(GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = alloc_instruction(ctx, OPCODE_MATRIX_TRANSLATE, 4); + if (n) { + n[1].e = matrixMode; + n[2].f = x; + n[3].f = y; + n[4].f = z; + } + if (ctx->ExecuteFlag) { + CALL_MatrixTranslatefEXT(ctx->Exec, (matrixMode, x, y, z)); + } +} + +static void GLAPIENTRY +save_MatrixTranslatedEXT(GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z) +{ + save_MatrixTranslatefEXT(matrixMode, (GLfloat) x, (GLfloat) y, (GLfloat) z); +} + +static void GLAPIENTRY +save_MatrixLoadIdentityEXT(GLenum matrixMode) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = alloc_instruction(ctx, OPCODE_MATRIX_LOAD_IDENTITY, 1); + if (n) { + n[1].e = matrixMode; + } + if (ctx->ExecuteFlag) { + CALL_MatrixLoadIdentityEXT(ctx->Exec, (matrixMode)); + } +} + +static void GLAPIENTRY +save_MatrixOrthoEXT(GLenum matrixMode, GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = alloc_instruction(ctx, OPCODE_MATRIX_ORTHO, 7); + if (n) { + n[1].e = matrixMode; + n[2].f = (GLfloat) left; + n[3].f = (GLfloat) right; + n[4].f = (GLfloat) bottom; + n[5].f = (GLfloat) top; + n[6].f = (GLfloat) nearval; + n[7].f = (GLfloat) farval; + } + if (ctx->ExecuteFlag) { + CALL_MatrixOrthoEXT(ctx->Exec, (matrixMode, left, right, bottom, top, nearval, farval)); + } +} + + +static void GLAPIENTRY +save_MatrixFrustumEXT(GLenum matrixMode, GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = alloc_instruction(ctx, OPCODE_MATRIX_FRUSTUM, 7); + if (n) { + n[1].e = matrixMode; + n[2].f = (GLfloat) left; + n[3].f = (GLfloat) right; + n[4].f = (GLfloat) bottom; + n[5].f = (GLfloat) top; + n[6].f = (GLfloat) nearval; + n[7].f = (GLfloat) farval; + } + if (ctx->ExecuteFlag) { + CALL_MatrixFrustumEXT(ctx->Exec, (matrixMode, left, right, bottom, top, nearval, farval)); + } +} + +static void GLAPIENTRY +save_MatrixPushEXT(GLenum matrixMode) +{ + GET_CURRENT_CONTEXT(ctx); + Node* n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = alloc_instruction(ctx, OPCODE_MATRIX_PUSH, 1); + if (n) { + n[1].e = matrixMode; + } + if (ctx->ExecuteFlag) { + CALL_MatrixPushEXT(ctx->Exec, (matrixMode)); + } +} + +static void GLAPIENTRY +save_MatrixPopEXT(GLenum matrixMode) +{ + GET_CURRENT_CONTEXT(ctx); + Node* n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = alloc_instruction(ctx, OPCODE_MATRIX_POP, 1); + if (n) { + n[1].e = matrixMode; + } + if (ctx->ExecuteFlag) { + CALL_MatrixPopEXT(ctx->Exec, (matrixMode)); + } +} + +static void GLAPIENTRY +save_MatrixLoadTransposefEXT(GLenum matrixMode, const GLfloat m[16]) +{ + GLfloat tm[16]; + _math_transposef(tm, m); + save_MatrixLoadfEXT(matrixMode, tm); +} + +static void GLAPIENTRY +save_MatrixLoadTransposedEXT(GLenum matrixMode, const GLdouble m[16]) +{ + GLfloat tm[16]; + _math_transposefd(tm, m); + save_MatrixLoadfEXT(matrixMode, tm); +} + +static void GLAPIENTRY +save_MatrixMultTransposefEXT(GLenum matrixMode, const GLfloat m[16]) +{ + GLfloat tm[16]; + _math_transposef(tm, m); + save_MatrixMultfEXT(matrixMode, tm); +} + +static void GLAPIENTRY +save_MatrixMultTransposedEXT(GLenum matrixMode, const GLdouble m[16]) +{ + GLfloat tm[16]; + _math_transposefd(tm, m); + save_MatrixMultfEXT(matrixMode, tm); +} + /** * Save an error-generating command into display list. @@ -10727,6 +10992,42 @@ execute_list(struct gl_context *ctx, GLuint list) CALL_ConservativeRasterParameteriNV(ctx->Exec, (n[1].e, n[2].i)); break; + /* GL_EXT_direct_state_access */ + case OPCODE_MATRIX_LOAD: + CALL_MatrixLoadfEXT(ctx->Exec, (n[1].e, &n[2].f)); + break; + case OPCODE_MATRIX_MULT: + CALL_MatrixMultfEXT(ctx->Exec, (n[1].e, &n[2].f)); + break; + case OPCODE_MATRIX_ROTATE: + CALL_MatrixRotatefEXT(ctx->Exec, (n[1].e, n[2].f, n[3].f, n[4].f, n[5].f)); + break; + case OPCODE_MATRIX_SCALE: + CALL_MatrixScalefEXT(ctx->Exec, (n[1].e, n[2].f, n[3].f, n[4].f)); + break; + case OPCODE_MATRIX_TRANSLATE: + CALL_MatrixTranslatefEXT(ctx->Exec, (n[1].e, n[2].f, n[3].f, n[4].f)); + break; + case OPCODE_MATRIX_LOAD_IDENTITY: + CALL_MatrixLoadIdentityEXT(ctx->Exec, (n[1].e)); + break; + case OPCODE_MATRIX_ORTHO: + CALL_MatrixOrthoEXT(ctx->Exec, (n[1].e, + n[2].f, n[3].f, n[4].f, + n[5].f, n[6].f, n[7].f)); + break; + case OPCODE_MATRIX_FRUSTUM: + CALL_MatrixFrustumEXT(ctx->Exec, (n[1].e, + n[2].f, n[3].f, n[4].f, + n[5].f, n[6].f, n[7].f)); + break; + case OPCODE_MATRIX_PUSH: + CALL_MatrixPushEXT(ctx->Exec, (n[1].e)); + break; + case OPCODE_MATRIX_POP: + CALL_MatrixPopEXT(ctx->Exec, (n[1].e)); + break; + case OPCODE_CONTINUE: n = (Node *) get_pointer(&n[1]); break; @@ -11697,6 +11998,27 @@ _mesa_initialize_save_table(const struct gl_context *ctx) /* GL_NV_conservative_raster_pre_snap_triangles */ SET_ConservativeRasterParameteriNV(table, save_ConservativeRasterParameteriNV); + + /* GL_EXT_direct_state_access */ + SET_MatrixLoadfEXT(table, save_MatrixLoadfEXT); + SET_MatrixLoaddEXT(table, save_MatrixLoaddEXT); + SET_MatrixMultfEXT(table, save_MatrixMultfEXT); + SET_MatrixMultdEXT(table, save_MatrixMultdEXT); + SET_MatrixRotatefEXT(table, save_MatrixRotatefEXT); + SET_MatrixRotatedEXT(table, save_MatrixRotatedEXT); + SET_MatrixScalefEXT(table, save_MatrixScalefEXT); + SET_MatrixScaledEXT(table, save_MatrixScaledEXT); + SET_MatrixTranslatefEXT(table, save_MatrixTranslatefEXT); + SET_MatrixTranslatedEXT(table, save_MatrixTranslatedEXT); + SET_MatrixLoadIdentityEXT(table, save_MatrixLoadIdentityEXT); + SET_MatrixOrthoEXT(table, save_MatrixOrthoEXT); + SET_MatrixFrustumEXT(table, save_MatrixFrustumEXT); + SET_MatrixPushEXT(table, save_MatrixPushEXT); + SET_MatrixPopEXT(table, save_MatrixPopEXT); + SET_MatrixLoadTransposefEXT(table, save_MatrixLoadTransposefEXT); + SET_MatrixLoadTransposedEXT(table, save_MatrixLoadTransposedEXT); + SET_MatrixMultTransposefEXT(table, save_MatrixMultTransposefEXT); + SET_MatrixMultTransposedEXT(table, save_MatrixMultTransposedEXT); } diff --git a/src/mesa/main/matrix.c b/src/mesa/main/matrix.c index 3b5159e1c7e..d9898aff628 100644 --- a/src/mesa/main/matrix.c +++ b/src/mesa/main/matrix.c @@ -47,7 +47,7 @@ static struct gl_matrix_stack * -get_named_matrix_stack(struct gl_context *ctx, GLenum mode) +get_named_matrix_stack(struct gl_context *ctx, GLenum mode, const char* caller) { switch (mode) { case GL_MODELVIEW: @@ -89,8 +89,39 @@ get_named_matrix_stack(struct gl_context *ctx, GLenum mode) } /* fallthrough */ default: - return NULL; + break; } + if (mode >= GL_TEXTURE0 && mode < (GL_TEXTURE0 + ctx->Const.MaxTextureCoordUnits)) { + return &ctx->TextureMatrixStack[mode - GL_TEXTURE0]; + } + _mesa_error(ctx, GL_INVALID_ENUM, caller); + return NULL; +} + + +static void matrix_frustum(struct gl_matrix_stack* stack, + GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble nearval, GLdouble farval, + const char* caller) +{ + GET_CURRENT_CONTEXT(ctx); + if (nearval <= 0.0 || + farval <= 0.0 || + nearval == farval || + left == right || + top == bottom) { + _mesa_error(ctx, GL_INVALID_VALUE, caller); + return; + } + + FLUSH_VERTICES(ctx, 0); + + _math_matrix_frustum(stack->Top, + (GLfloat) left, (GLfloat) right, + (GLfloat) bottom, (GLfloat) top, + (GLfloat) nearval, (GLfloat) farval); + ctx->NewState |= stack->DirtyFlag; } @@ -116,24 +147,62 @@ _mesa_Frustum( GLdouble left, GLdouble right, GLdouble nearval, GLdouble farval ) { GET_CURRENT_CONTEXT(ctx); + matrix_frustum(ctx->CurrentStack, + (GLfloat) left, (GLfloat) right, + (GLfloat) bottom, (GLfloat) top, + (GLfloat) nearval, (GLfloat) farval, + "glFrustum"); +} - FLUSH_VERTICES(ctx, 0); - if (nearval <= 0.0 || - farval <= 0.0 || - nearval == farval || - left == right || - top == bottom) +void GLAPIENTRY +_mesa_MatrixFrustumEXT( GLenum matrixMode, + GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble nearval, GLdouble farval ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_matrix_stack *stack = get_named_matrix_stack(ctx, matrixMode, + "glMatrixFrustumEXT"); + if (!stack) + return; + + matrix_frustum(stack, + (GLfloat) left, (GLfloat) right, + (GLfloat) bottom, (GLfloat) top, + (GLfloat) nearval, (GLfloat) farval, + "glMatrixFrustumEXT"); +} + + +static void +matrix_ortho(struct gl_matrix_stack* stack, + GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble nearval, GLdouble farval, + const char* caller) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "%s(%f, %f, %f, %f, %f, %f)\n", caller, + left, right, bottom, top, nearval, farval); + + if (left == right || + bottom == top || + nearval == farval) { - _mesa_error( ctx, GL_INVALID_VALUE, "glFrustum" ); + _mesa_error( ctx, GL_INVALID_VALUE, caller ); return; } - _math_matrix_frustum( ctx->CurrentStack->Top, - (GLfloat) left, (GLfloat) right, - (GLfloat) bottom, (GLfloat) top, - (GLfloat) nearval, (GLfloat) farval ); - ctx->NewState |= ctx->CurrentStack->DirtyFlag; + FLUSH_VERTICES(ctx, 0); + + _math_matrix_ortho( stack->Top, + (GLfloat) left, (GLfloat) right, + (GLfloat) bottom, (GLfloat) top, + (GLfloat) nearval, (GLfloat) farval ); + ctx->NewState |= stack->DirtyFlag; } @@ -159,26 +228,31 @@ _mesa_Ortho( GLdouble left, GLdouble right, GLdouble nearval, GLdouble farval ) { GET_CURRENT_CONTEXT(ctx); + matrix_ortho(ctx->CurrentStack, + (GLfloat) left, (GLfloat) right, + (GLfloat) bottom, (GLfloat) top, + (GLfloat) nearval, (GLfloat) farval, + "glOrtho"); +} - FLUSH_VERTICES(ctx, 0); - if (MESA_VERBOSE & VERBOSE_API) - _mesa_debug(ctx, "glOrtho(%f, %f, %f, %f, %f, %f)\n", - left, right, bottom, top, nearval, farval); - - if (left == right || - bottom == top || - nearval == farval) - { - _mesa_error( ctx, GL_INVALID_VALUE, "glOrtho" ); +void GLAPIENTRY +_mesa_MatrixOrthoEXT( GLenum matrixMode, + GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble nearval, GLdouble farval ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_matrix_stack *stack = get_named_matrix_stack(ctx, matrixMode, + "glMatrixOrthoEXT"); + if (!stack) return; - } - _math_matrix_ortho( ctx->CurrentStack->Top, - (GLfloat) left, (GLfloat) right, - (GLfloat) bottom, (GLfloat) top, - (GLfloat) nearval, (GLfloat) farval ); - ctx->NewState |= ctx->CurrentStack->DirtyFlag; + matrix_ortho(stack, + (GLfloat) left, (GLfloat) right, + (GLfloat) bottom, (GLfloat) top, + (GLfloat) nearval, (GLfloat) farval, + "glMatrixOrthoEXT"); } @@ -202,49 +276,34 @@ _mesa_MatrixMode( GLenum mode ) if (ctx->Transform.MatrixMode == mode && mode != GL_TEXTURE) return; - stack = get_named_matrix_stack(ctx, mode); + if (mode >= GL_TEXTURE0 && mode < (GL_TEXTURE0 + ctx->Const.MaxTextureCoordUnits)) { + stack = NULL; + } else { + stack = get_named_matrix_stack(ctx, mode, "glMatrixMode"); + } if (stack) { ctx->CurrentStack = stack; ctx->Transform.MatrixMode = mode; } - else { - _mesa_error( ctx, GL_INVALID_ENUM, "glMatrixMode(mode)" ); - } } -/** - * Push the current matrix stack. - * - * \sa glPushMatrix(). - * - * Verifies the current matrix stack is not full, and duplicates the top-most - * matrix in the stack. - * Marks __struct gl_contextRec::NewState with the stack dirty flag. - */ -void GLAPIENTRY -_mesa_PushMatrix( void ) +static void +push_matrix(struct gl_context *ctx, struct gl_matrix_stack *stack, + GLenum matrixMode, const char *func) { - GET_CURRENT_CONTEXT(ctx); - struct gl_matrix_stack *stack = ctx->CurrentStack; - - if (MESA_VERBOSE&VERBOSE_API) - _mesa_debug(ctx, "glPushMatrix %s\n", - _mesa_enum_to_string(ctx->Transform.MatrixMode)); - if (stack->Depth + 1 >= stack->MaxDepth) { if (ctx->Transform.MatrixMode == GL_TEXTURE) { - _mesa_error(ctx, GL_STACK_OVERFLOW, - "glPushMatrix(mode=GL_TEXTURE, unit=%d)", - ctx->Texture.CurrentUnit); - } - else { - _mesa_error(ctx, GL_STACK_OVERFLOW, "glPushMatrix(mode=%s)", - _mesa_enum_to_string(ctx->Transform.MatrixMode)); + _mesa_error(ctx, GL_STACK_OVERFLOW, "%s(mode=GL_TEXTURE, unit=%d)", + func, ctx->Texture.CurrentUnit); + } else { + _mesa_error(ctx, GL_STACK_OVERFLOW, "%s(mode=%s)", + func, _mesa_enum_to_string(matrixMode)); } return; } + if (stack->Depth + 1 >= stack->StackSize) { unsigned new_stack_size = stack->StackSize * 2; unsigned i; @@ -252,7 +311,7 @@ _mesa_PushMatrix( void ) sizeof(*new_stack) * new_stack_size); if (!new_stack) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushMatrix()"); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); return; } @@ -271,6 +330,54 @@ _mesa_PushMatrix( void ) } +/** + * Push the current matrix stack. + * + * \sa glPushMatrix(). + * + * Verifies the current matrix stack is not full, and duplicates the top-most + * matrix in the stack. + * Marks __struct gl_contextRec::NewState with the stack dirty flag. + */ +void GLAPIENTRY +_mesa_PushMatrix( void ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_matrix_stack *stack = ctx->CurrentStack; + + if (MESA_VERBOSE&VERBOSE_API) + _mesa_debug(ctx, "glPushMatrix %s\n", + _mesa_enum_to_string(ctx->Transform.MatrixMode)); + + push_matrix(ctx, stack, ctx->Transform.MatrixMode, "glPushMatrix"); +} + + +void GLAPIENTRY +_mesa_MatrixPushEXT( GLenum matrixMode ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_matrix_stack *stack = get_named_matrix_stack(ctx, matrixMode, + "glMatrixPushEXT"); + ASSERT_OUTSIDE_BEGIN_END(ctx); + if (stack) + push_matrix(ctx, stack, matrixMode, "glMatrixPushEXT"); +} + + +static GLboolean +pop_matrix( struct gl_context *ctx, struct gl_matrix_stack *stack ) +{ + if (stack->Depth == 0) + return GL_FALSE; + + stack->Depth--; + stack->Top = &(stack->Stack[stack->Depth]); + ctx->NewState |= stack->DirtyFlag; + return GL_TRUE; +} + + /** * Pop the current matrix stack. * @@ -292,24 +399,53 @@ _mesa_PopMatrix( void ) _mesa_debug(ctx, "glPopMatrix %s\n", _mesa_enum_to_string(ctx->Transform.MatrixMode)); - if (stack->Depth == 0) { + if (!pop_matrix(ctx, stack)) { if (ctx->Transform.MatrixMode == GL_TEXTURE) { - _mesa_error(ctx, GL_STACK_UNDERFLOW, + _mesa_error(ctx, GL_STACK_UNDERFLOW, "glPopMatrix(mode=GL_TEXTURE, unit=%d)", ctx->Texture.CurrentUnit); } else { - _mesa_error(ctx, GL_STACK_UNDERFLOW, "glPopMatrix(mode=%s)", + _mesa_error(ctx, GL_STACK_UNDERFLOW, "glPopMatrix(mode=%s)", _mesa_enum_to_string(ctx->Transform.MatrixMode)); } + } +} + + +void GLAPIENTRY +_mesa_MatrixPopEXT( GLenum matrixMode ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_matrix_stack *stack = get_named_matrix_stack(ctx, matrixMode, + "glMatrixPopEXT"); + if (!stack) return; + + if (!pop_matrix(ctx, stack)) { + if (matrixMode == GL_TEXTURE) { + _mesa_error(ctx, GL_STACK_UNDERFLOW, + "glMatrixPopEXT(mode=GL_TEXTURE, unit=%d)", + ctx->Texture.CurrentUnit); + } + else { + _mesa_error(ctx, GL_STACK_UNDERFLOW, "glMatrixPopEXT(mode=%s)", + _mesa_enum_to_string(matrixMode)); + } } - stack->Depth--; - stack->Top = &(stack->Stack[stack->Depth]); - ctx->NewState |= stack->DirtyFlag; } +static void +matrix_load_identity(struct gl_matrix_stack* stack) +{ + GET_CURRENT_CONTEXT(ctx); + + FLUSH_VERTICES(ctx, 0); + + _math_matrix_set_identity(stack->Top); + ctx->NewState |= stack->DirtyFlag; +} /** * Replace the current matrix with the identity matrix. * @@ -324,13 +460,45 @@ _mesa_LoadIdentity( void ) { GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0); - if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glLoadIdentity()\n"); - _math_matrix_set_identity( ctx->CurrentStack->Top ); - ctx->NewState |= ctx->CurrentStack->DirtyFlag; + matrix_load_identity(ctx->CurrentStack); +} + + +void GLAPIENTRY +_mesa_MatrixLoadIdentityEXT( GLenum matrixMode ) +{ + struct gl_matrix_stack *stack; + GET_CURRENT_CONTEXT(ctx); + stack = get_named_matrix_stack(ctx, matrixMode, "glMatrixLoadIdentityEXT"); + if (!stack) + return; + + matrix_load_identity(stack); +} + + +static void +matrix_load(struct gl_matrix_stack *stack, const GLfloat *m, const char* caller) +{ + GET_CURRENT_CONTEXT(ctx); + if (!m) return; + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, + "%s(%f %f %f %f, %f %f %f %f, %f %f %f %f, %f %f %f %f\n", + caller, + m[0], m[4], m[8], m[12], + m[1], m[5], m[9], m[13], + m[2], m[6], m[10], m[14], + m[3], m[7], m[11], m[15]); + + if (memcmp(m, stack->Top->m, 16 * sizeof(GLfloat)) != 0) { + FLUSH_VERTICES(ctx, 0); + _math_matrix_loadf( stack->Top, m ); + ctx->NewState |= stack->DirtyFlag; + } } @@ -347,22 +515,50 @@ _mesa_LoadIdentity( void ) */ void GLAPIENTRY _mesa_LoadMatrixf( const GLfloat *m ) +{ + GET_CURRENT_CONTEXT(ctx); + matrix_load(ctx->CurrentStack, m, "glLoadMatrix"); +} + + +/** + * Replace the named matrix with a given matrix. + * + * \param matrixMode matrix to replace + * \param m matrix + * + * \sa glLoadMatrixf(). + */ +void GLAPIENTRY +_mesa_MatrixLoadfEXT( GLenum matrixMode, const GLfloat *m ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_matrix_stack * stack = + get_named_matrix_stack(ctx, matrixMode, "glMatrixLoadfEXT"); + if (!stack) + return; + + matrix_load(stack, m, "glMatrixLoadfEXT"); +} + + +static void +matrix_mult(struct gl_matrix_stack *stack, const GLfloat *m, const char* caller) { GET_CURRENT_CONTEXT(ctx); if (!m) return; if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, - "glLoadMatrix(%f %f %f %f, %f %f %f %f, %f %f %f %f, %f %f %f %f\n", + "%s(%f %f %f %f, %f %f %f %f, %f %f %f %f, %f %f %f %f\n", + caller, m[0], m[4], m[8], m[12], m[1], m[5], m[9], m[13], m[2], m[6], m[10], m[14], m[3], m[7], m[11], m[15]); - if (memcmp(m, ctx->CurrentStack->Top->m, 16 * sizeof(GLfloat)) != 0) { - FLUSH_VERTICES(ctx, 0); - _math_matrix_loadf( ctx->CurrentStack->Top, m ); - ctx->NewState |= ctx->CurrentStack->DirtyFlag; - } + FLUSH_VERTICES(ctx, 0); + _math_matrix_mul_floats(stack->Top, m); + ctx->NewState |= stack->DirtyFlag; } @@ -381,18 +577,34 @@ void GLAPIENTRY _mesa_MultMatrixf( const GLfloat *m ) { GET_CURRENT_CONTEXT(ctx); - if (!m) return; - if (MESA_VERBOSE & VERBOSE_API) - _mesa_debug(ctx, - "glMultMatrix(%f %f %f %f, %f %f %f %f, %f %f %f %f, %f %f %f %f\n", - m[0], m[4], m[8], m[12], - m[1], m[5], m[9], m[13], - m[2], m[6], m[10], m[14], - m[3], m[7], m[11], m[15]); + matrix_mult(ctx->CurrentStack, m, "glMultMatrix"); +} + + +void GLAPIENTRY +_mesa_MatrixMultfEXT( GLenum matrixMode, const GLfloat *m ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_matrix_stack * stack = + get_named_matrix_stack(ctx, matrixMode, "glMatrixMultfEXT"); + if (!stack) + return; + + matrix_mult(stack, m, "glMultMatrix"); +} + + +static void +matrix_rotate(struct gl_matrix_stack *stack, GLfloat angle, + GLfloat x, GLfloat y, GLfloat z, const char* caller) +{ + GET_CURRENT_CONTEXT(ctx); FLUSH_VERTICES(ctx, 0); - _math_matrix_mul_floats( ctx->CurrentStack->Top, m ); - ctx->NewState |= ctx->CurrentStack->DirtyFlag; + if (angle != 0.0F) { + _math_matrix_rotate(stack->Top, angle, x, y, z); + ctx->NewState |=stack->DirtyFlag; + } } @@ -414,12 +626,20 @@ void GLAPIENTRY _mesa_Rotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z ) { GET_CURRENT_CONTEXT(ctx); + matrix_rotate(ctx->CurrentStack, angle, x, y, z, "glRotatef"); +} - FLUSH_VERTICES(ctx, 0); - if (angle != 0.0F) { - _math_matrix_rotate( ctx->CurrentStack->Top, angle, x, y, z); - ctx->NewState |= ctx->CurrentStack->DirtyFlag; - } + +void GLAPIENTRY +_mesa_MatrixRotatefEXT( GLenum matrixMode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_matrix_stack *stack = + get_named_matrix_stack(ctx, matrixMode, "glMatrixRotatefEXT"); + if (!stack) + return; + + matrix_rotate(stack, angle, x, y, z, "glMatrixRotatefEXT"); } @@ -447,6 +667,22 @@ _mesa_Scalef( GLfloat x, GLfloat y, GLfloat z ) } +void GLAPIENTRY +_mesa_MatrixScalefEXT( GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z ) +{ + struct gl_matrix_stack *stack; + GET_CURRENT_CONTEXT(ctx); + + stack = get_named_matrix_stack(ctx, matrixMode, "glMatrixScalefEXT"); + if (!stack) + return; + + FLUSH_VERTICES(ctx, 0); + _math_matrix_scale(stack->Top, x, y, z); + ctx->NewState |= stack->DirtyFlag; +} + + /** * Multiply the current matrix with a translation matrix. * @@ -470,7 +706,22 @@ _mesa_Translatef( GLfloat x, GLfloat y, GLfloat z ) ctx->NewState |= ctx->CurrentStack->DirtyFlag; } - + +void GLAPIENTRY +_mesa_MatrixTranslatefEXT( GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_matrix_stack *stack = + get_named_matrix_stack(ctx, matrixMode, "glMatrixTranslatefEXT"); + if (!stack) + return; + + FLUSH_VERTICES(ctx, 0); + _math_matrix_translate(stack->Top, x, y, z); + ctx->NewState |= stack->DirtyFlag; +} + + void GLAPIENTRY _mesa_LoadMatrixd( const GLdouble *m ) { @@ -482,6 +733,18 @@ _mesa_LoadMatrixd( const GLdouble *m ) _mesa_LoadMatrixf(f); } + +void GLAPIENTRY +_mesa_MatrixLoaddEXT( GLenum matrixMode, const GLdouble *m ) +{ + GLfloat f[16]; + if (!m) return; + for (unsigned i = 0; i < 16; i++) + f[i] = (GLfloat) m[i]; + _mesa_MatrixLoadfEXT(matrixMode, f); +} + + void GLAPIENTRY _mesa_MultMatrixd( const GLdouble *m ) { @@ -494,6 +757,17 @@ _mesa_MultMatrixd( const GLdouble *m ) } +void GLAPIENTRY +_mesa_MatrixMultdEXT( GLenum matrixMode, const GLdouble *m ) +{ + GLfloat f[16]; + if (!m) return; + for (unsigned i = 0; i < 16; i++) + f[i] = (GLfloat) m[i]; + _mesa_MatrixMultfEXT(matrixMode, f); +} + + void GLAPIENTRY _mesa_Rotated( GLdouble angle, GLdouble x, GLdouble y, GLdouble z ) { @@ -501,6 +775,15 @@ _mesa_Rotated( GLdouble angle, GLdouble x, GLdouble y, GLdouble z ) } +void GLAPIENTRY +_mesa_MatrixRotatedEXT( GLenum matrixMode, GLdouble angle, + GLdouble x, GLdouble y, GLdouble z ) +{ + _mesa_MatrixRotatefEXT(matrixMode, (GLfloat) angle, + (GLfloat) x, (GLfloat) y, (GLfloat) z); +} + + void GLAPIENTRY _mesa_Scaled( GLdouble x, GLdouble y, GLdouble z ) { @@ -508,6 +791,13 @@ _mesa_Scaled( GLdouble x, GLdouble y, GLdouble z ) } +void GLAPIENTRY +_mesa_MatrixScaledEXT( GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z ) +{ + _mesa_MatrixScalefEXT(matrixMode, (GLfloat) x, (GLfloat) y, (GLfloat) z); +} + + void GLAPIENTRY _mesa_Translated( GLdouble x, GLdouble y, GLdouble z ) { @@ -515,6 +805,13 @@ _mesa_Translated( GLdouble x, GLdouble y, GLdouble z ) } +void GLAPIENTRY +_mesa_MatrixTranslatedEXT( GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z ) +{ + _mesa_MatrixTranslatefEXT(matrixMode, (GLfloat) x, (GLfloat) y, (GLfloat) z); +} + + void GLAPIENTRY _mesa_LoadTransposeMatrixf( const GLfloat *m ) { @@ -524,6 +821,14 @@ _mesa_LoadTransposeMatrixf( const GLfloat *m ) _mesa_LoadMatrixf(tm); } +void GLAPIENTRY +_mesa_MatrixLoadTransposefEXT( GLenum matrixMode, const GLfloat *m ) +{ + GLfloat tm[16]; + if (!m) return; + _math_transposef(tm, m); + _mesa_MatrixLoadfEXT(matrixMode, tm); +} void GLAPIENTRY _mesa_LoadTransposeMatrixd( const GLdouble *m ) @@ -534,6 +839,14 @@ _mesa_LoadTransposeMatrixd( const GLdouble *m ) _mesa_LoadMatrixf(tm); } +void GLAPIENTRY +_mesa_MatrixLoadTransposedEXT( GLenum matrixMode, const GLdouble *m ) +{ + GLfloat tm[16]; + if (!m) return; + _math_transposefd(tm, m); + _mesa_MatrixLoadfEXT(matrixMode, tm); +} void GLAPIENTRY _mesa_MultTransposeMatrixf( const GLfloat *m ) @@ -544,6 +857,14 @@ _mesa_MultTransposeMatrixf( const GLfloat *m ) _mesa_MultMatrixf(tm); } +void GLAPIENTRY +_mesa_MatrixMultTransposefEXT( GLenum matrixMode, const GLfloat *m ) +{ + GLfloat tm[16]; + if (!m) return; + _math_transposef(tm, m); + _mesa_MatrixMultfEXT(matrixMode, tm); +} void GLAPIENTRY _mesa_MultTransposeMatrixd( const GLdouble *m ) @@ -554,7 +875,14 @@ _mesa_MultTransposeMatrixd( const GLdouble *m ) _mesa_MultMatrixf(tm); } - +void GLAPIENTRY +_mesa_MatrixMultTransposedEXT( GLenum matrixMode, const GLdouble *m ) +{ + GLfloat tm[16]; + if (!m) return; + _math_transposefd(tm, m); + _mesa_MatrixMultfEXT(matrixMode, tm); +} /**********************************************************************/ /** \name State management */ diff --git a/src/mesa/main/matrix.h b/src/mesa/main/matrix.h index 8eee67ca386..f9904ac8b46 100644 --- a/src/mesa/main/matrix.h +++ b/src/mesa/main/matrix.h @@ -96,6 +96,64 @@ _mesa_MultTransposeMatrixf( const GLfloat *m ); extern void GLAPIENTRY _mesa_MultTransposeMatrixd( const GLdouble *m ); +extern void GLAPIENTRY +_mesa_MatrixLoadfEXT( GLenum matrixMode, const GLfloat *m ); + +extern void GLAPIENTRY +_mesa_MatrixLoaddEXT( GLenum matrixMode, const GLdouble *m ); + +extern void GLAPIENTRY +_mesa_MatrixMultfEXT( GLenum matrixMode, const GLfloat *m ); + +extern void GLAPIENTRY +_mesa_MatrixMultdEXT( GLenum matrixMode, const GLdouble *m ); + +extern void GLAPIENTRY +_mesa_MatrixLoadIdentityEXT( GLenum matrixMode ); + +extern void GLAPIENTRY +_mesa_MatrixRotatefEXT( GLenum matrixMode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z ); + +extern void GLAPIENTRY +_mesa_MatrixRotatedEXT( GLenum matrixMode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z ); + +extern void GLAPIENTRY +_mesa_MatrixScalefEXT( GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z ); + +extern void GLAPIENTRY +_mesa_MatrixScaledEXT( GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z ); + +extern void GLAPIENTRY +_mesa_MatrixTranslatefEXT( GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z ); + +extern void GLAPIENTRY +_mesa_MatrixTranslatedEXT( GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z ); + +extern void GLAPIENTRY +_mesa_MatrixOrthoEXT( GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, + GLdouble n, GLdouble f ); + +extern void GLAPIENTRY +_mesa_MatrixFrustumEXT( GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, + GLdouble n, GLdouble f ); + +extern void GLAPIENTRY +_mesa_MatrixPushEXT( GLenum matrixMode ); + +extern void GLAPIENTRY +_mesa_MatrixPopEXT( GLenum matrixMode ); + +extern void GLAPIENTRY +_mesa_MatrixLoadTransposefEXT( GLenum matrixMode, const GLfloat* m ); + +extern void GLAPIENTRY +_mesa_MatrixLoadTransposedEXT( GLenum matrixMode, const GLdouble* m ); + +extern void GLAPIENTRY +_mesa_MatrixMultTransposefEXT( GLenum matrixMode, const GLfloat* m ); + +extern void GLAPIENTRY +_mesa_MatrixMultTransposedEXT( GLenum matrixMode, const GLdouble* m ); extern void _mesa_init_matrix( struct gl_context * ctx ); diff --git a/src/mesa/main/tests/dispatch_sanity.cpp b/src/mesa/main/tests/dispatch_sanity.cpp index d1618e7fde6..b171e1768b0 100644 --- a/src/mesa/main/tests/dispatch_sanity.cpp +++ b/src/mesa/main/tests/dispatch_sanity.cpp @@ -1016,21 +1016,21 @@ const struct function common_desktop_functions_possible[] = { { "glGetQueryBufferObjectui64v", 45, -1 }, /* GL_EXT_direct_state_access - GL 1.0 */ - //{ "glMatrixLoadfEXT", 10, -1 }, - //{ "glMatrixLoaddEXT", 10, -1 }, - //{ "glMatrixMultfEXT", 10, -1 }, - //{ "glMatrixMultdEXT", 10, -1 }, - //{ "glMatrixLoadIdentityEXT", 10, -1 }, - //{ "glMatrixRotatefEXT", 10, -1 }, - //{ "glMatrixRotatedEXT", 10, -1 }, - //{ "glMatrixScalefEXT", 10, -1 }, - //{ "glMatrixScaledEXT", 10, -1 }, - //{ "glMatrixTranslatefEXT", 10, -1 }, - //{ "glMatrixTranslatedEXT", 10, -1 }, - //{ "glMatrixOrthoEXT", 10, -1 }, - //{ "glMatrixFrustumEXT", 10, -1 }, - //{ "glMatrixPushEXT", 10, -1 }, - //{ "glMatrixPopEXT", 10, -1 }, + { "glMatrixLoadfEXT", 10, -1 }, + { "glMatrixLoaddEXT", 10, -1 }, + { "glMatrixMultfEXT", 10, -1 }, + { "glMatrixMultdEXT", 10, -1 }, + { "glMatrixLoadIdentityEXT", 10, -1 }, + { "glMatrixRotatefEXT", 10, -1 }, + { "glMatrixRotatedEXT", 10, -1 }, + { "glMatrixScalefEXT", 10, -1 }, + { "glMatrixScaledEXT", 10, -1 }, + { "glMatrixTranslatefEXT", 10, -1 }, + { "glMatrixTranslatedEXT", 10, -1 }, + { "glMatrixOrthoEXT", 10, -1 }, + { "glMatrixFrustumEXT", 10, -1 }, + { "glMatrixPushEXT", 10, -1 }, + { "glMatrixPopEXT", 10, -1 }, /* GL_EXT_direct_state_access - GL 1.1 */ //{ "glClientAttribDefaultEXT", 11, -1 }, //{ "glPushClientAttribDefaultEXT", 11, -1 }, @@ -1121,10 +1121,10 @@ const struct function common_desktop_functions_possible[] = { //{ "glCompressedMultiTexSubImage2DEXT", 13, -1 }, //{ "glCompressedMultiTexSubImage3DEXT", 13, -1 }, //{ "glGetCompressedMultiTexImageEXT", 13, -1 }, - //{ "glMatrixLoadTransposefEXT", 13, -1 }, - //{ "glMatrixLoadTransposedEXT", 13, -1 }, - //{ "glMatrixMultTransposefEXT", 13, -1 }, - //{ "glMatrixMultTransposedEXT", 13, -1 }, + { "glMatrixLoadTransposefEXT", 13, -1 }, + { "glMatrixLoadTransposedEXT", 13, -1 }, + { "glMatrixMultTransposefEXT", 13, -1 }, + { "glMatrixMultTransposedEXT", 13, -1 }, /* GL_EXT_direct_state_access - GL 1.5 */ //{ "glNamedBufferDataEXT", 15, -1 }, //{ "glNamedBufferSubDataEXT", 15, -1 },