mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-07 13:39:55 +00:00
test(agc): cover terminate invocation specialization, stage boundaries and disabled feature
This commit is contained in:
1 parent
0e8ce286e1
commit
0fe8527a0a
2 files changed
+58
No files matched your search
@@ -25,6 +25,7 @@
|
||||
#include "prx/libc/include/general/VabiMacros.hpp"
|
||||
#include "prx/libc/include/GuestHeap.hpp"
|
||||
#include "ImageTableAbi.hpp"
|
||||
#include "SpirvBackend/SpirvSpecialization.hpp"
|
||||
#include <spirv/unified1/spirv.hpp>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
@@ -5708,6 +5709,41 @@ void orderedPixelShaderTests() {
|
||||
if ((terminated[at] & 0xffffu) == spv::OpExtension && std::string_view(reinterpret_cast<const char*>(&terminated[at + 1])) == "SPV_KHR_terminate_invocation") ++terminateDeclarations;
|
||||
}
|
||||
Require(terminateDeclarations == 1u, "the module declared SPV_KHR_terminate_invocation " + std::to_string(terminateDeclarations) + " times");
|
||||
const auto countOps = [](std::span<const std::uint32_t> words) {
|
||||
std::map<spv::Op, std::size_t> counts;
|
||||
for (std::size_t at = 5; at < words.size() && (words[at] >> 16u) != 0; at += words[at] >> 16u) ++counts[static_cast<spv::Op>(words[at] & 0xffffu)];
|
||||
return counts;
|
||||
};
|
||||
const std::array<std::uint32_t, 4> bdaCapabilities{spv::CapabilityShader, spv::CapabilityInt64, spv::CapabilityPhysicalStorageBufferAddresses, spv::CapabilityStorageBuffer8BitAccess};
|
||||
auto unordered = orderedPixelRequest(0x20600u, bdaCapabilities, OrderedBdaPixelCode);
|
||||
unordered.target.bdaAbiVersion = ShaderRecompiler::BdaAbi::Version;
|
||||
unordered.target.supportedExtensions = terminateExtensions;
|
||||
const auto unorderedOps = countOps(ShaderRecompiler::Recompile(unordered).spirv.Words());
|
||||
Require(!unorderedOps.contains(spv::OpBeginInvocationInterlockEXT), "a pixel shader without PRIMITIVE_ORDERED_PIXEL_SHADER began the interlock");
|
||||
Require(unorderedOps.at(spv::OpTerminateInvocation) == 5u && unorderedOps.at(spv::OpKill) == 1u, "a pixel shader with BDA reads and SPV_KHR_terminate_invocation did not terminate on a fault");
|
||||
unordered.target.supportedExtensions = bdaExtensions;
|
||||
const auto unorderedKills = countOps(ShaderRecompiler::Recompile(unordered).spirv.Words());
|
||||
Require(!unorderedKills.contains(spv::OpTerminateInvocation) && unorderedKills.at(spv::OpKill) == 6u, "a pixel shader with BDA reads and no SPV_KHR_terminate_invocation did not kill on a fault");
|
||||
constexpr std::array<std::uint32_t, 12> vertexBdaCode{0x7e040f00u, 0x7e060280u, 0xdc208001u, 0x047d0002u, 0xdc308008u, 0x057d0002u, 0xbf8c3f70u, 0x4a080b04u, 0x7e0e0d04u, 0xf80008cfu, 0x07070707u, 0xbf810000u};
|
||||
const auto vertexWords = [&](std::span<const std::string_view> extensions) {
|
||||
ShaderRecompiler::RecompileRequest request{};
|
||||
request.shader = {ShaderRecompiler::ShaderStage::Vertex, 0x10000u, vertexBdaCode, 0, {}};
|
||||
request.context.waveSize = 64;
|
||||
request.context.vertex = ShaderRecompiler::ShaderVertexStageInfo{};
|
||||
request.target.vulkanVersion = 0x00401000u;
|
||||
request.target.spirvVersion = 0x00010300u;
|
||||
request.target.subgroupSize = 64;
|
||||
request.target.supportedCapabilities = bdaCapabilities;
|
||||
request.target.supportedExtensions = extensions;
|
||||
request.target.bdaAbiVersion = ShaderRecompiler::BdaAbi::Version;
|
||||
request.layout.pushConstantSizeBytes = 128;
|
||||
request.useCache = false;
|
||||
return ShaderRecompiler::Recompile(request).spirv.Words();
|
||||
};
|
||||
const auto vertexStops = vertexWords(bdaExtensions);
|
||||
const auto vertexTerminate = vertexWords(terminateExtensions);
|
||||
const auto vertexOps = countOps(vertexTerminate);
|
||||
Require(vertexStops == vertexTerminate && !vertexOps.contains(spv::OpTerminateInvocation) && !vertexOps.contains(spv::OpKill) && vertexOps.at(spv::OpReturn) > 1u, "a vertex shader with BDA reads changed its fault exit when SPV_KHR_terminate_invocation was advertised");
|
||||
expectFailure([&] { static_cast<void>(ShaderRecompiler::Recompile(orderedPixelRequest(0x30600u, plain))); }, "fragmentShaderPixelInterlock");
|
||||
}
|
||||
|
||||
@@ -6717,6 +6753,17 @@ void validationTests() {
|
||||
vertex.spirv = makeModule({.terminateInvocation = true, .omitTerminateExtension = true});
|
||||
pixel.spirv = makeModule({.fragment = true});
|
||||
expectFailure([&] { validateTerminate(true); }, "OpTerminateInvocation requires enabled shaderTerminateInvocation in a fragment shader");
|
||||
vertex.spirv = makeModule({});
|
||||
pixel.spirv = ShaderRecompiler::SpecializeSpirv(makeModule({.fragment = true, .terminateInvocation = true}));
|
||||
std::size_t terminates = 0;
|
||||
std::size_t declarations = 0;
|
||||
for (std::size_t at = 5; at < pixel.spirv.size(); at += pixel.spirv[at] >> 16u) {
|
||||
const auto op = pixel.spirv[at] & 0xffffu;
|
||||
if (op == spv::OpTerminateInvocation) ++terminates;
|
||||
if (op == spv::OpExtension && std::string_view(reinterpret_cast<const char*>(&pixel.spirv[at + 1])) == "SPV_KHR_terminate_invocation") ++declarations;
|
||||
}
|
||||
Require(terminates == 1u && declarations == 1u, "specialization dropped OpTerminateInvocation or its extension declaration");
|
||||
validateTerminate(true);
|
||||
}
|
||||
{
|
||||
ShaderRecompiler::RecompileResult vertex;
|
||||
|
||||
@@ -106,6 +106,17 @@ 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 terminating;
|
||||
VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR terminate{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR, &terminating.bda, VK_TRUE};
|
||||
terminating.device.pNext = &terminate;
|
||||
terminating.extensions.push_back("SPV_KHR_terminate_invocation");
|
||||
const AgcDriver::ShaderDeviceProfile terminated(terminating.Target(), terminating.device, terminating.limits);
|
||||
Require(std::ranges::find(terminated.Target().supportedExtensions, "SPV_KHR_terminate_invocation") != terminated.Target().supportedExtensions.end(), "enabled shaderTerminateInvocation was rejected");
|
||||
ProfileInput disabled;
|
||||
VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR disabledTerminate{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR, &disabled.bda, VK_FALSE};
|
||||
disabled.device.pNext = &disabledTerminate;
|
||||
disabled.extensions.push_back("SPV_KHR_terminate_invocation");
|
||||
Reject([&] { AgcDriver::ShaderDeviceProfile rejected(disabled.Target(), disabled.device, disabled.limits); }, "shaderTerminateInvocation");
|
||||
}
|
||||
|
||||
void CheckAbi() {
|
||||
|
||||
Reference in new issue
Block a user