Commit: fc834ee79f776bb936248446abcedab04f0062e4 Author: Jeroen Bakker Date: Fri Feb 3 13:54:52 2023 +0100 Branches: temp-vulkan-descriptor-sets https://developer.blender.org/rBfc834ee79f776bb936248446abcedab04f0062e4
Added ssbo test. =================================================================== M source/blender/gpu/CMakeLists.txt A source/blender/gpu/tests/gpu_storage_buffer_test.cc M source/blender/gpu/vulkan/vk_backend.cc A source/blender/gpu/vulkan/vk_buffer.cc A source/blender/gpu/vulkan/vk_buffer.hh M source/blender/gpu/vulkan/vk_context.hh M source/blender/gpu/vulkan/vk_shader.cc M source/blender/gpu/vulkan/vk_storage_buffer.cc M source/blender/gpu/vulkan/vk_storage_buffer.hh =================================================================== diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 44ec004f776..64fb909da68 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -190,6 +190,7 @@ set(OPENGL_SRC set(VULKAN_SRC vulkan/vk_backend.cc vulkan/vk_batch.cc + vulkan/vk_buffer.cc vulkan/vk_context.cc vulkan/vk_descriptor_pools.cc vulkan/vk_drawlist.cc @@ -208,6 +209,7 @@ set(VULKAN_SRC vulkan/vk_backend.hh vulkan/vk_batch.hh + vulkan/vk_buffer.hh vulkan/vk_context.hh vulkan/vk_descriptor_pools.hh vulkan/vk_drawlist.hh @@ -784,6 +786,7 @@ if(WITH_GTESTS) tests/gpu_index_buffer_test.cc tests/gpu_shader_builtin_test.cc tests/gpu_shader_test.cc + tests/gpu_storage_buffer_test.cc tests/gpu_testing.hh ) diff --git a/source/blender/gpu/tests/gpu_storage_buffer_test.cc b/source/blender/gpu/tests/gpu_storage_buffer_test.cc new file mode 100644 index 00000000000..e9e8efb1dc7 --- /dev/null +++ b/source/blender/gpu/tests/gpu_storage_buffer_test.cc @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include "testing/testing.h" + +#include "GPU_storage_buffer.h" + +#include "BLI_vector.hh" + +#include "gpu_testing.hh" + +namespace blender::gpu::tests { + +constexpr size_t SIZE = 128; +constexpr size_t SIZE_IN_BYTES = SIZE * sizeof(int); + +static void test_gpu_storage_buffer_create_update_read() +{ + GPUStorageBuf *ssbo = GPU_storagebuf_create_ex( + SIZE_IN_BYTES, nullptr, GPU_USAGE_STATIC, __func__); + EXPECT_NE(ssbo, nullptr); + + /* Upload some dummy data. */ + int data[SIZE]; + for (int i : IndexRange(SIZE)) { + data[i] = i; + } + GPU_storagebuf_update(ssbo, data); + + GPU_storagebuf_free(ssbo); +} + +GPU_TEST(gpu_storage_buffer_create_update_read); + +} // namespace blender::gpu::tests \ No newline at end of file diff --git a/source/blender/gpu/vulkan/vk_backend.cc b/source/blender/gpu/vulkan/vk_backend.cc index 74d9d8bed8e..5eea6faf3b4 100644 --- a/source/blender/gpu/vulkan/vk_backend.cc +++ b/source/blender/gpu/vulkan/vk_backend.cc @@ -123,9 +123,9 @@ UniformBuf *VKBackend::uniformbuf_alloc(int size, const char *name) return new VKUniformBuffer(size, name); } -StorageBuf *VKBackend::storagebuf_alloc(int size, GPUUsageType /*usage*/, const char *name) +StorageBuf *VKBackend::storagebuf_alloc(int size, GPUUsageType usage, const char *name) { - return new VKStorageBuffer(size, name); + return new VKStorageBuffer(size, usage, name); } VertBuf *VKBackend::vertbuf_alloc() diff --git a/source/blender/gpu/vulkan/vk_buffer.cc b/source/blender/gpu/vulkan/vk_buffer.cc new file mode 100644 index 00000000000..ff12d153702 --- /dev/null +++ b/source/blender/gpu/vulkan/vk_buffer.cc @@ -0,0 +1,104 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2023 Blender Foundation. All rights reserved. */ + +/** \file + * \ingroup gpu + */ + +#include "vk_buffer.hh" + +namespace blender::gpu { + +VKBuffer::~VKBuffer() +{ + VKContext &context = *VKContext::get(); + free(context); +} + +bool VKBuffer::is_allocated() +{ + return allocation_ != VK_NULL_HANDLE; +} + +static VmaAllocationCreateFlagBits vma_allocation_flags(GPUUsageType usage) +{ + switch (usage) { + case GPU_USAGE_STATIC: + return static_cast<VmaAllocationCreateFlagBits>( + VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT); + case GPU_USAGE_DYNAMIC: + return static_cast<VmaAllocationCreateFlagBits>( + VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT); + case GPU_USAGE_DEVICE_ONLY: + return VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT; + case GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY: + case GPU_USAGE_STREAM: + break; + } + BLI_assert_msg(false, "Incorrect GPUUsageType"); + return static_cast<VmaAllocationCreateFlagBits>(VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | + VMA_ALLOCATION_CREATE_MAPPED_BIT); +} + +bool VKBuffer::create(VKContext &context, + int64_t size_in_bytes, + GPUUsageType usage, + VkBufferUsageFlagBits buffer_usage) +{ + BLI_assert(!is_allocated()); + + size_in_bytes_ = size_in_bytes; + + VmaAllocator allocator = context.mem_allocator_get(); + VkBufferCreateInfo create_info = {}; + create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + create_info.flags = 0; + create_info.size = size_in_bytes; + create_info.usage = buffer_usage; + /* For now the compute and graphics command queues are the same, so we can safely assume + * exclusive mode.*/ + create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + create_info.queueFamilyIndexCount = 1; + create_info.pQueueFamilyIndices = context.queue_family_ptr_get(); + + VmaAllocationCreateInfo vma_create_info = {}; + vma_create_info.flags = vma_allocation_flags(usage); + vma_create_info.priority = 1.0f; + vma_create_info.usage = VMA_MEMORY_USAGE_AUTO; + + VkResult result = vmaCreateBuffer( + allocator, &create_info, &vma_create_info, &vk_buffer_, &allocation_, nullptr); + return result == VK_SUCCESS; +} + +bool VKBuffer::update(VKContext &context, const void *data) +{ + void *mapped_memory; + bool result = map(context, &mapped_memory); + if (result) { + memcpy(mapped_memory, data, size_in_bytes_); + unmap(context); + } + return result; +} + +bool VKBuffer::map(VKContext &context, void **r_mapped_memory) +{ + VmaAllocator allocator = context.mem_allocator_get(); + VkResult result = vmaMapMemory(allocator, allocation_, r_mapped_memory); + return result == VK_SUCCESS; +} +void VKBuffer::unmap(VKContext &context) +{ + VmaAllocator allocator = context.mem_allocator_get(); + vmaUnmapMemory(allocator, allocation_); +} + +bool VKBuffer::free(VKContext &context) +{ + VmaAllocator allocator = context.mem_allocator_get(); + vmaDestroyBuffer(allocator, vk_buffer_, allocation_); + return true; +} + +} // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_buffer.hh b/source/blender/gpu/vulkan/vk_buffer.hh new file mode 100644 index 00000000000..cdaca903299 --- /dev/null +++ b/source/blender/gpu/vulkan/vk_buffer.hh @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2023 Blender Foundation. All rights reserved. */ + +/** \file + * \ingroup gpu + */ + +#pragma once + +#include "gpu_context_private.hh" +#include "vk_context.hh" + +#ifdef __APPLE__ +# include <MoltenVK/vk_mvk_moltenvk.h> +#else +# include <vulkan/vulkan.h> +#endif + +namespace blender::gpu { + +/** + * Class for handing vulkan buffers (allocation/updating/binding). + */ +class VKBuffer { + int64_t size_in_bytes_; + VkBuffer vk_buffer_ = VK_NULL_HANDLE; + VmaAllocation allocation_ = VK_NULL_HANDLE; + + public: + VKBuffer() = default; + virtual ~VKBuffer(); + + /** Has this buffer been allocated? */ + bool is_allocated(); + + bool create(VKContext &context, + int64_t size, + GPUUsageType usage, + VkBufferUsageFlagBits buffer_usage); + bool update(VKContext &context, const void *data); + bool free(VKContext &context); + bool map(VKContext &context, void **r_mapped_memory); + void unmap(VKContext &context); +}; +} // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_context.hh b/source/blender/gpu/vulkan/vk_context.hh index d516b459b20..13123c1b1e4 100644 --- a/source/blender/gpu/vulkan/vk_context.hh +++ b/source/blender/gpu/vulkan/vk_context.hh @@ -60,6 +60,11 @@ class VKContext : public Context { return device_; } + const uint32_t *queue_family_ptr_get() const + { + return &graphic_queue_familly_; + } + VmaAllocator mem_allocator_get() const { return mem_allocator_; diff --git a/source/blender/gpu/vulkan/vk_shader.cc b/source/blender/gpu/vulkan/vk_shader.cc index 5704b7309a8..67d60780b44 100644 --- a/source/blender/gpu/vulkan/vk_shader.cc +++ b/source/blender/gpu/vulkan/vk_shader.cc @@ -599,6 +599,12 @@ VKShader::~VKShader() vkDestroyShaderModule(device, compute_module_, nullptr); compute_module_ = VK_NULL_HANDLE; } + if (pipeline_layout_ != VK_NULL_HANDLE) { + vkDestroyPipelineLayout(device, pipeline_layout_, nullptr); + } + for (VkDescriptorSetLayout &layout : layouts_) { + vkDestroyDescriptorSetLayout(device, layout, nullptr); + } } void VKShader::build_shader_module(MutableSpan<const char *> sources, diff --git a/source/blender/gpu/vulkan/vk_storage_buffer.cc b/source/blender/gpu/vulkan/vk_storage_buffer.cc index 40c770fa1d2..ccc8f9cb19f 100644 --- a/source/blender/gpu/vulkan/vk_storage_buffer.cc +++ b/source/blender/gpu/vulkan/vk_storage_buffer.cc @@ -11,8 +11,18 @@ namespace blender::gpu { -void VKStorageBuffer::update(const void * /*data*/) +void VKStorageBuffer::update(const void *data) { + VKContext &context = *VKContext::get(); + if (!buffer_.is_allocated()) { + allocate(context); + } + buffer_.update(context, data); +} + +void VKStorageBuffer::allocate(VKContext &context) +{ + buffer_.create(context, size_in_bytes_, usage_, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); } void VKStorageBuffer::bind(int /*slot*/) @@ -35,8 +45,18 @@ void VKStorageBuffer::copy_sub(VertBuf * /*src*/, { } -void VKStorageBuffer::read(void * /*data*/) +void VKStorageBuffer::read(void *data) { + VKContext &context = *VKContext::get(); + if (!buffer_.is_allocated()) { + allocate(context); + } + + void *mapped_memory; + if (buffer_.map(context, &mapped_memory)) { + memcpy(data, mapped_memory, size_in_bytes_); + buffer_.unmap(context); + } } } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_storage_buffer.hh b/source/blender/gpu/vulkan/vk_storage_buffer.hh index ab3cb584ea0..ff553d6d261 100644 --- a/source/blender/gpu/vulkan/vk_storage_buffer.hh +++ b/source/blender/gpu/vulkan/vk_storage_buffer.hh @@ -11,11 +11,17 @@ #include "gpu_storage_buffer_private.hh" +#include "vk_buffer.hh" + namespace blender::gpu { class VKStorageBuffer : public StorageBuf { + GPUUsageType usage_; + VKBuffer buffer_; + public: - VKStorageBuffer(int size, const char *name) : StorageBuf(size, name) + VKStora @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs