From c583cac5681409222c4557e48cbad8caedc17c4d Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Mon, 22 Feb 2021 19:03:06 -0800 Subject: [PATCH 1/3] Hack to hide debug cubes in Super Mario Sunshine ... while not breaking other games. --- Data/Sys/GameSettings/GMS.ini | 1 + Source/Core/Core/Config/GraphicsSettings.cpp | 2 ++ Source/Core/Core/Config/GraphicsSettings.h | 1 + .../VideoBackends/Software/SWVertexLoader.cpp | 19 +++++++-------- Source/Core/VideoCommon/ConstantManager.h | 3 ++- Source/Core/VideoCommon/ShaderGenCommon.h | 3 ++- Source/Core/VideoCommon/UberShaderVertex.cpp | 9 +++----- Source/Core/VideoCommon/VertexShaderGen.cpp | 5 +--- .../Core/VideoCommon/VertexShaderManager.cpp | 23 ++++++++++--------- Source/Core/VideoCommon/VideoConfig.cpp | 1 + Source/Core/VideoCommon/VideoConfig.h | 1 + 11 files changed, 34 insertions(+), 34 deletions(-) diff --git a/Data/Sys/GameSettings/GMS.ini b/Data/Sys/GameSettings/GMS.ini index 5dc4d512be..d27d391d4f 100644 --- a/Data/Sys/GameSettings/GMS.ini +++ b/Data/Sys/GameSettings/GMS.ini @@ -18,6 +18,7 @@ PerfQueriesEnable = True [Video_Hacks] EFBToTextureEnable = False EFBAccessEnable = True +MissingColorValue = 0x00000000 [Video_Enhancements] ForceFiltering = False diff --git a/Source/Core/Core/Config/GraphicsSettings.cpp b/Source/Core/Core/Config/GraphicsSettings.cpp index 506d9062d5..ebfa94b5bb 100644 --- a/Source/Core/Core/Config/GraphicsSettings.cpp +++ b/Source/Core/Core/Config/GraphicsSettings.cpp @@ -148,6 +148,8 @@ const Info GFX_HACK_COPY_EFB_SCALED{{System::GFX, "Hacks", "EFBScaledCopy" const Info GFX_HACK_EFB_EMULATE_FORMAT_CHANGES{ {System::GFX, "Hacks", "EFBEmulateFormatChanges"}, false}; const Info GFX_HACK_VERTEX_ROUDING{{System::GFX, "Hacks", "VertexRounding"}, false}; +const Info GFX_HACK_MISSING_COLOR_VALUE{{System::GFX, "Hacks", "MissingColorValue"}, + 0xFFFFFFFF}; // Graphics.GameSpecific diff --git a/Source/Core/Core/Config/GraphicsSettings.h b/Source/Core/Core/Config/GraphicsSettings.h index 75bcb227e0..b093c8faf4 100644 --- a/Source/Core/Core/Config/GraphicsSettings.h +++ b/Source/Core/Core/Config/GraphicsSettings.h @@ -122,6 +122,7 @@ extern const Info GFX_HACK_SKIP_DUPLICATE_XFBS; extern const Info GFX_HACK_COPY_EFB_SCALED; extern const Info GFX_HACK_EFB_EMULATE_FORMAT_CHANGES; extern const Info GFX_HACK_VERTEX_ROUDING; +extern const Info GFX_HACK_MISSING_COLOR_VALUE; // Graphics.GameSpecific diff --git a/Source/Core/VideoBackends/Software/SWVertexLoader.cpp b/Source/Core/VideoBackends/Software/SWVertexLoader.cpp index fdcafc71bf..8a4268febf 100644 --- a/Source/Core/VideoBackends/Software/SWVertexLoader.cpp +++ b/Source/Core/VideoBackends/Software/SWVertexLoader.cpp @@ -180,14 +180,11 @@ static void ReadVertexAttribute(T* dst, DataReader src, const AttributeFormat& f static void ParseColorAttributes(InputVertexData* dst, DataReader& src, const PortableVertexDeclaration& vdec) { - const auto set_default_color = [](u8* color, int i) { - // The default alpha channel seems to depend on the number of components in the vertex format. - const auto& g0 = g_main_cp_state.vtx_attr[g_main_cp_state.last_id].g0; - const auto color_elements = i == 0 ? g0.Color0Elements.Value() : g0.Color1Elements.Value(); - color[0] = color_elements == ColorComponentCount::RGB ? 255 : 0; - color[1] = 255; - color[2] = 255; - color[3] = 255; + const auto set_default_color = [](std::array& color) { + color[Tev::ALP_C] = g_ActiveConfig.iMissingColorValue & 0xFF; + color[Tev::BLU_C] = (g_ActiveConfig.iMissingColorValue >> 8) & 0xFF; + color[Tev::GRN_C] = (g_ActiveConfig.iMissingColorValue >> 16) & 0xFF; + color[Tev::RED_C] = (g_ActiveConfig.iMissingColorValue >> 24) & 0xFF; }; if (vdec.colors[0].enable) @@ -197,7 +194,7 @@ static void ParseColorAttributes(InputVertexData* dst, DataReader& src, if (vdec.colors[1].enable) ReadVertexAttribute(dst->color[1].data(), src, vdec.colors[1], 0, 4, true); else - set_default_color(dst->color[1].data(), 1); + set_default_color(dst->color[1]); } else { @@ -205,8 +202,8 @@ static void ParseColorAttributes(InputVertexData* dst, DataReader& src, if (vdec.colors[1].enable) ReadVertexAttribute(dst->color[0].data(), src, vdec.colors[1], 0, 4, true); else - set_default_color(dst->color[0].data(), 0); - set_default_color(dst->color[1].data(), 1); + set_default_color(dst->color[0]); + set_default_color(dst->color[1]); } } diff --git a/Source/Core/VideoCommon/ConstantManager.h b/Source/Core/VideoCommon/ConstantManager.h index ad21821052..89141e8d3c 100644 --- a/Source/Core/VideoCommon/ConstantManager.h +++ b/Source/Core/VideoCommon/ConstantManager.h @@ -61,7 +61,8 @@ struct VertexShaderConstants u32 components; // .x u32 xfmem_dualTexInfo; // .y u32 xfmem_numColorChans; // .z - u32 color_chan_alpha; // .w + u32 missing_color_hex; // .w, used for change detection but not directly by shaders + float4 missing_color_value; std::array posnormalmatrix; std::array projection; diff --git a/Source/Core/VideoCommon/ShaderGenCommon.h b/Source/Core/VideoCommon/ShaderGenCommon.h index 2bb15e1725..10e2aef979 100644 --- a/Source/Core/VideoCommon/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/ShaderGenCommon.h @@ -229,7 +229,8 @@ const char* GetInterpolationQualifier(bool msaa, bool ssaa, bool in_glsl_interfa static const char s_shader_uniforms[] = "\tuint components;\n" "\tuint xfmem_dualTexInfo;\n" "\tuint xfmem_numColorChans;\n" - "\tuint color_chan_alpha;\n" + "\tuint missing_color_hex;\n" + "\tfloat4 missing_color_value;\n" "\tfloat4 " I_POSNORMALMATRIX "[6];\n" "\tfloat4 " I_PROJECTION "[4];\n" "\tint4 " I_MATERIALS "[4];\n" diff --git a/Source/Core/VideoCommon/UberShaderVertex.cpp b/Source/Core/VideoCommon/UberShaderVertex.cpp index 0f33168e88..11bdecd70a 100644 --- a/Source/Core/VideoCommon/UberShaderVertex.cpp +++ b/Source/Core/VideoCommon/UberShaderVertex.cpp @@ -189,8 +189,7 @@ ShaderCode GenVertexShader(APIType api_type, const ShaderHostConfig& host_config out.Write("for (uint color = 0u; color < {}u; color++) {{\n", NUM_XF_COLOR_CHANNELS); out.Write(" if ((color == 0u || use_color_1) && (components & ({}u << color)) != 0u) {{\n", VB_HAS_COL0); - out.Write(" float4 color_value;\n" - " // Use color0 for channel 0, and color1 for channel 1 if both colors 0 and 1 are " + out.Write(" // Use color0 for channel 0, and color1 for channel 1 if both colors 0 and 1 are " "present.\n" " if (color == 0u)\n" " vertex_color_0 = rawcolor0;\n" @@ -201,12 +200,10 @@ ShaderCode GenVertexShader(APIType api_type, const ShaderHostConfig& host_config out.Write(" // Use color1 for channel 0 if color0 is not present.\n" " vertex_color_0 = rawcolor1;\n" " }} else {{\n" - " // The default alpha channel depends on the number of components in the vertex.\n" - " float alpha = float((color_chan_alpha >> color) & 1u);\n" " if (color == 0u)\n" - " vertex_color_0 = float4(1.0, 1.0, 1.0, alpha);\n" + " vertex_color_0 = missing_color_value;\n" " else\n" - " vertex_color_1 = float4(1.0, 1.0, 1.0, alpha);\n" + " vertex_color_1 = missing_color_value;\n" " }}\n" "}}\n" "\n"); diff --git a/Source/Core/VideoCommon/VertexShaderGen.cpp b/Source/Core/VideoCommon/VertexShaderGen.cpp index 28d1e78442..a7b32c4725 100644 --- a/Source/Core/VideoCommon/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/VertexShaderGen.cpp @@ -214,10 +214,7 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho } else { - // The default alpha channel depends on the number of components in the vertex format. - out.Write( - "vertex_color_{0} = float4(1.0, 1.0, 1.0, float((color_chan_alpha >> {0}) & 1u));\n", - color); + out.Write("vertex_color_{0} = missing_color_value;\n", color); } } diff --git a/Source/Core/VideoCommon/VertexShaderManager.cpp b/Source/Core/VideoCommon/VertexShaderManager.cpp index 8047714f61..fa999d7d3e 100644 --- a/Source/Core/VideoCommon/VertexShaderManager.cpp +++ b/Source/Core/VideoCommon/VertexShaderManager.cpp @@ -136,6 +136,18 @@ void VertexShaderManager::Dirty() // TODO: A cleaner way to control the matrices without making a mess in the parameters field void VertexShaderManager::SetConstants() { + if (constants.missing_color_hex != g_ActiveConfig.iMissingColorValue) + { + const float a = (g_ActiveConfig.iMissingColorValue) & 0xFF; + const float b = (g_ActiveConfig.iMissingColorValue >> 8) & 0xFF; + const float g = (g_ActiveConfig.iMissingColorValue >> 16) & 0xFF; + const float r = (g_ActiveConfig.iMissingColorValue >> 24) & 0xFF; + constants.missing_color_hex = g_ActiveConfig.iMissingColorValue; + constants.missing_color_value = {r / 255, g / 255, b / 255, a / 255}; + + dirty = true; + } + if (nTransformMatricesChanged[0] >= 0) { int startn = nTransformMatricesChanged[0] / 4; @@ -615,17 +627,6 @@ void VertexShaderManager::SetVertexFormat(u32 components) constants.components = components; dirty = true; } - - // The default alpha channel seems to depend on the number of components in the vertex format. - // If the vertex attribute has an alpha channel, zero is used, otherwise one. - const auto g0 = g_main_cp_state.vtx_attr[g_main_cp_state.last_id].g0; - const u32 color_chan_alpha = (g0.Color0Elements == ColorComponentCount::RGB ? 1 : 0) | - (g0.Color1Elements == ColorComponentCount::RGB ? 2 : 0); - if (color_chan_alpha != constants.color_chan_alpha) - { - constants.color_chan_alpha = color_chan_alpha; - dirty = true; - } } void VertexShaderManager::SetTexMatrixInfoChanged(int index) diff --git a/Source/Core/VideoCommon/VideoConfig.cpp b/Source/Core/VideoCommon/VideoConfig.cpp index 9ed9a599e4..db0845a643 100644 --- a/Source/Core/VideoCommon/VideoConfig.cpp +++ b/Source/Core/VideoCommon/VideoConfig.cpp @@ -158,6 +158,7 @@ void VideoConfig::Refresh() bEFBEmulateFormatChanges = Config::Get(Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES); bVertexRounding = Config::Get(Config::GFX_HACK_VERTEX_ROUDING); iEFBAccessTileSize = Config::Get(Config::GFX_HACK_EFB_ACCESS_TILE_SIZE); + iMissingColorValue = Config::Get(Config::GFX_HACK_MISSING_COLOR_VALUE); bPerfQueriesEnable = Config::Get(Config::GFX_PERF_QUERIES_ENABLE); diff --git a/Source/Core/VideoCommon/VideoConfig.h b/Source/Core/VideoCommon/VideoConfig.h index 6c328c864b..39a7b79c9d 100644 --- a/Source/Core/VideoCommon/VideoConfig.h +++ b/Source/Core/VideoCommon/VideoConfig.h @@ -135,6 +135,7 @@ struct VideoConfig final int iEFBAccessTileSize; int iLog; // CONF_ bits int iSaveTargetId; // TODO: Should be dropped + u32 iMissingColorValue; // Stereoscopy StereoMode stereo_mode; From 820d9ffbfa9fb06618ff8d93d5e9a1da72d897c0 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 8 Jun 2021 21:29:53 -0700 Subject: [PATCH 2/3] Remove PixelShaderGen hasindstage --- Source/Core/VideoCommon/GXPipelineTypes.h | 3 +-- Source/Core/VideoCommon/PixelShaderGen.cpp | 6 ------ Source/Core/VideoCommon/PixelShaderGen.h | 4 +--- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/Source/Core/VideoCommon/GXPipelineTypes.h b/Source/Core/VideoCommon/GXPipelineTypes.h index 8892d386f5..694c368ef6 100644 --- a/Source/Core/VideoCommon/GXPipelineTypes.h +++ b/Source/Core/VideoCommon/GXPipelineTypes.h @@ -20,8 +20,7 @@ namespace VideoCommon // As pipelines encompass both shader UIDs and render states, changes to either of these should // also increment the pipeline UID version. Incrementing the UID version will cause all UID // caches to be invalidated. -// TODO: Remove PixelShaderUid hasindstage on the next UID version bump -constexpr u32 GX_PIPELINE_UID_VERSION = 2; // Last changed in PR 9122 +constexpr u32 GX_PIPELINE_UID_VERSION = 3; // Last changed in PR 9532 struct GXPipelineUid { diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index 37e856ae42..567d161565 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -236,12 +236,6 @@ PixelShaderUid GetPixelShaderUid() for (unsigned int n = 0; n < numStages; n++) { uid_data->stagehash[n].tevorders_texcoord = bpmem.tevorders[n / 2].getTexCoord(n & 1); - - // hasindstage previously was used as a criterion to set tevind to 0, but there are variables in - // tevind that are used even if the indirect stage is disabled, so now it is only left in to - // avoid breaking existing UIDs (in most cases, games will have 0 in tevind anyways) - // TODO: Remove hasindstage on the next UID version bump - uid_data->stagehash[n].hasindstage = bpmem.tevind[n].bt < bpmem.genMode.numindstages; uid_data->stagehash[n].tevind = bpmem.tevind[n].hex; TevStageCombiner::ColorCombiner& cc = bpmem.combiners[n].colorC; diff --git a/Source/Core/VideoCommon/PixelShaderGen.h b/Source/Core/VideoCommon/PixelShaderGen.h index d75fac8eb7..b1f2c20681 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.h +++ b/Source/Core/VideoCommon/PixelShaderGen.h @@ -130,11 +130,9 @@ struct pixel_shader_uid_data u32 tevorders_texcoord : 3; u32 tevorders_enable : 1; RasColorChan tevorders_colorchan : 3; - u32 pad1 : 6; + u32 pad1 : 7; // TODO: Clean up the swapXY mess - // TODO: remove hasindstage, as it no longer does anything useful - u32 hasindstage : 1; u32 tevind : 21; u32 tevksel_swap1a : 2; u32 tevksel_swap2a : 2; From 1500a0119bbb9086b0482a94b154612a0684f194 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 8 Jun 2021 21:35:43 -0700 Subject: [PATCH 3/3] Eliminate TVtxDesc.GetLegacyHex --- Source/Core/Core/State.cpp | 2 +- Source/Core/VideoCommon/CPMemory.cpp | 4 +--- Source/Core/VideoCommon/CPMemory.h | 13 ------------- Source/Core/VideoCommon/VertexLoaderBase.h | 4 ++-- Source/UnitTests/VideoCommon/VertexLoaderTest.cpp | 3 ++- 5 files changed, 6 insertions(+), 20 deletions(-) diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index 2ab2146c06..d84c6cbb84 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -74,7 +74,7 @@ static Common::Event g_compressAndDumpStateSyncEvent; static std::thread g_save_thread; // Don't forget to increase this after doing changes on the savestate system -constexpr u32 STATE_VERSION = 131; // Last changed in PR 9773 +constexpr u32 STATE_VERSION = 132; // Last changed in PR 9532 // Maps savestate versions to Dolphin versions. // Versions after 42 don't need to be added to this list, diff --git a/Source/Core/VideoCommon/CPMemory.cpp b/Source/Core/VideoCommon/CPMemory.cpp index eb59869368..87f3375b31 100644 --- a/Source/Core/VideoCommon/CPMemory.cpp +++ b/Source/Core/VideoCommon/CPMemory.cpp @@ -17,9 +17,7 @@ void DoCPState(PointerWrap& p) p.DoArray(g_main_cp_state.array_strides); p.Do(g_main_cp_state.matrix_index_a); p.Do(g_main_cp_state.matrix_index_b); - u64 vtx_desc = g_main_cp_state.vtx_desc.GetLegacyHex(); - p.Do(vtx_desc); - g_main_cp_state.vtx_desc.SetLegacyHex(vtx_desc); + p.Do(g_main_cp_state.vtx_desc); p.DoArray(g_main_cp_state.vtx_attr); p.DoMarker("CP Memory"); if (p.mode == PointerWrap::MODE_READ) diff --git a/Source/Core/VideoCommon/CPMemory.h b/Source/Core/VideoCommon/CPMemory.h index 488d210129..ae240254e3 100644 --- a/Source/Core/VideoCommon/CPMemory.h +++ b/Source/Core/VideoCommon/CPMemory.h @@ -229,19 +229,6 @@ struct TVtxDesc Low low; High high; - - // This structure was originally packed into bits 0..32, using 33 total bits. - // The actual format has 17 bits in the low one and 16 bits in the high one, - // but the old format is still supported for compatibility. - u64 GetLegacyHex() const { return (low.Hex & 0x1FFFF) | (u64(high.Hex) << 17); } - u32 GetLegacyHex0() const { return static_cast(GetLegacyHex()); } - // Only *1* bit is used in this - u32 GetLegacyHex1() const { return static_cast(GetLegacyHex() >> 32); } - void SetLegacyHex(u64 value) - { - low.Hex = value & 0x1FFFF; - high.Hex = value >> 17; - } }; template <> struct fmt::formatter diff --git a/Source/Core/VideoCommon/VertexLoaderBase.h b/Source/Core/VideoCommon/VertexLoaderBase.h index 9b030e1f2b..06babc9d4a 100644 --- a/Source/Core/VideoCommon/VertexLoaderBase.h +++ b/Source/Core/VideoCommon/VertexLoaderBase.h @@ -24,8 +24,8 @@ public: VertexLoaderUID() {} VertexLoaderUID(const TVtxDesc& vtx_desc, const VAT& vat) { - vid[0] = vtx_desc.GetLegacyHex0(); - vid[1] = vtx_desc.GetLegacyHex1(); + vid[0] = vtx_desc.low.Hex; + vid[1] = vtx_desc.high.Hex; vid[2] = vat.g0.Hex; vid[3] = vat.g1.Hex; vid[4] = vat.g2.Hex; diff --git a/Source/UnitTests/VideoCommon/VertexLoaderTest.cpp b/Source/UnitTests/VideoCommon/VertexLoaderTest.cpp index 925a13114a..93656a9d23 100644 --- a/Source/UnitTests/VideoCommon/VertexLoaderTest.cpp +++ b/Source/UnitTests/VideoCommon/VertexLoaderTest.cpp @@ -29,7 +29,8 @@ TEST(VertexLoaderUID, UniqueEnough) memset(&vat, 0, sizeof(vat)); uids.insert(VertexLoaderUID(vtx_desc, vat)); - vtx_desc.SetLegacyHex(0xFEDCBA9876543210ull); + vtx_desc.low.Hex = 0x76543210; + vtx_desc.high.Hex = 0xFEDCBA98; EXPECT_EQ(uids.end(), uids.find(VertexLoaderUID(vtx_desc, vat))); uids.insert(VertexLoaderUID(vtx_desc, vat));