nv2a: Handles depth borders in 3D bordered textures

3D textures with texture borders have 4 layers of border on either side of the
content layers in addition to the normal 4 pixel border per layer. This change
handles those extra depth layers in roughly the same way that the per-layer
border texels are handled.

Fixes #1171

[Test](https://github.com/abaire/nxdk_pgraph_tests/blob/main/src/tests/texture_border_tests.cpp)
[HW results](https://github.com/abaire/nxdk_pgraph_tests_golden_results/wiki/Results-Texture_border)
This commit is contained in:
Erik Abair 2022-07-07 18:11:40 -07:00 committed by mborgerson
parent 248fc788c1
commit c83b53e09d
3 changed files with 21 additions and 7 deletions

View File

@ -4568,6 +4568,7 @@ static void pgraph_bind_shaders(PGRAPHState *pg)
bool cubemap = GET_MASK(tex_fmt, NV_PGRAPH_TEXFMT0_CUBEMAPENABLE);
state.psh.border_logical_size[i][0] = 0.0f;
state.psh.border_logical_size[i][1] = 0.0f;
state.psh.border_logical_size[i][2] = 0.0f;
if (border_source != NV_PGRAPH_TEXFMT0_BORDER_SOURCE_COLOR) {
if (!f.linear && !cubemap) {
// The actual texture will be (at least) double the reported
@ -4577,8 +4578,13 @@ static void pgraph_bind_shaders(PGRAPHState *pg)
1 << GET_MASK(tex_fmt, NV_PGRAPH_TEXFMT0_BASE_SIZE_U);
unsigned int reported_height =
1 << GET_MASK(tex_fmt, NV_PGRAPH_TEXFMT0_BASE_SIZE_V);
unsigned int reported_depth =
1 << GET_MASK(tex_fmt, NV_PGRAPH_TEXFMT0_BASE_SIZE_P);
state.psh.border_logical_size[i][0] = reported_width;
state.psh.border_logical_size[i][1] = reported_height;
state.psh.border_logical_size[i][2] = reported_depth;
if (reported_width < 8) {
state.psh.border_inv_real_size[i][0] = 0.0625f;
} else {
@ -4591,6 +4597,12 @@ static void pgraph_bind_shaders(PGRAPHState *pg)
state.psh.border_inv_real_size[i][1] =
1.0f / (reported_height * 2.0f);
}
if (reported_depth < 8) {
state.psh.border_inv_real_size[i][2] = 0.0625f;
} else {
state.psh.border_inv_real_size[i][2] =
1.0f / (reported_depth * 2.0f);
}
} else {
NV2A_UNIMPLEMENTED("Border source texture with linear %d cubemap %d",
f.linear, cubemap);
@ -7214,10 +7226,12 @@ static void upload_gl_texture(GLenum gl_target,
unsigned int adjusted_width = s.width;
unsigned int adjusted_height = s.height;
unsigned int adjusted_pitch = s.pitch;
unsigned int adjusted_depth = s.depth;
if (!f.linear && s.border) {
adjusted_width = MAX(16, adjusted_width * 2);
adjusted_height = MAX(16, adjusted_height * 2);
adjusted_pitch = adjusted_width * (s.pitch / s.width);
adjusted_depth = MAX(16, s.depth * 2);
}
switch(gl_target) {
@ -7353,7 +7367,7 @@ static void upload_gl_texture(GLenum gl_target,
unsigned int width = adjusted_width;
unsigned int height = adjusted_height;
unsigned int depth = s.depth;
unsigned int depth = adjusted_depth;
assert(f.linear == false);

View File

@ -679,10 +679,10 @@ static void apply_border_adjustment(const struct PixelShader *ps, MString *vars,
mstring_append_fmt(
vars,
"vec2 t%dLogicalSize = vec2(%f, %f);\n"
"%s.xy = (%s.xy * t%dLogicalSize + vec2(4, 4)) * vec2(%f, %f);\n",
i, ps->state.border_logical_size[i][0], ps->state.border_logical_size[i][1],
var_name, var_name, i, ps->state.border_inv_real_size[i][0], ps->state.border_inv_real_size[i][1]);
"vec3 t%dLogicalSize = vec3(%f, %f, %f);\n"
"%s.xyz = (%s.xyz * t%dLogicalSize + vec3(4, 4, 4)) * vec3(%f, %f, %f);\n",
i, ps->state.border_logical_size[i][0], ps->state.border_logical_size[i][1], ps->state.border_logical_size[i][2],
var_name, var_name, i, ps->state.border_inv_real_size[i][0], ps->state.border_inv_real_size[i][1], ps->state.border_inv_real_size[i][2]);
}
static MString* psh_convert(struct PixelShader *ps)

View File

@ -68,8 +68,8 @@ typedef struct PshState {
bool alphakill[4];
enum ConvolutionFilter conv_tex[4];
float border_logical_size[4][2];
float border_inv_real_size[4][2];
float border_logical_size[4][3];
float border_inv_real_size[4][3];
bool shadow_map[4];
enum PshShadowDepthFunc shadow_depth_func;