Preshader input registers are separate from the actual shader constant file!
authorRyan C. Gordon <icculus@icculus.org>
Wed, 01 Jun 2011 02:15:29 -0400
changeset 1043 6227066350b4
parent 1042 cb6659f80bb9
child 1044 1241d4a56b28
Preshader input registers are separate from the actual shader constant file! So make the effort to manage yet-another set of arrays for these registers...
mojoshader.h
mojoshader_effects.c
mojoshader_internal.h
mojoshader_opengl.c
--- a/mojoshader.h	Wed Jun 01 02:14:12 2011 -0400
+++ b/mojoshader.h	Wed Jun 01 02:15:29 2011 -0400
@@ -3002,6 +3002,25 @@
                                      int normalized, unsigned int stride,
                                      const void *ptr);
 
+
+
+
+/* These below functions are temporary and will be removed from the API once
+    the real Effects API is written. Do not use! */
+void MOJOSHADER_glSetVertexPreshaderUniformF(unsigned int idx, const float *data,
+                                             unsigned int vec4n);
+void MOJOSHADER_glGetVertexPreshaderUniformF(unsigned int idx, float *data,
+                                             unsigned int vec4n);
+void MOJOSHADER_glSetPixelPreshaderUniformF(unsigned int idx, const float *data,
+                                            unsigned int vec4n);
+void MOJOSHADER_glGetPixelPreshaderUniformF(unsigned int idx, float *data,
+                                            unsigned int vec4n);
+/* These above functions are temporary and will be removed from the API once
+    the real Effects API is written. Do not use! */
+
+
+
+
 /*
  * Inform MojoShader that it should commit any pending state to the GL. This
  *  must be called after you bind a program and update any inputs, right
--- a/mojoshader_effects.c	Wed Jun 01 02:14:12 2011 -0400
+++ b/mojoshader_effects.c	Wed Jun 01 02:15:29 2011 -0400
@@ -14,7 +14,7 @@
 
 #if SUPPORT_PRESHADERS
 void MOJOSHADER_runPreshader(const MOJOSHADER_preshader *preshader,
-                                 float *regs)
+                             const float *inregs, float *outregs)
 {
     // this is fairly straightforward, as there aren't any branching
     //  opcodes in the preshader instruction set (at the moment, at least).
@@ -61,14 +61,24 @@
                 } // case
 
                 case MOJOSHADER_PRESHADEROPERAND_INPUT:
-                case MOJOSHADER_PRESHADEROPERAND_OUTPUT:
                     if (isscalar)
-                        src[opiter][0] = regs[index];
+                        src[opiter][0] = inregs[index];
                     else
                     {
                         int cpy;
                         for (cpy = 0; cpy < elems; cpy++)
-                            src[opiter][cpy] = regs[index+cpy];
+                            src[opiter][cpy] = inregs[index+cpy];
+                    } // else
+                    break;
+
+                case MOJOSHADER_PRESHADEROPERAND_OUTPUT:
+                    if (isscalar)
+                        src[opiter][0] = outregs[index];
+                    else
+                    {
+                        int cpy;
+                        for (cpy = 0; cpy < elems; cpy++)
+                            src[opiter][cpy] = outregs[index+cpy];
                     } // else
                     break;
 
@@ -161,7 +171,7 @@
         {
             assert(operand->type == MOJOSHADER_PRESHADEROPERAND_OUTPUT);
             for (i = 0; i < elems; i++)
-                regs[operand->index + i] = (float) dst[i];
+                outregs[operand->index + i] = (float) dst[i];
         } // else
     } // for
 } // MOJOSHADER_runPreshader
--- a/mojoshader_internal.h	Wed Jun 01 02:14:12 2011 -0400
+++ b/mojoshader_internal.h	Wed Jun 01 02:15:29 2011 -0400
@@ -78,7 +78,7 @@
 #endif
 
 #if SUPPORT_PRESHADERS
-void MOJOSHADER_runPreshader(const MOJOSHADER_preshader *, float *);
+void MOJOSHADER_runPreshader(const MOJOSHADER_preshader*, const float*, float*);
 #else
 #define MOJOSHADER_runPreshader(a, b)
 #endif
--- a/mojoshader_opengl.c	Wed Jun 01 02:14:12 2011 -0400
+++ b/mojoshader_opengl.c	Wed Jun 01 02:15:29 2011 -0400
@@ -7,6 +7,9 @@
  *  This file written by Ryan C. Gordon.
  */
 
+// !!! FIXME: preshaders shouldn't be handled in here at all. This should
+// !!! FIXME:  be in the Effects API, once that's actually written.
+
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -85,6 +88,12 @@
     GLint *ps_uniforms_int4;
     size_t ps_uniforms_bool_count;
     GLint *ps_uniforms_bool;
+
+    size_t vs_preshader_reg_count;
+    GLfloat *vs_preshader_regs;
+    size_t ps_preshader_reg_count;
+    GLfloat *ps_preshader_regs;
+
     uint32 refcount;
     // GLSL uses these...location of uniform arrays.
     GLint vs_float4_loc;
@@ -1279,6 +1288,8 @@
             ctx->profileDeleteProgram(program->handle);
             shader_unref(program->vertex);
             shader_unref(program->fragment);
+            Free(program->vs_preshader_regs);
+            Free(program->ps_preshader_regs);
             Free(program->vs_uniforms_float4);
             Free(program->vs_uniforms_int4);
             Free(program->vs_uniforms_bool);
