node.h 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. // Copyright 2019 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <array>
  6. #include <cstddef>
  7. #include <memory>
  8. #include <optional>
  9. #include <string>
  10. #include <tuple>
  11. #include <utility>
  12. #include <variant>
  13. #include <vector>
  14. #include "common/common_types.h"
  15. #include "video_core/engines/shader_bytecode.h"
  16. namespace VideoCommon::Shader {
  17. enum class OperationCode {
  18. Assign, /// (float& dest, float src) -> void
  19. Select, /// (MetaArithmetic, bool pred, float a, float b) -> float
  20. FAdd, /// (MetaArithmetic, float a, float b) -> float
  21. FMul, /// (MetaArithmetic, float a, float b) -> float
  22. FDiv, /// (MetaArithmetic, float a, float b) -> float
  23. FFma, /// (MetaArithmetic, float a, float b, float c) -> float
  24. FNegate, /// (MetaArithmetic, float a) -> float
  25. FAbsolute, /// (MetaArithmetic, float a) -> float
  26. FClamp, /// (MetaArithmetic, float value, float min, float max) -> float
  27. FCastHalf0, /// (MetaArithmetic, f16vec2 a) -> float
  28. FCastHalf1, /// (MetaArithmetic, f16vec2 a) -> float
  29. FMin, /// (MetaArithmetic, float a, float b) -> float
  30. FMax, /// (MetaArithmetic, float a, float b) -> float
  31. FCos, /// (MetaArithmetic, float a) -> float
  32. FSin, /// (MetaArithmetic, float a) -> float
  33. FExp2, /// (MetaArithmetic, float a) -> float
  34. FLog2, /// (MetaArithmetic, float a) -> float
  35. FInverseSqrt, /// (MetaArithmetic, float a) -> float
  36. FSqrt, /// (MetaArithmetic, float a) -> float
  37. FRoundEven, /// (MetaArithmetic, float a) -> float
  38. FFloor, /// (MetaArithmetic, float a) -> float
  39. FCeil, /// (MetaArithmetic, float a) -> float
  40. FTrunc, /// (MetaArithmetic, float a) -> float
  41. FCastInteger, /// (MetaArithmetic, int a) -> float
  42. FCastUInteger, /// (MetaArithmetic, uint a) -> float
  43. FSwizzleAdd, /// (float a, float b, uint mask) -> float
  44. IAdd, /// (MetaArithmetic, int a, int b) -> int
  45. IMul, /// (MetaArithmetic, int a, int b) -> int
  46. IDiv, /// (MetaArithmetic, int a, int b) -> int
  47. INegate, /// (MetaArithmetic, int a) -> int
  48. IAbsolute, /// (MetaArithmetic, int a) -> int
  49. IMin, /// (MetaArithmetic, int a, int b) -> int
  50. IMax, /// (MetaArithmetic, int a, int b) -> int
  51. ICastFloat, /// (MetaArithmetic, float a) -> int
  52. ICastUnsigned, /// (MetaArithmetic, uint a) -> int
  53. ILogicalShiftLeft, /// (MetaArithmetic, int a, uint b) -> int
  54. ILogicalShiftRight, /// (MetaArithmetic, int a, uint b) -> int
  55. IArithmeticShiftRight, /// (MetaArithmetic, int a, uint b) -> int
  56. IBitwiseAnd, /// (MetaArithmetic, int a, int b) -> int
  57. IBitwiseOr, /// (MetaArithmetic, int a, int b) -> int
  58. IBitwiseXor, /// (MetaArithmetic, int a, int b) -> int
  59. IBitwiseNot, /// (MetaArithmetic, int a) -> int
  60. IBitfieldInsert, /// (MetaArithmetic, int base, int insert, int offset, int bits) -> int
  61. IBitfieldExtract, /// (MetaArithmetic, int value, int offset, int offset) -> int
  62. IBitCount, /// (MetaArithmetic, int) -> int
  63. IBitMSB, /// (MetaArithmetic, int) -> int
  64. UAdd, /// (MetaArithmetic, uint a, uint b) -> uint
  65. UMul, /// (MetaArithmetic, uint a, uint b) -> uint
  66. UDiv, /// (MetaArithmetic, uint a, uint b) -> uint
  67. UMin, /// (MetaArithmetic, uint a, uint b) -> uint
  68. UMax, /// (MetaArithmetic, uint a, uint b) -> uint
  69. UCastFloat, /// (MetaArithmetic, float a) -> uint
  70. UCastSigned, /// (MetaArithmetic, int a) -> uint
  71. ULogicalShiftLeft, /// (MetaArithmetic, uint a, uint b) -> uint
  72. ULogicalShiftRight, /// (MetaArithmetic, uint a, uint b) -> uint
  73. UArithmeticShiftRight, /// (MetaArithmetic, uint a, uint b) -> uint
  74. UBitwiseAnd, /// (MetaArithmetic, uint a, uint b) -> uint
  75. UBitwiseOr, /// (MetaArithmetic, uint a, uint b) -> uint
  76. UBitwiseXor, /// (MetaArithmetic, uint a, uint b) -> uint
  77. UBitwiseNot, /// (MetaArithmetic, uint a) -> uint
  78. UBitfieldInsert, /// (MetaArithmetic, uint base, uint insert, int offset, int bits) -> uint
  79. UBitfieldExtract, /// (MetaArithmetic, uint value, int offset, int offset) -> uint
  80. UBitCount, /// (MetaArithmetic, uint) -> uint
  81. UBitMSB, /// (MetaArithmetic, uint) -> uint
  82. HAdd, /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2
  83. HMul, /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2
  84. HFma, /// (MetaArithmetic, f16vec2 a, f16vec2 b, f16vec2 c) -> f16vec2
  85. HAbsolute, /// (f16vec2 a) -> f16vec2
  86. HNegate, /// (f16vec2 a, bool first, bool second) -> f16vec2
  87. HClamp, /// (f16vec2 src, float min, float max) -> f16vec2
  88. HCastFloat, /// (MetaArithmetic, float a) -> f16vec2
  89. HUnpack, /// (Tegra::Shader::HalfType, T value) -> f16vec2
  90. HMergeF32, /// (f16vec2 src) -> float
  91. HMergeH0, /// (f16vec2 dest, f16vec2 src) -> f16vec2
  92. HMergeH1, /// (f16vec2 dest, f16vec2 src) -> f16vec2
  93. HPack2, /// (float a, float b) -> f16vec2
  94. LogicalAssign, /// (bool& dst, bool src) -> void
  95. LogicalAnd, /// (bool a, bool b) -> bool
  96. LogicalOr, /// (bool a, bool b) -> bool
  97. LogicalXor, /// (bool a, bool b) -> bool
  98. LogicalNegate, /// (bool a) -> bool
  99. LogicalPick2, /// (bool2 pair, uint index) -> bool
  100. LogicalAnd2, /// (bool2 a) -> bool
  101. LogicalFLessThan, /// (float a, float b) -> bool
  102. LogicalFEqual, /// (float a, float b) -> bool
  103. LogicalFLessEqual, /// (float a, float b) -> bool
  104. LogicalFGreaterThan, /// (float a, float b) -> bool
  105. LogicalFNotEqual, /// (float a, float b) -> bool
  106. LogicalFGreaterEqual, /// (float a, float b) -> bool
  107. LogicalFIsNan, /// (float a) -> bool
  108. LogicalILessThan, /// (int a, int b) -> bool
  109. LogicalIEqual, /// (int a, int b) -> bool
  110. LogicalILessEqual, /// (int a, int b) -> bool
  111. LogicalIGreaterThan, /// (int a, int b) -> bool
  112. LogicalINotEqual, /// (int a, int b) -> bool
  113. LogicalIGreaterEqual, /// (int a, int b) -> bool
  114. LogicalULessThan, /// (uint a, uint b) -> bool
  115. LogicalUEqual, /// (uint a, uint b) -> bool
  116. LogicalULessEqual, /// (uint a, uint b) -> bool
  117. LogicalUGreaterThan, /// (uint a, uint b) -> bool
  118. LogicalUNotEqual, /// (uint a, uint b) -> bool
  119. LogicalUGreaterEqual, /// (uint a, uint b) -> bool
  120. Logical2HLessThan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  121. Logical2HEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  122. Logical2HLessEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  123. Logical2HGreaterThan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  124. Logical2HNotEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  125. Logical2HGreaterEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  126. Logical2HLessThanWithNan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  127. Logical2HEqualWithNan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  128. Logical2HLessEqualWithNan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  129. Logical2HGreaterThanWithNan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  130. Logical2HNotEqualWithNan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  131. Logical2HGreaterEqualWithNan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  132. Texture, /// (MetaTexture, float[N] coords) -> float4
  133. TextureLod, /// (MetaTexture, float[N] coords) -> float4
  134. TextureGather, /// (MetaTexture, float[N] coords) -> float4
  135. TextureQueryDimensions, /// (MetaTexture, float a) -> float4
  136. TextureQueryLod, /// (MetaTexture, float[N] coords) -> float4
  137. TexelFetch, /// (MetaTexture, int[N], int) -> float4
  138. TextureGradient, /// (MetaTexture, float[N] coords, float[N*2] derivates) -> float4
  139. ImageLoad, /// (MetaImage, int[N] coords) -> void
  140. ImageStore, /// (MetaImage, int[N] coords) -> void
  141. AtomicImageAdd, /// (MetaImage, int[N] coords) -> void
  142. AtomicImageAnd, /// (MetaImage, int[N] coords) -> void
  143. AtomicImageOr, /// (MetaImage, int[N] coords) -> void
  144. AtomicImageXor, /// (MetaImage, int[N] coords) -> void
  145. AtomicImageExchange, /// (MetaImage, int[N] coords) -> void
  146. AtomicUExchange, /// (memory, uint) -> uint
  147. AtomicUAdd, /// (memory, uint) -> uint
  148. AtomicUMin, /// (memory, uint) -> uint
  149. AtomicUMax, /// (memory, uint) -> uint
  150. AtomicUAnd, /// (memory, uint) -> uint
  151. AtomicUOr, /// (memory, uint) -> uint
  152. AtomicUXor, /// (memory, uint) -> uint
  153. AtomicIExchange, /// (memory, int) -> int
  154. AtomicIAdd, /// (memory, int) -> int
  155. AtomicIMin, /// (memory, int) -> int
  156. AtomicIMax, /// (memory, int) -> int
  157. AtomicIAnd, /// (memory, int) -> int
  158. AtomicIOr, /// (memory, int) -> int
  159. AtomicIXor, /// (memory, int) -> int
  160. ReduceUAdd, /// (memory, uint) -> void
  161. ReduceUMin, /// (memory, uint) -> void
  162. ReduceUMax, /// (memory, uint) -> void
  163. ReduceUAnd, /// (memory, uint) -> void
  164. ReduceUOr, /// (memory, uint) -> void
  165. ReduceUXor, /// (memory, uint) -> void
  166. ReduceIAdd, /// (memory, int) -> void
  167. ReduceIMin, /// (memory, int) -> void
  168. ReduceIMax, /// (memory, int) -> void
  169. ReduceIAnd, /// (memory, int) -> void
  170. ReduceIOr, /// (memory, int) -> void
  171. ReduceIXor, /// (memory, int) -> void
  172. Branch, /// (uint branch_target) -> void
  173. BranchIndirect, /// (uint branch_target) -> void
  174. PushFlowStack, /// (uint branch_target) -> void
  175. PopFlowStack, /// () -> void
  176. Exit, /// () -> void
  177. Discard, /// () -> void
  178. EmitVertex, /// () -> void
  179. EndPrimitive, /// () -> void
  180. InvocationId, /// () -> int
  181. YNegate, /// () -> float
  182. LocalInvocationIdX, /// () -> uint
  183. LocalInvocationIdY, /// () -> uint
  184. LocalInvocationIdZ, /// () -> uint
  185. WorkGroupIdX, /// () -> uint
  186. WorkGroupIdY, /// () -> uint
  187. WorkGroupIdZ, /// () -> uint
  188. BallotThread, /// (bool) -> uint
  189. VoteAll, /// (bool) -> bool
  190. VoteAny, /// (bool) -> bool
  191. VoteEqual, /// (bool) -> bool
  192. ThreadId, /// () -> uint
  193. ShuffleIndexed, /// (uint value, uint index) -> uint
  194. MemoryBarrierGL, /// () -> void
  195. Amount,
  196. };
  197. enum class InternalFlag {
  198. Zero = 0,
  199. Sign = 1,
  200. Carry = 2,
  201. Overflow = 3,
  202. Amount = 4,
  203. };
  204. enum class MetaStackClass {
  205. Ssy,
  206. Pbk,
  207. };
  208. class OperationNode;
  209. class ConditionalNode;
  210. class GprNode;
  211. class CustomVarNode;
  212. class ImmediateNode;
  213. class InternalFlagNode;
  214. class PredicateNode;
  215. class AbufNode;
  216. class CbufNode;
  217. class LmemNode;
  218. class PatchNode;
  219. class SmemNode;
  220. class GmemNode;
  221. class CommentNode;
  222. using NodeData = std::variant<OperationNode, ConditionalNode, GprNode, CustomVarNode, ImmediateNode,
  223. InternalFlagNode, PredicateNode, AbufNode, PatchNode, CbufNode,
  224. LmemNode, SmemNode, GmemNode, CommentNode>;
  225. using Node = std::shared_ptr<NodeData>;
  226. using Node4 = std::array<Node, 4>;
  227. using NodeBlock = std::vector<Node>;
  228. class BindlessSamplerNode;
  229. class ArraySamplerNode;
  230. using TrackSamplerData = std::variant<BindlessSamplerNode, ArraySamplerNode>;
  231. using TrackSampler = std::shared_ptr<TrackSamplerData>;
  232. class Sampler {
  233. public:
  234. /// This constructor is for bound samplers
  235. constexpr explicit Sampler(u32 index, u32 offset, Tegra::Shader::TextureType type,
  236. bool is_array, bool is_shadow, bool is_buffer, bool is_indexed)
  237. : index{index}, offset{offset}, type{type}, is_array{is_array}, is_shadow{is_shadow},
  238. is_buffer{is_buffer}, is_indexed{is_indexed} {}
  239. /// This constructor is for bindless samplers
  240. constexpr explicit Sampler(u32 index, u32 offset, u32 buffer, Tegra::Shader::TextureType type,
  241. bool is_array, bool is_shadow, bool is_buffer, bool is_indexed)
  242. : index{index}, offset{offset}, buffer{buffer}, type{type}, is_array{is_array},
  243. is_shadow{is_shadow}, is_buffer{is_buffer}, is_bindless{true}, is_indexed{is_indexed} {}
  244. constexpr u32 GetIndex() const {
  245. return index;
  246. }
  247. constexpr u32 GetOffset() const {
  248. return offset;
  249. }
  250. constexpr u32 GetBuffer() const {
  251. return buffer;
  252. }
  253. constexpr Tegra::Shader::TextureType GetType() const {
  254. return type;
  255. }
  256. constexpr bool IsArray() const {
  257. return is_array;
  258. }
  259. constexpr bool IsShadow() const {
  260. return is_shadow;
  261. }
  262. constexpr bool IsBuffer() const {
  263. return is_buffer;
  264. }
  265. constexpr bool IsBindless() const {
  266. return is_bindless;
  267. }
  268. constexpr bool IsIndexed() const {
  269. return is_indexed;
  270. }
  271. constexpr u32 Size() const {
  272. return size;
  273. }
  274. constexpr void SetSize(u32 new_size) {
  275. size = new_size;
  276. }
  277. private:
  278. u32 index{}; ///< Emulated index given for the this sampler.
  279. u32 offset{}; ///< Offset in the const buffer from where the sampler is being read.
  280. u32 buffer{}; ///< Buffer where the bindless sampler is being read (unused on bound samplers).
  281. u32 size{1}; ///< Size of the sampler.
  282. Tegra::Shader::TextureType type{}; ///< The type used to sample this texture (Texture2D, etc)
  283. bool is_array{}; ///< Whether the texture is being sampled as an array texture or not.
  284. bool is_shadow{}; ///< Whether the texture is being sampled as a depth texture or not.
  285. bool is_buffer{}; ///< Whether the texture is a texture buffer without sampler.
  286. bool is_bindless{}; ///< Whether this sampler belongs to a bindless texture or not.
  287. bool is_indexed{}; ///< Whether this sampler is an indexed array of textures.
  288. };
  289. /// Represents a tracked bindless sampler into a direct const buffer
  290. class ArraySamplerNode final {
  291. public:
  292. explicit ArraySamplerNode(u32 index, u32 base_offset, u32 bindless_var)
  293. : index{index}, base_offset{base_offset}, bindless_var{bindless_var} {}
  294. constexpr u32 GetIndex() const {
  295. return index;
  296. }
  297. constexpr u32 GetBaseOffset() const {
  298. return base_offset;
  299. }
  300. constexpr u32 GetIndexVar() const {
  301. return bindless_var;
  302. }
  303. private:
  304. u32 index;
  305. u32 base_offset;
  306. u32 bindless_var;
  307. };
  308. /// Represents a tracked bindless sampler into a direct const buffer
  309. class BindlessSamplerNode final {
  310. public:
  311. explicit BindlessSamplerNode(u32 index, u32 offset) : index{index}, offset{offset} {}
  312. constexpr u32 GetIndex() const {
  313. return index;
  314. }
  315. constexpr u32 GetOffset() const {
  316. return offset;
  317. }
  318. private:
  319. u32 index;
  320. u32 offset;
  321. };
  322. class Image final {
  323. public:
  324. /// This constructor is for bound images
  325. constexpr explicit Image(u32 index, u32 offset, Tegra::Shader::ImageType type)
  326. : index{index}, offset{offset}, type{type} {}
  327. /// This constructor is for bindless samplers
  328. constexpr explicit Image(u32 index, u32 offset, u32 buffer, Tegra::Shader::ImageType type)
  329. : index{index}, offset{offset}, buffer{buffer}, type{type}, is_bindless{true} {}
  330. void MarkWrite() {
  331. is_written = true;
  332. }
  333. void MarkRead() {
  334. is_read = true;
  335. }
  336. void MarkAtomic() {
  337. MarkWrite();
  338. MarkRead();
  339. is_atomic = true;
  340. }
  341. constexpr u32 GetIndex() const {
  342. return index;
  343. }
  344. constexpr u32 GetOffset() const {
  345. return offset;
  346. }
  347. constexpr u32 GetBuffer() const {
  348. return buffer;
  349. }
  350. constexpr Tegra::Shader::ImageType GetType() const {
  351. return type;
  352. }
  353. constexpr bool IsBindless() const {
  354. return is_bindless;
  355. }
  356. constexpr bool IsWritten() const {
  357. return is_written;
  358. }
  359. constexpr bool IsRead() const {
  360. return is_read;
  361. }
  362. constexpr bool IsAtomic() const {
  363. return is_atomic;
  364. }
  365. private:
  366. u32 index{};
  367. u32 offset{};
  368. u32 buffer{};
  369. Tegra::Shader::ImageType type{};
  370. bool is_bindless{};
  371. bool is_written{};
  372. bool is_read{};
  373. bool is_atomic{};
  374. };
  375. struct GlobalMemoryBase {
  376. u32 cbuf_index{};
  377. u32 cbuf_offset{};
  378. bool operator<(const GlobalMemoryBase& rhs) const {
  379. return std::tie(cbuf_index, cbuf_offset) < std::tie(rhs.cbuf_index, rhs.cbuf_offset);
  380. }
  381. };
  382. /// Parameters describing an arithmetic operation
  383. struct MetaArithmetic {
  384. bool precise{}; ///< Whether the operation can be constraint or not
  385. };
  386. /// Parameters describing a texture sampler
  387. struct MetaTexture {
  388. const Sampler& sampler;
  389. Node array;
  390. Node depth_compare;
  391. std::vector<Node> aoffi;
  392. std::vector<Node> ptp;
  393. std::vector<Node> derivates;
  394. Node bias;
  395. Node lod;
  396. Node component;
  397. u32 element{};
  398. Node index;
  399. };
  400. struct MetaImage {
  401. const Image& image;
  402. std::vector<Node> values;
  403. u32 element{};
  404. };
  405. /// Parameters that modify an operation but are not part of any particular operand
  406. using Meta =
  407. std::variant<MetaArithmetic, MetaTexture, MetaImage, MetaStackClass, Tegra::Shader::HalfType>;
  408. class AmendNode {
  409. public:
  410. std::optional<std::size_t> GetAmendIndex() const {
  411. if (amend_index == amend_null_index) {
  412. return std::nullopt;
  413. }
  414. return {amend_index};
  415. }
  416. void SetAmendIndex(std::size_t index) {
  417. amend_index = index;
  418. }
  419. void ClearAmend() {
  420. amend_index = amend_null_index;
  421. }
  422. private:
  423. static constexpr std::size_t amend_null_index = 0xFFFFFFFFFFFFFFFFULL;
  424. std::size_t amend_index{amend_null_index};
  425. };
  426. /// Holds any kind of operation that can be done in the IR
  427. class OperationNode final : public AmendNode {
  428. public:
  429. explicit OperationNode(OperationCode code) : OperationNode(code, Meta{}) {}
  430. explicit OperationNode(OperationCode code, Meta meta)
  431. : OperationNode(code, std::move(meta), std::vector<Node>{}) {}
  432. explicit OperationNode(OperationCode code, std::vector<Node> operands)
  433. : OperationNode(code, Meta{}, std::move(operands)) {}
  434. explicit OperationNode(OperationCode code, Meta meta, std::vector<Node> operands)
  435. : code{code}, meta{std::move(meta)}, operands{std::move(operands)} {}
  436. template <typename... Args>
  437. explicit OperationNode(OperationCode code, Meta meta, Args&&... operands)
  438. : code{code}, meta{std::move(meta)}, operands{operands...} {}
  439. OperationCode GetCode() const {
  440. return code;
  441. }
  442. const Meta& GetMeta() const {
  443. return meta;
  444. }
  445. std::size_t GetOperandsCount() const {
  446. return operands.size();
  447. }
  448. const Node& operator[](std::size_t operand_index) const {
  449. return operands.at(operand_index);
  450. }
  451. private:
  452. OperationCode code{};
  453. Meta meta{};
  454. std::vector<Node> operands;
  455. };
  456. /// Encloses inside any kind of node that returns a boolean conditionally-executed code
  457. class ConditionalNode final : public AmendNode {
  458. public:
  459. explicit ConditionalNode(Node condition, std::vector<Node>&& code)
  460. : condition{std::move(condition)}, code{std::move(code)} {}
  461. const Node& GetCondition() const {
  462. return condition;
  463. }
  464. const std::vector<Node>& GetCode() const {
  465. return code;
  466. }
  467. private:
  468. Node condition; ///< Condition to be satisfied
  469. std::vector<Node> code; ///< Code to execute
  470. };
  471. /// A general purpose register
  472. class GprNode final {
  473. public:
  474. explicit constexpr GprNode(Tegra::Shader::Register index) : index{index} {}
  475. u32 GetIndex() const {
  476. return static_cast<u32>(index);
  477. }
  478. private:
  479. Tegra::Shader::Register index{};
  480. };
  481. /// A custom variable
  482. class CustomVarNode final {
  483. public:
  484. explicit constexpr CustomVarNode(u32 index) : index{index} {}
  485. constexpr u32 GetIndex() const {
  486. return index;
  487. }
  488. private:
  489. u32 index{};
  490. };
  491. /// A 32-bits value that represents an immediate value
  492. class ImmediateNode final {
  493. public:
  494. explicit constexpr ImmediateNode(u32 value) : value{value} {}
  495. u32 GetValue() const {
  496. return value;
  497. }
  498. private:
  499. u32 value{};
  500. };
  501. /// One of Maxwell's internal flags
  502. class InternalFlagNode final {
  503. public:
  504. explicit constexpr InternalFlagNode(InternalFlag flag) : flag{flag} {}
  505. InternalFlag GetFlag() const {
  506. return flag;
  507. }
  508. private:
  509. InternalFlag flag{};
  510. };
  511. /// A predicate register, it can be negated without additional nodes
  512. class PredicateNode final {
  513. public:
  514. explicit constexpr PredicateNode(Tegra::Shader::Pred index, bool negated)
  515. : index{index}, negated{negated} {}
  516. Tegra::Shader::Pred GetIndex() const {
  517. return index;
  518. }
  519. bool IsNegated() const {
  520. return negated;
  521. }
  522. private:
  523. Tegra::Shader::Pred index{};
  524. bool negated{};
  525. };
  526. /// Attribute buffer memory (known as attributes or varyings in GLSL terms)
  527. class AbufNode final {
  528. public:
  529. // Initialize for standard attributes (index is explicit).
  530. explicit AbufNode(Tegra::Shader::Attribute::Index index, u32 element, Node buffer = {})
  531. : buffer{std::move(buffer)}, index{index}, element{element} {}
  532. // Initialize for physical attributes (index is a variable value).
  533. explicit AbufNode(Node physical_address, Node buffer = {})
  534. : physical_address{std::move(physical_address)}, buffer{std::move(buffer)} {}
  535. Tegra::Shader::Attribute::Index GetIndex() const {
  536. return index;
  537. }
  538. u32 GetElement() const {
  539. return element;
  540. }
  541. const Node& GetBuffer() const {
  542. return buffer;
  543. }
  544. bool IsPhysicalBuffer() const {
  545. return static_cast<bool>(physical_address);
  546. }
  547. const Node& GetPhysicalAddress() const {
  548. return physical_address;
  549. }
  550. private:
  551. Node physical_address;
  552. Node buffer;
  553. Tegra::Shader::Attribute::Index index{};
  554. u32 element{};
  555. };
  556. /// Patch memory (used to communicate tessellation stages).
  557. class PatchNode final {
  558. public:
  559. explicit PatchNode(u32 offset) : offset{offset} {}
  560. u32 GetOffset() const {
  561. return offset;
  562. }
  563. private:
  564. u32 offset{};
  565. };
  566. /// Constant buffer node, usually mapped to uniform buffers in GLSL
  567. class CbufNode final {
  568. public:
  569. explicit CbufNode(u32 index, Node offset) : index{index}, offset{std::move(offset)} {}
  570. u32 GetIndex() const {
  571. return index;
  572. }
  573. const Node& GetOffset() const {
  574. return offset;
  575. }
  576. private:
  577. u32 index{};
  578. Node offset;
  579. };
  580. /// Local memory node
  581. class LmemNode final {
  582. public:
  583. explicit LmemNode(Node address) : address{std::move(address)} {}
  584. const Node& GetAddress() const {
  585. return address;
  586. }
  587. private:
  588. Node address;
  589. };
  590. /// Shared memory node
  591. class SmemNode final {
  592. public:
  593. explicit SmemNode(Node address) : address{std::move(address)} {}
  594. const Node& GetAddress() const {
  595. return address;
  596. }
  597. private:
  598. Node address;
  599. };
  600. /// Global memory node
  601. class GmemNode final {
  602. public:
  603. explicit GmemNode(Node real_address, Node base_address, const GlobalMemoryBase& descriptor)
  604. : real_address{std::move(real_address)}, base_address{std::move(base_address)},
  605. descriptor{descriptor} {}
  606. const Node& GetRealAddress() const {
  607. return real_address;
  608. }
  609. const Node& GetBaseAddress() const {
  610. return base_address;
  611. }
  612. const GlobalMemoryBase& GetDescriptor() const {
  613. return descriptor;
  614. }
  615. private:
  616. Node real_address;
  617. Node base_address;
  618. GlobalMemoryBase descriptor;
  619. };
  620. /// Commentary, can be dropped
  621. class CommentNode final {
  622. public:
  623. explicit CommentNode(std::string text) : text{std::move(text)} {}
  624. const std::string& GetText() const {
  625. return text;
  626. }
  627. private:
  628. std::string text;
  629. };
  630. } // namespace VideoCommon::Shader