mirror of https://github.com/xemu-project/xemu.git
95 lines
3.2 KiB
C
95 lines
3.2 KiB
C
/*
|
|
* Geforce NV2A PGRAPH GLSL Shader Generator
|
|
*
|
|
* Copyright (c) 2025 Matt Borgerson
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "hw/xbox/nv2a/pgraph/pgraph.h"
|
|
#include "shaders.h"
|
|
|
|
ShaderState pgraph_glsl_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));
|
|
|
|
pgraph_glsl_set_vsh_state(pg, &state.vsh);
|
|
pgraph_glsl_set_geom_state(pg, &state.geom);
|
|
pgraph_glsl_set_psh_state(pg, &state.psh);
|
|
|
|
return state;
|
|
}
|
|
|
|
bool pgraph_glsl_check_shader_state_dirty(PGRAPHState *pg,
|
|
const ShaderState *state)
|
|
{
|
|
if (pg->program_data_dirty) {
|
|
return true;
|
|
}
|
|
|
|
unsigned int regs[] = {
|
|
NV_PGRAPH_COMBINECTL, NV_PGRAPH_COMBINESPECFOG0,
|
|
NV_PGRAPH_COMBINESPECFOG1, NV_PGRAPH_CONTROL_0,
|
|
NV_PGRAPH_CONTROL_3, NV_PGRAPH_CSV0_C,
|
|
NV_PGRAPH_CSV0_D, NV_PGRAPH_CSV1_A,
|
|
NV_PGRAPH_CSV1_B, NV_PGRAPH_POINTSIZE,
|
|
NV_PGRAPH_SETUPRASTER, NV_PGRAPH_SHADERCLIPMODE,
|
|
NV_PGRAPH_SHADERCTL, NV_PGRAPH_SHADERPROG,
|
|
NV_PGRAPH_SHADOWCTL, NV_PGRAPH_ZCOMPRESSOCCLUDE,
|
|
};
|
|
for (int i = 0; i < ARRAY_SIZE(regs); i++) {
|
|
if (pgraph_is_reg_dirty(pg, regs[i])) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
int num_stages = pgraph_reg_r(pg, NV_PGRAPH_COMBINECTL) & 0xFF;
|
|
for (int i = 0; i < num_stages; i++) {
|
|
if (pgraph_is_reg_dirty(pg, NV_PGRAPH_COMBINEALPHAI0 + i * 4) ||
|
|
pgraph_is_reg_dirty(pg, NV_PGRAPH_COMBINEALPHAO0 + i * 4) ||
|
|
pgraph_is_reg_dirty(pg, NV_PGRAPH_COMBINECOLORI0 + i * 4) ||
|
|
pgraph_is_reg_dirty(pg, NV_PGRAPH_COMBINECOLORO0 + i * 4)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
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->geom.primitive_mode ||
|
|
pg->surface_scale_factor != state->vsh.surface_scale_factor) {
|
|
return true;
|
|
}
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
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->texture_matrix_enable[i] !=
|
|
state->vsh.fixed_function.texture_matrix_enable[i]) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|