@@ -1395,6 +1406,38 @@
 
     #undef MAKE_ARRAY
 
+    if (pd->preshader)
+    {
+        unsigned int largest = 0;
+        const MOJOSHADER_symbol *sym = pd->preshader->symbols;
+        for (i = 0; i < pd->preshader->symbol_count; i++, sym++)
+        {
+            const unsigned int val = sym->register_index + sym->register_count;
+            if (val > largest)
+                largest = val;
+        } // for
+
+        if (largest > 0)
+        {
+            const size_t len = largest * sizeof (GLfloat);
+            GLfloat *buf = (GLfloat *) Malloc(len);
+            if (buf == NULL)
+                return 0;
+            memset(buf, '\0', len);
+
+            if (shader_type == MOJOSHADER_TYPE_VERTEX)
+            {
+                program->vs_preshader_reg_count = largest;
+                program->vs_preshader_regs = buf;
+            } // if
+            else if (shader_type == MOJOSHADER_TYPE_PIXEL)
+            {
+                program->ps_preshader_reg_count = largest;
+                program->ps_preshader_regs = buf;
+            } // else if
+        } // if
+    } // if
+
     return 1;
 } // lookup_uniforms
 
@@ -1884,6 +1927,78 @@
 } // MOJOSHADER_glSetVertexAttribute
 
 
+void MOJOSHADER_glSetVertexPreshaderUniformF(unsigned int idx,
+                                             const float *data,
+                                             unsigned int vec4n)
+{
+    MOJOSHADER_glProgram *program = ctx->bound_program;
+    if (program == NULL)
+        return;  // nothing to do.
+
+    const uint maxregs = program->vs_preshader_reg_count;
+    if (idx < maxregs)
+    {
+        assert(sizeof (GLfloat) == sizeof (float));
+        const uint cpy = (minuint(maxregs - idx, vec4n) * sizeof (*data)) * 4;
+        memcpy(program->vs_preshader_regs + (idx * 4), data, cpy);
+        program->generation = ctx->generation-1;
+    } // if
+} // MOJOSHADER_glSetVertexPreshaderUniformF
+
+
+void MOJOSHADER_glGetVertexPreshaderUniformF(unsigned int idx, float *data,
+                                             unsigned int vec4n)
+{
+    MOJOSHADER_glProgram *program = ctx->bound_program;
+    if (program == NULL)
+        return;  // nothing to do.
+
+    const uint maxregs = program->vs_preshader_reg_count;
+    if (idx < maxregs)
+    {
+        assert(sizeof (GLfloat) == sizeof (float));
+        const uint cpy = (minuint(maxregs - idx, vec4n) * sizeof (*data)) * 4;
+        memcpy(data, program->vs_preshader_regs + (idx * 4), cpy);
+    } // if
+} // MOJOSHADER_glGetVertexPreshaderUniformF
+
+
+void MOJOSHADER_glSetPixelPreshaderUniformF(unsigned int idx,
+                                             const float *data,
+                                             unsigned int vec4n)
+{
+    MOJOSHADER_glProgram *program = ctx->bound_program;
+    if (program == NULL)
+        return;  // nothing to do.
+
+    const uint maxregs = program->ps_preshader_reg_count;
+    if (idx < maxregs)
+    {
+        assert(sizeof (GLfloat) == sizeof (float));
+        const uint cpy = (minuint(maxregs - idx, vec4n) * sizeof (*data)) * 4;
+        memcpy(program->ps_preshader_regs + (idx * 4), data, cpy);
+        program->generation = ctx->generation-1;
+    } // if
+} // MOJOSHADER_glSetPixelPreshaderUniformF
+
+
+void MOJOSHADER_glGetPixelPreshaderUniformF(unsigned int idx, float *data,
+                                             unsigned int vec4n)
+{
+    MOJOSHADER_glProgram *program = ctx->bound_program;
+    if (program == NULL)
+        return;  // nothing to do.
+
+    const uint maxregs = program->ps_preshader_reg_count;
+    if (idx < maxregs)
+    {
+        assert(sizeof (GLfloat) == sizeof (float));
+        const uint cpy = (minuint(maxregs - idx, vec4n) * sizeof (*data)) * 4;
+        memcpy(data, program->ps_preshader_regs + (idx * 4), cpy);
+    } // if
+} // MOJOSHADER_glGetPixelPreshaderUniformF
+
+
 void MOJOSHADER_glProgramReady(void)
 {
     MOJOSHADER_glProgram *program = ctx->bound_program;
@@ -1915,7 +2030,8 @@
             preshader = program->vertex->parseData->preshader;
             if (preshader)
             {
-                MOJOSHADER_runPreshader(preshader, ctx->vs_reg_file_f);
+                MOJOSHADER_runPreshader(preshader, program->vs_preshader_regs,
+                                        ctx->vs_reg_file_f);
                 ran_preshader = 1;
             } // if
         } // if
@@ -1925,7 +2041,8 @@
             preshader = program->fragment->parseData->preshader;
             if (preshader)
             {
-                MOJOSHADER_runPreshader(preshader, ctx->ps_reg_file_f);
+                MOJOSHADER_runPreshader(preshader, program->ps_preshader_regs,
+                                        ctx->ps_reg_file_f);
                 ran_preshader = 1;
             } // if
         } // if