mirror of
https://github.com/yuzu-emu/yuzu.git
synced 2024-08-23 21:07:19 +02:00
Merge pull request #3109 from FernandoS27/new-instr
Implement FLO & TXD Instructions on GPU Shaders
This commit is contained in:
commit
e36814d6d5
@ -799,6 +799,12 @@ union Instruction {
|
|||||||
BitField<40, 1, u64> invert;
|
BitField<40, 1, u64> invert;
|
||||||
} popc;
|
} popc;
|
||||||
|
|
||||||
|
union {
|
||||||
|
BitField<41, 1, u64> sh;
|
||||||
|
BitField<40, 1, u64> invert;
|
||||||
|
BitField<48, 1, u64> is_signed;
|
||||||
|
} flo;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
BitField<39, 3, u64> pred;
|
BitField<39, 3, u64> pred;
|
||||||
BitField<42, 1, u64> neg_pred;
|
BitField<42, 1, u64> neg_pred;
|
||||||
@ -1439,6 +1445,26 @@ union Instruction {
|
|||||||
}
|
}
|
||||||
} tlds;
|
} tlds;
|
||||||
|
|
||||||
|
union {
|
||||||
|
BitField<28, 1, u64> is_array;
|
||||||
|
BitField<29, 2, TextureType> texture_type;
|
||||||
|
BitField<35, 1, u64> aoffi_flag;
|
||||||
|
BitField<49, 1, u64> nodep_flag;
|
||||||
|
|
||||||
|
bool UsesMiscMode(TextureMiscMode mode) const {
|
||||||
|
switch (mode) {
|
||||||
|
case TextureMiscMode::AOFFI:
|
||||||
|
return aoffi_flag != 0;
|
||||||
|
case TextureMiscMode::NODEP:
|
||||||
|
return nodep_flag != 0;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} txd;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
BitField<24, 2, StoreCacheManagement> cache_management;
|
BitField<24, 2, StoreCacheManagement> cache_management;
|
||||||
BitField<33, 3, ImageType> image_type;
|
BitField<33, 3, ImageType> image_type;
|
||||||
@ -1632,6 +1658,8 @@ public:
|
|||||||
TLD4S, // Texture Load 4 with scalar / non - vec4 source / destinations
|
TLD4S, // Texture Load 4 with scalar / non - vec4 source / destinations
|
||||||
TMML_B, // Texture Mip Map Level
|
TMML_B, // Texture Mip Map Level
|
||||||
TMML, // Texture Mip Map Level
|
TMML, // Texture Mip Map Level
|
||||||
|
TXD, // Texture Gradient/Load with Derivates
|
||||||
|
TXD_B, // Texture Gradient/Load with Derivates Bindless
|
||||||
SUST, // Surface Store
|
SUST, // Surface Store
|
||||||
SULD, // Surface Load
|
SULD, // Surface Load
|
||||||
SUATOM, // Surface Atomic Operation
|
SUATOM, // Surface Atomic Operation
|
||||||
@ -1664,6 +1692,9 @@ public:
|
|||||||
ISCADD_C, // Scale and Add
|
ISCADD_C, // Scale and Add
|
||||||
ISCADD_R,
|
ISCADD_R,
|
||||||
ISCADD_IMM,
|
ISCADD_IMM,
|
||||||
|
FLO_R,
|
||||||
|
FLO_C,
|
||||||
|
FLO_IMM,
|
||||||
LEA_R1,
|
LEA_R1,
|
||||||
LEA_R2,
|
LEA_R2,
|
||||||
LEA_RZ,
|
LEA_RZ,
|
||||||
@ -1727,6 +1758,10 @@ public:
|
|||||||
SHR_C,
|
SHR_C,
|
||||||
SHR_R,
|
SHR_R,
|
||||||
SHR_IMM,
|
SHR_IMM,
|
||||||
|
SHF_RIGHT_R,
|
||||||
|
SHF_RIGHT_IMM,
|
||||||
|
SHF_LEFT_R,
|
||||||
|
SHF_LEFT_IMM,
|
||||||
FMNMX_C,
|
FMNMX_C,
|
||||||
FMNMX_R,
|
FMNMX_R,
|
||||||
FMNMX_IMM,
|
FMNMX_IMM,
|
||||||
@ -1924,6 +1959,8 @@ private:
|
|||||||
INST("1101111100------", Id::TLD4S, Type::Texture, "TLD4S"),
|
INST("1101111100------", Id::TLD4S, Type::Texture, "TLD4S"),
|
||||||
INST("110111110110----", Id::TMML_B, Type::Texture, "TMML_B"),
|
INST("110111110110----", Id::TMML_B, Type::Texture, "TMML_B"),
|
||||||
INST("1101111101011---", Id::TMML, Type::Texture, "TMML"),
|
INST("1101111101011---", Id::TMML, Type::Texture, "TMML"),
|
||||||
|
INST("11011110011110--", Id::TXD_B, Type::Texture, "TXD_B"),
|
||||||
|
INST("11011110001110--", Id::TXD, Type::Texture, "TXD"),
|
||||||
INST("11101011001-----", Id::SUST, Type::Image, "SUST"),
|
INST("11101011001-----", Id::SUST, Type::Image, "SUST"),
|
||||||
INST("11101011000-----", Id::SULD, Type::Image, "SULD"),
|
INST("11101011000-----", Id::SULD, Type::Image, "SULD"),
|
||||||
INST("1110101000------", Id::SUATOM, Type::Image, "SUATOM_D"),
|
INST("1110101000------", Id::SUATOM, Type::Image, "SUATOM_D"),
|
||||||
@ -1965,6 +2002,9 @@ private:
|
|||||||
INST("010110110100----", Id::ICMP_R, Type::ArithmeticInteger, "ICMP_R"),
|
INST("010110110100----", Id::ICMP_R, Type::ArithmeticInteger, "ICMP_R"),
|
||||||
INST("010010110100----", Id::ICMP_CR, Type::ArithmeticInteger, "ICMP_CR"),
|
INST("010010110100----", Id::ICMP_CR, Type::ArithmeticInteger, "ICMP_CR"),
|
||||||
INST("0011011-0100----", Id::ICMP_IMM, Type::ArithmeticInteger, "ICMP_IMM"),
|
INST("0011011-0100----", Id::ICMP_IMM, Type::ArithmeticInteger, "ICMP_IMM"),
|
||||||
|
INST("0101110000110---", Id::FLO_R, Type::ArithmeticInteger, "FLO_R"),
|
||||||
|
INST("0100110000110---", Id::FLO_C, Type::ArithmeticInteger, "FLO_C"),
|
||||||
|
INST("0011100-00110---", Id::FLO_IMM, Type::ArithmeticInteger, "FLO_IMM"),
|
||||||
INST("0101101111011---", Id::LEA_R2, Type::ArithmeticInteger, "LEA_R2"),
|
INST("0101101111011---", Id::LEA_R2, Type::ArithmeticInteger, "LEA_R2"),
|
||||||
INST("0101101111010---", Id::LEA_R1, Type::ArithmeticInteger, "LEA_R1"),
|
INST("0101101111010---", Id::LEA_R1, Type::ArithmeticInteger, "LEA_R1"),
|
||||||
INST("001101101101----", Id::LEA_IMM, Type::ArithmeticInteger, "LEA_IMM"),
|
INST("001101101101----", Id::LEA_IMM, Type::ArithmeticInteger, "LEA_IMM"),
|
||||||
@ -2022,6 +2062,10 @@ private:
|
|||||||
INST("0100110000101---", Id::SHR_C, Type::Shift, "SHR_C"),
|
INST("0100110000101---", Id::SHR_C, Type::Shift, "SHR_C"),
|
||||||
INST("0101110000101---", Id::SHR_R, Type::Shift, "SHR_R"),
|
INST("0101110000101---", Id::SHR_R, Type::Shift, "SHR_R"),
|
||||||
INST("0011100-00101---", Id::SHR_IMM, Type::Shift, "SHR_IMM"),
|
INST("0011100-00101---", Id::SHR_IMM, Type::Shift, "SHR_IMM"),
|
||||||
|
INST("0101110011111---", Id::SHF_RIGHT_R, Type::Shift, "SHF_RIGHT_R"),
|
||||||
|
INST("0011100-11111---", Id::SHF_RIGHT_IMM, Type::Shift, "SHF_RIGHT_IMM"),
|
||||||
|
INST("0101101111111---", Id::SHF_LEFT_R, Type::Shift, "SHF_LEFT_R"),
|
||||||
|
INST("0011011-11111---", Id::SHF_LEFT_IMM, Type::Shift, "SHF_LEFT_IMM"),
|
||||||
INST("0100110011100---", Id::I2I_C, Type::Conversion, "I2I_C"),
|
INST("0100110011100---", Id::I2I_C, Type::Conversion, "I2I_C"),
|
||||||
INST("0101110011100---", Id::I2I_R, Type::Conversion, "I2I_R"),
|
INST("0101110011100---", Id::I2I_R, Type::Conversion, "I2I_R"),
|
||||||
INST("0011101-11100---", Id::I2I_IMM, Type::Conversion, "I2I_IMM"),
|
INST("0011101-11100---", Id::I2I_IMM, Type::Conversion, "I2I_IMM"),
|
||||||
|
@ -49,8 +49,9 @@ class ExprDecompiler;
|
|||||||
enum class Type { Void, Bool, Bool2, Float, Int, Uint, HalfFloat };
|
enum class Type { Void, Bool, Bool2, Float, Int, Uint, HalfFloat };
|
||||||
|
|
||||||
struct TextureAoffi {};
|
struct TextureAoffi {};
|
||||||
|
struct TextureDerivates {};
|
||||||
using TextureArgument = std::pair<Type, Node>;
|
using TextureArgument = std::pair<Type, Node>;
|
||||||
using TextureIR = std::variant<TextureAoffi, TextureArgument>;
|
using TextureIR = std::variant<TextureAoffi, TextureDerivates, TextureArgument>;
|
||||||
|
|
||||||
constexpr u32 MAX_CONSTBUFFER_ELEMENTS =
|
constexpr u32 MAX_CONSTBUFFER_ELEMENTS =
|
||||||
static_cast<u32>(Maxwell::MaxConstBufferSize) / (4 * sizeof(float));
|
static_cast<u32>(Maxwell::MaxConstBufferSize) / (4 * sizeof(float));
|
||||||
@ -1112,6 +1113,8 @@ private:
|
|||||||
expr += GenerateTextureArgument(*argument);
|
expr += GenerateTextureArgument(*argument);
|
||||||
} else if (std::holds_alternative<TextureAoffi>(variant)) {
|
} else if (std::holds_alternative<TextureAoffi>(variant)) {
|
||||||
expr += GenerateTextureAoffi(meta->aoffi);
|
expr += GenerateTextureAoffi(meta->aoffi);
|
||||||
|
} else if (std::holds_alternative<TextureDerivates>(variant)) {
|
||||||
|
expr += GenerateTextureDerivates(meta->derivates);
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
@ -1181,6 +1184,36 @@ private:
|
|||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string GenerateTextureDerivates(const std::vector<Node>& derivates) {
|
||||||
|
if (derivates.empty()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
constexpr std::array coord_constructors = {"float", "vec2", "vec3"};
|
||||||
|
std::string expr = ", ";
|
||||||
|
const std::size_t components = derivates.size() / 2;
|
||||||
|
std::string dx = coord_constructors.at(components - 1);
|
||||||
|
std::string dy = coord_constructors.at(components - 1);
|
||||||
|
dx += '(';
|
||||||
|
dy += '(';
|
||||||
|
|
||||||
|
for (std::size_t index = 0; index < components; ++index) {
|
||||||
|
const auto operand_x{derivates.at(index * 2)};
|
||||||
|
const auto operand_y{derivates.at(index * 2 + 1)};
|
||||||
|
dx += Visit(operand_x).AsFloat();
|
||||||
|
dy += Visit(operand_y).AsFloat();
|
||||||
|
|
||||||
|
if (index + 1 < components) {
|
||||||
|
dx += ", ";
|
||||||
|
dy += ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dx += ')';
|
||||||
|
dy += ')';
|
||||||
|
expr += dx + ", " + dy;
|
||||||
|
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
std::string BuildIntegerCoordinates(Operation operation) {
|
std::string BuildIntegerCoordinates(Operation operation) {
|
||||||
constexpr std::array constructors{"int(", "ivec2(", "ivec3(", "ivec4("};
|
constexpr std::array constructors{"int(", "ivec2(", "ivec3(", "ivec4("};
|
||||||
const std::size_t coords_count{operation.GetOperandsCount()};
|
const std::size_t coords_count{operation.GetOperandsCount()};
|
||||||
@ -1450,6 +1483,11 @@ private:
|
|||||||
return GenerateUnary(operation, "bitCount", type, type);
|
return GenerateUnary(operation, "bitCount", type, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <Type type>
|
||||||
|
Expression BitMSB(Operation operation) {
|
||||||
|
return GenerateUnary(operation, "findMSB", type, type);
|
||||||
|
}
|
||||||
|
|
||||||
Expression HNegate(Operation operation) {
|
Expression HNegate(Operation operation) {
|
||||||
const auto GetNegate = [&](std::size_t index) {
|
const auto GetNegate = [&](std::size_t index) {
|
||||||
return VisitOperand(operation, index).AsBool() + " ? -1 : 1";
|
return VisitOperand(operation, index).AsBool() + " ? -1 : 1";
|
||||||
@ -1738,6 +1776,14 @@ private:
|
|||||||
return {std::move(expr), Type::Float};
|
return {std::move(expr), Type::Float};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Expression TextureGradient(Operation operation) {
|
||||||
|
const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
|
||||||
|
ASSERT(meta);
|
||||||
|
|
||||||
|
std::string expr = GenerateTexture(operation, "Grad", {TextureDerivates{}, TextureAoffi{}});
|
||||||
|
return {std::move(expr) + GetSwizzle(meta->element), Type::Float};
|
||||||
|
}
|
||||||
|
|
||||||
Expression ImageLoad(Operation operation) {
|
Expression ImageLoad(Operation operation) {
|
||||||
if (!device.HasImageLoadFormatted()) {
|
if (!device.HasImageLoadFormatted()) {
|
||||||
LOG_ERROR(Render_OpenGL,
|
LOG_ERROR(Render_OpenGL,
|
||||||
@ -2003,6 +2049,7 @@ private:
|
|||||||
&GLSLDecompiler::BitfieldInsert<Type::Int>,
|
&GLSLDecompiler::BitfieldInsert<Type::Int>,
|
||||||
&GLSLDecompiler::BitfieldExtract<Type::Int>,
|
&GLSLDecompiler::BitfieldExtract<Type::Int>,
|
||||||
&GLSLDecompiler::BitCount<Type::Int>,
|
&GLSLDecompiler::BitCount<Type::Int>,
|
||||||
|
&GLSLDecompiler::BitMSB<Type::Int>,
|
||||||
|
|
||||||
&GLSLDecompiler::Add<Type::Uint>,
|
&GLSLDecompiler::Add<Type::Uint>,
|
||||||
&GLSLDecompiler::Mul<Type::Uint>,
|
&GLSLDecompiler::Mul<Type::Uint>,
|
||||||
@ -2021,6 +2068,7 @@ private:
|
|||||||
&GLSLDecompiler::BitfieldInsert<Type::Uint>,
|
&GLSLDecompiler::BitfieldInsert<Type::Uint>,
|
||||||
&GLSLDecompiler::BitfieldExtract<Type::Uint>,
|
&GLSLDecompiler::BitfieldExtract<Type::Uint>,
|
||||||
&GLSLDecompiler::BitCount<Type::Uint>,
|
&GLSLDecompiler::BitCount<Type::Uint>,
|
||||||
|
&GLSLDecompiler::BitMSB<Type::Uint>,
|
||||||
|
|
||||||
&GLSLDecompiler::Add<Type::HalfFloat>,
|
&GLSLDecompiler::Add<Type::HalfFloat>,
|
||||||
&GLSLDecompiler::Mul<Type::HalfFloat>,
|
&GLSLDecompiler::Mul<Type::HalfFloat>,
|
||||||
@ -2084,6 +2132,7 @@ private:
|
|||||||
&GLSLDecompiler::TextureQueryDimensions,
|
&GLSLDecompiler::TextureQueryDimensions,
|
||||||
&GLSLDecompiler::TextureQueryLod,
|
&GLSLDecompiler::TextureQueryLod,
|
||||||
&GLSLDecompiler::TexelFetch,
|
&GLSLDecompiler::TexelFetch,
|
||||||
|
&GLSLDecompiler::TextureGradient,
|
||||||
|
|
||||||
&GLSLDecompiler::ImageLoad,
|
&GLSLDecompiler::ImageLoad,
|
||||||
&GLSLDecompiler::ImageStore,
|
&GLSLDecompiler::ImageStore,
|
||||||
|
@ -983,6 +983,11 @@ private:
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Id TextureGradient(Operation operation) {
|
||||||
|
UNIMPLEMENTED();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
Id ImageLoad(Operation operation) {
|
Id ImageLoad(Operation operation) {
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
return {};
|
return {};
|
||||||
@ -1391,6 +1396,7 @@ private:
|
|||||||
&SPIRVDecompiler::Quaternary<&Module::OpBitFieldInsert, Type::Int>,
|
&SPIRVDecompiler::Quaternary<&Module::OpBitFieldInsert, Type::Int>,
|
||||||
&SPIRVDecompiler::Ternary<&Module::OpBitFieldSExtract, Type::Int>,
|
&SPIRVDecompiler::Ternary<&Module::OpBitFieldSExtract, Type::Int>,
|
||||||
&SPIRVDecompiler::Unary<&Module::OpBitCount, Type::Int>,
|
&SPIRVDecompiler::Unary<&Module::OpBitCount, Type::Int>,
|
||||||
|
&SPIRVDecompiler::Unary<&Module::OpFindSMsb, Type::Int>,
|
||||||
|
|
||||||
&SPIRVDecompiler::Binary<&Module::OpIAdd, Type::Uint>,
|
&SPIRVDecompiler::Binary<&Module::OpIAdd, Type::Uint>,
|
||||||
&SPIRVDecompiler::Binary<&Module::OpIMul, Type::Uint>,
|
&SPIRVDecompiler::Binary<&Module::OpIMul, Type::Uint>,
|
||||||
@ -1409,6 +1415,7 @@ private:
|
|||||||
&SPIRVDecompiler::Quaternary<&Module::OpBitFieldInsert, Type::Uint>,
|
&SPIRVDecompiler::Quaternary<&Module::OpBitFieldInsert, Type::Uint>,
|
||||||
&SPIRVDecompiler::Ternary<&Module::OpBitFieldUExtract, Type::Uint>,
|
&SPIRVDecompiler::Ternary<&Module::OpBitFieldUExtract, Type::Uint>,
|
||||||
&SPIRVDecompiler::Unary<&Module::OpBitCount, Type::Uint>,
|
&SPIRVDecompiler::Unary<&Module::OpBitCount, Type::Uint>,
|
||||||
|
&SPIRVDecompiler::Unary<&Module::OpFindUMsb, Type::Uint>,
|
||||||
|
|
||||||
&SPIRVDecompiler::Binary<&Module::OpFAdd, Type::HalfFloat>,
|
&SPIRVDecompiler::Binary<&Module::OpFAdd, Type::HalfFloat>,
|
||||||
&SPIRVDecompiler::Binary<&Module::OpFMul, Type::HalfFloat>,
|
&SPIRVDecompiler::Binary<&Module::OpFMul, Type::HalfFloat>,
|
||||||
@ -1473,6 +1480,7 @@ private:
|
|||||||
&SPIRVDecompiler::TextureQueryDimensions,
|
&SPIRVDecompiler::TextureQueryDimensions,
|
||||||
&SPIRVDecompiler::TextureQueryLod,
|
&SPIRVDecompiler::TextureQueryLod,
|
||||||
&SPIRVDecompiler::TexelFetch,
|
&SPIRVDecompiler::TexelFetch,
|
||||||
|
&SPIRVDecompiler::TextureGradient,
|
||||||
|
|
||||||
&SPIRVDecompiler::ImageLoad,
|
&SPIRVDecompiler::ImageLoad,
|
||||||
&SPIRVDecompiler::ImageStore,
|
&SPIRVDecompiler::ImageStore,
|
||||||
|
@ -130,6 +130,25 @@ u32 ShaderIR::DecodeArithmeticInteger(NodeBlock& bb, u32 pc) {
|
|||||||
SetRegister(bb, instr.gpr0, value);
|
SetRegister(bb, instr.gpr0, value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case OpCode::Id::FLO_R:
|
||||||
|
case OpCode::Id::FLO_C:
|
||||||
|
case OpCode::Id::FLO_IMM: {
|
||||||
|
Node value;
|
||||||
|
if (instr.flo.invert) {
|
||||||
|
op_b = Operation(OperationCode::IBitwiseNot, NO_PRECISE, std::move(op_b));
|
||||||
|
}
|
||||||
|
if (instr.flo.is_signed) {
|
||||||
|
value = Operation(OperationCode::IBitMSB, NO_PRECISE, std::move(op_b));
|
||||||
|
} else {
|
||||||
|
value = Operation(OperationCode::UBitMSB, NO_PRECISE, std::move(op_b));
|
||||||
|
}
|
||||||
|
if (instr.flo.sh) {
|
||||||
|
value =
|
||||||
|
Operation(OperationCode::UBitwiseXor, NO_PRECISE, std::move(value), Immediate(31));
|
||||||
|
}
|
||||||
|
SetRegister(bb, instr.gpr0, std::move(value));
|
||||||
|
break;
|
||||||
|
}
|
||||||
case OpCode::Id::SEL_C:
|
case OpCode::Id::SEL_C:
|
||||||
case OpCode::Id::SEL_R:
|
case OpCode::Id::SEL_R:
|
||||||
case OpCode::Id::SEL_IMM: {
|
case OpCode::Id::SEL_IMM: {
|
||||||
|
@ -134,13 +134,52 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
|
|||||||
Node4 values;
|
Node4 values;
|
||||||
for (u32 element = 0; element < values.size(); ++element) {
|
for (u32 element = 0; element < values.size(); ++element) {
|
||||||
auto coords_copy = coords;
|
auto coords_copy = coords;
|
||||||
MetaTexture meta{sampler, {}, {}, {}, {}, {}, component, element};
|
MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, component, element};
|
||||||
values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));
|
values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteTexsInstructionFloat(bb, instr, values, true);
|
WriteTexsInstructionFloat(bb, instr, values, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case OpCode::Id::TXD_B:
|
||||||
|
is_bindless = true;
|
||||||
|
[[fallthrough]];
|
||||||
|
case OpCode::Id::TXD: {
|
||||||
|
UNIMPLEMENTED_IF_MSG(instr.txd.UsesMiscMode(TextureMiscMode::AOFFI),
|
||||||
|
"AOFFI is not implemented");
|
||||||
|
UNIMPLEMENTED_IF_MSG(instr.txd.is_array != 0, "TXD Array is not implemented");
|
||||||
|
|
||||||
|
u64 base_reg = instr.gpr8.Value();
|
||||||
|
const auto derivate_reg = instr.gpr20.Value();
|
||||||
|
const auto texture_type = instr.txd.texture_type.Value();
|
||||||
|
const auto coord_count = GetCoordCount(texture_type);
|
||||||
|
|
||||||
|
const auto& sampler = is_bindless
|
||||||
|
? GetBindlessSampler(base_reg, {{texture_type, false, false}})
|
||||||
|
: GetSampler(instr.sampler, {{texture_type, false, false}});
|
||||||
|
if (is_bindless) {
|
||||||
|
base_reg++;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Node> coords;
|
||||||
|
std::vector<Node> derivates;
|
||||||
|
for (std::size_t i = 0; i < coord_count; ++i) {
|
||||||
|
coords.push_back(GetRegister(base_reg + i));
|
||||||
|
const std::size_t derivate = i * 2;
|
||||||
|
derivates.push_back(GetRegister(derivate_reg + derivate));
|
||||||
|
derivates.push_back(GetRegister(derivate_reg + derivate + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
Node4 values;
|
||||||
|
for (u32 element = 0; element < values.size(); ++element) {
|
||||||
|
MetaTexture meta{sampler, {}, {}, {}, derivates, {}, {}, {}, element};
|
||||||
|
values[element] = Operation(OperationCode::TextureGradient, std::move(meta), coords);
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteTexInstructionFloat(bb, instr, values);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case OpCode::Id::TXQ_B:
|
case OpCode::Id::TXQ_B:
|
||||||
is_bindless = true;
|
is_bindless = true;
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
@ -158,7 +197,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
|
|||||||
if (!instr.txq.IsComponentEnabled(element)) {
|
if (!instr.txq.IsComponentEnabled(element)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, element};
|
MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, {}, element};
|
||||||
const Node value =
|
const Node value =
|
||||||
Operation(OperationCode::TextureQueryDimensions, meta,
|
Operation(OperationCode::TextureQueryDimensions, meta,
|
||||||
GetRegister(instr.gpr8.Value() + (is_bindless ? 1 : 0)));
|
GetRegister(instr.gpr8.Value() + (is_bindless ? 1 : 0)));
|
||||||
@ -212,7 +251,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto params = coords;
|
auto params = coords;
|
||||||
MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, element};
|
MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, {}, element};
|
||||||
const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params));
|
const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params));
|
||||||
SetTemporary(bb, indexer++, value);
|
SetTemporary(bb, indexer++, value);
|
||||||
}
|
}
|
||||||
@ -442,7 +481,7 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,
|
|||||||
Node4 values;
|
Node4 values;
|
||||||
for (u32 element = 0; element < values.size(); ++element) {
|
for (u32 element = 0; element < values.size(); ++element) {
|
||||||
auto copy_coords = coords;
|
auto copy_coords = coords;
|
||||||
MetaTexture meta{sampler, array, depth_compare, aoffi, bias, lod, {}, element};
|
MetaTexture meta{sampler, array, depth_compare, aoffi, {}, bias, lod, {}, element};
|
||||||
values[element] = Operation(read_method, meta, std::move(copy_coords));
|
values[element] = Operation(read_method, meta, std::move(copy_coords));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -574,7 +613,7 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de
|
|||||||
Node4 values;
|
Node4 values;
|
||||||
for (u32 element = 0; element < values.size(); ++element) {
|
for (u32 element = 0; element < values.size(); ++element) {
|
||||||
auto coords_copy = coords;
|
auto coords_copy = coords;
|
||||||
MetaTexture meta{sampler, GetRegister(array_register), dc, aoffi, {}, {}, component,
|
MetaTexture meta{sampler, GetRegister(array_register), dc, aoffi, {}, {}, {}, component,
|
||||||
element};
|
element};
|
||||||
values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));
|
values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));
|
||||||
}
|
}
|
||||||
@ -608,7 +647,7 @@ Node4 ShaderIR::GetTldCode(Tegra::Shader::Instruction instr) {
|
|||||||
Node4 values;
|
Node4 values;
|
||||||
for (u32 element = 0; element < values.size(); ++element) {
|
for (u32 element = 0; element < values.size(); ++element) {
|
||||||
auto coords_copy = coords;
|
auto coords_copy = coords;
|
||||||
MetaTexture meta{sampler, array_register, {}, {}, {}, lod, {}, element};
|
MetaTexture meta{sampler, array_register, {}, {}, {}, {}, lod, {}, element};
|
||||||
values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy));
|
values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,7 +692,7 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is
|
|||||||
Node4 values;
|
Node4 values;
|
||||||
for (u32 element = 0; element < values.size(); ++element) {
|
for (u32 element = 0; element < values.size(); ++element) {
|
||||||
auto coords_copy = coords;
|
auto coords_copy = coords;
|
||||||
MetaTexture meta{sampler, array, {}, {}, {}, lod, {}, element};
|
MetaTexture meta{sampler, array, {}, {}, {}, {}, lod, {}, element};
|
||||||
values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy));
|
values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy));
|
||||||
}
|
}
|
||||||
return values;
|
return values;
|
||||||
|
@ -68,6 +68,7 @@ enum class OperationCode {
|
|||||||
IBitfieldInsert, /// (MetaArithmetic, int base, int insert, int offset, int bits) -> int
|
IBitfieldInsert, /// (MetaArithmetic, int base, int insert, int offset, int bits) -> int
|
||||||
IBitfieldExtract, /// (MetaArithmetic, int value, int offset, int offset) -> int
|
IBitfieldExtract, /// (MetaArithmetic, int value, int offset, int offset) -> int
|
||||||
IBitCount, /// (MetaArithmetic, int) -> int
|
IBitCount, /// (MetaArithmetic, int) -> int
|
||||||
|
IBitMSB, /// (MetaArithmetic, int) -> int
|
||||||
|
|
||||||
UAdd, /// (MetaArithmetic, uint a, uint b) -> uint
|
UAdd, /// (MetaArithmetic, uint a, uint b) -> uint
|
||||||
UMul, /// (MetaArithmetic, uint a, uint b) -> uint
|
UMul, /// (MetaArithmetic, uint a, uint b) -> uint
|
||||||
@ -86,6 +87,7 @@ enum class OperationCode {
|
|||||||
UBitfieldInsert, /// (MetaArithmetic, uint base, uint insert, int offset, int bits) -> uint
|
UBitfieldInsert, /// (MetaArithmetic, uint base, uint insert, int offset, int bits) -> uint
|
||||||
UBitfieldExtract, /// (MetaArithmetic, uint value, int offset, int offset) -> uint
|
UBitfieldExtract, /// (MetaArithmetic, uint value, int offset, int offset) -> uint
|
||||||
UBitCount, /// (MetaArithmetic, uint) -> uint
|
UBitCount, /// (MetaArithmetic, uint) -> uint
|
||||||
|
UBitMSB, /// (MetaArithmetic, uint) -> uint
|
||||||
|
|
||||||
HAdd, /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2
|
HAdd, /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2
|
||||||
HMul, /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2
|
HMul, /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2
|
||||||
@ -149,6 +151,7 @@ enum class OperationCode {
|
|||||||
TextureQueryDimensions, /// (MetaTexture, float a) -> float4
|
TextureQueryDimensions, /// (MetaTexture, float a) -> float4
|
||||||
TextureQueryLod, /// (MetaTexture, float[N] coords) -> float4
|
TextureQueryLod, /// (MetaTexture, float[N] coords) -> float4
|
||||||
TexelFetch, /// (MetaTexture, int[N], int) -> float4
|
TexelFetch, /// (MetaTexture, int[N], int) -> float4
|
||||||
|
TextureGradient, /// (MetaTexture, float[N] coords, float[N*2] derivates) -> float4
|
||||||
|
|
||||||
ImageLoad, /// (MetaImage, int[N] coords) -> void
|
ImageLoad, /// (MetaImage, int[N] coords) -> void
|
||||||
ImageStore, /// (MetaImage, int[N] coords) -> void
|
ImageStore, /// (MetaImage, int[N] coords) -> void
|
||||||
@ -367,6 +370,7 @@ struct MetaTexture {
|
|||||||
Node array;
|
Node array;
|
||||||
Node depth_compare;
|
Node depth_compare;
|
||||||
std::vector<Node> aoffi;
|
std::vector<Node> aoffi;
|
||||||
|
std::vector<Node> derivates;
|
||||||
Node bias;
|
Node bias;
|
||||||
Node lod;
|
Node lod;
|
||||||
Node component{};
|
Node component{};
|
||||||
|
Loading…
Reference in New Issue
Block a user