fix(agc): prepare combined shader layouts when linking

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPEHi56pUMbT1X4VZwStm9
This commit is contained in:
ah 2026-10-09 01:43:56 -05:00
parent 092e133efe
commit 23443fb34d
No known key found for this signature in database
3 changed files with 26 additions and 6 deletions

View File

@ -27,6 +27,10 @@ extern "C" int APS5_VABI sceAgcLinkShaders(ShaderRegister* context, ShaderRegist
std::array<ShaderRegister, 3> primitiveValues{};
sceAgcCreatePrimState(contextValues.data(), primitiveValues.data(), nullptr, vertex, primitiveType);
sceAgcCreateInterpolantMapping_0100(contextValues.data() + 2, vertex, pixel);
if (pixel != nullptr) {
const std::array<const Shader*, 2> stages{vertex, pixel};
AgcDriverResolveGraphicsStagesAbi_nid_postfix(stages, contextValues, primitiveValues);
}
AgcDriverResolveGraphicsAbi_nid_postfix(vertex, pixel, primitiveType);
transaction.Commit();
std::copy(contextValues.begin(), contextValues.end(), context);

View File

@ -17,6 +17,9 @@ namespace {
std::array<ShaderRegister, 2> preparedContext;
std::array<ShaderRegister, 3> preparedPrimitive;
std::size_t stageCount = 0;
std::array<const Shader*, 2> linkedStages{};
std::size_t linkedStageCount = 0;
std::size_t linkedContextCount = 0;
unsigned preparations = 0;
unsigned mappings = 0;
unsigned links = 0;
@ -48,10 +51,17 @@ void OptionalGeometryOutputRegister(ShaderSpecialRegs& special, const Shader& ve
}
extern "C" void AgcDriverResolveGraphicsStagesAbi_nid_postfix(std::span<const Shader* const> stages, std::span<const ShaderRegister> context, std::span<const ShaderRegister> primitive) {
Require(context.size() == 2 && primitive.size() == 3);
std::copy(context.begin(), context.end(), preparedContext.begin());
std::copy(primitive.begin(), primitive.end(), preparedPrimitive.begin());
stageCount = stages.size();
Require((context.size() == 2 || context.size() == 34) && primitive.size() == 3);
if (context.size() == 2) {
std::copy(context.begin(), context.end(), preparedContext.begin());
std::copy(primitive.begin(), primitive.end(), preparedPrimitive.begin());
stageCount = stages.size();
} else {
Require(stages.size() == 2);
std::copy(stages.begin(), stages.end(), linkedStages.begin());
linkedStageCount = stages.size();
linkedContextCount = context.size();
}
++preparations;
}
@ -148,7 +158,11 @@ int main() {
Require(rejected);
for (const auto value : interpolants) Require(value.value == 0xdeadbeef);
pixel.num_input_semantics = 1;
preparations = mappings = links = 0;
linkedStageCount = linkedContextCount = 0;
Require(sceAgcLinkShaders(linkedContext.data(), linkedPrimitive.data(), nullptr, &vertex, &pixel, 7) == 0);
Require(preparations == 2 && linkedStageCount == 2 && linkedContextCount == linkedContext.size());
Require(linkedStages[0] == &vertex && linkedStages[1] == &pixel);
preparations = mappings = links = 0;
Require(sceAgcCreatePrimState(nullptr, nullptr, nullptr, nullptr, 7) == 0);
Require(sceAgcCreateInterpolantMapping_0100(interpolants.data(), &vertex, nullptr) == 0);

View File

@ -16,7 +16,9 @@ static unsigned links = 0;
static const Shader* mappedPixel = nullptr;
extern "C" void AgcDriverResolveGraphicsStagesAbi_nid_postfix(std::span<const Shader* const> stages, std::span<const ShaderRegister> context, std::span<const ShaderRegister> primitive) {
Require(!stages.empty() && stages[0] != nullptr && context.size() == 2u && primitive.size() == 3u);
Require(!stages.empty() && stages[0] != nullptr && primitive.size() == 3u);
Require((stages.size() == 1u && context.size() == 2u) ||
(stages.size() == 2u && stages[1] == mappedPixel && context.size() == 34u));
++preparations;
}
@ -104,5 +106,5 @@ int main() {
input.default_value = 2;
Require(sceAgcLinkShaders(context.data(), primitive.data(), nullptr, &vertex, &pixel, 4) == 0);
Require(context[2].value == 0x220);
Require(preparations == 4u && mappings == 3u && links == 7u);
Require(preparations == 7u && mappings == 3u && links == 7u);
}