Merge branch 'main' of https://github.com/boykopovar/AnyPS5 into feat/agc-4-4-4-4-partial-writes

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
JAB-devandClaude Sonnet 5.5 committed 2026-10-23 21:18:00 +02:00
commit 8d54357e79
351 files changed
+16471 -1788

No files matched your search

+30 -6
View File
@@ -169,7 +169,7 @@ struct PreparedControlFlow {
bool Matches(const RecompileRequest& request, const SwappcInfo& swappcInfo) const {
return stage == request.shader.stage && mergedHull == MergedHullStage(request) && swappc.fetchCallAllowed == swappcInfo.fetchCallAllowed &&
swappc.userDataBaseRegister == swappcInfo.userDataBaseRegister && swappc.userDataCount == swappcInfo.userDataCount &&
swappc.userDataBaseRegister == swappcInfo.userDataBaseRegister && swappc.userDataCount == swappcInfo.userDataCount && swappc.waveSize == swappcInfo.waveSize &&
std::ranges::equal(fallbacks, swappcInfo.linkedCallFallbacks) && std::ranges::equal(code, request.shader.code);
}
@@ -189,7 +189,7 @@ struct PreparedControlFlow {
std::shared_ptr<const PreparedControlFlow> ShaderPreparationContext::AcquireFrontend(const RecompileRequest& request) {
const auto inputInfo = RequestInputInfo(request);
const SwappcInfo swappc{inputInfo.vertex != nullptr, request.context.userDataBaseRegister, static_cast<std::uint32_t>(request.context.userData.size()), 0u, request.context.linkedCallFallbacks};
const SwappcInfo swappc{inputInfo.vertex != nullptr, request.context.userDataBaseRegister, static_cast<std::uint32_t>(request.context.userData.size()), request.context.waveSize, request.context.linkedCallFallbacks};
static const bool reuse = std::getenv("APS5_NO_PERF_FRONTEND_PAIR") == nullptr;
if (reuse && frontend != nullptr && frontend->Matches(request, swappc)) {
return frontend;
@@ -605,6 +605,9 @@ CompiledVariant emitVariant(const RecompileRequest& request, IrProgram& program)
targetOptions.robustBufferAccess2 = request.target.robustBufferAccess2;
targetOptions.float32FlushToZero = request.target.float32FlushToZero;
targetOptions.float32DenormPreserve = request.target.float32DenormPreserve;
targetOptions.fusedExactArithmetic = request.target.fusedExactArithmetic;
targetOptions.largePixelFunctionLdsBuffer = request.target.largePixelFunctionLdsBuffer;
targetOptions.pixelFunctionStorageDwords = request.target.pixelFunctionStorageDwords;
targetOptions.meshBarycentricPixel = request.shader.stage == ShaderStage::Fragment && request.graphics && request.graphics->mesh;
if (request.shader.stage == ShaderStage::Mesh && request.graphics && request.graphics->meshBarycentrics) {
const auto& paired = *request.graphics->meshBarycentrics;
@@ -649,18 +652,19 @@ CompiledVariant emitVariant(const RecompileRequest& request, IrProgram& program)
} catch (const SpannedWaveUnsupported& error) {
std::fprintf(stderr, "[spanned-wave] 0x%llx falls back to two lanes per invocation: %s\n", static_cast<unsigned long long>(request.shader.codeAddress), error.what());
targetOptions.spannedWaves = false;
result.spirv = spirvEmitter.Emit(program, inputInfo, bindings, targetOptions);
result.spirv = spirvEmitter.Emit(program, inputInfo, bindings, targetOptions, &emitted);
}
if (registration && result.spirv.size() > request.target.registrationWordLimit) {
registration = false;
program.Metadata().bindingLayoutComplete = false;
bindings = bindingAllocator.Allocate(program, request.layout, false, stencilReplay);
targetOptions.registrationModules = false;
result.spirv = spirvEmitter.Emit(program, inputInfo, bindings, targetOptions);
result.spirv = spirvEmitter.Emit(program, inputInfo, bindings, targetOptions, &emitted);
}
result.registrationModule = registration;
if (request.shader.stage == ShaderStage::Mesh && request.graphics) result.meshBarycentrics = request.graphics->meshBarycentrics;
result.stencilReplaySafe = (request.shader.stage == ShaderStage::Vertex || stencilReplay) && StencilReplaySafe(program);
result.bdaWrites = program.Info().bdaWrites;
if (stencilReplay) {
result.stencilReferences = StencilReferenceValues(program, request.context.pixel.has_value() && request.context.pixel->stencilOperationValueExport ? 8u : 0u);
result.stencilReferenceDword = bindings.layout.stencilReferenceDword;
@@ -673,6 +677,7 @@ CompiledVariant emitVariant(const RecompileRequest& request, IrProgram& program)
result.runtimeImageCount = bindings.layout.runtimeImageCount;
result.hostSubgroupSize = HostSubgroupSize(request);
result.fullSubgroups = emitted.fullSubgroups;
result.functionLdsBuffer = emitted.functionLdsBuffer;
result.vertexOffsetSgpr = program.Info().vertexOffsetSgpr;
result.instanceOffsetSgpr = program.Info().instanceOffsetSgpr;
result.vertexOffsetShared = program.Info().vertexOffsetShared;
@@ -833,17 +838,19 @@ std::shared_ptr<const SpecializedModule> buildSpecializedModule(const CompiledSh
#endif
auto module = std::make_shared<SpecializedModule>();
std::map<std::uint32_t, std::uint32_t> bindingNumbers;
std::unordered_set<std::uint32_t> functionLdsBuffer;
for (std::size_t cursor = 5; cursor < materialized.size();) {
const auto count = materialized[cursor] >> 16u;
const auto op = static_cast<spv::Op>(materialized[cursor] & 0xffffu);
if (op == spv::OpDecorate && count == 4u && materialized[cursor + 2u] == spv::DecorationBinding) bindingNumbers.emplace(materialized[cursor + 1u], materialized[cursor + 3u]);
if (op == spv::OpVariable && count >= 4u) {
if (op == spv::OpDecorate && count == 4u && materialized[cursor + 2u] == spv::DecorationDescriptorSet && materialized[cursor + 3u] == PixelFunctionLdsDescriptorSet) functionLdsBuffer.insert(materialized[cursor + 1u]);
if (op == spv::OpVariable && count >= 4u && !functionLdsBuffer.contains(materialized[cursor + 2u])) {
if (const auto found = bindingNumbers.find(materialized[cursor + 2u]); found != bindingNumbers.end()) module->bindings.push_back(found->second);
module->pushData |= materialized[cursor + 3u] == spv::StorageClassPushConstant;
}
cursor += count;
}
module->spirv = std::move(materialized);
module->spirv = InternSpirv(std::move(materialized));
module->specializationId = constants.empty() ? 0u : nextVariantId();
return module;
}
@@ -1018,12 +1025,14 @@ RecompileResult materializeResult(const CompiledVariant& variant, const Recompil
.instanceOffsetConflict = artifact.instanceOffsetConflict,
.hostSubgroupSize = artifact.hostSubgroupSize,
.fullSubgroups = artifact.fullSubgroups,
.functionLdsBuffer = artifact.functionLdsBuffer,
.parameterExports = artifact.parameterExports,
.fragmentParameters = artifact.fragmentParameters,
.barycentricEmulation = artifact.barycentricEmulation,
.meshBarycentrics = artifact.meshBarycentrics,
.stencilReferences = artifact.stencilReferences,
.stencilReplaySafe = artifact.stencilReplaySafe,
.bdaWrites = artifact.bdaWrites,
.stencilReferenceDword = artifact.stencilReferenceDword,
.variantId = artifact.variantId
};
@@ -1143,6 +1152,7 @@ RecompileResult materializeResult(const CompiledVariant& variant, const Recompil
DescriptorBindingBuilder{}.Populate(bindings, variant.bindings, *bindingPlan, variant.info.userDataBase, snapshot, partialThreads(request), &tables);
result.workgroupMemoryDwords = WorkgroupMemoryStrideDwords(variant.info.info);
result.bindings = std::move(bindings.bindings);
if (std::ranges::none_of(result.bindings, [](const DescriptorBinding& binding) { return binding.role == DescriptorRole::BdaPagetable || binding.role == DescriptorRole::FaultBuffer; })) result.bdaAbiVersion = 0u;
result.pushConstants = std::move(bindings.pushConstants);
result.readsDepthRemapPush = depthRemap;
if (request.shader.stage == ShaderStage::Compute) {
@@ -1185,6 +1195,20 @@ bool sameLayout(const BindingLayout& left, const BindingLayout& right) {
}
SharedSpirv InternSpirv(std::vector<std::uint32_t> words) {
SharedSpirv spirv(std::move(words));
const auto hash = spirv.ContentHash();
static std::mutex mutex;
static std::unordered_map<std::uint64_t, std::vector<SharedSpirv>> interned;
std::lock_guard lock(mutex);
auto& candidates = interned[hash.low ^ (hash.high * 0x9e3779b97f4a7c15ull)];
for (const auto& candidate : candidates) {
if (candidate.ContentHash() == hash && candidate == spirv) return candidate;
}
candidates.push_back(spirv);
return spirv;
}
MeshOutputBudget MeshBarycentricOutputBudget(const MeshConfiguration& mesh, const MeshTargetLimits& limits, const MeshOutputUse& use) {
const auto alignUp = [](std::uint64_t value, std::uint64_t granularity) { return granularity <= 1u ? value : (value + granularity - 1u) / granularity * granularity; };
MeshOutputBudget budget;