Shader_IR: Implement Injectable Custom Variables to the IR.

This commit is contained in:
Fernando Sahmkow 2020-01-07 14:53:46 -04:00 committed by FernandoS27
parent 2b02f29a2d
commit 3c34678627
5 changed files with 70 additions and 1 deletions

View file

@ -391,6 +391,7 @@ public:
DeclareVertex(); DeclareVertex();
DeclareGeometry(); DeclareGeometry();
DeclareRegisters(); DeclareRegisters();
DeclareCustomVariables();
DeclarePredicates(); DeclarePredicates();
DeclareLocalMemory(); DeclareLocalMemory();
DeclareInternalFlags(); DeclareInternalFlags();
@ -503,6 +504,16 @@ private:
} }
} }
void DeclareCustomVariables() {
const u32 cv_num = ir.GetCustomVariablesAmount();
for (u32 i = 0; i < cv_num; ++i) {
code.AddLine("float {} = 0.0f;", GetCustomVariable(i));
}
if (cv_num > 0) {
code.AddNewLine();
}
}
void DeclarePredicates() { void DeclarePredicates() {
const auto& predicates = ir.GetPredicates(); const auto& predicates = ir.GetPredicates();
for (const auto pred : predicates) { for (const auto pred : predicates) {
@ -780,6 +791,11 @@ private:
return {GetRegister(index), Type::Float}; return {GetRegister(index), Type::Float};
} }
if (const auto cv = std::get_if<CustomVarNode>(&*node)) {
const u32 index = cv->GetIndex();
return {GetCustomVariable(index), Type::Float};
}
if (const auto immediate = std::get_if<ImmediateNode>(&*node)) { if (const auto immediate = std::get_if<ImmediateNode>(&*node)) {
const u32 value = immediate->GetValue(); const u32 value = immediate->GetValue();
if (value < 10) { if (value < 10) {
@ -2250,6 +2266,10 @@ private:
return GetDeclarationWithSuffix(index, "gpr"); return GetDeclarationWithSuffix(index, "gpr");
} }
std::string GetCustomVariable(u32 index) const {
return GetDeclarationWithSuffix(index, "custom_var");
}
std::string GetPredicate(Tegra::Shader::Pred pred) const { std::string GetPredicate(Tegra::Shader::Pred pred) const {
return GetDeclarationWithSuffix(static_cast<u32>(pred), "pred"); return GetDeclarationWithSuffix(static_cast<u32>(pred), "pred");
} }

View file

@ -353,6 +353,7 @@ private:
DeclareFragment(); DeclareFragment();
DeclareCompute(); DeclareCompute();
DeclareRegisters(); DeclareRegisters();
DeclareCustomVariables();
DeclarePredicates(); DeclarePredicates();
DeclareLocalMemory(); DeclareLocalMemory();
DeclareSharedMemory(); DeclareSharedMemory();
@ -587,6 +588,15 @@ private:
} }
} }
void DeclareCustomVariables() {
const u32 cv_num = ir.GetCustomVariablesAmount();
for (u32 i = 0; i < cv_num; ++i) {
const Id id = OpVariable(t_prv_float, spv::StorageClass::Private, v_float_zero);
Name(id, fmt::format("custom_var_{}", i));
custom_variables.emplace(i, AddGlobalVariable(id));
}
}
void DeclarePredicates() { void DeclarePredicates() {
for (const auto pred : ir.GetPredicates()) { for (const auto pred : ir.GetPredicates()) {
const Id id = OpVariable(t_prv_bool, spv::StorageClass::Private, v_false); const Id id = OpVariable(t_prv_bool, spv::StorageClass::Private, v_false);
@ -974,6 +984,11 @@ private:
return {OpLoad(t_float, registers.at(index)), Type::Float}; return {OpLoad(t_float, registers.at(index)), Type::Float};
} }
if (const auto cv = std::get_if<CustomVarNode>(&*node)) {
const u32 index = cv->GetIndex();
return {OpLoad(t_float, custom_variables.at(index)), Type::Float};
}
if (const auto immediate = std::get_if<ImmediateNode>(&*node)) { if (const auto immediate = std::get_if<ImmediateNode>(&*node)) {
return {Constant(t_uint, immediate->GetValue()), Type::Uint}; return {Constant(t_uint, immediate->GetValue()), Type::Uint};
} }
@ -2505,6 +2520,7 @@ private:
Id out_vertex{}; Id out_vertex{};
Id in_vertex{}; Id in_vertex{};
std::map<u32, Id> registers; std::map<u32, Id> registers;
std::map<u32, Id> custom_variables;
std::map<Tegra::Shader::Pred, Id> predicates; std::map<Tegra::Shader::Pred, Id> predicates;
std::map<u32, Id> flow_variables; std::map<u32, Id> flow_variables;
Id local_memory{}; Id local_memory{};

View file

@ -212,6 +212,7 @@ enum class MetaStackClass {
class OperationNode; class OperationNode;
class ConditionalNode; class ConditionalNode;
class GprNode; class GprNode;
class CustomVarNode;
class ImmediateNode; class ImmediateNode;
class InternalFlagNode; class InternalFlagNode;
class PredicateNode; class PredicateNode;
@ -223,7 +224,7 @@ class SmemNode;
class GmemNode; class GmemNode;
class CommentNode; class CommentNode;
using NodeData = std::variant<OperationNode, ConditionalNode, GprNode, ImmediateNode, using NodeData = std::variant<OperationNode, ConditionalNode, GprNode, CustomVarNode, ImmediateNode,
InternalFlagNode, PredicateNode, AbufNode, PatchNode, CbufNode, InternalFlagNode, PredicateNode, AbufNode, PatchNode, CbufNode,
LmemNode, SmemNode, GmemNode, CommentNode>; LmemNode, SmemNode, GmemNode, CommentNode>;
using Node = std::shared_ptr<NodeData>; using Node = std::shared_ptr<NodeData>;
@ -550,6 +551,20 @@ private:
Tegra::Shader::Register index{}; Tegra::Shader::Register index{};
}; };
/// A custom variable
class CustomVarNode final {
public:
explicit constexpr CustomVarNode(u32 index) : index{index} {}
u32 GetIndex() const {
return index;
}
private:
u32 index{};
};
/// A 32-bits value that represents an immediate value /// A 32-bits value that represents an immediate value
class ImmediateNode final { class ImmediateNode final {
public: public:

View file

@ -39,6 +39,10 @@ Node ShaderIR::GetRegister(Register reg) {
return MakeNode<GprNode>(reg); return MakeNode<GprNode>(reg);
} }
Node ShaderIR::GetCustomVariable(u32 id) {
return MakeNode<CustomVarNode>(id);
}
Node ShaderIR::GetImmediate19(Instruction instr) { Node ShaderIR::GetImmediate19(Instruction instr) {
return Immediate(instr.alu.GetImm20_19()); return Immediate(instr.alu.GetImm20_19());
} }
@ -453,4 +457,9 @@ std::size_t ShaderIR::DeclareAmend(Node new_amend) {
return id; return id;
} }
u32 ShaderIR::NewCustomVariable() {
const u32 id = num_custom_variables++;
return id;
}
} // namespace VideoCommon::Shader } // namespace VideoCommon::Shader

