diff options
Diffstat (limited to '')
-rw-r--r-- | src/video_core/engines/shader_bytecode.h | 111 |
1 files changed, 100 insertions, 11 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index b038a9d92..3ba6fe614 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h @@ -12,6 +12,7 @@ #include <boost/optional.hpp> +#include "common/assert.h" #include "common/bit_field.h" #include "common/common_types.h" @@ -79,6 +80,9 @@ union Attribute { // shader, and a tuple of (TessCoord.x, TessCoord.y, TessCoord.z, ~) when inside a Tess Eval // shader. TessCoordInstanceIDVertexID = 47, + // This attribute contains a tuple of (Unk, Unk, Unk, gl_FrontFacing) when inside a fragment + // shader. It is unknown what the other values contain. + FrontFacing = 63, }; union { @@ -214,6 +218,18 @@ enum class FlowCondition : u64 { Fcsm_Tr = 0x1C, // TODO(bunnei): What is this used for? }; +enum class PredicateResultMode : u64 { + None = 0x0, + NotZero = 0x3, +}; + +enum class TextureType : u64 { + Texture1D = 0, + Texture2D = 1, + Texture3D = 2, + TextureCube = 3, +}; + union Instruction { Instruction& operator=(const Instruction& instr) { value = instr.value; @@ -254,7 +270,7 @@ union Instruction { BitField<39, 1, u64> invert_a; BitField<40, 1, u64> invert_b; BitField<41, 2, LogicOperation> operation; - BitField<44, 2, u64> unk44; + BitField<44, 2, PredicateResultMode> pred_result_mode; BitField<48, 3, Pred> pred48; } lop; @@ -284,6 +300,10 @@ union Instruction { } alu; union { + BitField<48, 1, u64> negate_b; + } fmul; + + union { BitField<48, 1, u64> is_signed; } shift; @@ -421,6 +441,8 @@ union Instruction { } conversion; union { + BitField<28, 1, u64> array; + BitField<29, 2, TextureType> texture_type; BitField<31, 4, u64> component_mask; bool IsComponentEnabled(size_t component) const { @@ -429,29 +451,88 @@ union Instruction { } tex; union { - BitField<50, 3, u64> component_mask_selector; + BitField<28, 1, u64> array; + BitField<29, 2, TextureType> texture_type; + BitField<56, 2, u64> component; + } tld4; + + union { + BitField<52, 2, u64> component; + } tld4s; + + union { BitField<0, 8, Register> gpr0; BitField<28, 8, Register> gpr28; + BitField<50, 3, u64> component_mask_selector; + BitField<53, 4, u64> texture_info; + + TextureType GetTextureType() const { + // The TEXS instruction has a weird encoding for the texture type. + if (texture_info == 0) + return TextureType::Texture1D; + if (texture_info >= 1 && texture_info <= 9) + return TextureType::Texture2D; + if (texture_info >= 10 && texture_info <= 11) + return TextureType::Texture3D; + if (texture_info >= 12 && texture_info <= 13) + return TextureType::TextureCube; + + UNIMPLEMENTED(); + } + + bool IsArrayTexture() const { + // TEXS only supports Texture2D arrays. + return texture_info >= 7 && texture_info <= 9; + } bool HasTwoDestinations() const { return gpr28.Value() != Register::ZeroIndex; } bool IsComponentEnabled(size_t component) const { - static constexpr std::array<std::array<u32, 8>, 4> mask_lut{ - {{}, - {0x1, 0x2, 0x4, 0x8, 0x3}, - {0x1, 0x2, 0x4, 0x8, 0x3, 0x9, 0xa, 0xc}, - {0x7, 0xb, 0xd, 0xe, 0xf}}}; + static constexpr std::array<std::array<u32, 8>, 4> mask_lut{{ + {}, + {0x1, 0x2, 0x4, 0x8, 0x3, 0x9, 0xa, 0xc}, + {0x1, 0x2, 0x4, 0x8, 0x3, 0x9, 0xa, 0xc}, + {0x7, 0xb, 0xd, 0xe, 0xf}, + }}; size_t index{gpr0.Value() != Register::ZeroIndex ? 1U : 0U}; index |= gpr28.Value() != Register::ZeroIndex ? 2 : 0; - return ((1ull << component) & mask_lut[index][component_mask_selector]) != 0; + u32 mask = mask_lut[index][component_mask_selector]; + // A mask of 0 means this instruction uses an unimplemented mask. + ASSERT(mask != 0); + return ((1ull << component) & mask) != 0; } } texs; union { + BitField<53, 4, u64> texture_info; + + TextureType GetTextureType() const { + // The TLDS instruction has a weird encoding for the texture type. + if (texture_info >= 0 && texture_info <= 1) { + return TextureType::Texture1D; + } + if (texture_info == 2 || texture_info == 8 || texture_info == 12 || + texture_info >= 4 && texture_info <= 6) { + return TextureType::Texture2D; + } + if (texture_info == 7) { + return TextureType::Texture3D; + } + + UNIMPLEMENTED(); + } + + bool IsArrayTexture() const { + // TEXS only supports Texture2D arrays. + return texture_info == 8; + } + } tlds; + + union { BitField<20, 24, u64> target; BitField<5, 1, u64> constant_buffer; @@ -513,10 +594,14 @@ public: LD_A, LD_C, ST_A, + LDG, // Load from global memory + STG, // Store in global memory TEX, - TEXQ, // Texture Query - TEXS, // Texture Fetch with scalar/non-vec4 source/destinations - TLDS, // Texture Load with scalar/non-vec4 source/destinations + TEXQ, // Texture Query + TEXS, // Texture Fetch with scalar/non-vec4 source/destinations + TLDS, // Texture Load with scalar/non-vec4 source/destinations + TLD4, // Texture Load 4 + TLD4S, // Texture Load 4 with scalar / non - vec4 source / destinations EXIT, IPA, FFMA_IMM, // Fused Multiply and Add @@ -724,10 +809,14 @@ private: INST("1110111111011---", Id::LD_A, Type::Memory, "LD_A"), INST("1110111110010---", Id::LD_C, Type::Memory, "LD_C"), INST("1110111111110---", Id::ST_A, Type::Memory, "ST_A"), + INST("1110111011010---", Id::LDG, Type::Memory, "LDG"), + INST("1110111011011---", Id::STG, Type::Memory, "STG"), INST("110000----111---", Id::TEX, Type::Memory, "TEX"), INST("1101111101001---", Id::TEXQ, Type::Memory, "TEXQ"), INST("1101100---------", Id::TEXS, Type::Memory, "TEXS"), INST("1101101---------", Id::TLDS, Type::Memory, "TLDS"), + INST("110010----111---", Id::TLD4, Type::Memory, "TLD4"), + INST("1101111100------", Id::TLD4S, Type::Memory, "TLD4S"), INST("111000110000----", Id::EXIT, Type::Trivial, "EXIT"), INST("11100000--------", Id::IPA, Type::Trivial, "IPA"), INST("0011001-1-------", Id::FFMA_IMM, Type::Ffma, "FFMA_IMM"), |