mirror of
https://github.com/yuzu-emu/yuzu-android.git
synced 2025-06-18 02:48:00 -05:00
Merge pull request #3109 from FernandoS27/new-instr
Implement FLO & TXD Instructions on GPU Shaders
This commit is contained in:
@ -130,6 +130,25 @@ u32 ShaderIR::DecodeArithmeticInteger(NodeBlock& bb, u32 pc) {
|
||||
SetRegister(bb, instr.gpr0, value);
|
||||
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_R:
|
||||
case OpCode::Id::SEL_IMM: {
|
||||
|
@ -134,13 +134,52 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
|
||||
Node4 values;
|
||||
for (u32 element = 0; element < values.size(); ++element) {
|
||||
auto coords_copy = coords;
|
||||
MetaTexture meta{sampler, {}, {}, {}, {}, {}, component, element};
|
||||
MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, component, element};
|
||||
values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));
|
||||
}
|
||||
|
||||
WriteTexsInstructionFloat(bb, instr, values, true);
|
||||
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:
|
||||
is_bindless = true;
|
||||
[[fallthrough]];
|
||||
@ -158,7 +197,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
|
||||
if (!instr.txq.IsComponentEnabled(element)) {
|
||||
continue;
|
||||
}
|
||||
MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, element};
|
||||
MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, {}, element};
|
||||
const Node value =
|
||||
Operation(OperationCode::TextureQueryDimensions, meta,
|
||||
GetRegister(instr.gpr8.Value() + (is_bindless ? 1 : 0)));
|
||||
@ -212,7 +251,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
|
||||
continue;
|
||||
}
|
||||
auto params = coords;
|
||||
MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, element};
|
||||
MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, {}, element};
|
||||
const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params));
|
||||
SetTemporary(bb, indexer++, value);
|
||||
}
|
||||
@ -442,7 +481,7 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,
|
||||
Node4 values;
|
||||
for (u32 element = 0; element < values.size(); ++element) {
|
||||
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));
|
||||
}
|
||||
|
||||
@ -574,7 +613,7 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de
|
||||
Node4 values;
|
||||
for (u32 element = 0; element < values.size(); ++element) {
|
||||
auto coords_copy = coords;
|
||||
MetaTexture meta{sampler, GetRegister(array_register), dc, aoffi, {}, {}, component,
|
||||
MetaTexture meta{sampler, GetRegister(array_register), dc, aoffi, {}, {}, {}, component,
|
||||
element};
|
||||
values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));
|
||||
}
|
||||
@ -608,7 +647,7 @@ Node4 ShaderIR::GetTldCode(Tegra::Shader::Instruction instr) {
|
||||
Node4 values;
|
||||
for (u32 element = 0; element < values.size(); ++element) {
|
||||
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));
|
||||
}
|
||||
|
||||
@ -653,7 +692,7 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is
|
||||
Node4 values;
|
||||
for (u32 element = 0; element < values.size(); ++element) {
|
||||
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));
|
||||
}
|
||||
return values;
|
||||
|
@ -68,6 +68,7 @@ enum class OperationCode {
|
||||
IBitfieldInsert, /// (MetaArithmetic, int base, int insert, int offset, int bits) -> int
|
||||
IBitfieldExtract, /// (MetaArithmetic, int value, int offset, int offset) -> int
|
||||
IBitCount, /// (MetaArithmetic, int) -> int
|
||||
IBitMSB, /// (MetaArithmetic, int) -> int
|
||||
|
||||
UAdd, /// (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
|
||||
UBitfieldExtract, /// (MetaArithmetic, uint value, int offset, int offset) -> uint
|
||||
UBitCount, /// (MetaArithmetic, uint) -> uint
|
||||
UBitMSB, /// (MetaArithmetic, uint) -> uint
|
||||
|
||||
HAdd, /// (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
|
||||
TextureQueryLod, /// (MetaTexture, float[N] coords) -> float4
|
||||
TexelFetch, /// (MetaTexture, int[N], int) -> float4
|
||||
TextureGradient, /// (MetaTexture, float[N] coords, float[N*2] derivates) -> float4
|
||||
|
||||
ImageLoad, /// (MetaImage, int[N] coords) -> void
|
||||
ImageStore, /// (MetaImage, int[N] coords) -> void
|
||||
@ -367,6 +370,7 @@ struct MetaTexture {
|
||||
Node array;
|
||||
Node depth_compare;
|
||||
std::vector<Node> aoffi;
|
||||
std::vector<Node> derivates;
|
||||
Node bias;
|
||||
Node lod;
|
||||
Node component{};
|
||||
|
Reference in New Issue
Block a user