nv2a: Separate VshState and PshState generation

This commit is contained in:
Matt Borgerson 2025-06-28 00:08:45 -07:00 committed by mborgerson
parent 9020913e29
commit 23312f384b
2 changed files with 225 additions and 207 deletions

View File

@ -44,12 +44,89 @@ static uint32_t get_colorkey_mask(unsigned int color_format)
uint32_t pgraph_get_color_key_mask_for_texture(PGRAPHState *pg, int i)
{
assert(i < NV2A_MAX_TEXTURES);
uint32_t fmt = pgraph_reg_r(pg, NV_PGRAPH_TEXFMT0 + i*4);
uint32_t fmt = pgraph_reg_r(pg, NV_PGRAPH_TEXFMT0 + i * 4);
unsigned int color_format = GET_MASK(fmt, NV_PGRAPH_TEXFMT0_COLOR);
return get_colorkey_mask(color_format);
}
ShaderState pgraph_get_shader_state(PGRAPHState *pg)
static void set_fixed_function_vsh_state(PGRAPHState *pg,
FixedFunctionVshState *ff)
{
ff->skinning = (enum VshSkinning)GET_MASK(
pgraph_reg_r(pg, NV_PGRAPH_CSV0_D), NV_PGRAPH_CSV0_D_SKIN);
ff->normalization = pgraph_reg_r(pg, NV_PGRAPH_CSV0_C) &
NV_PGRAPH_CSV0_C_NORMALIZATION_ENABLE;
ff->local_eye =
GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_LOCALEYE);
/* color material */
ff->emission_src = (enum MaterialColorSource)GET_MASK(
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_EMISSION);
ff->ambient_src = (enum MaterialColorSource)GET_MASK(
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_AMBIENT);
ff->diffuse_src = (enum MaterialColorSource)GET_MASK(
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_DIFFUSE);
ff->specular_src = (enum MaterialColorSource)GET_MASK(
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_SPECULAR);
/* Texture matrices */
for (int i = 0; i < 4; i++) {
ff->texture_matrix_enable[i] = pg->texture_matrix_enable[i];
}
/* Texgen */
for (int i = 0; i < 4; i++) {
unsigned int reg = (i < 2) ? NV_PGRAPH_CSV1_A : NV_PGRAPH_CSV1_B;
for (int j = 0; j < 4; j++) {
unsigned int masks[] = {
(i % 2) ? NV_PGRAPH_CSV1_A_T1_S : NV_PGRAPH_CSV1_A_T0_S,
(i % 2) ? NV_PGRAPH_CSV1_A_T1_T : NV_PGRAPH_CSV1_A_T0_T,
(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
};
ff->texgen[i][j] =
(enum VshTexgen)GET_MASK(pgraph_reg_r(pg, reg), masks[j]);
}
}
/* Lighting */
ff->lighting =
GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_LIGHTING);
if (ff->lighting) {
for (int i = 0; i < NV2A_MAX_LIGHTS; i++) {
ff->light[i] =
(enum VshLight)GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CSV0_D),
NV_PGRAPH_CSV0_D_LIGHT0 << (i * 2));
}
}
if (pgraph_reg_r(pg, NV_PGRAPH_CONTROL_3) & NV_PGRAPH_CONTROL_3_FOGENABLE) {
ff->foggen = (enum VshFoggen)GET_MASK(
pgraph_reg_r(pg, NV_PGRAPH_CSV0_D), NV_PGRAPH_CSV0_D_FOGGENMODE);
}
}
static void set_programmable_vsh_state(PGRAPHState *pg,
ProgrammableVshState *prog)
{
int program_start = GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CSV0_C),
NV_PGRAPH_CSV0_C_CHEOPS_PROGRAM_START);
// copy in vertex program tokens
prog->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(&prog->program_data[prog->program_length], cur_token,
VSH_TOKEN_SIZE * sizeof(uint32_t));
prog->program_length++;
if (vsh_get_field(cur_token, FLD_FINAL)) {
break;
}
}
}
static void set_vsh_state(PGRAPHState *pg, VshState *vsh)
{
bool vertex_program = GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CSV0_D),
NV_PGRAPH_CSV0_D_MODE) == 2;
@ -57,194 +134,116 @@ ShaderState pgraph_get_shader_state(PGRAPHState *pg)
bool fixed_function = GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CSV0_D),
NV_PGRAPH_CSV0_D_MODE) == 0;
int program_start = GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CSV0_C),
NV_PGRAPH_CSV0_C_CHEOPS_PROGRAM_START);
assert(vertex_program || fixed_function);
pg->program_data_dirty = false;
vsh->surface_scale_factor = pg->surface_scale_factor; // FIXME
ShaderState state;
vsh->compressed_attrs = pg->compressed_attrs;
vsh->uniform_attrs = pg->uniform_attrs;
vsh->swizzle_attrs = pg->swizzle_attrs;
// We will hash it, so make sure any padding is zeroed
memset(&state, 0, sizeof(ShaderState));
vsh->specular_enable = GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CSV0_C),
NV_PGRAPH_CSV0_C_SPECULAR_ENABLE);
vsh->separate_specular = GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CSV0_C),
NV_PGRAPH_CSV0_C_SEPARATE_SPECULAR);
vsh->ignore_specular_alpha =
!GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CSV0_C),
NV_PGRAPH_CSV0_C_ALPHA_FROM_MATERIAL_SPECULAR);
vsh->specular_power = pg->specular_power;
vsh->specular_power_back = pg->specular_power_back;
state.vsh.surface_scale_factor = pg->surface_scale_factor;
vsh->z_perspective = pgraph_reg_r(pg, NV_PGRAPH_CONTROL_0) &
NV_PGRAPH_CONTROL_0_Z_PERSPECTIVE_ENABLE;
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.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);
state.psh.final_inputs_0 = pgraph_reg_r(pg, NV_PGRAPH_COMBINESPECFOG0);
state.psh.final_inputs_1 = pgraph_reg_r(pg, NV_PGRAPH_COMBINESPECFOG1);
state.psh.alpha_test =
pgraph_reg_r(pg, NV_PGRAPH_CONTROL_0) & NV_PGRAPH_CONTROL_0_ALPHATESTENABLE;
state.psh.alpha_func = (enum PshAlphaFunc)GET_MASK(
pgraph_reg_r(pg, NV_PGRAPH_CONTROL_0), NV_PGRAPH_CONTROL_0_ALPHAFUNC);
state.psh.point_sprite = pgraph_reg_r(pg, NV_PGRAPH_SETUPRASTER) &
NV_PGRAPH_SETUPRASTER_POINTSMOOTHENABLE;
state.psh.shadow_depth_func = (enum PshShadowDepthFunc)GET_MASK(
pgraph_reg_r(pg, NV_PGRAPH_SHADOWCTL), NV_PGRAPH_SHADOWCTL_SHADOW_ZFUNC);
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.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.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.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.vsh.fixed_function.texture_matrix_enable[i] =
pg->texture_matrix_enable[i];
}
/* Texgen */
for (int i = 0; i < 4; i++) {
unsigned int reg = (i < 2) ? NV_PGRAPH_CSV1_A : NV_PGRAPH_CSV1_B;
for (int j = 0; j < 4; j++) {
unsigned int masks[] = {
(i % 2) ? NV_PGRAPH_CSV1_A_T1_S : NV_PGRAPH_CSV1_A_T0_S,
(i % 2) ? NV_PGRAPH_CSV1_A_T1_T : NV_PGRAPH_CSV1_A_T0_T,
(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.vsh.fixed_function.texgen[i][j] =
(enum VshTexgen)GET_MASK(pgraph_reg_r(pg, reg), masks[j]);
}
vsh->point_params_enable = GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CSV0_D),
NV_PGRAPH_CSV0_D_POINTPARAMSENABLE);
vsh->point_size = GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_POINTSIZE),
NV097_SET_POINT_SIZE_V) /
8.0f;
if (vsh->point_params_enable) {
for (int i = 0; i < 8; i++) {
vsh->point_params[i] = pg->point_params[i];
}
}
state.vsh.separate_specular = GET_MASK(
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_SEPARATE_SPECULAR);
state.vsh.ignore_specular_alpha = !GET_MASK(
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_ALPHA_FROM_MATERIAL_SPECULAR);
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.vsh.specular_power = pg->specular_power;
state.vsh.specular_power_back = pg->specular_power_back;
/* vertex program stuff */
state.vsh.z_perspective = pgraph_reg_r(pg, NV_PGRAPH_CONTROL_0) &
NV_PGRAPH_CONTROL_0_Z_PERSPECTIVE_ENABLE;
state.psh.z_perspective = state.vsh.z_perspective;
state.vsh.point_params_enable = GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CSV0_D),
NV_PGRAPH_CSV0_D_POINTPARAMSENABLE);
state.vsh.point_size =
GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_POINTSIZE), NV097_SET_POINT_SIZE_V) / 8.0f;
if (state.vsh.point_params_enable) {
for (int i = 0; i < 8; i++) {
state.vsh.point_params[i] = pg->point_params[i];
}
/* Fog */
vsh->fog_enable =
pgraph_reg_r(pg, NV_PGRAPH_CONTROL_3) & NV_PGRAPH_CONTROL_3_FOGENABLE;
if (vsh->fog_enable) {
/*FIXME: Use CSV0_D? */
vsh->fog_mode =
(enum VshFogMode)GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CONTROL_3),
NV_PGRAPH_CONTROL_3_FOG_MODE);
}
/* geometry shader stuff */
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.vsh.polygon_back_mode = (enum ShaderPolygonMode)GET_MASK(
pgraph_reg_r(pg, NV_PGRAPH_SETUPRASTER), NV_PGRAPH_SETUPRASTER_BACKFACEMODE);
vsh->primitive_mode = (enum ShaderPrimitiveMode)pg->primitive_mode;
vsh->polygon_front_mode = (enum ShaderPolygonMode)GET_MASK(
pgraph_reg_r(pg, NV_PGRAPH_SETUPRASTER),
NV_PGRAPH_SETUPRASTER_FRONTFACEMODE);
vsh->polygon_back_mode = (enum ShaderPolygonMode)GET_MASK(
pgraph_reg_r(pg, NV_PGRAPH_SETUPRASTER),
NV_PGRAPH_SETUPRASTER_BACKFACEMODE);
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.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;
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.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;
}
}
}
/* Fog */
state.vsh.fog_enable =
pgraph_reg_r(pg, NV_PGRAPH_CONTROL_3) & NV_PGRAPH_CONTROL_3_FOGENABLE;
if (state.vsh.fog_enable) {
/*FIXME: Use CSV0_D? */
state.vsh.fog_mode = (enum VshFogMode)GET_MASK(
pgraph_reg_r(pg, NV_PGRAPH_CONTROL_3), NV_PGRAPH_CONTROL_3_FOG_MODE);
state.vsh.fixed_function.foggen = (enum VshFoggen)GET_MASK(
pgraph_reg_r(pg, NV_PGRAPH_CSV0_D), NV_PGRAPH_CSV0_D_FOGGENMODE);
vsh->is_fixed_function = fixed_function;
if (fixed_function) {
set_fixed_function_vsh_state(pg, &vsh->fixed_function);
} else {
/* FIXME: Do we still pass the fogmode? */
state.vsh.fog_mode = (enum VshFogMode)0;
state.vsh.fixed_function.foggen = (enum VshFoggen)0;
set_programmable_vsh_state(pg, &vsh->programmable);
}
}
/* Lighting */
if (state.vsh.fixed_function.lighting) {
for (int i = 0; i < NV2A_MAX_LIGHTS; i++) {
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));
}
}
static void set_psh_state(PGRAPHState *pg, PshState *psh)
{
psh->window_clip_exclusive = pgraph_reg_r(pg, NV_PGRAPH_SETUPRASTER) &
NV_PGRAPH_SETUPRASTER_WINDOWCLIPTYPE;
psh->combiner_control = pgraph_reg_r(pg, NV_PGRAPH_COMBINECTL);
psh->shader_stage_program = pgraph_reg_r(pg, NV_PGRAPH_SHADERPROG);
psh->other_stage_input = pgraph_reg_r(pg, NV_PGRAPH_SHADERCTL);
psh->final_inputs_0 = pgraph_reg_r(pg, NV_PGRAPH_COMBINESPECFOG0);
psh->final_inputs_1 = pgraph_reg_r(pg, NV_PGRAPH_COMBINESPECFOG1);
psh->alpha_test = pgraph_reg_r(pg, NV_PGRAPH_CONTROL_0) &
NV_PGRAPH_CONTROL_0_ALPHATESTENABLE;
psh->alpha_func = (enum PshAlphaFunc)GET_MASK(
pgraph_reg_r(pg, NV_PGRAPH_CONTROL_0), NV_PGRAPH_CONTROL_0_ALPHAFUNC);
psh->point_sprite = pgraph_reg_r(pg, NV_PGRAPH_SETUPRASTER) &
NV_PGRAPH_SETUPRASTER_POINTSMOOTHENABLE;
psh->shadow_depth_func =
(enum PshShadowDepthFunc)GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_SHADOWCTL),
NV_PGRAPH_SHADOWCTL_SHADOW_ZFUNC);
psh->z_perspective = pgraph_reg_r(pg, NV_PGRAPH_CONTROL_0) &
NV_PGRAPH_CONTROL_0_Z_PERSPECTIVE_ENABLE;
psh->smooth_shading = GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CONTROL_3),
NV_PGRAPH_CONTROL_3_SHADEMODE) ==
NV_PGRAPH_CONTROL_3_SHADEMODE_SMOOTH;
psh->depth_clipping = GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_ZCOMPRESSOCCLUDE),
NV_PGRAPH_ZCOMPRESSOCCLUDE_ZCLAMP_EN) ==
NV_PGRAPH_ZCOMPRESSOCCLUDE_ZCLAMP_EN_CULL;
/* 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] =
psh->rgb_inputs[i] = pgraph_reg_r(pg, NV_PGRAPH_COMBINECOLORI0 + i * 4);
psh->rgb_outputs[i] =
pgraph_reg_r(pg, NV_PGRAPH_COMBINECOLORO0 + i * 4);
state.psh.alpha_inputs[i] =
psh->alpha_inputs[i] =
pgraph_reg_r(pg, NV_PGRAPH_COMBINEALPHAI0 + i * 4);
state.psh.alpha_outputs[i] =
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);
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
state.psh.compare_mode[i][j] =
psh->compare_mode[i][j] =
(pgraph_reg_r(pg, NV_PGRAPH_SHADERCLIPMODE) >> (4 * i + j)) & 1;
}
@ -255,24 +254,27 @@ ShaderState pgraph_get_shader_state(PGRAPHState *pg)
continue;
}
state.psh.alphakill[i] = ctl_0 & NV_PGRAPH_TEXCTL0_0_ALPHAKILLEN;
state.psh.colorkey_mode[i] = ctl_0 & NV_PGRAPH_TEXCTL0_0_COLORKEYMODE;
psh->alphakill[i] = ctl_0 & NV_PGRAPH_TEXCTL0_0_ALPHAKILLEN;
psh->colorkey_mode[i] = ctl_0 & NV_PGRAPH_TEXCTL0_0_COLORKEYMODE;
uint32_t tex_fmt = pgraph_reg_r(pg, NV_PGRAPH_TEXFMT0 + i * 4);
state.psh.dim_tex[i] = GET_MASK(tex_fmt, NV_PGRAPH_TEXFMT0_DIMENSIONALITY);
psh->dim_tex[i] = GET_MASK(tex_fmt, NV_PGRAPH_TEXFMT0_DIMENSIONALITY);
unsigned int color_format = GET_MASK(tex_fmt, NV_PGRAPH_TEXFMT0_COLOR);
BasicColorFormatInfo f = kelvin_color_format_info_map[color_format];
state.psh.rect_tex[i] = f.linear;
state.psh.tex_x8y24[i] = color_format == NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_DEPTH_X8_Y24_FIXED ||
color_format == NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_DEPTH_X8_Y24_FLOAT;
psh->rect_tex[i] = f.linear;
psh->tex_x8y24[i] =
color_format ==
NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_DEPTH_X8_Y24_FIXED ||
color_format ==
NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_DEPTH_X8_Y24_FLOAT;
uint32_t border_source =
GET_MASK(tex_fmt, NV_PGRAPH_TEXFMT0_BORDER_SOURCE);
bool cubemap = GET_MASK(tex_fmt, NV_PGRAPH_TEXFMT0_CUBEMAPENABLE);
state.psh.border_logical_size[i][0] = 0.0f;
state.psh.border_logical_size[i][1] = 0.0f;
state.psh.border_logical_size[i][2] = 0.0f;
psh->border_logical_size[i][0] = 0.0f;
psh->border_logical_size[i][1] = 0.0f;
psh->border_logical_size[i][2] = 0.0f;
if (border_source != NV_PGRAPH_TEXFMT0_BORDER_SOURCE_COLOR) {
if (!f.linear && !cubemap) {
// The actual texture will be (at least) double the reported
@ -285,26 +287,26 @@ ShaderState pgraph_get_shader_state(PGRAPHState *pg)
unsigned int reported_depth =
1 << GET_MASK(tex_fmt, NV_PGRAPH_TEXFMT0_BASE_SIZE_P);
state.psh.border_logical_size[i][0] = reported_width;
state.psh.border_logical_size[i][1] = reported_height;
state.psh.border_logical_size[i][2] = reported_depth;
psh->border_logical_size[i][0] = reported_width;
psh->border_logical_size[i][1] = reported_height;
psh->border_logical_size[i][2] = reported_depth;
if (reported_width < 8) {
state.psh.border_inv_real_size[i][0] = 0.0625f;
psh->border_inv_real_size[i][0] = 0.0625f;
} else {
state.psh.border_inv_real_size[i][0] =
psh->border_inv_real_size[i][0] =
1.0f / (reported_width * 2.0f);
}
if (reported_height < 8) {
state.psh.border_inv_real_size[i][1] = 0.0625f;
psh->border_inv_real_size[i][1] = 0.0625f;
} else {
state.psh.border_inv_real_size[i][1] =
psh->border_inv_real_size[i][1] =
1.0f / (reported_height * 2.0f);
}
if (reported_depth < 8) {
state.psh.border_inv_real_size[i][2] = 0.0625f;
psh->border_inv_real_size[i][2] = 0.0625f;
} else {
state.psh.border_inv_real_size[i][2] =
psh->border_inv_real_size[i][2] =
1.0f / (reported_depth * 2.0f);
}
} else {
@ -324,10 +326,10 @@ ShaderState pgraph_get_shader_state(PGRAPHState *pg)
* support signed textures more appropriately.
*/
#if 0 // FIXME
state.psh.snorm_tex[i] = (f.gl_internal_format == GL_RGB8_SNORM)
psh->snorm_tex[i] = (f.gl_internal_format == GL_RGB8_SNORM)
|| (f.gl_internal_format == GL_RG8_SNORM);
#endif
state.psh.shadow_map[i] = f.depth;
psh->shadow_map[i] = f.depth;
uint32_t filter = pgraph_reg_r(pg, NV_PGRAPH_TEXFILTER0 + i * 4);
unsigned int min_filter = GET_MASK(filter, NV_PGRAPH_TEXFILTER0_MIN);
@ -343,8 +345,21 @@ ShaderState pgraph_get_shader_state(PGRAPHState *pg)
kernel = (enum ConvolutionFilter)k;
}
state.psh.conv_tex[i] = kernel;
psh->conv_tex[i] = kernel;
}
}
ShaderState pgraph_get_shader_state(PGRAPHState *pg)
{
pg->program_data_dirty = false; /* fixme */
ShaderState state;
// We will hash it, so make sure any padding is zeroed
memset(&state, 0, sizeof(ShaderState));
set_vsh_state(pg, &state.vsh);
set_psh_state(pg, &state.psh);
return state;
}

View File

@ -154,6 +154,26 @@ enum MaterialColorSource {
MATERIAL_COLOR_SRC_SPECULAR,
};
typedef struct FixedFunctionVshState {
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;
} FixedFunctionVshState;
typedef struct ProgrammableVshState {
uint32_t program_data[NV2A_MAX_TRANSFORM_PROGRAM_LENGTH][VSH_TOKEN_SIZE];
int program_length;
} ProgrammableVshState;
typedef struct {
unsigned int surface_scale_factor; // FIXME: Remove
@ -166,42 +186,25 @@ typedef struct {
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;
bool z_perspective;
bool is_fixed_function;
FixedFunctionVshState fixed_function;
ProgrammableVshState programmable;
} VshState;
#endif