From 69df21aaefd03fb7843cf845e793d4a5dc8dce55 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 1 Jun 2011 02:15:29 -0400 Subject: [PATCH] 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 | 19 +++++++ mojoshader_effects.c | 18 +++++-- mojoshader_internal.h | 2 +- mojoshader_opengl.c | 121 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 153 insertions(+), 7 deletions(-) diff --git a/mojoshader.h b/mojoshader.h index 18f5ff9d..4d4a0bdf 100644 --- a/mojoshader.h +++ b/mojoshader.h @@ -3002,6 +3002,25 @@ void MOJOSHADER_glSetVertexAttribute(MOJOSHADER_usage usage, 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 diff --git a/mojoshader_effects.c b/mojoshader_effects.c index 2900239a..9fa9e9e4 100644 --- a/mojoshader_effects.c +++ b/mojoshader_effects.c @@ -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 @@ void MOJOSHADER_runPreshader(const MOJOSHADER_preshader *preshader, } // case case MOJOSHADER_PRESHADEROPERAND_INPUT: + if (isscalar) + src[opiter][0] = inregs[index]; + else + { + int cpy; + for (cpy = 0; cpy < elems; cpy++) + src[opiter][cpy] = inregs[index+cpy]; + } // else + break; + case MOJOSHADER_PRESHADEROPERAND_OUTPUT: if (isscalar) - src[opiter][0] = regs[index]; + src[opiter][0] = outregs[index]; else { int cpy; for (cpy = 0; cpy < elems; cpy++) - src[opiter][cpy] = regs[index+cpy]; + src[opiter][cpy] = outregs[index+cpy]; } // else break; @@ -161,7 +171,7 @@ void MOJOSHADER_runPreshader(const MOJOSHADER_preshader *preshader, { 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 diff --git a/mojoshader_internal.h b/mojoshader_internal.h index ca3af0c6..20690a71 100644 --- a/mojoshader_internal.h +++ b/mojoshader_internal.h @@ -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 diff --git a/mojoshader_opengl.c b/mojoshader_opengl.c index e2c23708..6caf7c53 100644 --- a/mojoshader_opengl.c +++ b/mojoshader_opengl.c @@ -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 #include #include @@ -85,6 +88,12 @@ struct MOJOSHADER_glProgram 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 @@ static void program_unref(MOJOSHADER_glProgram *program) 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 @@ static int lookup_uniforms(MOJOSHADER_glProgram *program, #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 @@ void MOJOSHADER_glSetVertexAttribute(MOJOSHADER_usage usage, } // 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 @@ void MOJOSHADER_glProgramReady(void) 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 @@ void MOJOSHADER_glProgramReady(void) 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