Added functions to query the register files.
authorRyan C. Gordon <icculus@icculus.org>
Wed, 01 Jun 2011 01:16:12 -0400
changeset 1040 053626102255
parent 1039 2f758145e80e
child 1041 200cde29af83
Added functions to query the register files.
mojoshader.h
mojoshader_opengl.c
--- a/mojoshader.h	Tue May 31 16:25:37 2011 -0400
+++ b/mojoshader.h	Wed Jun 01 01:16:12 2011 -0400
@@ -2714,6 +2714,37 @@
                                           unsigned int vec4count);
 
 /*
+ * Retrieve a floating-point uniform value (what Direct3D calls a "constant").
+ *
+ * There is a single array of 4-float "registers" shared by all vertex shaders.
+ *  This is the "c" register file in Direct3D (c0, c1, c2, etc...)
+ *  MojoShader will take care of synchronizing this internal array with the
+ *  appropriate variables in the GL shaders.
+ *
+ * (idx) is the index into the internal array: 0 is the first four floats,
+ *  1 is the next four, etc.
+ * (data) is a pointer to space for (vec4count*4) floats.
+ *  (data) will be filled will current values in the register file. Results
+ *  are undefined if you request data past the end of the register file or
+ *  previously uninitialized registers.
+ *
+ * This is a "fast" call; we're just reading memory from internal memory. We
+ *  do not query the GPU or the GL for this information.
+ *
+ * This call is NOT thread safe! As most OpenGL implementations are not thread
+ *  safe, you should probably only call this from the same thread that created
+ *  the GL context.
+ *
+ * This call requires a valid MOJOSHADER_glContext to have been made current,
+ *  or it will crash your program. See MOJOSHADER_glMakeContextCurrent().
+ *
+ * Uniforms are not shared between contexts.
+ */
+void MOJOSHADER_glGetVertexShaderUniformF(unsigned int idx, float *data,
+                                          unsigned int vec4count);
+
+
+/*
  * Set an integer uniform value (what Direct3D calls a "constant").
  *
  * There is a single array of 4-int "registers" shared by all vertex shaders.
@@ -2738,6 +2769,36 @@
                                           unsigned int ivec4count);
 
 /*
+ * Retrieve an integer uniform value (what Direct3D calls a "constant").
+ *
+ * There is a single array of 4-int "registers" shared by all vertex shaders.
+ *  This is the "i" register file in Direct3D (i0, i1, i2, etc...)
+ *  MojoShader will take care of synchronizing this internal array with the
+ *  appropriate variables in the GL shaders.
+ *
+ * (idx) is the index into the internal array: 0 is the first four ints,
+ *  1 is the next four, etc.
+ * (data) is a pointer to space for (ivec4count*4) ints.
+ *  (data) will be filled will current values in the register file. Results
+ *  are undefined if you request data past the end of the register file or
+ *  previously uninitialized registers.
+ *
+ * This is a "fast" call; we're just reading memory from internal memory. We
+ *  do not query the GPU or the GL for this information.
+ *
+ * This call is NOT thread safe! As most OpenGL implementations are not thread
+ *  safe, you should probably only call this from the same thread that created
+ *  the GL context.
+ *
+ * This call requires a valid MOJOSHADER_glContext to have been made current,
+ *  or it will crash your program. See MOJOSHADER_glMakeContextCurrent().
+ *
+ * Uniforms are not shared between contexts.
+ */
+void MOJOSHADER_glGetVertexShaderUniformI(unsigned int idx, int *data,
+                                          unsigned int ivec4count);
+
+/*
  * Set a boolean uniform value (what Direct3D calls a "constant").
  *
  * There is a single array of "registers" shared by all vertex shaders.
@@ -2767,6 +2828,43 @@
                                           unsigned int bcount);
 
 /*
+ * Retrieve a boolean uniform value (what Direct3D calls a "constant").
+ *
+ * There is a single array of "registers" shared by all vertex shaders.
+ *  This is the "b" register file in Direct3D (b0, b1, b2, etc...)
+ *  MojoShader will take care of synchronizing this internal array with the
+ *  appropriate variables in the GL shaders.
+ *
+ * Unlike the float and int counterparts, booleans are single values, not
+ *  four-element vectors...so idx==1 is the second boolean in the internal
+ *  array, not the fifth.
+ *
+ * Non-zero values are considered "true" and zero is considered "false".
+ *  This function will always return true values as 1, regardless of what
+ *  non-zero integer you originally used to set the registers.
+ *
+ * (idx) is the index into the internal array.
+ * (data) is a pointer to space for (bcount) ints.
+ *  (data) will be filled will current values in the register file. Results
+ *  are undefined if you request data past the end of the register file or
+ *  previously uninitialized registers.
+ *
+ * This is a "fast" call; we're just reading memory from internal memory. We
+ *  do not query the GPU or the GL for this information.
+ *
+ * This call is NOT thread safe! As most OpenGL implementations are not thread
+ *  safe, you should probably only call this from the same thread that created
+ *  the GL context.
+ *
+ * This call requires a valid MOJOSHADER_glContext to have been made current,
+ *  or it will crash your program. See MOJOSHADER_glMakeContextCurrent().
+ *
+ * Uniforms are not shared between contexts.
+ */
+void MOJOSHADER_glGetVertexShaderUniformB(unsigned int idx, int *data,
+                                          unsigned int bcount);
+
+/*
  * The equivalent of MOJOSHADER_glSetVertexShaderUniformF() for pixel
  *  shaders. Other than using a different internal array that is specific
  *  to pixel shaders, this functions just like its vertex array equivalent.
@@ -2783,6 +2881,25 @@
 void MOJOSHADER_glSetPixelShaderUniformF(unsigned int idx, const float *data,
                                          unsigned int vec4count);
 
+
+/*
+ * The equivalent of MOJOSHADER_glGetVertexShaderUniformF() for pixel
+ *  shaders. Other than using a different internal array that is specific
+ *  to pixel shaders, this functions just like its vertex array equivalent.
+ *
+ * This call is NOT thread safe! As most OpenGL implementations are not thread
+ *  safe, you should probably only call this from the same thread that created
+ *  the GL context.
+ *
+ * This call requires a valid MOJOSHADER_glContext to have been made current,
+ *  or it will crash your program. See MOJOSHADER_glMakeContextCurrent().
+ *
+ * Uniforms are not shared between contexts.
+ */
+void MOJOSHADER_glGetPixelShaderUniformF(unsigned int idx, float *data,
+                                         unsigned int vec4count);
+
+
 /*
  * The equivalent of MOJOSHADER_glSetVertexShaderUniformI() for pixel
  *  shaders. Other than using a different internal array that is specific
@@ -2800,6 +2917,24 @@
 void MOJOSHADER_glSetPixelShaderUniformI(unsigned int idx, const int *data,
                                          unsigned int ivec4count);
 
+
+/*
+ * The equivalent of MOJOSHADER_glGetVertexShaderUniformI() for pixel
+ *  shaders. Other than using a different internal array that is specific
+ *  to pixel shaders, this functions just like its vertex array equivalent.
+ *
+ * This call is NOT thread safe! As most OpenGL implementations are not thread
+ *  safe, you should probably only call this from the same thread that created
+ *  the GL context.
+ *
+ * This call requires a valid MOJOSHADER_glContext to have been made current,
+ *  or it will crash your program. See MOJOSHADER_glMakeContextCurrent().
+ *
+ * Uniforms are not shared between contexts.
+ */
+void MOJOSHADER_glGetPixelShaderUniformI(unsigned int idx, int *data,
+                                         unsigned int ivec4count);
+
 /*
  * The equivalent of MOJOSHADER_glSetVertexShaderUniformB() for pixel
  *  shaders. Other than using a different internal array that is specific
@@ -2818,6 +2953,23 @@
                                          unsigned int bcount);
 
 /*
+ * The equivalent of MOJOSHADER_glGetVertexShaderUniformB() for pixel
+ *  shaders. Other than using a different internal array that is specific
+ *  to pixel shaders, this functions just like its vertex array equivalent.
+ *
+ * This call is NOT thread safe! As most OpenGL implementations are not thread
+ *  safe, you should probably only call this from the same thread that created
+ *  the GL context.
+ *
+ * This call requires a valid MOJOSHADER_glContext to have been made current,
+ *  or it will crash your program. See MOJOSHADER_glMakeContextCurrent().
+ *
+ * Uniforms are not shared between contexts.
+ */
+void MOJOSHADER_glGetPixelShaderUniformB(unsigned int idx, int *data,
+                                         unsigned int bcount);
+
+/*
  * Connect a client-side array to the currently-bound program.
  *
  * (usage) and (index) map to Direct3D vertex declaration values: COLOR1 would
--- a/mojoshader_opengl.c	Tue May 31 16:25:37 2011 -0400
+++ b/mojoshader_opengl.c	Wed Jun 01 01:16:12 2011 -0400
@@ -1659,6 +1659,19 @@
 } // MOJOSHADER_glSetVertexShaderUniformF
 
 
+void MOJOSHADER_glGetVertexShaderUniformF(unsigned int idx, float *data,
+                                          unsigned int vec4n)
+{
+    const uint maxregs = STATICARRAYLEN(ctx->vs_reg_file_f) / 4;
+    if (idx < maxregs)
+    {
+        assert(sizeof (GLfloat) == sizeof (float));
+        const uint cpy = (minuint(maxregs - idx, vec4n) * sizeof (*data)) * 4;
+        memcpy(data, ctx->vs_reg_file_f + (idx * 4), cpy);
+    } // if
+} // MOJOSHADER_glGetVertexShaderUniformF
+
+
 void MOJOSHADER_glSetVertexShaderUniformI(unsigned int idx, const int *data,
                                           unsigned int ivec4n)
 {
@@ -1673,6 +1686,19 @@
 } // MOJOSHADER_glSetVertexShaderUniformI
 
 
+void MOJOSHADER_glGetVertexShaderUniformI(unsigned int idx, int *data,
+                                          unsigned int ivec4n)
+{
+    const uint maxregs = STATICARRAYLEN(ctx->vs_reg_file_i) / 4;
+    if (idx < maxregs)
+    {
+        assert(sizeof (GLint) == sizeof (int));
+        const uint cpy = (minuint(maxregs - idx, ivec4n) * sizeof (*data)) * 4;
+        memcpy(data, ctx->vs_reg_file_i + (idx * 4), cpy);
+    } // if
+} // MOJOSHADER_glGetVertexShaderUniformI
+
+
 void MOJOSHADER_glSetVertexShaderUniformB(unsigned int idx, const int *data,
                                           unsigned int bcount)
 {
@@ -1688,6 +1714,20 @@
 } // MOJOSHADER_glSetVertexShaderUniformB
 
 
+void MOJOSHADER_glGetVertexShaderUniformB(unsigned int idx, int *data,
+                                          unsigned int bcount)
+{
+    const uint maxregs = STATICARRAYLEN(ctx->vs_reg_file_f) / 4;
+    if (idx < maxregs)
+    {
+        uint8 *rptr = ctx->vs_reg_file_b + idx;
+        uint8 *endptr = rptr + minuint(maxregs - idx, bcount);
+        while (rptr != endptr)
+            *(data++) = (int) *(rptr++);
+    } // if
+} // MOJOSHADER_glGetVertexShaderUniformB
+
+
 void MOJOSHADER_glSetPixelShaderUniformF(unsigned int idx, const float *data,
                                          unsigned int vec4n)
 {
@@ -1702,6 +1742,19 @@
 } // MOJOSHADER_glSetPixelShaderUniformF
 
 
+void MOJOSHADER_glGetPixelShaderUniformF(unsigned int idx, float *data,
+                                         unsigned int vec4n)
+{
+    const uint maxregs = STATICARRAYLEN(ctx->ps_reg_file_f) / 4;
+    if (idx < maxregs)
+    {
+        assert(sizeof (GLfloat) == sizeof (float));
+        const uint cpy = (minuint(maxregs - idx, vec4n) * sizeof (*data)) * 4;
+        memcpy(data, ctx->ps_reg_file_f + (idx * 4), cpy);
+    } // if
+} // MOJOSHADER_glGetPixelShaderUniformF
+
+
 void MOJOSHADER_glSetPixelShaderUniformI(unsigned int idx, const int *data,
                                          unsigned int ivec4n)
 {
@@ -1716,6 +1769,19 @@
 } // MOJOSHADER_glSetPixelShaderUniformI
 
 
+void MOJOSHADER_glGetPixelShaderUniformI(unsigned int idx, int *data,
+                                         unsigned int ivec4n)
+{
+    const uint maxregs = STATICARRAYLEN(ctx->ps_reg_file_i) / 4;
+    if (idx < maxregs)
+    {
+        assert(sizeof (GLint) == sizeof (int));
+        const uint cpy = (minuint(maxregs - idx, ivec4n) * sizeof (*data)) * 4;
+        memcpy(data, ctx->ps_reg_file_i + (idx * 4), cpy);
+    } // if
+} // MOJOSHADER_glGetPixelShaderUniformI
+
+
 void MOJOSHADER_glSetPixelShaderUniformB(unsigned int idx, const int *data,
                                          unsigned int bcount)
 {
@@ -1731,6 +1797,20 @@
 } // MOJOSHADER_glSetPixelShaderUniformB
 
 
+void MOJOSHADER_glGetPixelShaderUniformB(unsigned int idx, int *data,
+                                         unsigned int bcount)
+{
+    const uint maxregs = STATICARRAYLEN(ctx->ps_reg_file_f) / 4;
+    if (idx < maxregs)
+    {
+        uint8 *rptr = ctx->ps_reg_file_b + idx;
+        uint8 *endptr = rptr + minuint(maxregs - idx, bcount);
+        while (rptr != endptr)
+            *(data++) = (int) *(rptr++);
+    } // if
+} // MOJOSHADER_glGetPixelShaderUniformB
+
+
 static inline GLenum opengl_attr_type(const MOJOSHADER_attributeType type)
 {
     switch (type)