mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-01 15:02:40 +00:00
spirv: fix image sample offsets
This commit is contained in:
parent
c7286d7889
commit
97a555b736
@ -135,8 +135,8 @@ void Translator::IMAGE_SAMPLE(const GcnInst& inst) {
|
|||||||
|
|
||||||
// Load first address components as denoted in 8.2.4 VGPR Usage Sea Islands Series Instruction
|
// Load first address components as denoted in 8.2.4 VGPR Usage Sea Islands Series Instruction
|
||||||
// Set Architecture
|
// Set Architecture
|
||||||
const IR::Value offset =
|
const IR::U32 offset =
|
||||||
flags.test(MimgModifier::Offset) ? ir.GetVectorReg(addr_reg++) : IR::Value{};
|
flags.test(MimgModifier::Offset) ? ir.GetVectorReg<IR::U32>(addr_reg++) : IR::U32{};
|
||||||
const IR::F32 bias =
|
const IR::F32 bias =
|
||||||
flags.test(MimgModifier::LodBias) ? ir.GetVectorReg<IR::F32>(addr_reg++) : IR::F32{};
|
flags.test(MimgModifier::LodBias) ? ir.GetVectorReg<IR::F32>(addr_reg++) : IR::F32{};
|
||||||
const IR::F32 dref =
|
const IR::F32 dref =
|
||||||
|
@ -1375,24 +1375,24 @@ Value IREmitter::ImageAtomicExchange(const Value& handle, const Value& coords, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
Value IREmitter::ImageSampleImplicitLod(const Value& handle, const Value& body, const F32& bias,
|
Value IREmitter::ImageSampleImplicitLod(const Value& handle, const Value& body, const F32& bias,
|
||||||
const Value& offset, TextureInstInfo info) {
|
const U32& offset, TextureInstInfo info) {
|
||||||
return Inst(Opcode::ImageSampleImplicitLod, Flags{info}, handle, body, bias, offset);
|
return Inst(Opcode::ImageSampleImplicitLod, Flags{info}, handle, body, bias, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value IREmitter::ImageSampleExplicitLod(const Value& handle, const Value& body, const Value& offset,
|
Value IREmitter::ImageSampleExplicitLod(const Value& handle, const Value& body, const U32& offset,
|
||||||
TextureInstInfo info) {
|
TextureInstInfo info) {
|
||||||
return Inst(Opcode::ImageSampleExplicitLod, Flags{info}, handle, body, offset);
|
return Inst(Opcode::ImageSampleExplicitLod, Flags{info}, handle, body, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
F32 IREmitter::ImageSampleDrefImplicitLod(const Value& handle, const Value& body, const F32& dref,
|
F32 IREmitter::ImageSampleDrefImplicitLod(const Value& handle, const Value& body, const F32& dref,
|
||||||
const F32& bias, const Value& offset,
|
const F32& bias, const U32& offset,
|
||||||
TextureInstInfo info) {
|
TextureInstInfo info) {
|
||||||
return Inst<F32>(Opcode::ImageSampleDrefImplicitLod, Flags{info}, handle, body, dref, bias,
|
return Inst<F32>(Opcode::ImageSampleDrefImplicitLod, Flags{info}, handle, body, dref, bias,
|
||||||
offset);
|
offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
F32 IREmitter::ImageSampleDrefExplicitLod(const Value& handle, const Value& body, const F32& dref,
|
F32 IREmitter::ImageSampleDrefExplicitLod(const Value& handle, const Value& body, const F32& dref,
|
||||||
const Value& offset, TextureInstInfo info) {
|
const U32& offset, TextureInstInfo info) {
|
||||||
return Inst<F32>(Opcode::ImageSampleDrefExplicitLod, Flags{info}, handle, body, dref, offset);
|
return Inst<F32>(Opcode::ImageSampleDrefExplicitLod, Flags{info}, handle, body, dref, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,18 +242,18 @@ public:
|
|||||||
const Value& value, TextureInstInfo info);
|
const Value& value, TextureInstInfo info);
|
||||||
|
|
||||||
[[nodiscard]] Value ImageSampleImplicitLod(const Value& handle, const Value& body,
|
[[nodiscard]] Value ImageSampleImplicitLod(const Value& handle, const Value& body,
|
||||||
const F32& bias, const Value& offset,
|
const F32& bias, const U32& offset,
|
||||||
TextureInstInfo info);
|
TextureInstInfo info);
|
||||||
|
|
||||||
[[nodiscard]] Value ImageSampleExplicitLod(const Value& handle, const Value& body,
|
[[nodiscard]] Value ImageSampleExplicitLod(const Value& handle, const Value& body,
|
||||||
const Value& offset, TextureInstInfo info);
|
const U32& offset, TextureInstInfo info);
|
||||||
|
|
||||||
[[nodiscard]] F32 ImageSampleDrefImplicitLod(const Value& handle, const Value& body,
|
[[nodiscard]] F32 ImageSampleDrefImplicitLod(const Value& handle, const Value& body,
|
||||||
const F32& dref, const F32& bias,
|
const F32& dref, const F32& bias,
|
||||||
const Value& offset, TextureInstInfo info);
|
const U32& offset, TextureInstInfo info);
|
||||||
|
|
||||||
[[nodiscard]] F32 ImageSampleDrefExplicitLod(const Value& handle, const Value& body,
|
[[nodiscard]] F32 ImageSampleDrefExplicitLod(const Value& handle, const Value& body,
|
||||||
const F32& dref, const Value& offset,
|
const F32& dref, const U32& offset,
|
||||||
TextureInstInfo info);
|
TextureInstInfo info);
|
||||||
|
|
||||||
[[nodiscard]] Value ImageQueryDimension(const Value& handle, const IR::U32& lod,
|
[[nodiscard]] Value ImageQueryDimension(const Value& handle, const IR::U32& lod,
|
||||||
|
@ -298,10 +298,10 @@ OPCODE(ConvertU16U32, U16, U32,
|
|||||||
OPCODE(ConvertU32U16, U32, U16, )
|
OPCODE(ConvertU32U16, U32, U16, )
|
||||||
|
|
||||||
// Image operations
|
// Image operations
|
||||||
OPCODE(ImageSampleImplicitLod, F32x4, Opaque, Opaque, F32, Opaque, )
|
OPCODE(ImageSampleImplicitLod, F32x4, Opaque, Opaque, F32, U32, )
|
||||||
OPCODE(ImageSampleExplicitLod, F32x4, Opaque, Opaque, Opaque, )
|
OPCODE(ImageSampleExplicitLod, F32x4, Opaque, Opaque, U32, )
|
||||||
OPCODE(ImageSampleDrefImplicitLod, F32, Opaque, Opaque, F32, F32, Opaque, )
|
OPCODE(ImageSampleDrefImplicitLod, F32, Opaque, Opaque, F32, F32, U32, )
|
||||||
OPCODE(ImageSampleDrefExplicitLod, F32, Opaque, Opaque, F32, Opaque, )
|
OPCODE(ImageSampleDrefExplicitLod, F32, Opaque, Opaque, F32, U32, )
|
||||||
OPCODE(ImageGather, F32x4, Opaque, Opaque, Opaque, Opaque, )
|
OPCODE(ImageGather, F32x4, Opaque, Opaque, Opaque, Opaque, )
|
||||||
OPCODE(ImageGatherDref, F32x4, Opaque, Opaque, Opaque, Opaque, F32, )
|
OPCODE(ImageGatherDref, F32x4, Opaque, Opaque, Opaque, Opaque, F32, )
|
||||||
OPCODE(ImageFetch, F32x4, Opaque, Opaque, Opaque, U32, Opaque, )
|
OPCODE(ImageFetch, F32x4, Opaque, Opaque, Opaque, U32, Opaque, )
|
||||||
|
@ -567,19 +567,36 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip
|
|||||||
|
|
||||||
if (inst_info.has_offset) {
|
if (inst_info.has_offset) {
|
||||||
// The offsets are six-bit signed integers: X=[5:0], Y=[13:8], and Z=[21:16].
|
// The offsets are six-bit signed integers: X=[5:0], Y=[13:8], and Z=[21:16].
|
||||||
const bool is_gather = inst.GetOpcode() == IR::Opcode::ImageGather ||
|
const bool is_second = inst.GetOpcode() == IR::Opcode::ImageGather ||
|
||||||
inst.GetOpcode() == IR::Opcode::ImageGatherDref;
|
inst.GetOpcode() == IR::Opcode::ImageGatherDref ||
|
||||||
const u32 arg_pos = is_gather ? 2 : (inst_info.is_depth ? 4 : 3);
|
inst.GetOpcode() == IR::Opcode::ImageSampleExplicitLod ||
|
||||||
|
inst.GetOpcode() == IR::Opcode::ImageSampleDrefExplicitLod;
|
||||||
|
const u32 arg_pos = [&]() -> u32 {
|
||||||
|
switch (inst.GetOpcode()) {
|
||||||
|
case IR::Opcode::ImageGather:
|
||||||
|
case IR::Opcode::ImageGatherDref:
|
||||||
|
case IR::Opcode::ImageSampleExplicitLod:
|
||||||
|
return 2;
|
||||||
|
case IR::Opcode::ImageSampleImplicitLod:
|
||||||
|
case IR::Opcode::ImageSampleDrefExplicitLod:
|
||||||
|
return 3;
|
||||||
|
case IR::Opcode::ImageSampleDrefImplicitLod:
|
||||||
|
return 4;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return inst_info.is_depth ? 4 : 3;
|
||||||
|
}();
|
||||||
const IR::Value arg = inst.Arg(arg_pos);
|
const IR::Value arg = inst.Arg(arg_pos);
|
||||||
ASSERT_MSG(arg.Type() == IR::Type::U32, "Unexpected offset type");
|
ASSERT_MSG(arg.Type() == IR::Type::U32, "Unexpected offset type");
|
||||||
const auto sign_ext = [&](u32 value) { return ir.Imm32(s32(value << 24) >> 24); };
|
const auto f = [&](IR::Value value, u32 offset) -> auto {
|
||||||
union {
|
return ir.BitFieldExtract(IR::U32{arg}, ir.Imm32(offset), ir.Imm32(6), true);
|
||||||
u32 raw;
|
};
|
||||||
BitField<0, 6, u32> x;
|
|
||||||
BitField<8, 6, u32> y;
|
const auto x = f(arg, 0);
|
||||||
BitField<16, 6, u32> z;
|
const auto y = f(arg, 6);
|
||||||
} offset{arg.U32()};
|
const auto z = f(arg, 16);
|
||||||
const IR::Value value = ir.CompositeConstruct(sign_ext(offset.x), sign_ext(offset.y));
|
const IR::Value value = ir.CompositeConstruct(x, y, z);
|
||||||
inst.SetArg(arg_pos, value);
|
inst.SetArg(arg_pos, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user