graphics: replace raw GPU enum values with typed formats

This commit is contained in:
nmzik
2026-08-11 11:32:43 +02:00
parent 11b95bed20
commit 21aa7b66ce
36 changed files with 1002 additions and 956 deletions
@@ -893,7 +893,8 @@ uint32_t EmitByteAddress(EmitterState& state, const IR::Instruction& inst, uint3
uint32_t StorageBufferPackedStride(const EmitterState& state, const IR::MemoryInfo& mem,
uint32_t use_pc);
uint32_t StorageBufferFormat(const EmitterState& state, const IR::MemoryInfo& mem, uint32_t use_pc);
Prospero::BufferFormat StorageBufferFormat(const EmitterState& state, const IR::MemoryInfo& mem,
uint32_t use_pc);
bool ShouldApplyBufferAddTid(const IR::Instruction& inst);
@@ -153,8 +153,8 @@ uint32_t StorageBufferPackedStride(const EmitterState& state, const IR::MemoryIn
return state.program.info.buffers[mem.resource].packed_stride;
}
uint32_t StorageBufferFormat(const EmitterState& state, const IR::MemoryInfo& mem,
uint32_t use_pc) {
Prospero::BufferFormat StorageBufferFormat(const EmitterState& state, const IR::MemoryInfo& mem,
uint32_t use_pc) {
(void)use_pc;
if (mem.resource >= state.program.info.buffers.size()) {
ExitDescriptorBindingFailure(state, IR::DescriptorBindingKind::Buffers, mem.resource,
@@ -749,8 +749,7 @@ Prospero::BufferFormat FormattedBufferFormat(const EmitterState& state,
const IR::Instruction& inst) {
return inst.memory.typed
? Format::DecodeTBufferFormat(inst.memory.data_format, inst.memory.number_format)
: static_cast<Prospero::BufferFormat>(
StorageBufferFormat(state, inst.memory, inst.pc));
: StorageBufferFormat(state, inst.memory, inst.pc);
}
IR::Instruction WithFormatComponentByteOffset(const IR::Instruction& inst,
@@ -64,26 +64,26 @@ VertexInputScalarKind VertexParameterScalarKind(const EmitterState& state, uint3
}
switch (state.vertex_input_info->resources[location].Format()) {
case 5:
case 11:
case 18:
case 20:
case 27:
case 60:
case 62:
case 69:
case 72:
case 75: return VertexInputScalarKind::Uint;
case 6:
case 12:
case 19:
case 21:
case 28:
case 61:
case 63:
case 70:
case 73:
case 76: return VertexInputScalarKind::Sint;
case Prospero::BufferFormat::k8UInt:
case Prospero::BufferFormat::k16UInt:
case Prospero::BufferFormat::k8_8UInt:
case Prospero::BufferFormat::k32UInt:
case Prospero::BufferFormat::k16_16UInt:
case Prospero::BufferFormat::k8_8_8_8UInt:
case Prospero::BufferFormat::k32_32UInt:
case Prospero::BufferFormat::k16_16_16_16UInt:
case Prospero::BufferFormat::k32_32_32UInt:
case Prospero::BufferFormat::k32_32_32_32UInt: return VertexInputScalarKind::Uint;
case Prospero::BufferFormat::k8SInt:
case Prospero::BufferFormat::k16SInt:
case Prospero::BufferFormat::k8_8SInt:
case Prospero::BufferFormat::k32SInt:
case Prospero::BufferFormat::k16_16SInt:
case Prospero::BufferFormat::k8_8_8_8SInt:
case Prospero::BufferFormat::k32_32SInt:
case Prospero::BufferFormat::k16_16_16_16SInt:
case Prospero::BufferFormat::k32_32_32SInt:
case Prospero::BufferFormat::k32_32_32_32SInt: return VertexInputScalarKind::Sint;
default: return VertexInputScalarKind::Float;
}
}
@@ -220,13 +220,13 @@ bool ValidateResourceSpecialization(const Program& program, const ResourceSnapsh
}
return false;
}
const auto format = (descriptor.dwords[1] >> 20u) & 0x1ffu;
const bool raw_sint_storage =
storage && format == Prospero::GpuEnumValue(Prospero::BufferFormat::k32SInt) &&
!image.read && !image.atomic;
const bool uint_descriptor = Prospero::IsUintTextureFormat(format) || raw_sint_storage;
const auto uint_program = image.kind == ResourceKind::ImageUint ||
image.kind == ResourceKind::StorageImageUint;
const auto format =
static_cast<Prospero::BufferFormat>((descriptor.dwords[1] >> 20u) & 0x1ffu);
const bool raw_sint_storage = storage && format == Prospero::BufferFormat::k32SInt &&
!image.read && !image.atomic;
const bool uint_descriptor = Prospero::IsUintTextureFormat(format) || raw_sint_storage;
const auto uint_program = image.kind == ResourceKind::ImageUint ||
image.kind == ResourceKind::StorageImageUint;
if (uint_descriptor != uint_program && !(image.atomic && uint_program)) {
if (error != nullptr) {
*error = fmt::format(
@@ -415,12 +415,12 @@ bool SpecializeResources(Program& program, const ResourceSnapshot& snapshot, std
image.kind == ResourceKind::StorageImageUint) {
image.storage_swizzle = DescriptorImageSwizzle(descriptor);
}
const auto format = (descriptor.dwords[1] >> 20u) & 0x1ffu;
const auto format =
static_cast<Prospero::BufferFormat>((descriptor.dwords[1] >> 20u) & 0x1ffu);
const bool storage = image.kind == ResourceKind::StorageImage ||
image.kind == ResourceKind::StorageImageUint;
const bool raw_sint_storage =
storage && format == Prospero::GpuEnumValue(Prospero::BufferFormat::k32SInt) &&
!image.read && !image.atomic;
storage && format == Prospero::BufferFormat::k32SInt && !image.read && !image.atomic;
const bool uint_image = Prospero::IsUintTextureFormat(format) || raw_sint_storage;
if (uint_image) {
switch (image.kind) {
+12 -11
View File
@@ -3,6 +3,7 @@
#include "common/common.h"
#include "common/stringUtils.h"
#include "graphics/guest_gpu/gpu_defs.h"
#include "graphics/shader/recompiler/cfg/ShaderCFG.h"
#include "graphics/shader/recompiler/decompiler/ShaderDecoder.h"
#include "graphics/shader/shader.h"
@@ -276,17 +277,17 @@ struct SrtPlan {
struct BufferResource {
static constexpr uint32_t NoImageAlias = UINT32_MAX;
uint32_t source = 0;
uint32_t first_use_pc = 0;
uint32_t max_byte_extent = 0;
uint32_t packed_stride = 0;
uint32_t descriptor_format = 0;
uint32_t image_alias = NoImageAlias;
bool read = false;
bool written = false;
bool atomic = false;
bool formatted = false;
bool scalar = false;
uint32_t source = 0;
uint32_t first_use_pc = 0;
uint32_t max_byte_extent = 0;
uint32_t packed_stride = 0;
Prospero::BufferFormat descriptor_format = Prospero::BufferFormat::kInvalid;
uint32_t image_alias = NoImageAlias;
bool read = false;
bool written = false;
bool atomic = false;
bool formatted = false;
bool scalar = false;
bool operator==(const BufferResource& other) const = default;
};
+17 -13
View File
@@ -535,7 +535,8 @@ static void ShaderDetectBuffers(ShaderVertexInputInfo& info) {
}
}
static uint32_t VertexAttribFormatToBufferFormat(uint32_t format) {
static Prospero::BufferFormat
VertexAttribFormatToBufferFormat(Prospero::VertexAttribFormat format) {
struct FormatMap {
Prospero::VertexAttribFormat vertex;
Prospero::BufferFormat buffer;
@@ -633,12 +634,12 @@ static uint32_t VertexAttribFormatToBufferFormat(uint32_t format) {
};
for (const auto& entry: format_map) {
if (format == Prospero::GpuEnumValue(entry.vertex)) {
return Prospero::GpuEnumValue(entry.buffer);
if (format == entry.vertex) {
return entry.buffer;
}
}
return format;
return static_cast<Prospero::BufferFormat>(static_cast<uint32_t>(format));
}
static void ShaderApplyAttribSemantics(ShaderVertexInputInfo& info,
@@ -659,8 +660,9 @@ static void ShaderApplyAttribSemantics(ShaderVertexInputInfo& info,
LOGF("reg = %u, size = %u, va[%u] = 0x%08" PRIx32 "\n", reg, size, i, attrib[in.semantic]);
size_t index = attrib[in.semantic] & 0x1fu;
uint32_t format = (attrib[in.semantic] >> 5u) & 0x1ffu;
size_t index = attrib[in.semantic] & 0x1fu;
auto format =
static_cast<Prospero::VertexAttribFormat>((attrib[in.semantic] >> 5u) & 0x1ffu);
uint32_t offset = (attrib[in.semantic] >> 14u) & 0xfffu;
uint32_t fetch_index = (attrib[in.semantic] >> 26u) & 0x1u;
@@ -690,17 +692,19 @@ static void ShaderApplyAttribSemantics(ShaderVertexInputInfo& info,
r.fields[1] = sharp[1];
r.fields[2] = sharp[2];
r.fields[3] = sharp[3];
if (format != 0) {
if (format != Prospero::VertexAttribFormat::kInvalid) {
auto buffer_format = VertexAttribFormatToBufferFormat(format);
static std::atomic<uint64_t> log_count = 0;
auto log_id = log_count.fetch_add(1);
if (log_id < 64) {
LOGF("\t temporary: PS5 vertex attrib semantic %u uses attrib format %u -> buffer "
"format %u, offset %u, buffer index %zu\n",
static_cast<uint32_t>(in.semantic), format, buffer_format, offset, index);
static_cast<uint32_t>(in.semantic), static_cast<uint32_t>(format),
static_cast<uint32_t>(buffer_format), offset, index);
}
const auto buffer_format_raw = static_cast<uint32_t>(buffer_format);
r.fields[3] = (r.fields[3] & ~((0x7fu << 12u) | 0xfffu)) |
((buffer_format & 0x7fu) << 12u) | DstSel(4, 5, 6, 7);
((buffer_format_raw & 0x7fu) << 12u) | DstSel(4, 5, 6, 7);
}
if (offset != 0) {
r.UpdateAddress48(r.Base48() + offset);
@@ -1011,7 +1015,7 @@ static std::string ShaderDescribeSpecialization(const ShaderRecompiler::IR::Prog
for (uint32_t i = 0; i < program.info.buffers.size(); i++) {
const auto& buffer = program.info.buffers[i];
ret += fmt::format(" b{}[stride={} format={}]", i, buffer.packed_stride,
buffer.descriptor_format);
static_cast<uint32_t>(buffer.descriptor_format));
}
for (uint32_t i = 0; i < program.info.images.size(); i++) {
const auto& image = program.info.images[i];
@@ -1047,7 +1051,7 @@ static void ShaderAppendNativeSpecialization(std::vector<uint32_t>&
ids.push_back(static_cast<uint32_t>(program.info.buffers.size()));
for (const auto& buffer: program.info.buffers) {
ids.push_back(buffer.packed_stride);
ids.push_back(buffer.descriptor_format);
ids.push_back(static_cast<uint32_t>(buffer.descriptor_format));
}
ids.push_back(static_cast<uint32_t>(program.info.images.size()));
for (const auto& image: program.info.images) {
@@ -1250,7 +1254,7 @@ void ShaderDbgDumpInputInfo(const ShaderVertexInputInfo& info) {
r.DstSelX(), r.DstSelY(), r.DstSelZ(), r.DstSelW());
LOGF("\t\t Format() = %" PRIu8 "\n"
"\t\t OutOfBounds() = %" PRIu8 "\n",
r.Format(), r.OutOfBounds());
r.RawFormat(), r.OutOfBounds());
LOGF("\t\t AddTid() = %s\n", r.AddTid() ? "true" : "false");
}
@@ -1596,7 +1600,7 @@ ShaderId ShaderGetIdVS(const HW::VertexShaderInfo& regs, const ShaderVertexInput
ret.ids.push_back(r.DstSelY());
ret.ids.push_back(r.DstSelZ());
ret.ids.push_back(r.DstSelW());
ret.ids.push_back(r.Format());
ret.ids.push_back(r.RawFormat());
ret.ids.push_back(r.OutOfBounds());
ret.ids.push_back(static_cast<uint32_t>(r.AddTid()));
}
+1 -1
View File
@@ -29,7 +29,7 @@ ResourceDescriptorType ShaderClassifyResourceDescriptor(const uint32_t* desc) {
default: break;
}
return (raw_type & Prospero::GpuEnumValue(Prospero::ImageType::kColor1D)) == 0
return (raw_type & static_cast<uint32_t>(Prospero::ImageType::kColor1D)) == 0
? ResourceDescriptorType::Buffer
: ResourceDescriptorType::Unused;
}
+25 -15
View File
@@ -3,6 +3,7 @@
#include "common/abi.h"
#include "common/common.h"
#include "graphics/guest_gpu/gpu_defs.h"
namespace Libs::Graphics {
@@ -61,7 +62,10 @@ struct ShaderBufferResource {
[[nodiscard]] uint64_t Base48() const {
return (fields[0] | (static_cast<uint64_t>(fields[1]) << 32u)) & 0xFFFFFFFFFFFFu;
}
[[nodiscard]] uint8_t Format() const { return (fields[3] >> 12u) & 0x7Fu; }
[[nodiscard]] uint8_t RawFormat() const { return (fields[3] >> 12u) & 0x7Fu; }
[[nodiscard]] Prospero::BufferFormat Format() const {
return static_cast<Prospero::BufferFormat>(RawFormat());
}
[[nodiscard]] uint8_t OutOfBounds() const { return (fields[3] >> 28u) & 0x3u; }
[[nodiscard]] uint8_t Type() const { return (fields[3] >> 30u) & 0x3u; }
};
@@ -69,25 +73,31 @@ struct ShaderBufferResource {
struct ShaderTextureResource {
uint32_t fields[8] = {0};
[[nodiscard]] uint16_t MinLod() const { return (fields[1] >> 8u) & 0xFFFu; }
[[nodiscard]] uint8_t DstSelX() const { return (fields[3] >> 0u) & 0x7u; }
[[nodiscard]] uint8_t DstSelY() const { return (fields[3] >> 3u) & 0x7u; }
[[nodiscard]] uint8_t DstSelZ() const { return (fields[3] >> 6u) & 0x7u; }
[[nodiscard]] uint8_t DstSelW() const { return (fields[3] >> 9u) & 0x7u; }
[[nodiscard]] uint32_t DstSelXY() const { return (fields[3] >> 0u) & 0x3Fu; }
[[nodiscard]] uint32_t DstSelXYZ() const { return (fields[3] >> 0u) & 0x1FFu; }
[[nodiscard]] uint32_t DstSelXYZW() const { return (fields[3] >> 0u) & 0xFFFu; }
[[nodiscard]] uint8_t BaseLevel() const { return (fields[3] >> 12u) & 0xFu; }
[[nodiscard]] uint8_t LastLevel() const { return (fields[3] >> 16u) & 0xFu; }
[[nodiscard]] uint8_t TileMode() const { return (fields[3] >> 20u) & 0x1Fu; }
[[nodiscard]] uint8_t Type() const { return (fields[3] >> 28u) & 0xFu; }
[[nodiscard]] uint16_t MinLod() const { return (fields[1] >> 8u) & 0xFFFu; }
[[nodiscard]] uint8_t DstSelX() const { return (fields[3] >> 0u) & 0x7u; }
[[nodiscard]] uint8_t DstSelY() const { return (fields[3] >> 3u) & 0x7u; }
[[nodiscard]] uint8_t DstSelZ() const { return (fields[3] >> 6u) & 0x7u; }
[[nodiscard]] uint8_t DstSelW() const { return (fields[3] >> 9u) & 0x7u; }
[[nodiscard]] uint32_t DstSelXY() const { return (fields[3] >> 0u) & 0x3Fu; }
[[nodiscard]] uint32_t DstSelXYZ() const { return (fields[3] >> 0u) & 0x1FFu; }
[[nodiscard]] uint32_t DstSelXYZW() const { return (fields[3] >> 0u) & 0xFFFu; }
[[nodiscard]] uint8_t BaseLevel() const { return (fields[3] >> 12u) & 0xFu; }
[[nodiscard]] uint8_t LastLevel() const { return (fields[3] >> 16u) & 0xFu; }
[[nodiscard]] Prospero::TileMode TileMode() const {
return static_cast<Prospero::TileMode>((fields[3] >> 20u) & 0x1Fu);
}
[[nodiscard]] Prospero::ImageType Type() const {
return static_cast<Prospero::ImageType>((fields[3] >> 28u) & 0xFu);
}
[[nodiscard]] uint16_t Depth() const { return (fields[4] >> 0u) & 0x1FFFu; }
[[nodiscard]] uint64_t Base40() const {
return ((fields[0] | (static_cast<uint64_t>(fields[1]) << 32u)) & 0xFFFFFFFFFFu) << 8u;
}
[[nodiscard]] bool IsNull() const { return Base40() == 0; }
[[nodiscard]] uint16_t Format() const { return (fields[1] >> 20u) & 0x1FFu; }
[[nodiscard]] bool IsNull() const { return Base40() == 0; }
[[nodiscard]] Prospero::BufferFormat Format() const {
return static_cast<Prospero::BufferFormat>((fields[1] >> 20u) & 0x1FFu);
}
[[nodiscard]] uint16_t Width5() const {
return ((fields[1] >> 30u) & 0x3u) | (((fields[2] >> 0u) & 0xFFFu) << 2u);
}