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...
--- 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