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);
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:
push_constants.update_uniform_buffer(context.device_get());
push_constants.update_uniform_buffer();
descriptor_set.bind(push_constants.uniform_buffer_get(),
push_constants.layout_get().storage_buffer_binding_get());
break;

View File

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

View File

@ -29,7 +29,6 @@
namespace blender::gpu {
class VKShaderInterface;
class VKUniformBuffer;
class VKStorageBuffer;
/**
* Describe the layout of the push constants and the storage type that should be used.
@ -44,18 +43,11 @@ struct VKPushConstantsLayout {
PUSH_CONSTANTS,
/**
* Fallback when push constants doesn't meet the device requirements. This fallback uses a
* storage buffer.
*/
STORAGE_BUFFER,
/**
* Fallback when push constants doesn't meet the device requirements. This fallback uses an
* uniform buffer.
* Fallback when push constants doesn't meet the device requirements.
*/
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;
struct PushConstantLayout {
@ -113,7 +105,6 @@ class VKPushConstants : NonCopyable {
private:
const VKPushConstantsLayout *layout_ = nullptr;
void *data_ = nullptr;
VKStorageBuffer *storage_buffer_ = nullptr;
VKUniformBuffer *uniform_buffer_ = nullptr;
public:
@ -134,10 +125,7 @@ class VKPushConstants : NonCopyable {
return *layout_;
}
void update_storage_buffer(VkDevice vk_device);
VKStorageBuffer &storage_buffer_get();
void update_uniform_buffer(VkDevice vk_device);
void update_uniform_buffer();
VKUniformBuffer &uniform_buffer_get();
const void *data() const

View File

@ -888,15 +888,11 @@ static VkDescriptorSetLayoutBinding create_descriptor_set_layout_binding(
static VkDescriptorSetLayoutBinding create_descriptor_set_layout_binding(
const VKPushConstantsLayout &push_constants_layout)
{
BLI_assert(ELEM(push_constants_layout.storage_type_get(),
VKPushConstantsLayout::StorageType::STORAGE_BUFFER,
VKPushConstantsLayout::StorageType::UNIFORM_BUFFER));
BLI_assert(push_constants_layout.storage_type_get() ==
VKPushConstantsLayout::StorageType::UNIFORM_BUFFER);
VkDescriptorSetLayoutBinding binding = {};
binding.binding = push_constants_layout.storage_buffer_binding_get();
binding.descriptorType = push_constants_layout.storage_type_get() ==
VKPushConstantsLayout::StorageType::STORAGE_BUFFER ?
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER :
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
binding.descriptorCount = 1;
binding.stageFlags = VK_SHADER_STAGE_ALL;
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.*/
const VKPushConstantsLayout &push_constants_layout = interface.push_constants_layout_get();
if (ELEM(push_constants_layout.storage_type_get(),
VKPushConstantsLayout::StorageType::UNIFORM_BUFFER,
VKPushConstantsLayout::StorageType::STORAGE_BUFFER)) {
if (push_constants_layout.storage_type_get() ==
VKPushConstantsLayout::StorageType::UNIFORM_BUFFER) {
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)
{
return !info.pass_resources_.is_empty() || !info.batch_resources_.is_empty() ||
ELEM(shader_interface.push_constants_layout_get().storage_type_get(),
VKPushConstantsLayout::StorageType::STORAGE_BUFFER,
VKPushConstantsLayout::StorageType::UNIFORM_BUFFER);
shader_interface.push_constants_layout_get().storage_type_get() ==
VKPushConstantsLayout::StorageType::UNIFORM_BUFFER;
}
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();
const VKPushConstantsLayout::StorageType push_constants_storage_type =
VKPushConstantsLayout::determine_storage_type(info, context.physical_device_limits_get());
if (push_constants_storage_type == VKPushConstantsLayout::StorageType::STORAGE_BUFFER) {
ssbo_len_++;
names_size += PUSH_CONSTANTS_FALLBACK_NAME_LEN + 1;
}
else if (push_constants_storage_type == VKPushConstantsLayout::StorageType::UNIFORM_BUFFER) {
if (push_constants_storage_type == VKPushConstantsLayout::StorageType::UNIFORM_BUFFER) {
ubo_len_++;
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();
/* 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:
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: {
push_constant_descriptor_set_location = descriptor_set_location++;
const ShaderInput *push_constant_input = ubo_get(PUSH_CONSTANTS_FALLBACK_NAME.c_str());