Implement proper shader program DVLE constant management
This commit is contained in:
parent
ca410a80ac
commit
dfad81b53c
@ -49,9 +49,12 @@ static void C3Di_AptEventHook(APT_HookType hookType, void* param)
|
||||
case APTHOOK_ONRESTORE:
|
||||
{
|
||||
ctx->flags |= C3DiF_AttrInfo | C3DiF_BufInfo | C3DiF_Effect | C3DiF_RenderBuf
|
||||
| C3DiF_Viewport | C3DiF_Scissor | C3DiF_Program
|
||||
| C3DiF_Viewport | C3DiF_Scissor | C3DiF_Program | C3DiF_VshCode | C3DiF_GshCode
|
||||
| C3DiF_TexAll | C3DiF_TexEnvBuf | C3DiF_TexEnvAll | C3DiF_LightEnv;
|
||||
|
||||
C3Di_DirtyUniforms(GPU_VERTEX_SHADER);
|
||||
C3Di_DirtyUniforms(GPU_GEOMETRY_SHADER);
|
||||
|
||||
C3D_LightEnv* env = ctx->lightEnv;
|
||||
if (env)
|
||||
env->Dirty(env);
|
||||
@ -129,8 +132,8 @@ void C3Di_UpdateContext(void)
|
||||
|
||||
if (ctx->flags & C3DiF_Program)
|
||||
{
|
||||
ctx->flags &= ~C3DiF_Program;
|
||||
shaderProgramUse(ctx->program);
|
||||
shaderProgramConfigure(ctx->program, (ctx->flags & C3DiF_VshCode) != 0, (ctx->flags & C3DiF_GshCode) != 0);
|
||||
ctx->flags &= ~(C3DiF_Program | C3DiF_VshCode | C3DiF_GshCode);
|
||||
}
|
||||
|
||||
if (ctx->flags & C3DiF_RenderBuf)
|
||||
@ -270,6 +273,27 @@ void C3D_BindProgram(shaderProgram_s* program)
|
||||
if (!(ctx->flags & C3DiF_Active))
|
||||
return;
|
||||
|
||||
shaderProgram_s* oldProg = ctx->program;
|
||||
shaderInstance_s* newGsh = program->geometryShader;
|
||||
if (oldProg != program)
|
||||
{
|
||||
ctx->program = program;
|
||||
ctx->flags |= C3DiF_Program;
|
||||
|
||||
if (oldProg)
|
||||
{
|
||||
if (oldProg->vertexShader->dvle->dvlp != program->vertexShader->dvle->dvlp)
|
||||
ctx->flags |= C3DiF_VshCode;
|
||||
shaderInstance_s* oldGsh = oldProg->geometryShader;
|
||||
if (newGsh && (!oldGsh || oldGsh->dvle->dvlp != newGsh->dvle->dvlp))
|
||||
ctx->flags |= C3DiF_GshCode;
|
||||
} else
|
||||
ctx->flags |= C3DiF_VshCode | C3DiF_GshCode;
|
||||
}
|
||||
|
||||
C3Di_LoadShaderUniforms(program->vertexShader);
|
||||
if (newGsh)
|
||||
C3Di_LoadShaderUniforms(newGsh);
|
||||
else
|
||||
C3Di_ClearShaderUniforms(GPU_GEOMETRY_SHADER);
|
||||
}
|
||||
|
@ -59,6 +59,8 @@ enum
|
||||
C3DiF_Program = BIT(8),
|
||||
C3DiF_TexEnvBuf = BIT(9),
|
||||
C3DiF_LightEnv = BIT(10),
|
||||
C3DiF_VshCode = BIT(11),
|
||||
C3DiF_GshCode = BIT(12),
|
||||
|
||||
#define C3DiF_Tex(n) BIT(23+(n))
|
||||
C3DiF_TexAll = 7 << 23,
|
||||
@ -80,3 +82,7 @@ void C3Di_EffectBind(C3D_Effect* effect);
|
||||
void C3Di_RenderBufBind(C3D_RenderBuf* rb);
|
||||
|
||||
void C3Di_LightMtlBlend(C3D_Light* light);
|
||||
|
||||
void C3Di_DirtyUniforms(GPU_SHADER_TYPE type);
|
||||
void C3Di_LoadShaderUniforms(shaderInstance_s* si);
|
||||
void C3Di_ClearShaderUniforms(GPU_SHADER_TYPE type);
|
||||
|
@ -9,12 +9,35 @@ bool C3D_FVUnifDirty[2][C3D_FVUNIF_COUNT];
|
||||
bool C3D_IVUnifDirty[2][C3D_IVUNIF_COUNT];
|
||||
bool C3D_BoolUnifsDirty[2];
|
||||
|
||||
static struct
|
||||
{
|
||||
bool dirty;
|
||||
int count;
|
||||
float24Uniform_s* data;
|
||||
} C3Di_ShaderFVecData[2];
|
||||
|
||||
static bool C3Di_FVUnifEverDirty[2][C3D_FVUNIF_COUNT];
|
||||
static bool C3Di_IVUnifEverDirty[2][C3D_IVUNIF_COUNT];
|
||||
|
||||
void C3D_UpdateUniforms(GPU_SHADER_TYPE type)
|
||||
{
|
||||
int offset = type == GPU_GEOMETRY_SHADER ? (GPUREG_GSH_BOOLUNIFORM-GPUREG_VSH_BOOLUNIFORM) : 0;
|
||||
int i = 0;
|
||||
|
||||
// Update FVec uniforms that come from shader constants
|
||||
if (C3Di_ShaderFVecData[type].dirty)
|
||||
{
|
||||
while (i < C3Di_ShaderFVecData[type].count)
|
||||
{
|
||||
float24Uniform_s* u = &C3Di_ShaderFVecData[type].data[i++];
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_VSH_FLOATUNIFORM_CONFIG+offset, (u32*)u, 4);
|
||||
C3D_FVUnifDirty[type][u->id] = false;
|
||||
}
|
||||
C3Di_ShaderFVecData[type].dirty = false;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
// Update FVec uniforms
|
||||
int i = 0;
|
||||
while (i < C3D_FVUNIF_COUNT)
|
||||
{
|
||||
if (!C3D_FVUnifDirty[type][i])
|
||||
@ -27,14 +50,6 @@ void C3D_UpdateUniforms(GPU_SHADER_TYPE type)
|
||||
int j;
|
||||
for (j = i; j < C3D_FVUNIF_COUNT && C3D_FVUnifDirty[type][j]; j ++);
|
||||
|
||||
/*
|
||||
consoleClear();
|
||||
printf("FVEC Uniform %02X--%02X\n", i, j-1);
|
||||
int pp;
|
||||
for (pp = i; pp < j; pp ++)
|
||||
printf("%02X: (%f, %f, %f, %f)\n", pp, C3D_FVUnif[pp].x, C3D_FVUnif[pp].y, C3D_FVUnif[pp].z, C3D_FVUnif[pp].w);
|
||||
*/
|
||||
|
||||
// Upload the uniforms
|
||||
GPUCMD_AddWrite(GPUREG_VSH_FLOATUNIFORM_CONFIG+offset, 0x80000000|i);
|
||||
GPUCMD_AddWrites(GPUREG_VSH_FLOATUNIFORM_DATA+offset, (u32*)&C3D_FVUnif[i], (j-i)*4);
|
||||
@ -42,7 +57,10 @@ void C3D_UpdateUniforms(GPU_SHADER_TYPE type)
|
||||
// Clear the dirty flag
|
||||
int k;
|
||||
for (k = i; k < j; k ++)
|
||||
{
|
||||
C3D_FVUnifDirty[type][k] = false;
|
||||
C3Di_FVUnifEverDirty[type][k] = true;
|
||||
}
|
||||
|
||||
// Advance
|
||||
i += j;
|
||||
@ -55,12 +73,58 @@ void C3D_UpdateUniforms(GPU_SHADER_TYPE type)
|
||||
|
||||
GPUCMD_AddWrite(GPUREG_VSH_INTUNIFORM_I0+offset+i, C3D_IVUnif[type][i]);
|
||||
C3D_IVUnifDirty[type][i] = false;
|
||||
C3Di_IVUnifEverDirty[type][i] = false;
|
||||
}
|
||||
|
||||
// Update bool uniforms
|
||||
if (C3D_BoolUnifsDirty[type])
|
||||
{
|
||||
GPUCMD_AddWrite(GPUREG_VSH_BOOLUNIFORM+offset, 0x7FFF0000 | (u32)C3D_BoolUnifs[type]);
|
||||
GPUCMD_AddWrite(GPUREG_VSH_BOOLUNIFORM+offset, 0x7FFF0000 | (u32)~C3D_BoolUnifs[type]);
|
||||
C3D_BoolUnifsDirty[type] = false;
|
||||
}
|
||||
}
|
||||
|
||||
void C3Di_DirtyUniforms(GPU_SHADER_TYPE type)
|
||||
{
|
||||
int i;
|
||||
C3D_BoolUnifsDirty[type] = true;
|
||||
if (C3Di_ShaderFVecData[type].count)
|
||||
C3Di_ShaderFVecData[type].dirty = true;
|
||||
for (i = 0; i < C3D_FVUNIF_COUNT; i ++)
|
||||
C3D_FVUnifDirty[type][i] = C3D_FVUnifDirty[type][i] || C3Di_FVUnifEverDirty[type][i];
|
||||
for (i = 0; i < C3D_IVUNIF_COUNT; i ++)
|
||||
C3D_IVUnifDirty[type][i] = C3D_IVUnifDirty[type][i] || C3Di_IVUnifEverDirty[type][i];
|
||||
}
|
||||
|
||||
void C3Di_LoadShaderUniforms(shaderInstance_s* si)
|
||||
{
|
||||
GPU_SHADER_TYPE type = si->dvle->type;
|
||||
int i;
|
||||
if (si->boolUniformMask)
|
||||
{
|
||||
C3D_BoolUnifs[type] &= ~si->boolUniformMask;
|
||||
C3D_BoolUnifs[type] |= si->boolUniforms;
|
||||
C3D_BoolUnifsDirty[type] = true;
|
||||
}
|
||||
if (si->intUniformMask)
|
||||
{
|
||||
for (i = 0; i < 4; i ++)
|
||||
{
|
||||
if (si->intUniformMask & BIT(i))
|
||||
{
|
||||
C3D_IVUnif[type][i] = si->intUniforms[i];
|
||||
C3D_IVUnifDirty[type][i] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
C3Di_ShaderFVecData[type].dirty = true;
|
||||
C3Di_ShaderFVecData[type].count = si->numFloat24Uniforms;
|
||||
C3Di_ShaderFVecData[type].data = si->float24Uniforms;
|
||||
}
|
||||
|
||||
void C3Di_ClearShaderUniforms(GPU_SHADER_TYPE type)
|
||||
{
|
||||
C3Di_ShaderFVecData[type].dirty = false;
|
||||
C3Di_ShaderFVecData[type].count = 0;
|
||||
C3Di_ShaderFVecData[type].data = NULL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user