mirror of
https://github.com/mborgerson/xemu.git
synced 2025-12-01 16:10:01 +00:00
nv2a: Extract VshState from ShaderState
This commit is contained in:
committed by
mborgerson
parent
9d9c88f71d
commit
c575b08b5f
@ -195,7 +195,7 @@ static void update_shader_constant_locations(ShaderBinding *binding)
|
||||
binding->point_params_loc[i] = glGetUniformLocation(binding->gl_program, tmp);
|
||||
}
|
||||
|
||||
if (binding->state.fixed_function) {
|
||||
if (binding->state.vsh.is_fixed_function) {
|
||||
binding->material_alpha_loc =
|
||||
glGetUniformLocation(binding->gl_program, "material_alpha");
|
||||
binding->specular_power_loc =
|
||||
@ -230,14 +230,11 @@ static void generate_shaders(ShaderBinding *binding)
|
||||
ShaderState *state = &binding->state;
|
||||
|
||||
/* Create an optional geometry shader and find primitive type */
|
||||
GLenum gl_primitive_mode =
|
||||
get_gl_primitive_mode(state->polygon_front_mode, state->primitive_mode);
|
||||
MString* geometry_shader_code =
|
||||
pgraph_gen_geom_glsl(state->polygon_front_mode,
|
||||
state->polygon_back_mode,
|
||||
state->primitive_mode,
|
||||
state->smooth_shading,
|
||||
false);
|
||||
GLenum gl_primitive_mode = get_gl_primitive_mode(
|
||||
state->vsh.polygon_front_mode, state->vsh.primitive_mode);
|
||||
MString *geometry_shader_code = pgraph_gen_geom_glsl(
|
||||
state->vsh.polygon_front_mode, state->vsh.polygon_back_mode,
|
||||
state->vsh.primitive_mode, state->vsh.smooth_shading, false);
|
||||
if (geometry_shader_code) {
|
||||
const char* geometry_shader_code_str =
|
||||
mstring_get_str(geometry_shader_code);
|
||||
@ -250,7 +247,7 @@ static void generate_shaders(ShaderBinding *binding)
|
||||
|
||||
/* create the vertex shader */
|
||||
MString *vertex_shader_code =
|
||||
pgraph_gen_vsh_glsl(state, geometry_shader_code != NULL);
|
||||
pgraph_gen_vsh_glsl(&state->vsh, geometry_shader_code != NULL);
|
||||
GLuint vertex_shader = create_gl_shader(GL_VERTEX_SHADER,
|
||||
mstring_get_str(vertex_shader_code),
|
||||
"vertex shader");
|
||||
@ -378,8 +375,9 @@ bool pgraph_gl_shader_load_from_memory(ShaderBinding *binding)
|
||||
glUseProgram(gl_program);
|
||||
|
||||
binding->gl_program = gl_program;
|
||||
binding->gl_primitive_mode = get_gl_primitive_mode(
|
||||
binding->state.polygon_front_mode, binding->state.primitive_mode);
|
||||
binding->gl_primitive_mode =
|
||||
get_gl_primitive_mode(binding->state.vsh.polygon_front_mode,
|
||||
binding->state.vsh.primitive_mode);
|
||||
binding->initialized = true;
|
||||
|
||||
g_free(binding->program);
|
||||
@ -814,7 +812,7 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding,
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if (state->fixed_function) {
|
||||
if (state->vsh.is_fixed_function) {
|
||||
/* update lighting constants */
|
||||
struct {
|
||||
uint32_t* v;
|
||||
@ -1047,7 +1045,7 @@ void pgraph_gl_bind_shaders(PGRAPHState *pg)
|
||||
|
||||
ShaderBinding *old_binding = r->shader_binding;
|
||||
ShaderState state = pgraph_get_shader_state(pg);
|
||||
assert(!state.vulkan);
|
||||
assert(!state.vsh.vulkan);
|
||||
|
||||
NV2A_GL_DGROUP_BEGIN("%s (VP: %s FFP: %s)", __func__,
|
||||
state.vertex_program ? "yes" : "no",
|
||||
|
||||
@ -29,7 +29,7 @@ static void append_skinning_code(MString* str, bool mix,
|
||||
const char* output, const char* input,
|
||||
const char* matrix, const char* swizzle);
|
||||
|
||||
void pgraph_gen_vsh_ff_glsl(const ShaderState *state, MString *header,
|
||||
void pgraph_gen_vsh_ff_glsl(const VshState *state, MString *header,
|
||||
MString *body, MString *uniforms)
|
||||
{
|
||||
int i, j;
|
||||
@ -119,7 +119,7 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
||||
/* Skinning */
|
||||
unsigned int count;
|
||||
bool mix;
|
||||
switch (state->skinning) {
|
||||
switch (state->fixed_function.skinning) {
|
||||
case SKINNING_OFF:
|
||||
mix = false; count = 0; break;
|
||||
case SKINNING_1WEIGHTS:
|
||||
@ -139,7 +139,7 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
||||
break;
|
||||
}
|
||||
mstring_append_fmt(body, "/* Skinning mode %d */\n",
|
||||
state->skinning);
|
||||
state->fixed_function.skinning);
|
||||
|
||||
append_skinning_code(body, mix, count, "vec4",
|
||||
"tPosition", "position",
|
||||
@ -149,7 +149,7 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
||||
"invModelViewMat", "xyz");
|
||||
|
||||
/* Normalization */
|
||||
if (state->normalization) {
|
||||
if (state->fixed_function.normalization) {
|
||||
mstring_append(body, "tNormal = normalize(tNormal);\n");
|
||||
}
|
||||
|
||||
@ -163,7 +163,7 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
||||
/* TODO: TexGen View Model missing! */
|
||||
char c = "xyzw"[j];
|
||||
char cSuffix = "STRQ"[j];
|
||||
switch (state->texgen[i][j]) {
|
||||
switch (state->fixed_function.texgen[i][j]) {
|
||||
case TEXGEN_DISABLE:
|
||||
mstring_append_fmt(body, "oT%d.%c = texture%d.%c;\n",
|
||||
i, c, i, c);
|
||||
@ -220,7 +220,7 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
||||
|
||||
/* Apply texture matrices */
|
||||
for (i = 0; i < NV2A_MAX_TEXTURES; i++) {
|
||||
if (state->texture_matrix_enable[i]) {
|
||||
if (state->fixed_function.texture_matrix_enable[i]) {
|
||||
mstring_append_fmt(body,
|
||||
"oT%d = oT%d * texMat%d;\n",
|
||||
i, i, i);
|
||||
@ -228,7 +228,7 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
||||
}
|
||||
|
||||
/* Lighting */
|
||||
if (!state->lighting) {
|
||||
if (!state->fixed_function.lighting) {
|
||||
mstring_append(body, " oD0 = diffuse;\n");
|
||||
mstring_append(body, " oD1 = specular;\n");
|
||||
mstring_append(body, " oB0 = backDiffuse;\n");
|
||||
@ -242,47 +242,47 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
||||
static char alpha_source_specular[] = "specular.a";
|
||||
static char alpha_source_material[] = "material_alpha";
|
||||
const char *alpha_source = alpha_source_diffuse;
|
||||
if (state->diffuse_src == MATERIAL_COLOR_SRC_MATERIAL) {
|
||||
if (state->fixed_function.diffuse_src == MATERIAL_COLOR_SRC_MATERIAL) {
|
||||
mstring_append_fmt(uniforms, "%sfloat material_alpha;\n", u);
|
||||
alpha_source = alpha_source_material;
|
||||
} else if (state->diffuse_src == MATERIAL_COLOR_SRC_SPECULAR) {
|
||||
} else if (state->fixed_function.diffuse_src == MATERIAL_COLOR_SRC_SPECULAR) {
|
||||
alpha_source = alpha_source_specular;
|
||||
}
|
||||
|
||||
if (state->ambient_src == MATERIAL_COLOR_SRC_MATERIAL) {
|
||||
if (state->fixed_function.ambient_src == MATERIAL_COLOR_SRC_MATERIAL) {
|
||||
mstring_append_fmt(body, "oD0 = vec4(sceneAmbientColor, %s);\n", alpha_source);
|
||||
} else if (state->ambient_src == MATERIAL_COLOR_SRC_DIFFUSE) {
|
||||
} else if (state->fixed_function.ambient_src == MATERIAL_COLOR_SRC_DIFFUSE) {
|
||||
mstring_append_fmt(body, "oD0 = vec4(diffuse.rgb, %s);\n", alpha_source);
|
||||
} else if (state->ambient_src == MATERIAL_COLOR_SRC_SPECULAR) {
|
||||
} else if (state->fixed_function.ambient_src == MATERIAL_COLOR_SRC_SPECULAR) {
|
||||
mstring_append_fmt(body, "oD0 = vec4(specular.rgb, %s);\n", alpha_source);
|
||||
}
|
||||
|
||||
mstring_append(body, "oD0.rgb *= materialEmissionColor.rgb;\n");
|
||||
if (state->emission_src == MATERIAL_COLOR_SRC_MATERIAL) {
|
||||
if (state->fixed_function.emission_src == MATERIAL_COLOR_SRC_MATERIAL) {
|
||||
mstring_append(body, "oD0.rgb += sceneAmbientColor;\n");
|
||||
} else if (state->emission_src == MATERIAL_COLOR_SRC_DIFFUSE) {
|
||||
} else if (state->fixed_function.emission_src == MATERIAL_COLOR_SRC_DIFFUSE) {
|
||||
mstring_append(body, "oD0.rgb += diffuse.rgb;\n");
|
||||
} else if (state->emission_src == MATERIAL_COLOR_SRC_SPECULAR) {
|
||||
} else if (state->fixed_function.emission_src == MATERIAL_COLOR_SRC_SPECULAR) {
|
||||
mstring_append(body, "oD0.rgb += specular.rgb;\n");
|
||||
}
|
||||
|
||||
mstring_append(body, "oD1 = vec4(0.0, 0.0, 0.0, specular.a);\n");
|
||||
|
||||
if (state->local_eye) {
|
||||
if (state->fixed_function.local_eye) {
|
||||
mstring_append(body,
|
||||
"vec3 VPeye = normalize(eyePosition.xyz / eyePosition.w - tPosition.xyz / tPosition.w);\n"
|
||||
);
|
||||
}
|
||||
|
||||
for (i = 0; i < NV2A_MAX_LIGHTS; i++) {
|
||||
if (state->light[i] == LIGHT_OFF) {
|
||||
if (state->fixed_function.light[i] == LIGHT_OFF) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mstring_append_fmt(body, "/* Light %d */ {\n", i);
|
||||
|
||||
if (state->light[i] == LIGHT_LOCAL
|
||||
|| state->light[i] == LIGHT_SPOT) {
|
||||
if (state->fixed_function.light[i] == LIGHT_LOCAL
|
||||
|| state->fixed_function.light[i] == LIGHT_SPOT) {
|
||||
|
||||
mstring_append_fmt(uniforms,
|
||||
"%svec3 lightLocalPosition%d;\n"
|
||||
@ -301,11 +301,11 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
||||
" float nDotVP = max(0.0, dot(tNormal, VP));\n"
|
||||
" float nDotHV = max(0.0, dot(tNormal, halfVector));\n",
|
||||
i, i, i, i, i,
|
||||
state->local_eye ? "VPeye" : "vec3(0.0, 0.0, 0.0)"
|
||||
state->fixed_function.local_eye ? "VPeye" : "vec3(0.0, 0.0, 0.0)"
|
||||
);
|
||||
}
|
||||
|
||||
switch(state->light[i]) {
|
||||
switch(state->fixed_function.light[i]) {
|
||||
case LIGHT_INFINITE:
|
||||
|
||||
/* lightLocalRange will be 1e+30 here */
|
||||
@ -320,7 +320,7 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
||||
" vec3 lightDirection = normalize(lightInfiniteDirection%d);\n"
|
||||
" float nDotVP = max(0.0, dot(tNormal, lightDirection));\n",
|
||||
i);
|
||||
if (state->local_eye) {
|
||||
if (state->fixed_function.local_eye) {
|
||||
mstring_append(body,
|
||||
" float nDotHV = max(0.0, dot(tNormal, normalize(lightDirection + VPeye)));\n"
|
||||
);
|
||||
@ -371,7 +371,7 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
||||
mstring_append(body,
|
||||
" oD0.xyz += lightAmbient;\n");
|
||||
|
||||
switch (state->diffuse_src) {
|
||||
switch (state->fixed_function.diffuse_src) {
|
||||
case MATERIAL_COLOR_SRC_MATERIAL:
|
||||
mstring_append(body,
|
||||
" oD0.xyz += lightDiffuse;\n");
|
||||
@ -386,7 +386,7 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
||||
break;
|
||||
}
|
||||
|
||||
switch (state->specular_src) {
|
||||
switch (state->fixed_function.specular_src) {
|
||||
case MATERIAL_COLOR_SRC_MATERIAL:
|
||||
mstring_append(body,
|
||||
" oD1.xyz += lightSpecular;\n");
|
||||
@ -415,7 +415,7 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
||||
mstring_append(body, " oB1 = vec4(0.0, 0.0, 0.0, 1.0);\n");
|
||||
} else {
|
||||
if (!state->separate_specular) {
|
||||
if (state->lighting) {
|
||||
if (state->fixed_function.lighting) {
|
||||
mstring_append(body,
|
||||
" oD0.xyz += oD1.xyz;\n"
|
||||
" oB0.xyz += oB1.xyz;\n"
|
||||
@ -438,7 +438,7 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
||||
if (state->fog_enable) {
|
||||
|
||||
/* From: https://www.opengl.org/registry/specs/NV/fog_distance.txt */
|
||||
switch(state->foggen) {
|
||||
switch(state->fixed_function.foggen) {
|
||||
case FOGGEN_SPEC_ALPHA:
|
||||
/* FIXME: Do we have to clamp here? */
|
||||
mstring_append(body, " float fogDistance = clamp(specular.a, 0.0, 1.0);\n");
|
||||
@ -449,7 +449,7 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
||||
case FOGGEN_PLANAR:
|
||||
case FOGGEN_ABS_PLANAR:
|
||||
mstring_append(body, " float fogDistance = dot(fogPlane.xyz, tPosition.xyz) + fogPlane.w;\n");
|
||||
if (state->foggen == FOGGEN_ABS_PLANAR) {
|
||||
if (state->fixed_function.foggen == FOGGEN_ABS_PLANAR) {
|
||||
mstring_append(body, " fogDistance = abs(fogDistance);\n");
|
||||
}
|
||||
break;
|
||||
@ -464,7 +464,7 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
||||
}
|
||||
|
||||
/* If skinning is off the composite matrix already includes the MV matrix */
|
||||
if (state->skinning == SKINNING_OFF) {
|
||||
if (state->fixed_function.skinning == SKINNING_OFF) {
|
||||
mstring_append(body, " tPosition = position;\n");
|
||||
}
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
#include "qemu/mstring.h"
|
||||
#include "hw/xbox/nv2a/pgraph/shaders.h"
|
||||
|
||||
void pgraph_gen_vsh_ff_glsl(const ShaderState *state, MString *header,
|
||||
void pgraph_gen_vsh_ff_glsl(const VshState *state, MString *header,
|
||||
MString *body, MString *uniforms);
|
||||
|
||||
#endif
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
#include "vsh-prog.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
MString *pgraph_gen_vsh_glsl(const ShaderState *state, bool prefix_outputs)
|
||||
MString *pgraph_gen_vsh_glsl(const VshState *state, bool prefix_outputs)
|
||||
{
|
||||
int i;
|
||||
MString *output = mstring_new();
|
||||
@ -158,23 +158,20 @@ MString *pgraph_gen_vsh_glsl(const ShaderState *state, bool prefix_outputs)
|
||||
|
||||
}
|
||||
|
||||
if (state->fixed_function) {
|
||||
if (state->is_fixed_function) {
|
||||
pgraph_gen_vsh_ff_glsl(state, header, body, uniforms);
|
||||
} else if (state->vertex_program) {
|
||||
pgraph_gen_vsh_prog_glsl(VSH_VERSION_XVS,
|
||||
(uint32_t *)state->program_data,
|
||||
state->program_length,
|
||||
state->vulkan, header, body);
|
||||
} else {
|
||||
assert(false);
|
||||
pgraph_gen_vsh_prog_glsl(VSH_VERSION_XVS,
|
||||
(uint32_t *)state->programmable.program_data,
|
||||
state->programmable.program_length,
|
||||
state->vulkan, header, body);
|
||||
}
|
||||
|
||||
|
||||
/* Fog */
|
||||
|
||||
if (state->fog_enable) {
|
||||
|
||||
if (state->vertex_program) {
|
||||
if (!state->is_fixed_function) {
|
||||
/* FIXME: Does foggen do something here? Let's do some tracking..
|
||||
*
|
||||
* "RollerCoaster Tycoon" has
|
||||
|
||||
@ -28,6 +28,6 @@
|
||||
// FIXME: Move to struct
|
||||
#define VSH_UBO_BINDING 0
|
||||
|
||||
MString *pgraph_gen_vsh_glsl(const ShaderState *state, bool prefix_outputs);
|
||||
MString *pgraph_gen_vsh_glsl(const VshState *state, bool prefix_outputs);
|
||||
|
||||
#endif
|
||||
|
||||
@ -67,15 +67,15 @@ ShaderState pgraph_get_shader_state(PGRAPHState *pg)
|
||||
// We will hash it, so make sure any padding is zeroed
|
||||
memset(&state, 0, sizeof(ShaderState));
|
||||
|
||||
state.surface_scale_factor = pg->surface_scale_factor;
|
||||
state.vsh.surface_scale_factor = pg->surface_scale_factor;
|
||||
|
||||
state.compressed_attrs = pg->compressed_attrs;
|
||||
state.uniform_attrs = pg->uniform_attrs;
|
||||
state.swizzle_attrs = pg->swizzle_attrs;
|
||||
state.vsh.compressed_attrs = pg->compressed_attrs;
|
||||
state.vsh.uniform_attrs = pg->uniform_attrs;
|
||||
state.vsh.swizzle_attrs = pg->swizzle_attrs;
|
||||
|
||||
/* register combiner stuff */
|
||||
state.psh.window_clip_exclusive =
|
||||
pgraph_reg_r(pg, NV_PGRAPH_SETUPRASTER) & NV_PGRAPH_SETUPRASTER_WINDOWCLIPTYPE;
|
||||
state.psh.window_clip_exclusive = pgraph_reg_r(pg, NV_PGRAPH_SETUPRASTER) &
|
||||
NV_PGRAPH_SETUPRASTER_WINDOWCLIPTYPE;
|
||||
state.psh.combiner_control = pgraph_reg_r(pg, NV_PGRAPH_COMBINECTL);
|
||||
state.psh.shader_stage_program = pgraph_reg_r(pg, NV_PGRAPH_SHADERPROG);
|
||||
state.psh.other_stage_input = pgraph_reg_r(pg, NV_PGRAPH_SHADERCTL);
|
||||
@ -93,35 +93,41 @@ ShaderState pgraph_get_shader_state(PGRAPHState *pg)
|
||||
state.psh.shadow_depth_func = (enum PshShadowDepthFunc)GET_MASK(
|
||||
pgraph_reg_r(pg, NV_PGRAPH_SHADOWCTL), NV_PGRAPH_SHADOWCTL_SHADOW_ZFUNC);
|
||||
|
||||
state.fixed_function = fixed_function;
|
||||
state.specular_enable = GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CSV0_C),
|
||||
NV_PGRAPH_CSV0_C_SPECULAR_ENABLE);
|
||||
state.vsh.is_fixed_function = fixed_function;
|
||||
state.vsh.specular_enable = GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CSV0_C),
|
||||
NV_PGRAPH_CSV0_C_SPECULAR_ENABLE);
|
||||
|
||||
/* fixed function stuff */
|
||||
if (fixed_function) {
|
||||
state.skinning = (enum VshSkinning)GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CSV0_D),
|
||||
NV_PGRAPH_CSV0_D_SKIN);
|
||||
state.lighting =
|
||||
GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_LIGHTING);
|
||||
state.normalization =
|
||||
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C) & NV_PGRAPH_CSV0_C_NORMALIZATION_ENABLE;
|
||||
state.vsh.fixed_function.skinning = (enum VshSkinning)GET_MASK(
|
||||
pgraph_reg_r(pg, NV_PGRAPH_CSV0_D), NV_PGRAPH_CSV0_D_SKIN);
|
||||
state.vsh.fixed_function.lighting = GET_MASK(
|
||||
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_LIGHTING);
|
||||
state.vsh.fixed_function.normalization =
|
||||
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C) &
|
||||
NV_PGRAPH_CSV0_C_NORMALIZATION_ENABLE;
|
||||
|
||||
/* color material */
|
||||
state.emission_src = (enum MaterialColorSource)GET_MASK(
|
||||
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_EMISSION);
|
||||
state.ambient_src = (enum MaterialColorSource)GET_MASK(
|
||||
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_AMBIENT);
|
||||
state.diffuse_src = (enum MaterialColorSource)GET_MASK(
|
||||
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_DIFFUSE);
|
||||
state.specular_src = (enum MaterialColorSource)GET_MASK(
|
||||
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_SPECULAR);
|
||||
state.vsh.fixed_function.emission_src =
|
||||
(enum MaterialColorSource)GET_MASK(
|
||||
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_EMISSION);
|
||||
state.vsh.fixed_function.ambient_src =
|
||||
(enum MaterialColorSource)GET_MASK(
|
||||
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_AMBIENT);
|
||||
state.vsh.fixed_function.diffuse_src =
|
||||
(enum MaterialColorSource)GET_MASK(
|
||||
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_DIFFUSE);
|
||||
state.vsh.fixed_function.specular_src =
|
||||
(enum MaterialColorSource)GET_MASK(
|
||||
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_SPECULAR);
|
||||
|
||||
state.local_eye = GET_MASK(
|
||||
state.vsh.fixed_function.local_eye = GET_MASK(
|
||||
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_LOCALEYE);
|
||||
|
||||
/* Texture matrices */
|
||||
for (int i = 0; i < 4; i++) {
|
||||
state.texture_matrix_enable[i] = pg->texture_matrix_enable[i];
|
||||
state.vsh.fixed_function.texture_matrix_enable[i] =
|
||||
pg->texture_matrix_enable[i];
|
||||
}
|
||||
|
||||
/* Texgen */
|
||||
@ -134,62 +140,62 @@ ShaderState pgraph_get_shader_state(PGRAPHState *pg)
|
||||
(i % 2) ? NV_PGRAPH_CSV1_A_T1_R : NV_PGRAPH_CSV1_A_T0_R,
|
||||
(i % 2) ? NV_PGRAPH_CSV1_A_T1_Q : NV_PGRAPH_CSV1_A_T0_Q
|
||||
};
|
||||
state.texgen[i][j] =
|
||||
state.vsh.fixed_function.texgen[i][j] =
|
||||
(enum VshTexgen)GET_MASK(pgraph_reg_r(pg, reg), masks[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.separate_specular = GET_MASK(
|
||||
state.vsh.separate_specular = GET_MASK(
|
||||
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_SEPARATE_SPECULAR);
|
||||
state.ignore_specular_alpha = !GET_MASK(
|
||||
state.vsh.ignore_specular_alpha = !GET_MASK(
|
||||
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_ALPHA_FROM_MATERIAL_SPECULAR);
|
||||
|
||||
state.specular_power = pg->specular_power;
|
||||
state.specular_power_back = pg->specular_power_back;
|
||||
state.vsh.specular_power = pg->specular_power;
|
||||
state.vsh.specular_power_back = pg->specular_power_back;
|
||||
|
||||
/* vertex program stuff */
|
||||
state.vertex_program = vertex_program,
|
||||
state.z_perspective = pgraph_reg_r(pg, NV_PGRAPH_CONTROL_0) &
|
||||
state.vsh.z_perspective = pgraph_reg_r(pg, NV_PGRAPH_CONTROL_0) &
|
||||
NV_PGRAPH_CONTROL_0_Z_PERSPECTIVE_ENABLE;
|
||||
state.psh.z_perspective = state.z_perspective;
|
||||
state.psh.z_perspective = state.vsh.z_perspective;
|
||||
|
||||
state.point_params_enable = GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CSV0_D),
|
||||
state.vsh.point_params_enable = GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CSV0_D),
|
||||
NV_PGRAPH_CSV0_D_POINTPARAMSENABLE);
|
||||
state.point_size =
|
||||
state.vsh.point_size =
|
||||
GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_POINTSIZE), NV097_SET_POINT_SIZE_V) / 8.0f;
|
||||
if (state.point_params_enable) {
|
||||
if (state.vsh.point_params_enable) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
state.point_params[i] = pg->point_params[i];
|
||||
state.vsh.point_params[i] = pg->point_params[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* geometry shader stuff */
|
||||
state.primitive_mode = (enum ShaderPrimitiveMode)pg->primitive_mode;
|
||||
state.polygon_front_mode = (enum ShaderPolygonMode)GET_MASK(
|
||||
state.vsh.primitive_mode = (enum ShaderPrimitiveMode)pg->primitive_mode;
|
||||
state.vsh.polygon_front_mode = (enum ShaderPolygonMode)GET_MASK(
|
||||
pgraph_reg_r(pg, NV_PGRAPH_SETUPRASTER), NV_PGRAPH_SETUPRASTER_FRONTFACEMODE);
|
||||
state.polygon_back_mode = (enum ShaderPolygonMode)GET_MASK(
|
||||
state.vsh.polygon_back_mode = (enum ShaderPolygonMode)GET_MASK(
|
||||
pgraph_reg_r(pg, NV_PGRAPH_SETUPRASTER), NV_PGRAPH_SETUPRASTER_BACKFACEMODE);
|
||||
|
||||
state.smooth_shading = GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CONTROL_3),
|
||||
state.vsh.smooth_shading = GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CONTROL_3),
|
||||
NV_PGRAPH_CONTROL_3_SHADEMODE) ==
|
||||
NV_PGRAPH_CONTROL_3_SHADEMODE_SMOOTH;
|
||||
state.psh.smooth_shading = state.smooth_shading;
|
||||
state.psh.smooth_shading = state.vsh.smooth_shading;
|
||||
|
||||
state.psh.depth_clipping = GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_ZCOMPRESSOCCLUDE),
|
||||
NV_PGRAPH_ZCOMPRESSOCCLUDE_ZCLAMP_EN) ==
|
||||
NV_PGRAPH_ZCOMPRESSOCCLUDE_ZCLAMP_EN_CULL;
|
||||
|
||||
state.program_length = 0;
|
||||
|
||||
if (vertex_program) {
|
||||
// copy in vertex program tokens
|
||||
state.vsh.programmable.program_length = 0;
|
||||
for (int i = program_start; i < NV2A_MAX_TRANSFORM_PROGRAM_LENGTH;
|
||||
i++) {
|
||||
uint32_t *cur_token = (uint32_t *)&pg->program_data[i];
|
||||
memcpy(&state.program_data[state.program_length], cur_token,
|
||||
VSH_TOKEN_SIZE * sizeof(uint32_t));
|
||||
state.program_length++;
|
||||
memcpy(&state.vsh.programmable
|
||||
.program_data[state.vsh.programmable.program_length],
|
||||
cur_token, VSH_TOKEN_SIZE * sizeof(uint32_t));
|
||||
state.vsh.programmable.program_length++;
|
||||
|
||||
if (vsh_get_field(cur_token, FLD_FINAL)) {
|
||||
break;
|
||||
@ -198,35 +204,40 @@ ShaderState pgraph_get_shader_state(PGRAPHState *pg)
|
||||
}
|
||||
|
||||
/* Fog */
|
||||
state.fog_enable =
|
||||
state.vsh.fog_enable =
|
||||
pgraph_reg_r(pg, NV_PGRAPH_CONTROL_3) & NV_PGRAPH_CONTROL_3_FOGENABLE;
|
||||
if (state.fog_enable) {
|
||||
if (state.vsh.fog_enable) {
|
||||
/*FIXME: Use CSV0_D? */
|
||||
state.fog_mode = (enum VshFogMode)GET_MASK(
|
||||
state.vsh.fog_mode = (enum VshFogMode)GET_MASK(
|
||||
pgraph_reg_r(pg, NV_PGRAPH_CONTROL_3), NV_PGRAPH_CONTROL_3_FOG_MODE);
|
||||
state.foggen = (enum VshFoggen)GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CSV0_D),
|
||||
NV_PGRAPH_CSV0_D_FOGGENMODE);
|
||||
state.vsh.fixed_function.foggen = (enum VshFoggen)GET_MASK(
|
||||
pgraph_reg_r(pg, NV_PGRAPH_CSV0_D), NV_PGRAPH_CSV0_D_FOGGENMODE);
|
||||
} else {
|
||||
/* FIXME: Do we still pass the fogmode? */
|
||||
state.fog_mode = (enum VshFogMode)0;
|
||||
state.foggen = (enum VshFoggen)0;
|
||||
state.vsh.fog_mode = (enum VshFogMode)0;
|
||||
state.vsh.fixed_function.foggen = (enum VshFoggen)0;
|
||||
}
|
||||
|
||||
/* Lighting */
|
||||
if (state.lighting) {
|
||||
if (state.vsh.fixed_function.lighting) {
|
||||
for (int i = 0; i < NV2A_MAX_LIGHTS; i++) {
|
||||
state.light[i] = (enum VshLight)GET_MASK(
|
||||
pgraph_reg_r(pg, NV_PGRAPH_CSV0_D), NV_PGRAPH_CSV0_D_LIGHT0 << (i * 2));
|
||||
state.vsh.fixed_function.light[i] =
|
||||
(enum VshLight)GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CSV0_D),
|
||||
NV_PGRAPH_CSV0_D_LIGHT0 << (i * 2));
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy content of enabled combiner stages */
|
||||
int num_stages = pgraph_reg_r(pg, NV_PGRAPH_COMBINECTL) & 0xFF;
|
||||
for (int i = 0; i < num_stages; i++) {
|
||||
state.psh.rgb_inputs[i] = pgraph_reg_r(pg, NV_PGRAPH_COMBINECOLORI0 + i * 4);
|
||||
state.psh.rgb_outputs[i] = pgraph_reg_r(pg, NV_PGRAPH_COMBINECOLORO0 + i * 4);
|
||||
state.psh.alpha_inputs[i] = pgraph_reg_r(pg, NV_PGRAPH_COMBINEALPHAI0 + i * 4);
|
||||
state.psh.alpha_outputs[i] = pgraph_reg_r(pg, NV_PGRAPH_COMBINEALPHAO0 + i * 4);
|
||||
state.psh.rgb_inputs[i] =
|
||||
pgraph_reg_r(pg, NV_PGRAPH_COMBINECOLORI0 + i * 4);
|
||||
state.psh.rgb_outputs[i] =
|
||||
pgraph_reg_r(pg, NV_PGRAPH_COMBINECOLORO0 + i * 4);
|
||||
state.psh.alpha_inputs[i] =
|
||||
pgraph_reg_r(pg, NV_PGRAPH_COMBINEALPHAI0 + i * 4);
|
||||
state.psh.alpha_outputs[i] =
|
||||
pgraph_reg_r(pg, NV_PGRAPH_COMBINEALPHAO0 + i * 4);
|
||||
// constant_0[i] = pgraph_reg_r(pg, NV_PGRAPH_COMBINEFACTOR0 + i * 4);
|
||||
// constant_1[i] = pgraph_reg_r(pg, NV_PGRAPH_COMBINEFACTOR1 + i * 4);
|
||||
}
|
||||
|
||||
@ -22,91 +22,13 @@
|
||||
#define HW_XBOX_NV2A_PGRAPH_SHADERS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "hw/xbox/nv2a/nv2a_regs.h"
|
||||
|
||||
#include "vsh.h"
|
||||
#include "psh.h"
|
||||
|
||||
enum ShaderPrimitiveMode {
|
||||
PRIM_TYPE_INVALID,
|
||||
PRIM_TYPE_POINTS,
|
||||
PRIM_TYPE_LINES,
|
||||
PRIM_TYPE_LINE_LOOP,
|
||||
PRIM_TYPE_LINE_STRIP,
|
||||
PRIM_TYPE_TRIANGLES,
|
||||
PRIM_TYPE_TRIANGLE_STRIP,
|
||||
PRIM_TYPE_TRIANGLE_FAN,
|
||||
PRIM_TYPE_QUADS,
|
||||
PRIM_TYPE_QUAD_STRIP,
|
||||
PRIM_TYPE_POLYGON,
|
||||
};
|
||||
|
||||
enum ShaderPolygonMode {
|
||||
POLY_MODE_FILL,
|
||||
POLY_MODE_POINT,
|
||||
POLY_MODE_LINE,
|
||||
};
|
||||
|
||||
enum MaterialColorSource {
|
||||
MATERIAL_COLOR_SRC_MATERIAL,
|
||||
MATERIAL_COLOR_SRC_DIFFUSE,
|
||||
MATERIAL_COLOR_SRC_SPECULAR,
|
||||
};
|
||||
|
||||
typedef struct ShaderState {
|
||||
bool vulkan;
|
||||
bool use_push_constants_for_uniform_attrs;
|
||||
unsigned int surface_scale_factor;
|
||||
|
||||
VshState vsh;
|
||||
PshState psh;
|
||||
uint16_t compressed_attrs;
|
||||
uint16_t uniform_attrs;
|
||||
uint16_t swizzle_attrs;
|
||||
|
||||
bool texture_matrix_enable[4];
|
||||
enum VshTexgen texgen[4][4];
|
||||
|
||||
bool fog_enable;
|
||||
enum VshFoggen foggen;
|
||||
enum VshFogMode fog_mode;
|
||||
|
||||
enum VshSkinning skinning;
|
||||
|
||||
bool normalization;
|
||||
|
||||
enum MaterialColorSource emission_src;
|
||||
enum MaterialColorSource ambient_src;
|
||||
enum MaterialColorSource diffuse_src;
|
||||
enum MaterialColorSource specular_src;
|
||||
|
||||
bool separate_specular;
|
||||
bool ignore_specular_alpha;
|
||||
bool local_eye;
|
||||
float specular_power;
|
||||
float specular_power_back;
|
||||
|
||||
bool lighting;
|
||||
enum VshLight light[NV2A_MAX_LIGHTS];
|
||||
|
||||
bool fixed_function;
|
||||
bool specular_enable;
|
||||
|
||||
/* vertex program */
|
||||
bool vertex_program;
|
||||
uint32_t program_data[NV2A_MAX_TRANSFORM_PROGRAM_LENGTH][VSH_TOKEN_SIZE];
|
||||
int program_length;
|
||||
bool z_perspective;
|
||||
|
||||
/* primitive format for geometry shader */
|
||||
enum ShaderPolygonMode polygon_front_mode;
|
||||
enum ShaderPolygonMode polygon_back_mode;
|
||||
enum ShaderPrimitiveMode primitive_mode;
|
||||
|
||||
bool point_params_enable;
|
||||
float point_size;
|
||||
float point_params[8];
|
||||
|
||||
bool smooth_shading;
|
||||
} ShaderState;
|
||||
|
||||
typedef struct PGRAPHState PGRAPHState;
|
||||
|
||||
@ -51,8 +51,8 @@ static VkPrimitiveTopology get_primitive_topology(PGRAPHState *pg)
|
||||
{
|
||||
PGRAPHVkState *r = pg->vk_renderer_state;
|
||||
|
||||
int polygon_mode = r->shader_binding->state.polygon_front_mode;
|
||||
int primitive_mode = r->shader_binding->state.primitive_mode;
|
||||
int polygon_mode = r->shader_binding->state.vsh.polygon_front_mode;
|
||||
int primitive_mode = r->shader_binding->state.vsh.primitive_mode;
|
||||
|
||||
if (polygon_mode == POLY_MODE_POINT) {
|
||||
return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
|
||||
@ -816,7 +816,7 @@ static void create_pipeline(PGRAPHState *pg)
|
||||
.depthClampEnable = VK_TRUE,
|
||||
.rasterizerDiscardEnable = VK_FALSE,
|
||||
.polygonMode = pgraph_polygon_mode_vk_map[r->shader_binding->state
|
||||
.polygon_front_mode],
|
||||
.vsh.polygon_front_mode],
|
||||
.lineWidth = 1.0f,
|
||||
.frontFace = (pgraph_reg_r(pg, NV_PGRAPH_SETUPRASTER) &
|
||||
NV_PGRAPH_SETUPRASTER_FRONTFACE) ?
|
||||
@ -951,11 +951,11 @@ static void create_pipeline(PGRAPHState *pg)
|
||||
int num_dynamic_states = 2;
|
||||
|
||||
snode->has_dynamic_line_width =
|
||||
(r->enabled_physical_device_features.wideLines == VK_TRUE)
|
||||
&& (r->shader_binding->state.polygon_front_mode == POLY_MODE_LINE ||
|
||||
r->shader_binding->state.primitive_mode == PRIM_TYPE_LINES ||
|
||||
r->shader_binding->state.primitive_mode == PRIM_TYPE_LINE_LOOP ||
|
||||
r->shader_binding->state.primitive_mode == PRIM_TYPE_LINE_STRIP);
|
||||
(r->enabled_physical_device_features.wideLines == VK_TRUE) &&
|
||||
(r->shader_binding->state.vsh.polygon_front_mode == POLY_MODE_LINE ||
|
||||
r->shader_binding->state.vsh.primitive_mode == PRIM_TYPE_LINES ||
|
||||
r->shader_binding->state.vsh.primitive_mode == PRIM_TYPE_LINE_LOOP ||
|
||||
r->shader_binding->state.vsh.primitive_mode == PRIM_TYPE_LINE_STRIP);
|
||||
if (snode->has_dynamic_line_width) {
|
||||
dynamic_states[num_dynamic_states++] = VK_DYNAMIC_STATE_LINE_WIDTH;
|
||||
}
|
||||
@ -1012,9 +1012,9 @@ static void create_pipeline(PGRAPHState *pg)
|
||||
};
|
||||
|
||||
VkPushConstantRange push_constant_range;
|
||||
if (r->shader_binding->state.use_push_constants_for_uniform_attrs) {
|
||||
if (r->shader_binding->state.vsh.use_push_constants_for_uniform_attrs) {
|
||||
int num_uniform_attributes =
|
||||
__builtin_popcount(r->shader_binding->state.uniform_attrs);
|
||||
__builtin_popcount(r->shader_binding->state.vsh.uniform_attrs);
|
||||
if (num_uniform_attributes) {
|
||||
push_constant_range = (VkPushConstantRange){
|
||||
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
|
||||
@ -1067,7 +1067,7 @@ static void push_vertex_attr_values(PGRAPHState *pg)
|
||||
{
|
||||
PGRAPHVkState *r = pg->vk_renderer_state;
|
||||
|
||||
if (!r->shader_binding->state.use_push_constants_for_uniform_attrs) {
|
||||
if (!r->shader_binding->state.vsh.use_push_constants_for_uniform_attrs) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1076,8 +1076,8 @@ static void push_vertex_attr_values(PGRAPHState *pg)
|
||||
float values[NV2A_VERTEXSHADER_ATTRIBUTES][4];
|
||||
int num_uniform_attrs = 0;
|
||||
|
||||
pgraph_get_inline_values(pg, r->shader_binding->state.uniform_attrs, values,
|
||||
&num_uniform_attrs);
|
||||
pgraph_get_inline_values(pg, r->shader_binding->state.vsh.uniform_attrs,
|
||||
values, &num_uniform_attrs);
|
||||
|
||||
if (num_uniform_attrs > 0) {
|
||||
vkCmdPushConstants(r->command_buffer, r->pipeline_binding->layout,
|
||||
|
||||
@ -405,8 +405,8 @@ static ShaderBinding *gen_shaders(PGRAPHState *pg, ShaderState *state)
|
||||
setlocale(LC_NUMERIC, "C");
|
||||
|
||||
MString *geometry_shader_code = pgraph_gen_geom_glsl(
|
||||
state->polygon_front_mode, state->polygon_back_mode,
|
||||
state->primitive_mode, state->smooth_shading, true);
|
||||
state->vsh.polygon_front_mode, state->vsh.polygon_back_mode,
|
||||
state->vsh.primitive_mode, state->vsh.smooth_shading, true);
|
||||
if (geometry_shader_code) {
|
||||
NV2A_VK_DPRINTF("geometry shader: \n%s",
|
||||
mstring_get_str(geometry_shader_code));
|
||||
@ -419,7 +419,7 @@ static ShaderBinding *gen_shaders(PGRAPHState *pg, ShaderState *state)
|
||||
}
|
||||
|
||||
MString *vertex_shader_code =
|
||||
pgraph_gen_vsh_glsl(state, geometry_shader_code != NULL);
|
||||
pgraph_gen_vsh_glsl(&state->vsh, geometry_shader_code != NULL);
|
||||
NV2A_VK_DPRINTF("vertex shader: \n%s",
|
||||
mstring_get_str(vertex_shader_code));
|
||||
snode->vertex = pgraph_vk_create_shader_module_from_glsl(
|
||||
@ -453,7 +453,7 @@ static void update_uniform_attr_values(PGRAPHState *pg, ShaderBinding *binding)
|
||||
float values[NV2A_VERTEXSHADER_ATTRIBUTES][4];
|
||||
int num_uniform_attrs = 0;
|
||||
|
||||
pgraph_get_inline_values(pg, binding->state.uniform_attrs, values,
|
||||
pgraph_get_inline_values(pg, binding->state.vsh.uniform_attrs, values,
|
||||
&num_uniform_attrs);
|
||||
|
||||
if (num_uniform_attrs > 0) {
|
||||
@ -463,9 +463,7 @@ static void update_uniform_attr_values(PGRAPHState *pg, ShaderBinding *binding)
|
||||
}
|
||||
|
||||
// FIXME: Move to common
|
||||
static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding,
|
||||
bool binding_changed, bool vertex_program,
|
||||
bool fixed_function)
|
||||
static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding)
|
||||
{
|
||||
ShaderState *state = &binding->state;
|
||||
|
||||
@ -548,7 +546,10 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding,
|
||||
if (loc != -1) {
|
||||
assert(pg->vk_renderer_state->texture_bindings[i] != NULL);
|
||||
float scale = pg->vk_renderer_state->texture_bindings[i]->key.scale;
|
||||
BasicColorFormatInfo f_basic = kelvin_color_format_info_map[pg->vk_renderer_state->texture_bindings[i]->key.state.color_format];
|
||||
BasicColorFormatInfo f_basic =
|
||||
kelvin_color_format_info_map[pg->vk_renderer_state
|
||||
->texture_bindings[i]
|
||||
->key.state.color_format];
|
||||
if (!f_basic.linear) {
|
||||
scale = 1.0;
|
||||
}
|
||||
@ -592,7 +593,7 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding,
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if (fixed_function) {
|
||||
if (binding->state.vsh.is_fixed_function) {
|
||||
/* update lighting constants */
|
||||
struct {
|
||||
uint32_t *v;
|
||||
@ -733,7 +734,8 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding,
|
||||
pg->material_alpha);
|
||||
}
|
||||
|
||||
if (!state->use_push_constants_for_uniform_attrs && state->uniform_attrs) {
|
||||
if (!state->vsh.use_push_constants_for_uniform_attrs &&
|
||||
state->vsh.uniform_attrs) {
|
||||
update_uniform_attr_values(pg, binding);
|
||||
}
|
||||
}
|
||||
@ -786,22 +788,29 @@ static bool check_shaders_dirty(PGRAPHState *pg)
|
||||
}
|
||||
|
||||
ShaderState *state = &r->shader_binding->state;
|
||||
if (pg->uniform_attrs != state->uniform_attrs ||
|
||||
pg->swizzle_attrs != state->swizzle_attrs ||
|
||||
pg->compressed_attrs != state->compressed_attrs ||
|
||||
pg->primitive_mode != state->primitive_mode ||
|
||||
pg->surface_scale_factor != state->surface_scale_factor) {
|
||||
if (pg->uniform_attrs != state->vsh.uniform_attrs ||
|
||||
pg->swizzle_attrs != state->vsh.swizzle_attrs ||
|
||||
pg->compressed_attrs != state->vsh.compressed_attrs ||
|
||||
pg->primitive_mode != state->vsh.primitive_mode ||
|
||||
pg->surface_scale_factor != state->vsh.surface_scale_factor) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Textures
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (pg->texture_matrix_enable[i] != pg->vk_renderer_state->shader_binding->state.texture_matrix_enable[i] ||
|
||||
pgraph_is_reg_dirty(pg, NV_PGRAPH_TEXCTL0_0 + i * 4) ||
|
||||
if (pgraph_is_reg_dirty(pg, NV_PGRAPH_TEXCTL0_0 + i * 4) ||
|
||||
pgraph_is_reg_dirty(pg, NV_PGRAPH_TEXFILTER0 + i * 4) ||
|
||||
pgraph_is_reg_dirty(pg, NV_PGRAPH_TEXFMT0 + i * 4)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pg->vk_renderer_state->shader_binding->state.vsh
|
||||
.is_fixed_function &&
|
||||
(pg->texture_matrix_enable[i] !=
|
||||
pg->vk_renderer_state->shader_binding->state.vsh.fixed_function
|
||||
.texture_matrix_enable[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
nv2a_profile_inc_counter(NV2A_PROF_SHADER_BIND_NOTDIRTY);
|
||||
@ -821,11 +830,11 @@ void pgraph_vk_bind_shaders(PGRAPHState *pg)
|
||||
ShaderState new_state;
|
||||
memset(&new_state, 0, sizeof(ShaderState));
|
||||
new_state = pgraph_get_shader_state(pg);
|
||||
new_state.vulkan = true;
|
||||
new_state.psh.vulkan = true;
|
||||
new_state.use_push_constants_for_uniform_attrs =
|
||||
new_state.vsh.vulkan = true;
|
||||
new_state.vsh.use_push_constants_for_uniform_attrs =
|
||||
(r->device_props.limits.maxPushConstantsSize >=
|
||||
MAX_UNIFORM_ATTR_VALUES_SIZE);
|
||||
new_state.psh.vulkan = true;
|
||||
|
||||
if (!r->shader_binding || memcmp(&r->shader_binding->state, &new_state, sizeof(ShaderState))) {
|
||||
r->shader_binding = gen_shaders(pg, &new_state);
|
||||
@ -849,9 +858,7 @@ void pgraph_vk_update_shader_uniforms(PGRAPHState *pg)
|
||||
ShaderBinding *binding = r->shader_binding;
|
||||
ShaderUniformLayout *layouts[] = { &binding->vertex->uniforms,
|
||||
&binding->fragment->uniforms };
|
||||
shader_update_constants(pg, r->shader_binding, true,
|
||||
r->shader_binding->state.vertex_program,
|
||||
r->shader_binding->state.fixed_function);
|
||||
shader_update_constants(pg, r->shader_binding);
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(layouts); i++) {
|
||||
uint64_t hash = fast_hash(layouts[i]->allocation, layouts[i]->total_size);
|
||||
|
||||
@ -20,8 +20,8 @@
|
||||
#ifndef HW_NV2A_VSH_H
|
||||
#define HW_NV2A_VSH_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "qemu/mstring.h"
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/xbox/nv2a/nv2a_regs.h"
|
||||
|
||||
enum VshLight {
|
||||
LIGHT_OFF,
|
||||
@ -128,4 +128,82 @@ typedef enum {
|
||||
|
||||
uint8_t vsh_get_field(const uint32_t *shader_token, VshFieldName field_name);
|
||||
|
||||
enum ShaderPrimitiveMode {
|
||||
PRIM_TYPE_INVALID,
|
||||
PRIM_TYPE_POINTS,
|
||||
PRIM_TYPE_LINES,
|
||||
PRIM_TYPE_LINE_LOOP,
|
||||
PRIM_TYPE_LINE_STRIP,
|
||||
PRIM_TYPE_TRIANGLES,
|
||||
PRIM_TYPE_TRIANGLE_STRIP,
|
||||
PRIM_TYPE_TRIANGLE_FAN,
|
||||
PRIM_TYPE_QUADS,
|
||||
PRIM_TYPE_QUAD_STRIP,
|
||||
PRIM_TYPE_POLYGON,
|
||||
};
|
||||
|
||||
enum ShaderPolygonMode {
|
||||
POLY_MODE_FILL,
|
||||
POLY_MODE_POINT,
|
||||
POLY_MODE_LINE,
|
||||
};
|
||||
|
||||
enum MaterialColorSource {
|
||||
MATERIAL_COLOR_SRC_MATERIAL,
|
||||
MATERIAL_COLOR_SRC_DIFFUSE,
|
||||
MATERIAL_COLOR_SRC_SPECULAR,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
bool vulkan;
|
||||
bool use_push_constants_for_uniform_attrs;
|
||||
unsigned int surface_scale_factor; // FIXME: Remove
|
||||
|
||||
uint16_t compressed_attrs;
|
||||
uint16_t uniform_attrs;
|
||||
uint16_t swizzle_attrs;
|
||||
|
||||
/* primitive format for geometry shader */
|
||||
enum ShaderPolygonMode polygon_front_mode;
|
||||
enum ShaderPolygonMode polygon_back_mode;
|
||||
enum ShaderPrimitiveMode primitive_mode;
|
||||
|
||||
bool is_fixed_function;
|
||||
struct {
|
||||
bool normalization;
|
||||
bool texture_matrix_enable[4];
|
||||
enum VshTexgen texgen[4][4];
|
||||
enum VshFoggen foggen;
|
||||
enum VshSkinning skinning;
|
||||
bool lighting;
|
||||
enum VshLight light[NV2A_MAX_LIGHTS];
|
||||
enum MaterialColorSource emission_src;
|
||||
enum MaterialColorSource ambient_src;
|
||||
enum MaterialColorSource diffuse_src;
|
||||
enum MaterialColorSource specular_src;
|
||||
bool local_eye;
|
||||
} fixed_function;
|
||||
|
||||
struct {
|
||||
uint32_t program_data[NV2A_MAX_TRANSFORM_PROGRAM_LENGTH]
|
||||
[VSH_TOKEN_SIZE];
|
||||
int program_length;
|
||||
} programmable;
|
||||
|
||||
bool fog_enable;
|
||||
enum VshFogMode fog_mode;
|
||||
bool specular_enable;
|
||||
bool separate_specular;
|
||||
bool ignore_specular_alpha;
|
||||
float specular_power;
|
||||
float specular_power_back;
|
||||
|
||||
bool z_perspective;
|
||||
bool point_params_enable;
|
||||
float point_size;
|
||||
float point_params[8];
|
||||
|
||||
bool smooth_shading;
|
||||
} VshState;
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user