diff --git a/GPU/Common/ShaderId.cpp b/GPU/Common/ShaderId.cpp index f3a8e09228..21b4519af9 100644 --- a/GPU/Common/ShaderId.cpp +++ b/GPU/Common/ShaderId.cpp @@ -11,7 +11,7 @@ #include "GPU/Common/ShaderId.h" #include "GPU/Common/VertexDecoderCommon.h" -std::string VertexShaderDesc(const ShaderID &id) { +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 "; @@ -60,7 +60,7 @@ std::string VertexShaderDesc(const ShaderID &id) { return desc.str(); } -void ComputeVertexShaderID(ShaderID *id_out, u32 vertType, bool useHWTransform) { +void ComputeVertexShaderID(VShaderID *id_out, u32 vertType, bool useHWTransform) { bool isModeThrough = (vertType & GE_VTYPE_THROUGH) != 0; bool doTexture = gstate.isTextureMapEnabled() && !gstate.isModeClear(); bool doTextureTransform = gstate.getUVGenMode() == GE_TEXMAP_TEXTURE_MATRIX; @@ -81,7 +81,7 @@ void ComputeVertexShaderID(ShaderID *id_out, u32 vertType, bool useHWTransform) bool enableFog = gstate.isFogEnabled() && !isModeThrough && !gstate.isModeClear(); bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled() && !isModeThrough; - ShaderID id; + VShaderID id; id.SetBit(VS_BIT_LMODE, lmode); id.SetBit(VS_BIT_IS_THROUGH, isModeThrough); id.SetBit(VS_BIT_ENABLE_FOG, enableFog); @@ -160,7 +160,7 @@ static bool MatrixNeedsProjection(const float m[12]) { return m[2] != 0.0f || m[5] != 0.0f || m[8] != 0.0f || m[11] != 1.0f; } -std::string FragmentShaderDesc(const ShaderID &id) { +std::string FragmentShaderDesc(const FShaderID &id) { std::stringstream desc; desc << StringFromFormat("%08x:%08x ", id.d[1], id.d[0]); if (id.Bit(FS_BIT_CLEARMODE)) desc << "Clear "; @@ -226,8 +226,8 @@ std::string FragmentShaderDesc(const ShaderID &id) { // Here we must take all the bits of the gstate that determine what the fragment shader will // look like, and concatenate them together into an ID. -void ComputeFragmentShaderID(ShaderID *id_out, const Draw::Bugs &bugs) { - ShaderID id; +void ComputeFragmentShaderID(FShaderID *id_out, const Draw::Bugs &bugs) { + FShaderID id; if (gstate.isModeClear()) { // We only need one clear shader, so let's ignore the rest of the bits. id.SetBit(FS_BIT_CLEARMODE); diff --git a/GPU/Common/ShaderId.h b/GPU/Common/ShaderId.h index ec57b0273f..e614d8f112 100644 --- a/GPU/Common/ShaderId.h +++ b/GPU/Common/ShaderId.h @@ -8,7 +8,7 @@ // TODO: There will be additional bits, indicating that groups of these will be // sent to the shader and processed there. This will cut down the number of shaders ("ubershader approach") // This is probably only really worth doing for lighting and bones. -enum { +enum VShaderBit : uint8_t { VS_BIT_LMODE = 0, VS_BIT_IS_THROUGH = 1, VS_BIT_ENABLE_FOG = 2, @@ -55,9 +55,12 @@ enum { // No more free }; +static inline VShaderBit operator +(VShaderBit bit, int i) { + return VShaderBit((int)bit + i); +} // Local -enum { +enum FShaderBit : uint8_t { FS_BIT_CLEARMODE = 0, FS_BIT_DO_TEXTURE = 1, FS_BIT_TEXFUNC = 2, // 3 bits @@ -91,6 +94,10 @@ enum { // 50+ are free. }; +static inline FShaderBit operator +(FShaderBit bit, int i) { + return FShaderBit((int)bit + i); +} + struct ShaderID { ShaderID() { clear(); @@ -126,6 +133,20 @@ struct ShaderID { bool operator != (const ShaderID &other) const { return !(*this == other); } + + uint32_t Word(int word) const { + return d[word]; + } + + void ToString(std::string *dest) const { + dest->resize(sizeof(d)); + memcpy(&(*dest)[0], d, sizeof(d)); + } + void FromString(std::string src) { + memcpy(d, &(src)[0], sizeof(d)); + } + +protected: bool Bit(int bit) const { return (d[bit >> 5] >> (bit & 31)) & 1; } @@ -134,9 +155,6 @@ struct ShaderID { const int mask = (1 << count) - 1; return (d[bit >> 5] >> (bit & 31)) & mask; } - uint32_t Word(int word) const { - return d[word]; - } void SetBit(int bit, bool value = true) { if (value) { d[bit >> 5] |= 1 << (bit & 31); @@ -148,14 +166,6 @@ struct ShaderID { d[bit >> 5] |= (value & mask) << (bit & 31); } } - - void ToString(std::string *dest) const { - dest->resize(sizeof(d)); - memcpy(&(*dest)[0], d, sizeof(d)); - } - void FromString(std::string src) { - memcpy(d, &(src)[0], sizeof(d)); - } }; struct VShaderID : ShaderID { @@ -165,6 +175,22 @@ struct VShaderID : ShaderID { explicit VShaderID(ShaderID &src) { memcpy(d, src.d, sizeof(d)); } + + bool Bit(VShaderBit bit) const { + return ShaderID::Bit((int)bit); + } + + int Bits(VShaderBit bit, int count) const { + return ShaderID::Bits((int)bit, count); + } + + void SetBit(VShaderBit bit, bool value = true) { + ShaderID::SetBit((int)bit, value); + } + + void SetBits(VShaderBit bit, int count, int value) { + ShaderID::SetBits((int)bit, count, value); + } }; struct FShaderID : ShaderID { @@ -174,6 +200,22 @@ struct FShaderID : ShaderID { explicit FShaderID(ShaderID &src) { memcpy(d, src.d, sizeof(d)); } + + bool Bit(FShaderBit bit) const { + return ShaderID::Bit((int)bit); + } + + int Bits(FShaderBit bit, int count) const { + return ShaderID::Bits((int)bit, count); + } + + void SetBit(FShaderBit bit, bool value = true) { + ShaderID::SetBit((int)bit, value); + } + + void SetBits(FShaderBit bit, int count, int value) { + ShaderID::SetBits((int)bit, count, value); + } }; namespace Draw { @@ -181,10 +223,10 @@ class Bugs; } -void ComputeVertexShaderID(ShaderID *id, uint32_t vertexType, bool useHWTransform); +void ComputeVertexShaderID(VShaderID *id, uint32_t vertexType, bool useHWTransform); // Generates a compact string that describes the shader. Useful in a list to get an overview // of the current flora of shaders. -std::string VertexShaderDesc(const ShaderID &id); +std::string VertexShaderDesc(const VShaderID &id); -void ComputeFragmentShaderID(ShaderID *id, const Draw::Bugs &bugs); -std::string FragmentShaderDesc(const ShaderID &id); +void ComputeFragmentShaderID(FShaderID *id, const Draw::Bugs &bugs); +std::string FragmentShaderDesc(const FShaderID &id); diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index 585a6cf459..ffafcaa362 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -762,7 +762,7 @@ std::string Shader::GetShaderString(DebugShaderStringType type, ShaderID id) con case SHADER_STRING_SOURCE_CODE: return source_; case SHADER_STRING_SHORT_DESC: - return isFragment_ ? FragmentShaderDesc(id) : VertexShaderDesc(id); + return isFragment_ ? FragmentShaderDesc(FShaderID(id)) : VertexShaderDesc(VShaderID(id)); default: return "N/A"; }