shader: fix embedded vertex fetch swizzles

This commit is contained in:
nmzik
2026-09-05 16:00:46 +04:00
parent 9c00c7077b
commit 81a5dd612f
11 changed files with 163 additions and 120 deletions
@@ -1,4 +1,5 @@
#include "common/assert.h"
#include "graphics/shader/recompiler/BufferFormat.h"
#include "graphics/shader/recompiler/frontend/translate/Translator.h"
#include <algorithm>
@@ -47,10 +48,27 @@ IR::ExportFlags Translator::AddExportInfo(const Decoder::Instruction& inst) {
}
void Translator::TranslateEmbeddedFetch(const Decoder::Instruction& inst, uint32_t attribute,
uint32_t component_count) {
uint32_t component_count,
const ShaderBufferResource& resource) {
const auto format = Format::GetFormatInfo(resource.Format());
for (uint32_t component = 0; component < component_count; component++) {
const auto value =
ir.Emit(IR::ValueOpcode::GetAttribute, {IR::Value(attribute), IR::Value(component)});
auto source = Format::FormattedSource {Format::FormattedSourceKind::Memory, component};
if (inst.formatted && !inst.typed) {
source = Format::ResolveFormattedSource(
format, GetDstSel(resource.DstSelXYZW(), component));
if (source.kind == Format::FormattedSourceKind::Invalid) {
EXIT("invalid formatted vertex input %u at pc 0x%08x", attribute, inst.pc);
}
}
IR::Value value;
if (source.kind == Format::FormattedSourceKind::Memory) {
value = ir.Emit(IR::ValueOpcode::GetAttribute,
{IR::Value(attribute), IR::Value(source.component)});
auto& required = program.info.vertex_fetch_components[attribute];
required = static_cast<uint8_t>(std::max<uint32_t>(required, source.component + 1u));
} else {
value = IR::Value(Format::FormattedConstantBits(format, source.kind));
}
WriteOperand(OffsetOperand(inst.dst, component), value);
}
}
@@ -1204,12 +1204,9 @@ IR::Program TranslateProgram(const Decoder::Program& decoded, const CFG::Graph&
EXIT("embedded vertex fetch at 0x%08x has no resource for attribute %d",
instruction.pc, embedded->attrib_id);
}
result.info.vertex_fetch_components[static_cast<size_t>(resource)] =
static_cast<uint8_t>(std::max<uint32_t>(
result.info.vertex_fetch_components[static_cast<size_t>(resource)],
embedded->components));
translator.TranslateEmbeddedFetch(instruction, static_cast<uint32_t>(resource),
embedded->components);
embedded->components,
options.vertex->resources[resource]);
continue;
}
translator.TranslateInstruction(instruction);
@@ -15,7 +15,7 @@ public:
void TranslateInstruction(const Decoder::Instruction& inst);
void TranslateEmbeddedFetch(const Decoder::Instruction& inst, uint32_t attribute,
uint32_t component_count);
uint32_t component_count, const ShaderBufferResource& resource);
void AddBranchCondition(const CFG::BasicBlock& source, IR::BlockInfo& info);
private: