Reorganize the vertex ShaderId bits, better sorting order

This commit is contained in:
Henrik Rydgård
2026-07-07 18:37:32 +02:00
parent fdd6da77c0
commit 6508ae0aae
5 changed files with 74 additions and 71 deletions
+3
View File
@@ -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_;
}
+32 -27
View File
@@ -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<const char*, 4> 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) {
+37 -42
View File
@@ -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) {
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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;