diff --git a/hw/xbox/nv2a/pgraph/gl/renderer.h b/hw/xbox/nv2a/pgraph/gl/renderer.h index 2a759ba22f..0475986ef1 100644 --- a/hw/xbox/nv2a/pgraph/gl/renderer.h +++ b/hw/xbox/nv2a/pgraph/gl/renderer.h @@ -96,40 +96,40 @@ typedef struct ShaderBinding { GLuint gl_program; GLenum gl_primitive_mode; - GLint psh_constant_loc[9][2]; - GLint alpha_ref_loc; - - GLint bump_mat_loc[NV2A_MAX_TEXTURES]; - GLint bump_scale_loc[NV2A_MAX_TEXTURES]; - GLint bump_offset_loc[NV2A_MAX_TEXTURES]; - GLint tex_scale_loc[NV2A_MAX_TEXTURES]; - - GLint surface_size_loc; - GLint clip_range_loc; - GLint depth_offset_loc; - - GLint vsh_constant_loc[NV2A_VERTEXSHADER_CONSTANTS]; uint32_t vsh_constants[NV2A_VERTEXSHADER_CONSTANTS][4]; - GLint ltctxa_loc[NV2A_LTCTXA_COUNT]; - GLint ltctxb_loc[NV2A_LTCTXB_COUNT]; - GLint ltc1_loc[NV2A_LTC1_COUNT]; + struct { + struct { + GLint alpha_ref; + GLint bump_mat[NV2A_MAX_TEXTURES]; + GLint bump_offset[NV2A_MAX_TEXTURES]; + GLint bump_scale[NV2A_MAX_TEXTURES]; + GLint clip_range; + GLint clip_region[8]; + GLint color_key[4]; + GLint color_key_mask[4]; + GLint depth_offset; + GLint fog_color; + GLint psh_constant[9][2]; + GLint surface_size; + GLint tex_scale[NV2A_MAX_TEXTURES]; + } psh; - GLint fog_color_loc; - GLint fog_param_loc; - GLint light_infinite_half_vector_loc[NV2A_MAX_LIGHTS]; - GLint light_infinite_direction_loc[NV2A_MAX_LIGHTS]; - GLint light_local_position_loc[NV2A_MAX_LIGHTS]; - GLint light_local_attenuation_loc[NV2A_MAX_LIGHTS]; - int specular_power_loc; - - GLint clip_region_loc[8]; - - GLint point_params_loc[8]; - GLint material_alpha_loc; - - GLint color_key_loc[4]; - GLint color_key_mask_loc[4]; + struct { + GLint fog_param; + GLint light_infinite_direction[NV2A_MAX_LIGHTS]; + GLint light_infinite_half_vector[NV2A_MAX_LIGHTS]; + GLint light_local_attenuation[NV2A_MAX_LIGHTS]; + GLint light_local_position[NV2A_MAX_LIGHTS]; + GLint ltc1[NV2A_LTC1_COUNT]; + GLint ltctxa[NV2A_LTCTXA_COUNT]; + GLint ltctxb[NV2A_LTCTXB_COUNT]; + GLint material_alpha; + GLint point_params[8]; + GLint vsh_constant[NV2A_VERTEXSHADER_CONSTANTS]; + int specular_power; + } vsh; + } uniform_locs; } ShaderBinding; typedef struct VertexKey { diff --git a/hw/xbox/nv2a/pgraph/gl/shaders.c b/hw/xbox/nv2a/pgraph/gl/shaders.c index 2b387aecaa..080ee48817 100644 --- a/hw/xbox/nv2a/pgraph/gl/shaders.c +++ b/hw/xbox/nv2a/pgraph/gl/shaders.c @@ -108,7 +108,8 @@ static void update_shader_constant_locations(ShaderBinding *binding) for (int i = 0; i < NV2A_MAX_TEXTURES; i++) { char samplerName[16]; snprintf(samplerName, sizeof(samplerName), "texSamp%d", i); - GLint texSampLoc = glGetUniformLocation(binding->gl_program, samplerName); + GLint texSampLoc = + glGetUniformLocation(binding->gl_program, samplerName); if (texSampLoc >= 0) { glUniform1i(texSampLoc, i); } @@ -118,89 +119,107 @@ static void update_shader_constant_locations(ShaderBinding *binding) for (int i = 0; i < 9; i++) { for (int j = 0; j < 2; j++) { snprintf(tmp, sizeof(tmp), "c%d_%d", j, i); - binding->psh_constant_loc[i][j] = glGetUniformLocation(binding->gl_program, tmp); + binding->uniform_locs.psh.psh_constant[i][j] = + glGetUniformLocation(binding->gl_program, tmp); } } - binding->alpha_ref_loc = glGetUniformLocation(binding->gl_program, "alphaRef"); + binding->uniform_locs.psh.alpha_ref = + glGetUniformLocation(binding->gl_program, "alphaRef"); for (int i = 1; i < NV2A_MAX_TEXTURES; i++) { snprintf(tmp, sizeof(tmp), "bumpMat%d", i); - binding->bump_mat_loc[i] = glGetUniformLocation(binding->gl_program, tmp); + binding->uniform_locs.psh.bump_mat[i] = + glGetUniformLocation(binding->gl_program, tmp); snprintf(tmp, sizeof(tmp), "bumpScale%d", i); - binding->bump_scale_loc[i] = glGetUniformLocation(binding->gl_program, tmp); + binding->uniform_locs.psh.bump_scale[i] = + glGetUniformLocation(binding->gl_program, tmp); snprintf(tmp, sizeof(tmp), "bumpOffset%d", i); - binding->bump_offset_loc[i] = glGetUniformLocation(binding->gl_program, tmp); + binding->uniform_locs.psh.bump_offset[i] = + glGetUniformLocation(binding->gl_program, tmp); } for (int i = 0; i < NV2A_MAX_TEXTURES; i++) { snprintf(tmp, sizeof(tmp), "texScale%d", i); - binding->tex_scale_loc[i] = glGetUniformLocation(binding->gl_program, tmp); + binding->uniform_locs.psh.tex_scale[i] = + glGetUniformLocation(binding->gl_program, tmp); } /* lookup vertex shader uniforms */ for (int i = 0; i < NV2A_VERTEXSHADER_CONSTANTS; i++) { snprintf(tmp, sizeof(tmp), "c[%d]", i); - binding->vsh_constant_loc[i] = glGetUniformLocation(binding->gl_program, tmp); + binding->uniform_locs.vsh.vsh_constant[i] = + glGetUniformLocation(binding->gl_program, tmp); } - binding->surface_size_loc = glGetUniformLocation(binding->gl_program, "surfaceSize"); - binding->clip_range_loc = glGetUniformLocation(binding->gl_program, "clipRange"); - binding->depth_offset_loc = glGetUniformLocation(binding->gl_program, "depthOffset"); - binding->fog_color_loc = glGetUniformLocation(binding->gl_program, "fogColor"); - binding->fog_param_loc = glGetUniformLocation(binding->gl_program, "fogParam"); + binding->uniform_locs.psh.surface_size = + glGetUniformLocation(binding->gl_program, "surfaceSize"); + binding->uniform_locs.psh.clip_range = + glGetUniformLocation(binding->gl_program, "clipRange"); + binding->uniform_locs.psh.depth_offset = + glGetUniformLocation(binding->gl_program, "depthOffset"); + binding->uniform_locs.psh.fog_color = + glGetUniformLocation(binding->gl_program, "fogColor"); + binding->uniform_locs.vsh.fog_param = + glGetUniformLocation(binding->gl_program, "fogParam"); for (int i = 0; i < NV2A_LTCTXA_COUNT; i++) { snprintf(tmp, sizeof(tmp), "ltctxa[%d]", i); - binding->ltctxa_loc[i] = glGetUniformLocation(binding->gl_program, tmp); + binding->uniform_locs.vsh.ltctxa[i] = + glGetUniformLocation(binding->gl_program, tmp); } for (int i = 0; i < NV2A_LTCTXB_COUNT; i++) { snprintf(tmp, sizeof(tmp), "ltctxb[%d]", i); - binding->ltctxb_loc[i] = glGetUniformLocation(binding->gl_program, tmp); + binding->uniform_locs.vsh.ltctxb[i] = + glGetUniformLocation(binding->gl_program, tmp); } for (int i = 0; i < NV2A_LTC1_COUNT; i++) { snprintf(tmp, sizeof(tmp), "ltc1[%d]", i); - binding->ltc1_loc[i] = glGetUniformLocation(binding->gl_program, tmp); + binding->uniform_locs.vsh.ltc1[i] = + glGetUniformLocation(binding->gl_program, tmp); } for (int i = 0; i < NV2A_MAX_LIGHTS; i++) { snprintf(tmp, sizeof(tmp), "lightInfiniteHalfVector%d", i); - binding->light_infinite_half_vector_loc[i] = + binding->uniform_locs.vsh.light_infinite_half_vector[i] = glGetUniformLocation(binding->gl_program, tmp); snprintf(tmp, sizeof(tmp), "lightInfiniteDirection%d", i); - binding->light_infinite_direction_loc[i] = + binding->uniform_locs.vsh.light_infinite_direction[i] = glGetUniformLocation(binding->gl_program, tmp); snprintf(tmp, sizeof(tmp), "lightLocalPosition%d", i); - binding->light_local_position_loc[i] = glGetUniformLocation(binding->gl_program, tmp); + binding->uniform_locs.vsh.light_local_position[i] = + glGetUniformLocation(binding->gl_program, tmp); snprintf(tmp, sizeof(tmp), "lightLocalAttenuation%d", i); - binding->light_local_attenuation_loc[i] = + binding->uniform_locs.vsh.light_local_attenuation[i] = glGetUniformLocation(binding->gl_program, tmp); } for (int i = 0; i < 8; i++) { snprintf(tmp, sizeof(tmp), "clipRegion[%d]", i); - binding->clip_region_loc[i] = glGetUniformLocation(binding->gl_program, tmp); + binding->uniform_locs.psh.clip_region[i] = + glGetUniformLocation(binding->gl_program, tmp); } for (int i = 0; i < 8; ++i) { snprintf(tmp, sizeof(tmp), "pointParams[%d]", i); - binding->point_params_loc[i] = glGetUniformLocation(binding->gl_program, tmp); + binding->uniform_locs.vsh.point_params[i] = + glGetUniformLocation(binding->gl_program, tmp); } if (binding->state.vsh.is_fixed_function) { - binding->material_alpha_loc = + binding->uniform_locs.vsh.material_alpha = glGetUniformLocation(binding->gl_program, "material_alpha"); - binding->specular_power_loc = + binding->uniform_locs.vsh.specular_power = glGetUniformLocation(binding->gl_program, "specularPower"); } else { - binding->material_alpha_loc = -1; - binding->specular_power_loc = -1; + binding->uniform_locs.vsh.material_alpha = -1; + binding->uniform_locs.vsh.specular_power = -1; } for (int i = 0; i < 4; ++i) { snprintf(tmp, sizeof(tmp), "colorKey[%d]", i); - binding->color_key_loc[i] = + binding->uniform_locs.psh.color_key[i] = glGetUniformLocation(binding->gl_program, tmp); snprintf(tmp, sizeof(tmp), "colorKeyMask[%d]", i); - binding->color_key_mask_loc[i] = + binding->uniform_locs.psh.color_key_mask[i] = glGetUniformLocation(binding->gl_program, tmp); } } @@ -724,7 +743,7 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding, } for (j = 0; j < 2; j++) { - GLint loc = binding->psh_constant_loc[i][j]; + GLint loc = binding->uniform_locs.psh.psh_constant[i][j]; if (loc != -1) { float value[4]; pgraph_argb_pack32_to_rgba_float(constant[j], value); @@ -732,10 +751,10 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding, } } } - if (binding->alpha_ref_loc != -1) { + if (binding->uniform_locs.psh.alpha_ref != -1) { int alpha_ref = GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CONTROL_0), - NV_PGRAPH_CONTROL_0_ALPHAREF); - glUniform1i(binding->alpha_ref_loc, alpha_ref); + NV_PGRAPH_CONTROL_0_ALPHAREF); + glUniform1i(binding->uniform_locs.psh.alpha_ref, alpha_ref); } /* For each texture stage */ @@ -744,7 +763,7 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding, /* Bump luminance only during stages 1 - 3 */ if (i > 0) { - loc = binding->bump_mat_loc[i]; + loc = binding->uniform_locs.psh.bump_mat[i]; if (loc != -1) { uint32_t m_u32[4]; m_u32[0] = pgraph_reg_r(pg, NV_PGRAPH_BUMPMAT00 + 4 * (i - 1)); @@ -752,55 +771,56 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding, m_u32[2] = pgraph_reg_r(pg, NV_PGRAPH_BUMPMAT10 + 4 * (i - 1)); m_u32[3] = pgraph_reg_r(pg, NV_PGRAPH_BUMPMAT11 + 4 * (i - 1)); float m[4]; - m[0] = *(float*)&m_u32[0]; - m[1] = *(float*)&m_u32[1]; - m[2] = *(float*)&m_u32[2]; - m[3] = *(float*)&m_u32[3]; + m[0] = *(float *)&m_u32[0]; + m[1] = *(float *)&m_u32[1]; + m[2] = *(float *)&m_u32[2]; + m[3] = *(float *)&m_u32[3]; glUniformMatrix2fv(loc, 1, GL_FALSE, m); } - loc = binding->bump_scale_loc[i]; + loc = binding->uniform_locs.psh.bump_scale[i]; if (loc != -1) { uint32_t v = pgraph_reg_r(pg, NV_PGRAPH_BUMPSCALE1 + (i - 1) * 4); - glUniform1f(loc, *(float*)&v); + glUniform1f(loc, *(float *)&v); } - loc = binding->bump_offset_loc[i]; + loc = binding->uniform_locs.psh.bump_offset[i]; if (loc != -1) { uint32_t v = pgraph_reg_r(pg, NV_PGRAPH_BUMPOFFSET1 + (i - 1) * 4); - glUniform1f(loc, *(float*)&v); + glUniform1f(loc, *(float *)&v); } } - loc = r->shader_binding->tex_scale_loc[i]; + loc = r->shader_binding->uniform_locs.psh.tex_scale[i]; if (loc != -1) { assert(r->texture_binding[i] != NULL); glUniform1f(loc, (float)r->texture_binding[i]->scale); } - if (binding->color_key_loc[i] != -1) { - glUniform1ui(binding->color_key_loc[i], + if (binding->uniform_locs.psh.color_key[i] != -1) { + glUniform1ui(binding->uniform_locs.psh.color_key[i], pgraph_reg_r(pg, NV_PGRAPH_COLORKEYCOLOR0 + i * 4)); } - if (binding->color_key_mask_loc[i] != -1) { - glUniform1ui(binding->color_key_mask_loc[i], + if (binding->uniform_locs.psh.color_key_mask[i] != -1) { + glUniform1ui(binding->uniform_locs.psh.color_key_mask[i], pgraph_get_color_key_mask_for_texture(pg, i)); } } - if (binding->fog_color_loc != -1) { + if (binding->uniform_locs.psh.fog_color != -1) { uint32_t fog_color = pgraph_reg_r(pg, NV_PGRAPH_FOGCOLOR); - glUniform4f(binding->fog_color_loc, + glUniform4f(binding->uniform_locs.psh.fog_color, GET_MASK(fog_color, NV_PGRAPH_FOGCOLOR_RED) / 255.0, GET_MASK(fog_color, NV_PGRAPH_FOGCOLOR_GREEN) / 255.0, GET_MASK(fog_color, NV_PGRAPH_FOGCOLOR_BLUE) / 255.0, GET_MASK(fog_color, NV_PGRAPH_FOGCOLOR_ALPHA) / 255.0); } - if (binding->fog_param_loc != -1) { + if (binding->uniform_locs.vsh.fog_param != -1) { uint32_t v[2]; v[0] = pgraph_reg_r(pg, NV_PGRAPH_FOGPARAM0); v[1] = pgraph_reg_r(pg, NV_PGRAPH_FOGPARAM1); - glUniform2f(binding->fog_param_loc, *(float *)&v[0], *(float *)&v[1]); + glUniform2f(binding->uniform_locs.vsh.fog_param, *(float *)&v[0], + *(float *)&v[1]); } float zmax; @@ -818,26 +838,30 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding, if (state->vsh.is_fixed_function) { /* update lighting constants */ struct { - uint32_t* v; - bool* dirty; - GLint* locs; + uint32_t *v; + bool *dirty; + GLint *locs; size_t len; } lighting_arrays[] = { - {&pg->ltctxa[0][0], &pg->ltctxa_dirty[0], binding->ltctxa_loc, NV2A_LTCTXA_COUNT}, - {&pg->ltctxb[0][0], &pg->ltctxb_dirty[0], binding->ltctxb_loc, NV2A_LTCTXB_COUNT}, - {&pg->ltc1[0][0], &pg->ltc1_dirty[0], binding->ltc1_loc, NV2A_LTC1_COUNT}, + { &pg->ltctxa[0][0], &pg->ltctxa_dirty[0], + binding->uniform_locs.vsh.ltctxa, NV2A_LTCTXA_COUNT }, + { &pg->ltctxb[0][0], &pg->ltctxb_dirty[0], + binding->uniform_locs.vsh.ltctxb, NV2A_LTCTXB_COUNT }, + { &pg->ltc1[0][0], &pg->ltc1_dirty[0], + binding->uniform_locs.vsh.ltc1, NV2A_LTC1_COUNT }, }; - for (i=0; ilight_infinite_half_vector_loc[i]; + loc = binding->uniform_locs.vsh.light_infinite_half_vector[i]; if (loc != -1) { glUniform3fv(loc, 1, pg->light_infinite_half_vector[i]); } - loc = binding->light_infinite_direction_loc[i]; + loc = binding->uniform_locs.vsh.light_infinite_direction[i]; if (loc != -1) { glUniform3fv(loc, 1, pg->light_infinite_direction[i]); } - loc = binding->light_local_position_loc[i]; + loc = binding->uniform_locs.vsh.light_local_position[i]; if (loc != -1) { glUniform3fv(loc, 1, pg->light_local_position[i]); } - loc = binding->light_local_attenuation_loc[i]; + loc = binding->uniform_locs.vsh.light_local_attenuation[i]; if (loc != -1) { glUniform3fv(loc, 1, pg->light_local_attenuation[i]); } } - if (binding->specular_power_loc != -1) { - glUniform1f(binding->specular_power_loc, pg->specular_power); - } + if (binding->uniform_locs.vsh.specular_power != -1) { + glUniform1f(binding->uniform_locs.vsh.specular_power, + pg->specular_power); + } } /* update vertex program constants */ - for (i=0; ivsh_constants_dirty[i] && !binding_changed) continue; + for (i = 0; i < NV2A_VERTEXSHADER_CONSTANTS; i++) { + if (!pg->vsh_constants_dirty[i] && !binding_changed) + continue; - GLint loc = binding->vsh_constant_loc[i]; + GLint loc = binding->uniform_locs.vsh.vsh_constant[i]; if ((loc != -1) && memcmp(binding->vsh_constants[i], pg->vsh_constants[i], sizeof(pg->vsh_constants[1]))) { @@ -885,24 +911,25 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding, pg->vsh_constants_dirty[i] = false; } - if (binding->surface_size_loc != -1) { + if (binding->uniform_locs.psh.surface_size != -1) { unsigned int aa_width = 1, aa_height = 1; pgraph_apply_anti_aliasing_factor(pg, &aa_width, &aa_height); - glUniform2f(binding->surface_size_loc, + glUniform2f(binding->uniform_locs.psh.surface_size, pg->surface_binding_dim.width / aa_width, pg->surface_binding_dim.height / aa_height); } - if (binding->clip_range_loc != -1) { + if (binding->uniform_locs.psh.clip_range != -1) { uint32_t v[2]; v[0] = pgraph_reg_r(pg, NV_PGRAPH_ZCLIPMIN); v[1] = pgraph_reg_r(pg, NV_PGRAPH_ZCLIPMAX); float zclip_min = *(float *)&v[0]; float zclip_max = *(float *)&v[1]; - glUniform4f(binding->clip_range_loc, 0, zmax, zclip_min, zclip_max); + glUniform4f(binding->uniform_locs.psh.clip_range, 0, zmax, zclip_min, + zclip_max); } - if (binding->depth_offset_loc != -1) { + if (binding->uniform_locs.psh.depth_offset != -1) { float zbias = 0.0f; if (pgraph_reg_r(pg, NV_PGRAPH_SETUPRASTER) & @@ -924,7 +951,7 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding, } } - glUniform1f(binding->depth_offset_loc, zbias); + glUniform1f(binding->uniform_locs.psh.depth_offset, zbias); } /* Clipping regions */ @@ -945,19 +972,20 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding, pgraph_apply_scaling_factor(pg, &x_min, &y_min); pgraph_apply_scaling_factor(pg, &x_max, &y_max); - glUniform4i(r->shader_binding->clip_region_loc[i], - x_min, y_min, x_max, y_max); + glUniform4i(r->shader_binding->uniform_locs.psh.clip_region[i], x_min, + y_min, x_max, y_max); } for (i = 0; i < 8; ++i) { - GLint loc = binding->point_params_loc[i]; + GLint loc = binding->uniform_locs.vsh.point_params[i]; if (loc != -1) { glUniform1f(loc, pg->point_params[i]); } } - if (binding->material_alpha_loc != -1) { - glUniform1f(binding->material_alpha_loc, pg->material_alpha); + if (binding->uniform_locs.vsh.material_alpha != -1) { + glUniform1f(binding->uniform_locs.vsh.material_alpha, + pg->material_alpha); } } diff --git a/hw/xbox/nv2a/pgraph/vk/renderer.h b/hw/xbox/nv2a/pgraph/vk/renderer.h index c04fc4bec2..520ce5d738 100644 --- a/hw/xbox/nv2a/pgraph/vk/renderer.h +++ b/hw/xbox/nv2a/pgraph/vk/renderer.h @@ -164,42 +164,41 @@ typedef struct ShaderBinding { ShaderModuleInfo *vertex; ShaderModuleInfo *fragment; - int psh_constant_loc[9][2]; - int alpha_ref_loc; + struct { + struct { + int alpha_ref; + int bump_mat[NV2A_MAX_TEXTURES]; + int bump_offset[NV2A_MAX_TEXTURES]; + int bump_scale[NV2A_MAX_TEXTURES]; + int clip_range; + int clip_region; + int color_key; + int color_key_mask; + int depth_offset; + int fog_color; + int psh_constant[9][2]; + int surface_size; + int tex_scale[NV2A_MAX_TEXTURES]; + } psh; - int bump_mat_loc[NV2A_MAX_TEXTURES]; - int bump_scale_loc[NV2A_MAX_TEXTURES]; - int bump_offset_loc[NV2A_MAX_TEXTURES]; - int tex_scale_loc[NV2A_MAX_TEXTURES]; - - int surface_size_loc; - int clip_range_loc; - int clip_range_floc; - int depth_offset_loc; - - int vsh_constant_loc; - uint32_t vsh_constants[NV2A_VERTEXSHADER_CONSTANTS][4]; - - int ltctxa_loc; - int ltctxb_loc; - int ltc1_loc; - - int fog_color_loc; - int fog_param_loc; - int light_infinite_half_vector_loc[NV2A_MAX_LIGHTS]; - int light_infinite_direction_loc[NV2A_MAX_LIGHTS]; - int light_local_position_loc[NV2A_MAX_LIGHTS]; - int light_local_attenuation_loc[NV2A_MAX_LIGHTS]; - int specular_power_loc; - int point_params_loc; - - int clip_region_loc; - int material_alpha_loc; - - int color_key_loc; - int color_key_mask_loc; - - int uniform_attrs_loc; + struct { + int clip_range; + int fog_param; + int light_infinite_direction[NV2A_MAX_LIGHTS]; + int light_infinite_half_vector[NV2A_MAX_LIGHTS]; + int light_local_attenuation[NV2A_MAX_LIGHTS]; + int light_local_position[NV2A_MAX_LIGHTS]; + int ltc1; + int ltctxa; + int ltctxb; + int material_alpha; + int point_params; + int specular_power; + int uniform_attrs; + int vsh_constant; + uint32_t vsh_constants[NV2A_VERTEXSHADER_CONSTANTS][4]; + } vsh; + } uniform_locs; } ShaderBinding; typedef struct TextureKey { diff --git a/hw/xbox/nv2a/pgraph/vk/shaders.c b/hw/xbox/nv2a/pgraph/vk/shaders.c index 2528cd10bd..77801f7bdb 100644 --- a/hw/xbox/nv2a/pgraph/vk/shaders.c +++ b/hw/xbox/nv2a/pgraph/vk/shaders.c @@ -248,84 +248,88 @@ static void update_shader_constant_locations(ShaderBinding *binding) for (int i = 0; i < 9; i++) { for (int j = 0; j < 2; j++) { snprintf(tmp, sizeof(tmp), "c%d_%d", j, i); - binding->psh_constant_loc[i][j] = + binding->uniform_locs.psh.psh_constant[i][j] = uniform_index(&binding->fragment->uniforms, tmp); } } - binding->alpha_ref_loc = + binding->uniform_locs.psh.alpha_ref = uniform_index(&binding->fragment->uniforms, "alphaRef"); - binding->fog_color_loc = + binding->uniform_locs.psh.fog_color = uniform_index(&binding->fragment->uniforms, "fogColor"); for (int i = 1; i < NV2A_MAX_TEXTURES; i++) { snprintf(tmp, sizeof(tmp), "bumpMat%d", i); - binding->bump_mat_loc[i] = + binding->uniform_locs.psh.bump_mat[i] = uniform_index(&binding->fragment->uniforms, tmp); snprintf(tmp, sizeof(tmp), "bumpScale%d", i); - binding->bump_scale_loc[i] = + binding->uniform_locs.psh.bump_scale[i] = uniform_index(&binding->fragment->uniforms, tmp); snprintf(tmp, sizeof(tmp), "bumpOffset%d", i); - binding->bump_offset_loc[i] = + binding->uniform_locs.psh.bump_offset[i] = uniform_index(&binding->fragment->uniforms, tmp); } for (int i = 0; i < NV2A_MAX_TEXTURES; i++) { snprintf(tmp, sizeof(tmp), "texScale%d", i); - binding->tex_scale_loc[i] = + binding->uniform_locs.psh.tex_scale[i] = uniform_index(&binding->fragment->uniforms, tmp); } /* lookup vertex shader uniforms */ - binding->vsh_constant_loc = uniform_index(&binding->vertex->uniforms, "c"); - binding->surface_size_loc = + binding->uniform_locs.vsh.vsh_constant = + uniform_index(&binding->vertex->uniforms, "c"); + binding->uniform_locs.psh.surface_size = uniform_index(&binding->vertex->uniforms, "surfaceSize"); - binding->clip_range_loc = + binding->uniform_locs.vsh.clip_range = uniform_index(&binding->vertex->uniforms, "clipRange"); - binding->clip_range_floc = + binding->uniform_locs.psh.clip_range = uniform_index(&binding->fragment->uniforms, "clipRange"); - binding->depth_offset_loc = + binding->uniform_locs.psh.depth_offset = uniform_index(&binding->fragment->uniforms, "depthOffset"); - binding->fog_param_loc = + binding->uniform_locs.vsh.fog_param = uniform_index(&binding->vertex->uniforms, "fogParam"); - binding->ltctxa_loc = uniform_index(&binding->vertex->uniforms, "ltctxa"); - binding->ltctxb_loc = uniform_index(&binding->vertex->uniforms, "ltctxb"); - binding->ltc1_loc = uniform_index(&binding->vertex->uniforms, "ltc1"); + binding->uniform_locs.vsh.ltctxa = + uniform_index(&binding->vertex->uniforms, "ltctxa"); + binding->uniform_locs.vsh.ltctxb = + uniform_index(&binding->vertex->uniforms, "ltctxb"); + binding->uniform_locs.vsh.ltc1 = + uniform_index(&binding->vertex->uniforms, "ltc1"); for (int i = 0; i < NV2A_MAX_LIGHTS; i++) { snprintf(tmp, sizeof(tmp), "lightInfiniteHalfVector%d", i); - binding->light_infinite_half_vector_loc[i] = + binding->uniform_locs.vsh.light_infinite_half_vector[i] = uniform_index(&binding->vertex->uniforms, tmp); snprintf(tmp, sizeof(tmp), "lightInfiniteDirection%d", i); - binding->light_infinite_direction_loc[i] = + binding->uniform_locs.vsh.light_infinite_direction[i] = uniform_index(&binding->vertex->uniforms, tmp); snprintf(tmp, sizeof(tmp), "lightLocalPosition%d", i); - binding->light_local_position_loc[i] = + binding->uniform_locs.vsh.light_local_position[i] = uniform_index(&binding->vertex->uniforms, tmp); snprintf(tmp, sizeof(tmp), "lightLocalAttenuation%d", i); - binding->light_local_attenuation_loc[i] = + binding->uniform_locs.vsh.light_local_attenuation[i] = uniform_index(&binding->vertex->uniforms, tmp); } - binding->clip_region_loc = + binding->uniform_locs.psh.clip_region = uniform_index(&binding->fragment->uniforms, "clipRegion"); - binding->point_params_loc = + binding->uniform_locs.vsh.point_params = uniform_index(&binding->vertex->uniforms, "pointParams"); - binding->material_alpha_loc = + binding->uniform_locs.vsh.material_alpha = uniform_index(&binding->vertex->uniforms, "material_alpha"); - binding->color_key_loc = + binding->uniform_locs.psh.color_key = uniform_index(&binding->fragment->uniforms, "colorKey"); - binding->color_key_mask_loc = + binding->uniform_locs.psh.color_key_mask = uniform_index(&binding->fragment->uniforms, "colorKeyMask"); - binding->uniform_attrs_loc = + binding->uniform_locs.vsh.uniform_attrs = uniform_index(&binding->vertex->uniforms, "inlineValue"); - binding->specular_power_loc = + binding->uniform_locs.vsh.specular_power = uniform_index(&binding->vertex->uniforms, "specularPower"); } @@ -472,7 +476,8 @@ static void update_uniform_attr_values(PGRAPHState *pg, ShaderBinding *binding) &num_uniform_attrs); if (num_uniform_attrs > 0) { - uniform1fv(&binding->vertex->uniforms, binding->uniform_attrs_loc, + uniform1fv(&binding->vertex->uniforms, + binding->uniform_locs.vsh.uniform_attrs, num_uniform_attrs * 4, &values[0][0]); } } @@ -496,7 +501,7 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding) } for (int j = 0; j < 2; j++) { - GLint loc = binding->psh_constant_loc[i][j]; + GLint loc = binding->uniform_locs.psh.psh_constant[i][j]; if (loc != -1) { float value[4]; pgraph_argb_pack32_to_rgba_float(constant[j], value); @@ -504,21 +509,21 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding) } } } - if (binding->alpha_ref_loc != -1) { + if (binding->uniform_locs.psh.alpha_ref != -1) { int alpha_ref = GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_CONTROL_0), - NV_PGRAPH_CONTROL_0_ALPHAREF); - uniform1i(&binding->fragment->uniforms, binding->alpha_ref_loc, - alpha_ref); + NV_PGRAPH_CONTROL_0_ALPHAREF); + uniform1i(&binding->fragment->uniforms, + binding->uniform_locs.psh.alpha_ref, alpha_ref); } - if (binding->color_key_loc != -1) { + if (binding->uniform_locs.psh.color_key != -1) { uint32_t color_key_colors[4] = { pgraph_reg_r(pg, NV_PGRAPH_COLORKEYCOLOR0), pgraph_reg_r(pg, NV_PGRAPH_COLORKEYCOLOR1), pgraph_reg_r(pg, NV_PGRAPH_COLORKEYCOLOR2), pgraph_reg_r(pg, NV_PGRAPH_COLORKEYCOLOR3), }; - uniform1uiv(&binding->fragment->uniforms, binding->color_key_loc, 4, - color_key_colors); + uniform1uiv(&binding->fragment->uniforms, + binding->uniform_locs.psh.color_key, 4, color_key_colors); } uint32_t color_key_mask[4] = { 0 }; @@ -528,7 +533,7 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding) /* Bump luminance only during stages 1 - 3 */ if (i > 0) { - loc = binding->bump_mat_loc[i]; + loc = binding->uniform_locs.psh.bump_mat[i]; if (loc != -1) { uint32_t m_u32[4]; m_u32[0] = pgraph_reg_r(pg, NV_PGRAPH_BUMPMAT00 + 4 * (i - 1)); @@ -536,29 +541,27 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding) m_u32[2] = pgraph_reg_r(pg, NV_PGRAPH_BUMPMAT10 + 4 * (i - 1)); m_u32[3] = pgraph_reg_r(pg, NV_PGRAPH_BUMPMAT11 + 4 * (i - 1)); float m[4]; - m[0] = *(float*)&m_u32[0]; - m[1] = *(float*)&m_u32[1]; - m[2] = *(float*)&m_u32[2]; - m[3] = *(float*)&m_u32[3]; + m[0] = *(float *)&m_u32[0]; + m[1] = *(float *)&m_u32[1]; + m[2] = *(float *)&m_u32[2]; + m[3] = *(float *)&m_u32[3]; uniformMatrix2fv(&binding->fragment->uniforms, loc, m); } - loc = binding->bump_scale_loc[i]; + loc = binding->uniform_locs.psh.bump_scale[i]; if (loc != -1) { uint32_t v = pgraph_reg_r(pg, NV_PGRAPH_BUMPSCALE1 + (i - 1) * 4); - uniform1f(&binding->fragment->uniforms, loc, - *(float *)&v); + uniform1f(&binding->fragment->uniforms, loc, *(float *)&v); } - loc = binding->bump_offset_loc[i]; + loc = binding->uniform_locs.psh.bump_offset[i]; if (loc != -1) { uint32_t v = pgraph_reg_r(pg, NV_PGRAPH_BUMPOFFSET1 + (i - 1) * 4); - uniform1f(&binding->fragment->uniforms, loc, - *(float *)&v); + uniform1f(&binding->fragment->uniforms, loc, *(float *)&v); } } - loc = binding->tex_scale_loc[i]; + loc = binding->uniform_locs.psh.tex_scale[i]; if (loc != -1) { assert(pg->vk_renderer_state->texture_bindings[i] != NULL); float scale = pg->vk_renderer_state->texture_bindings[i]->key.scale; @@ -575,26 +578,28 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding) color_key_mask[i] = pgraph_get_color_key_mask_for_texture(pg, i); } - if (binding->color_key_mask_loc != -1) { - uniform1uiv(&binding->fragment->uniforms, binding->color_key_mask_loc, - 4, color_key_mask); + if (binding->uniform_locs.psh.color_key_mask != -1) { + uniform1uiv(&binding->fragment->uniforms, + binding->uniform_locs.psh.color_key_mask, 4, + color_key_mask); } - if (binding->fog_color_loc != -1) { + if (binding->uniform_locs.psh.fog_color != -1) { uint32_t fog_color = pgraph_reg_r(pg, NV_PGRAPH_FOGCOLOR); - uniform4f(&binding->fragment->uniforms, binding->fog_color_loc, - GET_MASK(fog_color, NV_PGRAPH_FOGCOLOR_RED) / 255.0, - GET_MASK(fog_color, NV_PGRAPH_FOGCOLOR_GREEN) / 255.0, - GET_MASK(fog_color, NV_PGRAPH_FOGCOLOR_BLUE) / 255.0, - GET_MASK(fog_color, NV_PGRAPH_FOGCOLOR_ALPHA) / 255.0); + uniform4f(&binding->fragment->uniforms, + binding->uniform_locs.psh.fog_color, + GET_MASK(fog_color, NV_PGRAPH_FOGCOLOR_RED) / 255.0, + GET_MASK(fog_color, NV_PGRAPH_FOGCOLOR_GREEN) / 255.0, + GET_MASK(fog_color, NV_PGRAPH_FOGCOLOR_BLUE) / 255.0, + GET_MASK(fog_color, NV_PGRAPH_FOGCOLOR_ALPHA) / 255.0); } - if (binding->fog_param_loc != -1) { + if (binding->uniform_locs.vsh.fog_param != -1) { uint32_t v[2]; v[0] = pgraph_reg_r(pg, NV_PGRAPH_FOGPARAM0); v[1] = pgraph_reg_r(pg, NV_PGRAPH_FOGPARAM1); uniform2f(&binding->vertex->uniforms, - binding->fog_param_loc, *(float *)&v[0], - *(float *)&v[1]); + binding->uniform_locs.vsh.fog_param, *(float *)&v[0], + *(float *)&v[1]); } float zmax; @@ -616,77 +621,86 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding) int locs; size_t len; } lighting_arrays[] = { - { &pg->ltctxa[0][0], binding->ltctxa_loc, NV2A_LTCTXA_COUNT }, - { &pg->ltctxb[0][0], binding->ltctxb_loc, NV2A_LTCTXB_COUNT }, - { &pg->ltc1[0][0], binding->ltc1_loc, NV2A_LTC1_COUNT }, + { &pg->ltctxa[0][0], binding->uniform_locs.vsh.ltctxa, + NV2A_LTCTXA_COUNT }, + { &pg->ltctxb[0][0], binding->uniform_locs.vsh.ltctxb, + NV2A_LTCTXB_COUNT }, + { &pg->ltc1[0][0], binding->uniform_locs.vsh.ltc1, + NV2A_LTC1_COUNT }, }; for (int i = 0; i < ARRAY_SIZE(lighting_arrays); i++) { - uniform1iv( - &binding->vertex->uniforms, lighting_arrays[i].locs, - lighting_arrays[i].len * 4, (void *)lighting_arrays[i].v); + uniform1iv(&binding->vertex->uniforms, lighting_arrays[i].locs, + lighting_arrays[i].len * 4, + (void *)lighting_arrays[i].v); } for (int i = 0; i < NV2A_MAX_LIGHTS; i++) { - int loc = binding->light_infinite_half_vector_loc[i]; + int loc = binding->uniform_locs.vsh.light_infinite_half_vector[i]; if (loc != -1) { uniform1fv(&binding->vertex->uniforms, loc, 3, - pg->light_infinite_half_vector[i]); + pg->light_infinite_half_vector[i]); } - loc = binding->light_infinite_direction_loc[i]; + loc = binding->uniform_locs.vsh.light_infinite_direction[i]; if (loc != -1) { uniform1fv(&binding->vertex->uniforms, loc, 3, - pg->light_infinite_direction[i]); + pg->light_infinite_direction[i]); } - loc = binding->light_local_position_loc[i]; + loc = binding->uniform_locs.vsh.light_local_position[i]; if (loc != -1) { uniform1fv(&binding->vertex->uniforms, loc, 3, - pg->light_local_position[i]); + pg->light_local_position[i]); } - loc = binding->light_local_attenuation_loc[i]; + loc = binding->uniform_locs.vsh.light_local_attenuation[i]; if (loc != -1) { uniform1fv(&binding->vertex->uniforms, loc, 3, - pg->light_local_attenuation[i]); + pg->light_local_attenuation[i]); } } - if (binding->specular_power_loc != -1) { - uniform1f(&binding->vertex->uniforms, binding->specular_power_loc, + if (binding->uniform_locs.vsh.specular_power != -1) { + uniform1f(&binding->vertex->uniforms, + binding->uniform_locs.vsh.specular_power, pg->specular_power); } } /* update vertex program constants */ - uniform1iv(&binding->vertex->uniforms, binding->vsh_constant_loc, + uniform1iv(&binding->vertex->uniforms, + binding->uniform_locs.vsh.vsh_constant, NV2A_VERTEXSHADER_CONSTANTS * 4, (void *)pg->vsh_constants); - if (binding->surface_size_loc != -1) { + if (binding->uniform_locs.psh.surface_size != -1) { unsigned int aa_width = 1, aa_height = 1; pgraph_apply_anti_aliasing_factor(pg, &aa_width, &aa_height); - uniform2f(&binding->vertex->uniforms, binding->surface_size_loc, - pg->surface_binding_dim.width / aa_width, - pg->surface_binding_dim.height / aa_height); + uniform2f(&binding->vertex->uniforms, + binding->uniform_locs.psh.surface_size, + pg->surface_binding_dim.width / aa_width, + pg->surface_binding_dim.height / aa_height); } - if (binding->clip_range_loc != -1 || binding->clip_range_floc != -1) { + if (binding->uniform_locs.vsh.clip_range != -1 || + binding->uniform_locs.psh.clip_range != -1) { uint32_t v[2]; v[0] = pgraph_reg_r(pg, NV_PGRAPH_ZCLIPMIN); v[1] = pgraph_reg_r(pg, NV_PGRAPH_ZCLIPMAX); float zclip_min = *(float *)&v[0]; float zclip_max = *(float *)&v[1]; - if (binding->clip_range_loc != -1) { - uniform4f(&binding->vertex->uniforms, binding->clip_range_loc, 0, - zmax, zclip_min, zclip_max); + if (binding->uniform_locs.vsh.clip_range != -1) { + uniform4f(&binding->vertex->uniforms, + binding->uniform_locs.vsh.clip_range, 0, zmax, zclip_min, + zclip_max); } - if (binding->clip_range_floc != -1) { - uniform4f(&binding->fragment->uniforms, binding->clip_range_floc, 0, - zmax, zclip_min, zclip_max); + if (binding->uniform_locs.psh.clip_range != -1) { + uniform4f(&binding->fragment->uniforms, + binding->uniform_locs.psh.clip_range, 0, zmax, zclip_min, + zclip_max); } } - if (binding->depth_offset_loc != -1) { + if (binding->uniform_locs.psh.depth_offset != -1) { float zbias = 0.0f; if (pgraph_reg_r(pg, NV_PGRAPH_SETUPRASTER) & @@ -708,8 +722,8 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding) } } - uniform1f(&binding->fragment->uniforms, binding->depth_offset_loc, - zbias); + uniform1f(&binding->fragment->uniforms, + binding->uniform_locs.psh.depth_offset, zbias); } /* Clipping regions */ @@ -737,21 +751,22 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding) clip_regions[i][2] = x_max; clip_regions[i][3] = y_max; } - uniform1iv(&binding->fragment->uniforms, binding->clip_region_loc, - 8 * 4, (void *)clip_regions); + uniform1iv(&binding->fragment->uniforms, + binding->uniform_locs.psh.clip_region, 8 * 4, + (void *)clip_regions); - if (binding->point_params_loc != -1) { - uniform1iv(&binding->vertex->uniforms, binding->point_params_loc, + if (binding->uniform_locs.vsh.point_params != -1) { + uniform1iv(&binding->vertex->uniforms, + binding->uniform_locs.vsh.point_params, ARRAY_SIZE(pg->point_params), (void *)pg->point_params); } - if (binding->material_alpha_loc != -1) { - uniform1f(&binding->vertex->uniforms, binding->material_alpha_loc, - pg->material_alpha); + if (binding->uniform_locs.vsh.material_alpha != -1) { + uniform1f(&binding->vertex->uniforms, + binding->uniform_locs.vsh.material_alpha, pg->material_alpha); } - if (!r->use_push_constants_for_uniform_attrs && - state->vsh.uniform_attrs) { + if (!r->use_push_constants_for_uniform_attrs && state->vsh.uniform_attrs) { update_uniform_attr_values(pg, binding); } }