| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  | // Copyright 2018 yuzu Emulator Project
 | 
					
						
							|  |  |  | // Licensed under GPLv2 or any later version
 | 
					
						
							|  |  |  | // Refer to the license.txt file included.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-27 01:50:22 -03:00
										 |  |  | #include <array>
 | 
					
						
							| 
									
										
										
										
											2019-10-28 02:31:05 -03:00
										 |  |  | #include <list>
 | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  | #include <map>
 | 
					
						
							| 
									
										
										
										
											2019-03-29 18:36:07 -03:00
										 |  |  | #include <optional>
 | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  | #include <set>
 | 
					
						
							|  |  |  | #include <tuple>
 | 
					
						
							|  |  |  | #include <vector>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "common/common_types.h"
 | 
					
						
							|  |  |  | #include "video_core/engines/maxwell_3d.h"
 | 
					
						
							|  |  |  | #include "video_core/engines/shader_bytecode.h"
 | 
					
						
							|  |  |  | #include "video_core/engines/shader_header.h"
 | 
					
						
							| 
									
										
										
										
											2019-06-28 22:59:43 -04:00
										 |  |  | #include "video_core/shader/ast.h"
 | 
					
						
							| 
									
										
										
										
											2019-08-16 16:25:02 -04:00
										 |  |  | #include "video_core/shader/compiler_settings.h"
 | 
					
						
							| 
									
										
										
										
											2019-09-23 14:02:02 -04:00
										 |  |  | #include "video_core/shader/const_buffer_locker.h"
 | 
					
						
							| 
									
										
										
										
											2019-06-29 01:44:07 -04:00
										 |  |  | #include "video_core/shader/node.h"
 | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace VideoCommon::Shader { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-25 11:10:45 -04:00
										 |  |  | struct ShaderBlock; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  | using ProgramCode = std::vector<u64>; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | constexpr u32 MAX_PROGRAM_LENGTH = 0x1000; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ConstBuffer { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2019-01-15 01:07:57 -03:00
										 |  |  |     explicit ConstBuffer(u32 max_offset, bool is_indirect) | 
					
						
							|  |  |  |         : max_offset{max_offset}, is_indirect{is_indirect} {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ConstBuffer() = default; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  |     void MarkAsUsed(u64 offset) { | 
					
						
							|  |  |  |         max_offset = std::max(max_offset, static_cast<u32>(offset)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void MarkAsUsedIndirect() { | 
					
						
							|  |  |  |         is_indirect = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool IsIndirect() const { | 
					
						
							|  |  |  |         return is_indirect; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     u32 GetSize() const { | 
					
						
							| 
									
										
										
										
											2019-01-28 18:11:23 -03:00
										 |  |  |         return max_offset + sizeof(float); | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-15 01:07:57 -03:00
										 |  |  |     u32 GetMaxOffset() const { | 
					
						
							|  |  |  |         return max_offset; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  | private: | 
					
						
							|  |  |  |     u32 max_offset{}; | 
					
						
							|  |  |  |     bool is_indirect{}; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-07 00:05:41 -03:00
										 |  |  | struct GlobalMemoryUsage { | 
					
						
							|  |  |  |     bool is_read{}; | 
					
						
							|  |  |  |     bool is_written{}; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  | class ShaderIR final { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2019-09-24 23:34:18 -03:00
										 |  |  |     explicit ShaderIR(const ProgramCode& program_code, u32 main_offset, CompilerSettings settings, | 
					
						
							|  |  |  |                       ConstBufferLocker& locker); | 
					
						
							| 
									
										
										
										
											2019-05-19 04:01:59 -04:00
										 |  |  |     ~ShaderIR(); | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-30 02:09:40 -03:00
										 |  |  |     const std::map<u32, NodeBlock>& GetBasicBlocks() const { | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  |         return basic_blocks; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const std::set<u32>& GetRegisters() const { | 
					
						
							|  |  |  |         return used_registers; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const std::set<Tegra::Shader::Pred>& GetPredicates() const { | 
					
						
							|  |  |  |         return used_predicates; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-29 23:37:09 -03:00
										 |  |  |     const std::set<Tegra::Shader::Attribute::Index>& GetInputAttributes() const { | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  |         return used_input_attributes; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const std::set<Tegra::Shader::Attribute::Index>& GetOutputAttributes() const { | 
					
						
							|  |  |  |         return used_output_attributes; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const std::map<u32, ConstBuffer>& GetConstantBuffers() const { | 
					
						
							|  |  |  |         return used_cbufs; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-28 02:31:05 -03:00
										 |  |  |     const std::list<Sampler>& GetSamplers() const { | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  |         return used_samplers; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-28 02:31:05 -03:00
										 |  |  |     const std::list<Image>& GetImages() const { | 
					
						
							| 
									
										
										
										
											2019-04-27 02:07:18 -03:00
										 |  |  |         return used_images; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  |     const std::array<bool, Tegra::Engines::Maxwell3D::Regs::NumClipDistances>& GetClipDistances() | 
					
						
							|  |  |  |         const { | 
					
						
							|  |  |  |         return used_clip_distances; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-07 00:05:41 -03:00
										 |  |  |     const std::map<GlobalMemoryBase, GlobalMemoryUsage>& GetGlobalMemory() const { | 
					
						
							|  |  |  |         return used_global_memory; | 
					
						
							| 
									
										
										
										
											2018-12-29 02:44:54 -03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  |     std::size_t GetLength() const { | 
					
						
							|  |  |  |         return static_cast<std::size_t>(coverage_end * sizeof(u64)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-07 20:36:42 -03:00
										 |  |  |     bool UsesLayer() const { | 
					
						
							|  |  |  |         return uses_layer; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool UsesViewportIndex() const { | 
					
						
							|  |  |  |         return uses_viewport_index; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool UsesPointSize() const { | 
					
						
							|  |  |  |         return uses_point_size; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-15 14:25:07 -04:00
										 |  |  |     bool UsesInstanceId() const { | 
					
						
							|  |  |  |         return uses_instance_id; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool UsesVertexId() const { | 
					
						
							|  |  |  |         return uses_vertex_id; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-29 23:28:28 -03:00
										 |  |  |     bool HasPhysicalAttributes() const { | 
					
						
							| 
									
										
										
										
											2019-04-30 19:46:49 -03:00
										 |  |  |         return uses_physical_attributes; | 
					
						
							| 
									
										
										
										
											2019-04-29 23:28:28 -03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  |     const Tegra::Shader::Header& GetHeader() const { | 
					
						
							|  |  |  |         return header; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-16 16:25:02 -04:00
										 |  |  |     bool IsFlowStackDisabled() const { | 
					
						
							|  |  |  |         return disable_flow_stack; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-29 01:44:07 -04:00
										 |  |  |     bool IsDecompiled() const { | 
					
						
							|  |  |  |         return decompiled; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-25 15:32:00 -04:00
										 |  |  |     const ASTManager& GetASTManager() const { | 
					
						
							|  |  |  |         return program_manager; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-29 01:44:07 -04:00
										 |  |  |     ASTNode GetASTProgram() const { | 
					
						
							|  |  |  |         return program_manager.GetProgram(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     u32 GetASTNumVariables() const { | 
					
						
							|  |  |  |         return program_manager.GetVariables(); | 
					
						
							| 
									
										
										
										
											2019-06-25 13:03:51 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-05 14:13:14 -04:00
										 |  |  |     u32 ConvertAddressToNvidiaSpace(const u32 address) const { | 
					
						
							|  |  |  |         return (address - main_offset) * sizeof(Tegra::Shader::Instruction); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-29 01:44:07 -04:00
										 |  |  |     /// Returns a condition code evaluated from internal flags
 | 
					
						
							|  |  |  |     Node GetConditionCode(Tegra::Shader::ConditionCode cc) const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2019-06-29 01:44:07 -04:00
										 |  |  |     friend class ASTDecoder; | 
					
						
							| 
									
										
										
										
											2019-09-25 09:53:18 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     struct SamplerInfo { | 
					
						
							|  |  |  |         Tegra::Shader::TextureType type; | 
					
						
							|  |  |  |         bool is_array; | 
					
						
							|  |  |  |         bool is_shadow; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  |     void Decode(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-30 02:09:40 -03:00
										 |  |  |     NodeBlock DecodeRange(u32 begin, u32 end); | 
					
						
							| 
									
										
										
										
											2019-06-25 13:03:51 -04:00
										 |  |  |     void DecodeRangeInner(NodeBlock& bb, u32 begin, u32 end); | 
					
						
							| 
									
										
										
										
											2019-06-25 11:10:45 -04:00
										 |  |  |     void InsertControlFlow(NodeBlock& bb, const ShaderBlock& block); | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /**
 | 
					
						
							|  |  |  |      * Decodes a single instruction from Tegra to IR. | 
					
						
							|  |  |  |      * @param bb Basic block where the nodes will be written to. | 
					
						
							|  |  |  |      * @param pc Program counter. Offset to decode. | 
					
						
							|  |  |  |      * @return Next address to decode. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2019-01-30 02:09:40 -03:00
										 |  |  |     u32 DecodeInstr(NodeBlock& bb, u32 pc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     u32 DecodeArithmetic(NodeBlock& bb, u32 pc); | 
					
						
							|  |  |  |     u32 DecodeArithmeticImmediate(NodeBlock& bb, u32 pc); | 
					
						
							|  |  |  |     u32 DecodeBfe(NodeBlock& bb, u32 pc); | 
					
						
							|  |  |  |     u32 DecodeBfi(NodeBlock& bb, u32 pc); | 
					
						
							|  |  |  |     u32 DecodeShift(NodeBlock& bb, u32 pc); | 
					
						
							|  |  |  |     u32 DecodeArithmeticInteger(NodeBlock& bb, u32 pc); | 
					
						
							|  |  |  |     u32 DecodeArithmeticIntegerImmediate(NodeBlock& bb, u32 pc); | 
					
						
							|  |  |  |     u32 DecodeArithmeticHalf(NodeBlock& bb, u32 pc); | 
					
						
							|  |  |  |     u32 DecodeArithmeticHalfImmediate(NodeBlock& bb, u32 pc); | 
					
						
							|  |  |  |     u32 DecodeFfma(NodeBlock& bb, u32 pc); | 
					
						
							|  |  |  |     u32 DecodeHfma2(NodeBlock& bb, u32 pc); | 
					
						
							|  |  |  |     u32 DecodeConversion(NodeBlock& bb, u32 pc); | 
					
						
							| 
									
										
										
										
											2019-08-09 23:50:21 -03:00
										 |  |  |     u32 DecodeWarp(NodeBlock& bb, u32 pc); | 
					
						
							| 
									
										
										
										
											2019-01-30 02:09:40 -03:00
										 |  |  |     u32 DecodeMemory(NodeBlock& bb, u32 pc); | 
					
						
							| 
									
										
										
										
											2019-02-22 02:19:45 -03:00
										 |  |  |     u32 DecodeTexture(NodeBlock& bb, u32 pc); | 
					
						
							| 
									
										
										
										
											2019-04-27 02:07:18 -03:00
										 |  |  |     u32 DecodeImage(NodeBlock& bb, u32 pc); | 
					
						
							| 
									
										
										
										
											2019-01-30 02:09:40 -03:00
										 |  |  |     u32 DecodeFloatSetPredicate(NodeBlock& bb, u32 pc); | 
					
						
							|  |  |  |     u32 DecodeIntegerSetPredicate(NodeBlock& bb, u32 pc); | 
					
						
							|  |  |  |     u32 DecodeHalfSetPredicate(NodeBlock& bb, u32 pc); | 
					
						
							|  |  |  |     u32 DecodePredicateSetRegister(NodeBlock& bb, u32 pc); | 
					
						
							|  |  |  |     u32 DecodePredicateSetPredicate(NodeBlock& bb, u32 pc); | 
					
						
							|  |  |  |     u32 DecodeRegisterSetPredicate(NodeBlock& bb, u32 pc); | 
					
						
							|  |  |  |     u32 DecodeFloatSet(NodeBlock& bb, u32 pc); | 
					
						
							|  |  |  |     u32 DecodeIntegerSet(NodeBlock& bb, u32 pc); | 
					
						
							|  |  |  |     u32 DecodeHalfSet(NodeBlock& bb, u32 pc); | 
					
						
							|  |  |  |     u32 DecodeVideo(NodeBlock& bb, u32 pc); | 
					
						
							|  |  |  |     u32 DecodeXmad(NodeBlock& bb, u32 pc); | 
					
						
							|  |  |  |     u32 DecodeOther(NodeBlock& bb, u32 pc); | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-20 22:41:31 -03:00
										 |  |  |     /// Generates a node for a passed register.
 | 
					
						
							|  |  |  |     Node GetRegister(Tegra::Shader::Register reg); | 
					
						
							| 
									
										
										
										
											2018-12-20 22:36:17 -03:00
										 |  |  |     /// Generates a node representing a 19-bit immediate value
 | 
					
						
							|  |  |  |     Node GetImmediate19(Tegra::Shader::Instruction instr); | 
					
						
							|  |  |  |     /// Generates a node representing a 32-bit immediate value
 | 
					
						
							|  |  |  |     Node GetImmediate32(Tegra::Shader::Instruction instr); | 
					
						
							| 
									
										
										
										
											2018-12-20 22:42:47 -03:00
										 |  |  |     /// Generates a node representing a constant buffer
 | 
					
						
							|  |  |  |     Node GetConstBuffer(u64 index, u64 offset); | 
					
						
							|  |  |  |     /// Generates a node representing a constant buffer with a variadic offset
 | 
					
						
							|  |  |  |     Node GetConstBufferIndirect(u64 index, u64 offset, Node node); | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  |     /// Generates a node for a passed predicate. It can be optionally negated
 | 
					
						
							|  |  |  |     Node GetPredicate(u64 pred, bool negated = false); | 
					
						
							| 
									
										
										
										
											2018-12-20 22:36:17 -03:00
										 |  |  |     /// Generates a predicate node for an immediate true or false value
 | 
					
						
							|  |  |  |     Node GetPredicate(bool immediate); | 
					
						
							| 
									
										
										
										
											2019-01-28 07:52:02 -05:00
										 |  |  |     /// Generates a node representing an input attribute. Keeps track of used attributes.
 | 
					
						
							| 
									
										
										
										
											2019-04-29 23:37:09 -03:00
										 |  |  |     Node GetInputAttribute(Tegra::Shader::Attribute::Index index, u64 element, Node buffer = {}); | 
					
						
							| 
									
										
										
										
											2019-04-30 18:12:30 -03:00
										 |  |  |     /// Generates a node representing a physical input attribute.
 | 
					
						
							|  |  |  |     Node GetPhysicalInputAttribute(Tegra::Shader::Register physical_address, Node buffer = {}); | 
					
						
							| 
									
										
										
										
											2019-01-28 07:52:02 -05:00
										 |  |  |     /// Generates a node representing an output attribute. Keeps track of used attributes.
 | 
					
						
							| 
									
										
										
										
											2018-12-20 22:45:34 -03:00
										 |  |  |     Node GetOutputAttribute(Tegra::Shader::Attribute::Index index, u64 element, Node buffer); | 
					
						
							| 
									
										
										
										
											2018-12-20 22:49:59 -03:00
										 |  |  |     /// Generates a node representing an internal flag
 | 
					
						
							| 
									
										
										
										
											2019-06-29 01:44:07 -04:00
										 |  |  |     Node GetInternalFlag(InternalFlag flag, bool negated = false) const; | 
					
						
							| 
									
										
										
										
											2018-12-20 22:51:38 -03:00
										 |  |  |     /// Generates a node representing a local memory address
 | 
					
						
							|  |  |  |     Node GetLocalMemory(Node address); | 
					
						
							| 
									
										
										
										
											2019-07-30 00:21:46 -03:00
										 |  |  |     /// Generates a node representing a shared memory address
 | 
					
						
							|  |  |  |     Node GetSharedMemory(Node address); | 
					
						
							| 
									
										
										
										
											2019-07-16 10:31:17 -04:00
										 |  |  |     /// Generates a temporary, internally it uses a post-RZ register
 | 
					
						
							|  |  |  |     Node GetTemporary(u32 id); | 
					
						
							| 
									
										
										
										
											2018-12-20 22:51:38 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-20 22:53:43 -03:00
										 |  |  |     /// Sets a register. src value must be a number-evaluated node.
 | 
					
						
							| 
									
										
										
										
											2019-01-30 02:09:40 -03:00
										 |  |  |     void SetRegister(NodeBlock& bb, Tegra::Shader::Register dest, Node src); | 
					
						
							| 
									
										
										
										
											2018-12-20 22:53:43 -03:00
										 |  |  |     /// Sets a predicate. src value must be a bool-evaluated node
 | 
					
						
							| 
									
										
										
										
											2019-01-30 02:09:40 -03:00
										 |  |  |     void SetPredicate(NodeBlock& bb, u64 dest, Node src); | 
					
						
							| 
									
										
										
										
											2018-12-20 22:53:43 -03:00
										 |  |  |     /// Sets an internal flag. src value must be a bool-evaluated node
 | 
					
						
							| 
									
										
										
										
											2019-01-30 02:09:40 -03:00
										 |  |  |     void SetInternalFlag(NodeBlock& bb, InternalFlag flag, Node value); | 
					
						
							| 
									
										
										
										
											2019-07-30 00:21:46 -03:00
										 |  |  |     /// Sets a local memory address with a value.
 | 
					
						
							| 
									
										
										
										
											2019-01-30 02:09:40 -03:00
										 |  |  |     void SetLocalMemory(NodeBlock& bb, Node address, Node value); | 
					
						
							| 
									
										
										
										
											2019-07-30 00:21:46 -03:00
										 |  |  |     /// Sets a shared memory address with a value.
 | 
					
						
							|  |  |  |     void SetSharedMemory(NodeBlock& bb, Node address, Node value); | 
					
						
							| 
									
										
										
										
											2019-07-16 10:31:17 -04:00
										 |  |  |     /// Sets a temporary. Internally it uses a post-RZ register
 | 
					
						
							|  |  |  |     void SetTemporary(NodeBlock& bb, u32 id, Node value); | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-27 16:50:36 -03:00
										 |  |  |     /// Sets internal flags from a float
 | 
					
						
							| 
									
										
										
										
											2019-01-30 02:09:40 -03:00
										 |  |  |     void SetInternalFlagsFromFloat(NodeBlock& bb, Node value, bool sets_cc = true); | 
					
						
							| 
									
										
										
										
											2018-12-27 16:50:36 -03:00
										 |  |  |     /// Sets internal flags from an integer
 | 
					
						
							| 
									
										
										
										
											2019-01-30 02:09:40 -03:00
										 |  |  |     void SetInternalFlagsFromInteger(NodeBlock& bb, Node value, bool sets_cc = true); | 
					
						
							| 
									
										
										
										
											2018-12-27 16:50:36 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-20 22:56:08 -03:00
										 |  |  |     /// Conditionally absolute/negated float. Absolute is applied first
 | 
					
						
							|  |  |  |     Node GetOperandAbsNegFloat(Node value, bool absolute, bool negate); | 
					
						
							|  |  |  |     /// Conditionally saturates a float
 | 
					
						
							|  |  |  |     Node GetSaturatedFloat(Node value, bool saturate = true); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-20 22:57:16 -03:00
										 |  |  |     /// Converts an integer to different sizes.
 | 
					
						
							|  |  |  |     Node ConvertIntegerSize(Node value, Tegra::Shader::Register::Size size, bool is_signed); | 
					
						
							|  |  |  |     /// Conditionally absolute/negated integer. Absolute is applied first
 | 
					
						
							|  |  |  |     Node GetOperandAbsNegInteger(Node value, bool absolute, bool negate, bool is_signed); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-20 22:58:33 -03:00
										 |  |  |     /// Unpacks a half immediate from an instruction
 | 
					
						
							|  |  |  |     Node UnpackHalfImmediate(Tegra::Shader::Instruction instr, bool has_negation); | 
					
						
							| 
									
										
										
										
											2019-04-15 19:48:11 -03:00
										 |  |  |     /// Unpacks a binary value into a half float pair with a type format
 | 
					
						
							|  |  |  |     Node UnpackHalfFloat(Node value, Tegra::Shader::HalfType type); | 
					
						
							| 
									
										
										
										
											2018-12-20 22:58:33 -03:00
										 |  |  |     /// Merges a half pair into another value
 | 
					
						
							|  |  |  |     Node HalfMerge(Node dest, Node src, Tegra::Shader::HalfMerge merge); | 
					
						
							|  |  |  |     /// Conditionally absolute/negated half float pair. Absolute is applied first
 | 
					
						
							|  |  |  |     Node GetOperandAbsNegHalf(Node value, bool absolute, bool negate); | 
					
						
							| 
									
										
										
										
											2019-04-09 18:41:41 -03:00
										 |  |  |     /// Conditionally saturates a half float pair
 | 
					
						
							|  |  |  |     Node GetSaturatedHalfFloat(Node value, bool saturate = true); | 
					
						
							| 
									
										
										
										
											2018-12-20 22:58:33 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-20 23:01:03 -03:00
										 |  |  |     /// Returns a predicate comparing two floats
 | 
					
						
							|  |  |  |     Node GetPredicateComparisonFloat(Tegra::Shader::PredCondition condition, Node op_a, Node op_b); | 
					
						
							|  |  |  |     /// Returns a predicate comparing two integers
 | 
					
						
							|  |  |  |     Node GetPredicateComparisonInteger(Tegra::Shader::PredCondition condition, bool is_signed, | 
					
						
							|  |  |  |                                        Node op_a, Node op_b); | 
					
						
							|  |  |  |     /// Returns a predicate comparing two half floats. meta consumes how both pairs will be compared
 | 
					
						
							| 
									
										
										
										
											2019-04-15 19:48:11 -03:00
										 |  |  |     Node GetPredicateComparisonHalf(Tegra::Shader::PredCondition condition, Node op_a, Node op_b); | 
					
						
							| 
									
										
										
										
											2018-12-20 23:01:03 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-20 23:40:54 -03:00
										 |  |  |     /// Returns a predicate combiner operation
 | 
					
						
							|  |  |  |     OperationCode GetPredicateCombiner(Tegra::Shader::PredOperation operation); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-21 01:27:47 -03:00
										 |  |  |     /// Accesses a texture sampler
 | 
					
						
							|  |  |  |     const Sampler& GetSampler(const Tegra::Shader::Sampler& sampler, | 
					
						
							| 
									
										
										
										
											2019-09-25 09:53:18 -04:00
										 |  |  |                               std::optional<SamplerInfo> sampler_info); | 
					
						
							| 
									
										
										
										
											2018-12-21 01:27:47 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 17:05:23 -04:00
										 |  |  |     // Accesses a texture sampler for a bindless texture.
 | 
					
						
							| 
									
										
										
										
											2019-03-26 17:56:16 -04:00
										 |  |  |     const Sampler& GetBindlessSampler(const Tegra::Shader::Register& reg, | 
					
						
							| 
									
										
										
										
											2019-09-25 09:53:18 -04:00
										 |  |  |                                       std::optional<SamplerInfo> sampler_info); | 
					
						
							| 
									
										
										
										
											2019-03-26 17:05:23 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-27 02:07:18 -03:00
										 |  |  |     /// Accesses an image.
 | 
					
						
							| 
									
										
										
										
											2019-09-18 01:50:40 -03:00
										 |  |  |     Image& GetImage(Tegra::Shader::Image image, Tegra::Shader::ImageType type); | 
					
						
							| 
									
										
										
										
											2019-04-27 02:07:18 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-27 03:04:13 -03:00
										 |  |  |     /// Access a bindless image sampler.
 | 
					
						
							| 
									
										
										
										
											2019-09-18 01:50:40 -03:00
										 |  |  |     Image& GetBindlessImage(Tegra::Shader::Register reg, Tegra::Shader::ImageType type); | 
					
						
							| 
									
										
										
										
											2019-07-17 21:03:53 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-26 02:58:47 -03:00
										 |  |  |     /// Extracts a sequence of bits from a node
 | 
					
						
							|  |  |  |     Node BitfieldExtract(Node value, u32 offset, u32 bits); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-11 21:14:44 -03:00
										 |  |  |     /// Inserts a sequence of bits from a node
 | 
					
						
							|  |  |  |     Node BitfieldInsert(Node base, Node insert, u32 offset, u32 bits); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-30 02:09:40 -03:00
										 |  |  |     void WriteTexInstructionFloat(NodeBlock& bb, Tegra::Shader::Instruction instr, | 
					
						
							| 
									
										
										
										
											2019-10-30 21:14:57 -04:00
										 |  |  |                                   const Node4& components); | 
					
						
							| 
									
										
										
										
											2018-12-21 01:27:47 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-30 02:09:40 -03:00
										 |  |  |     void WriteTexsInstructionFloat(NodeBlock& bb, Tegra::Shader::Instruction instr, | 
					
						
							| 
									
										
										
										
											2019-10-22 10:59:07 -04:00
										 |  |  |                                    const Node4& components, bool ignore_mask = false); | 
					
						
							| 
									
										
										
										
											2019-01-30 02:09:40 -03:00
										 |  |  |     void WriteTexsInstructionHalfFloat(NodeBlock& bb, Tegra::Shader::Instruction instr, | 
					
						
							| 
									
										
										
										
											2018-12-27 01:50:22 -03:00
										 |  |  |                                        const Node4& components); | 
					
						
							| 
									
										
										
										
											2018-12-13 16:59:28 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-27 01:50:22 -03:00
										 |  |  |     Node4 GetTexCode(Tegra::Shader::Instruction instr, Tegra::Shader::TextureType texture_type, | 
					
						
							| 
									
										
										
										
											2018-12-21 01:27:47 -03:00
										 |  |  |                      Tegra::Shader::TextureProcessMode process_mode, bool depth_compare, | 
					
						
							| 
									
										
										
										
											2019-03-27 07:11:50 -04:00
										 |  |  |                      bool is_array, bool is_aoffi, | 
					
						
							|  |  |  |                      std::optional<Tegra::Shader::Register> bindless_reg); | 
					
						
							| 
									
										
										
										
											2018-12-21 01:27:47 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-27 01:50:22 -03:00
										 |  |  |     Node4 GetTexsCode(Tegra::Shader::Instruction instr, Tegra::Shader::TextureType texture_type, | 
					
						
							|  |  |  |                       Tegra::Shader::TextureProcessMode process_mode, bool depth_compare, | 
					
						
							|  |  |  |                       bool is_array); | 
					
						
							| 
									
										
										
										
											2018-12-23 00:38:01 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-27 01:50:22 -03:00
										 |  |  |     Node4 GetTld4Code(Tegra::Shader::Instruction instr, Tegra::Shader::TextureType texture_type, | 
					
						
							| 
									
										
										
										
											2019-10-29 20:48:18 -04:00
										 |  |  |                       bool depth_compare, bool is_array, bool is_aoffi, bool is_bindless); | 
					
						
							| 
									
										
										
										
											2018-12-27 01:50:22 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-27 20:50:35 -03:00
										 |  |  |     Node4 GetTldCode(Tegra::Shader::Instruction instr); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-27 01:50:22 -03:00
										 |  |  |     Node4 GetTldsCode(Tegra::Shader::Instruction instr, Tegra::Shader::TextureType texture_type, | 
					
						
							|  |  |  |                       bool is_array); | 
					
						
							| 
									
										
										
										
											2018-12-23 01:18:33 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-21 01:27:47 -03:00
										 |  |  |     std::tuple<std::size_t, std::size_t> ValidateAndGetCoordinateElement( | 
					
						
							|  |  |  |         Tegra::Shader::TextureType texture_type, bool depth_compare, bool is_array, | 
					
						
							|  |  |  |         bool lod_bias_enabled, std::size_t max_coords, std::size_t max_inputs); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-29 18:36:54 -03:00
										 |  |  |     std::vector<Node> GetAoffiCoordinates(Node aoffi_reg, std::size_t coord_count, bool is_tld4); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-27 01:50:22 -03:00
										 |  |  |     Node4 GetTextureCode(Tegra::Shader::Instruction instr, Tegra::Shader::TextureType texture_type, | 
					
						
							| 
									
										
										
										
											2019-01-29 04:31:40 -03:00
										 |  |  |                          Tegra::Shader::TextureProcessMode process_mode, std::vector<Node> coords, | 
					
						
							| 
									
										
										
										
											2019-03-27 07:11:50 -04:00
										 |  |  |                          Node array, Node depth_compare, u32 bias_offset, std::vector<Node> aoffi, | 
					
						
							|  |  |  |                          std::optional<Tegra::Shader::Register> bindless_reg); | 
					
						
							| 
									
										
										
										
											2018-12-21 01:27:47 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-24 01:23:00 -03:00
										 |  |  |     Node GetVideoOperand(Node op, bool is_chunk, bool is_signed, Tegra::Shader::VideoType type, | 
					
						
							|  |  |  |                          u64 byte_height); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-30 02:09:40 -03:00
										 |  |  |     void WriteLogicOperation(NodeBlock& bb, Tegra::Shader::Register dest, | 
					
						
							| 
									
										
										
										
											2018-12-21 02:02:15 -03:00
										 |  |  |                              Tegra::Shader::LogicOperation logic_op, Node op_a, Node op_b, | 
					
						
							|  |  |  |                              Tegra::Shader::PredicateResultMode predicate_mode, | 
					
						
							| 
									
										
										
										
											2018-12-27 16:50:36 -03:00
										 |  |  |                              Tegra::Shader::Pred predicate, bool sets_cc); | 
					
						
							| 
									
										
										
										
											2019-01-30 02:09:40 -03:00
										 |  |  |     void WriteLop3Instruction(NodeBlock& bb, Tegra::Shader::Register dest, Node op_a, Node op_b, | 
					
						
							| 
									
										
										
										
											2018-12-27 16:50:36 -03:00
										 |  |  |                               Node op_c, Node imm_lut, bool sets_cc); | 
					
						
							| 
									
										
										
										
											2018-12-21 02:02:15 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-31 19:14:34 -03:00
										 |  |  |     std::tuple<Node, u32, u32> TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor) const; | 
					
						
							| 
									
										
										
										
											2018-12-29 02:44:54 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-19 04:10:32 -04:00
										 |  |  |     std::optional<u32> TrackImmediate(Node tracked, const NodeBlock& code, s64 cursor) const; | 
					
						
							| 
									
										
										
										
											2019-03-29 18:36:07 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-19 04:10:32 -04:00
										 |  |  |     std::pair<Node, s64> TrackRegister(const GprNode* tracked, const NodeBlock& code, | 
					
						
							|  |  |  |                                        s64 cursor) const; | 
					
						
							| 
									
										
										
										
											2018-12-29 02:44:54 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-18 01:23:10 -03:00
										 |  |  |     std::tuple<Node, Node, GlobalMemoryBase> TrackGlobalMemory(NodeBlock& bb, | 
					
						
							|  |  |  |                                                                Tegra::Shader::Instruction instr, | 
					
						
							|  |  |  |                                                                bool is_write); | 
					
						
							| 
									
										
										
										
											2019-02-07 00:05:41 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  |     const ProgramCode& program_code; | 
					
						
							|  |  |  |     const u32 main_offset; | 
					
						
							| 
									
										
										
										
											2019-09-24 23:34:18 -03:00
										 |  |  |     const CompilerSettings settings; | 
					
						
							|  |  |  |     ConstBufferLocker& locker; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-29 01:44:07 -04:00
										 |  |  |     bool decompiled{}; | 
					
						
							| 
									
										
										
										
											2019-08-16 16:25:02 -04:00
										 |  |  |     bool disable_flow_stack{}; | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     u32 coverage_begin{}; | 
					
						
							|  |  |  |     u32 coverage_end{}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-30 02:09:40 -03:00
										 |  |  |     std::map<u32, NodeBlock> basic_blocks; | 
					
						
							|  |  |  |     NodeBlock global_code; | 
					
						
							| 
									
										
										
										
											2019-09-24 23:34:18 -03:00
										 |  |  |     ASTManager program_manager{true, true}; | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     std::set<u32> used_registers; | 
					
						
							|  |  |  |     std::set<Tegra::Shader::Pred> used_predicates; | 
					
						
							| 
									
										
										
										
											2019-04-29 23:37:09 -03:00
										 |  |  |     std::set<Tegra::Shader::Attribute::Index> used_input_attributes; | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  |     std::set<Tegra::Shader::Attribute::Index> used_output_attributes; | 
					
						
							|  |  |  |     std::map<u32, ConstBuffer> used_cbufs; | 
					
						
							| 
									
										
										
										
											2019-10-28 02:31:05 -03:00
										 |  |  |     std::list<Sampler> used_samplers; | 
					
						
							|  |  |  |     std::list<Image> used_images; | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  |     std::array<bool, Tegra::Engines::Maxwell3D::Regs::NumClipDistances> used_clip_distances{}; | 
					
						
							| 
									
										
										
										
											2019-02-07 00:05:41 -03:00
										 |  |  |     std::map<GlobalMemoryBase, GlobalMemoryUsage> used_global_memory; | 
					
						
							| 
									
										
										
										
											2019-07-07 20:36:42 -03:00
										 |  |  |     bool uses_layer{}; | 
					
						
							|  |  |  |     bool uses_viewport_index{}; | 
					
						
							|  |  |  |     bool uses_point_size{}; | 
					
						
							| 
									
										
										
										
											2019-04-30 19:46:49 -03:00
										 |  |  |     bool uses_physical_attributes{}; // Shader uses AL2P or physical attribute read/writes
 | 
					
						
							| 
									
										
										
										
											2019-09-15 14:25:07 -04:00
										 |  |  |     bool uses_instance_id{}; | 
					
						
							|  |  |  |     bool uses_vertex_id{}; | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Tegra::Shader::Header header; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-21 03:22:26 -03:00
										 |  |  | } // namespace VideoCommon::Shader
 |