mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-11-27 17:22:46 +01:00
shader_decode: Rework HSETP2
This commit is contained in:
parent
8332482c24
commit
2df55985b6
4 changed files with 58 additions and 48 deletions
|
@ -39,10 +39,12 @@ u32 ShaderIR::DecodeHalfSetPredicate(BasicBlock& bb, u32 pc) {
|
||||||
const Node second_pred = GetPredicate(instr.hsetp2.pred39, instr.hsetp2.neg_pred != 0);
|
const Node second_pred = GetPredicate(instr.hsetp2.pred39, instr.hsetp2.neg_pred != 0);
|
||||||
|
|
||||||
const OperationCode combiner = GetPredicateCombiner(instr.hsetp2.op);
|
const OperationCode combiner = GetPredicateCombiner(instr.hsetp2.op);
|
||||||
|
const OperationCode pair_combiner =
|
||||||
|
instr.hsetp2.h_and ? OperationCode::LogicalAll2 : OperationCode::LogicalAny2;
|
||||||
|
|
||||||
MetaHalfArithmetic meta = {
|
MetaHalfArithmetic meta = {false, {instr.hsetp2.type_a, instr.hsetp2.type_b}};
|
||||||
false, {instr.hsetp2.type_a, instr.hsetp2.type_b}, instr.hsetp2.h_and != 0};
|
const Node comparison = GetPredicateComparisonHalf(instr.hsetp2.cond, meta, op_a, op_b);
|
||||||
const Node first_pred = GetPredicateComparisonHalf(instr.hsetp2.cond, meta, op_a, op_b);
|
const Node first_pred = Operation(pair_combiner, comparison);
|
||||||
|
|
||||||
// Set the primary predicate to the result of Predicate OP SecondPredicate
|
// Set the primary predicate to the result of Predicate OP SecondPredicate
|
||||||
const Node value = Operation(combiner, first_pred, second_pred);
|
const Node value = Operation(combiner, first_pred, second_pred);
|
||||||
|
|
|
@ -31,7 +31,7 @@ using Operation = const OperationNode&;
|
||||||
enum : u32 { POSITION_VARYING_LOCATION = 0, GENERIC_VARYING_START_LOCATION = 1 };
|
enum : u32 { POSITION_VARYING_LOCATION = 0, GENERIC_VARYING_START_LOCATION = 1 };
|
||||||
constexpr u32 MAX_CONSTBUFFER_ELEMENTS = 65536 / 16; // TODO(Rodrigo): Use rasterizer's value
|
constexpr u32 MAX_CONSTBUFFER_ELEMENTS = 65536 / 16; // TODO(Rodrigo): Use rasterizer's value
|
||||||
|
|
||||||
enum class Type { Bool, Float, Int, Uint, HalfFloat };
|
enum class Type { Bool, Bool2, Float, Int, Uint, HalfFloat };
|
||||||
|
|
||||||
class ShaderWriter {
|
class ShaderWriter {
|
||||||
public:
|
public:
|
||||||
|
@ -541,6 +541,7 @@ private:
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Type::Bool:
|
case Type::Bool:
|
||||||
|
case Type::Bool2:
|
||||||
case Type::Float:
|
case Type::Float:
|
||||||
return value;
|
return value;
|
||||||
case Type::Int:
|
case Type::Int:
|
||||||
|
@ -1011,38 +1012,42 @@ private:
|
||||||
return GenerateUnary(operation, "!", Type::Bool, Type::Bool, false);
|
return GenerateUnary(operation, "!", Type::Bool, Type::Bool, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LogicalHComparison(Operation operation, const std::string& func) {
|
std::string LogicalAll2(Operation operation) {
|
||||||
const auto& meta = std::get<MetaHalfArithmetic>(operation.GetMeta());
|
return GenerateUnary(operation, "all", Type::Bool, Type::Bool2);
|
||||||
const std::string op_a = VisitOperand(operation, 0, Type::HalfFloat);
|
|
||||||
const std::string op_b = VisitOperand(operation, 1, Type::HalfFloat);
|
|
||||||
|
|
||||||
std::string value = meta.and_comparison ? "all" : "any";
|
|
||||||
value += '(' + func + '(' + op_a + ", " + op_b + "))";
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LogicalHLessThan(Operation operation) {
|
std::string LogicalAny2(Operation operation) {
|
||||||
return LogicalHComparison(operation, "lessThan");
|
return GenerateUnary(operation, "any", Type::Bool, Type::Bool2);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LogicalHEqual(Operation operation) {
|
std::string Logical2HLessThan(Operation operation) {
|
||||||
return LogicalHComparison(operation, "equal");
|
return GenerateBinaryCall(operation, "lessThan", Type::Bool2, Type::HalfFloat,
|
||||||
|
Type::HalfFloat);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LogicalHLessEqual(Operation operation) {
|
std::string Logical2HEqual(Operation operation) {
|
||||||
return LogicalHComparison(operation, "lessThanEqual");
|
return GenerateBinaryCall(operation, "equal", Type::Bool2, Type::HalfFloat,
|
||||||
|
Type::HalfFloat);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LogicalHGreaterThan(Operation operation) {
|
std::string Logical2HLessEqual(Operation operation) {
|
||||||
return LogicalHComparison(operation, "greaterThan");
|
return GenerateBinaryCall(operation, "lessThanEqual", Type::Bool2, Type::HalfFloat,
|
||||||
|
Type::HalfFloat);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LogicalHNotEqual(Operation operation) {
|
std::string Logical2HGreaterThan(Operation operation) {
|
||||||
return LogicalHComparison(operation, "notEqual");
|
return GenerateBinaryCall(operation, "greaterThan", Type::Bool2, Type::HalfFloat,
|
||||||
|
Type::HalfFloat);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LogicalHGreaterEqual(Operation operation) {
|
std::string Logical2HNotEqual(Operation operation) {
|
||||||
return LogicalHComparison(operation, "greaterThanEqual");
|
return GenerateBinaryCall(operation, "notEqual", Type::Bool2, Type::HalfFloat,
|
||||||
|
Type::HalfFloat);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Logical2HGreaterEqual(Operation operation) {
|
||||||
|
return GenerateBinaryCall(operation, "greaterThanEqual", Type::Bool2, Type::HalfFloat,
|
||||||
|
Type::HalfFloat);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string F4Texture(Operation operation) {
|
std::string F4Texture(Operation operation) {
|
||||||
|
@ -1301,6 +1306,8 @@ private:
|
||||||
&LogicalOr,
|
&LogicalOr,
|
||||||
&LogicalXor,
|
&LogicalXor,
|
||||||
&LogicalNegate,
|
&LogicalNegate,
|
||||||
|
&LogicalAll2,
|
||||||
|
&LogicalAny2,
|
||||||
|
|
||||||
&LogicalLessThan<Type::Float>,
|
&LogicalLessThan<Type::Float>,
|
||||||
&LogicalEqual<Type::Float>,
|
&LogicalEqual<Type::Float>,
|
||||||
|
@ -1324,12 +1331,12 @@ private:
|
||||||
&LogicalNotEqual<Type::Uint>,
|
&LogicalNotEqual<Type::Uint>,
|
||||||
&LogicalGreaterEqual<Type::Uint>,
|
&LogicalGreaterEqual<Type::Uint>,
|
||||||
|
|
||||||
&LogicalHLessThan,
|
&Logical2HLessThan,
|
||||||
&LogicalHEqual,
|
&Logical2HEqual,
|
||||||
&LogicalHLessEqual,
|
&Logical2HLessEqual,
|
||||||
&LogicalHGreaterThan,
|
&Logical2HGreaterThan,
|
||||||
&LogicalHNotEqual,
|
&Logical2HNotEqual,
|
||||||
&LogicalHGreaterEqual,
|
&Logical2HGreaterEqual,
|
||||||
|
|
||||||
&F4Texture,
|
&F4Texture,
|
||||||
&F4TextureLod,
|
&F4TextureLod,
|
||||||
|
|
|
@ -289,17 +289,17 @@ Node ShaderIR::GetPredicateComparisonHalf(Tegra::Shader::PredCondition condition
|
||||||
"Unimplemented NaN comparison for half floats");
|
"Unimplemented NaN comparison for half floats");
|
||||||
|
|
||||||
static const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = {
|
static const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = {
|
||||||
{PredCondition::LessThan, OperationCode::LogicalHLessThan},
|
{PredCondition::LessThan, OperationCode::Logical2HLessThan},
|
||||||
{PredCondition::Equal, OperationCode::LogicalHEqual},
|
{PredCondition::Equal, OperationCode::Logical2HEqual},
|
||||||
{PredCondition::LessEqual, OperationCode::LogicalHLessEqual},
|
{PredCondition::LessEqual, OperationCode::Logical2HLessEqual},
|
||||||
{PredCondition::GreaterThan, OperationCode::LogicalHGreaterThan},
|
{PredCondition::GreaterThan, OperationCode::Logical2HGreaterThan},
|
||||||
{PredCondition::NotEqual, OperationCode::LogicalHNotEqual},
|
{PredCondition::NotEqual, OperationCode::Logical2HNotEqual},
|
||||||
{PredCondition::GreaterEqual, OperationCode::LogicalHGreaterEqual},
|
{PredCondition::GreaterEqual, OperationCode::Logical2HGreaterEqual},
|
||||||
{PredCondition::LessThanWithNan, OperationCode::LogicalHLessThan},
|
{PredCondition::LessThanWithNan, OperationCode::Logical2HLessThan},
|
||||||
{PredCondition::NotEqualWithNan, OperationCode::LogicalHNotEqual},
|
{PredCondition::NotEqualWithNan, OperationCode::Logical2HNotEqual},
|
||||||
{PredCondition::LessEqualWithNan, OperationCode::LogicalHLessEqual},
|
{PredCondition::LessEqualWithNan, OperationCode::Logical2HLessEqual},
|
||||||
{PredCondition::GreaterThanWithNan, OperationCode::LogicalHGreaterThan},
|
{PredCondition::GreaterThanWithNan, OperationCode::Logical2HGreaterThan},
|
||||||
{PredCondition::GreaterEqualWithNan, OperationCode::LogicalHGreaterEqual}};
|
{PredCondition::GreaterEqualWithNan, OperationCode::Logical2HGreaterEqual}};
|
||||||
|
|
||||||
const auto comparison{PredicateComparisonTable.find(condition)};
|
const auto comparison{PredicateComparisonTable.find(condition)};
|
||||||
UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(),
|
UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(),
|
||||||
|
|
|
@ -122,6 +122,8 @@ enum class OperationCode {
|
||||||
LogicalOr, /// (bool a, bool b) -> bool
|
LogicalOr, /// (bool a, bool b) -> bool
|
||||||
LogicalXor, /// (bool a, bool b) -> bool
|
LogicalXor, /// (bool a, bool b) -> bool
|
||||||
LogicalNegate, /// (bool a) -> bool
|
LogicalNegate, /// (bool a) -> bool
|
||||||
|
LogicalAll2, /// (bool2 a) -> bool
|
||||||
|
LogicalAny2, /// (bool2 a) -> bool
|
||||||
|
|
||||||
LogicalFLessThan, /// (float a, float b) -> bool
|
LogicalFLessThan, /// (float a, float b) -> bool
|
||||||
LogicalFEqual, /// (float a, float b) -> bool
|
LogicalFEqual, /// (float a, float b) -> bool
|
||||||
|
@ -145,12 +147,12 @@ enum class OperationCode {
|
||||||
LogicalUNotEqual, /// (uint a, uint b) -> bool
|
LogicalUNotEqual, /// (uint a, uint b) -> bool
|
||||||
LogicalUGreaterEqual, /// (uint a, uint b) -> bool
|
LogicalUGreaterEqual, /// (uint a, uint b) -> bool
|
||||||
|
|
||||||
LogicalHLessThan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool
|
Logical2HLessThan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
|
||||||
LogicalHEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool
|
Logical2HEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
|
||||||
LogicalHLessEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool
|
Logical2HLessEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
|
||||||
LogicalHGreaterThan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool
|
Logical2HGreaterThan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
|
||||||
LogicalHNotEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool
|
Logical2HNotEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
|
||||||
LogicalHGreaterEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool
|
Logical2HGreaterEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
|
||||||
|
|
||||||
F4Texture, /// (MetaTexture, float[N] coords, float[M] params) -> float4
|
F4Texture, /// (MetaTexture, float[N] coords, float[M] params) -> float4
|
||||||
F4TextureLod, /// (MetaTexture, float[N] coords, float[M] params) -> float4
|
F4TextureLod, /// (MetaTexture, float[N] coords, float[M] params) -> float4
|
||||||
|
@ -263,7 +265,6 @@ struct MetaHalfArithmetic {
|
||||||
std::array<Tegra::Shader::HalfType, 3> types = {Tegra::Shader::HalfType::H0_H1,
|
std::array<Tegra::Shader::HalfType, 3> types = {Tegra::Shader::HalfType::H0_H1,
|
||||||
Tegra::Shader::HalfType::H0_H1,
|
Tegra::Shader::HalfType::H0_H1,
|
||||||
Tegra::Shader::HalfType::H0_H1};
|
Tegra::Shader::HalfType::H0_H1};
|
||||||
bool and_comparison{};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MetaTexture {
|
struct MetaTexture {
|
||||||
|
|
Loading…
Reference in a new issue