mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[impeller] [vk] Implement device buffer support (flutter/engine#34961)
This commit is contained in:
parent
7d525ffed2
commit
e8019563a3
@ -9,17 +9,22 @@ _Pragma("GCC diagnostic ignored \"-Wthread-safety-analysis\"");
|
||||
|
||||
#define VMA_IMPLEMENTATION
|
||||
#include "impeller/renderer/backend/vulkan/allocator_vk.h"
|
||||
#include "impeller/renderer/backend/vulkan/device_buffer_vk.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
_Pragma("GCC diagnostic pop");
|
||||
|
||||
namespace impeller {
|
||||
|
||||
AllocatorVK::AllocatorVK(uint32_t vulkan_api_version,
|
||||
AllocatorVK::AllocatorVK(ContextVK& context,
|
||||
uint32_t vulkan_api_version,
|
||||
const vk::PhysicalDevice& physical_device,
|
||||
const vk::Device& logical_device,
|
||||
const vk::Instance& instance,
|
||||
PFN_vkGetInstanceProcAddr get_instance_proc_address,
|
||||
PFN_vkGetDeviceProcAddr get_device_proc_address) {
|
||||
PFN_vkGetDeviceProcAddr get_device_proc_address)
|
||||
: context_(context) {
|
||||
VmaVulkanFunctions proc_table = {};
|
||||
proc_table.vkGetInstanceProcAddr = get_instance_proc_address;
|
||||
proc_table.vkGetDeviceProcAddr = get_device_proc_address;
|
||||
@ -62,7 +67,39 @@ std::shared_ptr<Texture> AllocatorVK::CreateTexture(
|
||||
// |Allocator|
|
||||
std::shared_ptr<DeviceBuffer> AllocatorVK::CreateBuffer(StorageMode mode,
|
||||
size_t length) {
|
||||
FML_UNREACHABLE();
|
||||
// TODO (kaushikiska): consider optimizing the usage flags based on
|
||||
// StorageMode.
|
||||
auto buffer_create_info = static_cast<vk::BufferCreateInfo::NativeType>(
|
||||
vk::BufferCreateInfo()
|
||||
.setUsage(vk::BufferUsageFlagBits::eStorageBuffer |
|
||||
vk::BufferUsageFlagBits::eTransferSrc |
|
||||
vk::BufferUsageFlagBits::eTransferDst)
|
||||
.setSize(length)
|
||||
.setSharingMode(vk::SharingMode::eExclusive));
|
||||
|
||||
VmaAllocationCreateInfo allocCreateInfo = {};
|
||||
allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
|
||||
allocCreateInfo.flags =
|
||||
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
|
||||
VMA_ALLOCATION_CREATE_MAPPED_BIT;
|
||||
|
||||
VkBuffer buffer;
|
||||
VmaAllocation buffer_allocation;
|
||||
VmaAllocationInfo buffer_allocation_info;
|
||||
auto result = vk::Result{
|
||||
vmaCreateBuffer(allocator_, &buffer_create_info, &allocCreateInfo,
|
||||
&buffer, &buffer_allocation, &buffer_allocation_info)};
|
||||
|
||||
if (result != vk::Result::eSuccess) {
|
||||
VALIDATION_LOG << "Unable to allocate a device buffer";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto device_allocation = std::make_unique<DeviceBufferAllocationVK>(
|
||||
allocator_, buffer, buffer_allocation, buffer_allocation_info);
|
||||
|
||||
return std::make_shared<DeviceBufferVK>(length, mode, context_,
|
||||
std::move(device_allocation));
|
||||
}
|
||||
|
||||
} // namespace impeller
|
||||
|
||||
@ -6,8 +6,11 @@
|
||||
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "impeller/renderer/allocator.h"
|
||||
#include "impeller/renderer/backend/vulkan/context_vk.h"
|
||||
#include "impeller/renderer/backend/vulkan/vk.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace impeller {
|
||||
|
||||
class AllocatorVK final : public Allocator {
|
||||
@ -19,9 +22,11 @@ class AllocatorVK final : public Allocator {
|
||||
friend class ContextVK;
|
||||
|
||||
VmaAllocator allocator_ = {};
|
||||
ContextVK& context_;
|
||||
bool is_valid_ = false;
|
||||
|
||||
AllocatorVK(uint32_t vulkan_api_version,
|
||||
AllocatorVK(ContextVK& context,
|
||||
uint32_t vulkan_api_version,
|
||||
const vk::PhysicalDevice& physical_device,
|
||||
const vk::Device& logical_device,
|
||||
const vk::Instance& instance,
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#include "flutter/fml/build_config.h"
|
||||
#include "flutter/fml/trace_event.h"
|
||||
#include "impeller/base/validation.h"
|
||||
#include "impeller/renderer/backend/vulkan/allocator_vk.h"
|
||||
#include "impeller/renderer/backend/vulkan/capabilities_vk.h"
|
||||
#include "impeller/renderer/backend/vulkan/vk.h"
|
||||
|
||||
@ -336,6 +337,7 @@ ContextVK::ContextVK(
|
||||
}
|
||||
|
||||
auto allocator = std::shared_ptr<AllocatorVK>(new AllocatorVK(
|
||||
*this, //
|
||||
application_info.apiVersion, //
|
||||
physical_device.value(), //
|
||||
device.value.get(), //
|
||||
|
||||
@ -10,7 +10,6 @@
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "flutter/fml/mapping.h"
|
||||
#include "impeller/base/backend_cast.h"
|
||||
#include "impeller/renderer/backend/vulkan/allocator_vk.h"
|
||||
#include "impeller/renderer/backend/vulkan/pipeline_library_vk.h"
|
||||
#include "impeller/renderer/backend/vulkan/sampler_library_vk.h"
|
||||
#include "impeller/renderer/backend/vulkan/shader_library_vk.h"
|
||||
@ -34,12 +33,33 @@ class ContextVK final : public Context, public BackendCast<ContextVK, Context> {
|
||||
// |Context|
|
||||
bool IsValid() const override;
|
||||
|
||||
template <typename T>
|
||||
bool SetDebugName(T handle, std::string_view label) const {
|
||||
uint64_t handle_ptr =
|
||||
reinterpret_cast<uint64_t>(static_cast<typename T::NativeType>(handle));
|
||||
|
||||
std::string label_str = std::string(label);
|
||||
|
||||
auto ret = device_->setDebugUtilsObjectNameEXT(
|
||||
vk::DebugUtilsObjectNameInfoEXT()
|
||||
.setObjectType(T::objectType)
|
||||
.setObjectHandle(handle_ptr)
|
||||
.setPObjectName(label_str.c_str()));
|
||||
|
||||
if (ret != vk::Result::eSuccess) {
|
||||
VALIDATION_LOG << "unable to set debug name";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<fml::ConcurrentTaskRunner> worker_task_runner_;
|
||||
vk::UniqueInstance instance_;
|
||||
vk::UniqueDebugUtilsMessengerEXT debug_messenger_;
|
||||
vk::UniqueDevice device_;
|
||||
std::shared_ptr<AllocatorVK> allocator_;
|
||||
std::shared_ptr<Allocator> allocator_;
|
||||
std::shared_ptr<ShaderLibraryVK> shader_library_;
|
||||
std::shared_ptr<SamplerLibraryVK> sampler_library_;
|
||||
std::shared_ptr<PipelineLibraryVK> pipeline_library_;
|
||||
|
||||
@ -4,8 +4,78 @@
|
||||
|
||||
#include "impeller/renderer/backend/vulkan/device_buffer_vk.h"
|
||||
|
||||
#include "fml/logging.h"
|
||||
|
||||
namespace impeller {
|
||||
|
||||
//
|
||||
DeviceBufferAllocationVK::DeviceBufferAllocationVK(
|
||||
const VmaAllocator& allocator,
|
||||
VkBuffer buffer,
|
||||
VmaAllocation allocation,
|
||||
VmaAllocationInfo allocation_info)
|
||||
: allocator_(allocator),
|
||||
buffer_(buffer),
|
||||
allocation_(allocation),
|
||||
allocation_info_(allocation_info) {}
|
||||
|
||||
DeviceBufferAllocationVK::~DeviceBufferAllocationVK() {
|
||||
if (buffer_) {
|
||||
vmaDestroyBuffer(allocator_, buffer_, allocation_);
|
||||
}
|
||||
}
|
||||
|
||||
vk::Buffer DeviceBufferAllocationVK::GetBufferHandle() const {
|
||||
return buffer_;
|
||||
}
|
||||
|
||||
void* DeviceBufferAllocationVK::GetMapping() const {
|
||||
return allocation_info_.pMappedData;
|
||||
}
|
||||
|
||||
DeviceBufferVK::DeviceBufferVK(
|
||||
size_t size,
|
||||
StorageMode mode,
|
||||
ContextVK& context,
|
||||
std::unique_ptr<DeviceBufferAllocationVK> device_allocation)
|
||||
: DeviceBuffer(size, mode),
|
||||
context_(context),
|
||||
device_allocation_(std::move(device_allocation)) {}
|
||||
|
||||
DeviceBufferVK::~DeviceBufferVK() = default;
|
||||
|
||||
bool DeviceBufferVK::CopyHostBuffer(const uint8_t* source,
|
||||
Range source_range,
|
||||
size_t offset) {
|
||||
if (mode_ != StorageMode::kHostVisible) {
|
||||
// One of the storage modes where a transfer queue must be used.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (offset + source_range.length > size_) {
|
||||
// Out of bounds of this buffer.
|
||||
return false;
|
||||
}
|
||||
|
||||
auto dest = static_cast<uint8_t*>(device_allocation_->GetMapping());
|
||||
|
||||
if (!dest) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (source) {
|
||||
::memmove(dest + offset, source + source_range.offset, source_range.length);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeviceBufferVK::SetLabel(const std::string& label) {
|
||||
context_.SetDebugName(device_allocation_->GetBufferHandle(), label);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeviceBufferVK::SetLabel(const std::string& label, Range range) {
|
||||
return SetLabel(label);
|
||||
}
|
||||
|
||||
} // namespace impeller
|
||||
|
||||
@ -4,22 +4,53 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "impeller/base/backend_cast.h"
|
||||
#include "impeller/renderer/backend/vulkan/context_vk.h"
|
||||
#include "impeller/renderer/device_buffer.h"
|
||||
|
||||
namespace impeller {
|
||||
|
||||
class DeviceBufferAllocationVK {
|
||||
public:
|
||||
DeviceBufferAllocationVK(const VmaAllocator& allocator,
|
||||
VkBuffer buffer,
|
||||
VmaAllocation allocation,
|
||||
VmaAllocationInfo allocation_info);
|
||||
|
||||
~DeviceBufferAllocationVK();
|
||||
|
||||
vk::Buffer GetBufferHandle() const;
|
||||
|
||||
void* GetMapping() const;
|
||||
|
||||
private:
|
||||
const VmaAllocator& allocator_;
|
||||
vk::Buffer buffer_;
|
||||
VmaAllocation allocation_;
|
||||
VmaAllocationInfo allocation_info_;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(DeviceBufferAllocationVK);
|
||||
};
|
||||
|
||||
class DeviceBufferVK final : public DeviceBuffer,
|
||||
public BackendCast<DeviceBufferVK, DeviceBuffer> {
|
||||
public:
|
||||
DeviceBufferVK(size_t size,
|
||||
StorageMode mode,
|
||||
ContextVK& context,
|
||||
std::unique_ptr<DeviceBufferAllocationVK> device_allocation);
|
||||
|
||||
// |DeviceBuffer|
|
||||
~DeviceBufferVK() override;
|
||||
|
||||
private:
|
||||
friend class AllocatorVK;
|
||||
|
||||
DeviceBufferVK(size_t size, StorageMode mode);
|
||||
ContextVK& context_;
|
||||
std::unique_ptr<DeviceBufferAllocationVK> device_allocation_;
|
||||
|
||||
// |DeviceBuffer|
|
||||
bool CopyHostBuffer(const uint8_t* source,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user