mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 10:56:58 +02:00
shader: fix vertex attribute identity swizzles
This commit is contained in:
+11
-113
@@ -375,113 +375,6 @@ static void ShaderDetectBuffers(ShaderVertexInputInfo& info) {
|
||||
}
|
||||
}
|
||||
|
||||
static Prospero::BufferFormat
|
||||
VertexAttribFormatToBufferFormat(Prospero::VertexAttribFormat format) {
|
||||
struct FormatMap {
|
||||
Prospero::VertexAttribFormat vertex;
|
||||
Prospero::BufferFormat buffer;
|
||||
};
|
||||
|
||||
static constexpr FormatMap format_map[] = {
|
||||
{Prospero::VertexAttribFormat::kInvalid, Prospero::BufferFormat::kInvalid},
|
||||
{Prospero::VertexAttribFormat::k8UNorm, Prospero::BufferFormat::k8UNorm},
|
||||
{Prospero::VertexAttribFormat::k8SNorm, Prospero::BufferFormat::k8SNorm},
|
||||
{Prospero::VertexAttribFormat::k8UScaled, Prospero::BufferFormat::k8UScaled},
|
||||
{Prospero::VertexAttribFormat::k8SScaled, Prospero::BufferFormat::k8SScaled},
|
||||
{Prospero::VertexAttribFormat::k8UInt, Prospero::BufferFormat::k8UInt},
|
||||
{Prospero::VertexAttribFormat::k8SInt, Prospero::BufferFormat::k8SInt},
|
||||
{Prospero::VertexAttribFormat::k16UNorm, Prospero::BufferFormat::k16UNorm},
|
||||
{Prospero::VertexAttribFormat::k16SNorm, Prospero::BufferFormat::k16SNorm},
|
||||
{Prospero::VertexAttribFormat::k16UScaled, Prospero::BufferFormat::k16UScaled},
|
||||
{Prospero::VertexAttribFormat::k16SScaled, Prospero::BufferFormat::k16SScaled},
|
||||
{Prospero::VertexAttribFormat::k16UInt, Prospero::BufferFormat::k16UInt},
|
||||
{Prospero::VertexAttribFormat::k16SInt, Prospero::BufferFormat::k16SInt},
|
||||
{Prospero::VertexAttribFormat::k16Float, Prospero::BufferFormat::k16Float},
|
||||
{Prospero::VertexAttribFormat::k8_8UNorm, Prospero::BufferFormat::k8_8UNorm},
|
||||
{Prospero::VertexAttribFormat::k8_8SNorm, Prospero::BufferFormat::k8_8SNorm},
|
||||
{Prospero::VertexAttribFormat::k8_8UScaled, Prospero::BufferFormat::k8_8UScaled},
|
||||
{Prospero::VertexAttribFormat::k8_8SScaled, Prospero::BufferFormat::k8_8SScaled},
|
||||
{Prospero::VertexAttribFormat::k8_8UInt, Prospero::BufferFormat::k8_8UInt},
|
||||
{Prospero::VertexAttribFormat::k8_8SInt, Prospero::BufferFormat::k8_8SInt},
|
||||
{Prospero::VertexAttribFormat::k32UInt, Prospero::BufferFormat::k32UInt},
|
||||
{Prospero::VertexAttribFormat::k32SInt, Prospero::BufferFormat::k32SInt},
|
||||
{Prospero::VertexAttribFormat::k32Float, Prospero::BufferFormat::k32Float},
|
||||
{Prospero::VertexAttribFormat::k16_16UNorm, Prospero::BufferFormat::k16_16UNorm},
|
||||
{Prospero::VertexAttribFormat::k16_16SNorm, Prospero::BufferFormat::k16_16SNorm},
|
||||
{Prospero::VertexAttribFormat::k16_16UScaled, Prospero::BufferFormat::k16_16UScaled},
|
||||
{Prospero::VertexAttribFormat::k16_16SScaled, Prospero::BufferFormat::k16_16SScaled},
|
||||
{Prospero::VertexAttribFormat::k16_16UInt, Prospero::BufferFormat::k16_16UInt},
|
||||
{Prospero::VertexAttribFormat::k16_16SInt, Prospero::BufferFormat::k16_16SInt},
|
||||
{Prospero::VertexAttribFormat::k16_16Float, Prospero::BufferFormat::k16_16Float},
|
||||
{Prospero::VertexAttribFormat::k11_11_10UNorm, Prospero::BufferFormat::k11_11_10UNorm},
|
||||
{Prospero::VertexAttribFormat::k11_11_10SNorm, Prospero::BufferFormat::k11_11_10SNorm},
|
||||
{Prospero::VertexAttribFormat::k11_11_10UScaled, Prospero::BufferFormat::k11_11_10UScaled},
|
||||
{Prospero::VertexAttribFormat::k11_11_10SScaled, Prospero::BufferFormat::k11_11_10SScaled},
|
||||
{Prospero::VertexAttribFormat::k11_11_10UInt, Prospero::BufferFormat::k11_11_10UInt},
|
||||
{Prospero::VertexAttribFormat::k11_11_10SInt, Prospero::BufferFormat::k11_11_10SInt},
|
||||
{Prospero::VertexAttribFormat::k11_11_10Float, Prospero::BufferFormat::k11_11_10Float},
|
||||
{Prospero::VertexAttribFormat::k10_11_11UNorm, Prospero::BufferFormat::k10_11_11UNorm},
|
||||
{Prospero::VertexAttribFormat::k10_11_11SNorm, Prospero::BufferFormat::k10_11_11SNorm},
|
||||
{Prospero::VertexAttribFormat::k10_11_11UScaled, Prospero::BufferFormat::k10_11_11UScaled},
|
||||
{Prospero::VertexAttribFormat::k10_11_11SScaled, Prospero::BufferFormat::k10_11_11SScaled},
|
||||
{Prospero::VertexAttribFormat::k10_11_11UInt, Prospero::BufferFormat::k10_11_11UInt},
|
||||
{Prospero::VertexAttribFormat::k10_11_11SInt, Prospero::BufferFormat::k10_11_11SInt},
|
||||
{Prospero::VertexAttribFormat::k10_11_11Float, Prospero::BufferFormat::k10_11_11Float},
|
||||
{Prospero::VertexAttribFormat::k2_10_10_10UNorm, Prospero::BufferFormat::k2_10_10_10UNorm},
|
||||
{Prospero::VertexAttribFormat::k2_10_10_10SNorm, Prospero::BufferFormat::k2_10_10_10SNorm},
|
||||
{Prospero::VertexAttribFormat::k2_10_10_10UScaled,
|
||||
Prospero::BufferFormat::k2_10_10_10UScaled},
|
||||
{Prospero::VertexAttribFormat::k2_10_10_10SScaled,
|
||||
Prospero::BufferFormat::k2_10_10_10SScaled},
|
||||
{Prospero::VertexAttribFormat::k2_10_10_10UInt, Prospero::BufferFormat::k2_10_10_10UInt},
|
||||
{Prospero::VertexAttribFormat::k2_10_10_10SInt, Prospero::BufferFormat::k2_10_10_10SInt},
|
||||
{Prospero::VertexAttribFormat::k10_10_10_2UNorm, Prospero::BufferFormat::k10_10_10_2UNorm},
|
||||
{Prospero::VertexAttribFormat::k10_10_10_2SNorm, Prospero::BufferFormat::k10_10_10_2SNorm},
|
||||
{Prospero::VertexAttribFormat::k10_10_10_2UScaled,
|
||||
Prospero::BufferFormat::k10_10_10_2UScaled},
|
||||
{Prospero::VertexAttribFormat::k10_10_10_2SScaled,
|
||||
Prospero::BufferFormat::k10_10_10_2SScaled},
|
||||
{Prospero::VertexAttribFormat::k10_10_10_2UInt, Prospero::BufferFormat::k10_10_10_2UInt},
|
||||
{Prospero::VertexAttribFormat::k10_10_10_2SInt, Prospero::BufferFormat::k10_10_10_2SInt},
|
||||
{Prospero::VertexAttribFormat::k8_8_8_8UNorm, Prospero::BufferFormat::k8_8_8_8UNorm},
|
||||
{Prospero::VertexAttribFormat::k8_8_8_8SNorm, Prospero::BufferFormat::k8_8_8_8SNorm},
|
||||
{Prospero::VertexAttribFormat::k8_8_8_8UScaled, Prospero::BufferFormat::k8_8_8_8UScaled},
|
||||
{Prospero::VertexAttribFormat::k8_8_8_8SScaled, Prospero::BufferFormat::k8_8_8_8SScaled},
|
||||
{Prospero::VertexAttribFormat::k8_8_8_8UInt, Prospero::BufferFormat::k8_8_8_8UInt},
|
||||
{Prospero::VertexAttribFormat::k8_8_8_8SInt, Prospero::BufferFormat::k8_8_8_8SInt},
|
||||
{Prospero::VertexAttribFormat::k32_32UInt, Prospero::BufferFormat::k32_32UInt},
|
||||
{Prospero::VertexAttribFormat::k32_32SInt, Prospero::BufferFormat::k32_32SInt},
|
||||
{Prospero::VertexAttribFormat::k32_32Float, Prospero::BufferFormat::k32_32Float},
|
||||
{Prospero::VertexAttribFormat::k16_16_16_16UNorm,
|
||||
Prospero::BufferFormat::k16_16_16_16UNorm},
|
||||
{Prospero::VertexAttribFormat::k16_16_16_16SNorm,
|
||||
Prospero::BufferFormat::k16_16_16_16SNorm},
|
||||
{Prospero::VertexAttribFormat::k16_16_16_16UScaled,
|
||||
Prospero::BufferFormat::k16_16_16_16UScaled},
|
||||
{Prospero::VertexAttribFormat::k16_16_16_16SScaled,
|
||||
Prospero::BufferFormat::k16_16_16_16SScaled},
|
||||
{Prospero::VertexAttribFormat::k16_16_16_16UInt, Prospero::BufferFormat::k16_16_16_16UInt},
|
||||
{Prospero::VertexAttribFormat::k16_16_16_16SInt, Prospero::BufferFormat::k16_16_16_16SInt},
|
||||
{Prospero::VertexAttribFormat::k16_16_16_16Float,
|
||||
Prospero::BufferFormat::k16_16_16_16Float},
|
||||
{Prospero::VertexAttribFormat::k32_32_32UInt, Prospero::BufferFormat::k32_32_32UInt},
|
||||
{Prospero::VertexAttribFormat::k32_32_32SInt, Prospero::BufferFormat::k32_32_32SInt},
|
||||
{Prospero::VertexAttribFormat::k32_32_32Float, Prospero::BufferFormat::k32_32_32Float},
|
||||
{Prospero::VertexAttribFormat::k32_32_32_32UInt, Prospero::BufferFormat::k32_32_32_32UInt},
|
||||
{Prospero::VertexAttribFormat::k32_32_32_32SInt, Prospero::BufferFormat::k32_32_32_32SInt},
|
||||
{Prospero::VertexAttribFormat::k32_32_32_32Float,
|
||||
Prospero::BufferFormat::k32_32_32_32Float},
|
||||
};
|
||||
|
||||
for (const auto& entry: format_map) {
|
||||
if (format == entry.vertex) {
|
||||
return entry.buffer;
|
||||
}
|
||||
}
|
||||
|
||||
return static_cast<Prospero::BufferFormat>(static_cast<uint32_t>(format));
|
||||
}
|
||||
|
||||
static void ShaderApplyAttribSemantics(ShaderVertexInputInfo& info,
|
||||
const ShaderSemantic* input_semantics,
|
||||
uint32_t num_input_semantics, const uint32_t* attrib,
|
||||
@@ -536,18 +429,23 @@ static void ShaderApplyAttribSemantics(ShaderVertexInputInfo& info,
|
||||
r.fields[2] = sharp[2];
|
||||
r.fields[3] = sharp[3];
|
||||
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);
|
||||
const auto format_raw = static_cast<uint32_t>(format);
|
||||
const auto buffer_format = format_raw >> 2u;
|
||||
const auto channels = (format_raw & 3u) + 1u;
|
||||
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 "
|
||||
LOGF("\t PS5 vertex attrib semantic %u uses attrib format %u -> buffer "
|
||||
"format %u, offset %u, buffer index %zu\n",
|
||||
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);
|
||||
// AGC vertex formats encode the buffer format above the two channel-count bits.
|
||||
// The fetch prolog selects X001, XY01, XYZ1, or XYZW from that count.
|
||||
r.fields[3] = (r.fields[3] & ~((0x7fu << 12u) | 0xfffu)) |
|
||||
((buffer_format_raw & 0x7fu) << 12u) | DstSel(4, 5, 6, 7);
|
||||
(buffer_format << 12u) |
|
||||
DstSel(4, channels > 1u ? 5u : 0u, channels > 2u ? 6u : 0u,
|
||||
channels > 3u ? 7u : 1u);
|
||||
}
|
||||
if (offset != 0) {
|
||||
r.UpdateAddress48(r.Base48() + offset);
|
||||
|
||||
@@ -9221,6 +9221,7 @@ void TestEmbeddedVertexFormatSwizzle() {
|
||||
Prospero::BufferFormat format;
|
||||
uint32_t swizzle, opcode, components, source_width;
|
||||
std::array<uint32_t, 4> expected;
|
||||
Prospero::VertexAttribFormat attribute_format = Prospero::VertexAttribFormat::kInvalid;
|
||||
};
|
||||
const Case cases[] = {
|
||||
{Prospero::BufferFormat::k32_32_32Float, DstSel(4, 5, 6, 7), 3, 4, 3,
|
||||
@@ -9237,18 +9238,50 @@ void TestEmbeddedVertexFormatSwizzle() {
|
||||
{0x3f800000, 0, 0x3f800000, 0}},
|
||||
{Prospero::BufferFormat::k32_32_32_32Float, DstSel(7, 6, 5, 4), 0x0e, 4, 4,
|
||||
{0x3e800000, 0x3f000000, 0x3f400000, 0x40000000}},
|
||||
{Prospero::BufferFormat::k32UInt, DstSel(7, 6, 5, 4), 3, 4, 1,
|
||||
{0x3e800000, 0, 0, 1}, Prospero::VertexAttribFormat::k32UInt},
|
||||
{Prospero::BufferFormat::k32_32Float, DstSel(7, 6, 5, 4), 3, 4, 2,
|
||||
{0x3e800000, 0x3f000000, 0, 0x3f800000}, Prospero::VertexAttribFormat::k32_32Float},
|
||||
{Prospero::BufferFormat::k32_32_32Float, DstSel(7, 6, 5, 4), 3, 4, 3,
|
||||
{0x3e800000, 0x3f000000, 0x3f400000, 0x3f800000},
|
||||
Prospero::VertexAttribFormat::k32_32_32Float},
|
||||
{Prospero::BufferFormat::k32_32_32_32Float, DstSel(7, 6, 5, 4), 3, 4, 4,
|
||||
{0x3e800000, 0x3f000000, 0x3f400000, 0x40000000},
|
||||
Prospero::VertexAttribFormat::k32_32_32_32Float},
|
||||
};
|
||||
std::array<uint16_t, static_cast<size_t>(AgcDirectResourceType::Last) + 1> offsets;
|
||||
offsets.fill(AGC_ILLEGAL_DIRECT_OFFSET);
|
||||
offsets[static_cast<size_t>(AgcDirectResourceType::PtrVertexBufferTable)] = 0;
|
||||
offsets[static_cast<size_t>(AgcDirectResourceType::PtrVertexAttribDescTable)] = 2;
|
||||
ShaderUserData user_data{};
|
||||
user_data.direct_resource_offset = offsets.data();
|
||||
user_data.direct_resource_count = static_cast<uint16_t>(offsets.size());
|
||||
for (const auto &test : cases) {
|
||||
const uint32_t code[] = {EncodeMubuf0(test.opcode), EncodeMubuf1(9, 0, 0),
|
||||
EncodeExp0(0x20, (1u << test.components) - 1u),
|
||||
EncodeExp1(9, 10, 11, 12), EncodeSopp(0x01)};
|
||||
Decoder::Program decoded;
|
||||
Decoder::DecodeProgram(code, decoded);
|
||||
const uint32_t attribute = static_cast<uint32_t>(test.attribute_format) << 5u;
|
||||
const uint32_t buffer[] = {0x10000000u, 16u << 16u, 1u,
|
||||
(static_cast<uint32_t>(test.format) << 12u) | test.swizzle};
|
||||
HW::VertexShaderInfo regs{};
|
||||
regs.es_regs.data_addr = reinterpret_cast<uint64_t>(code);
|
||||
regs.gs_regs.rsrc2.user_sgpr = 4;
|
||||
const uint64_t tables[] = {reinterpret_cast<uint64_t>(buffer),
|
||||
reinterpret_cast<uint64_t>(&attribute)};
|
||||
std::memcpy(regs.gs_user_sgpr.value, tables, sizeof(tables));
|
||||
ShaderSemantic semantic{};
|
||||
semantic.hardware_mapping = 9;
|
||||
semantic.size_in_elements = test.components;
|
||||
ShaderMappedData mapped{};
|
||||
mapped.user_data = &user_data;
|
||||
mapped.input_semantics = &semantic;
|
||||
mapped.num_input_semantics = 1;
|
||||
mapped.code_size_bytes = sizeof(code);
|
||||
ShaderMapUserData(regs.es_regs.data_addr, mapped);
|
||||
ShaderVertexInputInfo input{};
|
||||
input.resources_num = 1;
|
||||
input.resources[0].fields[3] = (static_cast<uint32_t>(test.format) << 12u) | test.swizzle;
|
||||
input.resources_dst[0].attr_id = 0;
|
||||
input.resources_dst[0].registers_num = static_cast<int>(test.components);
|
||||
PrepareProgram(regs, HW::Context{}, HW::UserConfig{}, input);
|
||||
Frontend::EmbeddedFetchPlan fetch;
|
||||
fetch.loads.push_back({.pc = 0, .attrib_id = 0, .components = test.components});
|
||||
Frontend::TranslateOptions options{};
|
||||
|
||||
Reference in New Issue
Block a user