diff --git a/hw/xbox/nv2a/pgraph.c b/hw/xbox/nv2a/pgraph.c index 81aab293ba..86cdb6cba8 100644 --- a/hw/xbox/nv2a/pgraph.c +++ b/hw/xbox/nv2a/pgraph.c @@ -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); diff --git a/hw/xbox/nv2a/psh.c b/hw/xbox/nv2a/psh.c index e80a97d294..3049f0eb8a 100644 --- a/hw/xbox/nv2a/psh.c +++ b/hw/xbox/nv2a/psh.c @@ -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) diff --git a/hw/xbox/nv2a/psh.h b/hw/xbox/nv2a/psh.h index 449997a0c6..65ef4e43a2 100644 --- a/hw/xbox/nv2a/psh.h +++ b/hw/xbox/nv2a/psh.h @@ -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;