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:
|
case APTHOOK_ONRESTORE:
|
||||||
{
|
{
|
||||||
ctx->flags |= C3DiF_AttrInfo | C3DiF_BufInfo | C3DiF_Effect | C3DiF_RenderBuf
|
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;
|
| C3DiF_TexAll | C3DiF_TexEnvBuf | C3DiF_TexEnvAll | C3DiF_LightEnv;
|
||||||
|
|
||||||
|
C3Di_DirtyUniforms(GPU_VERTEX_SHADER);
|
||||||
|
C3Di_DirtyUniforms(GPU_GEOMETRY_SHADER);
|
||||||
|
|
||||||
C3D_LightEnv* env = ctx->lightEnv;
|
C3D_LightEnv* env = ctx->lightEnv;
|
||||||
if (env)
|
if (env)
|
||||||
env->Dirty(env);
|
env->Dirty(env);
|
||||||
@ -129,8 +132,8 @@ void C3Di_UpdateContext(void)
|
|||||||
|
|
||||||
if (ctx->flags & C3DiF_Program)
|
if (ctx->flags & C3DiF_Program)
|
||||||
{
|
{
|
||||||
ctx->flags &= ~C3DiF_Program;
|
shaderProgramConfigure(ctx->program, (ctx->flags & C3DiF_VshCode) != 0, (ctx->flags & C3DiF_GshCode) != 0);
|
||||||
shaderProgramUse(ctx->program);
|
ctx->flags &= ~(C3DiF_Program | C3DiF_VshCode | C3DiF_GshCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->flags & C3DiF_RenderBuf)
|
if (ctx->flags & C3DiF_RenderBuf)
|
||||||
@ -270,6 +273,27 @@ void C3D_BindProgram(shaderProgram_s* program)
|
|||||||
if (!(ctx->flags & C3DiF_Active))
|
if (!(ctx->flags & C3DiF_Active))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
shaderProgram_s* oldProg = ctx->program;
|
||||||
|
shaderInstance_s* newGsh = program->geometryShader;
|
||||||
|
if (oldProg != program)
|
||||||
|
{
|
||||||
ctx->program = program;
|
ctx->program = program;
|
||||||
ctx->flags |= C3DiF_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_Program = BIT(8),
|
||||||
C3DiF_TexEnvBuf = BIT(9),
|
C3DiF_TexEnvBuf = BIT(9),
|
||||||
C3DiF_LightEnv = BIT(10),
|
C3DiF_LightEnv = BIT(10),
|
||||||
|
C3DiF_VshCode = BIT(11),
|
||||||
|
C3DiF_GshCode = BIT(12),
|
||||||
|
|
||||||
#define C3DiF_Tex(n) BIT(23+(n))
|
#define C3DiF_Tex(n) BIT(23+(n))
|
||||||
C3DiF_TexAll = 7 << 23,
|
C3DiF_TexAll = 7 << 23,
|
||||||
@ -80,3 +82,7 @@ void C3Di_EffectBind(C3D_Effect* effect);
|
|||||||
void C3Di_RenderBufBind(C3D_RenderBuf* rb);
|
void C3Di_RenderBufBind(C3D_RenderBuf* rb);
|
||||||
|
|
||||||
void C3Di_LightMtlBlend(C3D_Light* light);
|
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_IVUnifDirty[2][C3D_IVUNIF_COUNT];
|
||||||
bool C3D_BoolUnifsDirty[2];
|
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)
|
void C3D_UpdateUniforms(GPU_SHADER_TYPE type)
|
||||||
{
|
{
|
||||||
int offset = type == GPU_GEOMETRY_SHADER ? (GPUREG_GSH_BOOLUNIFORM-GPUREG_VSH_BOOLUNIFORM) : 0;
|
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
|
// Update FVec uniforms
|
||||||
int i = 0;
|
|
||||||
while (i < C3D_FVUNIF_COUNT)
|
while (i < C3D_FVUNIF_COUNT)
|
||||||
{
|
{
|
||||||
if (!C3D_FVUnifDirty[type][i])
|
if (!C3D_FVUnifDirty[type][i])
|
||||||
@ -27,14 +50,6 @@ void C3D_UpdateUniforms(GPU_SHADER_TYPE type)
|
|||||||
int j;
|
int j;
|
||||||
for (j = i; j < C3D_FVUNIF_COUNT && C3D_FVUnifDirty[type][j]; 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
|
// Upload the uniforms
|
||||||
GPUCMD_AddWrite(GPUREG_VSH_FLOATUNIFORM_CONFIG+offset, 0x80000000|i);
|
GPUCMD_AddWrite(GPUREG_VSH_FLOATUNIFORM_CONFIG+offset, 0x80000000|i);
|
||||||
GPUCMD_AddWrites(GPUREG_VSH_FLOATUNIFORM_DATA+offset, (u32*)&C3D_FVUnif[i], (j-i)*4);
|
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
|
// Clear the dirty flag
|
||||||
int k;
|
int k;
|
||||||
for (k = i; k < j; k ++)
|
for (k = i; k < j; k ++)
|
||||||
|
{
|
||||||
C3D_FVUnifDirty[type][k] = false;
|
C3D_FVUnifDirty[type][k] = false;
|
||||||
|
C3Di_FVUnifEverDirty[type][k] = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Advance
|
// Advance
|
||||||
i += j;
|
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]);
|
GPUCMD_AddWrite(GPUREG_VSH_INTUNIFORM_I0+offset+i, C3D_IVUnif[type][i]);
|
||||||
C3D_IVUnifDirty[type][i] = false;
|
C3D_IVUnifDirty[type][i] = false;
|
||||||
|
C3Di_IVUnifEverDirty[type][i] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update bool uniforms
|
// Update bool uniforms
|
||||||
if (C3D_BoolUnifsDirty[type])
|
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;
|
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