node.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  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. IAdd, /// (MetaArithmetic, int a, int b) -> int
  44. IMul, /// (MetaArithmetic, int a, int b) -> int
  45. IDiv, /// (MetaArithmetic, int a, int b) -> int
  46. INegate, /// (MetaArithmetic, int a) -> int
  47. IAbsolute, /// (MetaArithmetic, int a) -> int
  48. IMin, /// (MetaArithmetic, int a, int b) -> int
  49. IMax, /// (MetaArithmetic, int a, int b) -> int
  50. ICastFloat, /// (MetaArithmetic, float a) -> int
  51. ICastUnsigned, /// (MetaArithmetic, uint a) -> int
  52. ILogicalShiftLeft, /// (MetaArithmetic, int a, uint b) -> int
  53. ILogicalShiftRight, /// (MetaArithmetic, int a, uint b) -> int
  54. IArithmeticShiftRight, /// (MetaArithmetic, int a, uint b) -> int
  55. IBitwiseAnd, /// (MetaArithmetic, int a, int b) -> int
  56. IBitwiseOr, /// (MetaArithmetic, int a, int b) -> int
  57. IBitwiseXor, /// (MetaArithmetic, int a, int b) -> int
  58. IBitwiseNot, /// (MetaArithmetic, int a) -> int
  59. IBitfieldInsert, /// (MetaArithmetic, int base, int insert, int offset, int bits) -> int
  60. IBitfieldExtract, /// (MetaArithmetic, int value, int offset, int offset) -> int
  61. IBitCount, /// (MetaArithmetic, int) -> int
  62. UAdd, /// (MetaArithmetic, uint a, uint b) -> uint
  63. UMul, /// (MetaArithmetic, uint a, uint b) -> uint
  64. UDiv, /// (MetaArithmetic, uint a, uint b) -> uint
  65. UMin, /// (MetaArithmetic, uint a, uint b) -> uint
  66. UMax, /// (MetaArithmetic, uint a, uint b) -> uint
  67. UCastFloat, /// (MetaArithmetic, float a) -> uint
  68. UCastSigned, /// (MetaArithmetic, int a) -> uint
  69. ULogicalShiftLeft, /// (MetaArithmetic, uint a, uint b) -> uint
  70. ULogicalShiftRight, /// (MetaArithmetic, uint a, uint b) -> uint
  71. UArithmeticShiftRight, /// (MetaArithmetic, uint a, uint b) -> uint
  72. UBitwiseAnd, /// (MetaArithmetic, uint a, uint b) -> uint
  73. UBitwiseOr, /// (MetaArithmetic, uint a, uint b) -> uint
  74. UBitwiseXor, /// (MetaArithmetic, uint a, uint b) -> uint
  75. UBitwiseNot, /// (MetaArithmetic, uint a) -> uint
  76. UBitfieldInsert, /// (MetaArithmetic, uint base, uint insert, int offset, int bits) -> uint
  77. UBitfieldExtract, /// (MetaArithmetic, uint value, int offset, int offset) -> uint
  78. UBitCount, /// (MetaArithmetic, uint) -> uint
  79. HAdd, /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2
  80. HMul, /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2
  81. HFma, /// (MetaArithmetic, f16vec2 a, f16vec2 b, f16vec2 c) -> f16vec2
  82. HAbsolute, /// (f16vec2 a) -> f16vec2
  83. HNegate, /// (f16vec2 a, bool first, bool second) -> f16vec2
  84. HClamp, /// (f16vec2 src, float min, float max) -> f16vec2
  85. HCastFloat, /// (MetaArithmetic, float a) -> f16vec2
  86. HUnpack, /// (Tegra::Shader::HalfType, T value) -> f16vec2
  87. HMergeF32, /// (f16vec2 src) -> float
  88. HMergeH0, /// (f16vec2 dest, f16vec2 src) -> f16vec2
  89. HMergeH1, /// (f16vec2 dest, f16vec2 src) -> f16vec2
  90. HPack2, /// (float a, float b) -> f16vec2
  91. LogicalAssign, /// (bool& dst, bool src) -> void
  92. LogicalAnd, /// (bool a, bool b) -> bool
  93. LogicalOr, /// (bool a, bool b) -> bool
  94. LogicalXor, /// (bool a, bool b) -> bool
  95. LogicalNegate, /// (bool a) -> bool
  96. LogicalPick2, /// (bool2 pair, uint index) -> bool
  97. LogicalAnd2, /// (bool2 a) -> bool
  98. LogicalFLessThan, /// (float a, float b) -> bool
  99. LogicalFEqual, /// (float a, float b) -> bool
  100. LogicalFLessEqual, /// (float a, float b) -> bool
  101. LogicalFGreaterThan, /// (float a, float b) -> bool
  102. LogicalFNotEqual, /// (float a, float b) -> bool
  103. LogicalFGreaterEqual, /// (float a, float b) -> bool
  104. LogicalFIsNan, /// (float a) -> bool
  105. LogicalILessThan, /// (int a, int b) -> bool
  106. LogicalIEqual, /// (int a, int b) -> bool
  107. LogicalILessEqual, /// (int a, int b) -> bool
  108. LogicalIGreaterThan, /// (int a, int b) -> bool
  109. LogicalINotEqual, /// (int a, int b) -> bool
  110. LogicalIGreaterEqual, /// (int a, int b) -> bool
  111. LogicalULessThan, /// (uint a, uint b) -> bool
  112. LogicalUEqual, /// (uint a, uint b) -> bool
  113. LogicalULessEqual, /// (uint a, uint b) -> bool
  114. LogicalUGreaterThan, /// (uint a, uint b) -> bool
  115. LogicalUNotEqual, /// (uint a, uint b) -> bool
  116. LogicalUGreaterEqual, /// (uint a, uint b) -> bool
  117. Logical2HLessThan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  118. Logical2HEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  119. Logical2HLessEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  120. Logical2HGreaterThan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  121. Logical2HNotEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  122. Logical2HGreaterEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  123. Logical2HLessThanWithNan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  124. Logical2HEqualWithNan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  125. Logical2HLessEqualWithNan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  126. Logical2HGreaterThanWithNan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  127. Logical2HNotEqualWithNan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  128. Logical2HGreaterEqualWithNan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
  129. Texture, /// (MetaTexture, float[N] coords) -> float4
  130. TextureLod, /// (MetaTexture, float[N] coords) -> float4
  131. TextureGather, /// (MetaTexture, float[N] coords) -> float4
  132. TextureQueryDimensions, /// (MetaTexture, float a) -> float4
  133. TextureQueryLod, /// (MetaTexture, float[N] coords) -> float4
  134. TexelFetch, /// (MetaTexture, int[N], int) -> float4
  135. ImageLoad, /// (MetaImage, int[N] coords) -> void
  136. ImageStore, /// (MetaImage, int[N] coords) -> void
  137. AtomicImageAdd, /// (MetaImage, int[N] coords) -> void
  138. AtomicImageAnd, /// (MetaImage, int[N] coords) -> void
  139. AtomicImageOr, /// (MetaImage, int[N] coords) -> void
  140. AtomicImageXor, /// (MetaImage, int[N] coords) -> void
  141. AtomicImageExchange, /// (MetaImage, int[N] coords) -> void
  142. Branch, /// (uint branch_target) -> void
  143. BranchIndirect, /// (uint branch_target) -> void
  144. PushFlowStack, /// (uint branch_target) -> void
  145. PopFlowStack, /// () -> void
  146. Exit, /// () -> void
  147. Discard, /// () -> void
  148. EmitVertex, /// () -> void
  149. EndPrimitive, /// () -> void
  150. YNegate, /// () -> float
  151. LocalInvocationIdX, /// () -> uint
  152. LocalInvocationIdY, /// () -> uint
  153. LocalInvocationIdZ, /// () -> uint
  154. WorkGroupIdX, /// () -> uint
  155. WorkGroupIdY, /// () -> uint
  156. WorkGroupIdZ, /// () -> uint
  157. BallotThread, /// (bool) -> uint
  158. VoteAll, /// (bool) -> bool
  159. VoteAny, /// (bool) -> bool
  160. VoteEqual, /// (bool) -> bool
  161. ShuffleIndexed, /// (uint value, uint index, uint width) -> uint
  162. ShuffleUp, /// (uint value, uint index, uint width) -> uint
  163. ShuffleDown, /// (uint value, uint index, uint width) -> uint
  164. ShuffleButterfly, /// (uint value, uint index, uint width) -> uint
  165. InRangeShuffleIndexed, /// (uint index, uint width) -> bool
  166. InRangeShuffleUp, /// (uint index, uint width) -> bool
  167. InRangeShuffleDown, /// (uint index, uint width) -> bool
  168. InRangeShuffleButterfly, /// (uint index, uint width) -> bool
  169. Amount,
  170. };
  171. enum class InternalFlag {
  172. Zero = 0,
  173. Sign = 1,
  174. Carry = 2,
  175. Overflow = 3,
  176. Amount = 4,
  177. };
  178. enum class MetaStackClass {
  179. Ssy,
  180. Pbk,
  181. };
  182. class OperationNode;
  183. class ConditionalNode;
  184. class GprNode;
  185. class ImmediateNode;
  186. class InternalFlagNode;
  187. class PredicateNode;
  188. class AbufNode;
  189. class CbufNode;
  190. class LmemNode;
  191. class SmemNode;
  192. class GmemNode;
  193. class CommentNode;
  194. using NodeData =
  195. std::variant<OperationNode, ConditionalNode, GprNode, ImmediateNode, InternalFlagNode,
  196. PredicateNode, AbufNode, CbufNode, LmemNode, SmemNode, GmemNode, CommentNode>;
  197. using Node = std::shared_ptr<NodeData>;
  198. using Node4 = std::array<Node, 4>;
  199. using NodeBlock = std::vector<Node>;
  200. class Sampler {
  201. public:
  202. /// This constructor is for bound samplers
  203. constexpr explicit Sampler(u32 index, u32 offset, Tegra::Shader::TextureType type,
  204. bool is_array, bool is_shadow)
  205. : index{index}, offset{offset}, type{type}, is_array{is_array}, is_shadow{is_shadow} {}
  206. /// This constructor is for bindless samplers
  207. constexpr explicit Sampler(u32 index, u32 offset, u32 buffer, Tegra::Shader::TextureType type,
  208. bool is_array, bool is_shadow)
  209. : index{index}, offset{offset}, buffer{buffer}, type{type}, is_array{is_array},
  210. is_shadow{is_shadow}, is_bindless{true} {}
  211. constexpr u32 GetIndex() const {
  212. return index;
  213. }
  214. constexpr u32 GetOffset() const {
  215. return offset;
  216. }
  217. constexpr u32 GetBuffer() const {
  218. return buffer;
  219. }
  220. constexpr Tegra::Shader::TextureType GetType() const {
  221. return type;
  222. }
  223. constexpr bool IsArray() const {
  224. return is_array;
  225. }
  226. constexpr bool IsShadow() const {
  227. return is_shadow;
  228. }
  229. constexpr bool IsBindless() const {
  230. return is_bindless;
  231. }
  232. private:
  233. u32 index{}; ///< Emulated index given for the this sampler.
  234. u32 offset{}; ///< Offset in the const buffer from where the sampler is being read.
  235. u32 buffer{}; ///< Buffer where the bindless sampler is being read (unused on bound samplers).
  236. Tegra::Shader::TextureType type{}; ///< The type used to sample this texture (Texture2D, etc)
  237. bool is_array{}; ///< Whether the texture is being sampled as an array texture or not.
  238. bool is_shadow{}; ///< Whether the texture is being sampled as a depth texture or not.
  239. bool is_bindless{}; ///< Whether this sampler belongs to a bindless texture or not.
  240. };
  241. class Image final {
  242. public:
  243. /// This constructor is for bound images
  244. constexpr explicit Image(u32 index, u32 offset, Tegra::Shader::ImageType type)
  245. : index{index}, offset{offset}, type{type} {}
  246. /// This constructor is for bindless samplers
  247. constexpr explicit Image(u32 index, u32 offset, u32 buffer, Tegra::Shader::ImageType type)
  248. : index{index}, offset{offset}, buffer{buffer}, type{type}, is_bindless{true} {}
  249. void MarkWrite() {
  250. is_written = true;
  251. }
  252. void MarkRead() {
  253. is_read = true;
  254. }
  255. void MarkAtomic() {
  256. MarkWrite();
  257. MarkRead();
  258. is_atomic = true;
  259. }
  260. constexpr u32 GetIndex() const {
  261. return index;
  262. }
  263. constexpr u32 GetOffset() const {
  264. return offset;
  265. }
  266. constexpr u32 GetBuffer() const {
  267. return buffer;
  268. }
  269. constexpr Tegra::Shader::ImageType GetType() const {
  270. return type;
  271. }
  272. constexpr bool IsBindless() const {
  273. return is_bindless;
  274. }
  275. constexpr bool IsWritten() const {
  276. return is_written;
  277. }
  278. constexpr bool IsRead() const {
  279. return is_read;
  280. }
  281. constexpr bool IsAtomic() const {
  282. return is_atomic;
  283. }
  284. private:
  285. u32 index{};
  286. u32 offset{};
  287. u32 buffer{};
  288. Tegra::Shader::ImageType type{};
  289. bool is_bindless{};
  290. bool is_written{};
  291. bool is_read{};
  292. bool is_atomic{};
  293. };
  294. struct GlobalMemoryBase {
  295. u32 cbuf_index{};
  296. u32 cbuf_offset{};
  297. bool operator<(const GlobalMemoryBase& rhs) const {
  298. return std::tie(cbuf_index, cbuf_offset) < std::tie(rhs.cbuf_index, rhs.cbuf_offset);
  299. }
  300. };
  301. /// Parameters describing an arithmetic operation
  302. struct MetaArithmetic {
  303. bool precise{}; ///< Whether the operation can be constraint or not
  304. };
  305. /// Parameters describing a texture sampler
  306. struct MetaTexture {
  307. const Sampler& sampler;
  308. Node array;
  309. Node depth_compare;
  310. std::vector<Node> aoffi;
  311. Node bias;
  312. Node lod;
  313. Node component{};
  314. u32 element{};
  315. };
  316. struct MetaImage {
  317. const Image& image;
  318. std::vector<Node> values;
  319. u32 element{};
  320. };
  321. /// Parameters that modify an operation but are not part of any particular operand
  322. using Meta =
  323. std::variant<MetaArithmetic, MetaTexture, MetaImage, MetaStackClass, Tegra::Shader::HalfType>;
  324. /// Holds any kind of operation that can be done in the IR
  325. class OperationNode final {
  326. public:
  327. explicit OperationNode(OperationCode code) : OperationNode(code, Meta{}) {}
  328. explicit OperationNode(OperationCode code, Meta meta)
  329. : OperationNode(code, std::move(meta), std::vector<Node>{}) {}
  330. explicit OperationNode(OperationCode code, std::vector<Node> operands)
  331. : OperationNode(code, Meta{}, std::move(operands)) {}
  332. explicit OperationNode(OperationCode code, Meta meta, std::vector<Node> operands)
  333. : code{code}, meta{std::move(meta)}, operands{std::move(operands)} {}
  334. template <typename... Args>
  335. explicit OperationNode(OperationCode code, Meta meta, Args&&... operands)
  336. : code{code}, meta{std::move(meta)}, operands{operands...} {}
  337. OperationCode GetCode() const {
  338. return code;
  339. }
  340. const Meta& GetMeta() const {
  341. return meta;
  342. }
  343. std::size_t GetOperandsCount() const {
  344. return operands.size();
  345. }
  346. const Node& operator[](std::size_t operand_index) const {
  347. return operands.at(operand_index);
  348. }
  349. private:
  350. OperationCode code{};
  351. Meta meta{};
  352. std::vector<Node> operands;
  353. };
  354. /// Encloses inside any kind of node that returns a boolean conditionally-executed code
  355. class ConditionalNode final {
  356. public:
  357. explicit ConditionalNode(Node condition, std::vector<Node>&& code)
  358. : condition{std::move(condition)}, code{std::move(code)} {}
  359. const Node& GetCondition() const {
  360. return condition;
  361. }
  362. const std::vector<Node>& GetCode() const {
  363. return code;
  364. }
  365. private:
  366. Node condition; ///< Condition to be satisfied
  367. std::vector<Node> code; ///< Code to execute
  368. };
  369. /// A general purpose register
  370. class GprNode final {
  371. public:
  372. explicit constexpr GprNode(Tegra::Shader::Register index) : index{index} {}
  373. u32 GetIndex() const {
  374. return static_cast<u32>(index);
  375. }
  376. private:
  377. Tegra::Shader::Register index{};
  378. };
  379. /// A 32-bits value that represents an immediate value
  380. class ImmediateNode final {
  381. public:
  382. explicit constexpr ImmediateNode(u32 value) : value{value} {}
  383. u32 GetValue() const {
  384. return value;
  385. }
  386. private:
  387. u32 value{};
  388. };
  389. /// One of Maxwell's internal flags
  390. class InternalFlagNode final {
  391. public:
  392. explicit constexpr InternalFlagNode(InternalFlag flag) : flag{flag} {}
  393. InternalFlag GetFlag() const {
  394. return flag;
  395. }
  396. private:
  397. InternalFlag flag{};
  398. };
  399. /// A predicate register, it can be negated without additional nodes
  400. class PredicateNode final {
  401. public:
  402. explicit constexpr PredicateNode(Tegra::Shader::Pred index, bool negated)
  403. : index{index}, negated{negated} {}
  404. Tegra::Shader::Pred GetIndex() const {
  405. return index;
  406. }
  407. bool IsNegated() const {
  408. return negated;
  409. }
  410. private:
  411. Tegra::Shader::Pred index{};
  412. bool negated{};
  413. };
  414. /// Attribute buffer memory (known as attributes or varyings in GLSL terms)
  415. class AbufNode final {
  416. public:
  417. // Initialize for standard attributes (index is explicit).
  418. explicit AbufNode(Tegra::Shader::Attribute::Index index, u32 element, Node buffer = {})
  419. : buffer{std::move(buffer)}, index{index}, element{element} {}
  420. // Initialize for physical attributes (index is a variable value).
  421. explicit AbufNode(Node physical_address, Node buffer = {})
  422. : physical_address{std::move(physical_address)}, buffer{std::move(buffer)} {}
  423. Tegra::Shader::Attribute::Index GetIndex() const {
  424. return index;
  425. }
  426. u32 GetElement() const {
  427. return element;
  428. }
  429. const Node& GetBuffer() const {
  430. return buffer;
  431. }
  432. bool IsPhysicalBuffer() const {
  433. return static_cast<bool>(physical_address);
  434. }
  435. const Node& GetPhysicalAddress() const {
  436. return physical_address;
  437. }
  438. private:
  439. Node physical_address;
  440. Node buffer;
  441. Tegra::Shader::Attribute::Index index{};
  442. u32 element{};
  443. };
  444. /// Constant buffer node, usually mapped to uniform buffers in GLSL
  445. class CbufNode final {
  446. public:
  447. explicit CbufNode(u32 index, Node offset) : index{index}, offset{std::move(offset)} {}
  448. u32 GetIndex() const {
  449. return index;
  450. }
  451. const Node& GetOffset() const {
  452. return offset;
  453. }
  454. private:
  455. u32 index{};
  456. Node offset;
  457. };
  458. /// Local memory node
  459. class LmemNode final {
  460. public:
  461. explicit LmemNode(Node address) : address{std::move(address)} {}
  462. const Node& GetAddress() const {
  463. return address;
  464. }
  465. private:
  466. Node address;
  467. };
  468. /// Shared memory node
  469. class SmemNode final {
  470. public:
  471. explicit SmemNode(Node address) : address{std::move(address)} {}
  472. const Node& GetAddress() const {
  473. return address;
  474. }
  475. private:
  476. Node address;
  477. };
  478. /// Global memory node
  479. class GmemNode final {
  480. public:
  481. explicit GmemNode(Node real_address, Node base_address, const GlobalMemoryBase& descriptor)
  482. : real_address{std::move(real_address)}, base_address{std::move(base_address)},
  483. descriptor{descriptor} {}
  484. const Node& GetRealAddress() const {
  485. return real_address;
  486. }
  487. const Node& GetBaseAddress() const {
  488. return base_address;
  489. }
  490. const GlobalMemoryBase& GetDescriptor() const {
  491. return descriptor;
  492. }
  493. private:
  494. Node real_address;
  495. Node base_address;
  496. GlobalMemoryBase descriptor;
  497. };
  498. /// Commentary, can be dropped
  499. class CommentNode final {
  500. public:
  501. explicit CommentNode(std::string text) : text{std::move(text)} {}
  502. const std::string& GetText() const {
  503. return text;
  504. }
  505. private:
  506. std::string text;
  507. };
  508. } // namespace VideoCommon::Shader