From 9a6b09b56b14504216aac9013c94b91297b024ad Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 12 Sep 2023 15:55:16 +0200 Subject: [PATCH 01/15] Many small things to get a no crashes --- intern/ghost/intern/GHOST_ContextVK.cc | 1 + source/blender/gpu/vulkan/vk_backend.hh | 5 ++++ source/blender/gpu/vulkan/vk_buffer.cc | 5 ++-- source/blender/gpu/vulkan/vk_context.cc | 6 +++- .../blender/gpu/vulkan/vk_descriptor_set.cc | 1 + source/blender/gpu/vulkan/vk_device.cc | 25 ++++++++++++++++- source/blender/gpu/vulkan/vk_device.hh | 7 +++++ source/blender/gpu/vulkan/vk_texture.cc | 28 +++++++++++++++++-- 8 files changed, 70 insertions(+), 8 deletions(-) diff --git a/intern/ghost/intern/GHOST_ContextVK.cc b/intern/ghost/intern/GHOST_ContextVK.cc index e677d63a36b..fde6afbc603 100644 --- a/intern/ghost/intern/GHOST_ContextVK.cc +++ b/intern/ghost/intern/GHOST_ContextVK.cc @@ -229,6 +229,7 @@ class GHOST_DeviceVK { device_features.multiViewport = VK_TRUE; #endif device_features.drawIndirectFirstInstance = VK_TRUE; + device_features.fragmentStoresAndAtomics = VK_TRUE; VkPhysicalDeviceMaintenance4FeaturesKHR maintenance_4 = {}; maintenance_4.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR; diff --git a/source/blender/gpu/vulkan/vk_backend.hh b/source/blender/gpu/vulkan/vk_backend.hh index c06e6ca483a..e5e35c03583 100644 --- a/source/blender/gpu/vulkan/vk_backend.hh +++ b/source/blender/gpu/vulkan/vk_backend.hh @@ -87,6 +87,11 @@ class VKBackend : public GPUBackend { return device_; } + VKDevice &device_get() + { + return device_; + } + static void platform_init(const VKDevice &device); static void capabilities_init(VKDevice &device); diff --git a/source/blender/gpu/vulkan/vk_buffer.cc b/source/blender/gpu/vulkan/vk_buffer.cc index d934d1e4384..c0f6048f40b 100644 --- a/source/blender/gpu/vulkan/vk_buffer.cc +++ b/source/blender/gpu/vulkan/vk_buffer.cc @@ -143,9 +143,8 @@ bool VKBuffer::free() unmap(); } - const VKDevice &device = VKBackend::get().device_get(); - VmaAllocator allocator = device.mem_allocator_get(); - vmaDestroyBuffer(allocator, vk_buffer_, allocation_); + VKDevice &device = VKBackend::get().device_get(); + device.discard_buffer(vk_buffer_, allocation_); allocation_ = VK_NULL_HANDLE; vk_buffer_ = VK_NULL_HANDLE; return true; diff --git a/source/blender/gpu/vulkan/vk_context.cc b/source/blender/gpu/vulkan/vk_context.cc index 0606813dff5..2510fd19932 100644 --- a/source/blender/gpu/vulkan/vk_context.cc +++ b/source/blender/gpu/vulkan/vk_context.cc @@ -112,7 +112,11 @@ void VKContext::deactivate() void VKContext::begin_frame() {} -void VKContext::end_frame() {} +void VKContext::end_frame() +{ + VKDevice &device = VKBackend::get().device_get(); + device.destroy_discarded_resources(); +} void VKContext::flush() { diff --git a/source/blender/gpu/vulkan/vk_descriptor_set.cc b/source/blender/gpu/vulkan/vk_descriptor_set.cc index df4ee31c285..499fb598fc0 100644 --- a/source/blender/gpu/vulkan/vk_descriptor_set.cc +++ b/source/blender/gpu/vulkan/vk_descriptor_set.cc @@ -181,6 +181,7 @@ void VKDescriptorSetTracker::update(VKContext &context) } /* TODO: Based on the actual usage we should use * VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL/VK_IMAGE_LAYOUT_GENERAL. */ + binding.texture->ensure_allocated(); binding.texture->layout_ensure(context, VK_IMAGE_LAYOUT_GENERAL); VkDescriptorImageInfo image_info = {}; image_info.sampler = binding.vk_sampler; diff --git a/source/blender/gpu/vulkan/vk_device.cc b/source/blender/gpu/vulkan/vk_device.cc index 12e2346df84..6a666cb9091 100644 --- a/source/blender/gpu/vulkan/vk_device.cc +++ b/source/blender/gpu/vulkan/vk_device.cc @@ -25,9 +25,9 @@ void VKDevice::deinit() { VK_ALLOCATION_CALLBACKS; vkDestroyCommandPool(vk_device_, vk_command_pool_, vk_allocation_callbacks); - dummy_buffer_.free(); sampler_.free(); + destroy_discarded_resources(); vmaDestroyAllocator(mem_allocator_); mem_allocator_ = VK_NULL_HANDLE; debugging_tools_.deinit(vk_instance_); @@ -248,6 +248,29 @@ const Vector> &VKDevice::contexts_get() const return contexts_; }; +void VKDevice::discard_image(VkImage vk_image, VmaAllocation vma_allocation) +{ + discarded_images_.append(std::pair(vk_image, vma_allocation)); +} + +void VKDevice::discard_buffer(VkBuffer vk_buffer, VmaAllocation vma_allocation) +{ + discarded_buffers_.append(std::pair(vk_buffer, vma_allocation)); +} + +void VKDevice::destroy_discarded_resources() +{ + while (!discarded_images_.is_empty()) { + std::pair image_allocation = discarded_images_.pop_last(); + vmaDestroyImage(mem_allocator_get(), image_allocation.first, image_allocation.second); + } + + while (!discarded_buffers_.is_empty()) { + std::pair buffer_allocation = discarded_buffers_.pop_last(); + vmaDestroyBuffer(mem_allocator_get(), buffer_allocation.first, buffer_allocation.second); + } +} + /** \} */ } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_device.hh b/source/blender/gpu/vulkan/vk_device.hh index 323d7877fd3..571959c1116 100644 --- a/source/blender/gpu/vulkan/vk_device.hh +++ b/source/blender/gpu/vulkan/vk_device.hh @@ -73,6 +73,9 @@ class VKDevice : public NonCopyable { /** Buffer to bind to unbound resource locations. */ VKBuffer dummy_buffer_; + Vector> discarded_images_; + Vector> discarded_buffers_; + public: VkPhysicalDevice physical_device_get() const { @@ -177,6 +180,10 @@ class VKDevice : public NonCopyable { return dummy_buffer_; } + void discard_image(VkImage vk_image, VmaAllocation vma_allocation); + void discard_buffer(VkBuffer vk_buffer, VmaAllocation vma_allocation); + void destroy_discarded_resources(); + /** \} */ private: diff --git a/source/blender/gpu/vulkan/vk_texture.cc b/source/blender/gpu/vulkan/vk_texture.cc index 49be3a4a79f..7291758e7f3 100644 --- a/source/blender/gpu/vulkan/vk_texture.cc +++ b/source/blender/gpu/vulkan/vk_texture.cc @@ -26,8 +26,11 @@ namespace blender::gpu { VKTexture::~VKTexture() { if (is_allocated() && !is_texture_view()) { - const VKDevice &device = VKBackend::get().device_get(); - vmaDestroyImage(device.mem_allocator_get(), vk_image_, allocation_); + VKDevice &device = VKBackend::get().device_get(); + device.discard_image(vk_image_, allocation_); + + vk_image_ = VK_NULL_HANDLE; + allocation_ = VK_NULL_HANDLE; } } @@ -58,6 +61,19 @@ void VKTexture::generate_mipmap() mip_size_get(src_mipmap, src_size); mip_size_get(dst_mipmap, dst_size); + /* GPU Texture stores the array length in the first unused dimension size. + * Vulkan uses layers and the array length should be removed from the dimensions. */ + if (ELEM(this->type_get(), GPU_TEXTURE_1D_ARRAY)) { + src_size.y = 1; + src_size.z = 1; + dst_size.y = 1; + dst_size.z = 1; + } + if (ELEM(this->type_get(), GPU_TEXTURE_2D_ARRAY)) { + src_size.z = 1; + dst_size.z = 1; + } + layout_ensure(context, IndexRange(src_mipmap, 1), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, @@ -359,6 +375,7 @@ bool VKTexture::init_internal(GPUTexture *src, int mip_offset, int layer_offset, VKTexture *texture = unwrap(unwrap(src)); source_texture_ = texture; mip_min_ = mip_offset; + mip_max_ = mip_offset; layer_offset_ = layer_offset; use_stencil_ = use_stencil; flags_ |= IMAGE_VIEW_DIRTY; @@ -373,7 +390,11 @@ bool VKTexture::is_texture_view() const void VKTexture::ensure_allocated() { - BLI_assert(!is_texture_view()); + if (is_texture_view()) { + source_texture_->ensure_allocated(); + return; + } + if (!is_allocated()) { allocate(); } @@ -560,6 +581,7 @@ void VKTexture::layout_ensure(VKContext &context, const VkImageLayout current_layout, const VkImageLayout requested_layout) { + BLI_assert(vk_image_ != VK_NULL_HANDLE); VkImageMemoryBarrier barrier{}; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; barrier.oldLayout = current_layout; -- 2.30.2 From 787f68675dd5d1715113079ec08a406ebd24157a Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 14 Sep 2023 16:14:14 +0200 Subject: [PATCH 02/15] Discard of frame buffer, renderpass and image views. --- source/blender/gpu/vulkan/vk_debug.cc | 2 ++ source/blender/gpu/vulkan/vk_device.cc | 31 +++++++++++++++++++++ source/blender/gpu/vulkan/vk_device.hh | 6 ++++ source/blender/gpu/vulkan/vk_framebuffer.cc | 7 ++--- source/blender/gpu/vulkan/vk_image_view.cc | 6 ++-- 5 files changed, 45 insertions(+), 7 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_debug.cc b/source/blender/gpu/vulkan/vk_debug.cc index b5d0778e434..8bf341bb8ad 100644 --- a/source/blender/gpu/vulkan/vk_debug.cc +++ b/source/blender/gpu/vulkan/vk_debug.cc @@ -297,6 +297,8 @@ messenger_callback(VkDebugUtilsMessageSeverityFlagBitsEXT message_severity, debugging_tools.print_labels(callback_data); } + BLI_assert(callback_data->messageIdNumber != 0x47172512); + return VK_FALSE; }; diff --git a/source/blender/gpu/vulkan/vk_device.cc b/source/blender/gpu/vulkan/vk_device.cc index 6a666cb9091..abcab6e3f92 100644 --- a/source/blender/gpu/vulkan/vk_device.cc +++ b/source/blender/gpu/vulkan/vk_device.cc @@ -253,13 +253,34 @@ void VKDevice::discard_image(VkImage vk_image, VmaAllocation vma_allocation) discarded_images_.append(std::pair(vk_image, vma_allocation)); } +void VKDevice::discard_image_view(VkImageView vk_image_view) +{ + discarded_image_views_.append(vk_image_view); +} + void VKDevice::discard_buffer(VkBuffer vk_buffer, VmaAllocation vma_allocation) { discarded_buffers_.append(std::pair(vk_buffer, vma_allocation)); } +void VKDevice::discard_render_pass(VkRenderPass vk_render_pass) +{ + discarded_render_passes_.append(vk_render_pass); +} +void VKDevice::discard_frame_buffer(VkFramebuffer vk_frame_buffer) +{ + discarded_frame_buffers_.append(vk_frame_buffer); +} + void VKDevice::destroy_discarded_resources() { + VK_ALLOCATION_CALLBACKS + + while (!discarded_image_views_.is_empty()) { + VkImageView vk_image_view = discarded_image_views_.pop_last(); + vkDestroyImageView(vk_device_, vk_image_view, vk_allocation_callbacks); + } + while (!discarded_images_.is_empty()) { std::pair image_allocation = discarded_images_.pop_last(); vmaDestroyImage(mem_allocator_get(), image_allocation.first, image_allocation.second); @@ -269,6 +290,16 @@ void VKDevice::destroy_discarded_resources() std::pair buffer_allocation = discarded_buffers_.pop_last(); vmaDestroyBuffer(mem_allocator_get(), buffer_allocation.first, buffer_allocation.second); } + + while (!discarded_render_passes_.is_empty()) { + VkRenderPass vk_render_pass = discarded_render_passes_.pop_last(); + vkDestroyRenderPass(vk_device_, vk_render_pass, vk_allocation_callbacks); + } + + while (!discarded_frame_buffers_.is_empty()) { + VkFramebuffer vk_frame_buffer = discarded_frame_buffers_.pop_last(); + vkDestroyFramebuffer(vk_device_, vk_frame_buffer, vk_allocation_callbacks); + } } /** \} */ diff --git a/source/blender/gpu/vulkan/vk_device.hh b/source/blender/gpu/vulkan/vk_device.hh index 571959c1116..ed027340f9f 100644 --- a/source/blender/gpu/vulkan/vk_device.hh +++ b/source/blender/gpu/vulkan/vk_device.hh @@ -75,6 +75,9 @@ class VKDevice : public NonCopyable { Vector> discarded_images_; Vector> discarded_buffers_; + Vector discarded_render_passes_; + Vector discarded_frame_buffers_; + Vector discarded_image_views_; public: VkPhysicalDevice physical_device_get() const @@ -181,7 +184,10 @@ class VKDevice : public NonCopyable { } void discard_image(VkImage vk_image, VmaAllocation vma_allocation); + void discard_image_view(VkImageView vk_image_view); void discard_buffer(VkBuffer vk_buffer, VmaAllocation vma_allocation); + void discard_render_pass(VkRenderPass vk_render_pass); + void discard_frame_buffer(VkFramebuffer vk_framebuffer); void destroy_discarded_resources(); /** \} */ diff --git a/source/blender/gpu/vulkan/vk_framebuffer.cc b/source/blender/gpu/vulkan/vk_framebuffer.cc index 6df0a9f2f43..cc9a7312b29 100644 --- a/source/blender/gpu/vulkan/vk_framebuffer.cc +++ b/source/blender/gpu/vulkan/vk_framebuffer.cc @@ -469,12 +469,11 @@ void VKFrameBuffer::render_pass_free() if (vk_render_pass_ == VK_NULL_HANDLE) { return; } - VK_ALLOCATION_CALLBACKS - const VKDevice &device = VKBackend::get().device_get(); + VKDevice &device = VKBackend::get().device_get(); if (device.is_initialized()) { - vkDestroyRenderPass(device.device_get(), vk_render_pass_, vk_allocation_callbacks); - vkDestroyFramebuffer(device.device_get(), vk_framebuffer_, vk_allocation_callbacks); + device.discard_render_pass(vk_render_pass_); + device.discard_frame_buffer(vk_framebuffer_); } image_views_.clear(); vk_render_pass_ = VK_NULL_HANDLE; diff --git a/source/blender/gpu/vulkan/vk_image_view.cc b/source/blender/gpu/vulkan/vk_image_view.cc index d66a93dbeda..9c90e26bc73 100644 --- a/source/blender/gpu/vulkan/vk_image_view.cc +++ b/source/blender/gpu/vulkan/vk_image_view.cc @@ -56,9 +56,9 @@ VKImageView::VKImageView(VKImageView &&other) VKImageView::~VKImageView() { if (vk_image_view_ != VK_NULL_HANDLE) { - VK_ALLOCATION_CALLBACKS - const VKDevice &device = VKBackend::get().device_get(); - vkDestroyImageView(device.device_get(), vk_image_view_, vk_allocation_callbacks); + VKDevice &device = VKBackend::get().device_get(); + device.discard_image_view(vk_image_view_); + vk_image_view_ = VK_NULL_HANDLE; } } -- 2.30.2 From 290ba4b3d2bb4aca75c5fbb0d5a40dff7c5c59f5 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 15 Sep 2023 09:07:27 +0200 Subject: [PATCH 03/15] Allocate framebuffer --- intern/ghost/intern/GHOST_ContextVK.cc | 2 +- source/blender/draw/engines/eevee_next/eevee_instance.cc | 4 ++-- source/blender/gpu/vulkan/vk_framebuffer.cc | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/intern/ghost/intern/GHOST_ContextVK.cc b/intern/ghost/intern/GHOST_ContextVK.cc index 11f60342ae2..24e841b86bf 100644 --- a/intern/ghost/intern/GHOST_ContextVK.cc +++ b/intern/ghost/intern/GHOST_ContextVK.cc @@ -630,7 +630,7 @@ static void enableLayer(vector &layers_available, const bool display_warning) { #define PUSH_VKLAYER(name, name2) \ - if (vklayer_config_exist("VkLayer_" #name ".json") && \ + if (/*vklayer_config_exist("VkLayer_" #name ".json") && */ \ checkLayerSupport(layers_available, "VK_LAYER_" #name2)) \ { \ layers_enabled.push_back("VK_LAYER_" #name2); \ diff --git a/source/blender/draw/engines/eevee_next/eevee_instance.cc b/source/blender/draw/engines/eevee_next/eevee_instance.cc index a8d6db72acd..810af3386e4 100644 --- a/source/blender/draw/engines/eevee_next/eevee_instance.cc +++ b/source/blender/draw/engines/eevee_next/eevee_instance.cc @@ -340,9 +340,9 @@ void Instance::render_sample() sampling.step(); capture_view.render_world(); - capture_view.render_probes(); + // capture_view.render_probes(); - main_view.render(); + // main_view.render(); motion_blur.step(); } diff --git a/source/blender/gpu/vulkan/vk_framebuffer.cc b/source/blender/gpu/vulkan/vk_framebuffer.cc index cc9a7312b29..159d033c658 100644 --- a/source/blender/gpu/vulkan/vk_framebuffer.cc +++ b/source/blender/gpu/vulkan/vk_framebuffer.cc @@ -493,6 +493,7 @@ void VKFrameBuffer::color_attachment_layout_ensure(VKContext &context, return; } + color_texture->ensure_allocated(); color_texture->layout_ensure(context, requested_layout); dirty_attachments_ = true; } -- 2.30.2 From c0cdb39edb88bb2b7c22c8b5e17162edd943a785 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 15 Sep 2023 13:32:42 +0200 Subject: [PATCH 04/15] Fix ubo attached data upload --- intern/ghost/intern/GHOST_ContextVK.cc | 4 ++-- .../draw/engines/eevee_next/eevee_instance.cc | 4 +++- source/blender/gpu/vulkan/vk_shader_interface.cc | 13 +++++++++++-- source/blender/gpu/vulkan/vk_uniform_buffer.cc | 7 +++++++ 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/intern/ghost/intern/GHOST_ContextVK.cc b/intern/ghost/intern/GHOST_ContextVK.cc index 24e841b86bf..4d7be9e55da 100644 --- a/intern/ghost/intern/GHOST_ContextVK.cc +++ b/intern/ghost/intern/GHOST_ContextVK.cc @@ -102,7 +102,7 @@ static bool vklayer_config_exist(const char *vk_extension_config) { const char *ev_val = getenv("VK_LAYER_PATH"); if (ev_val == nullptr) { - return false; + return true; } std::stringstream filename; filename << ev_val; @@ -630,7 +630,7 @@ static void enableLayer(vector &layers_available, const bool display_warning) { #define PUSH_VKLAYER(name, name2) \ - if (/*vklayer_config_exist("VkLayer_" #name ".json") && */ \ + if (vklayer_config_exist("VkLayer_" #name ".json") && \ checkLayerSupport(layers_available, "VK_LAYER_" #name2)) \ { \ layers_enabled.push_back("VK_LAYER_" #name2); \ diff --git a/source/blender/draw/engines/eevee_next/eevee_instance.cc b/source/blender/draw/engines/eevee_next/eevee_instance.cc index 810af3386e4..0b790edb24b 100644 --- a/source/blender/draw/engines/eevee_next/eevee_instance.cc +++ b/source/blender/draw/engines/eevee_next/eevee_instance.cc @@ -327,6 +327,7 @@ bool Instance::do_probe_sync() const **/ void Instance::render_sample() { + GPU_debug_capture_begin(); if (sampling.finished_viewport()) { film.display(); return; @@ -340,11 +341,12 @@ void Instance::render_sample() sampling.step(); capture_view.render_world(); - // capture_view.render_probes(); + capture_view.render_probes(); // main_view.render(); motion_blur.step(); + GPU_debug_capture_end(); } void Instance::render_read_result(RenderLayer *render_layer, const char *view_name) diff --git a/source/blender/gpu/vulkan/vk_shader_interface.cc b/source/blender/gpu/vulkan/vk_shader_interface.cc index f85dfadce5f..8232d357a37 100644 --- a/source/blender/gpu/vulkan/vk_shader_interface.cc +++ b/source/blender/gpu/vulkan/vk_shader_interface.cc @@ -153,6 +153,7 @@ void VKShaderInterface::init(const shader::ShaderCreateInfo &info) uint32_t descriptor_set_location = 0; for (ShaderCreateInfo::Resource &res : all_resources) { const ShaderInput *input = shader_input_get(res); + BLI_assert(input); descriptor_set_location_update(input, descriptor_set_location++); } @@ -217,8 +218,16 @@ const ShaderInput *VKShaderInterface::shader_input_get( const shader::ShaderCreateInfo::Resource::BindType &bind_type, int binding) const { switch (bind_type) { - case shader::ShaderCreateInfo::Resource::BindType::IMAGE: - return texture_get(binding + image_offset_); + case shader::ShaderCreateInfo::Resource::BindType::IMAGE: { + /* Not really nice, but the binding namespace between OpenGL and Vulkan don't match. To fix + * this we need to check if one of both cases return a binding. + * TODO: we might want to introduce a different API to fix this. */ + const ShaderInput *result = texture_get(binding + image_offset_); + if (!result) { + result = texture_get(binding); + } + return result; + } case shader::ShaderCreateInfo::Resource::BindType::SAMPLER: return texture_get(binding); case shader::ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER: diff --git a/source/blender/gpu/vulkan/vk_uniform_buffer.cc b/source/blender/gpu/vulkan/vk_uniform_buffer.cc index 25d02eabbb6..6651e8acce7 100644 --- a/source/blender/gpu/vulkan/vk_uniform_buffer.cc +++ b/source/blender/gpu/vulkan/vk_uniform_buffer.cc @@ -43,6 +43,13 @@ void VKUniformBuffer::bind(int slot, shader::ShaderCreateInfo::Resource::BindTyp allocate(); } + /* Upload attached data, during bind time. */ + if (data_) { + buffer_.update(data_); + MEM_freeN(data_); + data_ = nullptr; + } + VKContext &context = *VKContext::get(); VKShader *shader = static_cast(context.shader); const VKShaderInterface &shader_interface = shader->interface_get(); -- 2.30.2 From 44ad2c8f4fdb98cb0d8a910210d8c5d1002ce2db Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 15 Sep 2023 15:01:39 +0200 Subject: [PATCH 05/15] Limit the number of textures to fix issues between eevee-next and vulkan state manager. --- source/blender/gpu/vulkan/vk_backend.cc | 4 +++- source/blender/gpu/vulkan/vk_uniform_buffer.cc | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_backend.cc b/source/blender/gpu/vulkan/vk_backend.cc index 9bfb44c2315..f10bde7c4b7 100644 --- a/source/blender/gpu/vulkan/vk_backend.cc +++ b/source/blender/gpu/vulkan/vk_backend.cc @@ -231,7 +231,9 @@ void VKBackend::capabilities_init(VKDevice &device) GCaps.max_textures = limits.maxDescriptorSetSampledImages; GCaps.max_textures_vert = limits.maxPerStageDescriptorSampledImages; GCaps.max_textures_geom = limits.maxPerStageDescriptorSampledImages; - GCaps.max_textures_frag = limits.maxPerStageDescriptorSampledImages; + /* Eevee next reorder textures based on this number, but vulkan uses this also to offset images. + * TODO: change the state manager to use none-indexed bindings. */ + GCaps.max_textures_frag = min_ii(limits.maxPerStageDescriptorSampledImages, 12); GCaps.max_samplers = limits.maxSamplerAllocationCount; for (int i = 0; i < 3; i++) { GCaps.max_work_group_count[i] = limits.maxComputeWorkGroupCount[i]; diff --git a/source/blender/gpu/vulkan/vk_uniform_buffer.cc b/source/blender/gpu/vulkan/vk_uniform_buffer.cc index 6651e8acce7..740ceabe7a3 100644 --- a/source/blender/gpu/vulkan/vk_uniform_buffer.cc +++ b/source/blender/gpu/vulkan/vk_uniform_buffer.cc @@ -46,8 +46,7 @@ void VKUniformBuffer::bind(int slot, shader::ShaderCreateInfo::Resource::BindTyp /* Upload attached data, during bind time. */ if (data_) { buffer_.update(data_); - MEM_freeN(data_); - data_ = nullptr; + MEM_SAFE_FREE(data_); } VKContext &context = *VKContext::get(); -- 2.30.2 From c7f9778f7c56077cf11129390a980898d5157cd6 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 15 Sep 2023 15:33:20 +0200 Subject: [PATCH 06/15] Copy vertex buffer to storage buffer. --- .../draw/engines/eevee_next/eevee_instance.cc | 2 +- .../draw/engines/eevee_next/eevee_view.cc | 3 +++ .../blender/gpu/vulkan/vk_command_buffer.cc | 7 +++++++ .../blender/gpu/vulkan/vk_command_buffer.hh | 1 + source/blender/gpu/vulkan/vk_debug.cc | 1 + .../blender/gpu/vulkan/vk_storage_buffer.cc | 19 ++++++++++++++----- 6 files changed, 27 insertions(+), 6 deletions(-) diff --git a/source/blender/draw/engines/eevee_next/eevee_instance.cc b/source/blender/draw/engines/eevee_next/eevee_instance.cc index 0b790edb24b..9e3138f6bc6 100644 --- a/source/blender/draw/engines/eevee_next/eevee_instance.cc +++ b/source/blender/draw/engines/eevee_next/eevee_instance.cc @@ -343,7 +343,7 @@ void Instance::render_sample() capture_view.render_world(); capture_view.render_probes(); - // main_view.render(); + main_view.render(); motion_blur.step(); GPU_debug_capture_end(); diff --git a/source/blender/draw/engines/eevee_next/eevee_view.cc b/source/blender/draw/engines/eevee_next/eevee_view.cc index c27aa508187..b0e84fdcb89 100644 --- a/source/blender/draw/engines/eevee_next/eevee_view.cc +++ b/source/blender/draw/engines/eevee_next/eevee_view.cc @@ -120,6 +120,8 @@ void ShadingView::render() inst_.pipelines.background.render(render_view_new_); +#if 0 + /* TODO(fclem): Move it after the first prepass (and hiz update) once pipeline is stabilized. */ inst_.lights.set_view(render_view_new_, extent_); @@ -148,6 +150,7 @@ void ShadingView::render() inst_.irradiance_cache.viewport_draw(render_view_new_, combined_fb_); inst_.ambient_occlusion.render_pass(render_view_new_); +#endif GPUTexture *combined_final_tx = render_postfx(rbufs.combined_tx); inst_.film.accumulate(sub_view_, combined_final_tx); diff --git a/source/blender/gpu/vulkan/vk_command_buffer.cc b/source/blender/gpu/vulkan/vk_command_buffer.cc index 77bdc8c2f00..07216d5abf0 100644 --- a/source/blender/gpu/vulkan/vk_command_buffer.cc +++ b/source/blender/gpu/vulkan/vk_command_buffer.cc @@ -216,6 +216,13 @@ void VKCommandBuffer::copy(VKTexture &dst_texture, regions.data()); } +void VKCommandBuffer::copy(VKBuffer &dst_buffer, VkBuffer src_buffer, Span regions) +{ + ensure_no_active_framebuffer(); + vkCmdCopyBuffer( + vk_command_buffer_, src_buffer, dst_buffer.vk_handle(), regions.size(), regions.data()); +} + void VKCommandBuffer::blit(VKTexture &dst_texture, VKTexture &src_texture, Span regions) diff --git a/source/blender/gpu/vulkan/vk_command_buffer.hh b/source/blender/gpu/vulkan/vk_command_buffer.hh index c2b6dd62194..30b63b7696b 100644 --- a/source/blender/gpu/vulkan/vk_command_buffer.hh +++ b/source/blender/gpu/vulkan/vk_command_buffer.hh @@ -168,6 +168,7 @@ class VKCommandBuffer : NonCopyable, NonMovable { void copy(VKBuffer &dst_buffer, VKTexture &src_texture, Span regions); void copy(VKTexture &dst_texture, VKBuffer &src_buffer, Span regions); void copy(VKTexture &dst_texture, VKTexture &src_texture, Span regions); + void copy(VKBuffer &dst_buffer, VkBuffer src_buffer, Span regions); void blit(VKTexture &dst_texture, VKTexture &src_texture, Span regions); void blit(VKTexture &dst_texture, VkImageLayout dst_layout, diff --git a/source/blender/gpu/vulkan/vk_debug.cc b/source/blender/gpu/vulkan/vk_debug.cc index 8bf341bb8ad..95cf83951c3 100644 --- a/source/blender/gpu/vulkan/vk_debug.cc +++ b/source/blender/gpu/vulkan/vk_debug.cc @@ -298,6 +298,7 @@ messenger_callback(VkDebugUtilsMessageSeverityFlagBitsEXT message_severity, } BLI_assert(callback_data->messageIdNumber != 0x47172512); + BLI_assert(callback_data->messageIdNumber != 0x2ba3a98e); return VK_FALSE; }; diff --git a/source/blender/gpu/vulkan/vk_storage_buffer.cc b/source/blender/gpu/vulkan/vk_storage_buffer.cc index 4d187e21b27..a2fdbca4d32 100644 --- a/source/blender/gpu/vulkan/vk_storage_buffer.cc +++ b/source/blender/gpu/vulkan/vk_storage_buffer.cc @@ -73,12 +73,21 @@ void VKStorageBuffer::clear(uint32_t clear_value) buffer_.clear(context, clear_value); } -void VKStorageBuffer::copy_sub(VertBuf * /*src*/, - uint /*dst_offset*/, - uint /*src_offset*/, - uint /*copy_size*/) +void VKStorageBuffer::copy_sub(VertBuf *src, uint dst_offset, uint src_offset, uint copy_size) { - NOT_YET_IMPLEMENTED; + ensure_allocated(); + + const VKVertexBuffer &src_vertex_buffer = *unwrap(src); + + VkBufferCopy region = {}; + region.srcOffset = src_offset; + region.dstOffset = dst_offset; + region.size = copy_size; + + VKContext &context = *VKContext::get(); + VKCommandBuffer &command_buffer = context.command_buffer_get(); + command_buffer.copy(buffer_, src_vertex_buffer.vk_handle(), Span(®ion, 1)); + command_buffer.submit(); } void VKStorageBuffer::read(void *data) -- 2.30.2 From 35a515e974a6bd184e0e2c32444f685c05ba67db Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 18 Sep 2023 08:43:45 +0200 Subject: [PATCH 07/15] Submit after each compute dispatch. --- source/blender/gpu/vulkan/vk_backend.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_backend.cc b/source/blender/gpu/vulkan/vk_backend.cc index f10bde7c4b7..96866b2b590 100644 --- a/source/blender/gpu/vulkan/vk_backend.cc +++ b/source/blender/gpu/vulkan/vk_backend.cc @@ -107,6 +107,7 @@ void VKBackend::compute_dispatch(int groups_x_len, int groups_y_len, int groups_ context.bind_compute_pipeline(); VKCommandBuffer &command_buffer = context.command_buffer_get(); command_buffer.dispatch(groups_x_len, groups_y_len, groups_z_len); + command_buffer.submit(); } void VKBackend::compute_dispatch_indirect(StorageBuf *indirect_buf) @@ -118,6 +119,7 @@ void VKBackend::compute_dispatch_indirect(StorageBuf *indirect_buf) VKStorageBuffer &indirect_buffer = *unwrap(indirect_buf); VKCommandBuffer &command_buffer = context.command_buffer_get(); command_buffer.dispatch(indirect_buffer); + command_buffer.submit(); } Context *VKBackend::context_alloc(void *ghost_window, void *ghost_context) @@ -231,9 +233,7 @@ void VKBackend::capabilities_init(VKDevice &device) GCaps.max_textures = limits.maxDescriptorSetSampledImages; GCaps.max_textures_vert = limits.maxPerStageDescriptorSampledImages; GCaps.max_textures_geom = limits.maxPerStageDescriptorSampledImages; - /* Eevee next reorder textures based on this number, but vulkan uses this also to offset images. - * TODO: change the state manager to use none-indexed bindings. */ - GCaps.max_textures_frag = min_ii(limits.maxPerStageDescriptorSampledImages, 12); + GCaps.max_textures_frag = limits.maxPerStageDescriptorSampledImages; GCaps.max_samplers = limits.maxSamplerAllocationCount; for (int i = 0; i < 3; i++) { GCaps.max_work_group_count[i] = limits.maxComputeWorkGroupCount[i]; -- 2.30.2 From d6e0ffe022e18fb8f47ad4cb5785cc898add1404 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 18 Sep 2023 08:46:14 +0200 Subject: [PATCH 08/15] Remove length from bindable resource --- .../gpu/vulkan/vk_bindable_resource.hh | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_bindable_resource.hh b/source/blender/gpu/vulkan/vk_bindable_resource.hh index 6b729bb93a9..a75f5d79423 100644 --- a/source/blender/gpu/vulkan/vk_bindable_resource.hh +++ b/source/blender/gpu/vulkan/vk_bindable_resource.hh @@ -8,8 +8,6 @@ #pragma once -#include "BLI_array.hh" - #include "gpu_shader_create_info.hh" namespace blender::gpu { @@ -38,22 +36,29 @@ class VKBindableResource { * Blender binds resources at context level (VKStateManager). The bindings are organized in * namespaces. */ -template -class VKBindSpace { - Array bindings_ = Array(MaxBindings); +template class VKBindSpace { + class ResourceBinding { + public: + int binding; + VKBindableResource *resource; + }; + + Vector bindings_; public: - VKBindSpace() - { - bindings_.fill(nullptr); - } - /** * Register a binding to this namespace. */ void bind(int binding, VKBindableResource &resource) { - bindings_[binding] = &resource; + for (ResourceBinding &bind : bindings_) { + if (bind.binding == binding) { + bind.resource = &resource; + return; + } + } + ResourceBinding bind = {binding, &resource}; + bindings_.append(bind); } /** @@ -61,10 +66,8 @@ class VKBindSpace { */ void apply_bindings() { - for (int binding : IndexRange(MaxBindings)) { - if (bindings_[binding] != nullptr) { - bindings_[binding]->bind(binding, BindType); - } + for (ResourceBinding &binding : bindings_) { + binding.resource->bind(binding.binding, BindType); } } @@ -73,11 +76,8 @@ class VKBindSpace { */ void unbind(VKBindableResource &resource) { - for (int binding : IndexRange(MaxBindings)) { - if (bindings_[binding] == &resource) { - bindings_[binding] = nullptr; - } - } + bindings_.remove_if( + [&resource](const ResourceBinding &binding) { return binding.resource == &resource; }); } /** @@ -85,7 +85,7 @@ class VKBindSpace { */ void unbind_all() { - bindings_.fill(nullptr); + bindings_.clear(); } }; -- 2.30.2 From 8a95a881d79cbaa1c8345673edc6c65704d74465 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 18 Sep 2023 08:46:43 +0200 Subject: [PATCH 09/15] Upload vertex buffer in storage buffer copy sub. --- source/blender/gpu/vulkan/vk_storage_buffer.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/gpu/vulkan/vk_storage_buffer.cc b/source/blender/gpu/vulkan/vk_storage_buffer.cc index a2fdbca4d32..873c04d699e 100644 --- a/source/blender/gpu/vulkan/vk_storage_buffer.cc +++ b/source/blender/gpu/vulkan/vk_storage_buffer.cc @@ -77,7 +77,8 @@ void VKStorageBuffer::copy_sub(VertBuf *src, uint dst_offset, uint src_offset, u { ensure_allocated(); - const VKVertexBuffer &src_vertex_buffer = *unwrap(src); + VKVertexBuffer &src_vertex_buffer = *unwrap(src); + src_vertex_buffer.upload(); VkBufferCopy region = {}; region.srcOffset = src_offset; -- 2.30.2 From 56c1252b1dde92356b368f21c1bba6f1ee95c594 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 18 Sep 2023 09:51:43 +0200 Subject: [PATCH 10/15] Add debug print for descriptor sets --- source/blender/gpu/vulkan/vk_descriptor_set.cc | 13 +++++++++++++ source/blender/gpu/vulkan/vk_descriptor_set.hh | 4 ++++ 2 files changed, 17 insertions(+) diff --git a/source/blender/gpu/vulkan/vk_descriptor_set.cc b/source/blender/gpu/vulkan/vk_descriptor_set.cc index 499fb598fc0..5b6c400bb5f 100644 --- a/source/blender/gpu/vulkan/vk_descriptor_set.cc +++ b/source/blender/gpu/vulkan/vk_descriptor_set.cc @@ -212,4 +212,17 @@ std::unique_ptr VKDescriptorSetTracker::create_resource(VKConte return device.descriptor_pools_get().allocate(layout_); } +void VKDescriptorSetTracker::debug_print() const +{ + for (const Binding &binding : bindings_) { + binding.debug_print(); + } +} + +void VKDescriptorSetTracker::Binding::debug_print() const +{ + std::cout << "VkDescriptorSetTrackker::Binding(type: " << type + << ", location:" << location.binding << ")\n"; +} + } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_descriptor_set.hh b/source/blender/gpu/vulkan/vk_descriptor_set.hh index 275c92149c6..51dc7ccf296 100644 --- a/source/blender/gpu/vulkan/vk_descriptor_set.hh +++ b/source/blender/gpu/vulkan/vk_descriptor_set.hh @@ -148,6 +148,8 @@ class VKDescriptorSetTracker : protected VKResourceTracker { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) && texture != nullptr; } + + void debug_print() const; }; private: @@ -191,6 +193,8 @@ class VKDescriptorSetTracker : protected VKResourceTracker { return active_resource(); } + void debug_print() const; + protected: std::unique_ptr create_resource(VKContext &context) override; -- 2.30.2 From 698cb0681bb2cf38ec9033b64831e9d3cc4fb388 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 18 Sep 2023 11:17:47 +0200 Subject: [PATCH 11/15] Fix image offset and collsions --- .../blender/gpu/vulkan/vk_shader_interface.cc | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_shader_interface.cc b/source/blender/gpu/vulkan/vk_shader_interface.cc index 8232d357a37..09424ae63b2 100644 --- a/source/blender/gpu/vulkan/vk_shader_interface.cc +++ b/source/blender/gpu/vulkan/vk_shader_interface.cc @@ -24,7 +24,7 @@ void VKShaderInterface::init(const shader::ShaderCreateInfo &info) ssbo_len_ = 0; ubo_len_ = 0; image_offset_ = -1; - + int image_max_binding = -1; Vector all_resources; all_resources.extend(info.pass_resources_); all_resources.extend(info.batch_resources_); @@ -33,6 +33,7 @@ void VKShaderInterface::init(const shader::ShaderCreateInfo &info) switch (res.bind_type) { case ShaderCreateInfo::Resource::BindType::IMAGE: uniform_len_++; + image_max_binding = max_ii(image_max_binding, res.slot); break; case ShaderCreateInfo::Resource::BindType::SAMPLER: image_offset_ = max_ii(image_offset_, res.slot); @@ -57,8 +58,11 @@ void VKShaderInterface::init(const shader::ShaderCreateInfo &info) names_size += PUSH_CONSTANTS_FALLBACK_NAME_LEN + 1; } - /* Make sure that the image slots don't overlap with the sampler slots. */ + /* Make sure that the image slots don't overlap with other sampler or image slots. */ image_offset_++; + if (image_offset_ != 0 && image_offset_ <= image_max_binding) { + image_offset_ = image_max_binding + 1; + } int32_t input_tot_len = attr_len_ + ubo_len_ + uniform_len_ + ssbo_len_; inputs_ = static_cast( @@ -150,6 +154,7 @@ void VKShaderInterface::init(const shader::ShaderCreateInfo &info) /* Note: input_tot_len is sometimes more than we need. */ const uint32_t resources_len = input_tot_len; descriptor_set_locations_ = Array(resources_len); + descriptor_set_locations_.fill(-1); uint32_t descriptor_set_location = 0; for (ShaderCreateInfo::Resource &res : all_resources) { const ShaderInput *input = shader_input_get(res); @@ -180,6 +185,7 @@ void VKShaderInterface::descriptor_set_location_update(const ShaderInput *shader const VKDescriptorSet::Location location) { int32_t index = shader_input_index(inputs_, shader_input); + BLI_assert(descriptor_set_locations_[index].binding == -1); descriptor_set_locations_[index] = location; } @@ -218,16 +224,11 @@ const ShaderInput *VKShaderInterface::shader_input_get( const shader::ShaderCreateInfo::Resource::BindType &bind_type, int binding) const { switch (bind_type) { - case shader::ShaderCreateInfo::Resource::BindType::IMAGE: { + case shader::ShaderCreateInfo::Resource::BindType::IMAGE: /* Not really nice, but the binding namespace between OpenGL and Vulkan don't match. To fix * this we need to check if one of both cases return a binding. * TODO: we might want to introduce a different API to fix this. */ - const ShaderInput *result = texture_get(binding + image_offset_); - if (!result) { - result = texture_get(binding); - } - return result; - } + return texture_get((binding >= image_offset_) ? binding : binding + image_offset_); case shader::ShaderCreateInfo::Resource::BindType::SAMPLER: return texture_get(binding); case shader::ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER: -- 2.30.2 From 3dd838d885a551b7f6b34b87e5bf99eb8686d647 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 18 Sep 2023 11:38:50 +0200 Subject: [PATCH 12/15] Enable full eevee-next --- source/blender/draw/engines/eevee_next/eevee_view.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/source/blender/draw/engines/eevee_next/eevee_view.cc b/source/blender/draw/engines/eevee_next/eevee_view.cc index b0e84fdcb89..c27aa508187 100644 --- a/source/blender/draw/engines/eevee_next/eevee_view.cc +++ b/source/blender/draw/engines/eevee_next/eevee_view.cc @@ -120,8 +120,6 @@ void ShadingView::render() inst_.pipelines.background.render(render_view_new_); -#if 0 - /* TODO(fclem): Move it after the first prepass (and hiz update) once pipeline is stabilized. */ inst_.lights.set_view(render_view_new_, extent_); @@ -150,7 +148,6 @@ void ShadingView::render() inst_.irradiance_cache.viewport_draw(render_view_new_, combined_fb_); inst_.ambient_occlusion.render_pass(render_view_new_); -#endif GPUTexture *combined_final_tx = render_postfx(rbufs.combined_tx); inst_.film.accumulate(sub_view_, combined_final_tx); -- 2.30.2 From bea3663a164e4a00533ce01f2feab2b1a4847eb5 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 18 Sep 2023 11:56:39 +0200 Subject: [PATCH 13/15] Enable device features. --- intern/ghost/intern/GHOST_ContextVK.cc | 6 ++++++ source/blender/gpu/vulkan/vk_uniform_buffer.cc | 6 +++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/intern/ghost/intern/GHOST_ContextVK.cc b/intern/ghost/intern/GHOST_ContextVK.cc index 4d7be9e55da..ec404493adc 100644 --- a/intern/ghost/intern/GHOST_ContextVK.cc +++ b/intern/ghost/intern/GHOST_ContextVK.cc @@ -231,8 +231,14 @@ class GHOST_DeviceVK { device_features.drawIndirectFirstInstance = VK_TRUE; device_features.fragmentStoresAndAtomics = VK_TRUE; + VkPhysicalDeviceVulkan12Features device_12_features = {}; + device_12_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES; + device_12_features.shaderOutputLayer = VK_TRUE; + device_12_features.shaderOutputViewportIndex = VK_TRUE; + VkPhysicalDeviceMaintenance4FeaturesKHR maintenance_4 = {}; maintenance_4.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR; + maintenance_4.pNext = &device_12_features; maintenance_4.maintenance4 = VK_TRUE; /* Enable shader draw parameters on logical device when supported on physical device. */ diff --git a/source/blender/gpu/vulkan/vk_uniform_buffer.cc b/source/blender/gpu/vulkan/vk_uniform_buffer.cc index 740ceabe7a3..5e6d250bacc 100644 --- a/source/blender/gpu/vulkan/vk_uniform_buffer.cc +++ b/source/blender/gpu/vulkan/vk_uniform_buffer.cc @@ -24,7 +24,11 @@ void VKUniformBuffer::update(const void *data) void VKUniformBuffer::allocate() { - buffer_.create(size_in_bytes_, GPU_USAGE_STATIC, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + buffer_.create(size_in_bytes_, + GPU_USAGE_STATIC, + static_cast(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | + VK_BUFFER_USAGE_TRANSFER_DST_BIT)); debug::object_label(buffer_.vk_handle(), name_); } -- 2.30.2 From 9d359928b3dc5ce14ec46eb0e27897d103b96f99 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 18 Sep 2023 13:57:20 +0200 Subject: [PATCH 14/15] Revert removal of newline. --- source/blender/gpu/vulkan/vk_device.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/gpu/vulkan/vk_device.cc b/source/blender/gpu/vulkan/vk_device.cc index abcab6e3f92..befb83c3ec9 100644 --- a/source/blender/gpu/vulkan/vk_device.cc +++ b/source/blender/gpu/vulkan/vk_device.cc @@ -25,6 +25,7 @@ void VKDevice::deinit() { VK_ALLOCATION_CALLBACKS; vkDestroyCommandPool(vk_device_, vk_command_pool_, vk_allocation_callbacks); + dummy_buffer_.free(); sampler_.free(); destroy_discarded_resources(); -- 2.30.2 From e5acbcf818cc76ed40649c1a99c73dc5f6d49da0 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 19 Sep 2023 11:32:04 +0200 Subject: [PATCH 15/15] Fix Std430 alignment --- .../blender/gpu/tests/memory_layout_test.cc | 11 ++++++++ source/blender/gpu/vulkan/vk_memory_layout.cc | 27 ++++++++++++++++++- source/blender/gpu/vulkan/vk_shader.cc | 2 +- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/source/blender/gpu/tests/memory_layout_test.cc b/source/blender/gpu/tests/memory_layout_test.cc index 8e4eda29c99..7b277e8bade 100644 --- a/source/blender/gpu/tests/memory_layout_test.cc +++ b/source/blender/gpu/tests/memory_layout_test.cc @@ -112,4 +112,15 @@ TEST(std140, gpu_shader_2D_widget_base) EXPECT_EQ(offset, 272); } +TEST(std430, overlay_grid) +{ + uint32_t offset = 0; + + def_attr(shader::Type::VEC3, 0, 0, 12, &offset); + def_attr(shader::Type::INT, 0, 12, 16, &offset); + + align_end_of_struct(&offset); + EXPECT_EQ(offset, 16); +} + } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_memory_layout.cc b/source/blender/gpu/vulkan/vk_memory_layout.cc index a7e87e2ea7f..ae0310d0a99 100644 --- a/source/blender/gpu/vulkan/vk_memory_layout.cc +++ b/source/blender/gpu/vulkan/vk_memory_layout.cc @@ -60,6 +60,7 @@ uint32_t Std430::element_components_len(const shader::Type type) case shader::Type::VEC3: case shader::Type::UVEC3: case shader::Type::IVEC3: + return 3; case shader::Type::VEC4: case shader::Type::UVEC4: case shader::Type::IVEC4: @@ -76,7 +77,31 @@ uint32_t Std430::element_components_len(const shader::Type type) uint32_t Std430::array_components_len(const shader::Type type) { - return Std430::element_components_len(type); + switch (type) { + case shader::Type::FLOAT: + case shader::Type::UINT: + case shader::Type::INT: + case shader::Type::BOOL: + return 1; + case shader::Type::VEC2: + case shader::Type::UVEC2: + case shader::Type::IVEC2: + return 2; + case shader::Type::VEC3: + case shader::Type::UVEC3: + case shader::Type::IVEC3: + case shader::Type::VEC4: + case shader::Type::UVEC4: + case shader::Type::IVEC4: + return 4; + case shader::Type::MAT3: + return 12; + case shader::Type::MAT4: + return 16; + default: + BLI_assert_msg(false, "Type not supported in dynamic structs."); + } + return 0; } uint32_t Std140::component_mem_size(const shader::Type /*type*/) diff --git a/source/blender/gpu/vulkan/vk_shader.cc b/source/blender/gpu/vulkan/vk_shader.cc index a3f54eb1607..0a6d7d13041 100644 --- a/source/blender/gpu/vulkan/vk_shader.cc +++ b/source/blender/gpu/vulkan/vk_shader.cc @@ -1006,7 +1006,7 @@ std::string VKShader::resources_declare(const shader::ShaderCreateInfo &info) co if (push_constants_storage != VKPushConstants::StorageType::NONE) { ss << "\n/* Push Constants. */\n"; if (push_constants_storage == VKPushConstants::StorageType::PUSH_CONSTANTS) { - ss << "layout(push_constant) uniform constants\n"; + ss << "layout(push_constant, std430) uniform constants\n"; } else if (push_constants_storage == VKPushConstants::StorageType::UNIFORM_BUFFER) { ss << "layout(binding = " << push_constants_layout.descriptor_set_location_get() -- 2.30.2