mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 10:56:58 +02:00
shader: honor RDNA2 128-bit image descriptors
This commit is contained in:
@@ -309,6 +309,7 @@ void DecodeMimg(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
|
||||
const uint32_t vaddr = word1 & 0xffu;
|
||||
const uint32_t srsrc = (word1 >> 16u) & 0x1fu;
|
||||
const uint32_t ssamp = (word1 >> 21u) & 0x1fu;
|
||||
const bool r128 = ((word0 >> 15u) & 0x1u) != 0u;
|
||||
const bool a16 = ((word1 >> 30u) & 0x1u) != 0u;
|
||||
const bool d16 = ((word1 >> 31u) & 0x1u) != 0u;
|
||||
const auto* sample = LookupSample(opcode);
|
||||
@@ -332,6 +333,7 @@ void DecodeMimg(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
|
||||
inst.image_sample_flags |= ImageSampleFlagA16;
|
||||
}
|
||||
inst.image_dimension = dimension;
|
||||
inst.image_r128 = r128;
|
||||
inst.image_nsa_dwords = nsa_dwords;
|
||||
for (uint32_t i = 0; i < nsa_dwords * 4u; i++) {
|
||||
inst.image_nsa_addr[i] = (code[word_index + 2u + i / 4u] >> ((i % 4u) * 8u)) & 0xffu;
|
||||
|
||||
@@ -157,6 +157,9 @@ std::string FormatMimg(const Instruction& inst) {
|
||||
if (inst.data_bits == 16u) {
|
||||
text += " d16=1";
|
||||
}
|
||||
if (inst.image_r128) {
|
||||
text += " r128=1";
|
||||
}
|
||||
switch (inst.opcode) {
|
||||
case Opcode::IMAGE_SAMPLE:
|
||||
case Opcode::IMAGE_GATHER4_LZ:
|
||||
|
||||
@@ -667,6 +667,7 @@ struct Instruction {
|
||||
bool slc = false;
|
||||
bool idxen = false;
|
||||
bool offen = false;
|
||||
bool image_r128 = false;
|
||||
int32_t branch_offset = 0;
|
||||
uint32_t branch_target = 0;
|
||||
struct {
|
||||
|
||||
@@ -52,11 +52,13 @@ IR::Value Translator::GetScalarAddressResource(uint32_t base) {
|
||||
}
|
||||
|
||||
IR::Value Translator::GetImageResource(const IR::MemoryInfo& memory) {
|
||||
const auto dword = [&](uint32_t index) {
|
||||
return memory.image_r128 && index >= 4u ? IR::U32(IR::Value(0u))
|
||||
: GetResourceDword(memory.resource, index);
|
||||
};
|
||||
return ir.Emit(IR::ValueOpcode::GetImageResource,
|
||||
{GetResourceDword(memory.resource, 0), GetResourceDword(memory.resource, 1),
|
||||
GetResourceDword(memory.resource, 2), GetResourceDword(memory.resource, 3),
|
||||
GetResourceDword(memory.resource, 4), GetResourceDword(memory.resource, 5),
|
||||
GetResourceDword(memory.resource, 6), GetResourceDword(memory.resource, 7)});
|
||||
{dword(0), dword(1), dword(2), dword(3), dword(4), dword(5), dword(6),
|
||||
dword(7)});
|
||||
}
|
||||
|
||||
IR::Value Translator::GetSamplerResource(const IR::MemoryInfo& memory) {
|
||||
|
||||
@@ -232,6 +232,7 @@ MemoryInfo MemoryInfoFromDecoded(const Decoder::Instruction& decoded, ResourceKi
|
||||
mem.formatted = decoded.formatted;
|
||||
mem.image_has_mip = decoded.opcode == Decoder::Opcode::IMAGE_LOAD_MIP ||
|
||||
decoded.opcode == Decoder::Opcode::IMAGE_STORE_MIP;
|
||||
mem.image_r128 = decoded.image_r128;
|
||||
mem.glc = decoded.glc;
|
||||
mem.slc = decoded.slc;
|
||||
mem.idxen = decoded.idxen;
|
||||
|
||||
@@ -119,6 +119,7 @@ struct MemoryInfo {
|
||||
bool formatted = false;
|
||||
bool image_has_mip = false;
|
||||
bool image_cube = false;
|
||||
bool image_r128 = false;
|
||||
bool glc = false;
|
||||
bool slc = false;
|
||||
bool idxen = false;
|
||||
@@ -226,6 +227,7 @@ struct ImageResource {
|
||||
bool atomic = false;
|
||||
bool depth_compare = false;
|
||||
bool cube = false;
|
||||
bool r128 = false;
|
||||
uint32_t indirect_root = NoIndirectImage;
|
||||
uint32_t indirect_mapping_offset = 0;
|
||||
uint32_t indirect_mapping_capacity = 0;
|
||||
|
||||
@@ -98,14 +98,14 @@ std::string MemoryInfoToString(const MemoryInfo& mem) {
|
||||
" ; {} resource={} sampler={} offset={} offset2={} dmask=0x{:x} data_dwords={} "
|
||||
"data_bits={} component={}/{} dfmt={} nfmt={} signed={} typed={} formatted={} segment={} "
|
||||
"glc={} slc={} idxen={} offen={} image_flags=0x{:x} image_dim={} image_addr={} "
|
||||
"image_mip={}",
|
||||
"image_mip={} image_r128={}",
|
||||
ResourceKindToString(mem.kind).c_str(), mem.resource, mem.sampler, mem.offset,
|
||||
mem.secondary_offset, mem.dmask, mem.data_dwords, mem.data_bits, mem.component_index,
|
||||
mem.component_count, mem.data_format, mem.number_format, mem.data_signed ? 1u : 0u,
|
||||
mem.typed ? 1u : 0u, mem.formatted ? 1u : 0u, mem.memory_segment, mem.glc ? 1u : 0u,
|
||||
mem.slc ? 1u : 0u, mem.idxen ? 1u : 0u, mem.offen ? 1u : 0u, mem.image_sample_flags,
|
||||
Decoder::ImageDimensionToString(mem.image_dimension), mem.image_address_components,
|
||||
mem.image_has_mip ? 1u : 0u);
|
||||
mem.image_has_mip ? 1u : 0u, mem.image_r128 ? 1u : 0u);
|
||||
if (mem.image_nsa_dwords != 0) {
|
||||
text += fmt::format(" image_nsa_dwords={} image_nsa_addr=", mem.image_nsa_dwords);
|
||||
const auto count =
|
||||
|
||||
@@ -52,18 +52,23 @@ bool NullImageDescriptor(const DescriptorValue& descriptor) {
|
||||
return descriptor.dwords[0] == 0 && (descriptor.dwords[1] & 0xffu) == 0;
|
||||
}
|
||||
|
||||
bool ValidImageDescriptor(const DescriptorValue& descriptor) {
|
||||
bool ValidImageDescriptor(const DescriptorValue& descriptor, bool r128 = false) {
|
||||
const auto type = static_cast<Prospero::ImageType>((descriptor.dwords[3] >> 28u) & 0xfu);
|
||||
const auto format = static_cast<Prospero::BufferFormat>((descriptor.dwords[1] >> 20u) & 0x1ffu);
|
||||
if (type < Prospero::ImageType::kColor1D || format == Prospero::BufferFormat::kInvalid) {
|
||||
return false;
|
||||
}
|
||||
if (r128 && type != Prospero::ImageType::kColor1D &&
|
||||
type != Prospero::ImageType::kColor2D && type != Prospero::ImageType::kColor2DMsaa) {
|
||||
return false;
|
||||
}
|
||||
if (type == Prospero::ImageType::kColor2DMsaa ||
|
||||
type == Prospero::ImageType::kColor2DMsaaArray) {
|
||||
const auto base_level = (descriptor.dwords[3] >> 12u) & 0xfu;
|
||||
const auto fragments = (descriptor.dwords[3] >> 16u) & 0xfu;
|
||||
const auto max_mip = (descriptor.dwords[5] >> 4u) & 0xfu;
|
||||
return base_level == 0 && fragments >= 1 && fragments <= 3 && max_mip == fragments;
|
||||
return base_level == 0 && fragments >= 1 && fragments <= 3 &&
|
||||
(r128 || max_mip == fragments);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -644,7 +649,7 @@ bool MaterializeResources(const Program& program, const SrtRuntime& runtime,
|
||||
}
|
||||
} else {
|
||||
auto descriptor = *cursor++;
|
||||
if (!ValidImageDescriptor(descriptor)) {
|
||||
if (!ValidImageDescriptor(descriptor, image.r128)) {
|
||||
descriptor.dwords.fill(0);
|
||||
}
|
||||
next.images[image_index] = descriptor;
|
||||
|
||||
@@ -652,7 +652,7 @@ private:
|
||||
auto& image = m_info.images[i];
|
||||
if (image.source == source && image.kind == memory.kind &&
|
||||
image.dimension == memory.image_dimension && image.mip_mode == mip &&
|
||||
image.depth_compare == depth) {
|
||||
image.depth_compare == depth && image.r128 == memory.image_r128) {
|
||||
Merge(image, op, pc);
|
||||
return i;
|
||||
}
|
||||
@@ -667,6 +667,7 @@ private:
|
||||
image.dimension = memory.image_dimension;
|
||||
image.mip_mode = mip;
|
||||
image.depth_compare = depth;
|
||||
image.r128 = memory.image_r128;
|
||||
Merge(image, op, pc);
|
||||
m_info.images.push_back(image);
|
||||
return static_cast<uint32_t>(m_info.images.size() - 1);
|
||||
|
||||
Reference in New Issue
Block a user