Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

See through fix #7

Merged
merged 1 commit into from
Jan 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions hw/xbox/nv2a/pgraph/gl/shaders.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,9 @@ static ShaderBinding *generate_shaders(const ShaderState *state)
state->polygon_back_mode,
state->primitive_mode,
state->smooth_shading,
false);
false,
state->z_perspective
);
if (geometry_shader_code) {
const char* geometry_shader_code_str =
mstring_get_str(geometry_shader_code);
Expand All @@ -240,7 +242,7 @@ static ShaderBinding *generate_shaders(const ShaderState *state)
mstring_unref(vertex_shader_code);

/* generate a fragment shader from register combiners */
MString *fragment_shader_code = pgraph_gen_psh_glsl(state->psh);
MString *fragment_shader_code = pgraph_gen_psh_glsl(state->psh, state->z_perspective);
const char *fragment_shader_code_str =
mstring_get_str(fragment_shader_code);
GLuint fragment_shader = create_gl_shader(GL_FRAGMENT_SHADER,
Expand Down
6 changes: 3 additions & 3 deletions hw/xbox/nv2a/pgraph/glsl/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@
#include "common.h"


MString *pgraph_get_glsl_vtx_header(MString *out, bool location, bool smooth, bool in, bool prefix, bool array)
MString *pgraph_get_glsl_vtx_header(MString *out, bool location, bool smooth, bool in, bool prefix, bool array, bool z_perspective)
{
const char *flat_s = "flat";
const char *noperspective_s = "noperspective";
const char *noperspective_s = z_perspective ? "" : "noperspective";
const char *qualifier_s = smooth ? noperspective_s : flat_s;
const char *qualifiers[11] = {
noperspective_s, flat_s, qualifier_s, qualifier_s,
"noperspective", flat_s, qualifier_s, qualifier_s,
qualifier_s, qualifier_s, noperspective_s, noperspective_s,
noperspective_s, noperspective_s, noperspective_s
};
Expand Down
2 changes: 1 addition & 1 deletion hw/xbox/nv2a/pgraph/glsl/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@

#define GLSL_DEFINE(a, b) "#define " stringify(a) " " b "\n"

MString *pgraph_get_glsl_vtx_header(MString *out, bool location, bool smooth, bool in, bool prefix, bool array);
MString *pgraph_get_glsl_vtx_header(MString *out, bool location, bool smooth, bool in, bool prefix, bool array, bool z_perspective);

#endif
7 changes: 4 additions & 3 deletions hw/xbox/nv2a/pgraph/glsl/geom.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ MString *pgraph_gen_geom_glsl(enum ShaderPolygonMode polygon_front_mode,
enum ShaderPolygonMode polygon_back_mode,
enum ShaderPrimitiveMode primitive_mode,
bool smooth_shading,
bool vulkan)
bool vulkan,
bool z_perspective)
{
/* FIXME: Missing support for 2-sided-poly mode */
assert(polygon_front_mode == polygon_back_mode);
Expand Down Expand Up @@ -174,8 +175,8 @@ MString *pgraph_gen_geom_glsl(enum ShaderPolygonMode polygon_front_mode,
mstring_append(s, layout_in);
mstring_append(s, layout_out);
mstring_append(s, "\n");
pgraph_get_glsl_vtx_header(s, vulkan, smooth_shading, true, true, true);
pgraph_get_glsl_vtx_header(s, vulkan, smooth_shading, false, false, false);
pgraph_get_glsl_vtx_header(s, vulkan, smooth_shading, true, true, true, z_perspective);
pgraph_get_glsl_vtx_header(s, vulkan, smooth_shading, false, false, false, z_perspective);

if (smooth_shading) {
mstring_append(s,
Expand Down
3 changes: 2 additions & 1 deletion hw/xbox/nv2a/pgraph/glsl/geom.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ MString *pgraph_gen_geom_glsl(enum ShaderPolygonMode polygon_front_mode,
enum ShaderPolygonMode polygon_back_mode,
enum ShaderPrimitiveMode primitive_mode,
bool smooth_shading,
bool vulkan);
bool vulkan,
bool z_perspective);

#endif
62 changes: 43 additions & 19 deletions hw/xbox/nv2a/pgraph/glsl/psh.c
Original file line number Diff line number Diff line change
Expand Up @@ -726,15 +726,15 @@ static void apply_convolution_filter(const struct PixelShader *ps, MString *vars
"}\n", tex, tex, tex, tex, tex_remap, tex);
}

static MString* psh_convert(struct PixelShader *ps)
static MString *psh_convert(struct PixelShader *ps, bool z_perspective)
{
int i;

const char *u = ps->state.vulkan ? "" : "uniform "; // FIXME: Remove

MString *preflight = mstring_new();
pgraph_get_glsl_vtx_header(preflight, ps->state.vulkan,
ps->state.smooth_shading, true, false, false);
ps->state.smooth_shading, true, false, false, z_perspective);

if (ps->state.vulkan) {
mstring_append_fmt(preflight,
Expand All @@ -744,7 +744,11 @@ static MString* psh_convert(struct PixelShader *ps)
mstring_append_fmt(preflight,
"layout(location = 0) out vec4 fragColor;\n");
}

if (z_perspective) {
mstring_append_fmt(preflight,
"%svec4 clipRange;\n",
u);
}
mstring_append_fmt(preflight, "%sfloat alphaRef;\n"
"%svec4 fogColor;\n"
"%sivec4 clipRegion[8];\n",
Expand Down Expand Up @@ -865,26 +869,42 @@ static MString* psh_convert(struct PixelShader *ps)

/* calculate perspective-correct inputs */
MString *vars = mstring_new();
if (ps->state.smooth_shading) {
mstring_append(vars, "vec4 pD0 = vtxD0 / vtx_inv_w;\n");
mstring_append(vars, "vec4 pD1 = vtxD1 / vtx_inv_w;\n");
mstring_append(vars, "vec4 pB0 = vtxB0 / vtx_inv_w;\n");
mstring_append(vars, "vec4 pB1 = vtxB1 / vtx_inv_w;\n");
if (!z_perspective) {
if (ps->state.smooth_shading) {
mstring_append(vars, "vec4 pD0 = vtxD0 / vtx_inv_w;\n");
mstring_append(vars, "vec4 pD1 = vtxD1 / vtx_inv_w;\n");
mstring_append(vars, "vec4 pB0 = vtxB0 / vtx_inv_w;\n");
mstring_append(vars, "vec4 pB1 = vtxB1 / vtx_inv_w;\n");
} else {
mstring_append(vars, "vec4 pD0 = vtxD0 / vtx_inv_w_flat;\n");
mstring_append(vars, "vec4 pD1 = vtxD1 / vtx_inv_w_flat;\n");
mstring_append(vars, "vec4 pB0 = vtxB0 / vtx_inv_w_flat;\n");
mstring_append(vars, "vec4 pB1 = vtxB1 / vtx_inv_w_flat;\n");
}
mstring_append(vars, "vec4 pFog = vec4(fogColor.rgb, clamp(vtxFog / vtx_inv_w, 0.0, 1.0));\n");
mstring_append(vars, "vec4 pT0 = vtxT0 / vtx_inv_w;\n");
mstring_append(vars, "vec4 pT1 = vtxT1 / vtx_inv_w;\n");
mstring_append(vars, "vec4 pT2 = vtxT2 / vtx_inv_w;\n");
} else {
mstring_append(vars, "vec4 pD0 = vtxD0 / vtx_inv_w_flat;\n");
mstring_append(vars, "vec4 pD1 = vtxD1 / vtx_inv_w_flat;\n");
mstring_append(vars, "vec4 pB0 = vtxB0 / vtx_inv_w_flat;\n");
mstring_append(vars, "vec4 pB1 = vtxB1 / vtx_inv_w_flat;\n");
mstring_append(vars, "vec4 pD0 = vtxD0;\n");
mstring_append(vars, "vec4 pD1 = vtxD1;\n");
mstring_append(vars, "vec4 pB0 = vtxB0;\n");
mstring_append(vars, "vec4 pB1 = vtxB1;\n");
mstring_append(vars, "vec4 pFog = vec4(fogColor.rgb, clamp(vtxFog, 0.0, 1.0));\n");
mstring_append(vars, "vec4 pT0 = vtxT0;\n");
mstring_append(vars, "vec4 pT1 = vtxT1;\n");
mstring_append(vars, "vec4 pT2 = vtxT2;\n");
}
mstring_append(vars, "vec4 pFog = vec4(fogColor.rgb, clamp(vtxFog / vtx_inv_w, 0.0, 1.0));\n");
mstring_append(vars, "vec4 pT0 = vtxT0 / vtx_inv_w;\n");
mstring_append(vars, "vec4 pT1 = vtxT1 / vtx_inv_w;\n");
mstring_append(vars, "vec4 pT2 = vtxT2 / vtx_inv_w;\n");

if (ps->state.point_sprite) {
assert(!ps->state.rect_tex[3]);
mstring_append(vars, "vec4 pT3 = vec4(gl_PointCoord, 1.0, 1.0);\n");
} else {
mstring_append(vars, "vec4 pT3 = vtxT3 / vtx_inv_w;\n");
if (!z_perspective) {
mstring_append(vars, "vec4 pT3 = vtxT3 / vtx_inv_w;\n");
} else {
mstring_append(vars, "vec4 pT3 = vtxT3;\n");
}
}
mstring_append(vars, "\n");
mstring_append(vars, "vec4 v0 = pD0;\n");
Expand Down Expand Up @@ -1198,6 +1218,10 @@ static MString* psh_convert(struct PixelShader *ps)
}
}

if (z_perspective) {
mstring_append(ps->code, "gl_FragDepth = (1.0/gl_FragCoord.w)/clipRange.y;\n");
}

for (i = 0; i < ps->num_var_refs; i++) {
mstring_append_fmt(vars, "vec4 %s = vec4(0);\n", ps->var_refs[i]);
if (strcmp(ps->var_refs[i], "r0") == 0) {
Expand Down Expand Up @@ -1257,7 +1281,7 @@ static void parse_combiner_output(uint32_t value, struct OutputInfo *out)
out->cd_alphablue = flags & 0x40;
}

MString *pgraph_gen_psh_glsl(const PshState state)
MString *pgraph_gen_psh_glsl(const PshState state, bool z_perspective)
{
int i;
struct PixelShader ps;
Expand Down Expand Up @@ -1307,5 +1331,5 @@ MString *pgraph_gen_psh_glsl(const PshState state)
ps.final_input.inv_r0 = flags & PS_FINALCOMBINERSETTING_COMPLEMENT_R0;
}

return psh_convert(&ps);
return psh_convert(&ps, z_perspective);
}
2 changes: 1 addition & 1 deletion hw/xbox/nv2a/pgraph/glsl/psh.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@
#define PSH_UBO_BINDING 1
#define PSH_TEX_BINDING 2

MString *pgraph_gen_psh_glsl(const PshState state);
MString *pgraph_gen_psh_glsl(const PshState state, bool z_perspective);

#endif
19 changes: 11 additions & 8 deletions hw/xbox/nv2a/pgraph/glsl/vsh-prog.c
Original file line number Diff line number Diff line change
Expand Up @@ -831,11 +831,12 @@ void pgraph_gen_vsh_prog_glsl(uint16_t version,
* interpolation manually. OpenGL can't, since we give it a W of 1 to work
* around the perspective divide */
mstring_append(body,
" if (oPos.w == 0.0 || isinf(oPos.w)) {\n"
" vtx_inv_w = 1.0;\n"
" if (oPos.w < 0.0) {\n"
" oPos.w = clamp(oPos.w, -1.884467e+019, -5.421011e-20);\n"
" } else {\n"
" vtx_inv_w = 1.0 / oPos.w;\n"
" oPos.w = clamp(oPos.w, 5.421011e-20, 1.884467e+019);\n"
" }\n"
" vtx_inv_w = 1.0 / oPos.w;\n"
" vtx_inv_w_flat = vtx_inv_w;\n"
);

Expand All @@ -855,10 +856,6 @@ void pgraph_gen_vsh_prog_glsl(uint16_t version,
"/ surfaceSize.y;\n");
}

if (z_perspective) {
mstring_append(body, " oPos.z = oPos.w;\n");
}

mstring_append(body,
" if (clipRange.y != clipRange.x) {\n");
if (vulkan) {
Expand All @@ -870,6 +867,12 @@ void pgraph_gen_vsh_prog_glsl(uint16_t version,
}
mstring_append(body,
" }\n"
);
if(z_perspective) {
mstring_append(body, " oPos.xyz *= oPos.w;\n");
} else {
mstring_append(
body,

/* Correct for the perspective divide */
" if (oPos.w < 0.0) {\n"
Expand All @@ -882,5 +885,5 @@ void pgraph_gen_vsh_prog_glsl(uint16_t version,
" oPos.w = 1.0;\n"
" }\n"
);

}
}
67 changes: 44 additions & 23 deletions hw/xbox/nv2a/pgraph/glsl/vsh.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ MString *pgraph_gen_vsh_glsl(const ShaderState *state, bool prefix_outputs)
"}\n");

pgraph_get_glsl_vtx_header(header, state->vulkan, state->smooth_shading,
false, prefix_outputs, false);
false, prefix_outputs, false, state->z_perspective);

if (prefix_outputs) {
mstring_append(header,
Expand Down Expand Up @@ -233,28 +233,49 @@ MString *pgraph_gen_vsh_glsl(const ShaderState *state, bool prefix_outputs)
}

/* Set outputs */
const char *shade_model_mult = state->smooth_shading ? "vtx_inv_w" : "vtx_inv_w_flat";
mstring_append_fmt(body, "\n"
" vtxD0 = clamp(oD0, 0.0, 1.0) * %s;\n"
" vtxD1 = clamp(oD1, 0.0, 1.0) * %s;\n"
" vtxB0 = clamp(oB0, 0.0, 1.0) * %s;\n"
" vtxB1 = clamp(oB1, 0.0, 1.0) * %s;\n"
" vtxFog = oFog.x * vtx_inv_w;\n"
" vtxT0 = oT0 * vtx_inv_w;\n"
" vtxT1 = oT1 * vtx_inv_w;\n"
" vtxT2 = oT2 * vtx_inv_w;\n"
" vtxT3 = oT3 * vtx_inv_w;\n"
" gl_Position = oPos;\n"
" gl_PointSize = oPts.x;\n"
// " gl_ClipDistance[0] = oPos.z - oPos.w*clipRange.z;\n" // Near
// " gl_ClipDistance[1] = oPos.w*clipRange.w - oPos.z;\n" // Far
"\n"
"}\n",
shade_model_mult,
shade_model_mult,
shade_model_mult,
shade_model_mult);

if (state->z_perspective == false) {
const char *shade_model_mult = state->smooth_shading ? "vtx_inv_w" : "vtx_inv_w_flat";
mstring_append_fmt(body, "\n"
" vtxD0 = clamp(oD0, 0.0, 1.0) * %s;\n"
" vtxD1 = clamp(oD1, 0.0, 1.0) * %s;\n"
" vtxB0 = clamp(oB0, 0.0, 1.0) * %s;\n"
" vtxB1 = clamp(oB1, 0.0, 1.0) * %s;\n"
" vtxFog = oFog.x * vtx_inv_w;\n"
" vtxT0 = oT0 * vtx_inv_w;\n"
" vtxT1 = oT1 * vtx_inv_w;\n"
" vtxT2 = oT2 * vtx_inv_w;\n"
" vtxT3 = oT3 * vtx_inv_w;\n"
" gl_Position = oPos;\n"
" gl_PointSize = oPts.x;\n"
// " gl_ClipDistance[0] = oPos.z - oPos.w*clipRange.z;\n" // Near
// " gl_ClipDistance[1] = oPos.w*clipRange.w - oPos.z;\n" // Far
"\n"
"}\n",
shade_model_mult,
shade_model_mult,
shade_model_mult,
shade_model_mult
);
} else {
mstring_append_fmt(
body, "\n"
" vtxD0 = clamp(oD0, 0.0, 1.0);\n"
" vtxD1 = clamp(oD1, 0.0, 1.0);\n"
" vtxB0 = clamp(oB0, 0.0, 1.0);\n"
" vtxB1 = clamp(oB1, 0.0, 1.0);\n"
" vtxFog = oFog.x;\n"
" vtxT0 = oT0;\n"
" vtxT1 = oT1;\n"
" vtxT2 = oT2;\n"
" vtxT3 = oT3;\n"
" gl_Position = oPos;\n"
" gl_PointSize = oPts.x;\n"
//" gl_ClipDistance[0] = oPos.w - clipRange.z;\n" // Near
//" gl_ClipDistance[1] = clipRange.w - oPos.w;\n" // Far
"\n"
"}\n"
);
}
/* Return combined header + source */
if (state->vulkan) {
// FIXME: Optimize uniforms
Expand Down
1 change: 1 addition & 0 deletions hw/xbox/nv2a/pgraph/vk/renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ typedef struct ShaderBinding {

int surface_size_loc;
int clip_range_loc;
int clip_range_loc_frag;

int vsh_constant_loc;
uint32_t vsh_constants[NV2A_VERTEXSHADER_CONSTANTS][4];
Expand Down
24 changes: 16 additions & 8 deletions hw/xbox/nv2a/pgraph/vk/shaders.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,9 @@ static void update_shader_constant_locations(ShaderBinding *binding)

binding->uniform_attrs_loc =
uniform_index(&binding->vertex->uniforms, "inlineValue");

binding->clip_range_loc_frag =
uniform_index(&binding->fragment->uniforms, "clipRange");
}

static void shader_cache_entry_init(Lru *lru, LruNode *node, void *state)
Expand Down Expand Up @@ -393,7 +396,7 @@ static ShaderBinding *gen_shaders(PGRAPHState *pg, ShaderState *state)

MString *geometry_shader_code = pgraph_gen_geom_glsl(
state->polygon_front_mode, state->polygon_back_mode,
state->primitive_mode, state->smooth_shading, true);
state->primitive_mode, state->smooth_shading, true, state->z_perspective);
if (geometry_shader_code) {
NV2A_VK_DPRINTF("geometry shader: \n%s",
mstring_get_str(geometry_shader_code));
Expand All @@ -414,7 +417,7 @@ static ShaderBinding *gen_shaders(PGRAPHState *pg, ShaderState *state)
mstring_get_str(vertex_shader_code));
mstring_unref(vertex_shader_code);

MString *fragment_shader_code = pgraph_gen_psh_glsl(state->psh);
MString *fragment_shader_code = pgraph_gen_psh_glsl(state->psh, state->z_perspective);
NV2A_VK_DPRINTF("fragment shader: \n%s",
mstring_get_str(fragment_shader_code));
snode->fragment = pgraph_vk_create_shader_module_from_glsl(
Expand Down Expand Up @@ -640,16 +643,21 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding,
pg->surface_binding_dim.height / aa_height);
}

if (binding->clip_range_loc != -1) {
uint32_t v[2];
v[0] = pgraph_reg_r(pg, NV_PGRAPH_ZCLIPMIN);
v[1] = pgraph_reg_r(pg, NV_PGRAPH_ZCLIPMAX);
float zclip_min = *(float *)&v[0] / zmax * 2.0 - 1.0;
float zclip_max = *(float *)&v[1] / zmax * 2.0 - 1.0;
uint32_t v[2];
v[0] = pgraph_reg_r(pg, NV_PGRAPH_ZCLIPMIN);
v[1] = pgraph_reg_r(pg, NV_PGRAPH_ZCLIPMAX);
float zclip_min = *(float *)&v[0] / zmax * 2.0 - 1.0;
float zclip_max = *(float *)&v[1] / zmax * 2.0 - 1.0;

if (binding->clip_range_loc != -1) {
uniform4f(&binding->vertex->uniforms, binding->clip_range_loc, 0,
zmax, zclip_min, zclip_max);
}

if (binding->clip_range_loc_frag != -1) {
uniform4f(&binding->fragment->uniforms, binding->clip_range_loc_frag, 0,
zmax, zclip_min, zclip_max);
}
/* Clipping regions */
unsigned int max_gl_width = pg->surface_binding_dim.width;
unsigned int max_gl_height = pg->surface_binding_dim.height;
Expand Down
Loading