Merge pull request #6436 from LeandroLP23/fix/agc-key-modules-by-gpl-mode

fix(agc): key shader modules by the pipeline library mode
This commit is contained in:
Dean authored and GitHub committed 2026-10-21 07:02:24 +13:00
commit 2ea00aae40
10 files changed
+55 -73

No files matched your search

@@ -538,14 +538,8 @@ PerformanceOverlay::PerformanceOverlay(const Graphics::Context& context, std::si
layoutInfo.pushConstantRangeCount = 1;
layoutInfo.pPushConstantRanges = &push;
Graphics::Check(context.Function<PFN_vkCreatePipelineLayout>("vkCreatePipelineLayout")(context.device, &layoutInfo, nullptr, &pipelineLayout), "vkCreatePipelineLayout performance overlay");
const auto createModule = context.Function<PFN_vkCreateShaderModule>("vkCreateShaderModule");
VkShaderModuleCreateInfo moduleInfo{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
moduleInfo.codeSize = sizeof(PERFORMANCE_OVERLAY_VERT_SPV);
moduleInfo.pCode = PERFORMANCE_OVERLAY_VERT_SPV;
Graphics::Check(createModule(context.device, &moduleInfo, nullptr, &vertex), "vkCreateShaderModule performance overlay vertex");
moduleInfo.codeSize = sizeof(PERFORMANCE_OVERLAY_FRAG_SPV);
moduleInfo.pCode = PERFORMANCE_OVERLAY_FRAG_SPV;
Graphics::Check(createModule(context.device, &moduleInfo, nullptr, &fragment), "vkCreateShaderModule performance overlay fragment");
vertex = Graphics::CreateShaderModule(context, PERFORMANCE_OVERLAY_VERT_SPV, sizeof(PERFORMANCE_OVERLAY_VERT_SPV), "vkCreateShaderModule performance overlay vertex");
fragment = Graphics::CreateShaderModule(context, PERFORMANCE_OVERLAY_FRAG_SPV, sizeof(PERFORMANCE_OVERLAY_FRAG_SPV), "vkCreateShaderModule performance overlay fragment");
} catch (...) {
release();
throw;
@@ -70,14 +70,8 @@ PresentationPass::PresentationPass(const Graphics::Context& context, std::size_t
tableWrites[i].pBufferInfo = &tableInfo;
}
context.Function<PFN_vkUpdateDescriptorSets>("vkUpdateDescriptorSets")(context.device, static_cast<std::uint32_t>(tableWrites.size()), tableWrites.data(), 0, nullptr);
const auto createModule = context.Function<PFN_vkCreateShaderModule>("vkCreateShaderModule");
VkShaderModuleCreateInfo moduleInfo{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
moduleInfo.codeSize = sizeof(PRESENTATION_PASS_VERT_SPV);
moduleInfo.pCode = PRESENTATION_PASS_VERT_SPV;
Graphics::Check(createModule(context.device, &moduleInfo, nullptr, &vertex), "vkCreateShaderModule presentation vertex");
moduleInfo.codeSize = sizeof(PRESENTATION_PASS_FRAG_SPV);
moduleInfo.pCode = PRESENTATION_PASS_FRAG_SPV;
Graphics::Check(createModule(context.device, &moduleInfo, nullptr, &fragment), "vkCreateShaderModule presentation fragment");
vertex = Graphics::CreateShaderModule(context, PRESENTATION_PASS_VERT_SPV, sizeof(PRESENTATION_PASS_VERT_SPV), "vkCreateShaderModule presentation vertex");
fragment = Graphics::CreateShaderModule(context, PRESENTATION_PASS_FRAG_SPV, sizeof(PRESENTATION_PASS_FRAG_SPV), "vkCreateShaderModule presentation fragment");
} catch (...) {
release();
throw;
@@ -914,10 +914,7 @@ ComputePipelineReplayResult VulkanDevice::ReplayComputePipeline(const ComputePip
check(state->DeviceFunction<PFN_vkCreatePipelineCache>("vkCreatePipelineCache")(state->device, &cacheInfo, nullptr, &replay.cache), "vkCreatePipelineCache replay");
result.cacheMilliseconds = elapsed(phase);
phase = std::chrono::steady_clock::now();
VkShaderModuleCreateInfo moduleInfo{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
moduleInfo.codeSize = capture.spirv.size() * sizeof(std::uint32_t);
moduleInfo.pCode = capture.spirv.data();
check(state->DeviceFunction<PFN_vkCreateShaderModule>("vkCreateShaderModule")(state->device, &moduleInfo, nullptr, &objects.module), "vkCreateShaderModule replay");
objects.module = Graphics::CreateShaderModule(state->DeviceFunction<PFN_vkCreateShaderModule>("vkCreateShaderModule"), state->device, state->graphicsPipelineLibrary, capture.spirv.data(), capture.spirv.size() * sizeof(std::uint32_t), "vkCreateShaderModule replay");
result.moduleMilliseconds = elapsed(phase);
phase = std::chrono::steady_clock::now();
std::array<std::array<std::uint64_t, 4>, 2> descriptorCounts{};
@@ -4872,10 +4869,7 @@ std::shared_ptr<ComputePipelineObjects> VulkanDevice::createComputePipeline(cons
objects->destroyModule = state->DeviceFunction<PFN_vkDestroyShaderModule>("vkDestroyShaderModule");
objects->destroyLayout = state->DeviceFunction<PFN_vkDestroyPipelineLayout>("vkDestroyPipelineLayout");
objects->destroyPipeline = state->DeviceFunction<PFN_vkDestroyPipeline>("vkDestroyPipeline");
VkShaderModuleCreateInfo moduleInfo{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
moduleInfo.codeSize = shader.spirv.size() * sizeof(std::uint32_t);
moduleInfo.pCode = shader.spirv.data();
check(state->DeviceFunction<PFN_vkCreateShaderModule>("vkCreateShaderModule")(state->device, &moduleInfo, nullptr, &objects->module), "vkCreateShaderModule");
objects->module = Graphics::CreateShaderModule(state->DeviceFunction<PFN_vkCreateShaderModule>("vkCreateShaderModule"), state->device, state->graphicsPipelineLibrary, shader.spirv.data(), shader.spirv.size() * sizeof(std::uint32_t), "vkCreateShaderModule");
objects->resourcesLayout = setLayout;
const std::array<VkDescriptorSetLayout, 2> setLayouts{setLayout, shader.workgroupMemoryDwords != 0 ? state->workgroupMemoryLayout : VK_NULL_HANDLE};
const VkPushConstantRange push{VK_SHADER_STAGE_COMPUTE_BIT, 0, Graphics::ComputePushConstantBytes};
@@ -4935,11 +4929,7 @@ VkPipeline VulkanDevice::splitComputePipeline(const Graphics::Context& context,
std::array<ShaderRecompiler::PipelineSpecializationConstant, ShaderRecompiler::PipelineSpecialization::WorkgroupOffsetWords> offsets{};
for (std::uint32_t component = 0; component < offsets.size(); ++component) offsets[component] = {ShaderRecompiler::PipelineSpecialization::WorkgroupOffsetBase + component, base[component]};
const Graphics::PipelineSpecialization specialization(shader, offsets);
VkShaderModuleCreateInfo moduleInfo{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
moduleInfo.codeSize = shader.spirv.size() * sizeof(std::uint32_t);
moduleInfo.pCode = shader.spirv.data();
VkShaderModule module = VK_NULL_HANDLE;
check(state->DeviceFunction<PFN_vkCreateShaderModule>("vkCreateShaderModule")(state->device, &moduleInfo, nullptr, &module), "vkCreateShaderModule");
VkShaderModule module = Graphics::CreateShaderModule(state->DeviceFunction<PFN_vkCreateShaderModule>("vkCreateShaderModule"), state->device, state->graphicsPipelineLibrary, shader.spirv.data(), shader.spirv.size() * sizeof(std::uint32_t), "vkCreateShaderModule");
VkPipeline pipeline = VK_NULL_HANDLE;
try {
CreateComputePipeline(state->device, state->DeviceFunction<PFN_vkCreateComputePipelines>("vkCreateComputePipelines"), context.pipelineCache, module, objects.layout, computePipelineFlags(), computeStageFlags(shader), specialization.Info(), computeSubgroupSize(shader), &pipeline, context.pipelineCacheSynchronization);
@@ -20,6 +20,7 @@
namespace AgcDriver::Graphics {
class TextureDetiler;
class GpuColorTransfer;
class BufferPool;
@@ -71,6 +72,17 @@ inline void Check(VkResult result, const char* operation) {
if (result != VK_SUCCESS) throw std::runtime_error(std::string("AGC graphics: ") + operation + ": Vulkan result " + std::to_string(result));
}
inline VkShaderModule CreateShaderModule(PFN_vkCreateShaderModule create, VkDevice device, bool graphicsPipelineLibrary, const std::uint32_t* code, std::size_t bytes, const char* operation) {
std::vector<std::uint32_t> keyed(code, code + bytes / sizeof(std::uint32_t));
if (!graphicsPipelineLibrary && keyed.size() > 2) keyed[2] ^= 0x8000u;
VkShaderModuleCreateInfo info{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
info.codeSize = keyed.size() * sizeof(std::uint32_t);
info.pCode = keyed.data();
VkShaderModule module = VK_NULL_HANDLE;
Check(create(device, &info, nullptr, &module), operation);
return module;
}
inline void Require(bool condition, const char* reason) {
if (!condition) throw std::runtime_error(std::string("AGC graphics: ") + reason);
}
@@ -337,6 +349,10 @@ struct Context {
}
};
inline VkShaderModule CreateShaderModule(const Context& context, const std::uint32_t* code, std::size_t bytes, const char* operation) {
return CreateShaderModule(context.Function<PFN_vkCreateShaderModule>("vkCreateShaderModule"), context.device, context.graphicsPipelineLibrary, code, bytes, operation);
}
inline void EndRenderPass(const Context& context, VkCommandBuffer commands) {
if (context.graphicsPipelineLibrary) context.Resolved(&DeviceFunctions::cmdEndRendering, "vkCmdEndRenderingKHR")(commands);
else context.Resolved(&DeviceFunctions::cmdEndRenderPass, "vkCmdEndRenderPass")(commands);
@@ -28,10 +28,7 @@ GpuColorTransfer::GpuColorTransfer(const Context& context) : context(context) {
layoutInfo.pushConstantRangeCount = 1;
layoutInfo.pPushConstantRanges = &push;
Check(context.Function<PFN_vkCreatePipelineLayout>("vkCreatePipelineLayout")(context.device, &layoutInfo, nullptr, &pipelineLayout), "vkCreatePipelineLayout color transfer");
VkShaderModuleCreateInfo moduleInfo{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
moduleInfo.codeSize = sizeof(COLOR_TRANSFER_SPV);
moduleInfo.pCode = COLOR_TRANSFER_SPV;
Check(context.Function<PFN_vkCreateShaderModule>("vkCreateShaderModule")(context.device, &moduleInfo, nullptr, &module), "vkCreateShaderModule color transfer");
module = CreateShaderModule(context, COLOR_TRANSFER_SPV, sizeof(COLOR_TRANSFER_SPV), "vkCreateShaderModule color transfer");
VkComputePipelineCreateInfo pipelineInfo{VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO};
pipelineInfo.stage = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
pipelineInfo.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
@@ -46,10 +46,8 @@ VkPipeline TextureDetiler::multisampleReadbackPipeline(std::uint32_t elementByte
}
auto& module = readbackModules[depth ? 1u : 0u];
if (module == VK_NULL_HANDLE) {
VkShaderModuleCreateInfo info{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
info.codeSize = depth ? sizeof(MULTISAMPLE_READBACK_DEPTH_SPV) : sizeof(MULTISAMPLE_READBACK_UINT_SPV);
info.pCode = depth ? MULTISAMPLE_READBACK_DEPTH_SPV : MULTISAMPLE_READBACK_UINT_SPV;
Check(context.Function<PFN_vkCreateShaderModule>("vkCreateShaderModule")(context.device, &info, nullptr, &module), "vkCreateShaderModule multisample readback");
module = depth ? CreateShaderModule(context, MULTISAMPLE_READBACK_DEPTH_SPV, sizeof(MULTISAMPLE_READBACK_DEPTH_SPV), "vkCreateShaderModule multisample readback")
: CreateShaderModule(context, MULTISAMPLE_READBACK_UINT_SPV, sizeof(MULTISAMPLE_READBACK_UINT_SPV), "vkCreateShaderModule multisample readback");
}
const VkSpecializationMapEntry entry{0u, 0u, sizeof(elementBytes)};
const VkSpecializationInfo specialization{1u, &entry, sizeof(elementBytes), &elementBytes};
@@ -359,10 +359,7 @@ Pipeline::Pipeline(const Context& context, const State& state, const VertexInput
const VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT meshSubgroup{VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT, nullptr, 32u};
for (std::uint32_t i = 0; i < shaders.size(); ++i) {
const auto& shader = *shaders[i].program;
VkShaderModuleCreateInfo module{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
module.codeSize = shader.spirv.size() * sizeof(std::uint32_t);
module.pCode = shader.spirv.data();
Check(context.Function<PFN_vkCreateShaderModule>("vkCreateShaderModule")(context.device, &module, nullptr, &_modules[i]), "vkCreateShaderModule graphics");
_modules[i] = CreateShaderModule(context, shader.spirv.data(), shader.spirv.size() * sizeof(std::uint32_t), "vkCreateShaderModule graphics");
const auto stage = VulkanStage(shaders[i].stage);
stages[i].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
stages[i].stage = stage;
@@ -1992,10 +1992,7 @@ bool Recorder::RecordDispatchArguments(VkCommandBuffer commands, VkDeviceAddress
layoutInfo.pushConstantRangeCount = 1;
layoutInfo.pPushConstantRanges = &push;
Check(context.Function<PFN_vkCreatePipelineLayout>("vkCreatePipelineLayout")(context.device, &layoutInfo, nullptr, &dispatchArgumentLayout), "vkCreatePipelineLayout dispatch arguments");
VkShaderModuleCreateInfo moduleInfo{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
moduleInfo.codeSize = sizeof(DISPATCH_ARGUMENTS_SPV);
moduleInfo.pCode = DISPATCH_ARGUMENTS_SPV;
Check(context.Function<PFN_vkCreateShaderModule>("vkCreateShaderModule")(context.device, &moduleInfo, nullptr, &module), "vkCreateShaderModule dispatch arguments");
module = CreateShaderModule(context, DISPATCH_ARGUMENTS_SPV, sizeof(DISPATCH_ARGUMENTS_SPV), "vkCreateShaderModule dispatch arguments");
VkComputePipelineCreateInfo pipelineInfo{VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO};
pipelineInfo.stage = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
pipelineInfo.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
@@ -2075,10 +2072,7 @@ bool Recorder::gpuSampleCounter() {
layoutInfo.pushConstantRangeCount = 1;
layoutInfo.pPushConstantRanges = &push;
Check(context.Function<PFN_vkCreatePipelineLayout>("vkCreatePipelineLayout")(context.device, &layoutInfo, nullptr, &sampleLayout), "vkCreatePipelineLayout sample counter");
VkShaderModuleCreateInfo moduleInfo{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
moduleInfo.codeSize = sizeof(SAMPLE_COUNTER_SPV);
moduleInfo.pCode = SAMPLE_COUNTER_SPV;
Check(context.Function<PFN_vkCreateShaderModule>("vkCreateShaderModule")(context.device, &moduleInfo, nullptr, &module), "vkCreateShaderModule sample counter");
module = CreateShaderModule(context, SAMPLE_COUNTER_SPV, sizeof(SAMPLE_COUNTER_SPV), "vkCreateShaderModule sample counter");
VkComputePipelineCreateInfo pipelineInfo{VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO};
pipelineInfo.stage = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
pipelineInfo.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
@@ -2094,9 +2088,7 @@ bool Recorder::gpuSampleCounter() {
const VkPushConstantRange dumpPush{VK_SHADER_STAGE_COMPUTE_BIT, 0, SampleDumpPushBytes};
layoutInfo.pPushConstantRanges = &dumpPush;
Check(context.Function<PFN_vkCreatePipelineLayout>("vkCreatePipelineLayout")(context.device, &layoutInfo, nullptr, &dumpLayout), "vkCreatePipelineLayout sample dumps");
moduleInfo.codeSize = sizeof(SAMPLE_DUMPS_SPV);
moduleInfo.pCode = SAMPLE_DUMPS_SPV;
Check(context.Function<PFN_vkCreateShaderModule>("vkCreateShaderModule")(context.device, &moduleInfo, nullptr, &module), "vkCreateShaderModule sample dumps");
module = CreateShaderModule(context, SAMPLE_DUMPS_SPV, sizeof(SAMPLE_DUMPS_SPV), "vkCreateShaderModule sample dumps");
pipelineInfo.stage.module = module;
pipelineInfo.layout = dumpLayout;
{
@@ -2391,10 +2383,7 @@ bool Recorder::RecordMeshArguments(VkCommandBuffer commands, VkDeviceAddress rec
layoutInfo.pushConstantRangeCount = 1;
layoutInfo.pPushConstantRanges = &push;
Check(context.Function<PFN_vkCreatePipelineLayout>("vkCreatePipelineLayout")(context.device, &layoutInfo, nullptr, &meshArgumentLayout), "vkCreatePipelineLayout mesh arguments");
VkShaderModuleCreateInfo moduleInfo{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
moduleInfo.codeSize = sizeof(MESH_ARGUMENTS_SPV);
moduleInfo.pCode = MESH_ARGUMENTS_SPV;
Check(context.Function<PFN_vkCreateShaderModule>("vkCreateShaderModule")(context.device, &moduleInfo, nullptr, &module), "vkCreateShaderModule mesh arguments");
module = CreateShaderModule(context, MESH_ARGUMENTS_SPV, sizeof(MESH_ARGUMENTS_SPV), "vkCreateShaderModule mesh arguments");
VkComputePipelineCreateInfo pipelineInfo{VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO};
pipelineInfo.stage = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
pipelineInfo.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
@@ -89,10 +89,7 @@ TextureDetiler::TextureDetiler(const Context& context) : context(context) {
pipelineLayoutInfo.pushConstantRangeCount = 1;
pipelineLayoutInfo.pPushConstantRanges = &pushRange;
Check(context.Function<PFN_vkCreatePipelineLayout>("vkCreatePipelineLayout")(context.device, &pipelineLayoutInfo, nullptr, &pipelineLayout), "vkCreatePipelineLayout");
VkShaderModuleCreateInfo moduleInfo{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
moduleInfo.codeSize = sizeof(TEXTURE_DETILE_SPV);
moduleInfo.pCode = TEXTURE_DETILE_SPV;
Check(context.Function<PFN_vkCreateShaderModule>("vkCreateShaderModule")(context.device, &moduleInfo, nullptr, &module), "vkCreateShaderModule");
module = CreateShaderModule(context, TEXTURE_DETILE_SPV, sizeof(TEXTURE_DETILE_SPV), "vkCreateShaderModule");
bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
Check(context.Function<PFN_vkCreateDescriptorSetLayout>("vkCreateDescriptorSetLayout")(context.device, &layoutInfo, nullptr, &imageDescriptorLayout), "vkCreateDescriptorSetLayout");
pipelineLayoutInfo.pSetLayouts = &imageDescriptorLayout;
@@ -168,10 +165,7 @@ VkPipeline TextureDetiler::pipeline(TextureTileMode tileMode, std::uint32_t elem
std::copy(equation->bits.begin(), equation->bits.end(), values.begin() + 4);
}
if (image && imageModule == VK_NULL_HANDLE) {
VkShaderModuleCreateInfo moduleInfo{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
moduleInfo.codeSize = sizeof(TEXTURE_DETILE_IMAGE_SPV);
moduleInfo.pCode = TEXTURE_DETILE_IMAGE_SPV;
Check(context.Function<PFN_vkCreateShaderModule>("vkCreateShaderModule")(context.device, &moduleInfo, nullptr, &imageModule), "vkCreateShaderModule");
imageModule = CreateShaderModule(context, TEXTURE_DETILE_IMAGE_SPV, sizeof(TEXTURE_DETILE_IMAGE_SPV), "vkCreateShaderModule");
}
std::array<VkSpecializationMapEntry, 22> entries{};
for (std::uint32_t index = 0; index < entries.size(); ++index) entries[index] = {index, index * 4u, 4};
@@ -273,10 +267,7 @@ void TextureDetiler::DispatchRepack(VkCommandBuffer commands, VkBuffer source, s
Require(commands != VK_NULL_HANDLE && source != VK_NULL_HANDLE && destination != VK_NULL_HANDLE, "a texel repack needs a command buffer and its buffers");
Require(bytes != 0 && bytes % 4u == 0 && sourceOffset % 4u == 0 && destinationOffset % 4u == 0, "a texel repack needs whole aligned words");
if (repackPipeline == VK_NULL_HANDLE) {
VkShaderModuleCreateInfo moduleInfo{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
moduleInfo.codeSize = sizeof(TEXTURE_REPACK_SPV);
moduleInfo.pCode = TEXTURE_REPACK_SPV;
Check(context.Function<PFN_vkCreateShaderModule>("vkCreateShaderModule")(context.device, &moduleInfo, nullptr, &repackModule), "vkCreateShaderModule repack");
repackModule = CreateShaderModule(context, TEXTURE_REPACK_SPV, sizeof(TEXTURE_REPACK_SPV), "vkCreateShaderModule repack");
VkPipelineShaderStageCreateInfo stage{VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
stage.module = repackModule;
@@ -347,11 +338,7 @@ void TextureDetiler::DispatchCmaskClear(VkCommandBuffer commands, VkBuffer cmask
pipelineLayoutInfo.pushConstantRangeCount = 1;
pipelineLayoutInfo.pPushConstantRanges = &pushRange;
Check(context.Function<PFN_vkCreatePipelineLayout>("vkCreatePipelineLayout")(context.device, &pipelineLayoutInfo, nullptr, &cmaskPipelineLayout), "vkCreatePipelineLayout CMASK clear");
VkShaderModuleCreateInfo moduleInfo{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
moduleInfo.codeSize = sizeof(CMASK_CLEAR_SPV);
moduleInfo.pCode = CMASK_CLEAR_SPV;
VkShaderModule cmaskModule = VK_NULL_HANDLE;
Check(context.Function<PFN_vkCreateShaderModule>("vkCreateShaderModule")(context.device, &moduleInfo, nullptr, &cmaskModule), "vkCreateShaderModule CMASK clear");
VkShaderModule cmaskModule = CreateShaderModule(context, CMASK_CLEAR_SPV, sizeof(CMASK_CLEAR_SPV), "vkCreateShaderModule CMASK clear");
VkComputePipelineCreateInfo pipelineInfo{VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO};
pipelineInfo.stage = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
pipelineInfo.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
@@ -8393,6 +8393,25 @@ void LineStripTests() {
Require(rejection.empty(), "the draw precheck rejected an indexed line strip with primitive restart: " + rejection);
}
std::uint32_t keyedGenerator = 0;
std::size_t keyedWords = 0;
VKAPI_ATTR VkResult VKAPI_CALL keyedCreateShaderModule(VkDevice, const VkShaderModuleCreateInfo* info, const VkAllocationCallbacks*, VkShaderModule* module) {
keyedWords = info->codeSize / sizeof(std::uint32_t);
keyedGenerator = info->pCode[2];
*module = makeHandle<VkShaderModule>();
return VK_SUCCESS;
}
void ShaderModuleKeyTests() {
const std::array<std::uint32_t, 5> code{0x07230203u, 0x00010300u, 0x00080001u, 8u, 0u};
static_cast<void>(AgcDriver::Graphics::CreateShaderModule(keyedCreateShaderModule, VK_NULL_HANDLE, true, code.data(), sizeof(code), "keyed module"));
Require(keyedWords == code.size() && keyedGenerator == 0x00080001u, "a shader module with graphics pipeline libraries changed its generator word");
static_cast<void>(AgcDriver::Graphics::CreateShaderModule(keyedCreateShaderModule, VK_NULL_HANDLE, false, code.data(), sizeof(code), "keyed module"));
Require(keyedWords == code.size() && keyedGenerator == (0x00080001u ^ 0x8000u), "a shader module without graphics pipeline libraries kept the generator word of the other mode");
Require(code[2] == 0x00080001u, "keying a shader module changed its source words");
}
void ProvokingVertexTests() {
using namespace AgcDriver::Graphics;
constexpr std::uint32_t lastVertex = 1u << 19u;
@@ -10391,6 +10410,7 @@ int main(int argc, char** argv) {
stencilReferenceUnusedTests();
aliasedBufferViewTests();
LineStripTests();
ShaderModuleKeyTests();
ProvokingVertexTests();
ProvokingVertexRenderPassTests();
ConservativeRasterizationTests();