diff --git a/src/mapi/glapi/gen/EXT_direct_state_access.xml b/src/mapi/glapi/gen/EXT_direct_state_access.xml
index 4314973cc01..1a7ba6b2393 100644
--- a/src/mapi/glapi/gen/EXT_direct_state_access.xml
+++ b/src/mapi/glapi/gen/EXT_direct_state_access.xml
@@ -93,10 +93,12 @@
-
+
-
+
diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
index 7aab5c5d828..bd39ce3e20d 100644
--- a/src/mapi/glapi/gen/gl_API.xml
+++ b/src/mapi/glapi/gen/gl_API.xml
@@ -2402,11 +2402,13 @@
-
+
-
+
@@ -2910,7 +2912,8 @@
-
+
@@ -2935,11 +2938,13 @@
-
+
-
+
@@ -4292,7 +4297,8 @@
-
+
diff --git a/src/mesa/main/glthread.h b/src/mesa/main/glthread.h
index 177737f5be2..62367abbfad 100644
--- a/src/mesa/main/glthread.h
+++ b/src/mesa/main/glthread.h
@@ -124,6 +124,24 @@ struct glthread_client_attrib {
bool Valid;
};
+/* For glPushAttrib / glPopAttrib. */
+struct glthread_attrib_node {
+ GLbitfield Mask;
+ int ActiveTexture;
+ GLenum MatrixMode;
+};
+
+typedef enum {
+ M_MODELVIEW,
+ M_PROJECTION,
+ M_PROGRAM0,
+ M_PROGRAM_LAST = M_PROGRAM0 + MAX_PROGRAM_MATRICES - 1,
+ M_TEXTURE0,
+ M_TEXTURE_LAST = M_TEXTURE0 + MAX_TEXTURE_UNITS - 1,
+ M_DUMMY, /* used instead of reporting errors */
+ M_NUM_MATRIX_STACKS,
+} gl_matrix_index;
+
struct glthread_state
{
/** Multithreaded queue. */
@@ -191,6 +209,14 @@ struct glthread_state
* glDeleteProgram or -1 if there is no such enqueued call.
*/
int LastProgramChangeBatch;
+
+ /** Basic matrix state tracking. */
+ int ActiveTexture;
+ GLenum MatrixMode;
+ gl_matrix_index MatrixIndex;
+ struct glthread_attrib_node AttribStack[MAX_ATTRIB_STACK_DEPTH];
+ int AttribStackDepth;
+ int MatrixStackDepth[M_NUM_MATRIX_STACKS];
};
void _mesa_glthread_init(struct gl_context *ctx);
diff --git a/src/mesa/main/glthread_get.c b/src/mesa/main/glthread_get.c
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/src/mesa/main/glthread_marshal.h b/src/mesa/main/glthread_marshal.h
index 2680530a10f..0607dc4397a 100644
--- a/src/mesa/main/glthread_marshal.h
+++ b/src/mesa/main/glthread_marshal.h
@@ -405,4 +405,92 @@ _mesa_array_to_attrib(struct gl_context *ctx, GLenum array)
}
}
+static inline gl_matrix_index
+_mesa_get_matrix_index(struct gl_context *ctx, GLenum mode)
+{
+ if (mode == GL_MODELVIEW || mode == GL_PROJECTION)
+ return M_MODELVIEW + (mode - GL_MODELVIEW);
+
+ if (mode == GL_TEXTURE)
+ return M_TEXTURE0 + ctx->GLThread.ActiveTexture;
+
+ if (mode >= GL_TEXTURE0 && mode <= GL_TEXTURE0 + MAX_TEXTURE_UNITS - 1)
+ return M_TEXTURE0 + (mode - GL_TEXTURE0);
+
+ if (mode >= GL_MATRIX0_ARB && mode <= GL_MATRIX0_ARB + MAX_PROGRAM_MATRICES - 1)
+ return M_PROGRAM0 + (mode - GL_MATRIX0_ARB);
+
+ return M_DUMMY;
+}
+
+static inline void
+_mesa_glthread_PushAttrib(struct gl_context *ctx, GLbitfield mask)
+{
+ struct glthread_attrib_node *attr =
+ &ctx->GLThread.AttribStack[ctx->GLThread.AttribStackDepth++];
+
+ attr->Mask = mask;
+
+ if (mask & GL_TEXTURE_BIT)
+ attr->ActiveTexture = ctx->GLThread.ActiveTexture;
+
+ if (mask & GL_TRANSFORM_BIT)
+ attr->MatrixMode = ctx->GLThread.MatrixMode;
+}
+
+static inline void
+_mesa_glthread_PopAttrib(struct gl_context *ctx)
+{
+ struct glthread_attrib_node *attr =
+ &ctx->GLThread.AttribStack[--ctx->GLThread.AttribStackDepth];
+ unsigned mask = attr->Mask;
+
+ if (mask & GL_TEXTURE_BIT)
+ ctx->GLThread.ActiveTexture = attr->ActiveTexture;
+
+ if (mask & GL_TRANSFORM_BIT) {
+ ctx->GLThread.MatrixMode = attr->MatrixMode;
+ ctx->GLThread.MatrixIndex = _mesa_get_matrix_index(ctx, attr->MatrixMode);
+ }
+}
+
+static inline void
+_mesa_glthread_MatrixPushEXT(struct gl_context *ctx, GLenum matrixMode)
+{
+ ctx->GLThread.MatrixStackDepth[_mesa_get_matrix_index(ctx, matrixMode)]++;
+}
+
+static inline void
+_mesa_glthread_MatrixPopEXT(struct gl_context *ctx, GLenum matrixMode)
+{
+ ctx->GLThread.MatrixStackDepth[_mesa_get_matrix_index(ctx, matrixMode)]--;
+}
+
+static inline void
+_mesa_glthread_ActiveTexture(struct gl_context *ctx, GLenum texture)
+{
+ ctx->GLThread.ActiveTexture = texture - GL_TEXTURE0;
+ if (ctx->GLThread.MatrixMode == GL_TEXTURE)
+ ctx->GLThread.MatrixIndex = _mesa_get_matrix_index(ctx, texture);
+}
+
+static inline void
+_mesa_glthread_PushMatrix(struct gl_context *ctx)
+{
+ ctx->GLThread.MatrixStackDepth[ctx->GLThread.MatrixIndex]++;
+}
+
+static inline void
+_mesa_glthread_PopMatrix(struct gl_context *ctx)
+{
+ ctx->GLThread.MatrixStackDepth[ctx->GLThread.MatrixIndex]--;
+}
+
+static inline void
+_mesa_glthread_MatrixMode(struct gl_context *ctx, GLenum mode)
+{
+ ctx->GLThread.MatrixIndex = _mesa_get_matrix_index(ctx, mode);
+ ctx->GLThread.MatrixMode = mode;
+}
+
#endif /* MARSHAL_H */