diff --git a/hw/xbox/nv2a/pgraph/glsl/psh.c b/hw/xbox/nv2a/pgraph/glsl/psh.c index ff38a51106b..3fa7c98c6e8 100644 --- a/hw/xbox/nv2a/pgraph/glsl/psh.c +++ b/hw/xbox/nv2a/pgraph/glsl/psh.c @@ -707,12 +707,17 @@ static void apply_border_adjustment(const struct PixelShader *ps, MString *vars, static void apply_convolution_filter(const struct PixelShader *ps, MString *vars, int tex) { // FIXME: Quincunx + + g_autofree gchar *normalize_tex_coords = g_strdup_printf("norm%d", tex); + const char *tex_remap = ps->state.rect_tex[tex] ? normalize_tex_coords : ""; + mstring_append_fmt(vars, "vec4 t%d = vec4(0.0);\n" "for (int i = 0; i < 9; i++) {\n" - " vec3 texCoord = pT%d.xyw + vec3(convolution3x3[i] / (textureSize(texSamp%d, 0) * texScale%d), 0);\n" - " t%d += textureProj(texSamp%d, texCoord) * gaussian3x3[i];\n" - "}\n", tex, tex, tex, tex, tex, tex, tex); + " vec3 texCoordDelta = vec3(convolution3x3[i], 0);\n" + " texCoordDelta.xy /= textureSize(texSamp%d, 0);\n" + " t%d += textureProj(texSamp%d, %s(pT%d.xyw) + texCoordDelta) * gaussian3x3[i];\n" + "}\n", tex, tex, tex, tex, tex_remap, tex); } static MString* psh_convert(struct PixelShader *ps) @@ -884,16 +889,13 @@ static MString* psh_convert(struct PixelShader *ps) ps->code = mstring_new(); - for (i = 0; i < 4; i++) { - if (ps->state.rect_tex[i]) { - mstring_append_fmt(vars, "pT%d.xy /= textureSize(texSamp%d, 0) / texScale%d;\n", i, i, i); - } - } - for (i = 0; i < 4; i++) { const char *sampler_type = get_sampler_type(ps->tex_modes[i], &ps->state, i); + g_autofree gchar *normalize_tex_coords = g_strdup_printf("norm%d", i); + const char *tex_remap = ps->state.rect_tex[i] ? normalize_tex_coords : ""; + assert(ps->dot_map[i] < 8); const char *dotmap_func = dotmap_funcs[ps->dot_map[i]]; if (ps->dot_map[i] > 3) { @@ -914,8 +916,8 @@ static MString* psh_convert(struct PixelShader *ps) (ps->state.conv_tex[i] == CONVOLUTION_FILTER_QUINCUNX))) { apply_convolution_filter(ps, vars, i); } else { - mstring_append_fmt(vars, "vec4 t%d = textureProj(texSamp%d, pT%d.xyw);\n", - i, i, i); + mstring_append_fmt(vars, "vec4 t%d = textureProj(texSamp%d, %s(pT%d.xyw));\n", + i, i, tex_remap, i); } } break; @@ -964,8 +966,8 @@ static MString* psh_convert(struct PixelShader *ps) mstring_append_fmt(vars, "dsdt%d = bumpMat%d * dsdt%d;\n", i, i, i, i); - mstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, (pT%d.xy + dsdt%d));\n", - i, i, i, i); + mstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, %s(pT%d.xy + dsdt%d));\n", + i, i, tex_remap, i, i); break; case PS_TEXTUREMODES_BUMPENVMAP_LUM: assert(i >= 1); @@ -982,8 +984,8 @@ static MString* psh_convert(struct PixelShader *ps) mstring_append_fmt(vars, "dsdtl%d.st = bumpMat%d * dsdtl%d.st;\n", i, i, i, i); - mstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, (pT%d.xy + dsdtl%d.st));\n", - i, i, i, i); + mstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, %s(pT%d.xy + dsdtl%d.st));\n", + i, i, tex_remap, i, i); mstring_append_fmt(vars, "t%d = t%d * (bumpScale%d * dsdtl%d.p + bumpOffset%d);\n", i, i, i, i, i); break; @@ -1002,8 +1004,8 @@ static MString* psh_convert(struct PixelShader *ps) i, i, dotmap_func, ps->input_tex[i], i, i-1, i); apply_border_adjustment(ps, vars, i, "dotST%d"); - mstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, dotST%d);\n", - i, i, i); + mstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, %s(dotST%d));\n", + i, i, tex_remap, i); break; case PS_TEXTUREMODES_DOT_ZW: assert(i >= 2); @@ -1071,16 +1073,16 @@ static MString* psh_convert(struct PixelShader *ps) assert(!ps->state.rect_tex[i]); mstring_append_fmt(vars, "vec2 t%dAR = t%d.ar;\n", i, ps->input_tex[i]); apply_border_adjustment(ps, vars, i, "t%dAR"); - mstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, t%dAR);\n", - i, i, i); + mstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, %s(t%dAR));\n", + i, i, tex_remap, i); break; case PS_TEXTUREMODES_DPNDNT_GB: assert(i >= 1); assert(!ps->state.rect_tex[i]); mstring_append_fmt(vars, "vec2 t%dGB = t%d.gb;\n", i, ps->input_tex[i]); apply_border_adjustment(ps, vars, i, "t%dGB"); - mstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, t%dGB);\n", - i, i, i); + mstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, %s(t%dGB));\n", + i, i, tex_remap, i); break; case PS_TEXTUREMODES_DOTPRODUCT: assert(i == 1 || i == 2); @@ -1112,6 +1114,19 @@ static MString* psh_convert(struct PixelShader *ps) mstring_append_fmt(vars, "if (t%d.a == 0.0) { discard; };\n", i); } + + if (ps->state.rect_tex[i]) { + mstring_append_fmt(preflight, + "vec2 norm%d(vec2 coord) {\n" + " return coord / (textureSize(texSamp%d, 0) / texScale%d);\n" + "}\n", + i, i, i); + mstring_append_fmt(preflight, + "vec3 norm%d(vec3 coord) {\n" + " return vec3(norm%d(coord.xy), coord.z);\n" + "}\n", + i, i); + } } }