Vulkan: Refactor descriptor set bindings
Shader interface used shader create info bind types to communicate bind types to descriptor sets. However Vulkan supports more bind types than Blender exposes in its API. Current implementation resulted that next to the bind type the actual resource was queried to find out what needed to be done. This PR makes it more clear to convert the shader create info bind type to `VKBindType` that contains the vulkan bind types we support. Pull Request: https://projects.blender.org/blender/blender/pulls/130509
This commit is contained in:
@@ -112,7 +112,17 @@ void VKDescriptorSetTracker::bind_texture_resource(const VKDevice &device,
|
||||
}
|
||||
case BindSpaceTextures::Type::Texture: {
|
||||
VKTexture *texture = static_cast<VKTexture *>(elem.resource);
|
||||
if (texture->type_ != GPU_TEXTURE_BUFFER) {
|
||||
if (texture->type_ == GPU_TEXTURE_BUFFER) {
|
||||
/* Texture buffers are no textures, but wrap around vertex buffers and need to be
|
||||
* bound as texel buffers. */
|
||||
/* TODO: Investigate if this can be improved in the API. */
|
||||
VKVertexBuffer *vertex_buffer = texture->source_buffer_;
|
||||
vertex_buffer->ensure_updated();
|
||||
vertex_buffer->ensure_buffer_view();
|
||||
bind_texel_buffer(vertex_buffer->vk_buffer_view_get(), resource_binding.location);
|
||||
access_info.buffers.append({vertex_buffer->vk_handle(), resource_binding.access_mask});
|
||||
}
|
||||
else {
|
||||
const VKSampler &sampler = device.samplers().get(elem.sampler);
|
||||
bind_image(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
sampler.vk_handle(),
|
||||
@@ -125,16 +135,6 @@ void VKDescriptorSetTracker::bind_texture_resource(const VKDevice &device,
|
||||
0,
|
||||
VK_REMAINING_ARRAY_LAYERS});
|
||||
}
|
||||
else {
|
||||
/* Texture buffers are no textures, but wrap around vertex buffers and need to be
|
||||
* bound as texel buffers. */
|
||||
/* TODO: Investigate if this can be improved in the API. */
|
||||
VKVertexBuffer *vertex_buffer = texture->source_buffer_;
|
||||
vertex_buffer->ensure_updated();
|
||||
vertex_buffer->ensure_buffer_view();
|
||||
bind_texel_buffer(vertex_buffer->vk_buffer_view_get(), resource_binding.location);
|
||||
access_info.buffers.append({vertex_buffer->vk_handle(), resource_binding.access_mask});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BindSpaceTextures::Type::Unused: {
|
||||
@@ -143,6 +143,29 @@ void VKDescriptorSetTracker::bind_texture_resource(const VKDevice &device,
|
||||
}
|
||||
}
|
||||
|
||||
void VKDescriptorSetTracker::bind_input_attachment_resource(
|
||||
const VKDevice &device,
|
||||
const VKStateManager &state_manager,
|
||||
const VKResourceBinding &resource_binding,
|
||||
render_graph::VKResourceAccessInfo &access_info)
|
||||
{
|
||||
const BindSpaceTextures::Elem &elem = state_manager.textures_.get(resource_binding.binding);
|
||||
VKTexture *texture = static_cast<VKTexture *>(elem.resource);
|
||||
BLI_assert(elem.resource_type == BindSpaceTextures::Type::Texture);
|
||||
|
||||
const VKSampler &sampler = device.samplers().get(elem.sampler);
|
||||
bind_image(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
sampler.vk_handle(),
|
||||
texture->image_view_get(resource_binding.arrayed).vk_handle(),
|
||||
VK_IMAGE_LAYOUT_GENERAL,
|
||||
resource_binding.location);
|
||||
access_info.images.append({texture->vk_image_handle(),
|
||||
resource_binding.access_mask,
|
||||
to_vk_image_aspect_flag_bits(texture->device_format_get()),
|
||||
0,
|
||||
VK_REMAINING_ARRAY_LAYERS});
|
||||
}
|
||||
|
||||
void VKDescriptorSetTracker::bind_storage_buffer_resource(
|
||||
const VKStateManager &state_manager,
|
||||
const VKResourceBinding &resource_binding,
|
||||
@@ -234,20 +257,24 @@ void VKDescriptorSetTracker::bind_shader_resources(const VKDevice &device,
|
||||
}
|
||||
|
||||
switch (resource_binding.bind_type) {
|
||||
case shader::ShaderCreateInfo::Resource::BindType::IMAGE:
|
||||
bind_image_resource(state_manager, resource_binding, access_info);
|
||||
case VKBindType::UNIFORM_BUFFER:
|
||||
bind_uniform_buffer_resource(state_manager, resource_binding, access_info);
|
||||
break;
|
||||
|
||||
case shader::ShaderCreateInfo::Resource::BindType::SAMPLER:
|
||||
bind_texture_resource(device, state_manager, resource_binding, access_info);
|
||||
break;
|
||||
|
||||
case shader::ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER:
|
||||
case VKBindType::STORAGE_BUFFER:
|
||||
bind_storage_buffer_resource(state_manager, resource_binding, access_info);
|
||||
break;
|
||||
|
||||
case shader::ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER:
|
||||
bind_uniform_buffer_resource(state_manager, resource_binding, access_info);
|
||||
case VKBindType::SAMPLER:
|
||||
bind_texture_resource(device, state_manager, resource_binding, access_info);
|
||||
break;
|
||||
|
||||
case VKBindType::IMAGE:
|
||||
bind_image_resource(state_manager, resource_binding, access_info);
|
||||
break;
|
||||
|
||||
case VKBindType::INPUT_ATTACHMENT:
|
||||
bind_input_attachment_resource(device, state_manager, resource_binding, access_info);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,6 +119,10 @@ class VKDescriptorSetTracker {
|
||||
void bind_uniform_buffer_resource(const VKStateManager &state_manager,
|
||||
const VKResourceBinding &resource_binding,
|
||||
render_graph::VKResourceAccessInfo &access_info);
|
||||
void bind_input_attachment_resource(const VKDevice &device,
|
||||
const VKStateManager &state_manager,
|
||||
const VKResourceBinding &resource_binding,
|
||||
render_graph::VKResourceAccessInfo &access_info);
|
||||
void bind_push_constants(VKPushConstants &push_constants,
|
||||
|
||||
render_graph::VKResourceAccessInfo &access_info);
|
||||
|
||||
@@ -13,6 +13,22 @@
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
static VKBindType to_bind_type(shader::ShaderCreateInfo::Resource::BindType bind_type)
|
||||
{
|
||||
switch (bind_type) {
|
||||
case shader::ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER:
|
||||
return VKBindType::UNIFORM_BUFFER;
|
||||
case shader::ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER:
|
||||
return VKBindType::STORAGE_BUFFER;
|
||||
case shader::ShaderCreateInfo::Resource::BindType::SAMPLER:
|
||||
return VKBindType::SAMPLER;
|
||||
case shader::ShaderCreateInfo::Resource::BindType::IMAGE:
|
||||
return VKBindType::IMAGE;
|
||||
}
|
||||
BLI_assert_unreachable();
|
||||
return VKBindType::UNIFORM_BUFFER;
|
||||
}
|
||||
|
||||
void VKShaderInterface::init(const shader::ShaderCreateInfo &info)
|
||||
{
|
||||
static char PUSH_CONSTANTS_FALLBACK_NAME[] = "push_constants_fallback";
|
||||
@@ -190,7 +206,7 @@ void VKShaderInterface::init(const shader::ShaderCreateInfo &info)
|
||||
BLI_assert(input);
|
||||
descriptor_set_location_update(input,
|
||||
descriptor_set_location++,
|
||||
shader::ShaderCreateInfo::Resource::BindType::SAMPLER,
|
||||
VKBindType::INPUT_ATTACHMENT,
|
||||
std::nullopt,
|
||||
VKImageViewArrayed::DONT_CARE);
|
||||
}
|
||||
@@ -234,7 +250,9 @@ void VKShaderInterface::init(const shader::ShaderCreateInfo &info)
|
||||
VKImageViewArrayed::ARRAYED :
|
||||
VKImageViewArrayed::NOT_ARRAYED;
|
||||
}
|
||||
descriptor_set_location_update(input, descriptor_set_location++, res.bind_type, res, arrayed);
|
||||
|
||||
const VKBindType bind_type = to_bind_type(res.bind_type);
|
||||
descriptor_set_location_update(input, descriptor_set_location++, bind_type, res, arrayed);
|
||||
}
|
||||
|
||||
/* Post initializing push constants. */
|
||||
@@ -245,7 +263,7 @@ void VKShaderInterface::init(const shader::ShaderCreateInfo &info)
|
||||
const ShaderInput *push_constant_input = ubo_get(PUSH_CONSTANTS_FALLBACK_NAME);
|
||||
descriptor_set_location_update(push_constant_input,
|
||||
push_constants_fallback_location,
|
||||
shader::ShaderCreateInfo::Resource::UNIFORM_BUFFER,
|
||||
VKBindType::UNIFORM_BUFFER,
|
||||
std::nullopt,
|
||||
VKImageViewArrayed::DONT_CARE);
|
||||
}
|
||||
@@ -263,17 +281,15 @@ static int32_t shader_input_index(const ShaderInput *shader_inputs,
|
||||
void VKShaderInterface::descriptor_set_location_update(
|
||||
const ShaderInput *shader_input,
|
||||
const VKDescriptorSet::Location location,
|
||||
const shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const VKBindType bind_type,
|
||||
std::optional<const shader::ShaderCreateInfo::Resource> resource,
|
||||
VKImageViewArrayed arrayed)
|
||||
{
|
||||
BLI_assert_msg(resource.has_value() ||
|
||||
ELEM(bind_type,
|
||||
shader::ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER,
|
||||
shader::ShaderCreateInfo::Resource::BindType::SAMPLER),
|
||||
ELEM(bind_type, VKBindType::UNIFORM_BUFFER, VKBindType::SAMPLER),
|
||||
"Incorrect parameters, when no resource is given, it must be the uniform buffer "
|
||||
"for storing push constants or sampler for subpasses.");
|
||||
BLI_assert_msg(!resource.has_value() || resource->bind_type == bind_type,
|
||||
"for storing push constants or input attachment for subpass inputs.");
|
||||
BLI_assert_msg(!resource.has_value() || to_bind_type(resource->bind_type) == bind_type,
|
||||
"Incorrect parameter, bind types do not match.");
|
||||
|
||||
int32_t index = shader_input_index(inputs_, shader_input);
|
||||
@@ -309,10 +325,10 @@ void VKShaderInterface::descriptor_set_location_update(
|
||||
break;
|
||||
};
|
||||
}
|
||||
else if (bind_type == shader::ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER) {
|
||||
else if (bind_type == VKBindType::UNIFORM_BUFFER) {
|
||||
vk_access_flags |= VK_ACCESS_UNIFORM_READ_BIT;
|
||||
}
|
||||
else if (bind_type == shader::ShaderCreateInfo::Resource::BindType::SAMPLER) {
|
||||
else if (bind_type == VKBindType::INPUT_ATTACHMENT) {
|
||||
vk_access_flags |= VK_ACCESS_SHADER_READ_BIT;
|
||||
}
|
||||
|
||||
@@ -347,7 +363,7 @@ const std::optional<VKDescriptorSet::Location> VKShaderInterface::descriptor_set
|
||||
return std::nullopt;
|
||||
}
|
||||
const VKResourceBinding &resource_binding = resource_binding_info(shader_input);
|
||||
if (resource_binding.bind_type != bind_type) {
|
||||
if (resource_binding.bind_type != to_bind_type(bind_type)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return resource_binding.location;
|
||||
@@ -391,10 +407,8 @@ void VKShaderInterface::init_descriptor_set_layout_info(
|
||||
info.compute_source_.is_empty() && info.compute_source_generated.empty() ?
|
||||
VK_SHADER_STAGE_ALL_GRAPHICS :
|
||||
VK_SHADER_STAGE_COMPUTE_BIT;
|
||||
for (int index : IndexRange(info.subpass_inputs_.size())) {
|
||||
UNUSED_VARS(index);
|
||||
descriptor_set_layout_info_.bindings.append(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
|
||||
}
|
||||
descriptor_set_layout_info_.bindings.append_n_times(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
info.subpass_inputs_.size());
|
||||
for (const shader::ShaderCreateInfo::Resource &res : all_resources) {
|
||||
descriptor_set_layout_info_.bindings.append(to_vk_descriptor_type(res));
|
||||
}
|
||||
|
||||
@@ -20,9 +20,23 @@
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
/**
|
||||
* Bind types to bind resources to a shader.
|
||||
*
|
||||
* Keep in sync with gpu::shader::ShaderCreateInfo::Resource::BindType.
|
||||
* We add the term `INPUT_ATTACHMENT` as it is stored as a subpass input in the shader create info.
|
||||
*/
|
||||
/* TODO: Investigate if `TEXEL_BUFFER` can be added as well.*/
|
||||
enum VKBindType {
|
||||
UNIFORM_BUFFER = 0,
|
||||
STORAGE_BUFFER,
|
||||
SAMPLER,
|
||||
IMAGE,
|
||||
INPUT_ATTACHMENT,
|
||||
};
|
||||
|
||||
struct VKResourceBinding {
|
||||
shader::ShaderCreateInfo::Resource::BindType bind_type =
|
||||
shader::ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER;
|
||||
VKBindType bind_type = VKBindType::UNIFORM_BUFFER;
|
||||
int binding = -1;
|
||||
|
||||
VKDescriptorSet::Location location;
|
||||
@@ -95,7 +109,7 @@ class VKShaderInterface : public ShaderInterface {
|
||||
void descriptor_set_location_update(
|
||||
const ShaderInput *shader_input,
|
||||
const VKDescriptorSet::Location location,
|
||||
const shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const VKBindType bind_type,
|
||||
std::optional<const shader::ShaderCreateInfo::Resource> resource,
|
||||
VKImageViewArrayed arrayed);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user