Shader_IR: Implement Injectable Custom Variables to the IR.
This commit is contained in:
parent
2b02f29a2d
commit
3c34678627
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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{};
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Reference in New Issue