Vulkan: Push constants #104880

Merged
Jeroen Bakker merged 73 commits from Jeroen-Bakker/blender:vulkan-push-constants into main 2023-03-06 12:29:06 +01:00
5 changed files with 16 additions and 89 deletions
Showing only changes of commit c9bd43b0a1 - Show all commits

View File

@ -79,14 +79,8 @@ void VKBackend::compute_dispatch(int groups_x_len, int groups_y_len, int groups_
push_constants, shader->vk_pipeline_layout_get(), VK_SHADER_STAGE_ALL); push_constants, shader->vk_pipeline_layout_get(), VK_SHADER_STAGE_ALL);
break; break;
case VKPushConstantsLayout::StorageType::STORAGE_BUFFER:
push_constants.update_storage_buffer(context.device_get());
descriptor_set.bind(push_constants.storage_buffer_get(),
push_constants.layout_get().storage_buffer_binding_get());
break;
case VKPushConstantsLayout::StorageType::UNIFORM_BUFFER: case VKPushConstantsLayout::StorageType::UNIFORM_BUFFER:
push_constants.update_uniform_buffer(context.device_get()); push_constants.update_uniform_buffer();
descriptor_set.bind(push_constants.uniform_buffer_get(), descriptor_set.bind(push_constants.uniform_buffer_get(),
push_constants.layout_get().storage_buffer_binding_get()); push_constants.layout_get().storage_buffer_binding_get());
break; break;

View File

