From cbcb7c2181b65b69180f17bf4f0087e94272c827 Mon Sep 17 00:00:00 2001 From: Matt Borgerson Date: Sat, 28 Jun 2025 00:08:46 -0700 Subject: [PATCH] nv2a/glsl: Factor out geometry state to GeomState --- hw/xbox/nv2a/pgraph/gl/shaders.c | 8 ++++---- hw/xbox/nv2a/pgraph/glsl/geom.c | 21 +++++++++++++++++++-- hw/xbox/nv2a/pgraph/glsl/geom.h | 15 ++++++++++++--- hw/xbox/nv2a/pgraph/glsl/shaders.c | 3 ++- hw/xbox/nv2a/pgraph/glsl/shaders.h | 3 ++- hw/xbox/nv2a/pgraph/glsl/vsh.c | 9 --------- hw/xbox/nv2a/pgraph/glsl/vsh.h | 5 ----- hw/xbox/nv2a/pgraph/vk/draw.c | 14 +++++++------- hw/xbox/nv2a/pgraph/vk/shaders.c | 2 +- 9 files changed, 47 insertions(+), 33 deletions(-) diff --git a/hw/xbox/nv2a/pgraph/gl/shaders.c b/hw/xbox/nv2a/pgraph/gl/shaders.c index 22304895a7..55cda01500 100644 --- a/hw/xbox/nv2a/pgraph/gl/shaders.c +++ b/hw/xbox/nv2a/pgraph/gl/shaders.c @@ -145,9 +145,9 @@ static void generate_shaders(ShaderBinding *binding) /* Create an optional geometry shader and find primitive type */ GLenum gl_primitive_mode = get_gl_primitive_mode( - state->vsh.polygon_front_mode, state->vsh.primitive_mode); + state->geom.polygon_front_mode, state->geom.primitive_mode); MString *geometry_shader_code = - pgraph_gen_geom_glsl(&state->vsh, (GenGeomGlslOptions){ 0 }); + pgraph_gen_geom_glsl(&state->geom, (GenGeomGlslOptions){ 0 }); if (geometry_shader_code) { const char* geometry_shader_code_str = mstring_get_str(geometry_shader_code); @@ -303,8 +303,8 @@ bool pgraph_gl_shader_load_from_memory(ShaderBinding *binding) binding->gl_program = gl_program; binding->gl_primitive_mode = - get_gl_primitive_mode(binding->state.vsh.polygon_front_mode, - binding->state.vsh.primitive_mode); + get_gl_primitive_mode(binding->state.geom.polygon_front_mode, + binding->state.geom.primitive_mode); binding->initialized = true; g_free(binding->program); diff --git a/hw/xbox/nv2a/pgraph/glsl/geom.c b/hw/xbox/nv2a/pgraph/glsl/geom.c index ebcc678e00..b0a9577da6 100644 --- a/hw/xbox/nv2a/pgraph/glsl/geom.c +++ b/hw/xbox/nv2a/pgraph/glsl/geom.c @@ -19,10 +19,27 @@ * License along with this library; if not, see . */ -#include "common.h" +#include "qemu/osdep.h" +#include "hw/xbox/nv2a/pgraph/pgraph.h" #include "geom.h" -MString *pgraph_gen_geom_glsl(const VshState *state, GenGeomGlslOptions opts) +void pgraph_set_geom_state(PGRAPHState *pg, GeomState *state) +{ + state->primitive_mode = (enum ShaderPrimitiveMode)pg->primitive_mode; + + state->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( + pgraph_reg_r(pg, NV_PGRAPH_SETUPRASTER), + NV_PGRAPH_SETUPRASTER_BACKFACEMODE); + + state->smooth_shading = GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CONTROL_3), + NV_PGRAPH_CONTROL_3_SHADEMODE) == + NV_PGRAPH_CONTROL_3_SHADEMODE_SMOOTH; +} + +MString *pgraph_gen_geom_glsl(const GeomState *state, GenGeomGlslOptions opts) { /* FIXME: Missing support for 2-sided-poly mode */ assert(state->polygon_front_mode == state->polygon_back_mode); diff --git a/hw/xbox/nv2a/pgraph/glsl/geom.h b/hw/xbox/nv2a/pgraph/glsl/geom.h index b2bcfb3ef0..77e28095e7 100644 --- a/hw/xbox/nv2a/pgraph/glsl/geom.h +++ b/hw/xbox/nv2a/pgraph/glsl/geom.h @@ -22,13 +22,22 @@ #ifndef HW_XBOX_NV2A_PGRAPH_GLSL_GEOM_H #define HW_XBOX_NV2A_PGRAPH_GLSL_GEOM_H -#include "qemu/mstring.h" -#include "vsh.h" +#include "common.h" +#include "hw/xbox/nv2a/pgraph/vsh_regs.h" + +typedef struct { + enum ShaderPrimitiveMode primitive_mode; + enum ShaderPolygonMode polygon_front_mode; + enum ShaderPolygonMode polygon_back_mode; + bool smooth_shading; +} GeomState; typedef struct GenGeomGlslOptions { bool vulkan; } GenGeomGlslOptions; -MString *pgraph_gen_geom_glsl(const VshState *state, GenGeomGlslOptions opts); +void pgraph_set_geom_state(PGRAPHState *pg, GeomState *geom); + +MString *pgraph_gen_geom_glsl(const GeomState *state, GenGeomGlslOptions opts); #endif diff --git a/hw/xbox/nv2a/pgraph/glsl/shaders.c b/hw/xbox/nv2a/pgraph/glsl/shaders.c index 8ed959f69d..ee42843ec8 100644 --- a/hw/xbox/nv2a/pgraph/glsl/shaders.c +++ b/hw/xbox/nv2a/pgraph/glsl/shaders.c @@ -30,6 +30,7 @@ ShaderState pgraph_get_shader_state(PGRAPHState *pg) memset(&state, 0, sizeof(ShaderState)); pgraph_set_vsh_state(pg, &state.vsh); + pgraph_set_geom_state(pg, &state.geom); pgraph_set_psh_state(pg, &state.psh); return state; @@ -70,7 +71,7 @@ bool pgraph_check_shader_state_dirty(PGRAPHState *pg, const ShaderState *state) 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->primitive_mode != state->geom.primitive_mode || pg->surface_scale_factor != state->vsh.surface_scale_factor) { return true; } diff --git a/hw/xbox/nv2a/pgraph/glsl/shaders.h b/hw/xbox/nv2a/pgraph/glsl/shaders.h index 4712557f2e..5241ea8240 100644 --- a/hw/xbox/nv2a/pgraph/glsl/shaders.h +++ b/hw/xbox/nv2a/pgraph/glsl/shaders.h @@ -20,12 +20,13 @@ #ifndef HW_XBOX_NV2A_PGRAPH_GLSL_SHADERS_H #define HW_XBOX_NV2A_PGRAPH_GLSL_SHADERS_H -#include "geom.h" #include "vsh.h" +#include "geom.h" #include "psh.h" typedef struct ShaderState { VshState vsh; + GeomState geom; PshState psh; } ShaderState; diff --git a/hw/xbox/nv2a/pgraph/glsl/vsh.c b/hw/xbox/nv2a/pgraph/glsl/vsh.c index 17a33d51d0..a497925d9d 100644 --- a/hw/xbox/nv2a/pgraph/glsl/vsh.c +++ b/hw/xbox/nv2a/pgraph/glsl/vsh.c @@ -153,15 +153,6 @@ void pgraph_set_vsh_state(PGRAPHState *pg, VshState *vsh) NV_PGRAPH_CONTROL_3_FOG_MODE); } - /* geometry shader stuff */ - 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); - vsh->is_fixed_function = fixed_function; if (fixed_function) { set_fixed_function_vsh_state(pg, &vsh->fixed_function); diff --git a/hw/xbox/nv2a/pgraph/glsl/vsh.h b/hw/xbox/nv2a/pgraph/glsl/vsh.h index 790147107e..adfb164cc6 100644 --- a/hw/xbox/nv2a/pgraph/glsl/vsh.h +++ b/hw/xbox/nv2a/pgraph/glsl/vsh.h @@ -54,11 +54,6 @@ typedef struct { 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 fog_enable; enum VshFogMode fog_mode; diff --git a/hw/xbox/nv2a/pgraph/vk/draw.c b/hw/xbox/nv2a/pgraph/vk/draw.c index e4b5ad6ed9..6fa13296e8 100644 --- a/hw/xbox/nv2a/pgraph/vk/draw.c +++ b/hw/xbox/nv2a/pgraph/vk/draw.c @@ -51,8 +51,8 @@ static VkPrimitiveTopology get_primitive_topology(PGRAPHState *pg) { PGRAPHVkState *r = pg->vk_renderer_state; - int polygon_mode = r->shader_binding->state.vsh.polygon_front_mode; - int primitive_mode = r->shader_binding->state.vsh.primitive_mode; + int polygon_mode = r->shader_binding->state.geom.polygon_front_mode; + int primitive_mode = r->shader_binding->state.geom.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 - .vsh.polygon_front_mode], + .geom.polygon_front_mode], .lineWidth = 1.0f, .frontFace = (pgraph_reg_r(pg, NV_PGRAPH_SETUPRASTER) & NV_PGRAPH_SETUPRASTER_FRONTFACE) ? @@ -952,10 +952,10 @@ static void create_pipeline(PGRAPHState *pg) snode->has_dynamic_line_width = (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); + (r->shader_binding->state.geom.polygon_front_mode == POLY_MODE_LINE || + r->shader_binding->state.geom.primitive_mode == PRIM_TYPE_LINES || + r->shader_binding->state.geom.primitive_mode == PRIM_TYPE_LINE_LOOP || + r->shader_binding->state.geom.primitive_mode == PRIM_TYPE_LINE_STRIP); if (snode->has_dynamic_line_width) { dynamic_states[num_dynamic_states++] = VK_DYNAMIC_STATE_LINE_WIDTH; } diff --git a/hw/xbox/nv2a/pgraph/vk/shaders.c b/hw/xbox/nv2a/pgraph/vk/shaders.c index 1d1edf2a85..09b63aaef1 100644 --- a/hw/xbox/nv2a/pgraph/vk/shaders.c +++ b/hw/xbox/nv2a/pgraph/vk/shaders.c @@ -329,7 +329,7 @@ static ShaderBinding *gen_shaders(PGRAPHState *pg, ShaderState *state) setlocale(LC_NUMERIC, "C"); MString *geometry_shader_code = pgraph_gen_geom_glsl( - &state->vsh, (GenGeomGlslOptions){ .vulkan = true }); + &state->geom, (GenGeomGlslOptions){ .vulkan = true }); if (geometry_shader_code) { NV2A_VK_DPRINTF("geometry shader: \n%s", mstring_get_str(geometry_shader_code));