summaryrefslogtreecommitdiffstats
path: root/src/video_core/shader/shader_ir.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/shader/shader_ir.h')
-rw-r--r--src/video_core/shader/shader_ir.h59
1 files changed, 39 insertions, 20 deletions
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index e22548208..bcc9b79b6 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -5,13 +5,10 @@
#pragma once
#include <array>
-#include <cstring>
#include <map>
#include <optional>
#include <set>
-#include <string>
#include <tuple>
-#include <variant>
#include <vector>
#include "common/common_types.h"
@@ -22,18 +19,12 @@
namespace VideoCommon::Shader {
+struct ShaderBlock;
+
using ProgramCode = std::vector<u64>;
constexpr u32 MAX_PROGRAM_LENGTH = 0x1000;
-/// Describes the behaviour of code path of a given entry point and a return point.
-enum class ExitMethod {
- Undetermined, ///< Internal value. Only occur when analyzing JMP loop.
- AlwaysReturn, ///< All code paths reach the return point.
- Conditional, ///< Code path reaches the return point or an END instruction conditionally.
- AlwaysEnd, ///< All code paths reach a END instruction.
-};
-
class ConstBuffer {
public:
explicit ConstBuffer(u32 max_offset, bool is_indirect)
@@ -73,7 +64,7 @@ struct GlobalMemoryUsage {
class ShaderIR final {
public:
- explicit ShaderIR(const ProgramCode& program_code, u32 main_offset);
+ explicit ShaderIR(const ProgramCode& program_code, u32 main_offset, std::size_t size);
~ShaderIR();
const std::map<u32, NodeBlock>& GetBasicBlocks() const {
@@ -121,6 +112,18 @@ public:
return static_cast<std::size_t>(coverage_end * sizeof(u64));
}
+ bool UsesLayer() const {
+ return uses_layer;
+ }
+
+ bool UsesViewportIndex() const {
+ return uses_viewport_index;
+ }
+
+ bool UsesPointSize() const {
+ return uses_point_size;
+ }
+
bool HasPhysicalAttributes() const {
return uses_physical_attributes;
}
@@ -129,12 +132,20 @@ public:
return header;
}
+ bool IsFlowStackDisabled() const {
+ return disable_flow_stack;
+ }
+
+ u32 ConvertAddressToNvidiaSpace(const u32 address) const {
+ return (address - main_offset) * sizeof(Tegra::Shader::Instruction);
+ }
+
private:
void Decode();
- ExitMethod Scan(u32 begin, u32 end, std::set<u32>& labels);
-
NodeBlock DecodeRange(u32 begin, u32 end);
+ void DecodeRangeInner(NodeBlock& bb, u32 begin, u32 end);
+ void InsertControlFlow(NodeBlock& bb, const ShaderBlock& block);
/**
* Decodes a single instruction from Tegra to IR.
@@ -156,6 +167,7 @@ private:
u32 DecodeFfma(NodeBlock& bb, u32 pc);
u32 DecodeHfma2(NodeBlock& bb, u32 pc);
u32 DecodeConversion(NodeBlock& bb, u32 pc);
+ u32 DecodeWarp(NodeBlock& bb, u32 pc);
u32 DecodeMemory(NodeBlock& bb, u32 pc);
u32 DecodeTexture(NodeBlock& bb, u32 pc);
u32 DecodeImage(NodeBlock& bb, u32 pc);
@@ -196,8 +208,8 @@ private:
Node GetInternalFlag(InternalFlag flag, bool negated = false);
/// Generates a node representing a local memory address
Node GetLocalMemory(Node address);
- /// Generates a temporal, internally it uses a post-RZ register
- Node GetTemporal(u32 id);
+ /// Generates a temporary, internally it uses a post-RZ register
+ Node GetTemporary(u32 id);
/// Sets a register. src value must be a number-evaluated node.
void SetRegister(NodeBlock& bb, Tegra::Shader::Register dest, Node src);
@@ -207,8 +219,8 @@ private:
void SetInternalFlag(NodeBlock& bb, InternalFlag flag, Node value);
/// Sets a local memory address. address and value must be a number-evaluated node
void SetLocalMemory(NodeBlock& bb, Node address, Node value);
- /// Sets a temporal. Internally it uses a post-RZ register
- void SetTemporal(NodeBlock& bb, u32 id, Node value);
+ /// Sets a temporary. Internally it uses a post-RZ register
+ void SetTemporary(NodeBlock& bb, u32 id, Node value);
/// Sets internal flags from a float
void SetInternalFlagsFromFloat(NodeBlock& bb, Node value, bool sets_cc = true);
@@ -268,6 +280,9 @@ private:
/// Extracts a sequence of bits from a node
Node BitfieldExtract(Node value, u32 offset, u32 bits);
+ /// Inserts a sequence of bits from a node
+ Node BitfieldInsert(Node base, Node insert, u32 offset, u32 bits);
+
void WriteTexInstructionFloat(NodeBlock& bb, Tegra::Shader::Instruction instr,
const Node4& components);
@@ -314,7 +329,7 @@ private:
void WriteLop3Instruction(NodeBlock& bb, Tegra::Shader::Register dest, Node op_a, Node op_b,
Node op_c, Node imm_lut, bool sets_cc);
- Node TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor) const;
+ std::tuple<Node, u32, u32> TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor) const;
std::optional<u32> TrackImmediate(Node tracked, const NodeBlock& code, s64 cursor) const;
@@ -326,10 +341,11 @@ private:
const ProgramCode& program_code;
const u32 main_offset;
+ const std::size_t program_size;
+ bool disable_flow_stack{};
u32 coverage_begin{};
u32 coverage_end{};
- std::map<std::pair<u32, u32>, ExitMethod> exit_method_map;
std::map<u32, NodeBlock> basic_blocks;
NodeBlock global_code;
@@ -343,6 +359,9 @@ private:
std::set<Image> used_images;
std::array<bool, Tegra::Engines::Maxwell3D::Regs::NumClipDistances> used_clip_distances{};
std::map<GlobalMemoryBase, GlobalMemoryUsage> used_global_memory;
+ bool uses_layer{};
+ bool uses_viewport_index{};
+ bool uses_point_size{};
bool uses_physical_attributes{}; // Shader uses AL2P or physical attribute read/writes
Tegra::Shader::Header header;