@ -64,10 +64,11 @@ void VKPushConstantsLayout::init(const shader::ShaderCreateInfo &info,
{ {
BLI_assert(push_constants.is_empty()); BLI_assert(push_constants.is_empty());
storage_type_ = storage_type; storage_type_ = storage_type;
if (ELEM(storage_type, StorageType::STORAGE_BUFFER, StorageType::UNIFORM_BUFFER)) { if (storage_type == StorageType::UNIFORM_BUFFER) {
storage_buffer_binding_ = location; storage_buffer_binding_ = location;
} }
uint32_t offset = 0; uint32_t offset = 0;
/* TODO: add template for readability.*/
for (const shader::ShaderCreateInfo::PushConst &push_constant : info.push_constants_) { for (const shader::ShaderCreateInfo::PushConst &push_constant : info.push_constants_) {
const ShaderInput *shader_input = interface.uniform_get(push_constant.name.c_str()); const ShaderInput *shader_input = interface.uniform_get(push_constant.name.c_str());
BLI_assert(shader_input); BLI_assert(shader_input);
@ -81,7 +82,7 @@ void VKPushConstantsLayout::init(const shader::ShaderCreateInfo &info,
/* Align end of struct. */ /* Align end of struct. */
if (storage_type == StorageType::UNIFORM_BUFFER) { if (storage_type == StorageType::UNIFORM_BUFFER) {
align<Std140>(shader::Type::VEC4, &offset); align_end_of_struct<Std140>(&offset);
} }
else { else {
align_end_of_struct<Std430>(&offset); align_end_of_struct<Std430>(&offset);
@ -105,10 +106,6 @@ VKPushConstants::VKPushConstants(const VKPushConstantsLayout *layout) : layout_(
{ {
data_ = MEM_mallocN(layout->size_in_bytes(), __func__); data_ = MEM_mallocN(layout->size_in_bytes(), __func__);
switch (layout_->storage_type_get()) { switch (layout_->storage_type_get()) {
case VKPushConstantsLayout::StorageType::STORAGE_BUFFER:
storage_buffer_ = new VKStorageBuffer(layout_->size_in_bytes(), GPU_USAGE_DYNAMIC, __func__);
break;
case VKPushConstantsLayout::StorageType::UNIFORM_BUFFER: case VKPushConstantsLayout::StorageType::UNIFORM_BUFFER:
uniform_buffer_ = new VKUniformBuffer(layout_->size_in_bytes(), __func__); uniform_buffer_ = new VKUniformBuffer(layout_->size_in_bytes(), __func__);
break; break;
@ -124,9 +121,6 @@ VKPushConstants::VKPushConstants(VKPushConstants &&other) : layout_(other.layout
data_ = other.data_; data_ = other.data_;
other.data_ = nullptr; other.data_ = nullptr;
storage_buffer_ = other.storage_buffer_;
other.storage_buffer_ = nullptr;
uniform_buffer_ = other.uniform_buffer_; uniform_buffer_ = other.uniform_buffer_;
other.uniform_buffer_ = nullptr; other.uniform_buffer_ = nullptr;
} }
@ -138,9 +132,6 @@ VKPushConstants::~VKPushConstants()
data_ = nullptr; data_ = nullptr;
} }
delete storage_buffer_;
storage_buffer_ = nullptr;
delete uniform_buffer_; delete uniform_buffer_;
uniform_buffer_ = nullptr; uniform_buffer_ = nullptr;
} }
@ -152,31 +143,13 @@ VKPushConstants &VKPushConstants::operator=(VKPushConstants &&other)
data_ = other.data_; data_ = other.data_;
other.data_ = nullptr; other.data_ = nullptr;
storage_buffer_ = other.storage_buffer_;
other.storage_buffer_ = nullptr;
uniform_buffer_ = other.uniform_buffer_; uniform_buffer_ = other.uniform_buffer_;
other.uniform_buffer_ = nullptr; other.uniform_buffer_ = nullptr;
return *this; return *this;
} }
void VKPushConstants::update_storage_buffer(VkDevice /*vk_device*/) void VKPushConstants::update_uniform_buffer()
{
BLI_assert(layout_->storage_type_get() == VKPushConstantsLayout::StorageType::STORAGE_BUFFER);
BLI_assert(storage_buffer_ != nullptr);
BLI_assert(data_ != nullptr);
storage_buffer_->update(data_);
}
VKStorageBuffer &VKPushConstants::storage_buffer_get()
{
BLI_assert(layout_->storage_type_get() == VKPushConstantsLayout::StorageType::STORAGE_BUFFER);
BLI_assert(storage_buffer_ != nullptr);
return *storage_buffer_;
}
void VKPushConstants::update_uniform_buffer(VkDevice /*vk_device*/)
{ {
BLI_assert(layout_->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);

View File

@ -29,7 +29,6 @@
namespace blender::gpu { namespace blender::gpu {
class VKShaderInterface; class VKShaderInterface;
class VKUniformBuffer; class VKUniformBuffer;
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.
@ -44,18 +43,11 @@ struct VKPushConstantsLayout {
PUSH_CONSTANTS, PUSH_CONSTANTS,
/** /**
* Fallback when push constants doesn't meet the device requirements. This fallback uses a * Fallback when push constants doesn't meet the device requirements.
* 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::UNIFORM_BUFFER; static constexpr StorageType STORAGE_TYPE_DEFAULT = StorageType::PUSH_CONSTANTS;
static constexpr StorageType STORAGE_TYPE_FALLBACK = StorageType::UNIFORM_BUFFER; static constexpr StorageType STORAGE_TYPE_FALLBACK = StorageType::UNIFORM_BUFFER;
struct PushConstantLayout { struct PushConstantLayout {
@ -113,7 +105,6 @@ class VKPushConstants : NonCopyable {
private: private:
const VKPushConstantsLayout *layout_ = nullptr; const VKPushConstantsLayout *layout_ = nullptr;
void *data_ = nullptr; void *data_ = nullptr;
VKStorageBuffer *storage_buffer_ = nullptr;
VKUniformBuffer *uniform_buffer_ = nullptr; VKUniformBuffer *uniform_buffer_ = nullptr;
public: public:
@ -134,10 +125,7 @@ class VKPushConstants : NonCopyable {
return *layout_; return *layout_;
} }
void update_storage_buffer(VkDevice vk_device); void update_uniform_buffer();
VKStorageBuffer &storage_buffer_get();
void update_uniform_buffer(VkDevice vk_device);
VKUniformBuffer &uniform_buffer_get(); VKUniformBuffer &uniform_buffer_get();
const void *data() const const void *data() const

View File

@ -888,15 +888,11 @@ static VkDescriptorSetLayoutBinding create_descriptor_set_layout_binding(
static VkDescriptorSetLayoutBinding create_descriptor_set_layout_binding( static VkDescriptorSetLayoutBinding create_descriptor_set_layout_binding(
const VKPushConstantsLayout &push_constants_layout) const VKPushConstantsLayout &push_constants_layout)
{ {
BLI_assert(ELEM(push_constants_layout.storage_type_get(), BLI_assert(push_constants_layout.storage_type_get() ==
VKPushConstantsLayout::StorageType::STORAGE_BUFFER, VKPushConstantsLayout::StorageType::UNIFORM_BUFFER);
VKPushConstantsLayout::StorageType::UNIFORM_BUFFER));
VkDescriptorSetLayoutBinding binding = {}; VkDescriptorSetLayoutBinding binding = {};
binding.binding = push_constants_layout.storage_buffer_binding_get(); binding.binding = push_constants_layout.storage_buffer_binding_get();
binding.descriptorType = push_constants_layout.storage_type_get() == binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
VKPushConstantsLayout::StorageType::STORAGE_BUFFER ?
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER :
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
binding.descriptorCount = 1; binding.descriptorCount = 1;
binding.stageFlags = VK_SHADER_STAGE_ALL; binding.stageFlags = VK_SHADER_STAGE_ALL;
binding.pImmutableSamplers = nullptr; binding.pImmutableSamplers = nullptr;
@ -916,9 +912,8 @@ 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 (ELEM(push_constants_layout.storage_type_get(), if (push_constants_layout.storage_type_get() ==
VKPushConstantsLayout::StorageType::UNIFORM_BUFFER, VKPushConstantsLayout::StorageType::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));
} }
} }
@ -942,9 +937,8 @@ static bool descriptor_sets_needed(const VKShaderInterface &shader_interface,
const shader::ShaderCreateInfo &info) const shader::ShaderCreateInfo &info)
{ {
return !info.pass_resources_.is_empty() || !info.batch_resources_.is_empty() || return !info.pass_resources_.is_empty() || !info.batch_resources_.is_empty() ||
ELEM(shader_interface.push_constants_layout_get().storage_type_get(), shader_interface.push_constants_layout_get().storage_type_get() ==
VKPushConstantsLayout::StorageType::STORAGE_BUFFER, VKPushConstantsLayout::StorageType::UNIFORM_BUFFER;
VKPushConstantsLayout::StorageType::UNIFORM_BUFFER);
} }
bool VKShader::finalize_descriptor_set_layouts(VkDevice vk_device, bool VKShader::finalize_descriptor_set_layouts(VkDevice vk_device,

View File

@ -47,11 +47,7 @@ void VKShaderInterface::init(const shader::ShaderCreateInfo &info)
VKContext &context = *VKContext::get(); VKContext &context = *VKContext::get();
const VKPushConstantsLayout::StorageType push_constants_storage_type = const VKPushConstantsLayout::StorageType push_constants_storage_type =
VKPushConstantsLayout::determine_storage_type(info, context.physical_device_limits_get()); VKPushConstantsLayout::determine_storage_type(info, context.physical_device_limits_get());
if (push_constants_storage_type == VKPushConstantsLayout::StorageType::STORAGE_BUFFER) { if (push_constants_storage_type == VKPushConstantsLayout::StorageType::UNIFORM_BUFFER) {
ssbo_len_++;
names_size += PUSH_CONSTANTS_FALLBACK_NAME_LEN + 1;
}
else if (push_constants_storage_type == VKPushConstantsLayout::StorageType::UNIFORM_BUFFER) {
ubo_len_++; ubo_len_++;
names_size += PUSH_CONSTANTS_FALLBACK_NAME_LEN + 1; names_size += PUSH_CONSTANTS_FALLBACK_NAME_LEN + 1;
} }
@ -118,17 +114,6 @@ void VKShaderInterface::init(const shader::ShaderCreateInfo &info)
} }
} }
/* Push constant post initialization.*/
/*
* When using storage buffer storage type we need to add it to the the name list here.
* Also determine the location as this is used inside the descriptor set as its binding number.
*/
if (push_constants_storage_type == VKPushConstantsLayout::StorageType::STORAGE_BUFFER) {
copy_input_name(input, PUSH_CONSTANTS_FALLBACK_NAME, name_buffer_, name_buffer_offset);
input->location = input->binding = -1;
input++;
}
sort_inputs(); sort_inputs();
/* Determine the descriptor set locations after the inputs have been sorted.*/ /* Determine the descriptor set locations after the inputs have been sorted.*/
@ -147,13 +132,6 @@ void VKShaderInterface::init(const shader::ShaderCreateInfo &info)
case VKPushConstantsLayout::StorageType::PUSH_CONSTANTS: case VKPushConstantsLayout::StorageType::PUSH_CONSTANTS:
break; break;
case VKPushConstantsLayout::StorageType::STORAGE_BUFFER: {
push_constant_descriptor_set_location = descriptor_set_location++;
const ShaderInput *push_constant_input = ssbo_get(PUSH_CONSTANTS_FALLBACK_NAME.c_str());
descriptor_set_location_update(push_constant_input, push_constants_fallback_location);
break;
}
case VKPushConstantsLayout::StorageType::UNIFORM_BUFFER: { case VKPushConstantsLayout::StorageType::UNIFORM_BUFFER: {
push_constant_descriptor_set_location = descriptor_set_location++; push_constant_descriptor_set_location = descriptor_set_location++;
const ShaderInput *push_constant_input = ubo_get(PUSH_CONSTANTS_FALLBACK_NAME.c_str()); const ShaderInput *push_constant_input = ubo_get(PUSH_CONSTANTS_FALLBACK_NAME.c_str());