diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp index d60ba6250..5ac2807a9 100644 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp @@ -2058,6 +2058,9 @@ void VulkanPipelineStateViewer::setShaderState(const VKPipe::Shader &stage, shText += lit(" - ") + QFileInfo(dbg.files[entryFile].filename).fileName(); } + if(stage.requiredSubgroupSize != 0) + shText += tr(" (Subgroup size %1)").arg(stage.requiredSubgroupSize); + shader->setText(shText); int vs = 0; diff --git a/renderdoc/api/replay/vk_pipestate.h b/renderdoc/api/replay/vk_pipestate.h index ea77829c5..20742885b 100644 --- a/renderdoc/api/replay/vk_pipestate.h +++ b/renderdoc/api/replay/vk_pipestate.h @@ -611,6 +611,9 @@ struct Shader DOCUMENT("The number of bytes in the push constant data that is visible to this shader."); uint32_t pushConstantRangeByteSize = 0; + DOCUMENT("The required subgroup size specified for this shader at pipeline creation time."); + uint32_t requiredSubgroupSize = 0; + DOCUMENT(R"(The provided specialization constant data. Shader constants store the byte offset into this buffer as their byteOffset. This data includes the applied specialization constants over the top of the default values, so it is safe to read any constant from here and get the correct current diff --git a/renderdoc/driver/vulkan/vk_info.cpp b/renderdoc/driver/vulkan/vk_info.cpp index 4f707eaef..c237728e9 100644 --- a/renderdoc/driver/vulkan/vk_info.cpp +++ b/renderdoc/driver/vulkan/vk_info.cpp @@ -866,6 +866,13 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Shader &shad = shaders[stageIndex]; + VkPipelineShaderStageRequiredSubgroupSizeCreateInfo *subgroupSize = + (VkPipelineShaderStageRequiredSubgroupSizeCreateInfo *)FindNextStruct( + &pCreateInfo->pStages[i], + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO); + if(subgroupSize) + shad.requiredSubgroupSize = subgroupSize->requiredSubgroupSize; + shad.module = shadid; shad.entryPoint = pCreateInfo->pStages[i].pName; shad.stage = ShaderStage(stageIndex); @@ -1470,6 +1477,13 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk ResourceId shadid = GetResID(pCreateInfo->stage.module); Shader &shad = shaders[5]; // 5 is the compute shader's index (VS, TCS, TES, GS, FS, CS) + VkPipelineShaderStageRequiredSubgroupSizeCreateInfo *subgroupSize = + (VkPipelineShaderStageRequiredSubgroupSizeCreateInfo *)FindNextStruct( + &pCreateInfo->stage, + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO); + if(subgroupSize) + shad.requiredSubgroupSize = subgroupSize->requiredSubgroupSize; + shad.module = shadid; shad.entryPoint = pCreateInfo->stage.pName; diff --git a/renderdoc/driver/vulkan/vk_info.h b/renderdoc/driver/vulkan/vk_info.h index 64fac6ad6..dc2efb416 100644 --- a/renderdoc/driver/vulkan/vk_info.h +++ b/renderdoc/driver/vulkan/vk_info.h @@ -342,15 +342,17 @@ struct VulkanCreationInfo // VkPipelineShaderStageCreateInfo struct Shader { - Shader() : refl(NULL), mapping(NULL), patchData(NULL) {} ResourceId module; - ShaderStage stage; + ShaderStage stage = ShaderStage::Count; rdcstr entryPoint; - ShaderReflection *refl; - ShaderBindpointMapping *mapping; - SPIRVPatchData *patchData; + ShaderReflection *refl = NULL; + ShaderBindpointMapping *mapping = NULL; + SPIRVPatchData *patchData = NULL; rdcarray specialization; + + // VkPipelineShaderStageRequiredSubgroupSizeCreateInfo + uint32_t requiredSubgroupSize = 0; }; Shader shaders[NumShaderStages]; diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index 575e204b6..4318c3ddf 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -1123,6 +1123,8 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) } } + stage.requiredSubgroupSize = p.shaders[i].requiredSubgroupSize; + stage.specializationData.clear(); // set up the defaults @@ -1256,6 +1258,8 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) stages[i]->specializationData.clear(); + stages[i]->requiredSubgroupSize = p.shaders[i].requiredSubgroupSize; + // set up the defaults if(p.shaders[i].mapping && p.shaders[i].refl) { diff --git a/renderdoc/driver/vulkan/vk_shader_cache.cpp b/renderdoc/driver/vulkan/vk_shader_cache.cpp index 67dce8f3e..9978a523c 100644 --- a/renderdoc/driver/vulkan/vk_shader_cache.cpp +++ b/renderdoc/driver/vulkan/vk_shader_cache.cpp @@ -569,6 +569,8 @@ void VulkanShaderCache::MakeGraphicsPipelineInfo(VkGraphicsPipelineCreateInfo &p uint32_t stageCount = 0; uint32_t dataOffset = 0; + static VkPipelineShaderStageRequiredSubgroupSizeCreateInfo reqSubgroupSize[NumShaderStages] = {}; + // reserve space for spec constants for(uint32_t i = 0; i < NumShaderStages; i++) { @@ -581,6 +583,14 @@ void VulkanShaderCache::MakeGraphicsPipelineInfo(VkGraphicsPipelineCreateInfo &p stages[stageCount].pNext = NULL; stages[stageCount].pSpecializationInfo = NULL; + if(pipeInfo.shaders[i].requiredSubgroupSize != 0) + { + reqSubgroupSize[i].sType = + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO; + reqSubgroupSize[i].requiredSubgroupSize = pipeInfo.shaders[i].requiredSubgroupSize; + stages[stageCount].pNext = &reqSubgroupSize[i]; + } + if(!pipeInfo.shaders[i].specialization.empty()) { stages[stageCount].pSpecializationInfo = &specInfo[i]; @@ -1069,6 +1079,16 @@ void VulkanShaderCache::MakeComputePipelineInfo(VkComputePipelineCreateInfo &pip specInfo.pData = specdata.data(); } + static VkPipelineShaderStageRequiredSubgroupSizeCreateInfo reqSubgroupSize = { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO, + }; + + if(pipeInfo.shaders[i].requiredSubgroupSize != 0) + { + reqSubgroupSize.requiredSubgroupSize = pipeInfo.shaders[i].requiredSubgroupSize; + stage.pNext = &reqSubgroupSize; + } + VkComputePipelineCreateInfo ret = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, NULL,