Skip to content

Commit

Permalink
nv2a: Implement ZCLIP_MIN,MAX with gl_ClipDistance
Browse files Browse the repository at this point in the history
  • Loading branch information
mborgerson committed Oct 22, 2023
1 parent 5fa08d2 commit b3fc80b
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 9 deletions.
9 changes: 7 additions & 2 deletions hw/xbox/nv2a/pgraph.c
Original file line number Diff line number Diff line change
Expand Up @@ -2945,6 +2945,10 @@ DEF_METHOD(NV097, SET_BEGIN_END)
glDisable(GL_CULL_FACE);
}

/* Clipping */
glEnable(GL_CLIP_DISTANCE0);
glEnable(GL_CLIP_DISTANCE1);

/* Front-face select */
glFrontFace(pg->regs[NV_PGRAPH_SETUPRASTER]
& NV_PGRAPH_SETUPRASTER_FRONTFACE
Expand Down Expand Up @@ -4179,7 +4183,6 @@ static void pgraph_shader_update_constants(PGRAPHState *pg,
*(float*)&pg->regs[NV_PGRAPH_FOGPARAM1]);
}

/* FIXME: Handle NV_PGRAPH_ZCLIPMIN, NV_PGRAPH_ZCLIPMAX */
float zmax;
switch (pg->surface_shape.zeta_format) {
case NV097_SET_SURFACE_FORMAT_ZETA_Z16:
Expand Down Expand Up @@ -4289,7 +4292,9 @@ static void pgraph_shader_update_constants(PGRAPHState *pg,
}

if (binding->clip_range_loc != -1) {
glUniform2f(binding->clip_range_loc, 0, zmax);
float zclip_min = *(float*)&pg->regs[NV_PGRAPH_ZCLIPMIN] / zmax * 2.0 - 1.0;
float zclip_max = *(float*)&pg->regs[NV_PGRAPH_ZCLIPMAX] / zmax * 2.0 - 1.0;
glUniform4f(binding->clip_range_loc, 0, zmax, zclip_min, zclip_max);
}

/* Clipping regions */
Expand Down
9 changes: 7 additions & 2 deletions hw/xbox/nv2a/shaders.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,8 @@ static MString* generate_geometry_shader(
"void emit_vertex(int index, int _unused) {\n"
" gl_Position = gl_in[index].gl_Position;\n"
" gl_PointSize = gl_in[index].gl_PointSize;\n"
" gl_ClipDistance[0] = gl_in[index].gl_ClipDistance[0];\n"
" gl_ClipDistance[1] = gl_in[index].gl_ClipDistance[1];\n"
" vtx_inv_w = v_vtx_inv_w[index];\n"
" vtx_inv_w_flat = v_vtx_inv_w[index];\n"
" vtxD0 = v_vtxD0[index];\n"
Expand All @@ -289,6 +291,8 @@ static MString* generate_geometry_shader(
"void emit_vertex(int index, int provoking_index) {\n"
" gl_Position = gl_in[index].gl_Position;\n"
" gl_PointSize = gl_in[index].gl_PointSize;\n"
" gl_ClipDistance[0] = gl_in[index].gl_ClipDistance[0];\n"
" gl_ClipDistance[1] = gl_in[index].gl_ClipDistance[1];\n"
" vtx_inv_w = v_vtx_inv_w[index];\n"
" vtx_inv_w_flat = v_vtx_inv_w[provoking_index];\n"
" vtxD0 = v_vtxD0[provoking_index];\n"
Expand Down Expand Up @@ -784,7 +788,7 @@ static MString *generate_vertex_shader(const ShaderState *state,
MString *header = mstring_from_str(
"#version 400\n"
"\n"
"uniform vec2 clipRange;\n"
"uniform vec4 clipRange;\n"
"uniform vec2 surfaceSize;\n"
"\n"
/* All constants in 1 array declaration */
Expand Down Expand Up @@ -864,7 +868,6 @@ GLSL_DEFINE(texMat3, GLSL_C_MAT4(NV_IGRAPH_XF_XFCTX_T3MAT))

if (state->fixed_function) {
generate_fixed_function(state, header, body);

} else if (state->vertex_program) {
vsh_translate(VSH_VERSION_XVS,
(uint32_t*)state->program_data,
Expand Down Expand Up @@ -973,6 +976,8 @@ GLSL_DEFINE(texMat3, GLSL_C_MAT4(NV_IGRAPH_XF_XFCTX_T3MAT))
" 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,
Expand Down
5 changes: 0 additions & 5 deletions hw/xbox/nv2a/vsh.c
Original file line number Diff line number Diff line change
Expand Up @@ -849,11 +849,6 @@ void vsh_translate(uint16_t version,
mstring_append(body, " oPos.z = oPos.w;\n");
}
mstring_append(body,
/* Map the clip range into clip space so z is clipped correctly.
* Note this makes the values in the depth buffer wrong. This should be
* handled with gl_ClipDistance instead, but that has performance issues
* on OS X.
*/
" if (clipRange.y != clipRange.x) {\n"
" oPos.z = (oPos.z - clipRange.x)/(0.5*(clipRange.y - clipRange.x)) - 1;\n"
" }\n"
Expand Down

0 comments on commit b3fc80b

Please sign in to comment.