diff --git a/hw/xbox/nv2a/pgraph/gl/renderer.h b/hw/xbox/nv2a/pgraph/gl/renderer.h index a722a292ac..2a759ba22f 100644 --- a/hw/xbox/nv2a/pgraph/gl/renderer.h +++ b/hw/xbox/nv2a/pgraph/gl/renderer.h @@ -129,7 +129,7 @@ typedef struct ShaderBinding { GLint material_alpha_loc; GLint color_key_loc[4]; - GLint color_key_ignore_alpha_loc[4]; + GLint color_key_mask_loc[4]; } ShaderBinding; typedef struct VertexKey { diff --git a/hw/xbox/nv2a/pgraph/gl/shaders.c b/hw/xbox/nv2a/pgraph/gl/shaders.c index 9dc4e2487c..28476aa66a 100644 --- a/hw/xbox/nv2a/pgraph/gl/shaders.c +++ b/hw/xbox/nv2a/pgraph/gl/shaders.c @@ -210,8 +210,8 @@ static void update_shader_constant_locations(ShaderBinding *binding) binding->color_key_loc[i] = glGetUniformLocation(binding->gl_program, tmp); - snprintf(tmp, sizeof(tmp), "colorKeyIgnoreAlpha[%d]", i); - binding->color_key_ignore_alpha_loc[i] = + snprintf(tmp, sizeof(tmp), "colorKeyMask[%d]", i); + binding->color_key_mask_loc[i] = glGetUniformLocation(binding->gl_program, tmp); } } @@ -781,9 +781,9 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding, glUniform1ui(binding->color_key_loc[i], pgraph_reg_r(pg, NV_PGRAPH_COLORKEYCOLOR0 + i * 4)); } - if (binding->color_key_ignore_alpha_loc[i] != -1) { - glUniform1i(binding->color_key_ignore_alpha_loc[i], - state->psh.colorkey_ignore_alpha[i]); + if (binding->color_key_mask_loc[i] != -1) { + glUniform1ui(binding->color_key_mask_loc[i], + state->psh.colorkey_mask[i]); } } diff --git a/hw/xbox/nv2a/pgraph/glsl/psh.c b/hw/xbox/nv2a/pgraph/glsl/psh.c index b15797e0b8..85bce850cb 100644 --- a/hw/xbox/nv2a/pgraph/glsl/psh.c +++ b/hw/xbox/nv2a/pgraph/glsl/psh.c @@ -176,9 +176,9 @@ enum PS_DOTMAPPING enum PS_COLORKEYMODE { COLOR_KEY_NONE = 0, - COLOR_KEY_KILL_ALPHA = 0x01, - COLOR_KEY_KILL_COLOR_AND_ALPHA = 0x02, - COLOR_KEY_DISCARD = 0x03, + COLOR_KEY_KILL_ALPHA = 1, + COLOR_KEY_KILL_COLOR_AND_ALPHA = 2, + COLOR_KEY_DISCARD = 3, }; @@ -743,12 +743,10 @@ static void define_colorkey_comparator(MString *preflight) // clang-format off mstring_append( preflight, - "bool check_color_key(vec4 texel, uint color_key, bool ignore_alpha) {\n" - " uvec4 components = uvec4(round(texel * 255.0));\n" - " if (ignore_alpha) {\n" - " return uint((components.r << 16) + (components.g << 8) + components.b) == (color_key & 0x00FFFFFFu);\n" - " }\n" - " return uint((components.a << 24) + (components.r << 16) + (components.g << 8) + components.b) == color_key;\n" + "bool check_color_key(vec4 texel, uint color_key, uint color_key_mask) {\n" + " uvec4 c = uvec4(texel * 255.0 + 0.5);\n" + " uint color = (c.a << 24) | (c.r << 16) | (c.g << 8) | c.b;\n" + " return (color & color_key_mask) == (color_key & color_key_mask);\n" "}\n"); // clang-format on } @@ -777,7 +775,7 @@ static MString* psh_convert(struct PixelShader *ps) "%svec4 clipRange;\n" "%sfloat depthOffset;\n" "%suint colorKey[4];\n" - "%sint colorKeyIgnoreAlpha[4];\n", + "%suint colorKeyMask[4];\n", u, u, u, u, u, u, u); for (int i = 0; i < 4; i++) { mstring_append_fmt(preflight, "%smat2 bumpMat%d;\n" @@ -1211,7 +1209,7 @@ static MString* psh_convert(struct PixelShader *ps) i); } - enum PS_COLORKEYMODE color_key_mode = ps->state.colorkeymode[i]; + enum PS_COLORKEYMODE color_key_mode = ps->state.colorkey_mode[i]; if (color_key_mode != COLOR_KEY_NONE) { if (!color_key_comparator_defined) { define_colorkey_comparator(preflight); @@ -1221,7 +1219,7 @@ static MString* psh_convert(struct PixelShader *ps) // clang-format off mstring_append_fmt( vars, - "if (check_color_key(t%d, colorKey[%d], colorKeyIgnoreAlpha[%d] != 0)) {\n", + "if (check_color_key(t%d, colorKey[%d], colorKeyMask[%d])) {\n", i, i, i); // clang-format on diff --git a/hw/xbox/nv2a/pgraph/psh.h b/hw/xbox/nv2a/pgraph/psh.h index 6e4d5b1027..0b4df4c280 100644 --- a/hw/xbox/nv2a/pgraph/psh.h +++ b/hw/xbox/nv2a/pgraph/psh.h @@ -69,8 +69,8 @@ typedef struct PshState { bool snorm_tex[4]; bool compare_mode[4][4]; bool alphakill[4]; - int colorkeymode[4]; - bool colorkey_ignore_alpha[4]; + int colorkey_mode[4]; + uint32_t colorkey_mask[4]; enum ConvolutionFilter conv_tex[4]; bool tex_x8y24[4]; int dim_tex[4]; diff --git a/hw/xbox/nv2a/pgraph/shaders.c b/hw/xbox/nv2a/pgraph/shaders.c index 87ef2f465c..9fc28e773e 100644 --- a/hw/xbox/nv2a/pgraph/shaders.c +++ b/hw/xbox/nv2a/pgraph/shaders.c @@ -27,12 +27,18 @@ // TODO: https://github.com/xemu-project/xemu/issues/2260 // Investigate how color keying is handled for components with no alpha or // only alpha. -static bool color_format_ignores_alpha(unsigned int color_format) +static uint32_t get_colorkey_mask(unsigned int color_format) { - return color_format == NV097_SET_TEXTURE_FORMAT_COLOR_SZ_X1R5G5B5 || - color_format == NV097_SET_TEXTURE_FORMAT_COLOR_SZ_X8R8G8B8 || - color_format == NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_X1R5G5B5 || - color_format == NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_X8R8G8B8; + switch (color_format) { + case NV097_SET_TEXTURE_FORMAT_COLOR_SZ_X1R5G5B5: + case NV097_SET_TEXTURE_FORMAT_COLOR_SZ_X8R8G8B8: + case NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_X1R5G5B5: + case NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_X8R8G8B8: + return 0x00FFFFFF; + + default: + return 0xFFFFFFFF; + } } ShaderState pgraph_get_shader_state(PGRAPHState *pg) @@ -230,7 +236,7 @@ ShaderState pgraph_get_shader_state(PGRAPHState *pg) } state.psh.alphakill[i] = ctl_0 & NV_PGRAPH_TEXCTL0_0_ALPHAKILLEN; - state.psh.colorkeymode[i] = ctl_0 & NV_PGRAPH_TEXCTL0_0_COLORKEYMODE; + state.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); @@ -240,8 +246,7 @@ ShaderState pgraph_get_shader_state(PGRAPHState *pg) 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; - state.psh.colorkey_ignore_alpha[i] = - color_format_ignores_alpha(color_format); + state.psh.colorkey_mask[i] = get_colorkey_mask(color_format); uint32_t border_source = GET_MASK(tex_fmt, NV_PGRAPH_TEXFMT0_BORDER_SOURCE); diff --git a/hw/xbox/nv2a/pgraph/vk/renderer.h b/hw/xbox/nv2a/pgraph/vk/renderer.h index 59eb59e50f..3c3bb4ce91 100644 --- a/hw/xbox/nv2a/pgraph/vk/renderer.h +++ b/hw/xbox/nv2a/pgraph/vk/renderer.h @@ -196,7 +196,7 @@ typedef struct ShaderBinding { int material_alpha_loc; int color_key_loc; - int color_key_ignore_alpha_loc; + int color_key_mask_loc; int uniform_attrs_loc; } ShaderBinding; diff --git a/hw/xbox/nv2a/pgraph/vk/shaders.c b/hw/xbox/nv2a/pgraph/vk/shaders.c index 5706b0c989..466789a8ad 100644 --- a/hw/xbox/nv2a/pgraph/vk/shaders.c +++ b/hw/xbox/nv2a/pgraph/vk/shaders.c @@ -315,8 +315,8 @@ static void update_shader_constant_locations(ShaderBinding *binding) binding->color_key_loc = uniform_index(&binding->fragment->uniforms, "colorKey"); - binding->color_key_ignore_alpha_loc = - uniform_index(&binding->fragment->uniforms, "colorKeyIgnoreAlpha"); + binding->color_key_mask_loc = + uniform_index(&binding->fragment->uniforms, "colorKeyMask"); binding->uniform_attrs_loc = uniform_index(&binding->vertex->uniforms, "inlineValue"); @@ -506,10 +506,9 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding, uniform1uiv(&binding->fragment->uniforms, binding->color_key_loc, 4, color_key_colors); } - if (binding->color_key_ignore_alpha_loc != -1) { - uniform1iv(&binding->fragment->uniforms, - binding->color_key_ignore_alpha_loc, 4, - (int32_t *)&state->psh.colorkey_ignore_alpha); + if (binding->color_key_mask_loc != -1) { + uniform1uiv(&binding->fragment->uniforms, binding->color_key_mask_loc, + 4, state->psh.colorkey_mask); } /* For each texture stage */