mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-28 07:50:49 +00:00
Merge pull request #11801 from unknownbrackets/shaderid
GPU: Better typesafety for shader bits
This commit is contained in:
commit
8e0f3c9ea2
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user