Merge branch 'blender-v4.5-release'
This commit is contained in:
@@ -306,6 +306,7 @@ class GHOST_DeviceVK {
|
||||
vulkan_12_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
|
||||
vulkan_12_features.shaderOutputLayer = features_12.shaderOutputLayer;
|
||||
vulkan_12_features.shaderOutputViewportIndex = features_12.shaderOutputViewportIndex;
|
||||
vulkan_12_features.bufferDeviceAddress = features_12.bufferDeviceAddress;
|
||||
vulkan_12_features.timelineSemaphore = VK_TRUE;
|
||||
feature_struct_ptr.push_back(&vulkan_12_features);
|
||||
|
||||
@@ -365,6 +366,18 @@ class GHOST_DeviceVK {
|
||||
use_vk_ext_swapchain_maintenance_1 = true;
|
||||
}
|
||||
|
||||
/* Descriptor buffers */
|
||||
VkPhysicalDeviceDescriptorBufferPropertiesEXT descriptor_buffer = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_FEATURES_EXT,
|
||||
nullptr,
|
||||
VK_TRUE,
|
||||
VK_FALSE,
|
||||
VK_FALSE,
|
||||
VK_FALSE};
|
||||
if (extension_requested(VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME)) {
|
||||
feature_struct_ptr.push_back(&descriptor_buffer);
|
||||
}
|
||||
|
||||
/* Query and enable Fragment Shader Barycentrics. */
|
||||
VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR fragment_shader_barycentric = {};
|
||||
fragment_shader_barycentric.sType =
|
||||
@@ -1220,6 +1233,8 @@ GHOST_TSuccess GHOST_ContextVK::initializeDrawingContext()
|
||||
optional_device_extensions.push_back(VK_KHR_MAINTENANCE_4_EXTENSION_NAME);
|
||||
optional_device_extensions.push_back(VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME);
|
||||
optional_device_extensions.push_back(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME);
|
||||
optional_device_extensions.push_back(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
|
||||
optional_device_extensions.push_back(VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME);
|
||||
|
||||
VkInstance instance = VK_NULL_HANDLE;
|
||||
if (!vulkan_device.has_value()) {
|
||||
|
||||
@@ -55,6 +55,40 @@ void vk_pipeline_data_build_commands(VKCommandBufferInterface &command_buffer,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
if (assign_if_different(r_bound_pipeline.descriptor_buffer_device_address,
|
||||
pipeline_data.descriptor_buffer_device_address) &&
|
||||
r_bound_pipeline.descriptor_buffer_device_address != 0)
|
||||
{
|
||||
r_bound_pipeline.descriptor_buffer_offset = pipeline_data.descriptor_buffer_offset;
|
||||
VkDescriptorBufferBindingInfoEXT descriptor_buffer_binding_info = {
|
||||
VK_STRUCTURE_TYPE_DESCRIPTOR_BUFFER_BINDING_INFO_EXT,
|
||||
nullptr,
|
||||
r_bound_pipeline.descriptor_buffer_device_address,
|
||||
VK_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT |
|
||||
VK_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT};
|
||||
command_buffer.bind_descriptor_buffers(1, &descriptor_buffer_binding_info);
|
||||
|
||||
uint32_t buffer_index = 0;
|
||||
command_buffer.set_descriptor_buffer_offsets(vk_pipeline_bind_point,
|
||||
pipeline_data.vk_pipeline_layout,
|
||||
0,
|
||||
1,
|
||||
&buffer_index,
|
||||
&r_bound_pipeline.descriptor_buffer_offset);
|
||||
}
|
||||
else if (assign_if_different(r_bound_pipeline.descriptor_buffer_offset,
|
||||
pipeline_data.descriptor_buffer_offset) &&
|
||||
r_bound_pipeline.descriptor_buffer_device_address != 0)
|
||||
{
|
||||
uint32_t buffer_index = 0;
|
||||
command_buffer.set_descriptor_buffer_offsets(vk_pipeline_bind_point,
|
||||
pipeline_data.vk_pipeline_layout,
|
||||
0,
|
||||
1,
|
||||
&buffer_index,
|
||||
&r_bound_pipeline.descriptor_buffer_offset);
|
||||
}
|
||||
|
||||
if (pipeline_data.push_constants_size) {
|
||||
command_buffer.push_constants(pipeline_data.vk_pipeline_layout,
|
||||
vk_shader_stage_flags,
|
||||
|
||||
@@ -24,6 +24,10 @@ struct VKPipelineData {
|
||||
VkPipeline vk_pipeline;
|
||||
VkPipelineLayout vk_pipeline_layout;
|
||||
VkDescriptorSet vk_descriptor_set;
|
||||
/* VK_EXT_descriptor_buffer */
|
||||
VkDeviceAddress descriptor_buffer_device_address;
|
||||
VkDeviceSize descriptor_buffer_offset;
|
||||
|
||||
uint32_t push_constants_size;
|
||||
const void *push_constants_data;
|
||||
};
|
||||
@@ -65,6 +69,8 @@ struct VKViewportData {
|
||||
struct VKBoundPipeline {
|
||||
VkPipeline vk_pipeline;
|
||||
VkDescriptorSet vk_descriptor_set;
|
||||
VkDeviceAddress descriptor_buffer_device_address;
|
||||
VkDeviceSize descriptor_buffer_offset;
|
||||
};
|
||||
|
||||
struct VKIndexBufferBinding {
|
||||
|
||||
@@ -476,6 +476,21 @@ class CommandBufferLog : public VKCommandBufferInterface {
|
||||
|
||||
void begin_debug_utils_label(const VkDebugUtilsLabelEXT * /*vk_debug_utils_label*/) override {}
|
||||
void end_debug_utils_label() override {}
|
||||
|
||||
/* VK_EXT_descriptor_buffer */
|
||||
void bind_descriptor_buffers(
|
||||
uint32_t /*buffer_count*/,
|
||||
const VkDescriptorBufferBindingInfoEXT * /*p_binding_infos*/) override
|
||||
{
|
||||
}
|
||||
void set_descriptor_buffer_offsets(VkPipelineBindPoint /*pipeline_bind_point*/,
|
||||
VkPipelineLayout /*layout*/,
|
||||
uint32_t /*first_set*/,
|
||||
uint32_t /*set_count*/,
|
||||
const uint32_t * /*p_buffer_indices*/,
|
||||
const VkDeviceSize * /*p_offsets*/) override
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class VKRenderGraphTest : public ::testing::Test {
|
||||
|
||||
@@ -326,4 +326,28 @@ void VKCommandBufferWrapper::end_debug_utils_label()
|
||||
}
|
||||
}
|
||||
|
||||
/* VK_EXT_descriptor_buffer */
|
||||
void VKCommandBufferWrapper::bind_descriptor_buffers(
|
||||
uint32_t buffer_count, const VkDescriptorBufferBindingInfoEXT *p_binding_infos)
|
||||
{
|
||||
const VKDevice &device = VKBackend::get().device;
|
||||
device.functions.vkCmdBindDescriptorBuffers(vk_command_buffer_, buffer_count, p_binding_infos);
|
||||
}
|
||||
void VKCommandBufferWrapper::set_descriptor_buffer_offsets(VkPipelineBindPoint pipeline_bind_point,
|
||||
VkPipelineLayout layout,
|
||||
uint32_t first_set,
|
||||
uint32_t set_count,
|
||||
const uint32_t *p_buffer_indices,
|
||||
const VkDeviceSize *p_offsets)
|
||||
{
|
||||
const VKDevice &device = VKBackend::get().device;
|
||||
device.functions.vkCmdSetDescriptorBufferOffsets(vk_command_buffer_,
|
||||
pipeline_bind_point,
|
||||
layout,
|
||||
first_set,
|
||||
set_count,
|
||||
p_buffer_indices,
|
||||
p_offsets);
|
||||
}
|
||||
|
||||
} // namespace blender::gpu::render_graph
|
||||
|
||||
@@ -141,6 +141,16 @@ class VKCommandBufferInterface {
|
||||
/* VK_EXT_debug_utils */
|
||||
virtual void begin_debug_utils_label(const VkDebugUtilsLabelEXT *vk_debug_utils_label) = 0;
|
||||
virtual void end_debug_utils_label() = 0;
|
||||
|
||||
/* VK_EXT_descriptor_buffer */
|
||||
virtual void bind_descriptor_buffers(
|
||||
uint32_t buffer_count, const VkDescriptorBufferBindingInfoEXT *p_binding_infos) = 0;
|
||||
virtual void set_descriptor_buffer_offsets(VkPipelineBindPoint pipeline_bind_point,
|
||||
VkPipelineLayout layout,
|
||||
uint32_t first_set,
|
||||
uint32_t set_count,
|
||||
const uint32_t *p_buffer_indices,
|
||||
const VkDeviceSize *p_offsets) = 0;
|
||||
};
|
||||
|
||||
class VKCommandBufferWrapper : public VKCommandBufferInterface {
|
||||
@@ -261,6 +271,16 @@ class VKCommandBufferWrapper : public VKCommandBufferInterface {
|
||||
void end_rendering() override;
|
||||
void begin_debug_utils_label(const VkDebugUtilsLabelEXT *vk_debug_utils_label) override;
|
||||
void end_debug_utils_label() override;
|
||||
|
||||
/* VK_EXT_descriptor_buffer */
|
||||
void bind_descriptor_buffers(uint32_t buffer_count,
|
||||
const VkDescriptorBufferBindingInfoEXT *p_binding_infos) override;
|
||||
void set_descriptor_buffer_offsets(VkPipelineBindPoint pipeline_bind_point,
|
||||
VkPipelineLayout layout,
|
||||
uint32_t first_set,
|
||||
uint32_t set_count,
|
||||
const uint32_t *p_buffer_indices,
|
||||
const VkDeviceSize *p_offsets) override;
|
||||
};
|
||||
|
||||
} // namespace blender::gpu::render_graph
|
||||
|
||||
@@ -327,7 +327,7 @@ struct VKRenderGraphNode {
|
||||
}
|
||||
};
|
||||
|
||||
BLI_STATIC_ASSERT(sizeof(VKRenderGraphNode) <= 64,
|
||||
BLI_STATIC_ASSERT(sizeof(VKRenderGraphNode) <= 96,
|
||||
"VKRenderGraphNode should be kept small. Consider moving data to the "
|
||||
"VKRenderGraphStorage class.");
|
||||
|
||||
|
||||
@@ -137,6 +137,9 @@ static Vector<StringRefNull> missing_capabilities_get(VkPhysicalDevice vk_physic
|
||||
if (features_12.timelineSemaphore == VK_FALSE) {
|
||||
missing_capabilities.append("timeline semaphores");
|
||||
}
|
||||
if (features_12.bufferDeviceAddress == VK_FALSE) {
|
||||
missing_capabilities.append("buffer device address");
|
||||
}
|
||||
|
||||
/* Check device extensions. */
|
||||
uint32_t vk_extension_count;
|
||||
@@ -385,6 +388,7 @@ void VKBackend::detect_workarounds(VKDevice &device)
|
||||
extensions.dynamic_rendering = false;
|
||||
extensions.dynamic_rendering_local_read = false;
|
||||
extensions.dynamic_rendering_unused_attachments = false;
|
||||
extensions.descriptor_buffer = false;
|
||||
|
||||
GCaps.render_pass_workaround = true;
|
||||
|
||||
@@ -414,6 +418,8 @@ void VKBackend::detect_workarounds(VKDevice &device)
|
||||
#else
|
||||
extensions.external_memory = false;
|
||||
#endif
|
||||
extensions.descriptor_buffer = device.supports_extension(
|
||||
VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME);
|
||||
|
||||
/* AMD GPUs don't support texture formats that use are aligned to 24 or 48 bits. */
|
||||
if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY) ||
|
||||
|
||||
@@ -77,6 +77,11 @@ bool VKBuffer::create(size_t size_in_bytes,
|
||||
vma_create_info.pool = device.vma_pools.external_memory;
|
||||
}
|
||||
|
||||
const bool use_descriptor_buffer = device.extensions_get().descriptor_buffer;
|
||||
if (use_descriptor_buffer) {
|
||||
create_info.usage |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
|
||||
}
|
||||
|
||||
VkResult result = vmaCreateBuffer(
|
||||
allocator, &create_info, &vma_create_info, &vk_buffer_, &allocation_, nullptr);
|
||||
if (result != VK_SUCCESS) {
|
||||
@@ -88,11 +93,18 @@ bool VKBuffer::create(size_t size_in_bytes,
|
||||
|
||||
device.resources.add_buffer(vk_buffer_);
|
||||
|
||||
vmaGetAllocationMemoryProperties(allocator, allocation_, &vk_memory_property_flags_);
|
||||
if (use_descriptor_buffer) {
|
||||
VkBufferDeviceAddressInfo vk_buffer_device_address_info = {
|
||||
VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, nullptr, vk_buffer_};
|
||||
vk_device_address = vkGetBufferDeviceAddress(device.vk_handle(),
|
||||
&vk_buffer_device_address_info);
|
||||
}
|
||||
|
||||
vmaGetAllocationMemoryProperties(allocator, allocation_, &vk_memory_property_flags_);
|
||||
if (vk_memory_property_flags_ & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
|
||||
return map();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,8 +33,11 @@ class VKBuffer : public NonCopyable {
|
||||
/* Pointer to the virtually mapped memory. */
|
||||
void *mapped_memory_ = nullptr;
|
||||
|
||||
VkDeviceAddress vk_device_address = 0;
|
||||
|
||||
public:
|
||||
VKBuffer() = default;
|
||||
VKBuffer(VKBuffer &&other) = default;
|
||||
virtual ~VKBuffer();
|
||||
|
||||
/** Has this buffer been allocated? */
|
||||
@@ -108,6 +111,11 @@ class VKBuffer : public NonCopyable {
|
||||
*/
|
||||
void *mapped_memory_get() const;
|
||||
|
||||
VkDeviceAddress device_address_get() const
|
||||
{
|
||||
return vk_device_address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this buffer mapped (visible on host)
|
||||
*/
|
||||
|
||||
@@ -157,9 +157,11 @@ TimelineValue VKContext::flush_render_graph(RenderGraphFlushFlags flags,
|
||||
framebuffer.rendering_end(*this);
|
||||
}
|
||||
}
|
||||
descriptor_set_get().upload_descriptor_sets();
|
||||
descriptor_pools_get().discard(*this);
|
||||
VKDevice &device = VKBackend::get().device;
|
||||
descriptor_set_get().upload_descriptor_sets();
|
||||
if (!device.extensions_get().descriptor_buffer) {
|
||||
descriptor_pools_get().discard(*this);
|
||||
}
|
||||
TimelineValue timeline = device.render_graph_submit(
|
||||
&render_graph_.value().get(),
|
||||
discard_pool,
|
||||
@@ -317,8 +319,7 @@ void VKContext::update_pipeline_data(VKShader &vk_shader,
|
||||
r_pipeline_data.vk_descriptor_set = VK_NULL_HANDLE;
|
||||
if (vk_shader.has_descriptor_set()) {
|
||||
VKDescriptorSetTracker &descriptor_set = descriptor_set_get();
|
||||
descriptor_set.update_descriptor_set(*this, access_info_);
|
||||
r_pipeline_data.vk_descriptor_set = descriptor_set.vk_descriptor_set;
|
||||
descriptor_set.update_descriptor_set(*this, access_info_, r_pipeline_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,61 +17,49 @@
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
void VKDescriptorSetTracker::bind_buffer(VkDescriptorType vk_descriptor_type,
|
||||
VkBuffer vk_buffer,
|
||||
VkDeviceSize buffer_offset,
|
||||
VkDeviceSize size_in_bytes,
|
||||
VKDescriptorSet::Location location)
|
||||
void VKDescriptorSetTracker::update_descriptor_set(VKContext &context,
|
||||
render_graph::VKResourceAccessInfo &access_info,
|
||||
render_graph::VKPipelineData &r_pipeline_data)
|
||||
{
|
||||
vk_descriptor_buffer_infos_.append({vk_buffer, buffer_offset, size_in_bytes});
|
||||
vk_write_descriptor_sets_.append({VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
nullptr,
|
||||
vk_descriptor_set,
|
||||
location,
|
||||
0,
|
||||
1,
|
||||
vk_descriptor_type,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr});
|
||||
VKShader &shader = *unwrap(context.shader);
|
||||
VKStateManager &state_manager = context.state_manager_get();
|
||||
|
||||
/* Can we reuse previous descriptor set. */
|
||||
if (!state_manager.is_dirty &&
|
||||
!assign_if_different(vk_descriptor_set_layout_, shader.vk_descriptor_set_layout_get()) &&
|
||||
shader.push_constants.layout_get().storage_type_get() !=
|
||||
VKPushConstants::StorageType::UNIFORM_BUFFER)
|
||||
{
|
||||
return;
|
||||
}
|
||||
state_manager.is_dirty = false;
|
||||
|
||||
VKDevice &device = VKBackend::get().device;
|
||||
VkDescriptorSetLayout vk_descriptor_set_layout = shader.vk_descriptor_set_layout_get();
|
||||
VKDescriptorSetUpdator *updator = &descriptor_sets;
|
||||
if (device.extensions_get().descriptor_buffer) {
|
||||
updator = &descriptor_buffers;
|
||||
}
|
||||
updator->allocate_new_descriptor_set(
|
||||
device, context, shader, vk_descriptor_set_layout, r_pipeline_data);
|
||||
updator->bind_shader_resources(device, state_manager, shader, access_info);
|
||||
}
|
||||
|
||||
void VKDescriptorSetTracker::bind_texel_buffer(VkBufferView vk_buffer_view,
|
||||
const VKDescriptorSet::Location location)
|
||||
void VKDescriptorSetTracker::upload_descriptor_sets()
|
||||
{
|
||||
vk_buffer_views_.append(vk_buffer_view);
|
||||
vk_write_descriptor_sets_.append({VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
nullptr,
|
||||
vk_descriptor_set,
|
||||
location,
|
||||
0,
|
||||
1,
|
||||
VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr});
|
||||
VKDevice &device = VKBackend::get().device;
|
||||
VKDescriptorSetUpdator &updator = descriptor_sets;
|
||||
if (device.extensions_get().descriptor_buffer) {
|
||||
updator = descriptor_buffers;
|
||||
}
|
||||
updator.upload_descriptor_sets();
|
||||
}
|
||||
|
||||
void VKDescriptorSetTracker::bind_image(VkDescriptorType vk_descriptor_type,
|
||||
VkSampler vk_sampler,
|
||||
VkImageView vk_image_view,
|
||||
VkImageLayout vk_image_layout,
|
||||
VKDescriptorSet::Location location)
|
||||
{
|
||||
vk_descriptor_image_infos_.append({vk_sampler, vk_image_view, vk_image_layout});
|
||||
vk_write_descriptor_sets_.append({VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
nullptr,
|
||||
vk_descriptor_set,
|
||||
location,
|
||||
0,
|
||||
1,
|
||||
vk_descriptor_type,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr});
|
||||
}
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name VKDescriptorSetUpdator
|
||||
* \{ */
|
||||
|
||||
void VKDescriptorSetTracker::bind_image_resource(const VKStateManager &state_manager,
|
||||
void VKDescriptorSetUpdator::bind_image_resource(const VKStateManager &state_manager,
|
||||
const VKResourceBinding &resource_binding,
|
||||
render_graph::VKResourceAccessInfo &access_info)
|
||||
{
|
||||
@@ -97,7 +85,7 @@ void VKDescriptorSetTracker::bind_image_resource(const VKStateManager &state_man
|
||||
layer_count});
|
||||
}
|
||||
|
||||
void VKDescriptorSetTracker::bind_texture_resource(const VKDevice &device,
|
||||
void VKDescriptorSetUpdator::bind_texture_resource(const VKDevice &device,
|
||||
const VKStateManager &state_manager,
|
||||
const VKResourceBinding &resource_binding,
|
||||
render_graph::VKResourceAccessInfo &access_info)
|
||||
@@ -105,11 +93,10 @@ void VKDescriptorSetTracker::bind_texture_resource(const VKDevice &device,
|
||||
const BindSpaceTextures::Elem &elem = state_manager.textures_.get(resource_binding.binding);
|
||||
switch (elem.resource_type) {
|
||||
case BindSpaceTextures::Type::VertexBuffer: {
|
||||
VKVertexBuffer *vertex_buffer = static_cast<VKVertexBuffer *>(elem.resource);
|
||||
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});
|
||||
VKVertexBuffer &vertex_buffer = *static_cast<VKVertexBuffer *>(elem.resource);
|
||||
vertex_buffer.ensure_updated();
|
||||
bind_texel_buffer(vertex_buffer, resource_binding.location);
|
||||
access_info.buffers.append({vertex_buffer.vk_handle(), resource_binding.access_mask});
|
||||
break;
|
||||
}
|
||||
case BindSpaceTextures::Type::Texture: {
|
||||
@@ -118,11 +105,10 @@ void VKDescriptorSetTracker::bind_texture_resource(const VKDevice &device,
|
||||
/* 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});
|
||||
VKVertexBuffer &vertex_buffer = *texture->source_buffer_;
|
||||
vertex_buffer.ensure_updated();
|
||||
bind_texel_buffer(vertex_buffer, resource_binding.location);
|
||||
access_info.buffers.append({vertex_buffer.vk_handle(), resource_binding.access_mask});
|
||||
}
|
||||
else {
|
||||
const VKSampler &sampler = device.samplers().get(elem.sampler);
|
||||
@@ -146,7 +132,7 @@ void VKDescriptorSetTracker::bind_texture_resource(const VKDevice &device,
|
||||
}
|
||||
}
|
||||
|
||||
void VKDescriptorSetTracker::bind_input_attachment_resource(
|
||||
void VKDescriptorSetUpdator::bind_input_attachment_resource(
|
||||
const VKDevice &device,
|
||||
const VKStateManager &state_manager,
|
||||
const VKResourceBinding &resource_binding,
|
||||
@@ -215,7 +201,7 @@ void VKDescriptorSetTracker::bind_input_attachment_resource(
|
||||
}
|
||||
}
|
||||
|
||||
void VKDescriptorSetTracker::bind_storage_buffer_resource(
|
||||
void VKDescriptorSetUpdator::bind_storage_buffer_resource(
|
||||
const VKStateManager &state_manager,
|
||||
const VKResourceBinding &resource_binding,
|
||||
render_graph::VKResourceAccessInfo &access_info)
|
||||
@@ -224,12 +210,14 @@ void VKDescriptorSetTracker::bind_storage_buffer_resource(
|
||||
resource_binding.binding);
|
||||
VkBuffer vk_buffer = VK_NULL_HANDLE;
|
||||
VkDeviceSize vk_device_size = 0;
|
||||
VkDeviceAddress vk_device_address = 0;
|
||||
switch (elem.resource_type) {
|
||||
case BindSpaceStorageBuffers::Type::IndexBuffer: {
|
||||
VKIndexBuffer *index_buffer = static_cast<VKIndexBuffer *>(elem.resource);
|
||||
index_buffer->ensure_updated();
|
||||
vk_buffer = index_buffer->vk_handle();
|
||||
vk_device_size = index_buffer->size_get();
|
||||
vk_device_address = index_buffer->device_address_get();
|
||||
break;
|
||||
}
|
||||
case BindSpaceStorageBuffers::Type::VertexBuffer: {
|
||||
@@ -237,6 +225,7 @@ void VKDescriptorSetTracker::bind_storage_buffer_resource(
|
||||
vertex_buffer->ensure_updated();
|
||||
vk_buffer = vertex_buffer->vk_handle();
|
||||
vk_device_size = vertex_buffer->size_used_get();
|
||||
vk_device_address = vertex_buffer->device_address_get();
|
||||
break;
|
||||
}
|
||||
case BindSpaceStorageBuffers::Type::UniformBuffer: {
|
||||
@@ -244,6 +233,7 @@ void VKDescriptorSetTracker::bind_storage_buffer_resource(
|
||||
uniform_buffer->ensure_updated();
|
||||
vk_buffer = uniform_buffer->vk_handle();
|
||||
vk_device_size = uniform_buffer->size_in_bytes();
|
||||
vk_device_address = uniform_buffer->device_address_get();
|
||||
break;
|
||||
}
|
||||
case BindSpaceStorageBuffers::Type::StorageBuffer: {
|
||||
@@ -251,12 +241,14 @@ void VKDescriptorSetTracker::bind_storage_buffer_resource(
|
||||
storage_buffer->ensure_allocated();
|
||||
vk_buffer = storage_buffer->vk_handle();
|
||||
vk_device_size = storage_buffer->size_in_bytes();
|
||||
vk_device_address = storage_buffer->device_address_get();
|
||||
break;
|
||||
}
|
||||
case BindSpaceStorageBuffers::Type::Buffer: {
|
||||
VKBuffer *buffer = static_cast<VKBuffer *>(elem.resource);
|
||||
vk_buffer = buffer->vk_handle();
|
||||
vk_device_size = buffer->size_in_bytes();
|
||||
vk_device_address = buffer->device_address_get();
|
||||
break;
|
||||
}
|
||||
case BindSpaceStorageBuffers::Type::Unused: {
|
||||
@@ -266,6 +258,7 @@ void VKDescriptorSetTracker::bind_storage_buffer_resource(
|
||||
|
||||
bind_buffer(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
vk_buffer,
|
||||
vk_device_address,
|
||||
elem.offset,
|
||||
vk_device_size - elem.offset,
|
||||
resource_binding.location);
|
||||
@@ -274,7 +267,7 @@ void VKDescriptorSetTracker::bind_storage_buffer_resource(
|
||||
}
|
||||
}
|
||||
|
||||
void VKDescriptorSetTracker::bind_uniform_buffer_resource(
|
||||
void VKDescriptorSetUpdator::bind_uniform_buffer_resource(
|
||||
const VKStateManager &state_manager,
|
||||
const VKResourceBinding &resource_binding,
|
||||
render_graph::VKResourceAccessInfo &access_info)
|
||||
@@ -283,13 +276,14 @@ void VKDescriptorSetTracker::bind_uniform_buffer_resource(
|
||||
uniform_buffer.ensure_updated();
|
||||
bind_buffer(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
uniform_buffer.vk_handle(),
|
||||
uniform_buffer.device_address_get(),
|
||||
0,
|
||||
uniform_buffer.size_in_bytes(),
|
||||
resource_binding.location);
|
||||
access_info.buffers.append({uniform_buffer.vk_handle(), resource_binding.access_mask});
|
||||
}
|
||||
|
||||
void VKDescriptorSetTracker::bind_push_constants(VKPushConstants &push_constants,
|
||||
void VKDescriptorSetUpdator::bind_push_constants(VKPushConstants &push_constants,
|
||||
render_graph::VKResourceAccessInfo &access_info)
|
||||
{
|
||||
if (push_constants.layout_get().storage_type_get() !=
|
||||
@@ -301,13 +295,14 @@ void VKDescriptorSetTracker::bind_push_constants(VKPushConstants &push_constants
|
||||
const VKUniformBuffer &uniform_buffer = *push_constants.uniform_buffer_get().get();
|
||||
bind_buffer(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
uniform_buffer.vk_handle(),
|
||||
uniform_buffer.device_address_get(),
|
||||
0,
|
||||
uniform_buffer.size_in_bytes(),
|
||||
push_constants.layout_get().descriptor_set_location_get());
|
||||
access_info.buffers.append({uniform_buffer.vk_handle(), VK_ACCESS_UNIFORM_READ_BIT});
|
||||
}
|
||||
|
||||
void VKDescriptorSetTracker::bind_shader_resources(const VKDevice &device,
|
||||
void VKDescriptorSetUpdator::bind_shader_resources(const VKDevice &device,
|
||||
const VKStateManager &state_manager,
|
||||
VKShader &shader,
|
||||
render_graph::VKResourceAccessInfo &access_info)
|
||||
@@ -345,32 +340,83 @@ void VKDescriptorSetTracker::bind_shader_resources(const VKDevice &device,
|
||||
bind_push_constants(shader.push_constants, access_info);
|
||||
}
|
||||
|
||||
void VKDescriptorSetTracker::update_descriptor_set(VKContext &context,
|
||||
render_graph::VKResourceAccessInfo &access_info)
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name VKDescriptorSetPoolUpdator
|
||||
* \{ */
|
||||
|
||||
void VKDescriptorSetPoolUpdator::allocate_new_descriptor_set(
|
||||
VKDevice & /*device*/,
|
||||
VKContext &context,
|
||||
VKShader &shader,
|
||||
VkDescriptorSetLayout vk_descriptor_set_layout,
|
||||
render_graph::VKPipelineData &r_pipeline_data)
|
||||
{
|
||||
VKShader &shader = *unwrap(context.shader);
|
||||
VKStateManager &state_manager = context.state_manager_get();
|
||||
|
||||
/* Can we reuse previous descriptor set. */
|
||||
if (!state_manager.is_dirty &&
|
||||
!assign_if_different(vk_descriptor_set_layout_, shader.vk_descriptor_set_layout_get()) &&
|
||||
shader.push_constants.layout_get().storage_type_get() !=
|
||||
VKPushConstants::StorageType::UNIFORM_BUFFER)
|
||||
{
|
||||
return;
|
||||
}
|
||||
state_manager.is_dirty = false;
|
||||
|
||||
/* Allocate a new descriptor set. */
|
||||
VkDescriptorSetLayout vk_descriptor_set_layout = shader.vk_descriptor_set_layout_get();
|
||||
/* Use descriptor pools/sets. */
|
||||
vk_descriptor_set = context.descriptor_pools_get().allocate(vk_descriptor_set_layout);
|
||||
BLI_assert(vk_descriptor_set != VK_NULL_HANDLE);
|
||||
debug::object_label(vk_descriptor_set, shader.name_get());
|
||||
const VKDevice &device = VKBackend::get().device;
|
||||
bind_shader_resources(device, state_manager, shader, access_info);
|
||||
r_pipeline_data.vk_descriptor_set = vk_descriptor_set;
|
||||
}
|
||||
|
||||
void VKDescriptorSetTracker::upload_descriptor_sets()
|
||||
void VKDescriptorSetPoolUpdator::bind_buffer(VkDescriptorType vk_descriptor_type,
|
||||
VkBuffer vk_buffer,
|
||||
VkDeviceAddress /*vk_device_address*/,
|
||||
VkDeviceSize buffer_offset,
|
||||
VkDeviceSize size_in_bytes,
|
||||
VKDescriptorSet::Location location)
|
||||
{
|
||||
vk_descriptor_buffer_infos_.append({vk_buffer, buffer_offset, size_in_bytes});
|
||||
vk_write_descriptor_sets_.append({VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
nullptr,
|
||||
vk_descriptor_set,
|
||||
location,
|
||||
0,
|
||||
1,
|
||||
vk_descriptor_type,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr});
|
||||
}
|
||||
|
||||
void VKDescriptorSetPoolUpdator::bind_texel_buffer(VKVertexBuffer &vertex_buffer,
|
||||
const VKDescriptorSet::Location location)
|
||||
{
|
||||
vertex_buffer.ensure_buffer_view();
|
||||
vk_buffer_views_.append(vertex_buffer.vk_buffer_view_get());
|
||||
vk_write_descriptor_sets_.append({VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
nullptr,
|
||||
vk_descriptor_set,
|
||||
location,
|
||||
0,
|
||||
1,
|
||||
VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr});
|
||||
}
|
||||
|
||||
void VKDescriptorSetPoolUpdator::bind_image(VkDescriptorType vk_descriptor_type,
|
||||
VkSampler vk_sampler,
|
||||
VkImageView vk_image_view,
|
||||
VkImageLayout vk_image_layout,
|
||||
VKDescriptorSet::Location location)
|
||||
{
|
||||
vk_descriptor_image_infos_.append({vk_sampler, vk_image_view, vk_image_layout});
|
||||
vk_write_descriptor_sets_.append({VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
nullptr,
|
||||
vk_descriptor_set,
|
||||
location,
|
||||
0,
|
||||
1,
|
||||
vk_descriptor_type,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr});
|
||||
}
|
||||
|
||||
void VKDescriptorSetPoolUpdator::upload_descriptor_sets()
|
||||
{
|
||||
if (vk_write_descriptor_sets_.is_empty()) {
|
||||
return;
|
||||
@@ -464,4 +510,164 @@ void VKDescriptorSetTracker::upload_descriptor_sets()
|
||||
vk_write_descriptor_sets_.clear();
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name VKDescriptorBufferUpdator
|
||||
* \{ */
|
||||
|
||||
void VKDescriptorBufferUpdator::allocate_new_descriptor_set(
|
||||
VKDevice &device,
|
||||
VKContext & /*context*/,
|
||||
VKShader & /*shader*/,
|
||||
VkDescriptorSetLayout vk_descriptor_set_layout,
|
||||
render_graph::VKPipelineData &r_pipeline_data)
|
||||
{
|
||||
/* Use descriptor buffer. */
|
||||
descriptor_set_head = descriptor_set_tail;
|
||||
layout = device.descriptor_set_layouts_get().descriptor_buffer_layout_get(
|
||||
vk_descriptor_set_layout);
|
||||
|
||||
/* Ensure if there is still place left in the current buffer. */
|
||||
if (buffers.is_empty() || layout.size > buffers.last().size_in_bytes() - descriptor_set_head) {
|
||||
const VkDeviceSize default_buffer_size = 8 * 1024 * 1024;
|
||||
buffers.append({});
|
||||
VKBuffer &buffer = buffers.last();
|
||||
buffer.create(default_buffer_size,
|
||||
VK_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT |
|
||||
VK_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT,
|
||||
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
0,
|
||||
VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT);
|
||||
debug::object_label(buffer.vk_handle(), "DescriptorBuffer");
|
||||
descriptor_buffer_data = static_cast<uint8_t *>(buffer.mapped_memory_get());
|
||||
descriptor_buffer_device_address = buffer.device_address_get();
|
||||
descriptor_buffer_offset = 0;
|
||||
descriptor_set_head = 0;
|
||||
descriptor_set_tail = 0;
|
||||
}
|
||||
|
||||
descriptor_set_tail = descriptor_set_head + layout.size;
|
||||
|
||||
/* Update the current descriptor buffer and its offset to point to the active descriptor set. */
|
||||
descriptor_buffer_offset = descriptor_set_head;
|
||||
|
||||
r_pipeline_data.descriptor_buffer_device_address = descriptor_buffer_device_address;
|
||||
r_pipeline_data.descriptor_buffer_offset = descriptor_buffer_offset;
|
||||
}
|
||||
|
||||
void VKDescriptorBufferUpdator::bind_buffer(VkDescriptorType vk_descriptor_type,
|
||||
VkBuffer /*vk_buffer*/,
|
||||
VkDeviceAddress vk_device_address,
|
||||
VkDeviceSize buffer_offset,
|
||||
VkDeviceSize size_in_bytes,
|
||||
VKDescriptorSet::Location location)
|
||||
{
|
||||
BLI_assert(vk_device_address != 0);
|
||||
VKDevice &device = VKBackend::get().device;
|
||||
const VkPhysicalDeviceDescriptorBufferPropertiesEXT &vk_descriptor_buffer_properties =
|
||||
device.physical_device_descriptor_buffer_properties_get();
|
||||
VkDescriptorAddressInfoEXT descriptor_address_info = {
|
||||
VK_STRUCTURE_TYPE_DESCRIPTOR_ADDRESS_INFO_EXT,
|
||||
nullptr,
|
||||
vk_device_address + buffer_offset,
|
||||
size_in_bytes};
|
||||
|
||||
VkDescriptorGetInfoEXT vk_descriptor_get_info{
|
||||
VK_STRUCTURE_TYPE_DESCRIPTOR_GET_INFO_EXT, nullptr, vk_descriptor_type};
|
||||
VkDeviceSize descriptor_size = 0;
|
||||
switch (vk_descriptor_type) {
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
||||
vk_descriptor_get_info.data.pUniformBuffer = &descriptor_address_info;
|
||||
descriptor_size = vk_descriptor_buffer_properties.uniformBufferDescriptorSize;
|
||||
break;
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
||||
vk_descriptor_get_info.data.pStorageBuffer = &descriptor_address_info;
|
||||
descriptor_size = vk_descriptor_buffer_properties.storageBufferDescriptorSize;
|
||||
break;
|
||||
|
||||
default:
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
|
||||
uint8_t *descriptor_ptr = get_descriptor_binding_ptr(location);
|
||||
device.functions.vkGetDescriptor(
|
||||
device.vk_handle(), &vk_descriptor_get_info, descriptor_size, descriptor_ptr);
|
||||
}
|
||||
|
||||
void VKDescriptorBufferUpdator::bind_texel_buffer(VKVertexBuffer &vertex_buffer,
|
||||
const VKDescriptorSet::Location location)
|
||||
{
|
||||
VkDeviceAddress vk_device_address = vertex_buffer.device_address_get();
|
||||
BLI_assert(vk_device_address != 0);
|
||||
VKDevice &device = VKBackend::get().device;
|
||||
const VkPhysicalDeviceDescriptorBufferPropertiesEXT &vk_descriptor_buffer_properties =
|
||||
device.physical_device_descriptor_buffer_properties_get();
|
||||
VkDescriptorAddressInfoEXT descriptor_address_info = {
|
||||
VK_STRUCTURE_TYPE_DESCRIPTOR_ADDRESS_INFO_EXT,
|
||||
nullptr,
|
||||
vk_device_address,
|
||||
vertex_buffer.size_used_get(),
|
||||
vertex_buffer.to_vk_format()};
|
||||
|
||||
VkDescriptorGetInfoEXT vk_descriptor_get_info{
|
||||
VK_STRUCTURE_TYPE_DESCRIPTOR_GET_INFO_EXT, nullptr, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER};
|
||||
vk_descriptor_get_info.data.pUniformTexelBuffer = &descriptor_address_info;
|
||||
VkDeviceSize descriptor_size = vk_descriptor_buffer_properties.uniformTexelBufferDescriptorSize;
|
||||
|
||||
uint8_t *descriptor_ptr = get_descriptor_binding_ptr(location);
|
||||
device.functions.vkGetDescriptor(
|
||||
device.vk_handle(), &vk_descriptor_get_info, descriptor_size, descriptor_ptr);
|
||||
}
|
||||
|
||||
void VKDescriptorBufferUpdator::bind_image(VkDescriptorType vk_descriptor_type,
|
||||
VkSampler vk_sampler,
|
||||
VkImageView vk_image_view,
|
||||
VkImageLayout vk_image_layout,
|
||||
VKDescriptorSet::Location location)
|
||||
{
|
||||
VKDevice &device = VKBackend::get().device;
|
||||
const VkPhysicalDeviceDescriptorBufferPropertiesEXT &vk_descriptor_buffer_properties =
|
||||
device.physical_device_descriptor_buffer_properties_get();
|
||||
VkDescriptorImageInfo vk_descriptor_image_info = {vk_sampler, vk_image_view, vk_image_layout};
|
||||
VkDescriptorGetInfoEXT vk_descriptor_get_info{
|
||||
VK_STRUCTURE_TYPE_DESCRIPTOR_GET_INFO_EXT, nullptr, vk_descriptor_type};
|
||||
VkDeviceSize descriptor_size = 0;
|
||||
switch (vk_descriptor_type) {
|
||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||
vk_descriptor_get_info.data.pCombinedImageSampler = &vk_descriptor_image_info;
|
||||
descriptor_size = vk_descriptor_buffer_properties.combinedImageSamplerDescriptorSize;
|
||||
break;
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
||||
vk_descriptor_get_info.data.pStorageImage = &vk_descriptor_image_info;
|
||||
descriptor_size = vk_descriptor_buffer_properties.storageImageDescriptorSize;
|
||||
break;
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
|
||||
vk_descriptor_get_info.data.pInputAttachmentImage = &vk_descriptor_image_info;
|
||||
descriptor_size = vk_descriptor_buffer_properties.inputAttachmentDescriptorSize;
|
||||
break;
|
||||
|
||||
default:
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
|
||||
uint8_t *descriptor_ptr = get_descriptor_binding_ptr(location);
|
||||
device.functions.vkGetDescriptor(
|
||||
device.vk_handle(), &vk_descriptor_get_info, descriptor_size, descriptor_ptr);
|
||||
}
|
||||
|
||||
void VKDescriptorBufferUpdator::upload_descriptor_sets()
|
||||
{
|
||||
/* Buffers have already been updated. only need to discard the buffers. */
|
||||
buffers.clear();
|
||||
descriptor_buffer_data = nullptr;
|
||||
descriptor_buffer_device_address = 0;
|
||||
descriptor_buffer_offset = 0;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender::gpu
|
||||
|
||||
@@ -13,9 +13,11 @@
|
||||
|
||||
#include "gpu_shader_private.hh"
|
||||
|
||||
#include "render_graph/nodes/vk_pipeline_data.hh"
|
||||
#include "render_graph/vk_resource_access_info.hh"
|
||||
#include "vk_buffer.hh"
|
||||
#include "vk_common.hh"
|
||||
#include "vk_descriptor_set_layouts.hh"
|
||||
#include "vk_resource_tracker.hh"
|
||||
#include "vk_uniform_buffer.hh"
|
||||
|
||||
@@ -25,6 +27,8 @@ class VKStateManager;
|
||||
class VKDevice;
|
||||
class VKPushConstants;
|
||||
class VKShader;
|
||||
class VKDescriptorSetTracker;
|
||||
class VKVertexBuffer;
|
||||
|
||||
/**
|
||||
* In vulkan shader resources (images and buffers) are grouped in descriptor sets.
|
||||
@@ -76,42 +80,22 @@ class VKDescriptorSet : NonCopyable {
|
||||
};
|
||||
};
|
||||
|
||||
class VKDescriptorSetTracker {
|
||||
friend class VKDescriptorSet;
|
||||
|
||||
Vector<VkBufferView> vk_buffer_views_;
|
||||
Vector<VkDescriptorBufferInfo> vk_descriptor_buffer_infos_;
|
||||
Vector<VkDescriptorImageInfo> vk_descriptor_image_infos_;
|
||||
Vector<VkWriteDescriptorSet> vk_write_descriptor_sets_;
|
||||
|
||||
/* Last used layout to identify changes. */
|
||||
VkDescriptorSetLayout vk_descriptor_set_layout_ = VK_NULL_HANDLE;
|
||||
|
||||
class VKDescriptorSetUpdator {
|
||||
public:
|
||||
VkDescriptorSet vk_descriptor_set = VK_NULL_HANDLE;
|
||||
virtual ~VKDescriptorSetUpdator(){};
|
||||
|
||||
VKDescriptorSetTracker() {}
|
||||
|
||||
/**
|
||||
* Update the descriptor set. Reuses previous descriptor set when no changes are detected. This
|
||||
* improves performance when working with large grease pencil scenes.
|
||||
*/
|
||||
void update_descriptor_set(VKContext &context,
|
||||
render_graph::VKResourceAccessInfo &resource_access_info);
|
||||
|
||||
/**
|
||||
* Upload all descriptor sets to the device.
|
||||
*
|
||||
* NOTE: Caller should discard the associated descriptor pools. (VKDescriptorPools::discard)
|
||||
*/
|
||||
void upload_descriptor_sets();
|
||||
|
||||
private:
|
||||
virtual void allocate_new_descriptor_set(VKDevice &device,
|
||||
VKContext &context,
|
||||
VKShader &shader,
|
||||
VkDescriptorSetLayout vk_descriptor_set_layout,
|
||||
render_graph::VKPipelineData &r_pipeline_data) = 0;
|
||||
void bind_shader_resources(const VKDevice &device,
|
||||
const VKStateManager &state_manager,
|
||||
VKShader &shader,
|
||||
render_graph::VKResourceAccessInfo &access_info);
|
||||
virtual void upload_descriptor_sets() = 0;
|
||||
|
||||
private:
|
||||
void bind_image_resource(const VKStateManager &state_manager,
|
||||
const VKResourceBinding &resource_binding,
|
||||
render_graph::VKResourceAccessInfo &access_info);
|
||||
@@ -129,21 +113,134 @@ class VKDescriptorSetTracker {
|
||||
const VKStateManager &state_manager,
|
||||
const VKResourceBinding &resource_binding,
|
||||
render_graph::VKResourceAccessInfo &access_info);
|
||||
void bind_push_constants(VKPushConstants &push_constants,
|
||||
|
||||
void bind_push_constants(VKPushConstants &push_constants,
|
||||
render_graph::VKResourceAccessInfo &access_info);
|
||||
|
||||
void bind_texel_buffer(VkBufferView vk_buffer_view, VKDescriptorSet::Location location);
|
||||
protected:
|
||||
virtual void bind_texel_buffer(VKVertexBuffer &vertex_buffer,
|
||||
VKDescriptorSet::Location location) = 0;
|
||||
virtual void bind_buffer(VkDescriptorType vk_descriptor_type,
|
||||
VkBuffer vk_buffer,
|
||||
VkDeviceAddress vk_device_address,
|
||||
VkDeviceSize buffer_offset,
|
||||
VkDeviceSize size_in_bytes,
|
||||
VKDescriptorSet::Location location) = 0;
|
||||
virtual void bind_image(VkDescriptorType vk_descriptor_type,
|
||||
VkSampler vk_sampler,
|
||||
VkImageView vk_image_view,
|
||||
VkImageLayout vk_image_layout,
|
||||
VKDescriptorSet::Location location) = 0;
|
||||
};
|
||||
|
||||
class VKDescriptorSetPoolUpdator : public VKDescriptorSetUpdator {
|
||||
public:
|
||||
VkDescriptorSet vk_descriptor_set = VK_NULL_HANDLE;
|
||||
|
||||
void allocate_new_descriptor_set(VKDevice &device,
|
||||
VKContext &context,
|
||||
VKShader &shader,
|
||||
VkDescriptorSetLayout vk_descriptor_set_layout,
|
||||
render_graph::VKPipelineData &r_pipeline_data) override;
|
||||
|
||||
void upload_descriptor_sets() override;
|
||||
|
||||
protected:
|
||||
void bind_texel_buffer(VKVertexBuffer &vertex_buffer,
|
||||
VKDescriptorSet::Location location) override;
|
||||
void bind_buffer(VkDescriptorType vk_descriptor_type,
|
||||
VkBuffer vk_buffer,
|
||||
VkDeviceAddress vk_device_address,
|
||||
VkDeviceSize buffer_offset,
|
||||
VkDeviceSize size_in_bytes,
|
||||
VKDescriptorSet::Location location);
|
||||
VKDescriptorSet::Location location) override;
|
||||
void bind_image(VkDescriptorType vk_descriptor_type,
|
||||
VkSampler vk_sampler,
|
||||
VkImageView vk_image_view,
|
||||
VkImageLayout vk_image_layout,
|
||||
VKDescriptorSet::Location location);
|
||||
VKDescriptorSet::Location location) override;
|
||||
|
||||
private:
|
||||
Vector<VkBufferView> vk_buffer_views_;
|
||||
Vector<VkDescriptorBufferInfo> vk_descriptor_buffer_infos_;
|
||||
Vector<VkDescriptorImageInfo> vk_descriptor_image_infos_;
|
||||
Vector<VkWriteDescriptorSet> vk_write_descriptor_sets_;
|
||||
};
|
||||
|
||||
class VKDescriptorBufferUpdator : public VKDescriptorSetUpdator {
|
||||
public:
|
||||
/* Offset to the beginning of the current descriptor set. */
|
||||
VkDeviceSize descriptor_set_head = 0;
|
||||
/* Offset to the end (+1) of the current descriptor set. */
|
||||
VkDeviceSize descriptor_set_tail = 0;
|
||||
/* Current layout of the descriptor set being filled. */
|
||||
VKDescriptorBufferLayout layout;
|
||||
/* Descriptor buffers */
|
||||
Vector<VKBuffer> buffers;
|
||||
|
||||
/* Current descriptor buffer handle and offset. */
|
||||
VkDeviceAddress descriptor_buffer_device_address = 0;
|
||||
uint8_t *descriptor_buffer_data = nullptr;
|
||||
VkDeviceSize descriptor_buffer_offset = 0;
|
||||
|
||||
void allocate_new_descriptor_set(VKDevice &device,
|
||||
VKContext &context,
|
||||
VKShader &shader,
|
||||
VkDescriptorSetLayout vk_descriptor_set_layout,
|
||||
render_graph::VKPipelineData &r_pipeline_data) override;
|
||||
|
||||
void upload_descriptor_sets() override;
|
||||
|
||||
protected:
|
||||
void bind_texel_buffer(VKVertexBuffer &vertex_buffer,
|
||||
VKDescriptorSet::Location location) override;
|
||||
void bind_buffer(VkDescriptorType vk_descriptor_type,
|
||||
VkBuffer vk_buffer,
|
||||
VkDeviceAddress vk_device_address,
|
||||
VkDeviceSize buffer_offset,
|
||||
VkDeviceSize size_in_bytes,
|
||||
VKDescriptorSet::Location location) override;
|
||||
void bind_image(VkDescriptorType vk_descriptor_type,
|
||||
VkSampler vk_sampler,
|
||||
VkImageView vk_image_view,
|
||||
VkImageLayout vk_image_layout,
|
||||
VKDescriptorSet::Location location) override;
|
||||
|
||||
private:
|
||||
inline uint8_t *get_descriptor_binding_ptr(uint32_t binding) const
|
||||
{
|
||||
return descriptor_buffer_data + descriptor_buffer_offset + layout.binding_offsets[binding];
|
||||
}
|
||||
};
|
||||
|
||||
class VKDescriptorSetTracker {
|
||||
friend class VKDescriptorSet;
|
||||
|
||||
/* Last used layout to identify changes. */
|
||||
VkDescriptorSetLayout vk_descriptor_set_layout_ = VK_NULL_HANDLE;
|
||||
|
||||
public:
|
||||
class VKDescriptorBufferUpdator descriptor_buffers;
|
||||
class VKDescriptorSetPoolUpdator descriptor_sets;
|
||||
|
||||
VKDescriptorSetTracker() {}
|
||||
|
||||
/**
|
||||
* Update the descriptor set. Reuses previous descriptor set when no changes are detected. This
|
||||
* improves performance when working with large grease pencil scenes.
|
||||
*/
|
||||
void update_descriptor_set(VKContext &context,
|
||||
render_graph::VKResourceAccessInfo &resource_access_info,
|
||||
render_graph::VKPipelineData &r_pipeline_data);
|
||||
|
||||
/**
|
||||
* Upload all descriptor sets to the device.
|
||||
*
|
||||
* NOTE: Caller should discard the associated descriptor pools. (VKDescriptorPools::discard)
|
||||
*/
|
||||
void upload_descriptor_sets();
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
} // namespace blender::gpu
|
||||
|
||||
@@ -40,11 +40,16 @@ VkDescriptorSetLayout VKDescriptorSetLayouts::get_or_create(const VKDescriptorSe
|
||||
}
|
||||
|
||||
update_layout_bindings(info);
|
||||
const VKDevice &device = VKBackend::get().device;
|
||||
const bool use_descriptor_buffer = device.extensions_get().descriptor_buffer;
|
||||
|
||||
vk_descriptor_set_layout_create_info_.bindingCount = vk_descriptor_set_layout_bindings_.size();
|
||||
vk_descriptor_set_layout_create_info_.pBindings = vk_descriptor_set_layout_bindings_.data();
|
||||
if (use_descriptor_buffer) {
|
||||
vk_descriptor_set_layout_create_info_.flags =
|
||||
VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT;
|
||||
}
|
||||
|
||||
const VKDevice &device = VKBackend::get().device;
|
||||
VkDescriptorSetLayout vk_descriptor_set_layout = VK_NULL_HANDLE;
|
||||
vkCreateDescriptorSetLayout(device.vk_handle(),
|
||||
&vk_descriptor_set_layout_create_info_,
|
||||
@@ -58,6 +63,12 @@ VkDescriptorSetLayout VKDescriptorSetLayouts::get_or_create(const VKDescriptorSe
|
||||
vk_descriptor_set_layouts_.add(info, vk_descriptor_set_layout);
|
||||
r_created = true;
|
||||
|
||||
if (use_descriptor_buffer) {
|
||||
descriptor_buffer_layouts_.add(
|
||||
vk_descriptor_set_layout,
|
||||
create_descriptor_buffer_layout(device, info, vk_descriptor_set_layout));
|
||||
}
|
||||
|
||||
return vk_descriptor_set_layout;
|
||||
}
|
||||
|
||||
@@ -90,4 +101,32 @@ void VKDescriptorSetLayouts::deinit()
|
||||
vk_descriptor_set_layouts_.clear();
|
||||
}
|
||||
|
||||
static void align_size(VkDeviceSize &r_size, VkDeviceSize alignment)
|
||||
{
|
||||
if (alignment > 1) {
|
||||
r_size = (r_size + alignment - 1) & ~(alignment - 1);
|
||||
}
|
||||
}
|
||||
VKDescriptorBufferLayout VKDescriptorSetLayouts::create_descriptor_buffer_layout(
|
||||
const VKDevice &device,
|
||||
const VKDescriptorSetLayoutInfo &info,
|
||||
VkDescriptorSetLayout vk_descriptor_set_layout) const
|
||||
{
|
||||
const VkPhysicalDeviceDescriptorBufferPropertiesEXT &properties =
|
||||
device.physical_device_descriptor_buffer_properties_get();
|
||||
VKDescriptorBufferLayout result = {};
|
||||
|
||||
device.functions.vkGetDescriptorSetLayoutSize(
|
||||
device.vk_handle(), vk_descriptor_set_layout, &result.size);
|
||||
align_size(result.size, properties.descriptorBufferOffsetAlignment);
|
||||
|
||||
result.binding_offsets.resize(info.bindings.size());
|
||||
for (uint32_t binding : IndexRange(info.bindings.size())) {
|
||||
device.functions.vkGetDescriptorSetLayoutBindingOffset(
|
||||
device.vk_handle(), vk_descriptor_set_layout, binding, &result.binding_offsets[binding]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace blender::gpu
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
#include "vk_common.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
class VKDevice;
|
||||
|
||||
/**
|
||||
* Key of descriptor set layout
|
||||
*
|
||||
@@ -63,6 +66,25 @@ template<> struct DefaultHash<gpu::VKDescriptorSetLayoutInfo> {
|
||||
} // namespace blender
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
struct VKDescriptorBufferLayout {
|
||||
/**
|
||||
* Total size of the descriptor buffer.
|
||||
*
|
||||
* Size is aligned to
|
||||
* VkPhysicalDeviceDescriptorBufferProperties.descriptorBufferOffsetAlignment.
|
||||
*/
|
||||
VkDeviceSize size;
|
||||
|
||||
/**
|
||||
* Offsets of each binding inside the buffer.
|
||||
*
|
||||
* Offsets are aligned to
|
||||
* VkPhysicalDeviceDescriptorBufferProperties.descriptorBufferOffsetAlignment.
|
||||
*/
|
||||
Vector<VkDeviceSize> binding_offsets;
|
||||
};
|
||||
|
||||
/**
|
||||
* Registries of descriptor set layouts.
|
||||
*/
|
||||
@@ -74,6 +96,7 @@ class VKDescriptorSetLayouts : NonCopyable {
|
||||
* Map containing all created descriptor set layouts.
|
||||
*/
|
||||
Map<VKDescriptorSetLayoutInfo, VkDescriptorSetLayout> vk_descriptor_set_layouts_;
|
||||
Map<VkDescriptorSetLayout, VKDescriptorBufferLayout> descriptor_buffer_layouts_;
|
||||
|
||||
/**
|
||||
* Reusable descriptor set layout create info.
|
||||
@@ -96,6 +119,23 @@ class VKDescriptorSetLayouts : NonCopyable {
|
||||
bool &r_created,
|
||||
bool &r_needed);
|
||||
|
||||
/**
|
||||
* Return the descriptor buffer layout offsets and alignment for the given
|
||||
* vk_descriptor_set_layout handle.
|
||||
*
|
||||
* A copy of the buffer layout is returned due to other threads can alter the location of the
|
||||
* items.
|
||||
*
|
||||
* This function has undefined behavior when descriptor buffers extension isn't enabled on the
|
||||
* VKDevice.
|
||||
*/
|
||||
VKDescriptorBufferLayout descriptor_buffer_layout_get(
|
||||
VkDescriptorSetLayout vk_descriptor_set_layout)
|
||||
{
|
||||
std::scoped_lock lock(mutex_);
|
||||
return descriptor_buffer_layouts_.lookup(vk_descriptor_set_layout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free all descriptor set layouts.
|
||||
*
|
||||
@@ -113,6 +153,10 @@ class VKDescriptorSetLayouts : NonCopyable {
|
||||
|
||||
private:
|
||||
void update_layout_bindings(const VKDescriptorSetLayoutInfo &info);
|
||||
VKDescriptorBufferLayout create_descriptor_buffer_layout(
|
||||
const VKDevice &device,
|
||||
const VKDescriptorSetLayoutInfo &info,
|
||||
VkDescriptorSetLayout vk_descriptor_set_layout) const;
|
||||
};
|
||||
|
||||
} // namespace blender::gpu
|
||||
|
||||
@@ -39,6 +39,7 @@ void VKExtensions::log() const
|
||||
" - [%c] shader output layer\n"
|
||||
" - [%c] fragment shader barycentric\n"
|
||||
"Device extensions\n"
|
||||
" - [%c] descriptor buffer\n"
|
||||
" - [%c] dynamic rendering\n"
|
||||
" - [%c] dynamic rendering local read\n"
|
||||
" - [%c] dynamic rendering unused attachments\n"
|
||||
@@ -47,6 +48,7 @@ void VKExtensions::log() const
|
||||
shader_output_viewport_index ? 'X' : ' ',
|
||||
shader_output_layer ? 'X' : ' ',
|
||||
fragment_shader_barycentric ? 'X' : ' ',
|
||||
descriptor_buffer ? 'X' : ' ',
|
||||
dynamic_rendering ? 'X' : ' ',
|
||||
dynamic_rendering_local_read ? 'X' : ' ',
|
||||
dynamic_rendering_unused_attachments ? 'X' : ' ',
|
||||
@@ -126,10 +128,10 @@ void VKDevice::init(void *ghost_context)
|
||||
vk_queue_ = handles.queue;
|
||||
queue_mutex_ = static_cast<std::mutex *>(handles.queue_mutex);
|
||||
|
||||
init_physical_device_extensions();
|
||||
init_physical_device_properties();
|
||||
init_physical_device_memory_properties();
|
||||
init_physical_device_features();
|
||||
init_physical_device_extensions();
|
||||
VKBackend::platform_init(*this);
|
||||
VKBackend::capabilities_init(*this);
|
||||
init_functions();
|
||||
@@ -177,6 +179,14 @@ void VKDevice::init_functions()
|
||||
#endif
|
||||
}
|
||||
|
||||
/* VK_EXT_descriptor_buffer */
|
||||
functions.vkGetDescriptorSetLayoutSize = LOAD_FUNCTION(vkGetDescriptorSetLayoutSizeEXT);
|
||||
functions.vkGetDescriptorSetLayoutBindingOffset = LOAD_FUNCTION(
|
||||
vkGetDescriptorSetLayoutBindingOffsetEXT);
|
||||
functions.vkGetDescriptor = LOAD_FUNCTION(vkGetDescriptorEXT);
|
||||
functions.vkCmdBindDescriptorBuffers = LOAD_FUNCTION(vkCmdBindDescriptorBuffersEXT);
|
||||
functions.vkCmdSetDescriptorBufferOffsets = LOAD_FUNCTION(vkCmdSetDescriptorBufferOffsetsEXT);
|
||||
|
||||
#undef LOAD_FUNCTION
|
||||
}
|
||||
|
||||
@@ -197,6 +207,15 @@ void VKDevice::init_physical_device_properties()
|
||||
vk_physical_device_properties.pNext = &vk_physical_device_driver_properties_;
|
||||
vk_physical_device_driver_properties_.pNext = &vk_physical_device_id_properties_;
|
||||
|
||||
if (supports_extension(VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME)) {
|
||||
vk_physical_device_descriptor_buffer_properties_ = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_PROPERTIES_EXT};
|
||||
vk_physical_device_descriptor_buffer_properties_.pNext =
|
||||
vk_physical_device_driver_properties_.pNext;
|
||||
vk_physical_device_driver_properties_.pNext =
|
||||
&vk_physical_device_descriptor_buffer_properties_;
|
||||
}
|
||||
|
||||
vkGetPhysicalDeviceProperties2(vk_physical_device_, &vk_physical_device_properties);
|
||||
vk_physical_device_properties_ = vk_physical_device_properties.properties;
|
||||
}
|
||||
@@ -251,6 +270,9 @@ void VKDevice::init_memory_allocator()
|
||||
info.physicalDevice = vk_physical_device_;
|
||||
info.device = vk_device_;
|
||||
info.instance = vk_instance_;
|
||||
if (extensions_.descriptor_buffer) {
|
||||
info.flags |= VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT;
|
||||
}
|
||||
vmaCreateAllocator(&info, &mem_allocator_);
|
||||
|
||||
if (!extensions_.external_memory) {
|
||||
|
||||
@@ -59,6 +59,11 @@ struct VKExtensions {
|
||||
*/
|
||||
bool external_memory = false;
|
||||
|
||||
/**
|
||||
* Does the device support VK_EXT_descriptor_buffer.
|
||||
*/
|
||||
bool descriptor_buffer = false;
|
||||
|
||||
/**
|
||||
* Does the device support logic ops.
|
||||
*/
|
||||
@@ -208,6 +213,8 @@ class VKDevice : public NonCopyable {
|
||||
VkPhysicalDeviceDriverProperties vk_physical_device_driver_properties_ = {};
|
||||
VkPhysicalDeviceIDProperties vk_physical_device_id_properties_ = {};
|
||||
VkPhysicalDeviceMemoryProperties vk_physical_device_memory_properties_ = {};
|
||||
VkPhysicalDeviceDescriptorBufferPropertiesEXT vk_physical_device_descriptor_buffer_properties_ =
|
||||
{};
|
||||
/** Features support. */
|
||||
VkPhysicalDeviceFeatures vk_physical_device_features_ = {};
|
||||
VkPhysicalDeviceVulkan11Features vk_physical_device_vulkan_11_features_ = {};
|
||||
@@ -258,6 +265,14 @@ class VKDevice : public NonCopyable {
|
||||
/* Extension: VK_KHR_external_memory_win32 */
|
||||
PFN_vkGetMemoryWin32HandleKHR vkGetMemoryWin32Handle = nullptr;
|
||||
#endif
|
||||
|
||||
/* Extension: VK_EXT_descriptor_buffer */
|
||||
PFN_vkGetDescriptorSetLayoutSizeEXT vkGetDescriptorSetLayoutSize = nullptr;
|
||||
PFN_vkGetDescriptorSetLayoutBindingOffsetEXT vkGetDescriptorSetLayoutBindingOffset = nullptr;
|
||||
PFN_vkGetDescriptorEXT vkGetDescriptor = nullptr;
|
||||
PFN_vkCmdBindDescriptorBuffersEXT vkCmdBindDescriptorBuffers = nullptr;
|
||||
PFN_vkCmdSetDescriptorBufferOffsetsEXT vkCmdSetDescriptorBufferOffsets = nullptr;
|
||||
|
||||
} functions;
|
||||
|
||||
struct {
|
||||
@@ -288,6 +303,12 @@ class VKDevice : public NonCopyable {
|
||||
return vk_physical_device_id_properties_;
|
||||
}
|
||||
|
||||
inline const VkPhysicalDeviceDescriptorBufferPropertiesEXT &
|
||||
physical_device_descriptor_buffer_properties_get() const
|
||||
{
|
||||
return vk_physical_device_descriptor_buffer_properties_;
|
||||
}
|
||||
|
||||
const VkPhysicalDeviceFeatures &physical_device_features_get() const
|
||||
{
|
||||
return vk_physical_device_features_;
|
||||
@@ -365,7 +386,7 @@ class VKDevice : public NonCopyable {
|
||||
{
|
||||
return workarounds_;
|
||||
}
|
||||
const VKExtensions &extensions_get() const
|
||||
inline const VKExtensions &extensions_get() const
|
||||
{
|
||||
return extensions_;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,10 @@ class VKIndexBuffer : public IndexBuf {
|
||||
{
|
||||
return buffer_get().vk_handle();
|
||||
}
|
||||
inline VkDeviceAddress device_address_get() const
|
||||
{
|
||||
return buffer_get().device_address_get();
|
||||
}
|
||||
VkIndexType vk_index_type() const
|
||||
{
|
||||
return to_vk_index_type(index_type_);
|
||||
|
||||
@@ -202,6 +202,9 @@ VkPipeline VKPipelinePool::get_or_create_compute_pipeline(VKComputeInfo &compute
|
||||
/* Build pipeline. */
|
||||
VKBackend &backend = VKBackend::get();
|
||||
VKDevice &device = backend.device;
|
||||
if (device.extensions_get().descriptor_buffer) {
|
||||
vk_compute_pipeline_create_info_.flags |= VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT;
|
||||
}
|
||||
|
||||
VkPipeline pipeline = VK_NULL_HANDLE;
|
||||
vkCreateComputePipelines(device.vk_handle(),
|
||||
@@ -214,6 +217,7 @@ VkPipeline VKPipelinePool::get_or_create_compute_pipeline(VKComputeInfo &compute
|
||||
compute_pipelines_.add(compute_info, pipeline);
|
||||
|
||||
/* Reset values to initial value. */
|
||||
vk_compute_pipeline_create_info_.flags = 0;
|
||||
vk_compute_pipeline_create_info_.layout = VK_NULL_HANDLE;
|
||||
vk_compute_pipeline_create_info_.stage.module = VK_NULL_HANDLE;
|
||||
vk_compute_pipeline_create_info_.stage.pSpecializationInfo = nullptr;
|
||||
@@ -586,6 +590,9 @@ VkPipeline VKPipelinePool::get_or_create_graphics_pipeline(VKGraphicsInfo &graph
|
||||
/* Build pipeline. */
|
||||
VKBackend &backend = VKBackend::get();
|
||||
VKDevice &device = backend.device;
|
||||
if (device.extensions_get().descriptor_buffer) {
|
||||
vk_graphics_pipeline_create_info_.flags = VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT;
|
||||
}
|
||||
|
||||
VkPipeline pipeline = VK_NULL_HANDLE;
|
||||
vkCreateGraphicsPipelines(device.vk_handle(),
|
||||
@@ -599,6 +606,7 @@ VkPipeline VKPipelinePool::get_or_create_graphics_pipeline(VKGraphicsInfo &graph
|
||||
|
||||
/* Reset values to initial value. */
|
||||
specialization_info_reset();
|
||||
vk_graphics_pipeline_create_info_.flags = 0;
|
||||
vk_graphics_pipeline_create_info_.stageCount = 0;
|
||||
vk_graphics_pipeline_create_info_.layout = VK_NULL_HANDLE;
|
||||
vk_graphics_pipeline_create_info_.basePipelineHandle = VK_NULL_HANDLE;
|
||||
|
||||
@@ -204,7 +204,7 @@ class BindSpaceTextures {
|
||||
};
|
||||
|
||||
class VKStateManager : public StateManager {
|
||||
friend class VKDescriptorSetTracker;
|
||||
friend class VKDescriptorSetUpdator;
|
||||
|
||||
uint texture_unpack_row_length_ = 0;
|
||||
|
||||
|
||||
@@ -43,6 +43,10 @@ class VKStorageBuffer : public StorageBuf {
|
||||
{
|
||||
return buffer_.vk_handle();
|
||||
}
|
||||
inline VkDeviceAddress device_address_get() const
|
||||
{
|
||||
return buffer_.device_address_get();
|
||||
}
|
||||
|
||||
int64_t size_in_bytes() const
|
||||
{
|
||||
|
||||
@@ -29,7 +29,7 @@ enum class VKImageViewFlags {
|
||||
ENUM_OPERATORS(VKImageViewFlags, VKImageViewFlags::NO_SWIZZLING)
|
||||
|
||||
class VKTexture : public Texture {
|
||||
friend class VKDescriptorSetTracker;
|
||||
friend class VKDescriptorSetUpdator;
|
||||
|
||||
/**
|
||||
* Texture format how the texture is stored on the device.
|
||||
|
||||
@@ -42,6 +42,10 @@ class VKUniformBuffer : public UniformBuf, NonCopyable {
|
||||
{
|
||||
return buffer_.vk_handle();
|
||||
}
|
||||
inline VkDeviceAddress device_address_get() const
|
||||
{
|
||||
return buffer_.device_address_get();
|
||||
}
|
||||
|
||||
size_t size_in_bytes() const
|
||||
{
|
||||
|
||||
@@ -48,11 +48,9 @@ void VKVertexBuffer::ensure_buffer_view()
|
||||
}
|
||||
|
||||
VkBufferViewCreateInfo buffer_view_info = {};
|
||||
eGPUTextureFormat texture_format = to_texture_format(&format);
|
||||
|
||||
buffer_view_info.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
|
||||
buffer_view_info.buffer = buffer_.vk_handle();
|
||||
buffer_view_info.format = to_vk_format(texture_format);
|
||||
buffer_view_info.format = to_vk_format();
|
||||
buffer_view_info.range = buffer_.size_in_bytes();
|
||||
|
||||
const VKDevice &device = VKBackend::get().device;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "GPU_vertex_buffer.hh"
|
||||
|
||||
#include "vk_buffer.hh"
|
||||
#include "vk_common.hh"
|
||||
#include "vk_data_conversion.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
@@ -38,6 +39,11 @@ class VKVertexBuffer : public VertBuf {
|
||||
return buffer_.vk_handle();
|
||||
}
|
||||
|
||||
inline VkDeviceAddress device_address_get() const
|
||||
{
|
||||
return buffer_.device_address_get();
|
||||
}
|
||||
|
||||
VkBufferView vk_buffer_view_get() const
|
||||
{
|
||||
BLI_assert(vk_buffer_view_ != VK_NULL_HANDLE);
|
||||
@@ -47,6 +53,11 @@ class VKVertexBuffer : public VertBuf {
|
||||
void ensure_updated();
|
||||
void ensure_buffer_view();
|
||||
|
||||
inline VkFormat to_vk_format()
|
||||
{
|
||||
return blender::gpu::to_vk_format(to_texture_format(&format));
|
||||
}
|
||||
|
||||
protected:
|
||||
void acquire_data() override;
|
||||
void resize_data() override;
|
||||
|
||||
Reference in New Issue
Block a user