From 9d51a9445dff7521f5f3959f7003c86a19f7c09b Mon Sep 17 00:00:00 2001 From: fincs Date: Wed, 23 May 2018 13:54:49 +0200 Subject: [PATCH] Gas changes: - Separate gas reg writes according to stages - Related: Properly support C3D_GasAccMax - Add C3D_GasBeginAcc - Set correct gas depth function matching depth test in C3Di_EffectBind --- include/c3d/fog.h | 6 ++++-- source/base.c | 1 + source/effect.c | 1 + source/gas.c | 50 +++++++++++++++++++++++++++++++++++------------ source/internal.h | 12 +++++++++++- 5 files changed, 54 insertions(+), 16 deletions(-) diff --git a/include/c3d/fog.h b/include/c3d/fog.h index b4e62c2..8541af2 100644 --- a/include/c3d/fog.h +++ b/include/c3d/fog.h @@ -27,9 +27,11 @@ void C3D_FogLutBind(C3D_FogLut* lut); void GasLut_FromArray(C3D_GasLut* lut, const u32 data[9]); -void C3D_GasAttn(float value); -void C3D_GasAccMax(float value); +void C3D_GasBeginAcc(void); void C3D_GasDeltaZ(float value); + +void C3D_GasAccMax(float value); +void C3D_GasAttn(float value); void C3D_GasLightPlanar(float min, float max, float attn); void C3D_GasLightView(float min, float max, float attn); void C3D_GasLightDirection(float dotp); diff --git a/source/base.c b/source/base.c index 061c8d9..3b3d64d 100644 --- a/source/base.c +++ b/source/base.c @@ -62,6 +62,7 @@ static void C3Di_AptEventHook(APT_HookType hookType, C3D_UNUSED void* param) C3Di_DirtyUniforms(GPU_GEOMETRY_SHADER); ctx->fixedAttribDirty |= ctx->fixedAttribEverDirty; + ctx->gasFlags |= C3DiG_BeginAcc | C3DiG_AccStage | C3DiG_RenderStage; C3D_LightEnv* env = ctx->lightEnv; if (ctx->fogLut) diff --git a/source/effect.c b/source/effect.c index 7142afe..6904677 100644 --- a/source/effect.c +++ b/source/effect.c @@ -93,6 +93,7 @@ void C3Di_EffectBind(C3D_Effect* e) GPUCMD_AddWrite(GPUREG_FACECULLING_CONFIG, e->cullMode & 0x3); GPUCMD_AddIncrementalWrites(GPUREG_DEPTHMAP_SCALE, (u32*)&e->zScale, 2); GPUCMD_AddIncrementalWrites(GPUREG_FRAGOP_ALPHA_TEST, (u32*)&e->alphaTest, 4); + GPUCMD_AddMaskedWrite(GPUREG_GAS_DELTAZ_DEPTH, 0x8, (u32)GPU_MAKEGASDEPTHFUNC((e->depthTest>>4)&7) << 24); GPUCMD_AddWrite(GPUREG_BLEND_COLOR, e->blendClr); GPUCMD_AddWrite(GPUREG_BLEND_FUNC, e->alphaBlend); GPUCMD_AddWrite(GPUREG_LOGIC_OP, e->clrLogicOp); diff --git a/source/gas.c b/source/gas.c index 8fea5a4..819130b 100644 --- a/source/gas.c +++ b/source/gas.c @@ -39,7 +39,17 @@ void GasLut_FromArray(C3D_GasLut* lut, const u32 data[9]) } } -void C3D_GasAttn(float value) +void C3D_GasBeginAcc(void) +{ + C3D_Context* ctx = C3Di_GetContext(); + + if (!(ctx->flags & C3DiF_Active)) + return; + + ctx->gasFlags |= C3DiG_BeginAcc; +} + +void C3D_GasDeltaZ(float value) { C3D_Context* ctx = C3Di_GetContext(); @@ -47,7 +57,8 @@ void C3D_GasAttn(float value) return; ctx->flags |= C3DiF_Gas; - ctx->gasAttn = f32tof16(value); + ctx->gasDeltaZ = (u32)(value*0x100); + ctx->gasFlags |= C3DiG_AccStage; } void C3D_GasAccMax(float value) @@ -59,9 +70,10 @@ void C3D_GasAccMax(float value) ctx->flags |= C3DiF_Gas; ctx->gasAccMax = f32tof16(1.0f / value); + ctx->gasFlags |= C3DiG_SetAccMax; } -void C3D_GasDeltaZ(float value) +void C3D_GasAttn(float value) { C3D_Context* ctx = C3Di_GetContext(); @@ -69,8 +81,8 @@ void C3D_GasDeltaZ(float value) return; ctx->flags |= C3DiF_Gas; - ctx->gasDeltaZ = (u32)(value*0x100) & 0xFFFFFF; - ctx->gasDeltaZ |= 2<<24; + ctx->gasAttn = f32tof16(value); + ctx->gasFlags |= C3DiG_RenderStage; } void C3D_GasLightPlanar(float min, float max, float attn) @@ -82,6 +94,7 @@ void C3D_GasLightPlanar(float min, float max, float attn) ctx->flags |= C3DiF_Gas; ctx->gasLightXY = conv_u8(min,0) | conv_u8(max,8) | conv_u8(attn,16); + ctx->gasFlags |= C3DiG_RenderStage; } void C3D_GasLightView(float min, float max, float attn) @@ -93,6 +106,7 @@ void C3D_GasLightView(float min, float max, float attn) ctx->flags |= C3DiF_Gas; ctx->gasLightZ = conv_u8(min,0) | conv_u8(max,8) | conv_u8(attn,16); + ctx->gasFlags |= C3DiG_RenderStage; } void C3D_GasLightDirection(float dotp) @@ -105,6 +119,7 @@ void C3D_GasLightDirection(float dotp) ctx->flags |= C3DiF_Gas; ctx->gasLightZColor &= ~0xFF; ctx->gasLightZColor |= conv_u8(dotp,0); + ctx->gasFlags |= C3DiG_RenderStage; } void C3D_GasLutInput(GPU_GASLUTINPUT input) @@ -117,6 +132,7 @@ void C3D_GasLutInput(GPU_GASLUTINPUT input) ctx->flags |= C3DiF_Gas; ctx->gasLightZColor &= ~0x100; ctx->gasLightZColor |= (input&1)<<8; + ctx->gasFlags |= C3DiG_RenderStage; } void C3D_GasLutBind(C3D_GasLut* lut) @@ -136,17 +152,25 @@ void C3D_GasLutBind(C3D_GasLut* lut) void C3Di_GasUpdate(C3D_Context* ctx) { - //__builtin_printf("updgasstate %08lX\n", ctx->flags); - //for(;;); if (ctx->flags & C3DiF_Gas) { ctx->flags &= ~C3DiF_Gas; - GPUCMD_AddWrite(GPUREG_GAS_ATTENUATION, ctx->gasAttn); - //GPUCMD_AddWrite(GPUREG_GAS_ACCMAX, ctx->gasAccMax); - GPUCMD_AddWrite(GPUREG_GAS_LIGHT_XY, ctx->gasLightXY); - GPUCMD_AddWrite(GPUREG_GAS_LIGHT_Z, ctx->gasLightZ); - GPUCMD_AddWrite(GPUREG_GAS_LIGHT_Z_COLOR, ctx->gasLightZColor); - GPUCMD_AddWrite(GPUREG_GAS_DELTAZ_DEPTH, ctx->gasDeltaZ); + u32 gasFlags = ctx->gasFlags; + ctx->gasFlags = 0; + + if (gasFlags & C3DiG_BeginAcc) + GPUCMD_AddMaskedWrite(GPUREG_GAS_ACCMAX_FEEDBACK, 0x3, 0); + if (gasFlags & C3DiG_AccStage) + GPUCMD_AddMaskedWrite(GPUREG_GAS_DELTAZ_DEPTH, 0x7, ctx->gasDeltaZ); + if (gasFlags & C3DiG_SetAccMax) + GPUCMD_AddWrite(GPUREG_GAS_ACCMAX, ctx->gasAccMax); + if (gasFlags & C3DiG_RenderStage) + { + GPUCMD_AddWrite(GPUREG_GAS_ATTENUATION, ctx->gasAttn); + GPUCMD_AddWrite(GPUREG_GAS_LIGHT_XY, ctx->gasLightXY); + GPUCMD_AddWrite(GPUREG_GAS_LIGHT_Z, ctx->gasLightZ); + GPUCMD_AddWrite(GPUREG_GAS_LIGHT_Z_COLOR, ctx->gasLightZColor); + } } if (ctx->flags & C3DiF_GasLut) { diff --git a/source/internal.h b/source/internal.h index 6ac7231..25b4be6 100644 --- a/source/internal.h +++ b/source/internal.h @@ -53,7 +53,9 @@ typedef struct C3D_FogLut* fogLut; u16 gasAttn, gasAccMax; - u32 gasLightXY, gasLightZ, gasLightZColor, gasDeltaZ; + u32 gasLightXY, gasLightZ, gasLightZColor; + u32 gasDeltaZ : 24; + u32 gasFlags : 8; C3D_GasLut* gasLut; C3D_ProcTex* procTex; @@ -98,6 +100,14 @@ enum C3DiF_TexEnvAll = 0x3F << 26, }; +enum +{ + C3DiG_BeginAcc = BIT(0), + C3DiG_AccStage = BIT(1), + C3DiG_SetAccMax = BIT(2), + C3DiG_RenderStage = BIT(3), +}; + static inline C3D_Context* C3Di_GetContext(void) { extern C3D_Context __C3D_Context;