View file

@ -180,6 +180,10 @@ public:
return amend_code[index]; return amend_code[index];
} }
u32 GetCustomVariablesAmount() const {
return num_custom_variables;
}
private: private:
friend class ASTDecoder; friend class ASTDecoder;
@ -236,6 +240,8 @@ private:
/// Generates a node for a passed register. /// Generates a node for a passed register.
Node GetRegister(Tegra::Shader::Register reg); Node GetRegister(Tegra::Shader::Register reg);
/// Generates a node for a custom variable
Node GetCustomVariable(u32 id);
/// Generates a node representing a 19-bit immediate value /// Generates a node representing a 19-bit immediate value
Node GetImmediate19(Tegra::Shader::Instruction instr); Node GetImmediate19(Tegra::Shader::Instruction instr);
/// Generates a node representing a 32-bit immediate value /// Generates a node representing a 32-bit immediate value
@ -403,6 +409,8 @@ private:
/// Register new amending code and obtain the reference id. /// Register new amending code and obtain the reference id.
std::size_t DeclareAmend(Node new_amend); std::size_t DeclareAmend(Node new_amend);
u32 NewCustomVariable();
const ProgramCode& program_code; const ProgramCode& program_code;
const u32 main_offset; const u32 main_offset;
const CompilerSettings settings; const CompilerSettings settings;
@ -418,6 +426,7 @@ private:
NodeBlock global_code; NodeBlock global_code;
ASTManager program_manager{true, true}; ASTManager program_manager{true, true};
std::vector<Node> amend_code; std::vector<Node> amend_code;
u32 num_custom_variables{};
std::set<u32> used_registers; std::set<u32> used_registers;
std::set<Tegra::Shader::Pred> used_predicates; std::set<Tegra::Shader::Pred> used_predicates;