Patch some fmask reads

This commit is contained in:
Lander Gallastegi 2024-10-23 19:16:29 +02:00
parent 9e2d21f887
commit 70a25b87d3
2 changed files with 30 additions and 0 deletions

View File

@ -656,6 +656,32 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip
} }
ASSERT(image.GetType() != AmdGpu::ImageType::Invalid); ASSERT(image.GetType() != AmdGpu::ImageType::Invalid);
const bool is_storage = IsImageStorageInstruction(inst); const bool is_storage = IsImageStorageInstruction(inst);
// Patch image instruction if image is fmask.
if (image.IsFmask()) {
// Ignore fmask writes. TODO: handle dimension queries.
if (is_storage && inst.GetOpcode() == IR::Opcode::ImageQueryDimensions) {
inst.Invalidate();
return;
}
IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
switch (inst.GetOpcode()) {
case IR::Opcode::ImageFetch:
case IR::Opcode::ImageSampleRaw: {
IR::F32 fmaskx = ir.BitCast<IR::F32>(ir.Imm32(0x76543210));
IR::F32 fmasky = ir.BitCast<IR::F32>(ir.Imm32(0xfedcba98));
inst.ReplaceUsesWith(ir.CompositeConstruct(fmaskx, fmasky));
return;
}
case IR::Opcode::ImageQueryLod:
inst.ReplaceUsesWith(ir.Imm32(1));
return;
default:
UNREACHABLE_MSG("Can't patch fmask instruction {}", inst.GetOpcode());
}
}
const auto type = image.IsPartialCubemap() ? AmdGpu::ImageType::Color2DArray : image.GetType(); const auto type = image.IsPartialCubemap() ? AmdGpu::ImageType::Color2DArray : image.GetType();
u32 image_binding = descriptors.Add(ImageResource{ u32 image_binding = descriptors.Add(ImageResource{
.sgpr_base = tsharp.sgpr_base, .sgpr_base = tsharp.sgpr_base,

View File

@ -295,6 +295,10 @@ struct Image {
return GetTilingMode() != TilingMode::Display_Linear; return GetTilingMode() != TilingMode::Display_Linear;
} }
bool IsFmask() const noexcept {
return GetDataFmt() >= DataFormat::FormatFmask8_1 && GetDataFmt() <= DataFormat::FormatFmask64_8;
}
bool IsPartialCubemap() const { bool IsPartialCubemap() const {
const auto viewed_slice = last_array - base_array + 1; const auto viewed_slice = last_array - base_array + 1;
return GetType() == ImageType::Cube && viewed_slice < 6; return GetType() == ImageType::Cube && viewed_slice < 6;