mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-26 20:36:16 +00:00
spirv: fix image sample lod/clamp/offset translation (#402)
* spirv: fix image sample lod/clamp translation * spirv: fix image sample offsets * fix ImageSample opcodes & offset emission
This commit is contained in:
parent
5eecd089ab
commit
dfcfd62d4f
7 changed files with 112 additions and 77 deletions
|
@ -567,25 +567,47 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip
|
|||
|
||||
if (inst_info.has_offset) {
|
||||
// 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 ||
|
||||
inst.GetOpcode() == IR::Opcode::ImageGatherDref;
|
||||
const u32 arg_pos = is_gather ? 2 : (inst_info.is_depth ? 4 : 3);
|
||||
const u32 arg_pos = [&]() -> u32 {
|
||||
switch (inst.GetOpcode()) {
|
||||
case IR::Opcode::ImageGather:
|
||||
case IR::Opcode::ImageGatherDref:
|
||||
return 2;
|
||||
case IR::Opcode::ImageSampleExplicitLod:
|
||||
case IR::Opcode::ImageSampleImplicitLod:
|
||||
return 3;
|
||||
case IR::Opcode::ImageSampleDrefExplicitLod:
|
||||
case IR::Opcode::ImageSampleDrefImplicitLod:
|
||||
return 4;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return inst_info.is_depth ? 4 : 3;
|
||||
}();
|
||||
const IR::Value arg = inst.Arg(arg_pos);
|
||||
ASSERT_MSG(arg.Type() == IR::Type::U32, "Unexpected offset type");
|
||||
const auto sign_ext = [&](u32 value) { return ir.Imm32(s32(value << 24) >> 24); };
|
||||
union {
|
||||
u32 raw;
|
||||
BitField<0, 6, u32> x;
|
||||
BitField<8, 6, u32> y;
|
||||
BitField<16, 6, u32> z;
|
||||
} offset{arg.U32()};
|
||||
const IR::Value value = ir.CompositeConstruct(sign_ext(offset.x), sign_ext(offset.y));
|
||||
const auto f = [&](IR::Value value, u32 offset) -> auto {
|
||||
return ir.BitFieldExtract(IR::U32{arg}, ir.Imm32(offset), ir.Imm32(6), true);
|
||||
};
|
||||
|
||||
const auto x = f(arg, 0);
|
||||
const auto y = f(arg, 8);
|
||||
const auto z = f(arg, 16);
|
||||
const IR::Value value = ir.CompositeConstruct(x, y, z);
|
||||
inst.SetArg(arg_pos, value);
|
||||
}
|
||||
|
||||
if (inst_info.has_lod_clamp) {
|
||||
// Final argument contains lod_clamp
|
||||
const u32 arg_pos = inst_info.is_depth ? 5 : 4;
|
||||
const u32 arg_pos = [&]() -> u32 {
|
||||
switch (inst.GetOpcode()) {
|
||||
case IR::Opcode::ImageSampleImplicitLod:
|
||||
return 2;
|
||||
case IR::Opcode::ImageSampleDrefImplicitLod:
|
||||
return 3;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return inst_info.is_depth ? 5 : 4;
|
||||
}();
|
||||
inst.SetArg(arg_pos, arg);
|
||||
}
|
||||
if (inst_info.explicit_lod) {
|
||||
|
@ -593,7 +615,8 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip
|
|||
inst.GetOpcode() == IR::Opcode::ImageSampleExplicitLod ||
|
||||
inst.GetOpcode() == IR::Opcode::ImageSampleDrefExplicitLod);
|
||||
const u32 pos = inst.GetOpcode() == IR::Opcode::ImageSampleExplicitLod ? 2 : 3;
|
||||
inst.SetArg(pos, arg);
|
||||
const IR::Value value = inst_info.force_level0 ? ir.Imm32(0.f) : arg;
|
||||
inst.SetArg(pos, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue