fix(agc): accept core Vulkan capabilities during compute replay
This commit is contained in:
parent
598e991bca
commit
3740c233bc
|
|
@ -73,6 +73,24 @@ void require(bool condition, const char* reason) {
|
|||
if (!condition) throw std::runtime_error(std::string("Vulkan presentation: ") + reason);
|
||||
}
|
||||
|
||||
bool CoreVulkanCapability(std::uint32_t capability) {
|
||||
switch (capability) {
|
||||
case spv::CapabilityMatrix:
|
||||
case spv::CapabilityShader:
|
||||
case spv::CapabilityInputAttachment:
|
||||
case spv::CapabilitySampled1D:
|
||||
case spv::CapabilityImage1D:
|
||||
case spv::CapabilitySampledBuffer:
|
||||
case spv::CapabilityImageBuffer:
|
||||
case spv::CapabilityImageQuery:
|
||||
case spv::CapabilityDerivativeControl:
|
||||
case spv::CapabilityStorageImageExtendedFormats:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void CreateComputePipeline(VkDevice device, PFN_vkCreateComputePipelines create, VkPipelineCache cache, VkShaderModule module, VkPipelineLayout layout, VkPipelineCreateFlags flags, VkPipelineShaderStageCreateFlags stageFlags, const VkSpecializationInfo* specialization, std::uint32_t subgroupSize, VkPipeline* pipeline) {
|
||||
VkComputePipelineCreateInfo info{VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO};
|
||||
info.flags = flags;
|
||||
|
|
@ -722,7 +740,7 @@ ComputePipelineReplayResult VulkanDevice::ReplayComputePipeline(const ComputePip
|
|||
for (std::size_t cursor = 5; cursor < capture.spirv.size(); cursor += capture.spirv[cursor] >> 16u) {
|
||||
const auto count = capture.spirv[cursor] >> 16u;
|
||||
if ((capture.spirv[cursor] & 0xffffu) == spv::OpCapability) {
|
||||
require(count == 2 && std::ranges::find(target.supportedCapabilities, capture.spirv[cursor + 1]) != target.supportedCapabilities.end(), "captured SPIR-V capability is not enabled");
|
||||
require(count == 2 && (CoreVulkanCapability(capture.spirv[cursor + 1]) || std::ranges::find(target.supportedCapabilities, capture.spirv[cursor + 1]) != target.supportedCapabilities.end()), "captured SPIR-V capability is not enabled");
|
||||
}
|
||||
}
|
||||
#if ANYPS5_ENABLE_SPIRV_TOOLS
|
||||
|
|
|
|||
|
|
@ -38,6 +38,23 @@ int main() {
|
|||
std::printf("skipped, no usable Vulkan device: %s\n", error.what());
|
||||
return 77;
|
||||
}
|
||||
auto sampled1D = decoded;
|
||||
sampled1D.spirv.insert(sampled1D.spirv.begin() + 7, {0x00020011u, 43u});
|
||||
CheckResult(device->ReplayComputePipeline(sampled1D));
|
||||
std::puts("compute pipeline replay: core Vulkan Sampled1D capability compiled");
|
||||
for (const auto capability : {6u, 0xffffffffu}) {
|
||||
auto unsupported = decoded;
|
||||
unsupported.spirv.insert(unsupported.spirv.begin() + 7, {0x00020011u, capability});
|
||||
bool refused = false;
|
||||
try {
|
||||
device->ReplayComputePipeline(unsupported);
|
||||
} catch (const std::exception& error) {
|
||||
Require(std::string_view(error.what()) == "Vulkan presentation: captured SPIR-V capability is not enabled", "unsupported capability failed outside the replay capability guard");
|
||||
refused = true;
|
||||
}
|
||||
Require(refused, "non-Vulkan or unknown SPIR-V capability accepted");
|
||||
}
|
||||
std::puts("compute pipeline replay: non-Vulkan Kernel and unknown capabilities rejected");
|
||||
const auto fresh = device->ReplayComputePipeline(decoded);
|
||||
CheckResult(fresh);
|
||||
Require(fresh.initialCacheBytes == 0, "fresh replay imported cache bytes");
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ build/core/libs/prx/libSceAgcDriver/agc_compute_pipeline_replay capture.aps5cp -
|
|||
build/core/libs/prx/libSceAgcDriver/agc_compute_pipeline_replay capture.aps5cp --cache-in pipeline.cache --output imported.json
|
||||
```
|
||||
|
||||
On Windows use `agc_compute_pipeline_replay.exe` and prepend `build/core/libs/libs/unpatched` to the process `PATH`. `ANYPS5_GPU` selects a device by name as for the driver. The tool uses the driver's compute pipeline creation path, without recording commands, dispatching work or importing guest memory. Compile-only devices also enable supported partially-bound, variable-count and runtime-array descriptor features to replay captured layouts; ordinary runtime devices are unchanged. Binding flags are preserved independently of update-after-bind. Unsupported features, non-highest variable bindings and counts exceeding layout support fail explicitly. Unsupported inputs and mismatched cache vendor, device or UUID fail explicitly. Output files must not already exist.
|
||||
On Windows use `agc_compute_pipeline_replay.exe` and prepend `build/core/libs/libs/unpatched` to the process `PATH`. `ANYPS5_GPU` selects a device by name as for the driver. The tool uses the driver's compute pipeline creation path, without recording commands, dispatching work or importing guest memory. Compile-only devices also enable supported partially-bound, variable-count and runtime-array descriptor features to replay captured layouts; ordinary runtime devices are unchanged. Binding flags are preserved independently of update-after-bind. Replay accepts the unconditional Vulkan 1.0 capabilities listed in the pinned [Vulkan registry](https://github.com/KhronosGroup/Vulkan-Headers/blob/2fa203425eb4af9dfc6b03f97ef72b0b5bcb8350/registry/vk.xml); other capabilities must be enabled by the device target. Non-Vulkan capabilities such as Kernel and unknown capabilities fail before pipeline creation. Unsupported features, non-highest variable bindings and counts exceeding layout support fail explicitly. Unsupported inputs and mismatched cache vendor, device or UUID fail explicitly. Output files must not already exist.
|
||||
|
||||
Each invocation creates one pipeline. With no `--cache-in`, its application pipeline cache starts empty; `--cache-in` imports a raw cache previously written by `--cache-out` (at most 64 MiB), and `--cache-out` exports the resulting cache. The title's wrapped `vk-pipelines-*.bin` format is not accepted. It does not load or save the title's usual pipeline cache. NVIDIA and other driver caches remain uncontrolled: a fresh application cache is not a cold driver cache. JSON reports the capture identity, GPU/driver identifiers, word count, cache policy and separate wall times for shader module, layouts, pipeline creation and cache work. Device initialization is outside these timings. Pipeline statistics captures and `APS5_PIPELINE_STATS` are refused because they change compilation cost.
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue