Files
test/source/blender/gpu/vulkan/vk_index_buffer.cc
Jeroen Bakker 3f6e2ea915 Vulkan: Shader interface access mask
When building the resource access used when adding dispatch/draw commands
to the render graph, the access mask is required. This PR stores the
access mask in the shader interface. When binding the resources referenced
by the state manager, the resource access info struct is populated with
the access flags.

In the near future the resource access info will be passed when adding
a dispatch/draw node to the render graph to generate the links.

Pull Request: https://projects.blender.org/blender/blender/pulls/120908
2024-04-22 20:47:30 +02:00

108 lines
2.9 KiB
C++

/* SPDX-FileCopyrightText: 2022 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup gpu
*/
#include "vk_index_buffer.hh"
#include "vk_shader.hh"
#include "vk_shader_interface.hh"
#include "vk_staging_buffer.hh"
#include "vk_state_manager.hh"
namespace blender::gpu {
void VKIndexBuffer::ensure_updated()
{
if (is_subrange_) {
src_->upload_data();
return;
}
if (!buffer_.is_allocated()) {
allocate();
}
if (data_ == nullptr) {
return;
}
VKContext &context = *VKContext::get();
VKStagingBuffer staging_buffer(buffer_, VKStagingBuffer::Direction::HostToDevice);
staging_buffer.host_buffer_get().update(data_);
staging_buffer.copy_to_device(context);
MEM_SAFE_FREE(data_);
}
void VKIndexBuffer::upload_data()
{
ensure_updated();
}
void VKIndexBuffer::bind(VKContext &context)
{
context.command_buffers_get().bind(buffer_get(), to_vk_index_type(index_type_));
}
void VKIndexBuffer::bind_as_ssbo(uint binding)
{
VKContext::get()->state_manager_get().storage_buffer_bind(*this, binding);
}
void VKIndexBuffer::add_to_descriptor_set(AddToDescriptorSetContext &data,
int binding,
shader::ShaderCreateInfo::Resource::BindType bind_type,
const GPUSamplerState /*sampler_state*/)
{
BLI_assert(bind_type == shader::ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER);
ensure_updated();
const std::optional<VKDescriptorSet::Location> location =
data.shader_interface.descriptor_set_location(bind_type, binding);
if (location) {
data.descriptor_set.bind_as_ssbo(*this, *location);
render_graph::VKBufferAccess buffer_access = {};
buffer_access.vk_buffer = buffer_.vk_handle();
buffer_access.vk_access_flags = data.shader_interface.access_mask(bind_type, binding);
data.resource_access_info.buffers.append(buffer_access);
}
}
void VKIndexBuffer::read(uint32_t *data) const
{
VKContext &context = *VKContext::get();
VKStagingBuffer staging_buffer(buffer_, VKStagingBuffer::Direction::DeviceToHost);
staging_buffer.copy_from_device(context);
staging_buffer.host_buffer_get().read(context, data);
}
void VKIndexBuffer::update_sub(uint /*start*/, uint /*len*/, const void * /*data*/)
{
NOT_YET_IMPLEMENTED
}
void VKIndexBuffer::strip_restart_indices()
{
NOT_YET_IMPLEMENTED
}
void VKIndexBuffer::allocate()
{
GPUUsageType usage = data_ == nullptr ? GPU_USAGE_DEVICE_ONLY : GPU_USAGE_STATIC;
buffer_.create(size_get(),
usage,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
false);
debug::object_label(buffer_.vk_handle(), "IndexBuffer");
}
VKBuffer &VKIndexBuffer::buffer_get()
{
return is_subrange_ ? unwrap(src_)->buffer_ : buffer_;
}
} // namespace blender::gpu