mirror of
https://github.com/encounter/aurora.git
synced 2026-07-09 18:19:33 -07:00
Fix GX indirect tile window rendering (#218)
Co-authored-by: Thomas Ryan <contact@thomasryan.ca>
This commit is contained in:
+15
-24
@@ -173,35 +173,26 @@ void GXSetTevIndBumpST(GXTevStageID tevStage, GXIndTexStageID indStage, GXIndTex
|
||||
GX_ITW_OFF, GX_TRUE, GX_FALSE, GX_ITBA_OFF);
|
||||
}
|
||||
|
||||
void GXSetTevIndTile(GXTevStageID tevStage, GXIndTexStageID indStage, u16 tileSizeS, u16 tileSizeT, u16 tileSizeS_exp,
|
||||
u16 tileSizeT_exp, GXIndTexFormat fmt, GXIndTexMtxID matrixSel, GXIndTexBiasSel biasSel,
|
||||
void GXSetTevIndTile(GXTevStageID tevStage, GXIndTexStageID indStage, u16 tileSizeS, u16 tileSizeT, u16 tileSpacingS,
|
||||
u16 tileSpacingT, GXIndTexFormat fmt, GXIndTexMtxID matrixSel, GXIndTexBiasSel biasSel,
|
||||
GXIndTexAlphaSel alphaSel) {
|
||||
// Convert tile size exponents to wrap modes
|
||||
auto sizeToWrap = [](u16 sizeExp) -> GXIndTexWrap {
|
||||
switch (sizeExp) {
|
||||
case 8: return GX_ITW_256;
|
||||
case 7: return GX_ITW_128;
|
||||
case 6: return GX_ITW_64;
|
||||
case 5: return GX_ITW_32;
|
||||
case 4: return GX_ITW_16;
|
||||
auto sizeToWrap = [](u16 size) -> GXIndTexWrap {
|
||||
switch (size) {
|
||||
case 256: return GX_ITW_256;
|
||||
case 128: return GX_ITW_128;
|
||||
case 64: return GX_ITW_64;
|
||||
case 32: return GX_ITW_32;
|
||||
case 16: return GX_ITW_16;
|
||||
default: return GX_ITW_0;
|
||||
}
|
||||
};
|
||||
GXIndTexWrap wrapS = sizeToWrap(tileSizeS_exp);
|
||||
GXIndTexWrap wrapT = sizeToWrap(tileSizeT_exp);
|
||||
GXIndTexWrap wrapS = sizeToWrap(tileSizeS);
|
||||
GXIndTexWrap wrapT = sizeToWrap(tileSizeT);
|
||||
|
||||
// Set up the indirect matrix for tiling
|
||||
f32 mtx[2][3] = {};
|
||||
s8 scaleExp = 0;
|
||||
if (biasSel == GX_ITB_S || biasSel == GX_ITB_ST || biasSel == GX_ITB_SU || biasSel == GX_ITB_STU) {
|
||||
mtx[0][0] = static_cast<f32>(tileSizeS);
|
||||
scaleExp = tileSizeS_exp;
|
||||
}
|
||||
if (biasSel == GX_ITB_T || biasSel == GX_ITB_ST || biasSel == GX_ITB_TU || biasSel == GX_ITB_STU) {
|
||||
mtx[1][1] = static_cast<f32>(tileSizeT);
|
||||
scaleExp = tileSizeT_exp;
|
||||
}
|
||||
GXSetIndTexMtx(matrixSel, mtx, scaleExp);
|
||||
GXSetTevIndirect(tevStage, indStage, fmt, biasSel, matrixSel, wrapS, wrapT, GX_FALSE, GX_FALSE, alphaSel);
|
||||
mtx[0][0] = static_cast<f32>(tileSpacingS) / 1024.0f;
|
||||
mtx[1][1] = static_cast<f32>(tileSpacingT) / 1024.0f;
|
||||
GXSetIndTexMtx(matrixSel, mtx, 10);
|
||||
GXSetTevIndirect(tevStage, indStage, fmt, biasSel, matrixSel, wrapS, wrapT, GX_FALSE, GX_TRUE, alphaSel);
|
||||
}
|
||||
}
|
||||
|
||||
+21
-20
@@ -1191,18 +1191,19 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config) noexcept {
|
||||
continue;
|
||||
}
|
||||
const auto& indStage = config.indStages[i];
|
||||
std::string scaleExpr;
|
||||
if (indStage.scaleS == GX_ITS_1 && indStage.scaleT == GX_ITS_1) {
|
||||
scaleExpr = fmt::format("tex{0}_uv", underlying(indStage.texCoordId));
|
||||
} else {
|
||||
scaleExpr = fmt::format("tex{0}_uv * vec2f({1}, {2})", underlying(indStage.texCoordId),
|
||||
ind_scale(indStage.scaleS), ind_scale(indStage.scaleT));
|
||||
}
|
||||
const u32 texCoordId = underlying(indStage.texCoordId);
|
||||
const u32 texMapId = underlying(indStage.texMapId);
|
||||
// GX applies the SU texture-coordinate scale before the indirect stage scale.
|
||||
// The shader carries normalized UVs, so convert that texel-space result back
|
||||
// into normalized coordinates for the indirect texture sample.
|
||||
const auto scaleExpr =
|
||||
fmt::format("tex{0}_uv * ubuf.texcoord_scale[{0}].xy * vec2f({1}, {2}) / ubuf.tex{3}_size_bias.xy",
|
||||
texCoordId, ind_scale(indStage.scaleS), ind_scale(indStage.scaleT), texMapId);
|
||||
fragmentFnPre += fmt::format(
|
||||
"\n // Indirect stage {0}"
|
||||
"\n var t_IndTexCoord{0} = 255.0 * textureSampleBias(tex{1}, tex{1}_samp, {2}, "
|
||||
"ubuf.tex{1}_size_bias.z).abg;",
|
||||
i, underlying(indStage.texMapId), scaleExpr);
|
||||
i, texMapId, scaleExpr);
|
||||
}
|
||||
if (info.usedIndStages.any()) {
|
||||
fragmentFnPre += "\n var t_TexCoord = vec2f(0.0);";
|
||||
@@ -1283,23 +1284,21 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config) noexcept {
|
||||
") * ind{0}_c1.z",
|
||||
i);
|
||||
} else if (stage.indTexMtxId >= GX_ITM_S0 && stage.indTexMtxId <= GX_ITM_S2 && hasBaseCoord) {
|
||||
// Dynamic S: result = uv * texDim * ind_coord.x * scale / 256
|
||||
// Dynamic S: result = scaled texcoord * ind_coord.x * scale / 256
|
||||
u32 mtxIdx = stage.indTexMtxId - GX_ITM_S0;
|
||||
u32 regTexCoord = underlying(stage.texCoordId);
|
||||
u32 regTexMap = underlying(stage.texMapId);
|
||||
indirectOffsetTexel = fmt::format(
|
||||
"tex{1}_uv * ubuf.tex{2}_size_bias.xy * ind{0}_coord.x"
|
||||
" * ubuf.ind_mtx[{3}][1][2] / 256.0",
|
||||
i, regTexCoord, regTexMap, mtxIdx);
|
||||
"tex{1}_uv * ubuf.texcoord_scale[{1}].xy * ind{0}_coord.x"
|
||||
" * ubuf.ind_mtx[{2}][1][2] / 256.0",
|
||||
i, regTexCoord, mtxIdx);
|
||||
} else if (stage.indTexMtxId >= GX_ITM_T0 && stage.indTexMtxId <= GX_ITM_T2 && hasBaseCoord) {
|
||||
// Dynamic T: result = uv * texDim * ind_coord.y * scale / 256
|
||||
// Dynamic T: result = scaled texcoord * ind_coord.y * scale / 256
|
||||
u32 mtxIdx = stage.indTexMtxId - GX_ITM_T0;
|
||||
u32 regTexCoord = underlying(stage.texCoordId);
|
||||
u32 regTexMap = underlying(stage.texMapId);
|
||||
indirectOffsetTexel = fmt::format(
|
||||
"tex{1}_uv * ubuf.tex{2}_size_bias.xy * ind{0}_coord.y"
|
||||
" * ubuf.ind_mtx[{3}][1][2] / 256.0",
|
||||
i, regTexCoord, regTexMap, mtxIdx);
|
||||
"tex{1}_uv * ubuf.texcoord_scale[{1}].xy * ind{0}_coord.y"
|
||||
" * ubuf.ind_mtx[{2}][1][2] / 256.0",
|
||||
i, regTexCoord, mtxIdx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1330,12 +1329,11 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config) noexcept {
|
||||
std::string baseCoordExpr;
|
||||
if (hasBaseCoord) {
|
||||
u32 texCoordId = underlying(stage.texCoordId);
|
||||
u32 texMapId = underlying(stage.texMapId);
|
||||
if (useSimpleCoords) {
|
||||
baseCoordExpr = fmt::format("tex{}_uv", texCoordId);
|
||||
} else {
|
||||
fragmentFnPre +=
|
||||
fmt::format("\n var ind{0}_texel = tex{1}_uv * ubuf.tex{2}_size_bias.xy;", i, texCoordId, texMapId);
|
||||
fmt::format("\n var ind{0}_texel = tex{1}_uv * ubuf.texcoord_scale[{1}].xy;", i, texCoordId);
|
||||
baseCoordExpr = fmt::format("ind{}_texel", i);
|
||||
}
|
||||
}
|
||||
@@ -1430,6 +1428,9 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config) noexcept {
|
||||
}
|
||||
fragmentFn += "\n prev = vec4f(mix(prev.rgb, ubuf.fog.color.rgb, clamp(fogZ, 0.0, 1.0)), prev.a);";
|
||||
}
|
||||
if (info.usedIndStages.any()) {
|
||||
uniBufAttrs += fmt::format("\n texcoord_scale: array<vec4f, {}>,", MaxTexCoord);
|
||||
}
|
||||
if (info.usedIndTexMtxs.any()) {
|
||||
uniBufAttrs += "\n ind_mtx: array<mat2x4f, 3>,";
|
||||
}
|
||||
|
||||
@@ -306,6 +306,9 @@ ShaderInfo build_shader_info(const ShaderConfig& config) noexcept {
|
||||
info.usesFog = true;
|
||||
info.uniformSize += sizeof(Fog);
|
||||
}
|
||||
if (info.usedIndStages.any()) {
|
||||
info.uniformSize += MaxTexCoord * sizeof(Vec4<float>);
|
||||
}
|
||||
if (info.usedIndTexMtxs.any()) {
|
||||
info.uniformSize += MaxIndTexMtxs * sizeof(Mat2x4<float>);
|
||||
}
|
||||
@@ -446,6 +449,12 @@ gfx::Range build_uniform(const ShaderInfo& info, u32 vtxStart, const BindGroupRa
|
||||
Fog fog{.color = state.color, .a = state.a, .b = state.b, .c = state.c};
|
||||
buf.append(fog);
|
||||
}
|
||||
if (info.usedIndStages.any()) {
|
||||
for (const auto& scale : g_gxState.texCoordScales) {
|
||||
buf.append(
|
||||
Vec4{static_cast<f32>(scale.scaleS) + 1.0f, static_cast<f32>(scale.scaleT) + 1.0f, 0.0f, 0.0f});
|
||||
}
|
||||
}
|
||||
if (info.usedIndTexMtxs.any()) {
|
||||
for (int i = 0; i < MaxIndTexMtxs; ++i) {
|
||||
const auto& mtx = g_gxState.indTexMtxs[i];
|
||||
|
||||
Reference in New Issue
Block a user