Merge pull request #3258 from oneandonlydean/carry/2480-vertex-fetch-aliasing

fix(shader): preserve aliased embedded fetch attributes
This commit is contained in:
Dean 2026-10-11 18:23:47 +13:00 committed by GitHub
commit 1ae5b2fe5a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 47 additions and 2 deletions

View File

@ -1485,3 +1485,16 @@ if(BUILD_TESTING)
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libc>")
endif()
endif()
add_test_executable(agc_embedded_vertex_fetch_aliasing_tests EXCLUDE_FROM_ALL tests/EmbeddedVertexFetchAliasing.cpp)
target_link_libraries(agc_embedded_vertex_fetch_aliasing_tests PRIVATE shader_recompiler_agc_driver libc)
set_target_properties(agc_embedded_vertex_fetch_aliasing_tests PROPERTIES CXX_EXTENSIONS OFF)
configure_windows_unwind(agc_embedded_vertex_fetch_aliasing_tests)
if(BUILD_TESTING)
set_target_properties(agc_embedded_vertex_fetch_aliasing_tests PROPERTIES EXCLUDE_FROM_ALL OFF)
add_test(NAME agc_embedded_vertex_fetch_aliasing COMMAND agc_embedded_vertex_fetch_aliasing_tests)
if(WIN32)
set_tests_properties(agc_embedded_vertex_fetch_aliasing PROPERTIES ENVIRONMENT_MODIFICATION
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libc>")
endif()
endif()

View File

@ -0,0 +1,31 @@
#include "RdnaDecoder/RdnaInstructionDecoder.hpp"
#include "Translation/EmbeddedVertexFetch.hpp"
#include <array>
#include <cstdint>
#include <cstdio>
#include <vector>
using namespace ShaderRecompiler;
int main() {
int failures = 0;
for (const std::uint32_t waveSize : {32u, 64u}) {
for (const std::uint32_t indexRegister : {0u, 1u, 2u, 3u, 16u}) {
const std::array<std::uint32_t, 8> code{
0xf4000004u | (indexRegister << 6u), 0xfa00000cu,
0xf4080005u, indexRegister << 25u,
0x02140b08u,
0xe00c2000u, 0x80000b0au,
0xbf810000u,
};
const auto decoded = RdnaInstructionDecoder{}.Decode(code);
const auto plan = EmbeddedVertexFetchAnalyzer{}.Analyze(decoded, 0, 2, 0, 16, waveSize);
if (plan.loads.size() != 1 || plan.loads.front().attributeId != 3 || plan.loads.front().componentCount != 4 ||
plan.loads.front().programCounter != 20 || plan.loads.front().prologLoads != std::vector<std::uint32_t>{0, 8}) {
std::fprintf(stderr, "wave%u descriptor offset s%u lost its attribute or load provenance\n", waveSize, indexRegister);
++failures;
}
}
}
return failures == 0 ? 0 : 1;
}

View File

@ -516,12 +516,13 @@ EmbeddedFetchPlan EmbeddedVertexFetchAnalyzer::Analyze(const RdnaProgram& progra
dst.loadPcs.push_back(inst.programCounter);
}
} else if (isScalarOperand(inst.source1) && scalarSlot(inst.source1) < sgprs.size() && sgprs[scalarSlot(inst.source1)].kind == SgprValueKind::Attribute && (inst.memoryOffset & 0x3u) == 0u) {
const auto attribute = sgprs[scalarSlot(inst.source1)];
for (std::uint32_t i = 0u; i < decodedDstSize(inst) && slot + i < sgprs.size(); i++) {
auto& dst = sgprs[slot + i];
dst = SgprValue{};
dst.kind = SgprValueKind::Buffer;
dst.attributeId = sgprs[scalarSlot(inst.source1)].attributeId;
dst.loadPcs = sgprs[scalarSlot(inst.source1)].loadPcs;
dst.attributeId = attribute.attributeId;
dst.loadPcs = attribute.loadPcs;
dst.loadPcs.push_back(inst.programCounter);
}
} else {