summaryrefslogtreecommitdiffstats
path: root/src/video_core/shader/node.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/shader/node.h170
1 files changed, 150 insertions, 20 deletions
diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h
index c002f90f9..338bab17c 100644
--- a/src/video_core/shader/node.h
+++ b/src/video_core/shader/node.h
@@ -7,6 +7,7 @@
#include <array>
#include <cstddef>
#include <memory>
+#include <optional>
#include <string>
#include <tuple>
#include <utility>
@@ -30,6 +31,8 @@ enum class OperationCode {
FNegate, /// (MetaArithmetic, float a) -> float
FAbsolute, /// (MetaArithmetic, float a) -> float
FClamp, /// (MetaArithmetic, float value, float min, float max) -> float
+ FCastHalf0, /// (MetaArithmetic, f16vec2 a) -> float
+ FCastHalf1, /// (MetaArithmetic, f16vec2 a) -> float
FMin, /// (MetaArithmetic, float a, float b) -> float
FMax, /// (MetaArithmetic, float a, float b) -> float
FCos, /// (MetaArithmetic, float a) -> float
@@ -83,17 +86,18 @@ enum class OperationCode {
UBitfieldExtract, /// (MetaArithmetic, uint value, int offset, int offset) -> uint
UBitCount, /// (MetaArithmetic, uint) -> uint
- HAdd, /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2
- HMul, /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2
- HFma, /// (MetaArithmetic, f16vec2 a, f16vec2 b, f16vec2 c) -> f16vec2
- HAbsolute, /// (f16vec2 a) -> f16vec2
- HNegate, /// (f16vec2 a, bool first, bool second) -> f16vec2
- HClamp, /// (f16vec2 src, float min, float max) -> f16vec2
- HUnpack, /// (Tegra::Shader::HalfType, T value) -> f16vec2
- HMergeF32, /// (f16vec2 src) -> float
- HMergeH0, /// (f16vec2 dest, f16vec2 src) -> f16vec2
- HMergeH1, /// (f16vec2 dest, f16vec2 src) -> f16vec2
- HPack2, /// (float a, float b) -> f16vec2
+ HAdd, /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2
+ HMul, /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2
+ HFma, /// (MetaArithmetic, f16vec2 a, f16vec2 b, f16vec2 c) -> f16vec2
+ HAbsolute, /// (f16vec2 a) -> f16vec2
+ HNegate, /// (f16vec2 a, bool first, bool second) -> f16vec2
+ HClamp, /// (f16vec2 src, float min, float max) -> f16vec2
+ HCastFloat, /// (MetaArithmetic, float a) -> f16vec2
+ HUnpack, /// (Tegra::Shader::HalfType, T value) -> f16vec2
+ HMergeF32, /// (f16vec2 src) -> float
+ HMergeH0, /// (f16vec2 dest, f16vec2 src) -> f16vec2
+ HMergeH1, /// (f16vec2 dest, f16vec2 src) -> f16vec2
+ HPack2, /// (float a, float b) -> f16vec2
LogicalAssign, /// (bool& dst, bool src) -> void
LogicalAnd, /// (bool a, bool b) -> bool
@@ -101,8 +105,7 @@ enum class OperationCode {
LogicalXor, /// (bool a, bool b) -> bool
LogicalNegate, /// (bool a) -> bool
LogicalPick2, /// (bool2 pair, uint index) -> bool
- LogicalAll2, /// (bool2 a) -> bool
- LogicalAny2, /// (bool2 a) -> bool
+ LogicalAnd2, /// (bool2 a) -> bool
LogicalFLessThan, /// (float a, float b) -> bool
LogicalFEqual, /// (float a, float b) -> bool
@@ -146,11 +149,21 @@ enum class OperationCode {
TextureQueryLod, /// (MetaTexture, float[N] coords) -> float4
TexelFetch, /// (MetaTexture, int[N], int) -> float4
- Branch, /// (uint branch_target) -> void
- PushFlowStack, /// (uint branch_target) -> void
- PopFlowStack, /// () -> void
- Exit, /// () -> void
- Discard, /// () -> void
+ ImageLoad, /// (MetaImage, int[N] coords) -> void
+ ImageStore, /// (MetaImage, int[N] coords) -> void
+
+ AtomicImageAdd, /// (MetaImage, int[N] coords) -> void
+ AtomicImageAnd, /// (MetaImage, int[N] coords) -> void
+ AtomicImageOr, /// (MetaImage, int[N] coords) -> void
+ AtomicImageXor, /// (MetaImage, int[N] coords) -> void
+ AtomicImageExchange, /// (MetaImage, int[N] coords) -> void
+
+ Branch, /// (uint branch_target) -> void
+ BranchIndirect, /// (uint branch_target) -> void
+ PushFlowStack, /// (uint branch_target) -> void
+ PopFlowStack, /// () -> void
+ Exit, /// () -> void
+ Discard, /// () -> void
EmitVertex, /// () -> void
EndPrimitive, /// () -> void
@@ -163,6 +176,21 @@ enum class OperationCode {
WorkGroupIdY, /// () -> uint
WorkGroupIdZ, /// () -> uint
+ BallotThread, /// (bool) -> uint
+ VoteAll, /// (bool) -> bool
+ VoteAny, /// (bool) -> bool
+ VoteEqual, /// (bool) -> bool
+
+ ShuffleIndexed, /// (uint value, uint index, uint width) -> uint
+ ShuffleUp, /// (uint value, uint index, uint width) -> uint
+ ShuffleDown, /// (uint value, uint index, uint width) -> uint
+ ShuffleButterfly, /// (uint value, uint index, uint width) -> uint
+
+ InRangeShuffleIndexed, /// (uint index, uint width) -> bool
+ InRangeShuffleUp, /// (uint index, uint width) -> bool
+ InRangeShuffleDown, /// (uint index, uint width) -> bool
+ InRangeShuffleButterfly, /// (uint index, uint width) -> bool
+
Amount,
};
@@ -174,6 +202,11 @@ enum class InternalFlag {
Amount = 4,
};
+enum class MetaStackClass {
+ Ssy,
+ Pbk,
+};
+
class OperationNode;
class ConditionalNode;
class GprNode;
@@ -183,12 +216,13 @@ class PredicateNode;
class AbufNode;
class CbufNode;
class LmemNode;
+class SmemNode;
class GmemNode;
class CommentNode;
using NodeData =
std::variant<OperationNode, ConditionalNode, GprNode, ImmediateNode, InternalFlagNode,
- PredicateNode, AbufNode, CbufNode, LmemNode, GmemNode, CommentNode>;
+ PredicateNode, AbufNode, CbufNode, LmemNode, SmemNode, GmemNode, CommentNode>;
using Node = std::shared_ptr<NodeData>;
using Node4 = std::array<Node, 4>;
using NodeBlock = std::vector<Node>;
@@ -258,6 +292,82 @@ private:
bool is_bindless{}; ///< Whether this sampler belongs to a bindless texture or not.
};
+class Image final {
+public:
+ constexpr explicit Image(std::size_t offset, std::size_t index, Tegra::Shader::ImageType type)
+ : offset{offset}, index{index}, type{type}, is_bindless{false} {}
+
+ constexpr explicit Image(u32 cbuf_index, u32 cbuf_offset, std::size_t index,
+ Tegra::Shader::ImageType type)
+ : offset{(static_cast<u64>(cbuf_index) << 32) | cbuf_offset}, index{index}, type{type},
+ is_bindless{true} {}
+
+ constexpr explicit Image(std::size_t offset, std::size_t index, Tegra::Shader::ImageType type,
+ bool is_bindless, bool is_written, bool is_read, bool is_atomic)
+ : offset{offset}, index{index}, type{type}, is_bindless{is_bindless},
+ is_written{is_written}, is_read{is_read}, is_atomic{is_atomic} {}
+
+ void MarkWrite() {
+ is_written = true;
+ }
+
+ void MarkRead() {
+ is_read = true;
+ }
+
+ void MarkAtomic() {
+ MarkWrite();
+ MarkRead();
+ is_atomic = true;
+ }
+
+ constexpr std::size_t GetOffset() const {
+ return offset;
+ }
+
+ constexpr std::size_t GetIndex() const {
+ return index;
+ }
+
+ constexpr Tegra::Shader::ImageType GetType() const {
+ return type;
+ }
+
+ constexpr bool IsBindless() const {
+ return is_bindless;
+ }
+
+ constexpr bool IsWritten() const {
+ return is_written;
+ }
+
+ constexpr bool IsRead() const {
+ return is_read;
+ }
+
+ constexpr bool IsAtomic() const {
+ return is_atomic;
+ }
+
+ constexpr std::pair<u32, u32> GetBindlessCBuf() const {
+ return {static_cast<u32>(offset >> 32), static_cast<u32>(offset)};
+ }
+
+ constexpr bool operator<(const Image& rhs) const {
+ return std::tie(offset, index, type, is_bindless) <
+ std::tie(rhs.offset, rhs.index, rhs.type, rhs.is_bindless);
+ }
+
+private:
+ u64 offset{};
+ std::size_t index{};
+ Tegra::Shader::ImageType type{};
+ bool is_bindless{};
+ bool is_written{};
+ bool is_read{};
+ bool is_atomic{};
+};
+
struct GlobalMemoryBase {
u32 cbuf_index{};
u32 cbuf_offset{};
@@ -284,8 +394,15 @@ struct MetaTexture {
u32 element{};
};
+struct MetaImage {
+ const Image& image;
+ std::vector<Node> values;
+ u32 element{};
+};
+
/// Parameters that modify an operation but are not part of any particular operand
-using Meta = std::variant<MetaArithmetic, MetaTexture, Tegra::Shader::HalfType>;
+using Meta =
+ std::variant<MetaArithmetic, MetaTexture, MetaImage, MetaStackClass, Tegra::Shader::HalfType>;
/// Holds any kind of operation that can be done in the IR
class OperationNode final {
@@ -473,6 +590,19 @@ private:
Node address;
};
+/// Shared memory node
+class SmemNode final {
+public:
+ explicit SmemNode(Node address) : address{std::move(address)} {}
+
+ const Node& GetAddress() const {
+ return address;
+ }
+
+private:
+ Node address;
+};
+
/// Global memory node
class GmemNode final {
public: