nv2a: Store shading mode in CONTROL_3

This commit is contained in:
Matt Borgerson 2022-06-25 20:12:50 -07:00 committed by mborgerson
parent 4132845336
commit 83e16c996d
8 changed files with 78 additions and 59 deletions

View File

@ -348,8 +348,6 @@ typedef struct PGRAPHState {
bool ltc1_dirty[NV2A_LTC1_COUNT];
float material_alpha;
// FIXME: Find the correct register for this.
uint32_t shade_model;
// should figure out where these are in lighting context
float light_infinite_half_vector[NV2A_MAX_LIGHTS][3];

View File

@ -448,6 +448,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_SHADEMODE (1 << 7)
# define NV_PGRAPH_CONTROL_3_SHADEMODE_FLAT 0
# define NV_PGRAPH_CONTROL_3_SHADEMODE_SMOOTH 1
# define NV_PGRAPH_CONTROL_3_FOGENABLE (1 << 8)
# define NV_PGRAPH_CONTROL_3_FOG_MODE 0x00070000
# define NV_PGRAPH_CONTROL_3_FOG_MODE_LINEAR 0
@ -974,9 +977,9 @@
# define NV097_SET_STENCIL_OP_V_INVERT 0x150A
# define NV097_SET_STENCIL_OP_V_INCR 0x8507
# define NV097_SET_STENCIL_OP_V_DECR 0x8508
# define NV097_SET_SHADE_MODEL 0x0000037C
# define NV097_SET_SHADE_MODEL_FLAT 0x1D00
# define NV097_SET_SHADE_MODEL_SMOOTH 0x1D01
# define NV097_SET_SHADE_MODE 0x0000037C
# define NV097_SET_SHADE_MODE_V_FLAT 0x1D00
# define NV097_SET_SHADE_MODE_V_SMOOTH 0x1D01
# define NV097_SET_POLYGON_OFFSET_SCALE_FACTOR 0x00000384
# define NV097_SET_POLYGON_OFFSET_BIAS 0x00000388
# define NV097_SET_FRONT_POLYGON_MODE 0x0000038C

View File

@ -1840,10 +1840,21 @@ DEF_METHOD(NV097, SET_STENCIL_OP_ZPASS)
kelvin_map_stencil_op(parameter));
}
DEF_METHOD(NV097, SET_SHADE_MODEL)
DEF_METHOD(NV097, SET_SHADE_MODE)
{
// FIXME: Find the correct register for this.
pg->shade_model = parameter;
switch (parameter) {
case NV097_SET_SHADE_MODE_V_FLAT:
SET_MASK(pg->regs[NV_PGRAPH_CONTROL_3], NV_PGRAPH_CONTROL_3_SHADEMODE,
NV_PGRAPH_CONTROL_3_SHADEMODE_FLAT);
break;
case NV097_SET_SHADE_MODE_V_SMOOTH:
SET_MASK(pg->regs[NV_PGRAPH_CONTROL_3], NV_PGRAPH_CONTROL_3_SHADEMODE,
NV_PGRAPH_CONTROL_3_SHADEMODE_SMOOTH);
break;
default:
/* Discard */
break;
}
}
DEF_METHOD(NV097, SET_POLYGON_OFFSET_SCALE_FACTOR)
@ -2979,7 +2990,9 @@ DEF_METHOD(NV097, SET_BEGIN_END)
glDisable(GL_DEPTH_CLAMP);
}
if (pg->shade_model == NV097_SET_SHADE_MODEL_FLAT) {
if (GET_MASK(pg->regs[NV_PGRAPH_CONTROL_3],
NV_PGRAPH_CONTROL_3_SHADEMODE) ==
NV_PGRAPH_CONTROL_3_SHADEMODE_FLAT) {
glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
}
@ -4006,7 +4019,8 @@ void pgraph_init(NV2AState *d)
pg->shader_cache = g_hash_table_new(shader_hash, shader_equal);
pg->material_alpha = 0.0f;
pg->shade_model = NV097_SET_SHADE_MODEL_SMOOTH;
SET_MASK(pg->regs[NV_PGRAPH_CONTROL_3], NV_PGRAPH_CONTROL_3_SHADEMODE,
NV_PGRAPH_CONTROL_3_SHADEMODE_SMOOTH);
pg->primitive_mode = PRIM_TYPE_INVALID;
for (i=0; i<NV2A_VERTEXSHADER_ATTRIBUTES; i++) {
@ -4331,7 +4345,6 @@ static bool pgraph_bind_shaders_test_dirty(PGRAPHState *pg)
CR_8(NV_PGRAPH_WINDOWCLIPX0) \
CR_8(NV_PGRAPH_WINDOWCLIPY0) \
CF(pg->primitive_mode, primitive_mode) \
CF(pg->shade_model, shade_model) \
CF(pg->surface_scale_factor, surface_scale_factor) \
CF(pg->compressed_attrs, compressed_attrs) \
CFA(pg->texture_matrix_enable, texture_matrix_enable)
@ -4453,8 +4466,10 @@ static void pgraph_bind_shaders(PGRAPHState *pg)
state.polygon_back_mode = (enum ShaderPolygonMode)GET_MASK(pg->regs[NV_PGRAPH_SETUPRASTER],
NV_PGRAPH_SETUPRASTER_BACKFACEMODE);
state.shade_model_flat = pg->shade_model == NV097_SET_SHADE_MODEL_FLAT;
state.psh.shade_model_flat = pg->shade_model == NV097_SET_SHADE_MODEL_FLAT;
state.smooth_shading = GET_MASK(pg->regs[NV_PGRAPH_CONTROL_3],
NV_PGRAPH_CONTROL_3_SHADEMODE) ==
NV_PGRAPH_CONTROL_3_SHADEMODE_SMOOTH;
state.psh.smooth_shading = state.smooth_shading;
state.program_length = 0;

View File

@ -66,7 +66,7 @@ DEF_METHOD(NV097, SET_STENCIL_FUNC_MASK)
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_MODEL)
DEF_METHOD(NV097, SET_SHADE_MODE)
DEF_METHOD(NV097, SET_POLYGON_OFFSET_SCALE_FACTOR)
DEF_METHOD(NV097, SET_POLYGON_OFFSET_BIAS)
DEF_METHOD(NV097, SET_FRONT_POLYGON_MODE)

View File

@ -690,8 +690,9 @@ static MString* psh_convert(struct PixelShader *ps)
int i;
MString *preflight = mstring_new();
mstring_append(preflight,
ps->state.shade_model_flat ? STRUCT_VERTEX_DATA_IN_FLAT : STRUCT_VERTEX_DATA_IN_SMOOTH);
mstring_append(preflight, ps->state.smooth_shading ?
STRUCT_VERTEX_DATA_IN_SMOOTH :
STRUCT_VERTEX_DATA_IN_FLAT);
mstring_append(preflight, "\n");
mstring_append(preflight, "out vec4 fragColor;\n");
mstring_append(preflight, "\n");

View File

@ -79,7 +79,7 @@ typedef struct PshState {
bool window_clip_exclusive;
bool shade_model_flat;
bool smooth_shading;
} PshState;
MString *psh_translate(const PshState state);

View File

@ -76,7 +76,7 @@ static MString* generate_geometry_shader(
enum ShaderPolygonMode polygon_back_mode,
enum ShaderPrimitiveMode primitive_mode,
GLenum *gl_primitive_mode,
bool shade_model_flat)
bool smooth_shading)
{
/* FIXME: Missing support for 2-sided-poly mode */
@ -203,7 +203,7 @@ static MString* generate_geometry_shader(
}
if (polygon_mode == POLY_MODE_FILL) {
*gl_primitive_mode = GL_TRIANGLE_FAN;
if (!shade_model_flat) {
if (smooth_shading) {
return NULL;
}
layout_in = "layout(triangles) in;\n";
@ -232,28 +232,7 @@ static MString* generate_geometry_shader(
mstring_append(s, layout_in);
mstring_append(s, layout_out);
mstring_append(s, "\n");
if (shade_model_flat) {
mstring_append(s,
STRUCT_V_VERTEX_DATA_IN_ARRAY_FLAT
"\n"
STRUCT_VERTEX_DATA_OUT_FLAT
"\n"
"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"
" vtx_inv_w = v_vtx_inv_w[index];\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"
" EmitVertex();\n"
"}\n");
} else {
if (smooth_shading) {
mstring_append(s,
STRUCT_V_VERTEX_DATA_IN_ARRAY_SMOOTH
"\n"
@ -274,6 +253,27 @@ static MString* generate_geometry_shader(
" vtxT3 = v_vtxT3[index];\n"
" EmitVertex();\n"
"}\n");
} else {
mstring_append(s,
STRUCT_V_VERTEX_DATA_IN_ARRAY_FLAT
"\n"
STRUCT_VERTEX_DATA_OUT_FLAT
"\n"
"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"
" vtx_inv_w = v_vtx_inv_w[index];\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"
" EmitVertex();\n"
"}\n");
}
mstring_append(s, "\n"
@ -807,11 +807,9 @@ GLSL_DEFINE(texMat3, GLSL_C_MAT4(NV_IGRAPH_XF_XFCTX_T3MAT))
" return vec4(x, y, z, 1);\n"
"}\n");
if (prefix_outputs) {
if (state->shade_model_flat) {
mstring_append(header, STRUCT_V_VERTEX_DATA_OUT_FLAT);
} else {
mstring_append(header, STRUCT_V_VERTEX_DATA_OUT_SMOOTH);
}
mstring_append(header, state->smooth_shading ?
STRUCT_V_VERTEX_DATA_OUT_SMOOTH :
STRUCT_V_VERTEX_DATA_OUT_FLAT);
mstring_append(header,
"#define vtx_inv_w v_vtx_inv_w\n"
"#define vtxD0 v_vtxD0\n"
@ -825,11 +823,9 @@ GLSL_DEFINE(texMat3, GLSL_C_MAT4(NV_IGRAPH_XF_XFCTX_T3MAT))
"#define vtxT3 v_vtxT3\n"
);
} else {
if (state->shade_model_flat) {
mstring_append(header, STRUCT_VERTEX_DATA_OUT_FLAT);
} else {
mstring_append(header, STRUCT_VERTEX_DATA_OUT_SMOOTH);
}
mstring_append(header, state->smooth_shading ?
STRUCT_VERTEX_DATA_OUT_SMOOTH :
STRUCT_VERTEX_DATA_OUT_FLAT);
}
mstring_append(header, "\n");
for (i = 0; i < NV2A_VERTEXSHADER_ATTRIBUTES; i++) {
@ -1030,7 +1026,7 @@ ShaderBinding *generate_shaders(const ShaderState *state)
state->polygon_back_mode,
state->primitive_mode,
&gl_primitive_mode,
state->shade_model_flat);
state->smooth_shading);
if (geometry_shader_code) {
const char* geometry_shader_code_str =
mstring_get_str(geometry_shader_code);
@ -1042,7 +1038,8 @@ ShaderBinding *generate_shaders(const ShaderState *state)
}
/* create the vertex shader */
MString *vertex_shader_code = generate_vertex_shader(state, geometry_shader_code);
MString *vertex_shader_code =
generate_vertex_shader(state, geometry_shader_code != NULL);
GLuint vertex_shader = create_gl_shader(GL_VERTEX_SHADER,
mstring_get_str(vertex_shader_code),
"vertex shader");
@ -1051,7 +1048,8 @@ ShaderBinding *generate_shaders(const ShaderState *state)
/* generate a fragment shader from register combiners */
MString *fragment_shader_code = psh_translate(state->psh);
const char *fragment_shader_code_str = mstring_get_str(fragment_shader_code);
const char *fragment_shader_code_str =
mstring_get_str(fragment_shader_code);
GLuint fragment_shader = create_gl_shader(GL_FRAGMENT_SHADER,
fragment_shader_code_str,
"fragment shader");
@ -1144,14 +1142,17 @@ ShaderBinding *generate_shaders(const ShaderState *state)
}
for (i = 0; i < NV2A_MAX_LIGHTS; i++) {
snprintf(tmp, sizeof(tmp), "lightInfiniteHalfVector%d", i);
ret->light_infinite_half_vector_loc[i] = glGetUniformLocation(program, tmp);
ret->light_infinite_half_vector_loc[i] =
glGetUniformLocation(program, tmp);
snprintf(tmp, sizeof(tmp), "lightInfiniteDirection%d", i);
ret->light_infinite_direction_loc[i] = glGetUniformLocation(program, tmp);
ret->light_infinite_direction_loc[i] =
glGetUniformLocation(program, tmp);
snprintf(tmp, sizeof(tmp), "lightLocalPosition%d", i);
ret->light_local_position_loc[i] = glGetUniformLocation(program, tmp);
snprintf(tmp, sizeof(tmp), "lightLocalAttenuation%d", i);
ret->light_local_attenuation_loc[i] = glGetUniformLocation(program, tmp);
ret->light_local_attenuation_loc[i] =
glGetUniformLocation(program, tmp);
}
for (i = 0; i < 8; i++) {
snprintf(tmp, sizeof(tmp), "clipRegion[%d]", i);
@ -1159,7 +1160,8 @@ ShaderBinding *generate_shaders(const ShaderState *state)
}
if (state->fixed_function) {
ret->material_alpha_loc = glGetUniformLocation(program, "material_alpha");
ret->material_alpha_loc =
glGetUniformLocation(program, "material_alpha");
} else {
ret->material_alpha_loc = -1;
}

View File

@ -98,7 +98,7 @@ typedef struct ShaderState {
float point_size;
float point_params[8];
bool shade_model_flat;
bool smooth_shading;
} ShaderState;
typedef struct ShaderBinding {