shader: fix packed image address reads

This commit is contained in:
nmzik
2026-09-05 11:32:32 +04:00
parent 51afce3a97
commit 2ec0e9e8f3
5 changed files with 112 additions and 39 deletions
@@ -274,6 +274,7 @@ uint32_t DecodeMimgAddressComponents(uint32_t opcode, ImageDimension dimension,
}
switch (opcode) {
case 0x0eu: return 1u;
case 0x01u:
case 0x09u: return ImageCoordComponents(dimension) + 1u;
case 0x00u:
@@ -297,6 +298,36 @@ bool IsSingleDmaskBit(uint32_t dmask) {
} // namespace
ImageAddressComponent ImageAddressComponentLayout(uint32_t flags, uint32_t component) {
const auto width = [flags](uint32_t index) {
if ((flags & ImageSampleFlagA16) == 0u) return 32u;
uint32_t cursor = 0;
if ((flags & ImageSampleFlagOffset) != 0u) {
if (index == cursor++) return 32u;
}
if ((flags & ImageSampleFlagBias) != 0u) {
if (index == cursor++) return 16u;
}
if ((flags & ImageSampleFlagCompare) != 0u && index == cursor) return 32u;
return 16u;
};
uint32_t offset = 0;
for (uint32_t index = 0; index < component; index++) {
const auto bits = width(index);
if (bits == 32u) offset = (offset + 31u) & ~31u;
offset += bits;
}
const auto bits = width(component);
if (bits == 32u) offset = (offset + 31u) & ~31u;
return {offset, bits};
}
uint32_t ImageAddressDwordCount(uint32_t flags, uint32_t components) {
if (components == 0u) return 0u;
const auto last = ImageAddressComponentLayout(flags, components - 1u);
return (last.bit_offset + last.bit_width + 31u) / 32u;
}
void DecodeMimg(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index,
Instruction& inst) {
const uint32_t word0 = code[word_index];
@@ -10,6 +10,14 @@ void DecodeMimg(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
const char* MimgSampleOpcodeName(uint32_t opcode);
struct ImageAddressComponent {
uint32_t bit_offset;
uint32_t bit_width;
};
ImageAddressComponent ImageAddressComponentLayout(uint32_t flags, uint32_t component);
uint32_t ImageAddressDwordCount(uint32_t flags, uint32_t components);
} // namespace Libs::Graphics::ShaderRecompiler::Decoder
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_SHADER_RECOMPILER_IMAGEOPS_H_ */