Vulkan: Push constants #104880
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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());
|
||||||
|
|
Loading…
Reference in New Issue