From 3d3a9fa585ef695d91e459f8507ad3c65f86053b Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 30 Apr 2021 13:22:05 +0100 Subject: [PATCH] Make sure spec constants used for mesh fetch don't overlap with user's --- renderdoc/driver/vulkan/vk_postvs.cpp | 60 +++++++++++-------- .../vulkan/wrappers/vk_device_funcs.cpp | 12 ++++ 2 files changed, 46 insertions(+), 26 deletions(-) diff --git a/renderdoc/driver/vulkan/vk_postvs.cpp b/renderdoc/driver/vulkan/vk_postvs.cpp index 1eab4e291..a1f33a94d 100644 --- a/renderdoc/driver/vulkan/vk_postvs.cpp +++ b/renderdoc/driver/vulkan/vk_postvs.cpp @@ -65,8 +65,8 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRVPatchData &patchData, const char *entryName, StorageMode storageMode, rdcarray instDivisor, const DrawcallDescription *draw, uint32_t numVerts, - uint32_t numViews, rdcarray &modSpirv, - uint32_t &bufStride) + uint32_t numViews, uint32_t baseSpecConstant, + rdcarray &modSpirv, uint32_t &bufStride) { rdcspv::Editor editor(modSpirv); @@ -700,8 +700,10 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, if(storageMode == KHR_bda) { - rdcspv::Id addressConstantLSB = editor.AddSpecConstantImmediate(0U, i * 2 + 0); - rdcspv::Id addressConstantMSB = editor.AddSpecConstantImmediate(0U, i * 2 + 1); + rdcspv::Id addressConstantLSB = + editor.AddSpecConstantImmediate(0U, baseSpecConstant + i * 2 + 0); + rdcspv::Id addressConstantMSB = + editor.AddSpecConstantImmediate(0U, baseSpecConstant + i * 2 + 1); rdcspv::Id uint2 = editor.DeclareType(rdcspv::Vector(rdcspv::scalar(), 2)); @@ -710,7 +712,7 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, } else { - *dstId = editor.AddSpecConstantImmediate(0ULL, i * 2); + *dstId = editor.AddSpecConstantImmediate(0ULL, baseSpecConstant + i * 2); } if(i == MeshOutputBufferArraySize) @@ -1902,6 +1904,31 @@ void VulkanReplay::FetchVSOut(uint32_t eventId, VulkanRenderState &state) m_pDriver->vkUnmapMemory(m_Device, rebasedIdxBufMem); } + uint32_t baseSpecConstant = 0; + + bytebuf specData; + rdcarray specEntries; + + // copy over specialization info + for(uint32_t s = 0; s < pipeCreateInfo.stageCount; s++) + { + if(pipeCreateInfo.pStages[s].stage == VK_SHADER_STAGE_VERTEX_BIT) + { + if(pipeCreateInfo.pStages[s].pSpecializationInfo) + { + specData.assign((const byte *)pipeCreateInfo.pStages[s].pSpecializationInfo->pData, + pipeCreateInfo.pStages[s].pSpecializationInfo->dataSize); + specEntries.assign(pipeCreateInfo.pStages[s].pSpecializationInfo->pMapEntries, + pipeCreateInfo.pStages[s].pSpecializationInfo->mapEntryCount); + } + break; + } + } + + // don't overlap with existing pipeline constants + for(const VkSpecializationMapEntry &specConst : specEntries) + baseSpecConstant = RDCMAX(baseSpecConstant, specConst.constantID + 1); + uint32_t bufStride = 0; rdcarray modSpirv = moduleInfo.spirv.GetSPIRV(); @@ -2285,7 +2312,7 @@ void VulkanReplay::FetchVSOut(uint32_t eventId, VulkanRenderState &state) ConvertToMeshOutputCompute(*refl, *pipeInfo.shaders[0].patchData, pipeInfo.shaders[0].entryPoint.c_str(), storageMode, attrInstDivisor, - drawcall, numVerts, numViews, modSpirv, bufStride); + drawcall, numVerts, numViews, baseSpecConstant, modSpirv, bufStride); if(!Vulkan_Debug_PostVSDumpDirPath().empty()) FileIO::WriteAll(Vulkan_Debug_PostVSDumpDirPath() + "/debug_postvs_comp.spv", modSpirv); @@ -2382,25 +2409,6 @@ void VulkanReplay::FetchVSOut(uint32_t eventId, VulkanRenderState &state) compPipeInfo.stage.pName = PatchedMeshOutputEntryPoint; compPipeInfo.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT; - bytebuf specData; - rdcarray specEntries; - - // copy over specialization info - for(uint32_t s = 0; s < pipeCreateInfo.stageCount; s++) - { - if(pipeCreateInfo.pStages[s].stage == VK_SHADER_STAGE_VERTEX_BIT) - { - if(pipeCreateInfo.pStages[s].pSpecializationInfo) - { - specData.assign((const byte *)pipeCreateInfo.pStages[s].pSpecializationInfo->pData, - pipeCreateInfo.pStages[s].pSpecializationInfo->dataSize); - specEntries.assign(pipeCreateInfo.pStages[s].pSpecializationInfo->pMapEntries, - pipeCreateInfo.pStages[s].pSpecializationInfo->mapEntryCount); - } - break; - } - } - // append our own if we're using BDA if(storageMode != Binding) { @@ -2436,7 +2444,7 @@ void VulkanReplay::FetchVSOut(uint32_t eventId, VulkanRenderState &state) VkSpecializationMapEntry entry; entry.offset = baseOffset + i * sizeof(uint64_t); - entry.constantID = i * 2 + 0; + entry.constantID = baseSpecConstant + i * 2 + 0; // for EXT we have one 64-bit spec constant per address, for KHR we have a uvec2 - two // constants diff --git a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp index d3bd49448..86ef71d55 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp @@ -353,6 +353,18 @@ ReplayStatus WrappedVulkan::Initialise(VkInitParams ¶ms, uint64_t sectionVer featuresEXT.disabledValidationFeatureCount = ARRAY_COUNT(disableFeatures); featuresEXT.pDisabledValidationFeatures = disableFeatures; +// enable this to get GPU-based validation, where available, whenever we enable API validation +#if 0 + if(m_ReplayOptions.apiValidation) + { + VkValidationFeatureEnableEXT enableFeatures[] = { + VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT, + VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT}; + featuresEXT.enabledValidationFeatureCount = ARRAY_COUNT(enableFeatures); + featuresEXT.pEnabledValidationFeatures = enableFeatures; + } +#endif + VkValidationFlagsEXT flagsEXT = {VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT}; VkValidationCheckEXT disableChecks[] = {VK_VALIDATION_CHECK_SHADERS_EXT}; flagsEXT.disabledValidationCheckCount = ARRAY_COUNT(disableChecks);