Skip to content

Commit

Permalink
igl | vulkan | Check if SPIR-V shader uses push constants
Browse files Browse the repository at this point in the history
Summary: Added a new member field `SpvModuleInfo::hasPushConstants` to check if a SPIR-V shader uses push constants.

Reviewed By: mmaurer

Differential Revision: D52446637

fbshipit-source-id: 4b05638c04564cc56f9469176ca8f4d308807d32
  • Loading branch information
corporateshark authored and facebook-github-bot committed Dec 29, 2023
1 parent 694b692 commit f313bce
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 7 deletions.
32 changes: 30 additions & 2 deletions src/igl/vulkan/PipelineState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,21 @@

namespace igl::vulkan {

void PipelineState::initializeSpvModuleInfoFromShaderStages(IShaderStages* stages) {
void PipelineState::initializeSpvModuleInfoFromShaderStages(const VulkanContext& ctx,
IShaderStages* stages) {
auto* smComp = static_cast<igl::vulkan::ShaderModule*>(stages->getComputeModule().get());

VkShaderStageFlags pushConstantMask = 0;

if (smComp) {
// compute
ensureShaderModule(smComp);

info_ = smComp->getVulkanShaderModule().getSpvModuleInfo();

if (info_.hasPushConstants) {
pushConstantMask |= VK_SHADER_STAGE_COMPUTE_BIT;
}
} else {
auto* smVert = static_cast<igl::vulkan::ShaderModule*>(stages->getVertexModule().get());
auto* smFrag = static_cast<igl::vulkan::ShaderModule*>(stages->getFragmentModule().get());
Expand All @@ -34,16 +41,37 @@ void PipelineState::initializeSpvModuleInfoFromShaderStages(IShaderStages* stage
const util::SpvModuleInfo& infoVert = smVert->getVulkanShaderModule().getSpvModuleInfo();
const util::SpvModuleInfo& infoFrag = smFrag->getVulkanShaderModule().getSpvModuleInfo();

if (infoVert.hasPushConstants) {
pushConstantMask |= VK_SHADER_STAGE_VERTEX_BIT;
}
if (infoFrag.hasPushConstants) {
pushConstantMask |= VK_SHADER_STAGE_FRAGMENT_BIT;
}

info_ = util::mergeReflectionData(infoVert, infoFrag);
}

if (pushConstantMask) {
const VkPhysicalDeviceLimits& limits = ctx.getVkPhysicalDeviceProperties().limits;

constexpr uint32_t kPushConstantsSize = 128;

if (!IGL_VERIFY(kPushConstantsSize <= limits.maxPushConstantsSize)) {
IGL_LOG_ERROR("Push constants size exceeded %u (max %u bytes)",
kPushConstantsSize,
limits.maxPushConstantsSize);
}

pushConstantRange_ = ivkGetPushConstantRange(pushConstantMask, 0, kPushConstantsSize);
}
}

PipelineState::PipelineState(const VulkanContext& ctx,
IShaderStages* stages,
const char* debugName) {
IGL_ASSERT(stages);

initializeSpvModuleInfoFromShaderStages(stages);
initializeSpvModuleInfoFromShaderStages(ctx, stages);

// Create all Vulkan descriptor set layouts for this pipeline

Expand Down
8 changes: 4 additions & 4 deletions src/igl/vulkan/PipelineState.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ class PipelineState {
}

private:
void initializeSpvModuleInfoFromShaderStages(IShaderStages* stages);

protected:
friend class ResourcesBinder;
void initializeSpvModuleInfoFromShaderStages(const VulkanContext& ctx, IShaderStages* stages);

public:
igl::vulkan::util::SpvModuleInfo info_;

VkPushConstantRange pushConstantRange_ = {};

mutable std::unique_ptr<igl::vulkan::VulkanPipelineLayout> pipelineLayout_;

// the last seen VkDescriptorSetLayout from VulkanContext::dslBindless_
Expand Down
2 changes: 1 addition & 1 deletion src/igl/vulkan/VulkanHelpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -1170,7 +1170,7 @@ VkPipelineLayoutCreateInfo ivkGetPipelineLayoutCreateInfo(uint32_t numLayouts,
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.setLayoutCount = numLayouts,
.pSetLayouts = layouts,
.pushConstantRangeCount = 1,
.pushConstantRangeCount = range ? 1u : 0u,
.pPushConstantRanges = range,
};
return ci;
Expand Down
5 changes: 5 additions & 0 deletions src/igl/vulkan/util/SpvReflection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,9 @@ SpvModuleInfo getReflectionData(const uint32_t* spirv, size_t numBytes) {
break;
}
}
if (id.opCode == SpvOpVariable && id.storageClass == SpvStorageClassPushConstant) {
info.hasPushConstants = true;
}
}

return info;
Expand Down Expand Up @@ -260,6 +263,8 @@ SpvModuleInfo mergeReflectionData(const SpvModuleInfo& info1, const SpvModuleInf
combineDescriptions(result.storageBuffers, info1.storageBuffers, info2.storageBuffers);
combineDescriptions(result.textures, info1.textures, info2.textures);

result.hasPushConstants = info1.hasPushConstants || info2.hasPushConstants;

return result;
}

Expand Down
1 change: 1 addition & 0 deletions src/igl/vulkan/util/SpvReflection.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ struct SpvModuleInfo {
std::vector<BufferDescription> uniformBuffers;
std::vector<BufferDescription> storageBuffers;
std::vector<TextureDescription> textures;
bool hasPushConstants = false;
};

SpvModuleInfo getReflectionData(const uint32_t* spirv, size_t numBytes);
Expand Down

0 comments on commit f313bce

Please sign in to comment.