Skip to content

Commit

Permalink
Merge pull request #7 from polymetal0/master
Browse files Browse the repository at this point in the history
See through fix
  • Loading branch information
backgamon authored Jan 1, 2025
2 parents 8f478e0 + cac29ed commit 6420210
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 69 deletions.
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

0 comments on commit 6420210

Please sign in to comment.