mirror of https://github.com/xemu-project/xemu.git
nv2a: Fix polygon line mode and implement flat shading provoking vertex
Xbox draws lines in polygon mode without trying to avoid overlaps, e.g. internal edge lines are drawn twice for triangle strips and fans. This is evidenced by using additive blending and also stencil adds. This commit removes the gl_PrimitiveIDIn==0 checks which were there to avoid drawing lines twice. This commit also implements flat shading first/last provoking vertex handling. This fixes triangle strip and fan flat shading in nxdk_pgraph_tests shade model tests.
This commit is contained in:
parent
e21af7a8f2
commit
e96663669e
|
@ -471,6 +471,9 @@
|
|||
# define NV_PGRAPH_CONTROL_2_STENCIL_OP_V_INCR 7
|
||||
# define NV_PGRAPH_CONTROL_2_STENCIL_OP_V_DECR 8
|
||||
#define NV_PGRAPH_CONTROL_3 0x00001958
|
||||
# define NV_PGRAPH_CONTROL_3_PROVOKING_VERTEX (1 << 0)
|
||||
# define NV_PGRAPH_CONTROL_3_PROVOKING_VERTEX_LAST 0
|
||||
# define NV_PGRAPH_CONTROL_3_PROVOKING_VERTEX_FIRST 1
|
||||
# define NV_PGRAPH_CONTROL_3_SHADEMODE (1 << 7)
|
||||
# define NV_PGRAPH_CONTROL_3_SHADEMODE_FLAT 0
|
||||
# define NV_PGRAPH_CONTROL_3_SHADEMODE_SMOOTH 1
|
||||
|
@ -1062,6 +1065,9 @@
|
|||
# define NV097_SET_TEXGEN_VIEW_MODEL_INFINITE_VIEWER 1
|
||||
# define NV097_SET_FOG_PLANE 0x000009D0
|
||||
# define NV097_SET_SPECULAR_PARAMS 0x000009E0
|
||||
# define NV097_SET_PROVOKING_VERTEX 0x000009FC
|
||||
# define NV097_SET_PROVOKING_VERTEX_LAST 0
|
||||
# define NV097_SET_PROVOKING_VERTEX_FIRST 1
|
||||
# define NV097_SET_SCENE_AMBIENT_COLOR 0x00000A10
|
||||
# define NV097_SET_VIEWPORT_OFFSET 0x00000A20
|
||||
# define NV097_SET_POINT_PARAMS 0x00000A30
|
||||
|
|
|
@ -38,6 +38,11 @@ void pgraph_glsl_set_geom_state(PGRAPHState *pg, GeomState *state)
|
|||
NV_PGRAPH_CONTROL_3_SHADEMODE) ==
|
||||
NV_PGRAPH_CONTROL_3_SHADEMODE_SMOOTH;
|
||||
|
||||
state->first_vertex_is_provoking =
|
||||
GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CONTROL_3),
|
||||
NV_PGRAPH_CONTROL_3_PROVOKING_VERTEX) ==
|
||||
NV_PGRAPH_CONTROL_3_PROVOKING_VERTEX_FIRST;
|
||||
|
||||
state->z_perspective = pgraph_reg_r(pg, NV_PGRAPH_CONTROL_0) &
|
||||
NV_PGRAPH_CONTROL_0_Z_PERSPECTIVE_ENABLE;
|
||||
}
|
||||
|
@ -83,67 +88,51 @@ MString *pgraph_glsl_gen_geom(const GeomState *state, GenGeomGlslOptions opts)
|
|||
const char *layout_in = NULL;
|
||||
const char *layout_out = NULL;
|
||||
const char *body = NULL;
|
||||
const char *provoking_index = "0";
|
||||
|
||||
/* TODO: frontface/backface culling for polygon modes POLY_MODE_LINE and
|
||||
* POLY_MODE_POINT.
|
||||
* FIXME: OpenGL/Vulkan does not specify absolute vertex order when input
|
||||
* is a triangle list, triangle strip or fan. Only vertex winding order
|
||||
* is specified. Currently we assume input triangle vertex order follows
|
||||
* the last provoking vertex convention.
|
||||
*/
|
||||
switch (state->primitive_mode) {
|
||||
case PRIM_TYPE_POINTS: return NULL;
|
||||
case PRIM_TYPE_LINES:
|
||||
case PRIM_TYPE_LINE_LOOP:
|
||||
case PRIM_TYPE_LINE_STRIP:
|
||||
provoking_index = state->first_vertex_is_provoking ? "0" : "1";
|
||||
need_linez = true;
|
||||
layout_in = "layout(lines) in;\n";
|
||||
layout_out = "layout(line_strip, max_vertices = 2) out;\n";
|
||||
body = " mat4 pz = calc_linez(0, 1);\n"
|
||||
" emit_vertex(0, 0, pz);\n"
|
||||
" emit_vertex(1, 1, pz);\n"
|
||||
" emit_vertex(0, pz);\n"
|
||||
" emit_vertex(1, pz);\n"
|
||||
" EndPrimitive();\n";
|
||||
break;
|
||||
case PRIM_TYPE_TRIANGLES:
|
||||
need_triz = true;
|
||||
layout_in = "layout(triangles) in;\n";
|
||||
if (polygon_mode == POLY_MODE_FILL) {
|
||||
layout_out = "layout(triangle_strip, max_vertices = 3) out;\n";
|
||||
body = " mat4 pz = calc_triz(0, 1, 2);\n"
|
||||
" emit_vertex(0, 0, pz);\n"
|
||||
" emit_vertex(1, 1, pz);\n"
|
||||
" emit_vertex(2, 2, pz);\n"
|
||||
" EndPrimitive();\n";
|
||||
} else if (polygon_mode == POLY_MODE_LINE) {
|
||||
need_linez = true;
|
||||
layout_out = "layout(line_strip, max_vertices = 4) out;\n";
|
||||
body = " float triMZ = calc_triz(0, 1, 2)[3].x;\n"
|
||||
" mat4 pz1 = calc_linez(0, 1);\n"
|
||||
" pz1[3].x = triMZ;\n"
|
||||
" mat4 pz2 = calc_linez(1, 2);\n"
|
||||
" pz2[3].x = triMZ;\n"
|
||||
" mat4 pz3 = calc_linez(2, 0);\n"
|
||||
" pz3[3].x = triMZ;\n"
|
||||
" emit_vertex(0, 0, pz1);\n"
|
||||
" emit_vertex(1, 0, pz1);\n"
|
||||
" emit_vertex(2, 0, pz2);\n"
|
||||
" emit_vertex(0, 0, pz3);\n"
|
||||
" EndPrimitive();\n";
|
||||
} else {
|
||||
assert(polygon_mode == POLY_MODE_POINT);
|
||||
layout_out = "layout(points, max_vertices = 3) out;\n";
|
||||
body = " mat4 pz = calc_triz(0, 1, 2);\n"
|
||||
" emit_vertex(0, 0, mat4(pz[0], pz[0], pz[0], pz[3]));\n"
|
||||
" EndPrimitive();\n"
|
||||
" emit_vertex(1, 0, mat4(pz[1], pz[1], pz[1], pz[3]));\n"
|
||||
" EndPrimitive();\n"
|
||||
" emit_vertex(2, 0, mat4(pz[2], pz[2], pz[2], pz[3]));\n"
|
||||
" EndPrimitive();\n";
|
||||
}
|
||||
break;
|
||||
case PRIM_TYPE_TRIANGLE_STRIP:
|
||||
case PRIM_TYPE_TRIANGLE_FAN:
|
||||
if (state->first_vertex_is_provoking) {
|
||||
if (state->primitive_mode == PRIM_TYPE_TRIANGLE_STRIP) {
|
||||
provoking_index = "gl_PrimitiveIDIn & 1";
|
||||
} else if (state->primitive_mode == PRIM_TYPE_TRIANGLE_FAN) {
|
||||
provoking_index = "1";
|
||||
} else {
|
||||
provoking_index = "0";
|
||||
}
|
||||
} else {
|
||||
provoking_index = "2";
|
||||
}
|
||||
need_triz = true;
|
||||
layout_in = "layout(triangles) in;\n";
|
||||
if (polygon_mode == POLY_MODE_FILL) {
|
||||
layout_out = "layout(triangle_strip, max_vertices = 3) out;\n";
|
||||
body = " mat4 pz = calc_triz(0, 1, 2);\n"
|
||||
" emit_vertex(0, 0, pz);\n"
|
||||
" emit_vertex(1, 1, pz);\n"
|
||||
" emit_vertex(2, 2, pz);\n"
|
||||
" emit_vertex(0, pz);\n"
|
||||
" emit_vertex(1, pz);\n"
|
||||
" emit_vertex(2, pz);\n"
|
||||
" EndPrimitive();\n";
|
||||
} else if (polygon_mode == POLY_MODE_LINE) {
|
||||
need_linez = true;
|
||||
|
@ -155,31 +144,37 @@ MString *pgraph_glsl_gen_geom(const GeomState *state, GenGeomGlslOptions opts)
|
|||
" pz2[3].x = triMZ;\n"
|
||||
" mat4 pz3 = calc_linez(2, 0);\n"
|
||||
" pz3[3].x = triMZ;\n"
|
||||
" if (gl_PrimitiveIDIn == 0) {\n"
|
||||
" emit_vertex(0, 0, pz1);\n"
|
||||
" }\n"
|
||||
" emit_vertex(1, 0, pz1);\n"
|
||||
" emit_vertex(2, 0, pz2);\n"
|
||||
" emit_vertex(0, 0, pz3);\n"
|
||||
" emit_vertex(0, pz1);\n"
|
||||
" emit_vertex(1, pz1);\n"
|
||||
" emit_vertex(2, pz2);\n"
|
||||
" emit_vertex(0, pz3);\n"
|
||||
" EndPrimitive();\n";
|
||||
} else {
|
||||
assert(polygon_mode == POLY_MODE_POINT);
|
||||
layout_out = "layout(points, max_vertices = 3) out;\n";
|
||||
body = " mat4 pz = calc_triz(0, 1, 2);\n"
|
||||
" if (gl_PrimitiveIDIn == 0) {\n"
|
||||
" emit_vertex(0, 0, mat4(pz[0], pz[0], pz[0], pz[3]));\n"
|
||||
" EndPrimitive();\n"
|
||||
" emit_vertex(1, 0, mat4(pz[1], pz[1], pz[1], pz[3]));\n"
|
||||
" EndPrimitive();\n"
|
||||
" }\n"
|
||||
" emit_vertex(2, 0, mat4(pz[2], pz[2], pz[2], pz[3]));\n"
|
||||
" emit_vertex(0, mat4(pz[0], pz[0], pz[0], pz[3]));\n"
|
||||
" EndPrimitive();\n"
|
||||
" emit_vertex(1, mat4(pz[1], pz[1], pz[1], pz[3]));\n"
|
||||
" EndPrimitive();\n"
|
||||
" emit_vertex(2, mat4(pz[2], pz[2], pz[2], pz[3]));\n"
|
||||
" EndPrimitive();\n";
|
||||
}
|
||||
break;
|
||||
case PRIM_TYPE_QUADS:
|
||||
provoking_index = "3";
|
||||
need_quadz = true;
|
||||
layout_in = "layout(lines_adjacency) in;\n";
|
||||
if (polygon_mode == POLY_MODE_LINE) {
|
||||
if (polygon_mode == POLY_MODE_FILL) {
|
||||
layout_out = "layout(triangle_strip, max_vertices = 4) out;\n";
|
||||
body = " mat4 pz, pz2;\n"
|
||||
" calc_quadz(0, 1, 2, 3, pz, pz2);\n"
|
||||
" emit_vertex(1, pz);\n"
|
||||
" emit_vertex(2, pz2);\n"
|
||||
" emit_vertex(0, pz);\n"
|
||||
" emit_vertex(3, pz2);\n"
|
||||
" EndPrimitive();\n";
|
||||
} else if (polygon_mode == POLY_MODE_LINE) {
|
||||
need_linez = true;
|
||||
layout_out = "layout(line_strip, max_vertices = 5) out;\n";
|
||||
body = " mat4 pz, pzs;\n"
|
||||
|
@ -192,40 +187,42 @@ MString *pgraph_glsl_gen_geom(const GeomState *state, GenGeomGlslOptions opts)
|
|||
" pz3[3].x = pzs[3].x;\n"
|
||||
" mat4 pz4 = calc_linez(3, 0);\n"
|
||||
" pz4[3].x = pzs[3].x;\n"
|
||||
" emit_vertex(0, 3, pz1);\n"
|
||||
" emit_vertex(1, 3, pz1);\n"
|
||||
" emit_vertex(2, 3, pz2);\n"
|
||||
" emit_vertex(3, 3, pz3);\n"
|
||||
" emit_vertex(0, 3, pz4);\n"
|
||||
" EndPrimitive();\n";
|
||||
} else if (polygon_mode == POLY_MODE_FILL) {
|
||||
layout_out = "layout(triangle_strip, max_vertices = 4) out;\n";
|
||||
body = " mat4 pz, pz2;\n"
|
||||
" calc_quadz(0, 1, 2, 3, pz, pz2);\n"
|
||||
" emit_vertex(1, 3, pz);\n"
|
||||
" emit_vertex(2, 3, pz2);\n"
|
||||
" emit_vertex(0, 3, pz);\n"
|
||||
" emit_vertex(3, 3, pz2);\n"
|
||||
" emit_vertex(0, pz1);\n"
|
||||
" emit_vertex(1, pz1);\n"
|
||||
" emit_vertex(2, pz2);\n"
|
||||
" emit_vertex(3, pz3);\n"
|
||||
" emit_vertex(0, pz4);\n"
|
||||
" EndPrimitive();\n";
|
||||
} else {
|
||||
assert(polygon_mode == POLY_MODE_POINT);
|
||||
layout_out = "layout(points, max_vertices = 4) out;\n";
|
||||
body = " mat4 pz, pz2;\n"
|
||||
" calc_quadz(0, 1, 2, 3, pz, pz2);\n"
|
||||
" emit_vertex(0, 3, mat4(pz[0], pz[0], pz[0], pz[3]));\n"
|
||||
" emit_vertex(0, mat4(pz[0], pz[0], pz[0], pz[3]));\n"
|
||||
" EndPrimitive();\n"
|
||||
" emit_vertex(1, 3, mat4(pz[1], pz[1], pz[1], pz[3]));\n"
|
||||
" emit_vertex(1, mat4(pz[1], pz[1], pz[1], pz[3]));\n"
|
||||
" EndPrimitive();\n"
|
||||
" emit_vertex(2, 3, mat4(pz[2], pz[2], pz[2], pz[3]));\n"
|
||||
" emit_vertex(2, mat4(pz[2], pz[2], pz[2], pz[3]));\n"
|
||||
" EndPrimitive();\n"
|
||||
" emit_vertex(3, 3, mat4(pz2[2], pz2[2], pz2[2], pz2[3]));\n"
|
||||
" emit_vertex(3, mat4(pz2[2], pz2[2], pz2[2], pz2[3]));\n"
|
||||
" EndPrimitive();\n";
|
||||
}
|
||||
break;
|
||||
case PRIM_TYPE_QUAD_STRIP:
|
||||
provoking_index = "3";
|
||||
need_quadz = true;
|
||||
layout_in = "layout(lines_adjacency) in;\n";
|
||||
if (polygon_mode == POLY_MODE_LINE) {
|
||||
if (polygon_mode == POLY_MODE_FILL) {
|
||||
layout_out = "layout(triangle_strip, max_vertices = 4) out;\n";
|
||||
body = " if ((gl_PrimitiveIDIn & 1) != 0) { return; }\n"
|
||||
" mat4 pz, pz2;\n"
|
||||
" calc_quadz(2, 0, 1, 3, pz, pz2);\n"
|
||||
" emit_vertex(0, pz);\n"
|
||||
" emit_vertex(1, pz2);\n"
|
||||
" emit_vertex(2, pz);\n"
|
||||
" emit_vertex(3, pz2);\n"
|
||||
" EndPrimitive();\n";
|
||||
} else if (polygon_mode == POLY_MODE_LINE) {
|
||||
need_linez = true;
|
||||
layout_out = "layout(line_strip, max_vertices = 5) out;\n";
|
||||
body = " if ((gl_PrimitiveIDIn & 1) != 0) { return; }\n"
|
||||
|
@ -239,23 +236,11 @@ MString *pgraph_glsl_gen_geom(const GeomState *state, GenGeomGlslOptions opts)
|
|||
" pz3[3].x = pzs[3].x;\n"
|
||||
" mat4 pz4 = calc_linez(2, 0);\n"
|
||||
" pz4[3].x = pz[3].x;\n"
|
||||
" if (gl_PrimitiveIDIn == 0) {\n"
|
||||
" emit_vertex(0, 3, pz1);\n"
|
||||
" }\n"
|
||||
" emit_vertex(1, 3, pz1);\n"
|
||||
" emit_vertex(3, 3, pz2);\n"
|
||||
" emit_vertex(2, 3, pz3);\n"
|
||||
" emit_vertex(0, 3, pz4);\n"
|
||||
" EndPrimitive();\n";
|
||||
} else if (polygon_mode == POLY_MODE_FILL) {
|
||||
layout_out = "layout(triangle_strip, max_vertices = 4) out;\n";
|
||||
body = " if ((gl_PrimitiveIDIn & 1) != 0) { return; }\n"
|
||||
" mat4 pz, pz2;\n"
|
||||
" calc_quadz(2, 0, 1, 3, pz, pz2);\n"
|
||||
" emit_vertex(0, 3, pz);\n"
|
||||
" emit_vertex(1, 3, pz2);\n"
|
||||
" emit_vertex(2, 3, pz);\n"
|
||||
" emit_vertex(3, 3, pz2);\n"
|
||||
" emit_vertex(0, pz1);\n"
|
||||
" emit_vertex(1, pz1);\n"
|
||||
" emit_vertex(3, pz2);\n"
|
||||
" emit_vertex(2, pz3);\n"
|
||||
" emit_vertex(0, pz4);\n"
|
||||
" EndPrimitive();\n";
|
||||
} else {
|
||||
assert(polygon_mode == POLY_MODE_POINT);
|
||||
|
@ -263,39 +248,39 @@ MString *pgraph_glsl_gen_geom(const GeomState *state, GenGeomGlslOptions opts)
|
|||
body = " if ((gl_PrimitiveIDIn & 1) != 0) { return; }\n"
|
||||
" mat4 pz, pz2;\n"
|
||||
" calc_quadz(2, 0, 1, 3, pz, pz2);\n"
|
||||
" if (gl_PrimitiveIDIn == 0) {\n"
|
||||
" emit_vertex(0, 3, mat4(pz[1], pz[1], pz[1], pz[3]));\n"
|
||||
" EndPrimitive();\n"
|
||||
" emit_vertex(1, 3, mat4(pz[2], pz[2], pz[2], pz[3]));\n"
|
||||
" EndPrimitive();\n"
|
||||
" }\n"
|
||||
" emit_vertex(2, 3, mat4(pz[0], pz[0], pz[0], pz[3]));\n"
|
||||
" emit_vertex(0, mat4(pz[1], pz[1], pz[1], pz[3]));\n"
|
||||
" EndPrimitive();\n"
|
||||
" emit_vertex(3, 3, mat4(pz2[2], pz2[2], pz2[2], pz2[3]));\n"
|
||||
" emit_vertex(1, mat4(pz[2], pz[2], pz[2], pz[3]));\n"
|
||||
" EndPrimitive();\n"
|
||||
" emit_vertex(2, mat4(pz[0], pz[0], pz[0], pz[3]));\n"
|
||||
" EndPrimitive();\n"
|
||||
" emit_vertex(3, mat4(pz2[2], pz2[2], pz2[2], pz2[3]));\n"
|
||||
" EndPrimitive();\n";
|
||||
}
|
||||
break;
|
||||
case PRIM_TYPE_POLYGON:
|
||||
provoking_index = "0";
|
||||
if (polygon_mode == POLY_MODE_FILL) {
|
||||
need_triz = true;
|
||||
layout_in = "layout(triangles) in;\n";
|
||||
layout_out = "layout(triangle_strip, max_vertices = 3) out;\n";
|
||||
body = " mat4 pz = calc_triz(0, 1, 2);\n"
|
||||
" emit_vertex(0, 0, pz);\n"
|
||||
" emit_vertex(1, 0, pz);\n"
|
||||
" emit_vertex(2, 0, pz);\n"
|
||||
" emit_vertex(0, pz);\n"
|
||||
" emit_vertex(1, pz);\n"
|
||||
" emit_vertex(2, pz);\n"
|
||||
" EndPrimitive();\n";
|
||||
} else if (polygon_mode == POLY_MODE_LINE) {
|
||||
need_linez = true;
|
||||
// FIXME: input here is lines and not triangles so we cannot
|
||||
// calculate triangle plane slope. Also, the first vertex of the
|
||||
// polygon is unavailable so flat shading provoking vertex is
|
||||
// wrong.
|
||||
/* FIXME: input here is lines and not triangles so we cannot
|
||||
* calculate triangle plane slope. Also, the first vertex of the
|
||||
* polygon is unavailable so flat shading provoking vertex is
|
||||
* wrong.
|
||||
*/
|
||||
layout_in = "layout(lines) in;\n";
|
||||
layout_out = "layout(line_strip, max_vertices = 2) out;\n";
|
||||
body = " mat4 pz = calc_linez(0, 1);\n"
|
||||
" emit_vertex(0, 0, pz);\n"
|
||||
" emit_vertex(1, 1, pz);\n"
|
||||
" emit_vertex(0, pz);\n"
|
||||
" emit_vertex(1, pz);\n"
|
||||
" EndPrimitive();\n";
|
||||
} else {
|
||||
assert(false);
|
||||
|
@ -326,49 +311,34 @@ MString *pgraph_glsl_gen_geom(const GeomState *state, GenGeomGlslOptions opts)
|
|||
false, false, false);
|
||||
|
||||
if (state->smooth_shading) {
|
||||
mstring_append(
|
||||
output,
|
||||
"void emit_vertex(int index, int _unused, mat4 pz) {\n"
|
||||
" gl_Position = gl_in[index].gl_Position;\n"
|
||||
" gl_PointSize = gl_in[index].gl_PointSize;\n"
|
||||
" vtxD0 = v_vtxD0[index];\n"
|
||||
" vtxD1 = v_vtxD1[index];\n"
|
||||
" vtxB0 = v_vtxB0[index];\n"
|
||||
" vtxB1 = v_vtxB1[index];\n"
|
||||
" vtxFog = v_vtxFog[index];\n"
|
||||
" vtxT0 = v_vtxT0[index];\n"
|
||||
" vtxT1 = v_vtxT1[index];\n"
|
||||
" vtxT2 = v_vtxT2[index];\n"
|
||||
" vtxT3 = v_vtxT3[index];\n"
|
||||
" vtxPos0 = pz[0];\n"
|
||||
" vtxPos1 = pz[1];\n"
|
||||
" vtxPos2 = pz[2];\n"
|
||||
" triMZ = (isnan(pz[3].x) || isinf(pz[3].x)) ? 0.0 : pz[3].x;\n"
|
||||
" EmitVertex();\n"
|
||||
"}\n");
|
||||
} else {
|
||||
mstring_append(
|
||||
output,
|
||||
"void emit_vertex(int index, int provoking_index, mat4 pz) {\n"
|
||||
" gl_Position = gl_in[index].gl_Position;\n"
|
||||
" gl_PointSize = gl_in[index].gl_PointSize;\n"
|
||||
" vtxD0 = v_vtxD0[provoking_index];\n"
|
||||
" vtxD1 = v_vtxD1[provoking_index];\n"
|
||||
" vtxB0 = v_vtxB0[provoking_index];\n"
|
||||
" vtxB1 = v_vtxB1[provoking_index];\n"
|
||||
" vtxFog = v_vtxFog[index];\n"
|
||||
" vtxT0 = v_vtxT0[index];\n"
|
||||
" vtxT1 = v_vtxT1[index];\n"
|
||||
" vtxT2 = v_vtxT2[index];\n"
|
||||
" vtxT3 = v_vtxT3[index];\n"
|
||||
" vtxPos0 = pz[0];\n"
|
||||
" vtxPos1 = pz[1];\n"
|
||||
" vtxPos2 = pz[2];\n"
|
||||
" triMZ = (isnan(pz[3].x) || isinf(pz[3].x)) ? 0.0 : pz[3].x;\n"
|
||||
" EmitVertex();\n"
|
||||
"}\n");
|
||||
provoking_index = "index";
|
||||
}
|
||||
|
||||
mstring_append_fmt(
|
||||
output,
|
||||
"void emit_vertex(int index, mat4 pz) {\n"
|
||||
" gl_Position = gl_in[index].gl_Position;\n"
|
||||
" gl_PointSize = gl_in[index].gl_PointSize;\n"
|
||||
" vtxD0 = v_vtxD0[%s];\n"
|
||||
" vtxD1 = v_vtxD1[%s];\n"
|
||||
" vtxB0 = v_vtxB0[%s];\n"
|
||||
" vtxB1 = v_vtxB1[%s];\n"
|
||||
" vtxFog = v_vtxFog[index];\n"
|
||||
" vtxT0 = v_vtxT0[index];\n"
|
||||
" vtxT1 = v_vtxT1[index];\n"
|
||||
" vtxT2 = v_vtxT2[index];\n"
|
||||
" vtxT3 = v_vtxT3[index];\n"
|
||||
" vtxPos0 = pz[0];\n"
|
||||
" vtxPos1 = pz[1];\n"
|
||||
" vtxPos2 = pz[2];\n"
|
||||
" triMZ = (isnan(pz[3].x) || isinf(pz[3].x)) ? 0.0 : pz[3].x;\n"
|
||||
" EmitVertex();\n"
|
||||
"}\n",
|
||||
provoking_index,
|
||||
provoking_index,
|
||||
provoking_index,
|
||||
provoking_index);
|
||||
|
||||
if (need_triz || need_quadz) {
|
||||
mstring_append(
|
||||
output,
|
||||
|
@ -430,10 +400,12 @@ MString *pgraph_glsl_gen_geom(const GeomState *state, GenGeomGlslOptions opts)
|
|||
if (need_linez) {
|
||||
mstring_append(
|
||||
output,
|
||||
// Calculate a third vertex by rotating 90 degrees so that triangle
|
||||
// interpolation in fragment shader can be used as is for lines.
|
||||
"mat4 calc_linez(int i0, int i1) {\n"
|
||||
" vec2 delta = v_vtxPos[i1].xy - v_vtxPos[i0].xy;\n"
|
||||
" vec2 v2 = vec2(-delta.y, delta.x) + v_vtxPos[i0].xy;\n"
|
||||
" return mat4(v_vtxPos[i0], v_vtxPos[i1], vec4(v2, v_vtxPos[i0].zw), vec4(0.0));\n"
|
||||
" return mat4(v_vtxPos[i0], v_vtxPos[i1], v2, v_vtxPos[i0].zw, vec4(0.0));\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ typedef struct {
|
|||
enum ShaderPolygonMode polygon_front_mode;
|
||||
enum ShaderPolygonMode polygon_back_mode;
|
||||
bool smooth_shading;
|
||||
bool first_vertex_is_provoking;
|
||||
bool z_perspective;
|
||||
} GeomState;
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ DEF_METHOD(NV097, SET_STENCIL_OP_FAIL)
|
|||
DEF_METHOD(NV097, SET_STENCIL_OP_ZFAIL)
|
||||
DEF_METHOD(NV097, SET_STENCIL_OP_ZPASS)
|
||||
DEF_METHOD(NV097, SET_SHADE_MODE)
|
||||
DEF_METHOD(NV097, SET_PROVOKING_VERTEX)
|
||||
DEF_METHOD(NV097, SET_POLYGON_OFFSET_SCALE_FACTOR)
|
||||
DEF_METHOD(NV097, SET_POLYGON_OFFSET_BIAS)
|
||||
DEF_METHOD(NV097, SET_FRONT_POLYGON_MODE)
|
||||
|
|
|
@ -1534,6 +1534,13 @@ DEF_METHOD(NV097, SET_SHADE_MODE)
|
|||
}
|
||||
}
|
||||
|
||||
DEF_METHOD(NV097, SET_PROVOKING_VERTEX)
|
||||
{
|
||||
assert((parameter & ~1) == 0);
|
||||
PG_SET_MASK(NV_PGRAPH_CONTROL_3, NV_PGRAPH_CONTROL_3_PROVOKING_VERTEX,
|
||||
parameter);
|
||||
}
|
||||
|
||||
DEF_METHOD(NV097, SET_POLYGON_OFFSET_SCALE_FACTOR)
|
||||
{
|
||||
pgraph_reg_w(pg, NV_PGRAPH_ZOFFSETFACTOR, parameter);
|
||||
|
|
|
@ -791,8 +791,8 @@ static void create_pipeline(PGRAPHState *pg)
|
|||
VkPipelineRasterizationProvokingVertexStateCreateInfoEXT provoking_state;
|
||||
|
||||
if (r->provoking_vertex_extension_enabled) {
|
||||
// TODO: remove use of provoking vertex extension since we just want
|
||||
// the default last vertex convention always.
|
||||
// Use last provoking vertex convention to match geometry shader
|
||||
// assumption, because Vulkan default is first vertex convention.
|
||||
VkProvokingVertexModeEXT provoking_mode =
|
||||
VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT;
|
||||
|
||||
|
|
Loading…
Reference in New Issue