Skip to content

Commit

Permalink
Relaxed binding of push constants
Browse files Browse the repository at this point in the history
  • Loading branch information
corporateshark committed Feb 18, 2024
1 parent 22c740d commit 61bb4ef
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 11 deletions.
72 changes: 61 additions & 11 deletions lvk/vulkan/VulkanClasses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2531,20 +2531,26 @@ void lvk::CommandBuffer::cmdPushConstants(const void* data, size_t size, size_t
LLOGW("Push constants size exceeded %u (max %u bytes)", size + offset, limits.maxPushConstantsSize);
}

if (currentPipelineGraphics_.empty() && currentPipelineCompute_.empty()) {
LVK_ASSERT_MSG(false, "No pipeline bound - cannot set push constants");
return;
VkPipelineLayout layout = ctx_->vkGenericPipelineLayout_;
VkShaderStageFlags stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
if (ctx_->vkFeatures10_.features.tessellationShader == VK_TRUE) {
stageFlags |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
stageFlags |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
}
if (ctx_->vkFeatures10_.features.geometryShader == VK_TRUE) {
stageFlags |= VK_SHADER_STAGE_GEOMETRY_BIT;
}

const lvk::RenderPipelineState* stateGraphics = ctx_->renderPipelinesPool_.get(currentPipelineGraphics_);
const lvk::ComputePipelineState* stateCompute = ctx_->computePipelinesPool_.get(currentPipelineCompute_);

LVK_ASSERT(stateGraphics || stateCompute);

VkPipelineLayout layout = stateGraphics ? stateGraphics->pipelineLayout_ : stateCompute->pipelineLayout_;
VkShaderStageFlags shaderStageFlags = stateGraphics ? stateGraphics->shaderStageFlags_ : VK_SHADER_STAGE_COMPUTE_BIT;
if (const lvk::RenderPipelineState* state = ctx_->renderPipelinesPool_.get(currentPipelineGraphics_)) {
stageFlags = state->shaderStageFlags_;
layout = state->pipelineLayout_;
}
if (const lvk::ComputePipelineState* state = ctx_->computePipelinesPool_.get(currentPipelineCompute_)) {
stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
layout = state->pipelineLayout_;
}

vkCmdPushConstants(wrapper_->cmdBuf_, layout, shaderStageFlags, (uint32_t)offset, (uint32_t)size, data);
vkCmdPushConstants(wrapper_->cmdBuf_, layout, stageFlags, (uint32_t)offset, (uint32_t)size, data);
}

void lvk::CommandBuffer::cmdDraw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t baseInstance) {
Expand Down Expand Up @@ -3169,6 +3175,7 @@ lvk::VulkanContext::~VulkanContext() {

immediate_.reset(nullptr);

vkDestroyPipelineLayout(vkDevice_, vkGenericPipelineLayout_, nullptr);
vkDestroyDescriptorSetLayout(vkDevice_, vkDSL_, nullptr);
vkDestroyDescriptorPool(vkDevice_, vkDPool_, nullptr);
vkDestroySurfaceKHR(vkInstance_, vkSurface_, nullptr);
Expand Down Expand Up @@ -5036,6 +5043,10 @@ lvk::Result lvk::VulkanContext::growDescriptorPool(uint32_t maxTextures, uint32_
if (vkDPool_ != VK_NULL_HANDLE) {
deferredTask(std::packaged_task<void()>([device = vkDevice_, dp = vkDPool_]() { vkDestroyDescriptorPool(device, dp, nullptr); }));
}
if (vkGenericPipelineLayout_ != VK_NULL_HANDLE) {
deferredTask(std::packaged_task<void()>(
[device = vkDevice_, layout = vkGenericPipelineLayout_]() { vkDestroyPipelineLayout(device, layout, nullptr); }));
}

// create default descriptor set layout which is going to be shared by graphics pipelines
const VkDescriptorSetLayoutBinding bindings[kBinding_NumBindings] = {
Expand Down Expand Up @@ -5089,6 +5100,45 @@ lvk::Result lvk::VulkanContext::growDescriptorPool(uint32_t maxTextures, uint32_
VK_ASSERT_RETURN(vkAllocateDescriptorSets(vkDevice_, &ai, &vkDSet_));
}

// create pipeline layout
{
// maxPushConstantsSize is guaranteed to be at least 128 bytes
// https://www.khronos.org/registry/vulkan/specs/1.3/html/vkspec.html#features-limits
// Table 32. Required Limits
const uint32_t kPushConstantsSize = 128;
const VkPhysicalDeviceLimits& limits = getVkPhysicalDeviceProperties().limits;
if (!LVK_VERIFY(kPushConstantsSize <= limits.maxPushConstantsSize)) {
LLOGW("Push constants size exceeded %u (max %u bytes)", kPushConstantsSize, limits.maxPushConstantsSize);
}

VkShaderStageFlags stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
if (vkFeatures10_.features.tessellationShader == VK_TRUE) {
stageFlags |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
stageFlags |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
}
if (vkFeatures10_.features.geometryShader == VK_TRUE) {
stageFlags |= VK_SHADER_STAGE_GEOMETRY_BIT;
}

const VkPushConstantRange range = {
.stageFlags = stageFlags,
.offset = 0,
.size = kPushConstantsSize,
};
const VkPipelineLayoutCreateInfo ci = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.setLayoutCount = 0,
.pSetLayouts = nullptr,
.pushConstantRangeCount = 1,
.pPushConstantRanges = &range,
};
VK_ASSERT(vkCreatePipelineLayout(vkDevice_, &ci, nullptr, &vkGenericPipelineLayout_));
VK_ASSERT(lvk::setDebugObjectName(vkDevice_,
VK_OBJECT_TYPE_PIPELINE_LAYOUT,
(uint64_t)vkGenericPipelineLayout_,
"Pipeline Layout: VulkanContext::vkGenericPipelineLayout_"));
}

return Result();
}

Expand Down
3 changes: 3 additions & 0 deletions lvk/vulkan/VulkanClasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -615,13 +615,15 @@ class VulkanContext final : public IContext {
VkPhysicalDevice vkPhysicalDevice_ = VK_NULL_HANDLE;
VkDevice vkDevice_ = VK_NULL_HANDLE;

public:
VkPhysicalDeviceVulkan13Features vkFeatures13_ = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES};
VkPhysicalDeviceVulkan12Features vkFeatures12_ = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
.pNext = &vkFeatures13_};
VkPhysicalDeviceVulkan11Features vkFeatures11_ = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES,
.pNext = &vkFeatures12_};
VkPhysicalDeviceFeatures2 vkFeatures10_ = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, .pNext = &vkFeatures11_};

private:
// provided by Vulkan 1.2
VkPhysicalDeviceDriverProperties vkPhysicalDeviceDriverProperties_ = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES, nullptr};
VkPhysicalDeviceVulkan12Properties vkPhysicalDeviceVulkan12Properties_ = {
Expand All @@ -645,6 +647,7 @@ class VulkanContext final : public IContext {
std::unique_ptr<lvk::VulkanStagingDevice> stagingDevice_;
uint32_t currentMaxTextures_ = 16;
uint32_t currentMaxSamplers_ = 16;
VkPipelineLayout vkGenericPipelineLayout_ = VK_NULL_HANDLE;
VkDescriptorSetLayout vkDSL_ = VK_NULL_HANDLE;
VkDescriptorPool vkDPool_ = VK_NULL_HANDLE;
VkDescriptorSet vkDSet_ = VK_NULL_HANDLE;
Expand Down

0 comments on commit 61bb4ef

Please sign in to comment.