mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-13 00:26:00 +00:00
Add CreateImage support to MemoryService
This CL introduces SupportsCreateImage and CreateImage to the external memory service API to provide different implementations for creating VkImages for different types of external image handles. While opaque FD and Zircon seem to share the same vkCreateImage implementation, dma-buf import will require the use of the VkImageDrmFormatModifierExplicitCreateInfoEXT [1] struct (among other differences) with vkCreateImage. [1] https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkImageDrmFormatModifierExplicitCreateInfoEXT.html BUG=chromium:996470 Change-Id: I3eb11f8877d4465f5fcdd4089d5fdd8acbc1da10 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/13781 Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Brian Ho <hob@chromium.org>
This commit is contained in:
parent
858f93b86f
commit
ae687f5b83
@ -615,7 +615,7 @@ namespace dawn_native { namespace vulkan {
|
||||
if (!mExternalSemaphoreService->Supported()) {
|
||||
return DAWN_VALIDATION_ERROR("External semaphore usage not supported");
|
||||
}
|
||||
if (!mExternalMemoryService->Supported(
|
||||
if (!mExternalMemoryService->SupportsImportMemory(
|
||||
VulkanImageFormat(textureDescriptor->format), VK_IMAGE_TYPE_2D,
|
||||
VK_IMAGE_TILING_OPTIMAL,
|
||||
VulkanImageUsage(textureDescriptor->usage,
|
||||
@ -683,7 +683,8 @@ namespace dawn_native { namespace vulkan {
|
||||
// if a failure happems.
|
||||
Texture* result = nullptr;
|
||||
// TODO(crbug.com/1026480): Consolidate this into a single CreateFromExternal call.
|
||||
if (ConsumedError(Texture::CreateFromExternal(this, descriptor, textureDescriptor),
|
||||
if (ConsumedError(Texture::CreateFromExternal(this, descriptor, textureDescriptor,
|
||||
mExternalMemoryService.get()),
|
||||
&result) ||
|
||||
ConsumedError(ImportExternalImage(descriptor, memoryHandle, result->GetHandle(),
|
||||
waitHandles, &signalSemaphore, &allocation,
|
||||
|
@ -200,22 +200,6 @@ namespace dawn_native { namespace vulkan {
|
||||
return {extent.width, extent.height, extent.depth};
|
||||
}
|
||||
|
||||
bool IsSampleCountSupported(const dawn_native::vulkan::Device* device,
|
||||
const VkImageCreateInfo& imageCreateInfo) {
|
||||
ASSERT(device);
|
||||
|
||||
VkPhysicalDevice physicalDevice = ToBackend(device->GetAdapter())->GetPhysicalDevice();
|
||||
VkImageFormatProperties properties;
|
||||
if (device->fn.GetPhysicalDeviceImageFormatProperties(
|
||||
physicalDevice, imageCreateInfo.format, imageCreateInfo.imageType,
|
||||
imageCreateInfo.tiling, imageCreateInfo.usage, imageCreateInfo.flags,
|
||||
&properties) != VK_SUCCESS) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
return properties.sampleCounts & imageCreateInfo.samples;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Converts Dawn texture format to Vulkan formats.
|
||||
@ -397,6 +381,22 @@ namespace dawn_native { namespace vulkan {
|
||||
return {};
|
||||
}
|
||||
|
||||
bool IsSampleCountSupported(const dawn_native::vulkan::Device* device,
|
||||
const VkImageCreateInfo& imageCreateInfo) {
|
||||
ASSERT(device);
|
||||
|
||||
VkPhysicalDevice physicalDevice = ToBackend(device->GetAdapter())->GetPhysicalDevice();
|
||||
VkImageFormatProperties properties;
|
||||
if (device->fn.GetPhysicalDeviceImageFormatProperties(
|
||||
physicalDevice, imageCreateInfo.format, imageCreateInfo.imageType,
|
||||
imageCreateInfo.tiling, imageCreateInfo.usage, imageCreateInfo.flags,
|
||||
&properties) != VK_SUCCESS) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
return properties.sampleCounts & imageCreateInfo.samples;
|
||||
}
|
||||
|
||||
// static
|
||||
ResultOrError<Texture*> Texture::Create(Device* device, const TextureDescriptor* descriptor) {
|
||||
std::unique_ptr<Texture> texture =
|
||||
@ -409,10 +409,11 @@ namespace dawn_native { namespace vulkan {
|
||||
ResultOrError<Texture*> Texture::CreateFromExternal(
|
||||
Device* device,
|
||||
const ExternalImageDescriptor* descriptor,
|
||||
const TextureDescriptor* textureDescriptor) {
|
||||
const TextureDescriptor* textureDescriptor,
|
||||
external_memory::Service* externalMemoryService) {
|
||||
std::unique_ptr<Texture> texture =
|
||||
std::make_unique<Texture>(device, textureDescriptor, TextureState::OwnedInternal);
|
||||
DAWN_TRY(texture->InitializeFromExternal(descriptor));
|
||||
DAWN_TRY(texture->InitializeFromExternal(descriptor, externalMemoryService));
|
||||
return texture.release();
|
||||
}
|
||||
|
||||
@ -481,38 +482,34 @@ namespace dawn_native { namespace vulkan {
|
||||
}
|
||||
|
||||
// Internally managed, but imported from external handle
|
||||
MaybeError Texture::InitializeFromExternal(const ExternalImageDescriptor* descriptor) {
|
||||
MaybeError Texture::InitializeFromExternal(const ExternalImageDescriptor* descriptor,
|
||||
external_memory::Service* externalMemoryService) {
|
||||
VkFormat format = VulkanImageFormat(GetFormat().format);
|
||||
if (!externalMemoryService->SupportsCreateImage(descriptor, format)) {
|
||||
return DAWN_VALIDATION_ERROR("Creating an image from external memory is not supported");
|
||||
}
|
||||
|
||||
mExternalState = ExternalState::PendingAcquire;
|
||||
Device* device = ToBackend(GetDevice());
|
||||
|
||||
VkImageCreateInfo createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
createInfo.pNext = nullptr;
|
||||
createInfo.flags = VK_IMAGE_CREATE_ALIAS_BIT_KHR;
|
||||
createInfo.imageType = VulkanImageType(GetDimension());
|
||||
createInfo.format = VulkanImageFormat(GetFormat().format);
|
||||
createInfo.extent = VulkanExtent3D(GetSize());
|
||||
createInfo.mipLevels = GetNumMipLevels();
|
||||
createInfo.arrayLayers = GetArrayLayers();
|
||||
createInfo.samples = VulkanSampleCount(GetSampleCount());
|
||||
createInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
createInfo.usage = VulkanImageUsage(GetUsage(), GetFormat());
|
||||
createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
createInfo.queueFamilyIndexCount = 0;
|
||||
createInfo.pQueueFamilyIndices = nullptr;
|
||||
createInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
||||
ASSERT(IsSampleCountSupported(device, createInfo));
|
||||
VkImageCreateInfo baseCreateInfo = {};
|
||||
baseCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
baseCreateInfo.pNext = nullptr;
|
||||
baseCreateInfo.imageType = VulkanImageType(GetDimension());
|
||||
baseCreateInfo.format = format;
|
||||
baseCreateInfo.extent = VulkanExtent3D(GetSize());
|
||||
baseCreateInfo.mipLevels = GetNumMipLevels();
|
||||
baseCreateInfo.arrayLayers = GetArrayLayers();
|
||||
baseCreateInfo.samples = VulkanSampleCount(GetSampleCount());
|
||||
baseCreateInfo.usage = VulkanImageUsage(GetUsage(), GetFormat());
|
||||
baseCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
baseCreateInfo.queueFamilyIndexCount = 0;
|
||||
baseCreateInfo.pQueueFamilyIndices = nullptr;
|
||||
|
||||
// We always set VK_IMAGE_USAGE_TRANSFER_DST_BIT unconditionally beause the Vulkan images
|
||||
// that are used in vkCmdClearColorImage() must have been created with this flag, which is
|
||||
// also required for the implementation of robust resource initialization.
|
||||
createInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
|
||||
DAWN_TRY(CheckVkSuccess(
|
||||
device->fn.CreateImage(device->GetVkDevice(), &createInfo, nullptr, &mHandle),
|
||||
"CreateImage"));
|
||||
baseCreateInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
|
||||
DAWN_TRY_ASSIGN(mHandle, externalMemoryService->CreateImage(descriptor, baseCreateInfo));
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "common/vulkan_platform.h"
|
||||
#include "dawn_native/ResourceMemoryAllocation.h"
|
||||
#include "dawn_native/vulkan/ExternalHandle.h"
|
||||
#include "dawn_native/vulkan/external_memory/MemoryService.h"
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
@ -34,6 +35,9 @@ namespace dawn_native { namespace vulkan {
|
||||
MaybeError ValidateVulkanImageCanBeWrapped(const DeviceBase* device,
|
||||
const TextureDescriptor* descriptor);
|
||||
|
||||
bool IsSampleCountSupported(const dawn_native::vulkan::Device* device,
|
||||
const VkImageCreateInfo& imageCreateInfo);
|
||||
|
||||
class Texture : public TextureBase {
|
||||
public:
|
||||
// Used to create a regular texture from a descriptor.
|
||||
@ -45,7 +49,8 @@ namespace dawn_native { namespace vulkan {
|
||||
static ResultOrError<Texture*> CreateFromExternal(
|
||||
Device* device,
|
||||
const ExternalImageDescriptor* descriptor,
|
||||
const TextureDescriptor* textureDescriptor);
|
||||
const TextureDescriptor* textureDescriptor,
|
||||
external_memory::Service* externalMemoryService);
|
||||
|
||||
Texture(Device* device, const TextureDescriptor* descriptor, VkImage nativeImage);
|
||||
~Texture();
|
||||
@ -76,7 +81,8 @@ namespace dawn_native { namespace vulkan {
|
||||
using TextureBase::TextureBase;
|
||||
MaybeError InitializeAsInternalTexture();
|
||||
|
||||
MaybeError InitializeFromExternal(const ExternalImageDescriptor* descriptor);
|
||||
MaybeError InitializeFromExternal(const ExternalImageDescriptor* descriptor,
|
||||
external_memory::Service* externalMemoryService);
|
||||
|
||||
void DestroyImpl() override;
|
||||
MaybeError ClearTexture(CommandRecordingContext* recordingContext,
|
||||
|
@ -36,13 +36,16 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||
explicit Service(Device* device);
|
||||
~Service();
|
||||
|
||||
// True if the device reports it supports this feature
|
||||
bool Supported(VkFormat format,
|
||||
// True if the device reports it supports importing external memory.
|
||||
bool SupportsImportMemory(VkFormat format,
|
||||
VkImageType type,
|
||||
VkImageTiling tiling,
|
||||
VkImageUsageFlags usage,
|
||||
VkImageCreateFlags flags);
|
||||
|
||||
// True if the device reports it supports creating VkImages from external memory.
|
||||
bool SupportsCreateImage(const ExternalImageDescriptor* descriptor, VkFormat format);
|
||||
|
||||
// Returns the parameters required for importing memory
|
||||
ResultOrError<MemoryImportParams> GetMemoryImportParams(
|
||||
const ExternalImageDescriptor* descriptor,
|
||||
@ -53,6 +56,10 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||
const MemoryImportParams& importParams,
|
||||
VkImage image);
|
||||
|
||||
// Create a VkImage for the given handle type
|
||||
ResultOrError<VkImage> CreateImage(const ExternalImageDescriptor* descriptor,
|
||||
const VkImageCreateInfo& baseCreateInfo);
|
||||
|
||||
private:
|
||||
Device* mDevice = nullptr;
|
||||
|
||||
|
@ -24,7 +24,7 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||
|
||||
Service::~Service() = default;
|
||||
|
||||
bool Service::Supported(VkFormat format,
|
||||
bool Service::SupportsImportMemory(VkFormat format,
|
||||
VkImageType type,
|
||||
VkImageTiling tiling,
|
||||
VkImageUsageFlags usage,
|
||||
@ -32,6 +32,10 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Service::SupportsCreateImage(const ExternalImageDescriptor* descriptor, VkFormat format) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ResultOrError<MemoryImportParams> Service::GetMemoryImportParams(
|
||||
const ExternalImageDescriptor* descriptor,
|
||||
VkImage image) {
|
||||
@ -44,4 +48,9 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||
return DAWN_UNIMPLEMENTED_ERROR("Using null memory service to interop inside Vulkan");
|
||||
}
|
||||
|
||||
ResultOrError<VkImage> Service::CreateImage(const ExternalImageDescriptor* descriptor,
|
||||
const VkImageCreateInfo& baseCreateInfo) {
|
||||
return DAWN_UNIMPLEMENTED_ERROR("Using null memory service to interop inside Vulkan");
|
||||
}
|
||||
|
||||
}}} // namespace dawn_native::vulkan::external_memory
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "dawn_native/vulkan/AdapterVk.h"
|
||||
#include "dawn_native/vulkan/BackendVk.h"
|
||||
#include "dawn_native/vulkan/DeviceVk.h"
|
||||
#include "dawn_native/vulkan/TextureVk.h"
|
||||
#include "dawn_native/vulkan/VulkanError.h"
|
||||
#include "dawn_native/vulkan/external_memory/MemoryService.h"
|
||||
|
||||
@ -33,7 +34,7 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||
|
||||
Service::~Service() = default;
|
||||
|
||||
bool Service::Supported(VkFormat format,
|
||||
bool Service::SupportsImportMemory(VkFormat format,
|
||||
VkImageType type,
|
||||
VkImageTiling tiling,
|
||||
VkImageUsageFlags usage,
|
||||
@ -80,6 +81,10 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||
!(memoryFlags & VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR);
|
||||
}
|
||||
|
||||
bool Service::SupportsCreateImage(const ExternalImageDescriptor* descriptor, VkFormat format) {
|
||||
return mSupported;
|
||||
}
|
||||
|
||||
ResultOrError<MemoryImportParams> Service::GetMemoryImportParams(
|
||||
const ExternalImageDescriptor* descriptor,
|
||||
VkImage image) {
|
||||
@ -113,4 +118,20 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||
return allocatedMemory;
|
||||
}
|
||||
|
||||
ResultOrError<VkImage> Service::CreateImage(const ExternalImageDescriptor* descriptor,
|
||||
const VkImageCreateInfo& baseCreateInfo) {
|
||||
VkImageCreateInfo createInfo = baseCreateInfo;
|
||||
createInfo.flags = VK_IMAGE_CREATE_ALIAS_BIT_KHR;
|
||||
createInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
createInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
||||
ASSERT(IsSampleCountSupported(mDevice, createInfo));
|
||||
|
||||
VkImage image;
|
||||
DAWN_TRY(CheckVkSuccess(
|
||||
mDevice->fn.CreateImage(mDevice->GetVkDevice(), &createInfo, nullptr, &image),
|
||||
"CreateImage"));
|
||||
return image;
|
||||
}
|
||||
|
||||
}}} // namespace dawn_native::vulkan::external_memory
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "dawn_native/vulkan/AdapterVk.h"
|
||||
#include "dawn_native/vulkan/BackendVk.h"
|
||||
#include "dawn_native/vulkan/DeviceVk.h"
|
||||
#include "dawn_native/vulkan/TextureVk.h"
|
||||
#include "dawn_native/vulkan/VulkanError.h"
|
||||
#include "dawn_native/vulkan/external_memory/MemoryService.h"
|
||||
|
||||
@ -33,7 +34,7 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||
|
||||
Service::~Service() = default;
|
||||
|
||||
bool Service::Supported(VkFormat format,
|
||||
bool Service::SupportsImportMemory(VkFormat format,
|
||||
VkImageType type,
|
||||
VkImageTiling tiling,
|
||||
VkImageUsageFlags usage,
|
||||
@ -80,6 +81,10 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||
!(memoryFlags & VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR);
|
||||
}
|
||||
|
||||
bool Service::SupportsCreateImage(const ExternalImageDescriptor* descriptor, VkFormat format) {
|
||||
return mSupported;
|
||||
}
|
||||
|
||||
ResultOrError<MemoryImportParams> Service::GetMemoryImportParams(
|
||||
const ExternalImageDescriptor* descriptor,
|
||||
VkImage image) {
|
||||
@ -115,4 +120,20 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||
return allocatedMemory;
|
||||
}
|
||||
|
||||
ResultOrError<VkImage> Service::CreateImage(const ExternalImageDescriptor* descriptor,
|
||||
const VkImageCreateInfo& baseCreateInfo) {
|
||||
VkImageCreateInfo createInfo = baseCreateInfo;
|
||||
createInfo.flags = VK_IMAGE_CREATE_ALIAS_BIT_KHR;
|
||||
createInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
createInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
||||
ASSERT(IsSampleCountSupported(mDevice, createInfo));
|
||||
|
||||
VkImage image;
|
||||
DAWN_TRY(CheckVkSuccess(
|
||||
mDevice->fn.CreateImage(mDevice->GetVkDevice(), &createInfo, nullptr, &image),
|
||||
"CreateImage"));
|
||||
return image;
|
||||
}
|
||||
|
||||
}}} // namespace dawn_native::vulkan::external_memory
|
||||
|
Loading…
x
Reference in New Issue
Block a user