mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-05-25 21:03:18 +00:00
shader_recompiler: Rework image read/write emit. (#1819)
This commit is contained in:
parent
95638d5ca5
commit
a89c29c2ca
15 changed files with 88 additions and 88 deletions
|
@ -1630,11 +1630,6 @@ Value IREmitter::ImageGatherDref(const Value& handle, const Value& coords, const
|
|||
return Inst(Opcode::ImageGatherDref, Flags{info}, handle, coords, offset, dref);
|
||||
}
|
||||
|
||||
Value IREmitter::ImageFetch(const Value& handle, const Value& coords, const U32& lod,
|
||||
const Value& offset, const U32& multisampling, TextureInstInfo info) {
|
||||
return Inst(Opcode::ImageFetch, Flags{info}, handle, coords, lod, offset, multisampling);
|
||||
}
|
||||
|
||||
Value IREmitter::ImageQueryDimension(const Value& handle, const IR::U32& lod,
|
||||
const IR::U1& skip_mips) {
|
||||
return Inst(Opcode::ImageQueryDimensions, handle, lod, skip_mips);
|
||||
|
@ -1657,13 +1652,13 @@ Value IREmitter::ImageGradient(const Value& handle, const Value& coords,
|
|||
}
|
||||
|
||||
Value IREmitter::ImageRead(const Value& handle, const Value& coords, const U32& lod,
|
||||
TextureInstInfo info) {
|
||||
return Inst(Opcode::ImageRead, Flags{info}, handle, coords, lod);
|
||||
const U32& multisampling, TextureInstInfo info) {
|
||||
return Inst(Opcode::ImageRead, Flags{info}, handle, coords, lod, multisampling);
|
||||
}
|
||||
|
||||
void IREmitter::ImageWrite(const Value& handle, const Value& coords, const U32& lod,
|
||||
const Value& color, TextureInstInfo info) {
|
||||
Inst(Opcode::ImageWrite, Flags{info}, handle, coords, lod, color);
|
||||
const U32& multisampling, const Value& color, TextureInstInfo info) {
|
||||
Inst(Opcode::ImageWrite, Flags{info}, handle, coords, lod, multisampling, color);
|
||||
}
|
||||
|
||||
// Debug print maps to SPIRV's NonSemantic DebugPrintf instruction
|
||||
|
|
|
@ -325,17 +325,14 @@ public:
|
|||
TextureInstInfo info);
|
||||
[[nodiscard]] Value ImageGatherDref(const Value& handle, const Value& coords,
|
||||
const Value& offset, const F32& dref, TextureInstInfo info);
|
||||
[[nodiscard]] Value ImageFetch(const Value& handle, const Value& coords, const U32& lod,
|
||||
const Value& offset, const U32& multisampling,
|
||||
TextureInstInfo info);
|
||||
[[nodiscard]] Value ImageGradient(const Value& handle, const Value& coords,
|
||||
const Value& derivatives_dx, const Value& derivatives_dy,
|
||||
const Value& offset, const F32& lod_clamp,
|
||||
TextureInstInfo info);
|
||||
[[nodiscard]] Value ImageRead(const Value& handle, const Value& coords, const U32& lod,
|
||||
TextureInstInfo info);
|
||||
void ImageWrite(const Value& handle, const Value& coords, const U32& lod, const Value& color,
|
||||
TextureInstInfo info);
|
||||
const U32& multisampling, TextureInstInfo info);
|
||||
void ImageWrite(const Value& handle, const Value& coords, const U32& lod,
|
||||
const U32& multisampling, const Value& color, TextureInstInfo info);
|
||||
|
||||
void EmitVertex();
|
||||
void EmitPrimitive();
|
||||
|
|
|
@ -338,12 +338,11 @@ OPCODE(ImageSampleDrefImplicitLod, F32x4, Opaq
|
|||
OPCODE(ImageSampleDrefExplicitLod, F32x4, Opaque, Opaque, F32, F32, Opaque, )
|
||||
OPCODE(ImageGather, F32x4, Opaque, Opaque, Opaque, )
|
||||
OPCODE(ImageGatherDref, F32x4, Opaque, Opaque, Opaque, F32, )
|
||||
OPCODE(ImageFetch, F32x4, Opaque, Opaque, U32, Opaque, Opaque, )
|
||||
OPCODE(ImageQueryDimensions, U32x4, Opaque, U32, U1, )
|
||||
OPCODE(ImageQueryLod, F32x4, Opaque, Opaque, )
|
||||
OPCODE(ImageGradient, F32x4, Opaque, Opaque, Opaque, Opaque, Opaque, F32, )
|
||||
OPCODE(ImageRead, U32x4, Opaque, Opaque, U32, )
|
||||
OPCODE(ImageWrite, Void, Opaque, Opaque, U32, U32x4, )
|
||||
OPCODE(ImageRead, U32x4, Opaque, Opaque, U32, U32, )
|
||||
OPCODE(ImageWrite, Void, Opaque, Opaque, U32, U32, U32x4, )
|
||||
|
||||
// Image atomic operations
|
||||
OPCODE(ImageAtomicIAdd32, U32, Opaque, Opaque, U32, )
|
||||
|
|
|
@ -115,25 +115,16 @@ bool IsImageAtomicInstruction(const IR::Inst& inst) {
|
|||
}
|
||||
}
|
||||
|
||||
bool IsImageStorageInstruction(const IR::Inst& inst) {
|
||||
switch (inst.GetOpcode()) {
|
||||
case IR::Opcode::ImageWrite:
|
||||
case IR::Opcode::ImageRead:
|
||||
return true;
|
||||
default:
|
||||
return IsImageAtomicInstruction(inst);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsImageInstruction(const IR::Inst& inst) {
|
||||
switch (inst.GetOpcode()) {
|
||||
case IR::Opcode::ImageFetch:
|
||||
case IR::Opcode::ImageRead:
|
||||
case IR::Opcode::ImageWrite:
|
||||
case IR::Opcode::ImageQueryDimensions:
|
||||
case IR::Opcode::ImageQueryLod:
|
||||
case IR::Opcode::ImageSampleRaw:
|
||||
return true;
|
||||
default:
|
||||
return IsImageStorageInstruction(inst);
|
||||
return IsImageAtomicInstruction(inst);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,7 +192,8 @@ public:
|
|||
return desc.sharp_idx == existing.sharp_idx;
|
||||
})};
|
||||
auto& image = image_resources[index];
|
||||
image.is_storage |= desc.is_storage;
|
||||
image.is_read |= desc.is_read;
|
||||
image.is_written |= desc.is_written;
|
||||
return index;
|
||||
}
|
||||
|
||||
|
@ -429,9 +421,9 @@ void PatchTextureBufferInstruction(IR::Block& block, IR::Inst& inst, Info& info,
|
|||
}
|
||||
|
||||
IR::Value PatchCubeCoord(IR::IREmitter& ir, const IR::Value& s, const IR::Value& t,
|
||||
const IR::Value& z, bool is_storage, bool is_array) {
|
||||
const IR::Value& z, bool is_written, bool is_array) {
|
||||
// When cubemap is written with imageStore it is treated like 2DArray.
|
||||
if (is_storage) {
|
||||
if (is_written) {
|
||||
return ir.CompositeConstruct(s, t, z);
|
||||
}
|
||||
|
||||
|
@ -684,15 +676,16 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip
|
|||
image = AmdGpu::Image::Null();
|
||||
}
|
||||
ASSERT(image.GetType() != AmdGpu::ImageType::Invalid);
|
||||
const bool is_storage = IsImageStorageInstruction(inst);
|
||||
const bool is_read = inst.GetOpcode() == IR::Opcode::ImageRead;
|
||||
const bool is_written = inst.GetOpcode() == IR::Opcode::ImageWrite;
|
||||
|
||||
// Patch image instruction if image is FMask.
|
||||
if (image.IsFmask()) {
|
||||
ASSERT_MSG(!is_storage, "FMask storage instructions are not supported");
|
||||
ASSERT_MSG(!is_written, "FMask storage instructions are not supported");
|
||||
|
||||
IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
|
||||
switch (inst.GetOpcode()) {
|
||||
case IR::Opcode::ImageFetch:
|
||||
case IR::Opcode::ImageRead:
|
||||
case IR::Opcode::ImageSampleRaw: {
|
||||
IR::F32 fmaskx = ir.BitCast<IR::F32>(ir.Imm32(0x76543210));
|
||||
IR::F32 fmasky = ir.BitCast<IR::F32>(ir.Imm32(0xfedcba98));
|
||||
|
@ -721,10 +714,11 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip
|
|||
|
||||
u32 image_binding = descriptors.Add(ImageResource{
|
||||
.sharp_idx = tsharp,
|
||||
.is_storage = is_storage,
|
||||
.is_depth = bool(inst_info.is_depth),
|
||||
.is_atomic = IsImageAtomicInstruction(inst),
|
||||
.is_array = bool(inst_info.is_array),
|
||||
.is_read = is_read,
|
||||
.is_written = is_written,
|
||||
});
|
||||
|
||||
// Sample instructions must be resolved into a new instruction using address register data.
|
||||
|
@ -762,7 +756,7 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip
|
|||
case AmdGpu::ImageType::Color3D: // x, y, z, [lod]
|
||||
return {ir.CompositeConstruct(body->Arg(0), body->Arg(1), body->Arg(2)), body->Arg(3)};
|
||||
case AmdGpu::ImageType::Cube: // x, y, face, [lod]
|
||||
return {PatchCubeCoord(ir, body->Arg(0), body->Arg(1), body->Arg(2), is_storage,
|
||||
return {PatchCubeCoord(ir, body->Arg(0), body->Arg(1), body->Arg(2), is_written,
|
||||
inst_info.is_array),
|
||||
body->Arg(3)};
|
||||
default:
|
||||
|
@ -772,19 +766,20 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip
|
|||
inst.SetArg(1, coords);
|
||||
|
||||
if (inst.GetOpcode() == IR::Opcode::ImageWrite) {
|
||||
inst.SetArg(3, SwizzleVector(ir, image, inst.Arg(3)));
|
||||
inst.SetArg(4, SwizzleVector(ir, image, inst.Arg(4)));
|
||||
}
|
||||
|
||||
if (inst_info.has_lod) {
|
||||
ASSERT(inst.GetOpcode() == IR::Opcode::ImageFetch ||
|
||||
inst.GetOpcode() == IR::Opcode::ImageRead ||
|
||||
ASSERT(inst.GetOpcode() == IR::Opcode::ImageRead ||
|
||||
inst.GetOpcode() == IR::Opcode::ImageWrite);
|
||||
ASSERT(image.GetType() != AmdGpu::ImageType::Color2DMsaa &&
|
||||
image.GetType() != AmdGpu::ImageType::Color2DMsaaArray);
|
||||
inst.SetArg(2, arg);
|
||||
} else if (image.GetType() == AmdGpu::ImageType::Color2DMsaa ||
|
||||
image.GetType() == AmdGpu::ImageType::Color2DMsaaArray) {
|
||||
inst.SetArg(4, arg);
|
||||
} else if ((image.GetType() == AmdGpu::ImageType::Color2DMsaa ||
|
||||
image.GetType() == AmdGpu::ImageType::Color2DMsaaArray) &&
|
||||
(inst.GetOpcode() == IR::Opcode::ImageRead ||
|
||||
inst.GetOpcode() == IR::Opcode::ImageWrite)) {
|
||||
inst.SetArg(3, arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue