Vulkan: Push constants #104880
|
@ -70,7 +70,7 @@ void VKBackend::compute_dispatch(int groups_x_len, int groups_y_len, int groups_
|
||||||
VKPushConstants &push_constants = pipeline.push_constants_get();
|
VKPushConstants &push_constants = pipeline.push_constants_get();
|
||||||
|
|
||||||
/* Update push constants based on their storage type.*/
|
/* Update push constants based on their storage type.*/
|
||||||
switch (push_constants.storage_type_get()) {
|
switch (push_constants.layout_get().storage_type_get()) {
|
||||||
Jeroen-Bakker marked this conversation as resolved
|
|||||||
case VKPushConstantsLayout::StorageType::NONE:
|
case VKPushConstantsLayout::StorageType::NONE:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -82,13 +82,13 @@ void VKBackend::compute_dispatch(int groups_x_len, int groups_y_len, int groups_
|
||||||
case VKPushConstantsLayout::StorageType::STORAGE_BUFFER:
|
case VKPushConstantsLayout::StorageType::STORAGE_BUFFER:
|
||||||
push_constants.update_storage_buffer(context.device_get());
|
push_constants.update_storage_buffer(context.device_get());
|
||||||
descriptor_set.bind(push_constants.storage_buffer_get(),
|
descriptor_set.bind(push_constants.storage_buffer_get(),
|
||||||
push_constants.storage_buffer_binding_get());
|
push_constants.layout_get().storage_buffer_binding_get());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VKPushConstantsLayout::StorageType::UNIFORM_BUFFER:
|
case VKPushConstantsLayout::StorageType::UNIFORM_BUFFER:
|
||||||
push_constants.update_uniform_buffer(context.device_get());
|
push_constants.update_uniform_buffer(context.device_get());
|
||||||
descriptor_set.bind(push_constants.uniform_buffer_get(),
|
descriptor_set.bind(push_constants.uniform_buffer_get(),
|
||||||
push_constants.storage_buffer_binding_get());
|
push_constants.layout_get().storage_buffer_binding_get());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
descriptor_set.update(context.device_get());
|
descriptor_set.update(context.device_get());
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
#include "vk_buffer.hh"
|
#include "vk_buffer.hh"
|
||||||
#include "vk_context.hh"
|
#include "vk_context.hh"
|
||||||
#include "vk_memory.hh"
|
#include "vk_memory.hh"
|
||||||
#include "vk_texture.hh"
|
|
||||||
#include "vk_pipeline.hh"
|
#include "vk_pipeline.hh"
|
||||||
|
#include "vk_texture.hh"
|
||||||
|
|
||||||
#include "BLI_assert.h"
|
#include "BLI_assert.h"
|
||||||
|
|
||||||
|
@ -76,14 +76,15 @@ void VKCommandBuffer::push_constants(const VKPushConstants &push_constants,
|
||||||
const VkPipelineLayout vk_pipeline_layout,
|
const VkPipelineLayout vk_pipeline_layout,
|
||||||
const VkShaderStageFlags vk_shader_stages)
|
const VkShaderStageFlags vk_shader_stages)
|
||||||
{
|
{
|
||||||
if (push_constants.storage_type_get() != VKPushConstantsLayout::StorageType::PUSH_CONSTANTS) {
|
if (push_constants.layout_get().storage_type_get() !=
|
||||||
|
VKPushConstantsLayout::StorageType::PUSH_CONSTANTS) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vkCmdPushConstants(vk_command_buffer_,
|
vkCmdPushConstants(vk_command_buffer_,
|
||||||
vk_pipeline_layout,
|
vk_pipeline_layout,
|
||||||
vk_shader_stages,
|
vk_shader_stages,
|
||||||
push_constants.offset(),
|
push_constants.offset(),
|
||||||
push_constants.size_in_bytes(),
|
push_constants.layout_get().size_in_bytes(),
|
||||||
push_constants.data());
|
push_constants.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ VKPipeline VKPipeline::create_compute_pipeline(VKContext &context,
|
||||||
if (vkCreateComputePipelines(
|
if (vkCreateComputePipelines(
|
||||||
vk_device, nullptr, 1, &pipeline_info, vk_allocation_callbacks, &vk_pipeline) !=
|
vk_device, nullptr, 1, &pipeline_info, vk_allocation_callbacks, &vk_pipeline) !=
|
||||||
VK_SUCCESS) {
|
VK_SUCCESS) {
|
||||||
//return VKPipeline();
|
return VKPipeline();
|
||||||
Jeroen-Bakker marked this conversation as resolved
Jeroen Bakker
commented
This should be fixed. This should be fixed.
|
|||||||
}
|
}
|
||||||
|
|
||||||
VKDescriptorSet descriptor_set = context.descriptor_pools_get().allocate(descriptor_set_layout);
|
VKDescriptorSet descriptor_set = context.descriptor_pools_get().allocate(descriptor_set_layout);
|
||||||
|
|
|
@ -78,8 +78,8 @@ VKPushConstantsLayout::StorageType VKPushConstantsLayout::determine_storage_type
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t size = struct_size<Std430>(info.push_constants_);
|
uint32_t size = struct_size<Std430>(info.push_constants_);
|
||||||
return size <= vk_physical_device_limits.maxPushConstantsSize ? StorageType::PUSH_CONSTANTS :
|
return size <= vk_physical_device_limits.maxPushConstantsSize ? STORAGE_TYPE_DEFAULT :
|
||||||
StorageType::STORAGE_BUFFER;
|
STORAGE_TYPE_FALLBACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VKPushConstantsLayout::init(const shader::ShaderCreateInfo &info,
|
void VKPushConstantsLayout::init(const shader::ShaderCreateInfo &info,
|
||||||
|
@ -122,13 +122,13 @@ VKPushConstants::VKPushConstants() = default;
|
||||||
VKPushConstants::VKPushConstants(const VKPushConstantsLayout *layout) : layout_(layout)
|
VKPushConstants::VKPushConstants(const VKPushConstantsLayout *layout) : layout_(layout)
|
||||||
{
|
{
|
||||||
data_ = MEM_mallocN(layout->size_in_bytes(), __func__);
|
data_ = MEM_mallocN(layout->size_in_bytes(), __func__);
|
||||||
switch (storage_type_get()) {
|
switch (layout_->storage_type_get()) {
|
||||||
case VKPushConstantsLayout::StorageType::STORAGE_BUFFER:
|
case VKPushConstantsLayout::StorageType::STORAGE_BUFFER:
|
||||||
storage_buffer_ = new VKStorageBuffer(size_in_bytes(), GPU_USAGE_DYNAMIC, __func__);
|
storage_buffer_ = new VKStorageBuffer(layout_->size_in_bytes(), GPU_USAGE_DYNAMIC, __func__);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VKPushConstantsLayout::StorageType::UNIFORM_BUFFER:
|
case VKPushConstantsLayout::StorageType::UNIFORM_BUFFER:
|
||||||
uniform_buffer_ = new VKUniformBuffer(size_in_bytes(), __func__);
|
uniform_buffer_ = new VKUniformBuffer(layout_->size_in_bytes(), __func__);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VKPushConstantsLayout::StorageType::PUSH_CONSTANTS:
|
case VKPushConstantsLayout::StorageType::PUSH_CONSTANTS:
|
||||||
|
@ -178,7 +178,7 @@ VKPushConstants &VKPushConstants::operator=(VKPushConstants &&other)
|
||||||
|
|
||||||
void VKPushConstants::update_storage_buffer(VkDevice /*vk_device*/)
|
void VKPushConstants::update_storage_buffer(VkDevice /*vk_device*/)
|
||||||
{
|
{
|
||||||
BLI_assert(storage_type_get() == VKPushConstantsLayout::StorageType::STORAGE_BUFFER);
|
BLI_assert(layout_->storage_type_get() == VKPushConstantsLayout::StorageType::STORAGE_BUFFER);
|
||||||
BLI_assert(storage_buffer_ != nullptr);
|
BLI_assert(storage_buffer_ != nullptr);
|
||||||
BLI_assert(data_ != nullptr);
|
BLI_assert(data_ != nullptr);
|
||||||
storage_buffer_->update(data_);
|
storage_buffer_->update(data_);
|
||||||
|
@ -186,14 +186,14 @@ void VKPushConstants::update_storage_buffer(VkDevice /*vk_device*/)
|
||||||
|
|
||||||
VKStorageBuffer &VKPushConstants::storage_buffer_get()
|
VKStorageBuffer &VKPushConstants::storage_buffer_get()
|
||||||
{
|
{
|
||||||
BLI_assert(storage_type_get() == VKPushConstantsLayout::StorageType::STORAGE_BUFFER);
|
BLI_assert(layout_->storage_type_get() == VKPushConstantsLayout::StorageType::STORAGE_BUFFER);
|
||||||
BLI_assert(storage_buffer_ != nullptr);
|
BLI_assert(storage_buffer_ != nullptr);
|
||||||
return *storage_buffer_;
|
return *storage_buffer_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VKPushConstants::update_uniform_buffer(VkDevice /*vk_device*/)
|
void VKPushConstants::update_uniform_buffer(VkDevice /*vk_device*/)
|
||||||
{
|
{
|
||||||
BLI_assert(storage_type_get() == VKPushConstantsLayout::StorageType::UNIFORM_BUFFER);
|
BLI_assert(layout_->storage_type_get() == VKPushConstantsLayout::StorageType::UNIFORM_BUFFER);
|
||||||
BLI_assert(uniform_buffer_ != nullptr);
|
BLI_assert(uniform_buffer_ != nullptr);
|
||||||
BLI_assert(data_ != nullptr);
|
BLI_assert(data_ != nullptr);
|
||||||
uniform_buffer_->update(data_);
|
uniform_buffer_->update(data_);
|
||||||
|
@ -201,7 +201,7 @@ void VKPushConstants::update_uniform_buffer(VkDevice /*vk_device*/)
|
||||||
|
|
||||||
VKUniformBuffer &VKPushConstants::uniform_buffer_get()
|
VKUniformBuffer &VKPushConstants::uniform_buffer_get()
|
||||||
{
|
{
|
||||||
BLI_assert(storage_type_get() == VKPushConstantsLayout::StorageType::UNIFORM_BUFFER);
|
BLI_assert(layout_->storage_type_get() == VKPushConstantsLayout::StorageType::UNIFORM_BUFFER);
|
||||||
BLI_assert(uniform_buffer_ != nullptr);
|
BLI_assert(uniform_buffer_ != nullptr);
|
||||||
return *uniform_buffer_;
|
return *uniform_buffer_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,13 +35,28 @@ class VKStorageBuffer;
|
||||||
* Describe the layout of the push constants and the storage type that should be used.
|
* Describe the layout of the push constants and the storage type that should be used.
|
||||||
*/
|
*/
|
||||||
struct VKPushConstantsLayout {
|
struct VKPushConstantsLayout {
|
||||||
/* Should the push constant use regular push constants or a buffer.*/
|
/* Different methods to store push constants.*/
|
||||||
enum class StorageType {
|
enum class StorageType {
|
||||||
|
/** Push constants aren't in use.*/
|
||||||
NONE,
|
NONE,
|
||||||
|
|
||||||
|
/** Store push constants as regular vulkan push constants.*/
|
||||||
PUSH_CONSTANTS,
|
PUSH_CONSTANTS,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fallback when push constants doesn't meet the device requirements. This fallback uses a
|
||||||
|
* storage buffer.
|
||||||
|
*/
|
||||||
STORAGE_BUFFER,
|
STORAGE_BUFFER,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fallback when push constants doesn't meet the device requirements. This fallback uses an
|
||||||
|
* uniform buffer.
|
||||||
|
*/
|
||||||
UNIFORM_BUFFER,
|
UNIFORM_BUFFER,
|
||||||
};
|
};
|
||||||
|
static constexpr StorageType STORAGE_TYPE_DEFAULT = StorageType::PUSH_CONSTANTS;
|
||||||
|
static constexpr StorageType STORAGE_TYPE_FALLBACK = StorageType::UNIFORM_BUFFER;
|
||||||
|
|
||||||
struct PushConstantLayout {
|
struct PushConstantLayout {
|
||||||
/* TODO: location requires sequential lookups, we should make the location index based for
|
/* TODO: location requires sequential lookups, we should make the location index based for
|
||||||
|
@ -114,19 +129,9 @@ class VKPushConstants : NonCopyable {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size_in_bytes() const
|
const VKPushConstantsLayout &layout_get() const
|
||||||
{
|
{
|
||||||
return layout_->size_in_bytes();
|
return *layout_;
|
||||||
}
|
|
||||||
|
|
||||||
VKPushConstantsLayout::StorageType storage_type_get() const
|
|
||||||
{
|
|
||||||
return layout_->storage_type_get();
|
|
||||||
}
|
|
||||||
|
|
||||||
VKDescriptorSet::Location storage_buffer_binding_get() const
|
|
||||||
{
|
|
||||||
return layout_->storage_buffer_binding_get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_storage_buffer(VkDevice vk_device);
|
void update_storage_buffer(VkDevice vk_device);
|
||||||
|
|
|
@ -925,8 +925,9 @@ static void add_descriptor_set_layout_bindings(
|
||||||
|
|
||||||
/* Add push constants to the descriptor when push constants are stored in a storage buffer.*/
|
/* Add push constants to the descriptor when push constants are stored in a storage buffer.*/
|
||||||
const VKPushConstantsLayout &push_constants_layout = interface.push_constants_layout_get();
|
const VKPushConstantsLayout &push_constants_layout = interface.push_constants_layout_get();
|
||||||
if (push_constants_layout.storage_type_get() ==
|
if (ELEM(push_constants_layout.storage_type_get(),
|
||||||
VKPushConstantsLayout::StorageType::STORAGE_BUFFER) {
|
VKPushConstantsLayout::StorageType::UNIFORM_BUFFER,
|
||||||
Jeroen-Bakker marked this conversation as resolved
Jeroen Bakker
commented
Also check for uniform_buffer Also check for uniform_buffer
|
|||||||
|
VKPushConstantsLayout::StorageType::STORAGE_BUFFER)) {
|
||||||
r_bindings.append(create_descriptor_set_layout_binding(push_constants_layout));
|
r_bindings.append(create_descriptor_set_layout_binding(push_constants_layout));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,6 +143,7 @@ void VKShaderInterface::init(const shader::ShaderCreateInfo &info)
|
||||||
info, *this, push_constants_storage_type, push_constants_fallback_input);
|
info, *this, push_constants_storage_type, push_constants_fallback_input);
|
||||||
|
|
||||||
sort_inputs();
|
sort_inputs();
|
||||||
|
debug_print();
|
||||||
}
|
}
|
||||||
|
|
||||||
const ShaderInput *VKShaderInterface::shader_input_get(
|
const ShaderInput *VKShaderInterface::shader_input_get(
|
||||||
|
|
Loading…
Reference in New Issue
I may be missing something, but this whole
switch
block feels like it does not belong here. It looks way too specific to me.Would rather see that logic as part of the
VKPushConstants
class itself, but no idea if this is doable in practice... At the very least would have it in a dedicated util function ofVKBackend
otherwise?Yes you're right, will move this part into a method of VKPushConstants.