#include "Recompiler.hpp" #include #include #include #include #include #include #include namespace { constexpr std::array BarrierExport{0xbf8a0000u, 0xf80008cfu, 0u, 0xbf810000u}; constexpr std::array BarrierLdsExport{0xd8340000u, 0u, 0xbf8a0000u, 0xf80008cfu, 0u, 0xbf810000u}; constexpr std::array VertexCapabilities{spv::CapabilityClipDistance}; ShaderRecompiler::RecompileRequest vertexRequest(std::span code) { using namespace ShaderRecompiler; RecompileRequest request{}; request.shader = {ShaderStage::Vertex, 0x10000u, code, 0, {}}; request.context.waveSize = 32; request.context.vertex = ShaderVertexStageInfo{}; request.target.vulkanVersion = 0x00401000u; request.target.spirvVersion = 0x00010300u; request.target.subgroupSize = 32; request.target.supportedCapabilities = VertexCapabilities; request.layout.pushConstantSizeBytes = 128; request.useCache = false; return request; } bool hasControlBarrier(const ShaderRecompiler::RecompileResult& result) { const auto& words = result.spirv.Words(); for (std::size_t at = 5; at < words.size() && (words[at] >> 16u) != 0; at += words[at] >> 16u) { if (static_cast(words[at] & 0xffffu) == spv::OpControlBarrier) return true; } return false; } void verifyBarrierWithoutMemory() { const auto result = ShaderRecompiler::Recompile(vertexRequest(BarrierExport)); if (hasControlBarrier(result)) throw std::runtime_error("a vertex program's s_barrier became a workgroup OpControlBarrier, which the Vertex execution model does not allow"); } void verifyBarrierWithLds() { try { (void)ShaderRecompiler::Recompile(vertexRequest(BarrierLdsExport)); } catch (const std::exception& error) { if (std::string(error.what()).find("s_barrier in a vertex program that accesses LDS or GDS or writes memory is not implemented") != std::string::npos) return; throw; } throw std::runtime_error("a vertex program with s_barrier and an LDS write compiled"); } } // namespace int main() { try { verifyBarrierWithoutMemory(); verifyBarrierWithLds(); std::cout << "vertex barrier tests passed\n"; return 0; } catch (const std::exception& error) { const std::string message(error.what()); std::cerr << message.substr(0, message.find("RecompileRequest:")) << '\n'; return 1; } }