From 8a82811d9b02fc18cb40a281bc9fe2b3e07ca659 Mon Sep 17 00:00:00 2001 From: MarcZX100 Date: Fri, 16 Oct 2026 05:40:22 +0000 Subject: [PATCH] fix(agc): preserve draw parameter profile validation Restore the shaderDrawParameters feature guard while adding shaderTerminateInvocation support. Cover enabled and disabled DrawParameters profiles, and pass the termination feature to the correct shader validation argument. --- .../libSceAgcDriver/Execution/src/ShaderDeviceProfile.cpp | 2 ++ core/libs/prx/libSceAgcDriver/tests/Graphics.cpp | 2 +- .../libs/prx/libSceAgcDriver/tests/ShaderDeviceProfile.cpp | 7 +++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/core/libs/prx/libSceAgcDriver/Execution/src/ShaderDeviceProfile.cpp b/core/libs/prx/libSceAgcDriver/Execution/src/ShaderDeviceProfile.cpp index 45bbf6c978..df5ad7ec42 100644 --- a/core/libs/prx/libSceAgcDriver/Execution/src/ShaderDeviceProfile.cpp +++ b/core/libs/prx/libSceAgcDriver/Execution/src/ShaderDeviceProfile.cpp @@ -30,6 +30,7 @@ ShaderDeviceProfile::ShaderDeviceProfile(const ShaderRecompiler::SpirvTarget& ta const auto* barycentric = findFeatures(deviceInfo.pNext, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR); const auto* mesh = findFeatures(deviceInfo.pNext, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT); const auto* clock = findFeatures(deviceInfo.pNext, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR); + const auto* drawParameters = findFeatures(deviceInfo.pNext, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES); const auto* terminate = findFeatures(deviceInfo.pNext, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR); const auto* maintenance8 = findFeatures(deviceInfo.pNext, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_8_FEATURES_KHR); Require(target.bdaAbiVersion == ShaderRecompiler::BdaAbi::Version, "shader device profile has an incompatible BDA ABI"); @@ -65,6 +66,7 @@ ShaderDeviceProfile::ShaderDeviceProfile(const ShaderRecompiler::SpirvTarget& ta const bool meshEnabled = mesh != nullptr && mesh->meshShader == VK_TRUE; checkFeature(spv::CapabilityFragmentBarycentricKHR, barycentricEnabled, "fragmentShaderBarycentric"); checkFeature(spv::CapabilityMeshShadingEXT, meshEnabled, "meshShader"); + checkFeature(spv::CapabilityDrawParameters, drawParameters != nullptr && drawParameters->shaderDrawParameters == VK_TRUE, "shaderDrawParameters"); checkFeature(spv::CapabilityShaderClockKHR, clock != nullptr && clock->shaderSubgroupClock == VK_TRUE && clock->shaderDeviceClock == VK_TRUE, "shader clock"); Require(!target.fragmentShaderBarycentricEnabled || barycentricEnabled, "shader device profile exposes disabled barycentrics"); Require(!target.mesh || meshEnabled, "shader device profile exposes disabled mesh shaders"); diff --git a/core/libs/prx/libSceAgcDriver/tests/Graphics.cpp b/core/libs/prx/libSceAgcDriver/tests/Graphics.cpp index 5131ceaf2a..30078a407a 100644 --- a/core/libs/prx/libSceAgcDriver/tests/Graphics.cpp +++ b/core/libs/prx/libSceAgcDriver/tests/Graphics.cpp @@ -6737,7 +6737,7 @@ void validationTests() { pixel.spirv = makeModule({.fragment = true}); expectFailure([&] { AgcDriver::Graphics::ValidateShaders(shaders, state, subgroup, true); }, "requires a fragment shader"); const auto validateTerminate = [&](bool enabled) { - return AgcDriver::Graphics::ValidateShaders(shaders, state, subgroup, false, false, false, false, false, false, false, false, false, false, enabled); + return AgcDriver::Graphics::ValidateShaders(shaders, state, subgroup, false, false, false, false, false, false, false, false, false, false, false, enabled); }; vertex.spirv = makeModule({}); pixel.spirv = makeModule({.fragment = true, .terminateInvocation = true}); diff --git a/core/libs/prx/libSceAgcDriver/tests/ShaderDeviceProfile.cpp b/core/libs/prx/libSceAgcDriver/tests/ShaderDeviceProfile.cpp index 53f43075d8..f5014a3cb9 100644 --- a/core/libs/prx/libSceAgcDriver/tests/ShaderDeviceProfile.cpp +++ b/core/libs/prx/libSceAgcDriver/tests/ShaderDeviceProfile.cpp @@ -100,6 +100,7 @@ void CheckProfile() { invalid([](auto& value) { value.capabilities.push_back(spv::CapabilityStorageImageMultisample); }, "shaderStorageImageMultisample"); invalid([](auto& value) { value.capabilities.push_back(spv::CapabilityFragmentBarycentricKHR); }, "fragmentShaderBarycentric"); invalid([](auto& value) { value.capabilities.push_back(spv::CapabilityMeshShadingEXT); }, "meshShader"); + invalid([](auto& value) { value.capabilities.push_back(spv::CapabilityDrawParameters); }, "shaderDrawParameters"); invalid([](auto& value) { value.extensions.push_back("SPV_KHR_terminate_invocation"); }, "shaderTerminateInvocation"); ProfileInput enabled; enabled.capabilities.push_back(spv::CapabilitySampledImageArrayDynamicIndexing); @@ -108,6 +109,12 @@ void CheckProfile() { enabled.indexing.shaderStorageImageArrayNonUniformIndexing = VK_TRUE; const AgcDriver::ShaderDeviceProfile accepted(enabled.Target(), enabled.device, enabled.limits); Require(accepted.Target().supportedCapabilities.size() == 6u, "enabled descriptor indexing was rejected"); + ProfileInput drawParameters; + drawParameters.capabilities.push_back(spv::CapabilityDrawParameters); + VkPhysicalDeviceShaderDrawParametersFeatures drawFeatures{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, &drawParameters.bda, VK_TRUE}; + drawParameters.device.pNext = &drawFeatures; + const AgcDriver::ShaderDeviceProfile drawParametersAccepted(drawParameters.Target(), drawParameters.device, drawParameters.limits); + Require(std::ranges::find(drawParametersAccepted.Target().supportedCapabilities, spv::CapabilityDrawParameters) != drawParametersAccepted.Target().supportedCapabilities.end(), "enabled shaderDrawParameters was rejected"); ProfileInput terminating; VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR terminate{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR, &terminating.bda, VK_TRUE}; terminating.device.pNext = &terminate;