diff --git a/Common/Data/Text/StringWriter.h b/Common/Data/Text/StringWriter.h index 42d29998ce..0486323a50 100644 --- a/Common/Data/Text/StringWriter.h +++ b/Common/Data/Text/StringWriter.h @@ -22,6 +22,9 @@ public: std::string_view as_view() const { return std::string_view(start_, p_ - start_); } + std::string as_string() const { + return std::string(start_, p_ - start_); + } const char *begin() const { return start_; } diff --git a/GPU/Common/ShaderId.cpp b/GPU/Common/ShaderId.cpp index 56178ae393..db3c5d8474 100644 --- a/GPU/Common/ShaderId.cpp +++ b/GPU/Common/ShaderId.cpp @@ -4,6 +4,7 @@ #include "Common/GPU/thin3d.h" #include "Common/StringUtils.h" +#include "Common/Data/Text/StringWriter.h" #include "Core/Config.h" #include "GPU/ge_constants.h" @@ -15,53 +16,57 @@ #include "GPU/Common/DrawEngineCommon.h" // Just for ClipInfoFlags std::string VertexShaderDesc(const VShaderID &id) { - std::stringstream desc; - desc << StringFromFormat("%08x:%08x ", id.d[1], id.d[0]); - if (id.Bit(VS_BIT_IS_THROUGH)) desc << "THR "; - if (id.Bit(VS_BIT_USE_HW_TRANSFORM)) desc << "HWX "; - if (id.Bit(VS_BIT_HAS_COLOR)) desc << "C "; - if (id.Bit(VS_BIT_HAS_TEXCOORD)) desc << "T "; - if (id.Bit(VS_BIT_HAS_NORMAL)) desc << "N "; - if (id.Bit(VS_BIT_LMODE)) desc << "LM "; - if (id.Bit(VS_BIT_NORM_REVERSE)) desc << "RevN "; + char buffer[512]; + StringWriter desc(buffer, sizeof(buffer)); + + desc.F("%08x:%08x ", id.d[1], id.d[0]); + if (id.Bit(VS_BIT_IS_THROUGH)) desc.C("THR "); + if (id.Bit(VS_BIT_USE_HW_TRANSFORM)) desc.C("HWX "); else desc.C("SWX "); + if (id.Bit(VS_BIT_HAS_NORMAL)) desc.C("N "); + if (id.Bit(VS_BIT_HAS_TEXCOORD)) desc.C("T "); + if (id.Bit(VS_BIT_HAS_COLOR)) desc.C("C "); + if (id.Bit(VS_BIT_LMODE)) desc.C("LM "); + if (id.Bit(VS_BIT_NORM_REVERSE)) desc.C("RevN "); + if (id.Bit(VS_BIT_FLATSHADE)) desc.C("Flat "); + if (id.Bits(VS_BIT_MATERIAL_UPDATE, 3)) desc.C("MatUp:").F("%d", id.Bits(VS_BIT_MATERIAL_UPDATE, 3)).C(" "); + int uvgMode = id.Bits(VS_BIT_UVGEN_MODE, 2); + static constexpr std::string_view uvgModes[4] = {"UV ", "UVMtx ", "UVEnv ", "UVUnk "}; + if (uvgMode) desc.W(uvgModes[uvgMode]); if (uvgMode == GE_TEXMAP_TEXTURE_MATRIX) { int uvprojMode = id.Bits(VS_BIT_UVPROJ_MODE, 2); - const char *uvprojModes[4] = { "TexProjPos ", "TexProjUV ", "TexProjNNrm ", "TexProjNrm " }; - desc << uvprojModes[uvprojMode]; + static constexpr std::string_view uvprojModes[4] = { "TexProjPos ", "TexProjUV ", "TexProjNNrm ", "TexProjNrm " }; + desc.W(uvprojModes[uvprojMode]); } - static constexpr std::array uvgModes = { "UV ", "UVMtx ", "UVEnv ", "UVUnk " }; + + if (id.Bit(VS_BIT_ENABLE_BONES)) desc.F("Bones:%d ", id.Bits(VS_BIT_BONES, 3) + 1); + if (id.Bits(VS_BIT_WEIGHT_FMTSCALE, 2)) desc.F("WScale:%d ", id.Bits(VS_BIT_WEIGHT_FMTSCALE, 2)); + int ls0 = id.Bits(VS_BIT_LS0, 2); int ls1 = id.Bits(VS_BIT_LS1, 2); - if (uvgMode) desc << uvgModes[uvgMode]; - if (id.Bit(VS_BIT_ENABLE_BONES)) desc << "Bones:" << (id.Bits(VS_BIT_BONES, 3) + 1) << " "; + if (id.Bit(VS_BIT_FS_MINMAX_DISCARD)) desc.C("FSMinMax "); + if (id.Bit(VS_BIT_FS_DEPTH_CLAMP)) desc.C("FSDepthClamp "); // Lights if (id.Bit(VS_BIT_LIGHTING_ENABLE)) { - desc << "Light: "; + desc.C("Light: "); } if (id.Bit(VS_BIT_LIGHT_UBERSHADER)) { - desc << "LightUberShader "; + desc.C("LightUberShader "); } for (int i = 0; i < 4; i++) { bool enabled = id.Bit(VS_BIT_LIGHT0_ENABLE + i) && id.Bit(VS_BIT_LIGHTING_ENABLE); if (enabled || (uvgMode == GE_TEXMAP_ENVIRONMENT_MAP && (ls0 == i || ls1 == i))) { - desc << i << ": "; - desc << "c:" << id.Bits(VS_BIT_LIGHT0_COMP + 4 * i, 2) << " t:" << id.Bits(VS_BIT_LIGHT0_TYPE + 4 * i, 2) << " "; + desc.F("%d: ", i); + desc.F("c:%d t:%d ", id.Bits(VS_BIT_LIGHT0_COMP + 4 * i, 2), id.Bits(VS_BIT_LIGHT0_TYPE + 4 * i, 2)); } } - if (id.Bits(VS_BIT_MATERIAL_UPDATE, 3)) desc << "MatUp:" << id.Bits(VS_BIT_MATERIAL_UPDATE, 3) << " "; - if (id.Bits(VS_BIT_WEIGHT_FMTSCALE, 2)) desc << "WScale " << id.Bits(VS_BIT_WEIGHT_FMTSCALE, 2) << " "; - if (id.Bit(VS_BIT_FLATSHADE)) desc << "Flat "; - if (id.Bit(VS_BIT_VERTEX_RANGE_CULLING)) desc << "RangeCull "; + if (id.Bit(VS_BIT_SIMPLE_STEREO)) desc.C("SimpleStereo "); + if (id.Bit(VS_BIT_VERTEX_RANGE_CULLING)) desc.C("RangeCull "); - if (id.Bit(VS_BIT_SIMPLE_STEREO)) desc << "SimpleStereo "; - if (id.Bit(VS_BIT_FS_MINMAX_DISCARD)) desc << "FSMinMax "; - if (id.Bit(VS_BIT_FS_DEPTH_CLAMP)) desc << "FSDepthClamp "; - - return desc.str(); + return desc.as_string(); } void ComputeVertexShaderID(VShaderID *id_out, u32 vertType, bool useHWTransform, bool weightsAsFloat, bool useSkinInDecode, ClipInfoFlags clipInfoFlags) { diff --git a/GPU/Common/ShaderId.h b/GPU/Common/ShaderId.h index 26807c3837..b853a4dc6b 100644 --- a/GPU/Common/ShaderId.h +++ b/GPU/Common/ShaderId.h @@ -24,52 +24,47 @@ inline bool needFragmentDepthClamp() { // VS_BIT_LIGHT_UBERSHADER indicates that some groups of these will be // sent to the shader and processed there. This cuts down the number of shaders ("ubershader approach"). enum VShaderBit : uint8_t { - VS_BIT_LMODE = 0, - VS_BIT_IS_THROUGH = 1, - // bit 2 is free. - VS_BIT_HAS_COLOR = 3, - // bit 4 is free. - VS_BIT_VERTEX_RANGE_CULLING = 5, - VS_BIT_SIMPLE_STEREO = 6, - // bit 7 is free, - VS_BIT_USE_HW_TRANSFORM = 8, - VS_BIT_HAS_NORMAL = 9, // conditioned on hw transform - VS_BIT_NORM_REVERSE = 10, - VS_BIT_HAS_TEXCOORD = 11, - // 4 bits free: 12-15 - VS_BIT_UVGEN_MODE = 16, - VS_BIT_UVPROJ_MODE = 18, // 2, can overlap with LS0 - VS_BIT_LS0 = 18, // 2 - VS_BIT_LS1 = 20, // 2 - VS_BIT_BONES = 22, // 3 should be enough, not 8 - // 25 - 29 are free. - VS_BIT_ENABLE_BONES = 30, + VS_BIT_IS_THROUGH = 0, + VS_BIT_USE_HW_TRANSFORM = 1, + VS_BIT_HAS_NORMAL = 2, // conditioned on hw transform + VS_BIT_HAS_TEXCOORD = 3, + VS_BIT_HAS_COLOR = 4, + VS_BIT_LMODE = 5, + VS_BIT_NORM_REVERSE = 6, + VS_BIT_FLATSHADE = 7, + VS_BIT_MATERIAL_UPDATE = 8, // 3 bits + // Free bit: 11 + VS_BIT_UVGEN_MODE = 12, // 2 bits + VS_BIT_UVPROJ_MODE = 14, // 2 bits + VS_BIT_ENABLE_BONES = 16, + VS_BIT_WEIGHT_FMTSCALE = 17, // only two bits + VS_BIT_BONES = 19, // 3 should be enough to represent 1-8 bones. + VS_BIT_FS_MINMAX_DISCARD = 22, // Do min/max and/or depth clamp in the fragment shader. It just means we need to forward Z and W to the fragment shader. + VS_BIT_FS_DEPTH_CLAMP = 23, // Do depth clamp in the fragment shader. + VS_BIT_LIGHTING_ENABLE = 24, + VS_BIT_LS0 = 25, // 2 bits + VS_BIT_LS1 = 27, // 2 bits // If this is set along with LIGHTING_ENABLE, all other lighting bits below // are passed to the shader directly instead. - VS_BIT_LIGHT_UBERSHADER = 31, + VS_BIT_LIGHT_UBERSHADER = 29, - VS_BIT_LIGHT0_COMP = 32, // 2 bits - VS_BIT_LIGHT0_TYPE = 34, // 2 bits - VS_BIT_LIGHT1_COMP = 36, // 2 bits - VS_BIT_LIGHT1_TYPE = 38, // 2 bits - VS_BIT_LIGHT2_COMP = 40, // 2 bits - VS_BIT_LIGHT2_TYPE = 42, // 2 bits - VS_BIT_LIGHT3_COMP = 44, // 2 bits - VS_BIT_LIGHT3_TYPE = 46, // 2 bits - VS_BIT_MATERIAL_UPDATE = 48, // 3 bits - // Bit 51 is free. - VS_BIT_LIGHT0_ENABLE = 52, - VS_BIT_LIGHT1_ENABLE = 53, - VS_BIT_LIGHT2_ENABLE = 54, - VS_BIT_LIGHT3_ENABLE = 55, - VS_BIT_LIGHTING_ENABLE = 56, - VS_BIT_WEIGHT_FMTSCALE = 57, // only two bits - // 59 - 61 are free. - VS_BIT_FS_MINMAX_DISCARD = 59, // Do min/max and/or depth clamp in the fragment shader. It just means we need to forward Z and W to the fragment shader. - VS_BIT_FS_DEPTH_CLAMP = 60, // Do depth clamp in the fragment shader. - VS_BIT_FLATSHADE = 62, // 1 bit - // Bit 63 is free. + VS_BIT_LIGHT0_COMP = 30, // 2 bits + VS_BIT_LIGHT0_TYPE = 32, // 2 bits + VS_BIT_LIGHT1_COMP = 34, // 2 bits + VS_BIT_LIGHT1_TYPE = 36, // 2 bits + VS_BIT_LIGHT2_COMP = 38, // 2 bits + VS_BIT_LIGHT2_TYPE = 40, // 2 bits + VS_BIT_LIGHT3_COMP = 42, // 2 bits + VS_BIT_LIGHT3_TYPE = 44, // 2 bits + VS_BIT_LIGHT0_ENABLE = 46, + VS_BIT_LIGHT1_ENABLE = 47, + VS_BIT_LIGHT2_ENABLE = 48, + VS_BIT_LIGHT3_ENABLE = 49, + + VS_BIT_VERTEX_RANGE_CULLING = 50, + VS_BIT_SIMPLE_STEREO = 51, + // bits 52-63 are free. }; static inline VShaderBit operator +(VShaderBit bit, int i) { diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index 34cf666006..a086a0f3e8 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -900,7 +900,7 @@ enum class CacheDetectFlags { }; #define CACHE_HEADER_MAGIC 0x83277592 -#define CACHE_VERSION 40 +#define CACHE_VERSION 41 struct CacheHeader { uint32_t magic; diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index acf919f0b9..c2b8c20ca5 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -408,7 +408,7 @@ enum class VulkanCacheDetectFlags { }; #define CACHE_HEADER_MAGIC 0xff51f420 -#define CACHE_VERSION 56 +#define CACHE_VERSION 57 struct VulkanCacheHeader { uint32_t magic;