summaryrefslogtreecommitdiffstats
path: root/src/video_core/engines/shader_bytecode.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/engines/shader_bytecode.h111
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"),