mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-23 23:13:46 +00:00
Pass the old/new VkImageLayouts to Vulkan image import/export
Returning the layouts from an export operation and then using them in a subsequent import operation allows the import to preserve the texture contents. This fixes Vukan image wrapping on some AMD/NVIDIA devices. Bug: dawn:200 Change-Id: Icbb6e759856d410bb69724b9f439bc3088756d19 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/28380 Commit-Queue: Austin Eng <enga@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
parent
670858da9b
commit
0b29732cd8
@ -195,8 +195,14 @@ namespace dawn_native {
|
||||
return GetProcMapNamesForTestingInternal();
|
||||
}
|
||||
|
||||
ExternalImageDescriptor::ExternalImageDescriptor(ExternalImageDescriptorType type)
|
||||
: type(type) {
|
||||
// ExternalImageDescriptor
|
||||
|
||||
ExternalImageDescriptor::ExternalImageDescriptor(ExternalImageType type) : type(type) {
|
||||
}
|
||||
|
||||
// ExternalImageExportInfo
|
||||
|
||||
ExternalImageExportInfo::ExternalImageExportInfo(ExternalImageType type) : type(type) {
|
||||
}
|
||||
|
||||
} // namespace dawn_native
|
||||
|
@ -48,7 +48,7 @@ namespace dawn_native { namespace d3d12 {
|
||||
}
|
||||
|
||||
ExternalImageDescriptorDXGISharedHandle::ExternalImageDescriptorDXGISharedHandle()
|
||||
: ExternalImageDescriptor(ExternalImageDescriptorType::DXGISharedHandle) {
|
||||
: ExternalImageDescriptor(ExternalImageType::DXGISharedHandle) {
|
||||
}
|
||||
|
||||
uint64_t SetExternalMemoryReservation(WGPUDevice device,
|
||||
|
@ -396,7 +396,7 @@ namespace dawn_native { namespace d3d12 {
|
||||
AcquireRef(new Texture(device, textureDescriptor, TextureState::OwnedExternal));
|
||||
DAWN_TRY(dawnTexture->InitializeAsExternalTexture(textureDescriptor, sharedHandle,
|
||||
acquireMutexKey, isSwapChainTexture));
|
||||
dawnTexture->SetIsSubresourceContentInitialized(descriptor->isCleared,
|
||||
dawnTexture->SetIsSubresourceContentInitialized(descriptor->isInitialized,
|
||||
dawnTexture->GetAllSubresources());
|
||||
return std::move(dawnTexture);
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ namespace dawn_native { namespace metal {
|
||||
}
|
||||
|
||||
ExternalImageDescriptorIOSurface::ExternalImageDescriptorIOSurface()
|
||||
: ExternalImageDescriptor(ExternalImageDescriptorType::IOSurface) {
|
||||
: ExternalImageDescriptor(ExternalImageType::IOSurface) {
|
||||
}
|
||||
|
||||
WGPUTexture WrapIOSurface(WGPUDevice cDevice,
|
||||
|
@ -355,7 +355,7 @@ namespace dawn_native { namespace metal {
|
||||
plane:plane];
|
||||
[mtlDesc release];
|
||||
|
||||
SetIsSubresourceContentInitialized(descriptor->isCleared, GetAllSubresources());
|
||||
SetIsSubresourceContentInitialized(descriptor->isInitialized, GetAllSubresources());
|
||||
}
|
||||
|
||||
Texture::~Texture() {
|
||||
|
@ -658,7 +658,7 @@ namespace dawn_native { namespace vulkan {
|
||||
return {};
|
||||
}
|
||||
|
||||
MaybeError Device::ImportExternalImage(const ExternalImageDescriptor* descriptor,
|
||||
MaybeError Device::ImportExternalImage(const ExternalImageDescriptorVk* descriptor,
|
||||
ExternalMemoryHandle memoryHandle,
|
||||
VkImage image,
|
||||
const std::vector<ExternalSemaphoreHandle>& waitHandles,
|
||||
@ -702,22 +702,35 @@ namespace dawn_native { namespace vulkan {
|
||||
return {};
|
||||
}
|
||||
|
||||
MaybeError Device::SignalAndExportExternalTexture(Texture* texture,
|
||||
ExternalSemaphoreHandle* outHandle) {
|
||||
DAWN_TRY(ValidateObject(texture));
|
||||
bool Device::SignalAndExportExternalTexture(
|
||||
Texture* texture,
|
||||
VkImageLayout desiredLayout,
|
||||
ExternalImageExportInfoVk* info,
|
||||
std::vector<ExternalSemaphoreHandle>* semaphoreHandles) {
|
||||
return !ConsumedError([&]() -> MaybeError {
|
||||
DAWN_TRY(ValidateObject(texture));
|
||||
|
||||
VkSemaphore outSignalSemaphore;
|
||||
DAWN_TRY(texture->SignalAndDestroy(&outSignalSemaphore));
|
||||
VkSemaphore signalSemaphore;
|
||||
VkImageLayout releasedOldLayout;
|
||||
VkImageLayout releasedNewLayout;
|
||||
DAWN_TRY(texture->ExportExternalTexture(desiredLayout, &signalSemaphore,
|
||||
&releasedOldLayout, &releasedNewLayout));
|
||||
|
||||
// This has to happen right after SignalAndDestroy, since the semaphore will be
|
||||
// deleted when the fenced deleter runs after the queue submission
|
||||
DAWN_TRY_ASSIGN(*outHandle, mExternalSemaphoreService->ExportSemaphore(outSignalSemaphore));
|
||||
ExternalSemaphoreHandle semaphoreHandle;
|
||||
DAWN_TRY_ASSIGN(semaphoreHandle,
|
||||
mExternalSemaphoreService->ExportSemaphore(signalSemaphore));
|
||||
semaphoreHandles->push_back(semaphoreHandle);
|
||||
info->releasedOldLayout = releasedOldLayout;
|
||||
info->releasedNewLayout = releasedNewLayout;
|
||||
info->isInitialized =
|
||||
texture->IsSubresourceContentInitialized(texture->GetAllSubresources());
|
||||
|
||||
return {};
|
||||
return {};
|
||||
}());
|
||||
}
|
||||
|
||||
TextureBase* Device::CreateTextureWrappingVulkanImage(
|
||||
const ExternalImageDescriptor* descriptor,
|
||||
const ExternalImageDescriptorVk* descriptor,
|
||||
ExternalMemoryHandle memoryHandle,
|
||||
const std::vector<ExternalSemaphoreHandle>& waitHandles) {
|
||||
const TextureDescriptor* textureDescriptor =
|
||||
|
@ -69,12 +69,13 @@ namespace dawn_native { namespace vulkan {
|
||||
// Dawn Native API
|
||||
|
||||
TextureBase* CreateTextureWrappingVulkanImage(
|
||||
const ExternalImageDescriptor* descriptor,
|
||||
const ExternalImageDescriptorVk* descriptor,
|
||||
ExternalMemoryHandle memoryHandle,
|
||||
const std::vector<ExternalSemaphoreHandle>& waitHandles);
|
||||
|
||||
MaybeError SignalAndExportExternalTexture(Texture* texture,
|
||||
ExternalSemaphoreHandle* outHandle);
|
||||
bool SignalAndExportExternalTexture(Texture* texture,
|
||||
VkImageLayout desiredLayout,
|
||||
ExternalImageExportInfoVk* info,
|
||||
std::vector<ExternalSemaphoreHandle>* semaphoreHandle);
|
||||
|
||||
// Dawn API
|
||||
CommandBufferBase* CreateCommandBuffer(CommandEncoder* encoder,
|
||||
@ -192,7 +193,7 @@ namespace dawn_native { namespace vulkan {
|
||||
// There is always a valid recording context stored in mRecordingContext
|
||||
CommandRecordingContext mRecordingContext;
|
||||
|
||||
MaybeError ImportExternalImage(const ExternalImageDescriptor* descriptor,
|
||||
MaybeError ImportExternalImage(const ExternalImageDescriptorVk* descriptor,
|
||||
ExternalMemoryHandle memoryHandle,
|
||||
VkImage image,
|
||||
const std::vector<ExternalSemaphoreHandle>& waitHandles,
|
||||
@ -203,4 +204,4 @@ namespace dawn_native { namespace vulkan {
|
||||
|
||||
}} // namespace dawn_native::vulkan
|
||||
|
||||
#endif // DAWNNATIVE_VULKAN_DEVICEVK_H_
|
||||
#endif // DAWNNATIVE_VULKAN_DEVICEVK_H_
|
||||
|
@ -462,7 +462,7 @@ namespace dawn_native { namespace vulkan {
|
||||
// static
|
||||
ResultOrError<Texture*> Texture::CreateFromExternal(
|
||||
Device* device,
|
||||
const ExternalImageDescriptor* descriptor,
|
||||
const ExternalImageDescriptorVk* descriptor,
|
||||
const TextureDescriptor* textureDescriptor,
|
||||
external_memory::Service* externalMemoryService) {
|
||||
Ref<Texture> texture =
|
||||
@ -537,7 +537,7 @@ namespace dawn_native { namespace vulkan {
|
||||
}
|
||||
|
||||
// Internally managed, but imported from external handle
|
||||
MaybeError Texture::InitializeFromExternal(const ExternalImageDescriptor* descriptor,
|
||||
MaybeError Texture::InitializeFromExternal(const ExternalImageDescriptorVk* descriptor,
|
||||
external_memory::Service* externalMemoryService) {
|
||||
VkFormat format = VulkanImageFormat(ToBackend(GetDevice()), GetFormat().format);
|
||||
VkImageUsageFlags usage = VulkanImageUsage(GetUsage(), GetFormat());
|
||||
@ -547,6 +547,9 @@ namespace dawn_native { namespace vulkan {
|
||||
|
||||
mExternalState = ExternalState::PendingAcquire;
|
||||
|
||||
mPendingAcquireOldLayout = descriptor->releasedOldLayout;
|
||||
mPendingAcquireNewLayout = descriptor->releasedNewLayout;
|
||||
|
||||
VkImageCreateInfo baseCreateInfo = {};
|
||||
FillVulkanCreateInfoSizesAndType(*this, &baseCreateInfo);
|
||||
|
||||
@ -571,7 +574,7 @@ namespace dawn_native { namespace vulkan {
|
||||
mHandle = nativeImage;
|
||||
}
|
||||
|
||||
MaybeError Texture::BindExternalMemory(const ExternalImageDescriptor* descriptor,
|
||||
MaybeError Texture::BindExternalMemory(const ExternalImageDescriptorVk* descriptor,
|
||||
VkSemaphore signalSemaphore,
|
||||
VkDeviceMemory externalMemoryAllocation,
|
||||
std::vector<VkSemaphore> waitSemaphores) {
|
||||
@ -580,8 +583,8 @@ namespace dawn_native { namespace vulkan {
|
||||
device->fn.BindImageMemory(device->GetVkDevice(), mHandle, externalMemoryAllocation, 0),
|
||||
"BindImageMemory (external)"));
|
||||
|
||||
// Don't clear imported texture if already cleared
|
||||
if (descriptor->isCleared) {
|
||||
// Don't clear imported texture if already initialized
|
||||
if (descriptor->isInitialized) {
|
||||
SetIsSubresourceContentInitialized(true, GetAllSubresources());
|
||||
}
|
||||
|
||||
@ -592,7 +595,10 @@ namespace dawn_native { namespace vulkan {
|
||||
return {};
|
||||
}
|
||||
|
||||
MaybeError Texture::SignalAndDestroy(VkSemaphore* outSignalSemaphore) {
|
||||
MaybeError Texture::ExportExternalTexture(VkImageLayout desiredLayout,
|
||||
VkSemaphore* signalSemaphore,
|
||||
VkImageLayout* releasedOldLayout,
|
||||
VkImageLayout* releasedNewLayout) {
|
||||
Device* device = ToBackend(GetDevice());
|
||||
|
||||
if (mExternalState == ExternalState::Released) {
|
||||
@ -605,17 +611,60 @@ namespace dawn_native { namespace vulkan {
|
||||
}
|
||||
|
||||
ASSERT(mSignalSemaphore != VK_NULL_HANDLE);
|
||||
ASSERT(GetNumMipLevels() == 1 && GetArrayLayers() == 1);
|
||||
|
||||
// Release the texture
|
||||
mExternalState = ExternalState::PendingRelease;
|
||||
TransitionFullUsage(device->GetPendingRecordingContext(), wgpu::TextureUsage::None);
|
||||
mExternalState = ExternalState::Released;
|
||||
|
||||
wgpu::TextureUsage usage = mSubresourceLastUsages[0];
|
||||
|
||||
VkImageMemoryBarrier barrier;
|
||||
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
barrier.pNext = nullptr;
|
||||
barrier.image = GetHandle();
|
||||
barrier.subresourceRange.aspectMask = VulkanAspectMask(GetFormat().aspects);
|
||||
barrier.subresourceRange.baseMipLevel = 0;
|
||||
barrier.subresourceRange.levelCount = 1;
|
||||
barrier.subresourceRange.baseArrayLayer = 0;
|
||||
barrier.subresourceRange.layerCount = 1;
|
||||
|
||||
barrier.srcAccessMask = VulkanAccessFlags(usage, GetFormat());
|
||||
barrier.dstAccessMask = 0; // The barrier must be paired with another barrier that will
|
||||
// specify the dst access mask on the importing queue.
|
||||
|
||||
barrier.oldLayout = VulkanImageLayout(usage, GetFormat());
|
||||
if (desiredLayout == VK_IMAGE_LAYOUT_UNDEFINED) {
|
||||
// VK_IMAGE_LAYOUT_UNDEFINED is invalid here. We use it as a
|
||||
// special value to indicate no layout transition should be done.
|
||||
barrier.newLayout = barrier.oldLayout;
|
||||
} else {
|
||||
barrier.newLayout = desiredLayout;
|
||||
}
|
||||
|
||||
barrier.srcQueueFamilyIndex = device->GetGraphicsQueueFamily();
|
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_EXTERNAL_KHR;
|
||||
|
||||
VkPipelineStageFlags srcStages = VulkanPipelineStage(usage, GetFormat());
|
||||
VkPipelineStageFlags dstStages =
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; // We don't know when the importing queue will need
|
||||
// the texture, so pass
|
||||
// VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT to ensure
|
||||
// the barrier happens-before any usage in the
|
||||
// importing queue.
|
||||
|
||||
CommandRecordingContext* recordingContext = device->GetPendingRecordingContext();
|
||||
device->fn.CmdPipelineBarrier(recordingContext->commandBuffer, srcStages, dstStages, 0, 0,
|
||||
nullptr, 0, nullptr, 1, &barrier);
|
||||
|
||||
// Queue submit to signal we are done with the texture
|
||||
device->GetPendingRecordingContext()->signalSemaphores.push_back(mSignalSemaphore);
|
||||
recordingContext->signalSemaphores.push_back(mSignalSemaphore);
|
||||
DAWN_TRY(device->SubmitPendingCommands());
|
||||
|
||||
// Write out the signal semaphore
|
||||
*outSignalSemaphore = mSignalSemaphore;
|
||||
// Write out the layouts and signal semaphore
|
||||
*releasedOldLayout = barrier.oldLayout;
|
||||
*releasedNewLayout = barrier.newLayout;
|
||||
*signalSemaphore = mSignalSemaphore;
|
||||
|
||||
mSignalSemaphore = VK_NULL_HANDLE;
|
||||
|
||||
// Destroy the texture so it can't be used again
|
||||
@ -688,26 +737,58 @@ namespace dawn_native { namespace vulkan {
|
||||
SubresourceRange::SingleMipAndLayer(0, 0, GetFormat().aspects)));
|
||||
}
|
||||
|
||||
VkImageMemoryBarrier* barrier = &(*barriers)[transitionBarrierStart];
|
||||
// Transfer texture from external queue to graphics queue
|
||||
(*barriers)[transitionBarrierStart].srcQueueFamilyIndex = VK_QUEUE_FAMILY_EXTERNAL_KHR;
|
||||
(*barriers)[transitionBarrierStart].dstQueueFamilyIndex =
|
||||
ToBackend(GetDevice())->GetGraphicsQueueFamily();
|
||||
// Don't override oldLayout to leave it as VK_IMAGE_LAYOUT_UNDEFINED
|
||||
// TODO(http://crbug.com/dawn/200)
|
||||
mExternalState = ExternalState::Acquired;
|
||||
} else if (mExternalState == ExternalState::PendingRelease) {
|
||||
if (barriers->size() == transitionBarrierStart) {
|
||||
barriers->push_back(BuildMemoryBarrier(
|
||||
GetFormat(), mHandle, wgpu::TextureUsage::None, wgpu::TextureUsage::None,
|
||||
SubresourceRange::SingleMipAndLayer(0, 0, GetFormat().aspects)));
|
||||
barrier->srcQueueFamilyIndex = VK_QUEUE_FAMILY_EXTERNAL_KHR;
|
||||
barrier->dstQueueFamilyIndex = ToBackend(GetDevice())->GetGraphicsQueueFamily();
|
||||
|
||||
// srcAccessMask means nothing when importing. Queue transfers require a barrier on
|
||||
// both the importing and exporting queues. The exporting queue should have specified
|
||||
// this.
|
||||
barrier->srcAccessMask = 0;
|
||||
|
||||
// This should be the first barrier after import.
|
||||
ASSERT(barrier->oldLayout == VK_IMAGE_LAYOUT_UNDEFINED);
|
||||
|
||||
// Save the desired layout. We may need to transition through an intermediate
|
||||
// |mPendingAcquireLayout| first.
|
||||
VkImageLayout desiredLayout = barrier->newLayout;
|
||||
|
||||
bool isInitialized = IsSubresourceContentInitialized(GetAllSubresources());
|
||||
|
||||
// We don't care about the pending old layout if the texture is uninitialized. The
|
||||
// driver is free to discard it. Likewise, we don't care about the pending new layout if
|
||||
// the texture is uninitialized. We can skip the layout transition.
|
||||
if (!isInitialized) {
|
||||
barrier->oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
barrier->newLayout = desiredLayout;
|
||||
} else {
|
||||
barrier->oldLayout = mPendingAcquireOldLayout;
|
||||
barrier->newLayout = mPendingAcquireNewLayout;
|
||||
}
|
||||
|
||||
// Transfer texture from graphics queue to external queue
|
||||
(*barriers)[transitionBarrierStart].srcQueueFamilyIndex =
|
||||
ToBackend(GetDevice())->GetGraphicsQueueFamily();
|
||||
(*barriers)[transitionBarrierStart].dstQueueFamilyIndex = VK_QUEUE_FAMILY_EXTERNAL_KHR;
|
||||
(*barriers)[transitionBarrierStart].newLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
mExternalState = ExternalState::Released;
|
||||
// If these are unequal, we need an another barrier to transition the layout.
|
||||
if (barrier->newLayout != desiredLayout) {
|
||||
VkImageMemoryBarrier layoutBarrier;
|
||||
layoutBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
layoutBarrier.pNext = nullptr;
|
||||
layoutBarrier.image = GetHandle();
|
||||
layoutBarrier.subresourceRange = barrier->subresourceRange;
|
||||
|
||||
// Transition from the acquired new layout to the desired layout.
|
||||
layoutBarrier.oldLayout = barrier->newLayout;
|
||||
layoutBarrier.newLayout = desiredLayout;
|
||||
|
||||
// We already transitioned these.
|
||||
layoutBarrier.srcAccessMask = 0;
|
||||
layoutBarrier.dstAccessMask = 0;
|
||||
layoutBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
layoutBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
|
||||
barriers->push_back(layoutBarrier);
|
||||
}
|
||||
|
||||
mExternalState = ExternalState::Acquired;
|
||||
}
|
||||
|
||||
mLastExternalState = mExternalState;
|
||||
|
@ -49,7 +49,7 @@ namespace dawn_native { namespace vulkan {
|
||||
// image must be bound via Texture::BindExternalMemory.
|
||||
static ResultOrError<Texture*> CreateFromExternal(
|
||||
Device* device,
|
||||
const ExternalImageDescriptor* descriptor,
|
||||
const ExternalImageDescriptorVk* descriptor,
|
||||
const TextureDescriptor* textureDescriptor,
|
||||
external_memory::Service* externalMemoryService);
|
||||
|
||||
@ -84,20 +84,24 @@ namespace dawn_native { namespace vulkan {
|
||||
void EnsureSubresourceContentInitialized(CommandRecordingContext* recordingContext,
|
||||
const SubresourceRange& range);
|
||||
|
||||
MaybeError SignalAndDestroy(VkSemaphore* outSignalSemaphore);
|
||||
// Binds externally allocated memory to the VkImage and on success, takes ownership of
|
||||
// semaphores.
|
||||
MaybeError BindExternalMemory(const ExternalImageDescriptor* descriptor,
|
||||
MaybeError BindExternalMemory(const ExternalImageDescriptorVk* descriptor,
|
||||
VkSemaphore signalSemaphore,
|
||||
VkDeviceMemory externalMemoryAllocation,
|
||||
std::vector<VkSemaphore> waitSemaphores);
|
||||
|
||||
MaybeError ExportExternalTexture(VkImageLayout desiredLayout,
|
||||
VkSemaphore* signalSemaphore,
|
||||
VkImageLayout* releasedOldLayout,
|
||||
VkImageLayout* releasedNewLayout);
|
||||
|
||||
private:
|
||||
~Texture() override;
|
||||
using TextureBase::TextureBase;
|
||||
|
||||
MaybeError InitializeAsInternalTexture();
|
||||
MaybeError InitializeFromExternal(const ExternalImageDescriptor* descriptor,
|
||||
MaybeError InitializeFromExternal(const ExternalImageDescriptorVk* descriptor,
|
||||
external_memory::Service* externalMemoryService);
|
||||
void InitializeForSwapChain(VkImage nativeImage);
|
||||
|
||||
@ -119,12 +123,14 @@ namespace dawn_native { namespace vulkan {
|
||||
InternalOnly,
|
||||
PendingAcquire,
|
||||
Acquired,
|
||||
PendingRelease,
|
||||
Released
|
||||
};
|
||||
ExternalState mExternalState = ExternalState::InternalOnly;
|
||||
ExternalState mLastExternalState = ExternalState::InternalOnly;
|
||||
|
||||
VkImageLayout mPendingAcquireOldLayout;
|
||||
VkImageLayout mPendingAcquireNewLayout;
|
||||
|
||||
VkSemaphore mSignalSemaphore = VK_NULL_HANDLE;
|
||||
std::vector<VkSemaphore> mWaitRequirements;
|
||||
|
||||
|
@ -59,51 +59,75 @@ namespace dawn_native { namespace vulkan {
|
||||
return static_cast<WGPUTextureFormat>(impl->GetPreferredFormat());
|
||||
}
|
||||
|
||||
#ifdef DAWN_PLATFORM_LINUX
|
||||
ExternalImageDescriptorFD::ExternalImageDescriptorFD(ExternalImageDescriptorType descType)
|
||||
: ExternalImageDescriptor(descType) {
|
||||
}
|
||||
|
||||
#if defined(DAWN_PLATFORM_LINUX)
|
||||
ExternalImageDescriptorOpaqueFD::ExternalImageDescriptorOpaqueFD()
|
||||
: ExternalImageDescriptorFD(ExternalImageDescriptorType::OpaqueFD) {
|
||||
: ExternalImageDescriptorFD(ExternalImageType::OpaqueFD) {
|
||||
}
|
||||
|
||||
ExternalImageDescriptorDmaBuf::ExternalImageDescriptorDmaBuf()
|
||||
: ExternalImageDescriptorFD(ExternalImageDescriptorType::DmaBuf) {
|
||||
: ExternalImageDescriptorFD(ExternalImageType::DmaBuf) {
|
||||
}
|
||||
|
||||
ExternalImageExportInfoOpaqueFD::ExternalImageExportInfoOpaqueFD()
|
||||
: ExternalImageExportInfoFD(ExternalImageType::OpaqueFD) {
|
||||
}
|
||||
|
||||
ExternalImageExportInfoDmaBuf::ExternalImageExportInfoDmaBuf()
|
||||
: ExternalImageExportInfoFD(ExternalImageType::DmaBuf) {
|
||||
}
|
||||
|
||||
int ExportSignalSemaphoreOpaqueFD(WGPUDevice cDevice, WGPUTexture cTexture) {
|
||||
// Doesn't actually matter if we use OpaqueFD or DmaBuf since these paths are the same right
|
||||
// now. This function will be removed.
|
||||
Device* device = reinterpret_cast<Device*>(cDevice);
|
||||
Texture* texture = reinterpret_cast<Texture*>(cTexture);
|
||||
|
||||
if (!texture) {
|
||||
device->EmitDeprecationWarning(
|
||||
"ExportSignalSemaphoreOpaqueFD is deprecated. Please use ExportVulkanImage instead.");
|
||||
ExternalImageExportInfoOpaqueFD info;
|
||||
if (!ExportVulkanImage(cTexture, VK_IMAGE_LAYOUT_GENERAL, &info)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ExternalSemaphoreHandle outHandle;
|
||||
if (device->ConsumedError(device->SignalAndExportExternalTexture(texture, &outHandle))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return outHandle;
|
||||
return info.semaphoreHandles[0];
|
||||
}
|
||||
#endif // DAWN_PLATFORM_LINUX
|
||||
|
||||
WGPUTexture WrapVulkanImage(WGPUDevice cDevice, const ExternalImageDescriptor* descriptor) {
|
||||
Device* device = reinterpret_cast<Device*>(cDevice);
|
||||
|
||||
WGPUTexture WrapVulkanImage(WGPUDevice cDevice, const ExternalImageDescriptorVk* descriptor) {
|
||||
switch (descriptor->type) {
|
||||
case ExternalImageDescriptorType::OpaqueFD:
|
||||
case ExternalImageDescriptorType::DmaBuf: {
|
||||
#if defined(DAWN_PLATFORM_LINUX)
|
||||
case ExternalImageType::OpaqueFD:
|
||||
case ExternalImageType::DmaBuf: {
|
||||
const ExternalImageDescriptorFD* fdDescriptor =
|
||||
static_cast<const ExternalImageDescriptorFD*>(descriptor);
|
||||
Device* device = reinterpret_cast<Device*>(cDevice);
|
||||
TextureBase* texture = device->CreateTextureWrappingVulkanImage(
|
||||
descriptor, fdDescriptor->memoryFD, fdDescriptor->waitFDs);
|
||||
fdDescriptor, fdDescriptor->memoryFD, fdDescriptor->waitFDs);
|
||||
return reinterpret_cast<WGPUTexture>(texture);
|
||||
}
|
||||
#endif // DAWN_PLATFORM_LINUX
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool ExportVulkanImage(WGPUTexture cTexture,
|
||||
VkImageLayout desiredLayout,
|
||||
ExternalImageExportInfoVk* info) {
|
||||
if (cTexture == nullptr) {
|
||||
return false;
|
||||
}
|
||||
switch (info->type) {
|
||||
#if defined(DAWN_PLATFORM_LINUX)
|
||||
case ExternalImageType::OpaqueFD:
|
||||
case ExternalImageType::DmaBuf: {
|
||||
Texture* texture = reinterpret_cast<Texture*>(cTexture);
|
||||
Device* device = ToBackend(texture->GetDevice());
|
||||
ExternalImageExportInfoFD* fdInfo = static_cast<ExternalImageExportInfoFD*>(info);
|
||||
return device->SignalAndExportExternalTexture(texture, desiredLayout, fdInfo,
|
||||
&fdInfo->semaphoreHandles);
|
||||
}
|
||||
#endif // DAWN_PLATFORM_LINUX
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}} // namespace dawn_native::vulkan
|
||||
|
@ -83,7 +83,7 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||
if (!mSupported) {
|
||||
return false;
|
||||
}
|
||||
if (descriptor->type != ExternalImageDescriptorType::DmaBuf) {
|
||||
if (descriptor->type != ExternalImageType::DmaBuf) {
|
||||
return false;
|
||||
}
|
||||
const ExternalImageDescriptorDmaBuf* dmaBufDescriptor =
|
||||
@ -150,7 +150,7 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||
ResultOrError<MemoryImportParams> Service::GetMemoryImportParams(
|
||||
const ExternalImageDescriptor* descriptor,
|
||||
VkImage image) {
|
||||
if (descriptor->type != ExternalImageDescriptorType::DmaBuf) {
|
||||
if (descriptor->type != ExternalImageType::DmaBuf) {
|
||||
return DAWN_VALIDATION_ERROR("ExternalImageDescriptor is not a dma-buf descriptor");
|
||||
}
|
||||
const ExternalImageDescriptorDmaBuf* dmaBufDescriptor =
|
||||
@ -216,7 +216,7 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||
|
||||
ResultOrError<VkImage> Service::CreateImage(const ExternalImageDescriptor* descriptor,
|
||||
const VkImageCreateInfo& baseCreateInfo) {
|
||||
if (descriptor->type != ExternalImageDescriptorType::DmaBuf) {
|
||||
if (descriptor->type != ExternalImageType::DmaBuf) {
|
||||
return DAWN_VALIDATION_ERROR("ExternalImageDescriptor is not a dma-buf descriptor");
|
||||
}
|
||||
const ExternalImageDescriptorDmaBuf* dmaBufDescriptor =
|
||||
|
@ -71,8 +71,7 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||
// TODO(http://crbug.com/dawn/206): Investigate dedicated only images
|
||||
VkFlags memoryFlags =
|
||||
externalFormatProperties.externalMemoryProperties.externalMemoryFeatures;
|
||||
return (memoryFlags & VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR) &&
|
||||
!(memoryFlags & VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR);
|
||||
return (memoryFlags & VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR) != 0;
|
||||
}
|
||||
|
||||
bool Service::SupportsCreateImage(const ExternalImageDescriptor* descriptor,
|
||||
@ -84,7 +83,7 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||
ResultOrError<MemoryImportParams> Service::GetMemoryImportParams(
|
||||
const ExternalImageDescriptor* descriptor,
|
||||
VkImage image) {
|
||||
if (descriptor->type != ExternalImageDescriptorType::OpaqueFD) {
|
||||
if (descriptor->type != ExternalImageType::OpaqueFD) {
|
||||
return DAWN_VALIDATION_ERROR("ExternalImageDescriptor is not an OpaqueFD descriptor");
|
||||
}
|
||||
const ExternalImageDescriptorOpaqueFD* opaqueFDDescriptor =
|
||||
|
@ -71,8 +71,7 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||
// TODO(http://crbug.com/dawn/206): Investigate dedicated only images
|
||||
VkFlags memoryFlags =
|
||||
externalFormatProperties.externalMemoryProperties.externalMemoryFeatures;
|
||||
return (memoryFlags & VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR) &&
|
||||
!(memoryFlags & VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR);
|
||||
return (memoryFlags & VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR) != 0;
|
||||
}
|
||||
|
||||
bool Service::SupportsCreateImage(const ExternalImageDescriptor* descriptor,
|
||||
@ -84,7 +83,7 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||
ResultOrError<MemoryImportParams> Service::GetMemoryImportParams(
|
||||
const ExternalImageDescriptor* descriptor,
|
||||
VkImage image) {
|
||||
if (descriptor->type != ExternalImageDescriptorType::OpaqueFD) {
|
||||
if (descriptor->type != ExternalImageType::OpaqueFD) {
|
||||
return DAWN_VALIDATION_ERROR("ExternalImageDescriptor is not an OpaqueFD descriptor");
|
||||
}
|
||||
const ExternalImageDescriptorOpaqueFD* opaqueFDDescriptor =
|
||||
|
@ -200,8 +200,8 @@ namespace dawn_native {
|
||||
DAWN_NATIVE_EXPORT uint64_t AcquireErrorInjectorCallCount();
|
||||
DAWN_NATIVE_EXPORT void InjectErrorAt(uint64_t index);
|
||||
|
||||
// The different types of ExternalImageDescriptors
|
||||
enum ExternalImageDescriptorType {
|
||||
// The different types of external images
|
||||
enum ExternalImageType {
|
||||
OpaqueFD,
|
||||
DmaBuf,
|
||||
IOSurface,
|
||||
@ -211,13 +211,26 @@ namespace dawn_native {
|
||||
// Common properties of external images
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageDescriptor {
|
||||
public:
|
||||
const ExternalImageDescriptorType type;
|
||||
const ExternalImageType type;
|
||||
const WGPUTextureDescriptor* cTextureDescriptor; // Must match image creation params
|
||||
bool isCleared; // Sets whether the texture will be cleared before use
|
||||
union {
|
||||
bool isInitialized; // Whether the texture is initialized on import
|
||||
bool isCleared; // DEPRECATED: Sets whether the texture will be cleared before use
|
||||
};
|
||||
|
||||
protected:
|
||||
ExternalImageDescriptor(ExternalImageDescriptorType type);
|
||||
ExternalImageDescriptor(ExternalImageType type);
|
||||
};
|
||||
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageExportInfo {
|
||||
public:
|
||||
const ExternalImageType type;
|
||||
bool isInitialized; // Whether the texture is initialized after export
|
||||
|
||||
protected:
|
||||
ExternalImageExportInfo(ExternalImageType type);
|
||||
};
|
||||
|
||||
} // namespace dawn_native
|
||||
|
||||
#endif // DAWNNATIVE_DAWNNATIVE_H_
|
||||
|
@ -33,19 +33,49 @@ namespace dawn_native { namespace vulkan {
|
||||
DAWN_NATIVE_EXPORT WGPUTextureFormat
|
||||
GetNativeSwapChainPreferredFormat(const DawnSwapChainImplementation* swapChain);
|
||||
|
||||
// Can't use DAWN_PLATFORM_LINUX since header included in both dawn and chrome
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageDescriptorVk : ExternalImageDescriptor {
|
||||
public:
|
||||
// The following members may be ignored if |ExternalImageDescriptor::isInitialized| is false
|
||||
// since the import does not need to preserve texture contents.
|
||||
|
||||
// See https://www.khronos.org/registry/vulkan/specs/1.1/html/chap7.html. The acquire
|
||||
// operation old/new layouts must match exactly the layouts in the release operation. So
|
||||
// we may need to issue two barriers releasedOldLayout -> releasedNewLayout ->
|
||||
// cTextureDescriptor.usage if the new layout is not compatible with the desired usage.
|
||||
// The first barrier is the queue transfer, the second is the layout transition to our
|
||||
// desired usage.
|
||||
VkImageLayout releasedOldLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
VkImageLayout releasedNewLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
|
||||
protected:
|
||||
using ExternalImageDescriptor::ExternalImageDescriptor;
|
||||
};
|
||||
|
||||
struct ExternalImageExportInfoVk : ExternalImageExportInfo {
|
||||
public:
|
||||
// See comments in |ExternalImageDescriptorVk|
|
||||
// Contains the old/new layouts used in the queue release operation.
|
||||
VkImageLayout releasedOldLayout;
|
||||
VkImageLayout releasedNewLayout;
|
||||
|
||||
protected:
|
||||
using ExternalImageExportInfo::ExternalImageExportInfo;
|
||||
};
|
||||
|
||||
// Can't use DAWN_PLATFORM_LINUX since header included in both Dawn and Chrome
|
||||
#ifdef __linux__
|
||||
|
||||
// Common properties of external images represented by FDs. On successful import the file
|
||||
// descriptor's ownership is transferred to the Dawn implementation and they shouldn't be
|
||||
// used outside of Dawn again. TODO(enga): Also transfer ownership in the error case so the
|
||||
// caller can assume the FD is always consumed.
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageDescriptorFD : ExternalImageDescriptor {
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageDescriptorFD : ExternalImageDescriptorVk {
|
||||
public:
|
||||
int memoryFD; // A file descriptor from an export of the memory of the image
|
||||
std::vector<int> waitFDs; // File descriptors of semaphores which will be waited on
|
||||
|
||||
protected:
|
||||
ExternalImageDescriptorFD(ExternalImageDescriptorType type);
|
||||
using ExternalImageDescriptorVk::ExternalImageDescriptorVk;
|
||||
};
|
||||
|
||||
// Descriptor for opaque file descriptor image import
|
||||
@ -64,8 +94,29 @@ namespace dawn_native { namespace vulkan {
|
||||
uint64_t drmModifier; // DRM modifier of the buffer
|
||||
};
|
||||
|
||||
// Info struct that is written to in |ExportVulkanImage|.
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageExportInfoFD : ExternalImageExportInfoVk {
|
||||
public:
|
||||
// Contains the exported semaphore handles.
|
||||
std::vector<int> semaphoreHandles;
|
||||
|
||||
protected:
|
||||
using ExternalImageExportInfoVk::ExternalImageExportInfoVk;
|
||||
};
|
||||
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageExportInfoOpaqueFD : ExternalImageExportInfoFD {
|
||||
ExternalImageExportInfoOpaqueFD();
|
||||
};
|
||||
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageExportInfoDmaBuf : ExternalImageExportInfoFD {
|
||||
ExternalImageExportInfoDmaBuf();
|
||||
};
|
||||
|
||||
#endif // __linux__
|
||||
|
||||
// Exports a signal semaphore from a wrapped texture. This must be called on wrapped
|
||||
// textures before they are destroyed. On failure, returns -1
|
||||
// TODO(enga): Remove after updating Chromium to use ExportVulkanImage.
|
||||
DAWN_NATIVE_EXPORT int ExportSignalSemaphoreOpaqueFD(WGPUDevice cDevice,
|
||||
WGPUTexture cTexture);
|
||||
|
||||
@ -74,8 +125,15 @@ namespace dawn_native { namespace vulkan {
|
||||
// primitives before the texture can be used.
|
||||
// On failure, returns a nullptr.
|
||||
DAWN_NATIVE_EXPORT WGPUTexture WrapVulkanImage(WGPUDevice cDevice,
|
||||
const ExternalImageDescriptor* descriptor);
|
||||
#endif // __linux__
|
||||
const ExternalImageDescriptorVk* descriptor);
|
||||
|
||||
// Exports external memory from a Vulkan image. This must be called on wrapped textures
|
||||
// before they are destroyed. It writes the semaphore to wait on and the old/new image
|
||||
// layouts to |info|. Pass VK_IMAGE_LAYOUT_UNDEFINED as |desiredLayout| if you don't want to
|
||||
// perform a layout transition.
|
||||
DAWN_NATIVE_EXPORT bool ExportVulkanImage(WGPUTexture cTexture,
|
||||
VkImageLayout desiredLayout,
|
||||
ExternalImageExportInfoVk* info);
|
||||
|
||||
}} // namespace dawn_native::vulkan
|
||||
|
||||
|
@ -300,7 +300,7 @@ class D3D12SharedHandleUsageTests : public D3D12ResourceTestBase {
|
||||
const wgpu::Color& clearColor,
|
||||
ID3D11Texture2D** d3d11TextureOut,
|
||||
IDXGIKeyedMutex** dxgiKeyedMutexOut,
|
||||
bool isCleared = true) const {
|
||||
bool isInitialized = true) const {
|
||||
ComPtr<ID3D11Texture2D> d3d11Texture;
|
||||
HRESULT hr = mD3d11Device->CreateTexture2D(d3dDescriptor, nullptr, &d3d11Texture);
|
||||
ASSERT_EQ(hr, S_OK);
|
||||
@ -339,7 +339,7 @@ class D3D12SharedHandleUsageTests : public D3D12ResourceTestBase {
|
||||
reinterpret_cast<const WGPUTextureDescriptor*>(dawnDescriptor);
|
||||
externDesc.sharedHandle = sharedHandle;
|
||||
externDesc.acquireMutexKey = 1;
|
||||
externDesc.isCleared = isCleared;
|
||||
externDesc.isInitialized = isInitialized;
|
||||
WGPUTexture dawnTexture = dawn_native::d3d12::WrapSharedHandle(device.Get(), &externDesc);
|
||||
|
||||
*dawnTextureOut = wgpu::Texture::Acquire(dawnTexture);
|
||||
@ -502,9 +502,9 @@ TEST_P(D3D12SharedHandleUsageTests, ClearTwiceInD3D12ReadbackInD3D11) {
|
||||
}
|
||||
|
||||
// 1. Create and clear a D3D11 texture with clearColor
|
||||
// 2. Import the texture with isCleared = false
|
||||
// 2. Import the texture with isInitialized = false
|
||||
// 3. Verify clearColor is not visible in wrapped texture
|
||||
TEST_P(D3D12SharedHandleUsageTests, UnclearedTextureIsCleared) {
|
||||
TEST_P(D3D12SharedHandleUsageTests, UninitializedTextureIsCleared) {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
|
||||
const wgpu::Color clearColor{1.0f, 0.0f, 0.0f, 1.0f};
|
||||
|
@ -97,13 +97,13 @@ namespace {
|
||||
wgpu::Texture WrapIOSurface(const wgpu::TextureDescriptor* descriptor,
|
||||
IOSurfaceRef ioSurface,
|
||||
uint32_t plane,
|
||||
bool isCleared = true) {
|
||||
bool isInitialized = true) {
|
||||
dawn_native::metal::ExternalImageDescriptorIOSurface externDesc;
|
||||
externDesc.cTextureDescriptor =
|
||||
reinterpret_cast<const WGPUTextureDescriptor*>(descriptor);
|
||||
externDesc.ioSurface = ioSurface;
|
||||
externDesc.plane = plane;
|
||||
externDesc.isCleared = isCleared;
|
||||
externDesc.isInitialized = isInitialized;
|
||||
WGPUTexture texture = dawn_native::metal::WrapIOSurface(device.Get(), &externDesc);
|
||||
return wgpu::Texture::Acquire(texture);
|
||||
}
|
||||
@ -446,8 +446,8 @@ TEST_P(IOSurfaceUsageTests, ClearRGBA8IOSurface) {
|
||||
DoClearTest(ioSurface.get(), wgpu::TextureFormat::RGBA8Unorm, &data, sizeof(data));
|
||||
}
|
||||
|
||||
// Test that texture with color is cleared when isCleared = false
|
||||
TEST_P(IOSurfaceUsageTests, UnclearedTextureIsCleared) {
|
||||
// Test that texture with color is cleared when isInitialized = false
|
||||
TEST_P(IOSurfaceUsageTests, UninitializedTextureIsCleared) {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
|
||||
ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(1, 1, kCVPixelFormatType_32RGBA, 4);
|
||||
@ -465,7 +465,7 @@ TEST_P(IOSurfaceUsageTests, UnclearedTextureIsCleared) {
|
||||
textureDescriptor.mipLevelCount = 1;
|
||||
textureDescriptor.usage = wgpu::TextureUsage::OutputAttachment | wgpu::TextureUsage::CopySrc;
|
||||
|
||||
// wrap ioSurface and ensure color is not visible when isCleared set to false
|
||||
// wrap ioSurface and ensure color is not visible when isInitialized set to false
|
||||
wgpu::Texture ioSurfaceTexture = WrapIOSurface(&textureDescriptor, ioSurface.get(), 0, false);
|
||||
EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 0, 0, 0), ioSurfaceTexture, 0, 0);
|
||||
}
|
||||
|
@ -104,16 +104,34 @@ namespace dawn_native { namespace vulkan {
|
||||
uint32_t stride,
|
||||
uint64_t drmModifier,
|
||||
std::vector<int> waitFDs,
|
||||
bool isCleared = true,
|
||||
bool isInitialized = true,
|
||||
bool expectValid = true) {
|
||||
dawn_native::vulkan::ExternalImageDescriptorDmaBuf descriptor;
|
||||
return WrapVulkanImage(dawnDevice, textureDescriptor, memoryFd, stride, drmModifier,
|
||||
waitFDs, descriptor.releasedOldLayout,
|
||||
descriptor.releasedNewLayout, isInitialized, expectValid);
|
||||
}
|
||||
|
||||
wgpu::Texture WrapVulkanImage(wgpu::Device dawnDevice,
|
||||
const wgpu::TextureDescriptor* textureDescriptor,
|
||||
int memoryFd,
|
||||
uint32_t stride,
|
||||
uint64_t drmModifier,
|
||||
std::vector<int> waitFDs,
|
||||
VkImageLayout releasedOldLayout,
|
||||
VkImageLayout releasedNewLayout,
|
||||
bool isInitialized = true,
|
||||
bool expectValid = true) {
|
||||
dawn_native::vulkan::ExternalImageDescriptorDmaBuf descriptor;
|
||||
descriptor.cTextureDescriptor =
|
||||
reinterpret_cast<const WGPUTextureDescriptor*>(textureDescriptor);
|
||||
descriptor.isCleared = isCleared;
|
||||
descriptor.isInitialized = isInitialized;
|
||||
descriptor.stride = stride;
|
||||
descriptor.drmModifier = drmModifier;
|
||||
descriptor.memoryFD = memoryFd;
|
||||
descriptor.waitFDs = waitFDs;
|
||||
descriptor.releasedOldLayout = releasedOldLayout;
|
||||
descriptor.releasedNewLayout = releasedNewLayout;
|
||||
|
||||
WGPUTexture texture =
|
||||
dawn_native::vulkan::WrapVulkanImage(dawnDevice.Get(), &descriptor);
|
||||
@ -131,11 +149,13 @@ namespace dawn_native { namespace vulkan {
|
||||
// Exports the signal from a wrapped texture and ignores it
|
||||
// We have to export the signal before destroying the wrapped texture else it's an
|
||||
// assertion failure
|
||||
void IgnoreSignalSemaphore(wgpu::Device dawnDevice, wgpu::Texture wrappedTexture) {
|
||||
int fd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(dawnDevice.Get(),
|
||||
wrappedTexture.Get());
|
||||
ASSERT_NE(fd, -1);
|
||||
close(fd);
|
||||
void IgnoreSignalSemaphore(wgpu::Texture wrappedTexture) {
|
||||
dawn_native::vulkan::ExternalImageExportInfoDmaBuf exportInfo;
|
||||
dawn_native::vulkan::ExportVulkanImage(wrappedTexture.Get(), VK_IMAGE_LAYOUT_GENERAL, &exportInfo));
|
||||
for (int handle : info.semaphoreHandles) {
|
||||
ASSERT_NE(handle, -1);
|
||||
close(handle);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -157,7 +177,7 @@ namespace dawn_native { namespace vulkan {
|
||||
wgpu::Texture texture = WrapVulkanImage(device, &defaultDescriptor, defaultFd,
|
||||
defaultStride, defaultModifier, {}, true, true);
|
||||
EXPECT_NE(texture.Get(), nullptr);
|
||||
IgnoreSignalSemaphore(device, texture);
|
||||
IgnoreSignalSemaphore(texture);
|
||||
}
|
||||
|
||||
// Test an error occurs if the texture descriptor is missing
|
||||
@ -230,10 +250,12 @@ namespace dawn_native { namespace vulkan {
|
||||
wgpu::Texture texture = WrapVulkanImage(device, &defaultDescriptor, defaultFd,
|
||||
defaultStride, defaultModifier, {}, true, true);
|
||||
ASSERT_NE(texture.Get(), nullptr);
|
||||
IgnoreSignalSemaphore(device, texture);
|
||||
ASSERT_DEVICE_ERROR(int fd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(
|
||||
device.Get(), texture.Get()));
|
||||
ASSERT_EQ(fd, -1);
|
||||
IgnoreSignalSemaphore(texture);
|
||||
|
||||
dawn_native::vulkan::ExternalImageExportInfoDmaBuf exportInfo;
|
||||
ASSERT_DEVICE_ERROR(bool success = dawn_native::vulkan::ExportVulkanImage(
|
||||
texture.Get(), VK_IMAGE_LAYOUT_GENERAL, &exportInfo));
|
||||
ASSERT_FALSE(success);
|
||||
}
|
||||
|
||||
// Test an error occurs if we try to export the signal semaphore from a normal texture
|
||||
@ -242,9 +264,11 @@ namespace dawn_native { namespace vulkan {
|
||||
|
||||
wgpu::Texture texture = device.CreateTexture(&defaultDescriptor);
|
||||
ASSERT_NE(texture.Get(), nullptr);
|
||||
ASSERT_DEVICE_ERROR(int fd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(
|
||||
device.Get(), texture.Get()));
|
||||
ASSERT_EQ(fd, -1);
|
||||
|
||||
dawn_native::vulkan::ExternalImageExportInfoDmaBuf exportInfo;
|
||||
ASSERT_DEVICE_ERROR(bool success = dawn_native::vulkan::ExportVulkanImage(
|
||||
texture.Get(), VK_IMAGE_LAYOUT_GENERAL, &exportInfo));
|
||||
ASSERT_FALSE(success);
|
||||
}
|
||||
|
||||
// Test an error occurs if we try to export the signal semaphore from a destroyed texture
|
||||
@ -254,9 +278,11 @@ namespace dawn_native { namespace vulkan {
|
||||
wgpu::Texture texture = device.CreateTexture(&defaultDescriptor);
|
||||
ASSERT_NE(texture.Get(), nullptr);
|
||||
texture.Destroy();
|
||||
ASSERT_DEVICE_ERROR(int fd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(
|
||||
device.Get(), texture.Get()));
|
||||
ASSERT_EQ(fd, -1);
|
||||
|
||||
dawn_native::vulkan::ExternalImageExportInfoDmaBuf exportInfo;
|
||||
ASSERT_DEVICE_ERROR(bool success = dawn_native::vulkan::ExportVulkanImage(
|
||||
texture.Get(), VK_IMAGE_LAYOUT_GENERAL, &exportInfo));
|
||||
ASSERT_FALSE(success);
|
||||
}
|
||||
|
||||
// Fixture to test using external memory textures through different usages.
|
||||
@ -330,84 +356,56 @@ namespace dawn_native { namespace vulkan {
|
||||
// Verify clear color is visible in |device|
|
||||
TEST_P(VulkanImageWrappingUsageTests, ClearImageAcrossDevices) {
|
||||
// Import the image on |secondDevice|
|
||||
wgpu::Texture wrappedTexture = WrapVulkanImage(secondDevice, &defaultDescriptor, defaultFd,
|
||||
defaultStride, defaultModifier, {});
|
||||
wgpu::Texture wrappedTexture = WrapVulkanImage(
|
||||
secondDevice, &defaultDescriptor, defaultFd, defaultStride, defaultModifier, {},
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
// Clear |wrappedTexture| on |secondDevice|
|
||||
ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
|
||||
|
||||
int signalFd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(secondDevice.Get(),
|
||||
wrappedTexture.Get());
|
||||
dawn_native::vulkan::ExternalImageExportInfoDmaBuf exportInfo;
|
||||
dawn_native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo);
|
||||
|
||||
// Import the image to |device|, making sure we wait on signalFd
|
||||
int nextFd = gbm_bo_get_fd(defaultGbmBo);
|
||||
wgpu::Texture nextWrappedTexture = WrapVulkanImage(
|
||||
device, &defaultDescriptor, nextFd, defaultStride, defaultModifier, {signalFd});
|
||||
wgpu::Texture nextWrappedTexture =
|
||||
WrapVulkanImage(device, &defaultDescriptor, nextFd, defaultStride, defaultModifier,
|
||||
exportInfo.semaphoreHandles, exportInfo.releasedOldLayout,
|
||||
exportInfo.releasedNewLayout);
|
||||
|
||||
// Verify |device| sees the changes from |secondDevice|
|
||||
EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), nextWrappedTexture, 0, 0);
|
||||
|
||||
IgnoreSignalSemaphore(device, nextWrappedTexture);
|
||||
}
|
||||
|
||||
// Import texture to |device| and |secondDevice|
|
||||
// Clear image in |secondDevice|
|
||||
// Verify clear color is visible in |device|
|
||||
// Verify the very first import into |device| also sees the change, since it should
|
||||
// alias the same memory
|
||||
TEST_P(VulkanImageWrappingUsageTests, ClearImageAcrossDevicesAliased) {
|
||||
// Import the image on |device|
|
||||
wgpu::Texture wrappedTextureAlias = WrapVulkanImage(device, &defaultDescriptor, defaultFd,
|
||||
defaultStride, defaultModifier, {});
|
||||
|
||||
// Import the image on |secondDevice|
|
||||
int nextFd = gbm_bo_get_fd(defaultGbmBo);
|
||||
wgpu::Texture wrappedTexture = WrapVulkanImage(secondDevice, &defaultDescriptor, nextFd,
|
||||
defaultStride, defaultModifier, {});
|
||||
|
||||
// Clear |wrappedTexture| on |secondDevice|
|
||||
ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
|
||||
|
||||
int signalFd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(secondDevice.Get(),
|
||||
wrappedTexture.Get());
|
||||
|
||||
// Import the image to |device|, making sure we wait on signalFd
|
||||
nextFd = gbm_bo_get_fd(defaultGbmBo);
|
||||
wgpu::Texture nextWrappedTexture = WrapVulkanImage(
|
||||
device, &defaultDescriptor, nextFd, defaultStride, defaultModifier, {signalFd});
|
||||
|
||||
// Verify |device| sees the changes from |secondDevice| (waits)
|
||||
EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), nextWrappedTexture, 0, 0);
|
||||
|
||||
// Verify aliased texture sees changes from |secondDevice| (without waiting!)
|
||||
EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), wrappedTextureAlias, 0, 0);
|
||||
|
||||
IgnoreSignalSemaphore(device, nextWrappedTexture);
|
||||
IgnoreSignalSemaphore(device, wrappedTextureAlias);
|
||||
IgnoreSignalSemaphore(nextWrappedTexture);
|
||||
}
|
||||
|
||||
// Clear an image in |secondDevice|
|
||||
// Verify clear color is not visible in |device| if we import the texture as not cleared
|
||||
TEST_P(VulkanImageWrappingUsageTests, UnclearedTextureIsCleared) {
|
||||
TEST_P(VulkanImageWrappingUsageTests, UninitializedTextureIsCleared) {
|
||||
// Import the image on |secondDevice|
|
||||
wgpu::Texture wrappedTexture = WrapVulkanImage(secondDevice, &defaultDescriptor, defaultFd,
|
||||
defaultStride, defaultModifier, {});
|
||||
wgpu::Texture wrappedTexture = WrapVulkanImage(
|
||||
secondDevice, &defaultDescriptor, defaultFd, defaultStride, defaultModifier, {},
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
// Clear |wrappedTexture| on |secondDevice|
|
||||
ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
|
||||
|
||||
int signalFd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(secondDevice.Get(),
|
||||
wrappedTexture.Get());
|
||||
dawn_native::vulkan::ExternalImageExportInfoDmaBuf exportInfo;
|
||||
dawn_native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo);
|
||||
|
||||
// Import the image to |device|, making sure we wait on signalFd
|
||||
int nextFd = gbm_bo_get_fd(defaultGbmBo);
|
||||
wgpu::Texture nextWrappedTexture = WrapVulkanImage(
|
||||
device, &defaultDescriptor, nextFd, defaultStride, defaultModifier, {signalFd}, false);
|
||||
wgpu::Texture nextWrappedTexture =
|
||||
WrapVulkanImage(device, &defaultDescriptor, nextFd, defaultStride, defaultModifier,
|
||||
exportInfo.semaphoreHandles, exportInfo.releasedOldLayout,
|
||||
exportInfo.releasedNewLayout, false);
|
||||
|
||||
// Verify |device| doesn't see the changes from |secondDevice|
|
||||
EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 0, 0, 0), nextWrappedTexture, 0, 0);
|
||||
|
||||
IgnoreSignalSemaphore(device, nextWrappedTexture);
|
||||
IgnoreSignalSemaphore(nextWrappedTexture);
|
||||
}
|
||||
|
||||
// Import a texture into |secondDevice|
|
||||
@ -416,19 +414,23 @@ namespace dawn_native { namespace vulkan {
|
||||
// Verify the clear color from |secondDevice| is visible in |copyDstTexture|
|
||||
TEST_P(VulkanImageWrappingUsageTests, CopyTextureToTextureSrcSync) {
|
||||
// Import the image on |secondDevice|
|
||||
wgpu::Texture wrappedTexture = WrapVulkanImage(secondDevice, &defaultDescriptor, defaultFd,
|
||||
defaultStride, defaultModifier, {});
|
||||
wgpu::Texture wrappedTexture = WrapVulkanImage(
|
||||
secondDevice, &defaultDescriptor, defaultFd, defaultStride, defaultModifier, {},
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
// Clear |wrappedTexture| on |secondDevice|
|
||||
ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
|
||||
|
||||
int signalFd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(secondDevice.Get(),
|
||||
wrappedTexture.Get());
|
||||
dawn_native::vulkan::ExternalImageExportInfoDmaBuf exportInfo;
|
||||
dawn_native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo);
|
||||
|
||||
// Import the image to |device|, making sure we wait on |signalFd|
|
||||
int nextFd = gbm_bo_get_fd(defaultGbmBo);
|
||||
wgpu::Texture deviceWrappedTexture = WrapVulkanImage(
|
||||
device, &defaultDescriptor, nextFd, defaultStride, defaultModifier, {signalFd});
|
||||
wgpu::Texture deviceWrappedTexture =
|
||||
WrapVulkanImage(device, &defaultDescriptor, nextFd, defaultStride, defaultModifier,
|
||||
exportInfo.semaphoreHandles, exportInfo.releasedOldLayout,
|
||||
exportInfo.releasedNewLayout);
|
||||
|
||||
// Create a second texture on |device|
|
||||
wgpu::Texture copyDstTexture = device.CreateTexture(&defaultDescriptor);
|
||||
@ -439,7 +441,7 @@ namespace dawn_native { namespace vulkan {
|
||||
// Verify |copyDstTexture| sees changes from |secondDevice|
|
||||
EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), copyDstTexture, 0, 0);
|
||||
|
||||
IgnoreSignalSemaphore(device, deviceWrappedTexture);
|
||||
IgnoreSignalSemaphore(deviceWrappedTexture);
|
||||
}
|
||||
|
||||
// Import a texture into |device|
|
||||
@ -453,19 +455,23 @@ namespace dawn_native { namespace vulkan {
|
||||
// into the texture first, then |device| writes color A
|
||||
TEST_P(VulkanImageWrappingUsageTests, CopyTextureToTextureDstSync) {
|
||||
// Import the image on |device|
|
||||
wgpu::Texture wrappedTexture = WrapVulkanImage(device, &defaultDescriptor, defaultFd,
|
||||
defaultStride, defaultModifier, {});
|
||||
wgpu::Texture wrappedTexture = WrapVulkanImage(
|
||||
device, &defaultDescriptor, defaultFd, defaultStride, defaultModifier, {},
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
// Clear |wrappedTexture| on |device|
|
||||
ClearImage(device, wrappedTexture, {5 / 255.0f, 6 / 255.0f, 7 / 255.0f, 8 / 255.0f});
|
||||
|
||||
int signalFd =
|
||||
dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(device.Get(), wrappedTexture.Get());
|
||||
dawn_native::vulkan::ExternalImageExportInfoDmaBuf exportInfo;
|
||||
dawn_native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &exportInfo);
|
||||
|
||||
// Import the image to |secondDevice|, making sure we wait on |signalFd|
|
||||
int nextFd = gbm_bo_get_fd(defaultGbmBo);
|
||||
wgpu::Texture secondDeviceWrappedTexture = WrapVulkanImage(
|
||||
secondDevice, &defaultDescriptor, nextFd, defaultStride, defaultModifier, {signalFd});
|
||||
wgpu::Texture secondDeviceWrappedTexture =
|
||||
WrapVulkanImage(secondDevice, &defaultDescriptor, nextFd, defaultStride,
|
||||
defaultModifier, exportInfo.semaphoreHandles,
|
||||
exportInfo.releasedOldLayout, exportInfo.releasedNewLayout);
|
||||
|
||||
// Create a texture with color B on |secondDevice|
|
||||
wgpu::Texture copySrcTexture = secondDevice.CreateTexture(&defaultDescriptor);
|
||||
@ -477,17 +483,21 @@ namespace dawn_native { namespace vulkan {
|
||||
secondDeviceWrappedTexture);
|
||||
|
||||
// Re-import back into |device|, waiting on |secondDevice|'s signal
|
||||
signalFd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(
|
||||
secondDevice.Get(), secondDeviceWrappedTexture.Get());
|
||||
dawn_native::vulkan::ExternalImageExportInfoDmaBuf secondExportInfo;
|
||||
dawn_native::vulkan::ExportVulkanImage(secondDeviceWrappedTexture.Get(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
&secondExportInfo);
|
||||
nextFd = gbm_bo_get_fd(defaultGbmBo);
|
||||
|
||||
wgpu::Texture nextWrappedTexture = WrapVulkanImage(
|
||||
device, &defaultDescriptor, nextFd, defaultStride, defaultModifier, {signalFd});
|
||||
wgpu::Texture nextWrappedTexture =
|
||||
WrapVulkanImage(device, &defaultDescriptor, nextFd, defaultStride, defaultModifier,
|
||||
secondExportInfo.semaphoreHandles, secondExportInfo.releasedOldLayout,
|
||||
secondExportInfo.releasedNewLayout);
|
||||
|
||||
// Verify |nextWrappedTexture| contains the color from our copy
|
||||
EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), nextWrappedTexture, 0, 0);
|
||||
|
||||
IgnoreSignalSemaphore(device, nextWrappedTexture);
|
||||
IgnoreSignalSemaphore(nextWrappedTexture);
|
||||
}
|
||||
|
||||
// Import a texture from |secondDevice|
|
||||
@ -496,19 +506,23 @@ namespace dawn_native { namespace vulkan {
|
||||
// Verify the clear color from |secondDevice| is visible in |copyDstBuffer|
|
||||
TEST_P(VulkanImageWrappingUsageTests, CopyTextureToBufferSrcSync) {
|
||||
// Import the image on |secondDevice|
|
||||
wgpu::Texture wrappedTexture = WrapVulkanImage(secondDevice, &defaultDescriptor, defaultFd,
|
||||
defaultStride, defaultModifier, {});
|
||||
wgpu::Texture wrappedTexture = WrapVulkanImage(
|
||||
secondDevice, &defaultDescriptor, defaultFd, defaultStride, defaultModifier, {},
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
// Clear |wrappedTexture| on |secondDevice|
|
||||
ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
|
||||
|
||||
int signalFd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(secondDevice.Get(),
|
||||
wrappedTexture.Get());
|
||||
dawn_native::vulkan::ExternalImageExportInfoDmaBuf exportInfo;
|
||||
dawn_native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo);
|
||||
|
||||
// Import the image to |device|, making sure we wait on |signalFd|
|
||||
int nextFd = gbm_bo_get_fd(defaultGbmBo);
|
||||
wgpu::Texture deviceWrappedTexture = WrapVulkanImage(
|
||||
device, &defaultDescriptor, nextFd, defaultStride, defaultModifier, {signalFd});
|
||||
wgpu::Texture deviceWrappedTexture =
|
||||
WrapVulkanImage(device, &defaultDescriptor, nextFd, defaultStride, defaultModifier,
|
||||
exportInfo.semaphoreHandles, exportInfo.releasedOldLayout,
|
||||
exportInfo.releasedNewLayout);
|
||||
|
||||
// Create a destination buffer on |device|
|
||||
wgpu::BufferDescriptor bufferDesc;
|
||||
@ -532,7 +546,7 @@ namespace dawn_native { namespace vulkan {
|
||||
uint32_t expected = 1;
|
||||
EXPECT_BUFFER_U32_EQ(expected, copyDstBuffer, 0);
|
||||
|
||||
IgnoreSignalSemaphore(device, deviceWrappedTexture);
|
||||
IgnoreSignalSemaphore(deviceWrappedTexture);
|
||||
}
|
||||
|
||||
// Import a texture into |device|
|
||||
@ -545,19 +559,23 @@ namespace dawn_native { namespace vulkan {
|
||||
// into the texture first, then |device| writes color A
|
||||
TEST_P(VulkanImageWrappingUsageTests, CopyBufferToTextureDstSync) {
|
||||
// Import the image on |device|
|
||||
wgpu::Texture wrappedTexture = WrapVulkanImage(device, &defaultDescriptor, defaultFd,
|
||||
defaultStride, defaultModifier, {});
|
||||
wgpu::Texture wrappedTexture = WrapVulkanImage(
|
||||
device, &defaultDescriptor, defaultFd, defaultStride, defaultModifier, {},
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
// Clear |wrappedTexture| on |device|
|
||||
ClearImage(device, wrappedTexture, {5 / 255.0f, 6 / 255.0f, 7 / 255.0f, 8 / 255.0f});
|
||||
|
||||
int signalFd =
|
||||
dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(device.Get(), wrappedTexture.Get());
|
||||
dawn_native::vulkan::ExternalImageExportInfoDmaBuf exportInfo;
|
||||
dawn_native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo);
|
||||
|
||||
// Import the image to |secondDevice|, making sure we wait on |signalFd|
|
||||
int nextFd = gbm_bo_get_fd(defaultGbmBo);
|
||||
wgpu::Texture secondDeviceWrappedTexture = WrapVulkanImage(
|
||||
secondDevice, &defaultDescriptor, nextFd, defaultStride, defaultModifier, {signalFd});
|
||||
wgpu::Texture secondDeviceWrappedTexture =
|
||||
WrapVulkanImage(secondDevice, &defaultDescriptor, nextFd, defaultStride,
|
||||
defaultModifier, exportInfo.semaphoreHandles,
|
||||
exportInfo.releasedOldLayout, exportInfo.releasedNewLayout);
|
||||
|
||||
// Copy color B on |secondDevice|
|
||||
wgpu::Queue secondDeviceQueue = secondDevice.GetDefaultQueue();
|
||||
@ -579,17 +597,21 @@ namespace dawn_native { namespace vulkan {
|
||||
secondDeviceQueue.Submit(1, &commands);
|
||||
|
||||
// Re-import back into |device|, waiting on |secondDevice|'s signal
|
||||
signalFd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(
|
||||
secondDevice.Get(), secondDeviceWrappedTexture.Get());
|
||||
dawn_native::vulkan::ExternalImageExportInfoDmaBuf secondExportInfo;
|
||||
dawn_native::vulkan::ExportVulkanImage(secondDeviceWrappedTexture.Get(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
&secondExportInfo);
|
||||
nextFd = gbm_bo_get_fd(defaultGbmBo);
|
||||
|
||||
wgpu::Texture nextWrappedTexture = WrapVulkanImage(
|
||||
device, &defaultDescriptor, nextFd, defaultStride, defaultModifier, {signalFd});
|
||||
wgpu::Texture nextWrappedTexture =
|
||||
WrapVulkanImage(device, &defaultDescriptor, nextFd, defaultStride, defaultModifier,
|
||||
secondExportInfo.semaphoreHandles, secondExportInfo.releasedOldLayout,
|
||||
secondExportInfo.releasedNewLayout);
|
||||
|
||||
// Verify |nextWrappedTexture| contains the color from our copy
|
||||
EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), nextWrappedTexture, 0, 0);
|
||||
|
||||
IgnoreSignalSemaphore(device, nextWrappedTexture);
|
||||
IgnoreSignalSemaphore(nextWrappedTexture);
|
||||
}
|
||||
|
||||
// Import a texture from |secondDevice|
|
||||
@ -599,19 +621,23 @@ namespace dawn_native { namespace vulkan {
|
||||
// Verify the clear color from |secondDevice| is visible in both copies
|
||||
TEST_P(VulkanImageWrappingUsageTests, DoubleTextureUsage) {
|
||||
// Import the image on |secondDevice|
|
||||
wgpu::Texture wrappedTexture = WrapVulkanImage(secondDevice, &defaultDescriptor, defaultFd,
|
||||
defaultStride, defaultModifier, {});
|
||||
wgpu::Texture wrappedTexture = WrapVulkanImage(
|
||||
secondDevice, &defaultDescriptor, defaultFd, defaultStride, defaultModifier, {},
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
// Clear |wrappedTexture| on |secondDevice|
|
||||
ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
|
||||
|
||||
int signalFd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(secondDevice.Get(),
|
||||
wrappedTexture.Get());
|
||||
dawn_native::vulkan::ExternalImageExportInfoDmaBuf exportInfo;
|
||||
dawn_native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo);
|
||||
|
||||
// Import the image to |device|, making sure we wait on |signalFd|
|
||||
int nextFd = gbm_bo_get_fd(defaultGbmBo);
|
||||
wgpu::Texture deviceWrappedTexture = WrapVulkanImage(
|
||||
device, &defaultDescriptor, nextFd, defaultStride, defaultModifier, {signalFd});
|
||||
wgpu::Texture deviceWrappedTexture =
|
||||
WrapVulkanImage(device, &defaultDescriptor, nextFd, defaultStride, defaultModifier,
|
||||
exportInfo.semaphoreHandles, exportInfo.releasedOldLayout,
|
||||
exportInfo.releasedNewLayout);
|
||||
|
||||
// Create a second texture on |device|
|
||||
wgpu::Texture copyDstTexture = device.CreateTexture(&defaultDescriptor);
|
||||
@ -631,7 +657,7 @@ namespace dawn_native { namespace vulkan {
|
||||
// Verify |secondCopyDstTexture| sees changes from |secondDevice|
|
||||
EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), secondCopyDstTexture, 0, 0);
|
||||
|
||||
IgnoreSignalSemaphore(device, deviceWrappedTexture);
|
||||
IgnoreSignalSemaphore(deviceWrappedTexture);
|
||||
}
|
||||
|
||||
// Tex A on device 3 (external export)
|
||||
@ -676,10 +702,12 @@ namespace dawn_native { namespace vulkan {
|
||||
|
||||
// Import TexA, TexB on device 3
|
||||
wgpu::Texture wrappedTexADevice3 =
|
||||
WrapVulkanImage(thirdDevice, &defaultDescriptor, fdA, strideA, modifierA, {});
|
||||
WrapVulkanImage(thirdDevice, &defaultDescriptor, fdA, strideA, modifierA, {},
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
wgpu::Texture wrappedTexBDevice3 =
|
||||
WrapVulkanImage(thirdDevice, &defaultDescriptor, fdB, strideB, modifierB, {});
|
||||
WrapVulkanImage(thirdDevice, &defaultDescriptor, fdB, strideB, modifierB, {},
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
|
||||
// Clear TexA
|
||||
ClearImage(thirdDevice, wrappedTexADevice3,
|
||||
@ -689,30 +717,37 @@ namespace dawn_native { namespace vulkan {
|
||||
SimpleCopyTextureToTexture(thirdDevice, thirdDeviceQueue, wrappedTexADevice3,
|
||||
wrappedTexBDevice3);
|
||||
|
||||
int signalFdTexBDevice3 = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(
|
||||
thirdDevice.Get(), wrappedTexBDevice3.Get());
|
||||
IgnoreSignalSemaphore(thirdDevice, wrappedTexADevice3);
|
||||
dawn_native::vulkan::ExternalImageExportInfoDmaBuf exportInfoTexBDevice3;
|
||||
dawn_native::vulkan::ExportVulkanImage(
|
||||
wrappedTexBDevice3.Get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfoTexBDevice3);
|
||||
IgnoreSignalSemaphore(wrappedTexADevice3);
|
||||
|
||||
// Import TexB, TexC on device 2
|
||||
fdB = gbm_bo_get_fd(gbmBoB);
|
||||
wgpu::Texture wrappedTexBDevice2 = WrapVulkanImage(
|
||||
secondDevice, &defaultDescriptor, fdB, strideB, modifierB, {signalFdTexBDevice3});
|
||||
secondDevice, &defaultDescriptor, fdB, strideB, modifierB,
|
||||
exportInfoTexBDevice3.semaphoreHandles, exportInfoTexBDevice3.releasedOldLayout,
|
||||
exportInfoTexBDevice3.releasedNewLayout);
|
||||
|
||||
wgpu::Texture wrappedTexCDevice2 =
|
||||
WrapVulkanImage(secondDevice, &defaultDescriptor, fdC, strideC, modifierC, {});
|
||||
WrapVulkanImage(secondDevice, &defaultDescriptor, fdC, strideC, modifierC, {},
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
|
||||
// Copy B->C on device 2
|
||||
SimpleCopyTextureToTexture(secondDevice, secondDeviceQueue, wrappedTexBDevice2,
|
||||
wrappedTexCDevice2);
|
||||
|
||||
int signalFdTexCDevice2 = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(
|
||||
secondDevice.Get(), wrappedTexCDevice2.Get());
|
||||
IgnoreSignalSemaphore(secondDevice, wrappedTexBDevice2);
|
||||
dawn_native::vulkan::ExternalImageExportInfoDmaBuf exportInfoTexCDevice2;
|
||||
dawn_native::vulkan::ExportVulkanImage(
|
||||
wrappedTexCDevice2.Get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfoTexCDevice2);
|
||||
IgnoreSignalSemaphore(wrappedTexBDevice2);
|
||||
|
||||
// Import TexC on device 1
|
||||
fdC = gbm_bo_get_fd(gbmBoC);
|
||||
wgpu::Texture wrappedTexCDevice1 = WrapVulkanImage(device, &defaultDescriptor, fdC, strideC,
|
||||
modifierC, {signalFdTexCDevice2});
|
||||
wgpu::Texture wrappedTexCDevice1 = WrapVulkanImage(
|
||||
device, &defaultDescriptor, fdC, strideC, modifierC,
|
||||
exportInfoTexCDevice2.semaphoreHandles, exportInfoTexCDevice2.releasedOldLayout,
|
||||
exportInfoTexCDevice2.releasedNewLayout);
|
||||
|
||||
// Create TexD on device 1
|
||||
wgpu::Texture texD = device.CreateTexture(&defaultDescriptor);
|
||||
@ -723,7 +758,7 @@ namespace dawn_native { namespace vulkan {
|
||||
// Verify D matches clear color
|
||||
EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), texD, 0, 0);
|
||||
|
||||
IgnoreSignalSemaphore(device, wrappedTexCDevice1);
|
||||
IgnoreSignalSemaphore(wrappedTexCDevice1);
|
||||
}
|
||||
|
||||
// Tests a larger image is preserved when importing
|
||||
@ -756,7 +791,8 @@ namespace dawn_native { namespace vulkan {
|
||||
|
||||
// Import the image on |secondDevice|
|
||||
wgpu::Texture wrappedTexture =
|
||||
WrapVulkanImage(secondDevice, &descriptor, fd, stride, modifier, {});
|
||||
WrapVulkanImage(secondDevice, &descriptor, fd, stride, modifier, {},
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
|
||||
// Draw a non-trivial picture
|
||||
uint32_t width = 640, height = 480, pixelSize = 4;
|
||||
@ -791,14 +827,15 @@ namespace dawn_native { namespace vulkan {
|
||||
wgpu::CommandBuffer commands = encoder.Finish();
|
||||
secondDeviceQueue.Submit(1, &commands);
|
||||
}
|
||||
|
||||
int signalFd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(secondDevice.Get(),
|
||||
wrappedTexture.Get());
|
||||
dawn_native::vulkan::ExternalImageExportInfoDmaBuf exportInfo;
|
||||
dawn_native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo);
|
||||
int nextFd = gbm_bo_get_fd(gbmBo);
|
||||
|
||||
// Import the image on |device|
|
||||
wgpu::Texture nextWrappedTexture =
|
||||
WrapVulkanImage(device, &descriptor, nextFd, stride, modifier, {signalFd});
|
||||
wgpu::Texture nextWrappedTexture = WrapVulkanImage(
|
||||
device, &descriptor, nextFd, stride, modifier, exportInfo.semaphoreHandles,
|
||||
exportInfo.releasedOldLayout, exportInfo.releasedNewLayout);
|
||||
|
||||
// Copy the image into a buffer for comparison
|
||||
wgpu::BufferDescriptor copyDesc;
|
||||
@ -823,7 +860,7 @@ namespace dawn_native { namespace vulkan {
|
||||
EXPECT_BUFFER_U32_RANGE_EQ(reinterpret_cast<uint32_t*>(data.data()), copyDstBuffer, 0,
|
||||
data.size() / 4);
|
||||
|
||||
IgnoreSignalSemaphore(device, nextWrappedTexture);
|
||||
IgnoreSignalSemaphore(nextWrappedTexture);
|
||||
}
|
||||
|
||||
DAWN_INSTANTIATE_TEST(VulkanImageWrappingValidationTests, VulkanBackend());
|
||||
|
@ -157,16 +157,34 @@ namespace dawn_native { namespace vulkan {
|
||||
VkDeviceSize allocationSize,
|
||||
uint32_t memoryTypeIndex,
|
||||
std::vector<int> waitFDs,
|
||||
bool isCleared = true,
|
||||
bool isInitialized = true,
|
||||
bool expectValid = true) {
|
||||
dawn_native::vulkan::ExternalImageDescriptorOpaqueFD descriptor;
|
||||
return WrapVulkanImage(dawnDevice, textureDescriptor, memoryFd, allocationSize,
|
||||
memoryTypeIndex, waitFDs, descriptor.releasedOldLayout,
|
||||
descriptor.releasedNewLayout, isInitialized, expectValid);
|
||||
}
|
||||
|
||||
wgpu::Texture WrapVulkanImage(wgpu::Device dawnDevice,
|
||||
const wgpu::TextureDescriptor* textureDescriptor,
|
||||
int memoryFd,
|
||||
VkDeviceSize allocationSize,
|
||||
uint32_t memoryTypeIndex,
|
||||
std::vector<int> waitFDs,
|
||||
VkImageLayout releasedOldLayout,
|
||||
VkImageLayout releasedNewLayout,
|
||||
bool isInitialized = true,
|
||||
bool expectValid = true) {
|
||||
dawn_native::vulkan::ExternalImageDescriptorOpaqueFD descriptor;
|
||||
descriptor.cTextureDescriptor =
|
||||
reinterpret_cast<const WGPUTextureDescriptor*>(textureDescriptor);
|
||||
descriptor.isCleared = isCleared;
|
||||
descriptor.isInitialized = isInitialized;
|
||||
descriptor.allocationSize = allocationSize;
|
||||
descriptor.memoryTypeIndex = memoryTypeIndex;
|
||||
descriptor.memoryFD = memoryFd;
|
||||
descriptor.waitFDs = waitFDs;
|
||||
descriptor.releasedOldLayout = releasedOldLayout;
|
||||
descriptor.releasedNewLayout = releasedNewLayout;
|
||||
|
||||
WGPUTexture texture =
|
||||
dawn_native::vulkan::WrapVulkanImage(dawnDevice.Get(), &descriptor);
|
||||
@ -184,11 +202,14 @@ namespace dawn_native { namespace vulkan {
|
||||
// Exports the signal from a wrapped texture and ignores it
|
||||
// We have to export the signal before destroying the wrapped texture else it's an
|
||||
// assertion failure
|
||||
void IgnoreSignalSemaphore(wgpu::Device dawnDevice, wgpu::Texture wrappedTexture) {
|
||||
int fd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(dawnDevice.Get(),
|
||||
wrappedTexture.Get());
|
||||
ASSERT_NE(fd, -1);
|
||||
close(fd);
|
||||
void IgnoreSignalSemaphore(wgpu::Texture wrappedTexture) {
|
||||
dawn_native::vulkan::ExternalImageExportInfoOpaqueFD info;
|
||||
dawn_native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
|
||||
VK_IMAGE_LAYOUT_GENERAL, &info);
|
||||
for (int handle : info.semaphoreHandles) {
|
||||
ASSERT_NE(handle, -1);
|
||||
close(handle);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -244,7 +265,7 @@ namespace dawn_native { namespace vulkan {
|
||||
WrapVulkanImage(device, &defaultDescriptor, defaultFd, defaultAllocationSize,
|
||||
defaultMemoryTypeIndex, {}, true, true);
|
||||
EXPECT_NE(texture.Get(), nullptr);
|
||||
IgnoreSignalSemaphore(device, texture);
|
||||
IgnoreSignalSemaphore(texture);
|
||||
}
|
||||
|
||||
// Test an error occurs if the texture descriptor is missing
|
||||
@ -319,10 +340,12 @@ namespace dawn_native { namespace vulkan {
|
||||
WrapVulkanImage(device, &defaultDescriptor, defaultFd, defaultAllocationSize,
|
||||
defaultMemoryTypeIndex, {}, true, true);
|
||||
ASSERT_NE(texture.Get(), nullptr);
|
||||
IgnoreSignalSemaphore(device, texture);
|
||||
ASSERT_DEVICE_ERROR(int fd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(
|
||||
device.Get(), texture.Get()));
|
||||
ASSERT_EQ(fd, -1);
|
||||
IgnoreSignalSemaphore(texture);
|
||||
|
||||
dawn_native::vulkan::ExternalImageExportInfoOpaqueFD exportInfo;
|
||||
ASSERT_DEVICE_ERROR(bool success = dawn_native::vulkan::ExportVulkanImage(
|
||||
texture.Get(), VK_IMAGE_LAYOUT_GENERAL, &exportInfo));
|
||||
ASSERT_FALSE(success);
|
||||
}
|
||||
|
||||
// Test an error occurs if we try to export the signal semaphore from a normal texture
|
||||
@ -330,9 +353,11 @@ namespace dawn_native { namespace vulkan {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
wgpu::Texture texture = device.CreateTexture(&defaultDescriptor);
|
||||
ASSERT_NE(texture.Get(), nullptr);
|
||||
ASSERT_DEVICE_ERROR(int fd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(
|
||||
device.Get(), texture.Get()));
|
||||
ASSERT_EQ(fd, -1);
|
||||
|
||||
dawn_native::vulkan::ExternalImageExportInfoOpaqueFD exportInfo;
|
||||
ASSERT_DEVICE_ERROR(bool success = dawn_native::vulkan::ExportVulkanImage(
|
||||
texture.Get(), VK_IMAGE_LAYOUT_GENERAL, &exportInfo));
|
||||
ASSERT_FALSE(success);
|
||||
}
|
||||
|
||||
// Test an error occurs if we try to export the signal semaphore from a destroyed texture
|
||||
@ -341,9 +366,11 @@ namespace dawn_native { namespace vulkan {
|
||||
wgpu::Texture texture = device.CreateTexture(&defaultDescriptor);
|
||||
ASSERT_NE(texture.Get(), nullptr);
|
||||
texture.Destroy();
|
||||
ASSERT_DEVICE_ERROR(int fd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(
|
||||
device.Get(), texture.Get()));
|
||||
ASSERT_EQ(fd, -1);
|
||||
|
||||
dawn_native::vulkan::ExternalImageExportInfoOpaqueFD exportInfo;
|
||||
ASSERT_DEVICE_ERROR(bool success = dawn_native::vulkan::ExportVulkanImage(
|
||||
texture.Get(), VK_IMAGE_LAYOUT_GENERAL, &exportInfo));
|
||||
ASSERT_FALSE(success);
|
||||
}
|
||||
|
||||
// Fixture to test using external memory textures through different usages.
|
||||
@ -456,97 +483,58 @@ namespace dawn_native { namespace vulkan {
|
||||
// Import the image on |secondDevice|
|
||||
wgpu::Texture wrappedTexture =
|
||||
WrapVulkanImage(secondDevice, &defaultDescriptor, defaultFd, defaultAllocationSize,
|
||||
defaultMemoryTypeIndex, {});
|
||||
defaultMemoryTypeIndex, {}, VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
// Clear |wrappedTexture| on |secondDevice|
|
||||
ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
|
||||
|
||||
int signalFd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(secondDevice.Get(),
|
||||
wrappedTexture.Get());
|
||||
dawn_native::vulkan::ExternalImageExportInfoOpaqueFD exportInfo;
|
||||
dawn_native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo);
|
||||
|
||||
// Import the image to |device|, making sure we wait on signalFd
|
||||
int memoryFd = GetMemoryFd(deviceVk, defaultAllocation);
|
||||
wgpu::Texture nextWrappedTexture =
|
||||
WrapVulkanImage(device, &defaultDescriptor, memoryFd, defaultAllocationSize,
|
||||
defaultMemoryTypeIndex, {signalFd});
|
||||
defaultMemoryTypeIndex, exportInfo.semaphoreHandles,
|
||||
exportInfo.releasedOldLayout, exportInfo.releasedNewLayout);
|
||||
|
||||
// Verify |device| sees the changes from |secondDevice|
|
||||
EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), nextWrappedTexture, 0, 0);
|
||||
|
||||
IgnoreSignalSemaphore(device, nextWrappedTexture);
|
||||
}
|
||||
|
||||
// Import texture to |device| and |secondDevice|
|
||||
// Clear image in |secondDevice|
|
||||
// Verify clear color is visible in |device|
|
||||
// Verify the very first import into |device| also sees the change, since it should
|
||||
// alias the same memory
|
||||
TEST_P(VulkanImageWrappingUsageTests, ClearImageAcrossDevicesAliased) {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
|
||||
// WrapVulkanImage consumes the file descriptor so we can't import defaultFd twice.
|
||||
// Duplicate the file descriptor so we can import it twice.
|
||||
int defaultFdCopy = dup(defaultFd);
|
||||
ASSERT(defaultFdCopy != -1);
|
||||
|
||||
// Import the image on |device
|
||||
wgpu::Texture wrappedTextureAlias =
|
||||
WrapVulkanImage(device, &defaultDescriptor, defaultFdCopy, defaultAllocationSize,
|
||||
defaultMemoryTypeIndex, {});
|
||||
|
||||
// Import the image on |secondDevice|
|
||||
wgpu::Texture wrappedTexture =
|
||||
WrapVulkanImage(secondDevice, &defaultDescriptor, defaultFd, defaultAllocationSize,
|
||||
defaultMemoryTypeIndex, {});
|
||||
|
||||
// Clear |wrappedTexture| on |secondDevice|
|
||||
ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
|
||||
|
||||
int signalFd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(secondDevice.Get(),
|
||||
wrappedTexture.Get());
|
||||
|
||||
// Import the image to |device|, making sure we wait on signalFd
|
||||
int memoryFd = GetMemoryFd(deviceVk, defaultAllocation);
|
||||
wgpu::Texture nextWrappedTexture =
|
||||
WrapVulkanImage(device, &defaultDescriptor, memoryFd, defaultAllocationSize,
|
||||
defaultMemoryTypeIndex, {signalFd});
|
||||
|
||||
// Verify |device| sees the changes from |secondDevice| (waits)
|
||||
EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), nextWrappedTexture, 0, 0);
|
||||
|
||||
// Verify aliased texture sees changes from |secondDevice| (without waiting!)
|
||||
EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), wrappedTextureAlias, 0, 0);
|
||||
|
||||
IgnoreSignalSemaphore(device, nextWrappedTexture);
|
||||
IgnoreSignalSemaphore(device, wrappedTextureAlias);
|
||||
IgnoreSignalSemaphore(nextWrappedTexture);
|
||||
}
|
||||
|
||||
// Clear an image in |secondDevice|
|
||||
// Verify clear color is not visible in |device| if we import the texture as not cleared
|
||||
TEST_P(VulkanImageWrappingUsageTests, UnclearedTextureIsCleared) {
|
||||
TEST_P(VulkanImageWrappingUsageTests, UninitializedTextureIsCleared) {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
|
||||
// Import the image on |secondDevice|
|
||||
wgpu::Texture wrappedTexture =
|
||||
WrapVulkanImage(secondDevice, &defaultDescriptor, defaultFd, defaultAllocationSize,
|
||||
defaultMemoryTypeIndex, {});
|
||||
defaultMemoryTypeIndex, {}, VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
// Clear |wrappedTexture| on |secondDevice|
|
||||
ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
|
||||
|
||||
int signalFd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(secondDevice.Get(),
|
||||
wrappedTexture.Get());
|
||||
dawn_native::vulkan::ExternalImageExportInfoOpaqueFD exportInfo;
|
||||
dawn_native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo);
|
||||
|
||||
// Import the image to |device|, making sure we wait on signalFd
|
||||
// Import the image to |device|, making sure we wait on the semaphore
|
||||
int memoryFd = GetMemoryFd(deviceVk, defaultAllocation);
|
||||
wgpu::Texture nextWrappedTexture =
|
||||
WrapVulkanImage(device, &defaultDescriptor, memoryFd, defaultAllocationSize,
|
||||
defaultMemoryTypeIndex, {signalFd}, false);
|
||||
defaultMemoryTypeIndex, exportInfo.semaphoreHandles,
|
||||
exportInfo.releasedOldLayout, exportInfo.releasedNewLayout, false);
|
||||
|
||||
// Verify |device| doesn't see the changes from |secondDevice|
|
||||
EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 0, 0, 0), nextWrappedTexture, 0, 0);
|
||||
|
||||
IgnoreSignalSemaphore(device, nextWrappedTexture);
|
||||
IgnoreSignalSemaphore(nextWrappedTexture);
|
||||
}
|
||||
|
||||
// Import a texture into |secondDevice|
|
||||
@ -558,19 +546,22 @@ namespace dawn_native { namespace vulkan {
|
||||
// Import the image on |secondDevice|
|
||||
wgpu::Texture wrappedTexture =
|
||||
WrapVulkanImage(secondDevice, &defaultDescriptor, defaultFd, defaultAllocationSize,
|
||||
defaultMemoryTypeIndex, {});
|
||||
defaultMemoryTypeIndex, {}, VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
// Clear |wrappedTexture| on |secondDevice|
|
||||
ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
|
||||
|
||||
int signalFd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(secondDevice.Get(),
|
||||
wrappedTexture.Get());
|
||||
dawn_native::vulkan::ExternalImageExportInfoOpaqueFD exportInfo;
|
||||
dawn_native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo);
|
||||
|
||||
// Import the image to |device|, making sure we wait on |signalFd|
|
||||
// Import the image to |device|, making sure we wait on the semaphore
|
||||
int memoryFd = GetMemoryFd(deviceVk, defaultAllocation);
|
||||
wgpu::Texture deviceWrappedTexture =
|
||||
WrapVulkanImage(device, &defaultDescriptor, memoryFd, defaultAllocationSize,
|
||||
defaultMemoryTypeIndex, {signalFd});
|
||||
defaultMemoryTypeIndex, exportInfo.semaphoreHandles,
|
||||
exportInfo.releasedOldLayout, exportInfo.releasedNewLayout);
|
||||
|
||||
// Create a second texture on |device|
|
||||
wgpu::Texture copyDstTexture = device.CreateTexture(&defaultDescriptor);
|
||||
@ -581,7 +572,7 @@ namespace dawn_native { namespace vulkan {
|
||||
// Verify |copyDstTexture| sees changes from |secondDevice|
|
||||
EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), copyDstTexture, 0, 0);
|
||||
|
||||
IgnoreSignalSemaphore(device, deviceWrappedTexture);
|
||||
IgnoreSignalSemaphore(deviceWrappedTexture);
|
||||
}
|
||||
|
||||
// Import a texture into |device|
|
||||
@ -596,21 +587,23 @@ namespace dawn_native { namespace vulkan {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
|
||||
// Import the image on |device|
|
||||
wgpu::Texture wrappedTexture =
|
||||
WrapVulkanImage(device, &defaultDescriptor, defaultFd, defaultAllocationSize,
|
||||
defaultMemoryTypeIndex, {});
|
||||
wgpu::Texture wrappedTexture = WrapVulkanImage(
|
||||
device, &defaultDescriptor, defaultFd, defaultAllocationSize, defaultMemoryTypeIndex,
|
||||
{}, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
// Clear |wrappedTexture| on |device|
|
||||
ClearImage(device, wrappedTexture, {5 / 255.0f, 6 / 255.0f, 7 / 255.0f, 8 / 255.0f});
|
||||
|
||||
int signalFd =
|
||||
dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(device.Get(), wrappedTexture.Get());
|
||||
dawn_native::vulkan::ExternalImageExportInfoOpaqueFD exportInfo;
|
||||
dawn_native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &exportInfo);
|
||||
|
||||
// Import the image to |secondDevice|, making sure we wait on |signalFd|
|
||||
// Import the image to |secondDevice|, making sure we wait on the semaphore
|
||||
int memoryFd = GetMemoryFd(deviceVk, defaultAllocation);
|
||||
wgpu::Texture secondDeviceWrappedTexture =
|
||||
WrapVulkanImage(secondDevice, &defaultDescriptor, memoryFd, defaultAllocationSize,
|
||||
defaultMemoryTypeIndex, {signalFd});
|
||||
defaultMemoryTypeIndex, exportInfo.semaphoreHandles,
|
||||
exportInfo.releasedOldLayout, exportInfo.releasedNewLayout);
|
||||
|
||||
// Create a texture with color B on |secondDevice|
|
||||
wgpu::Texture copySrcTexture = secondDevice.CreateTexture(&defaultDescriptor);
|
||||
@ -622,18 +615,21 @@ namespace dawn_native { namespace vulkan {
|
||||
secondDeviceWrappedTexture);
|
||||
|
||||
// Re-import back into |device|, waiting on |secondDevice|'s signal
|
||||
signalFd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(
|
||||
secondDevice.Get(), secondDeviceWrappedTexture.Get());
|
||||
dawn_native::vulkan::ExternalImageExportInfoOpaqueFD secondExportInfo;
|
||||
dawn_native::vulkan::ExportVulkanImage(secondDeviceWrappedTexture.Get(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
&secondExportInfo);
|
||||
memoryFd = GetMemoryFd(deviceVk, defaultAllocation);
|
||||
|
||||
wgpu::Texture nextWrappedTexture =
|
||||
WrapVulkanImage(device, &defaultDescriptor, memoryFd, defaultAllocationSize,
|
||||
defaultMemoryTypeIndex, {signalFd});
|
||||
defaultMemoryTypeIndex, secondExportInfo.semaphoreHandles,
|
||||
secondExportInfo.releasedOldLayout, secondExportInfo.releasedNewLayout);
|
||||
|
||||
// Verify |nextWrappedTexture| contains the color from our copy
|
||||
EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), nextWrappedTexture, 0, 0);
|
||||
|
||||
IgnoreSignalSemaphore(device, nextWrappedTexture);
|
||||
IgnoreSignalSemaphore(nextWrappedTexture);
|
||||
}
|
||||
|
||||
// Import a texture from |secondDevice|
|
||||
@ -645,19 +641,22 @@ namespace dawn_native { namespace vulkan {
|
||||
// Import the image on |secondDevice|
|
||||
wgpu::Texture wrappedTexture =
|
||||
WrapVulkanImage(secondDevice, &defaultDescriptor, defaultFd, defaultAllocationSize,
|
||||
defaultMemoryTypeIndex, {});
|
||||
defaultMemoryTypeIndex, {}, VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
// Clear |wrappedTexture| on |secondDevice|
|
||||
ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
|
||||
|
||||
int signalFd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(secondDevice.Get(),
|
||||
wrappedTexture.Get());
|
||||
dawn_native::vulkan::ExternalImageExportInfoOpaqueFD exportInfo;
|
||||
dawn_native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo);
|
||||
|
||||
// Import the image to |device|, making sure we wait on |signalFd|
|
||||
// Import the image to |device|, making sure we wait on the semaphore
|
||||
int memoryFd = GetMemoryFd(deviceVk, defaultAllocation);
|
||||
wgpu::Texture deviceWrappedTexture =
|
||||
WrapVulkanImage(device, &defaultDescriptor, memoryFd, defaultAllocationSize,
|
||||
defaultMemoryTypeIndex, {signalFd});
|
||||
defaultMemoryTypeIndex, exportInfo.semaphoreHandles,
|
||||
exportInfo.releasedOldLayout, exportInfo.releasedNewLayout);
|
||||
|
||||
// Create a destination buffer on |device|
|
||||
wgpu::BufferDescriptor bufferDesc;
|
||||
@ -681,7 +680,7 @@ namespace dawn_native { namespace vulkan {
|
||||
uint32_t expected = 0x04030201;
|
||||
EXPECT_BUFFER_U32_EQ(expected, copyDstBuffer, 0);
|
||||
|
||||
IgnoreSignalSemaphore(device, deviceWrappedTexture);
|
||||
IgnoreSignalSemaphore(deviceWrappedTexture);
|
||||
}
|
||||
|
||||
// Import a texture into |device|
|
||||
@ -696,21 +695,23 @@ namespace dawn_native { namespace vulkan {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
|
||||
// Import the image on |device|
|
||||
wgpu::Texture wrappedTexture =
|
||||
WrapVulkanImage(device, &defaultDescriptor, defaultFd, defaultAllocationSize,
|
||||
defaultMemoryTypeIndex, {});
|
||||
wgpu::Texture wrappedTexture = WrapVulkanImage(
|
||||
device, &defaultDescriptor, defaultFd, defaultAllocationSize, defaultMemoryTypeIndex,
|
||||
{}, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
// Clear |wrappedTexture| on |device|
|
||||
ClearImage(device, wrappedTexture, {5 / 255.0f, 6 / 255.0f, 7 / 255.0f, 8 / 255.0f});
|
||||
|
||||
int signalFd =
|
||||
dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(device.Get(), wrappedTexture.Get());
|
||||
dawn_native::vulkan::ExternalImageExportInfoOpaqueFD exportInfo;
|
||||
dawn_native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo);
|
||||
|
||||
// Import the image to |secondDevice|, making sure we wait on |signalFd|
|
||||
int memoryFd = GetMemoryFd(deviceVk, defaultAllocation);
|
||||
wgpu::Texture secondDeviceWrappedTexture =
|
||||
WrapVulkanImage(secondDevice, &defaultDescriptor, memoryFd, defaultAllocationSize,
|
||||
defaultMemoryTypeIndex, {signalFd});
|
||||
defaultMemoryTypeIndex, exportInfo.semaphoreHandles,
|
||||
exportInfo.releasedOldLayout, exportInfo.releasedNewLayout);
|
||||
|
||||
// Copy color B on |secondDevice|
|
||||
wgpu::Queue secondDeviceQueue = secondDevice.GetDefaultQueue();
|
||||
@ -732,18 +733,21 @@ namespace dawn_native { namespace vulkan {
|
||||
secondDeviceQueue.Submit(1, &commands);
|
||||
|
||||
// Re-import back into |device|, waiting on |secondDevice|'s signal
|
||||
signalFd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(
|
||||
secondDevice.Get(), secondDeviceWrappedTexture.Get());
|
||||
dawn_native::vulkan::ExternalImageExportInfoOpaqueFD secondExportInfo;
|
||||
dawn_native::vulkan::ExportVulkanImage(secondDeviceWrappedTexture.Get(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
&secondExportInfo);
|
||||
memoryFd = GetMemoryFd(deviceVk, defaultAllocation);
|
||||
|
||||
wgpu::Texture nextWrappedTexture =
|
||||
WrapVulkanImage(device, &defaultDescriptor, memoryFd, defaultAllocationSize,
|
||||
defaultMemoryTypeIndex, {signalFd});
|
||||
defaultMemoryTypeIndex, secondExportInfo.semaphoreHandles,
|
||||
secondExportInfo.releasedOldLayout, secondExportInfo.releasedNewLayout);
|
||||
|
||||
// Verify |nextWrappedTexture| contains the color from our copy
|
||||
EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), nextWrappedTexture, 0, 0);
|
||||
|
||||
IgnoreSignalSemaphore(device, nextWrappedTexture);
|
||||
IgnoreSignalSemaphore(nextWrappedTexture);
|
||||
}
|
||||
|
||||
// Import a texture from |secondDevice|
|
||||
@ -756,19 +760,22 @@ namespace dawn_native { namespace vulkan {
|
||||
// Import the image on |secondDevice|
|
||||
wgpu::Texture wrappedTexture =
|
||||
WrapVulkanImage(secondDevice, &defaultDescriptor, defaultFd, defaultAllocationSize,
|
||||
defaultMemoryTypeIndex, {});
|
||||
defaultMemoryTypeIndex, {}, VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
// Clear |wrappedTexture| on |secondDevice|
|
||||
ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
|
||||
|
||||
int signalFd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(secondDevice.Get(),
|
||||
wrappedTexture.Get());
|
||||
dawn_native::vulkan::ExternalImageExportInfoOpaqueFD exportInfo;
|
||||
dawn_native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo);
|
||||
|
||||
// Import the image to |device|, making sure we wait on |signalFd|
|
||||
// Import the image to |device|, making sure we wait on the semaphore
|
||||
int memoryFd = GetMemoryFd(deviceVk, defaultAllocation);
|
||||
wgpu::Texture deviceWrappedTexture =
|
||||
WrapVulkanImage(device, &defaultDescriptor, memoryFd, defaultAllocationSize,
|
||||
defaultMemoryTypeIndex, {signalFd});
|
||||
defaultMemoryTypeIndex, exportInfo.semaphoreHandles,
|
||||
exportInfo.releasedOldLayout, exportInfo.releasedNewLayout);
|
||||
|
||||
// Create a second texture on |device|
|
||||
wgpu::Texture copyDstTexture = device.CreateTexture(&defaultDescriptor);
|
||||
@ -788,7 +795,7 @@ namespace dawn_native { namespace vulkan {
|
||||
// Verify |secondCopyDstTexture| sees changes from |secondDevice|
|
||||
EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), secondCopyDstTexture, 0, 0);
|
||||
|
||||
IgnoreSignalSemaphore(device, deviceWrappedTexture);
|
||||
IgnoreSignalSemaphore(deviceWrappedTexture);
|
||||
}
|
||||
|
||||
// Tex A on device 3 (external export)
|
||||
@ -844,10 +851,12 @@ namespace dawn_native { namespace vulkan {
|
||||
|
||||
// Import TexA, TexB on device 3
|
||||
wgpu::Texture wrappedTexADevice3 = WrapVulkanImage(
|
||||
thirdDevice, &defaultDescriptor, memoryFdA, allocationSizeA, memoryTypeIndexA, {});
|
||||
thirdDevice, &defaultDescriptor, memoryFdA, allocationSizeA, memoryTypeIndexA, {},
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
wgpu::Texture wrappedTexBDevice3 = WrapVulkanImage(
|
||||
thirdDevice, &defaultDescriptor, memoryFdB, allocationSizeB, memoryTypeIndexB, {});
|
||||
thirdDevice, &defaultDescriptor, memoryFdB, allocationSizeB, memoryTypeIndexB, {},
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
|
||||
// Clear TexA
|
||||
ClearImage(thirdDevice, wrappedTexADevice3,
|
||||
@ -857,32 +866,39 @@ namespace dawn_native { namespace vulkan {
|
||||
SimpleCopyTextureToTexture(thirdDevice, thirdDeviceQueue, wrappedTexADevice3,
|
||||
wrappedTexBDevice3);
|
||||
|
||||
int signalFdTexBDevice3 = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(
|
||||
thirdDevice.Get(), wrappedTexBDevice3.Get());
|
||||
IgnoreSignalSemaphore(thirdDevice, wrappedTexADevice3);
|
||||
dawn_native::vulkan::ExternalImageExportInfoOpaqueFD exportInfoTexBDevice3;
|
||||
dawn_native::vulkan::ExportVulkanImage(
|
||||
wrappedTexBDevice3.Get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfoTexBDevice3);
|
||||
|
||||
IgnoreSignalSemaphore(wrappedTexADevice3);
|
||||
|
||||
// Import TexB, TexC on device 2
|
||||
memoryFdB = GetMemoryFd(secondDeviceVk, allocationB);
|
||||
wgpu::Texture wrappedTexBDevice2 =
|
||||
WrapVulkanImage(secondDevice, &defaultDescriptor, memoryFdB, allocationSizeB,
|
||||
memoryTypeIndexB, {signalFdTexBDevice3});
|
||||
wgpu::Texture wrappedTexBDevice2 = WrapVulkanImage(
|
||||
secondDevice, &defaultDescriptor, memoryFdB, allocationSizeB, memoryTypeIndexB,
|
||||
exportInfoTexBDevice3.semaphoreHandles, exportInfoTexBDevice3.releasedOldLayout,
|
||||
exportInfoTexBDevice3.releasedNewLayout);
|
||||
|
||||
wgpu::Texture wrappedTexCDevice2 = WrapVulkanImage(
|
||||
secondDevice, &defaultDescriptor, memoryFdC, allocationSizeC, memoryTypeIndexC, {});
|
||||
secondDevice, &defaultDescriptor, memoryFdC, allocationSizeC, memoryTypeIndexC, {},
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
|
||||
// Copy B->C on device 2
|
||||
SimpleCopyTextureToTexture(secondDevice, secondDeviceQueue, wrappedTexBDevice2,
|
||||
wrappedTexCDevice2);
|
||||
|
||||
int signalFdTexCDevice2 = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(
|
||||
secondDevice.Get(), wrappedTexCDevice2.Get());
|
||||
IgnoreSignalSemaphore(secondDevice, wrappedTexBDevice2);
|
||||
dawn_native::vulkan::ExternalImageExportInfoOpaqueFD exportInfoTexCDevice2;
|
||||
dawn_native::vulkan::ExportVulkanImage(
|
||||
wrappedTexCDevice2.Get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfoTexCDevice2);
|
||||
|
||||
IgnoreSignalSemaphore(wrappedTexBDevice2);
|
||||
|
||||
// Import TexC on device 1
|
||||
memoryFdC = GetMemoryFd(deviceVk, allocationC);
|
||||
wgpu::Texture wrappedTexCDevice1 =
|
||||
WrapVulkanImage(device, &defaultDescriptor, memoryFdC, allocationSizeC,
|
||||
memoryTypeIndexC, {signalFdTexCDevice2});
|
||||
wgpu::Texture wrappedTexCDevice1 = WrapVulkanImage(
|
||||
device, &defaultDescriptor, memoryFdC, allocationSizeC, memoryTypeIndexC,
|
||||
exportInfoTexCDevice2.semaphoreHandles, exportInfoTexCDevice2.releasedOldLayout,
|
||||
exportInfoTexCDevice2.releasedNewLayout);
|
||||
|
||||
// Create TexD on device 1
|
||||
wgpu::Texture texD = device.CreateTexture(&defaultDescriptor);
|
||||
@ -900,7 +916,7 @@ namespace dawn_native { namespace vulkan {
|
||||
deviceVk->GetFencedDeleter()->DeleteWhenUnused(imageC);
|
||||
deviceVk->GetFencedDeleter()->DeleteWhenUnused(allocationC);
|
||||
|
||||
IgnoreSignalSemaphore(device, wrappedTexCDevice1);
|
||||
IgnoreSignalSemaphore(wrappedTexCDevice1);
|
||||
}
|
||||
|
||||
// Tests a larger image is preserved when importing
|
||||
@ -938,8 +954,9 @@ namespace dawn_native { namespace vulkan {
|
||||
&allocationA, &allocationSizeA, &memoryTypeIndexA, &memoryFdA);
|
||||
|
||||
// Import the image on |secondDevice|
|
||||
wgpu::Texture wrappedTexture = WrapVulkanImage(secondDevice, &descriptor, memoryFdA,
|
||||
allocationSizeA, memoryTypeIndexA, {});
|
||||
wgpu::Texture wrappedTexture =
|
||||
WrapVulkanImage(secondDevice, &descriptor, memoryFdA, allocationSizeA, memoryTypeIndexA,
|
||||
{}, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
|
||||
// Draw a non-trivial picture
|
||||
uint32_t width = 640, height = 480, pixelSize = 4;
|
||||
@ -975,13 +992,17 @@ namespace dawn_native { namespace vulkan {
|
||||
secondDeviceQueue.Submit(1, &commands);
|
||||
}
|
||||
|
||||
int signalFd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(secondDevice.Get(),
|
||||
wrappedTexture.Get());
|
||||
dawn_native::vulkan::ExternalImageExportInfoOpaqueFD exportInfo;
|
||||
dawn_native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo);
|
||||
|
||||
int memoryFd = GetMemoryFd(secondDeviceVk, allocationA);
|
||||
|
||||
// Import the image on |device|
|
||||
wgpu::Texture nextWrappedTexture = WrapVulkanImage(
|
||||
device, &descriptor, memoryFd, allocationSizeA, memoryTypeIndexA, {signalFd});
|
||||
wgpu::Texture nextWrappedTexture =
|
||||
WrapVulkanImage(device, &descriptor, memoryFd, allocationSizeA, memoryTypeIndexA,
|
||||
exportInfo.semaphoreHandles, exportInfo.releasedOldLayout,
|
||||
exportInfo.releasedNewLayout);
|
||||
|
||||
// Copy the image into a buffer for comparison
|
||||
wgpu::BufferDescriptor copyDesc;
|
||||
@ -1006,7 +1027,7 @@ namespace dawn_native { namespace vulkan {
|
||||
EXPECT_BUFFER_U32_RANGE_EQ(reinterpret_cast<uint32_t*>(data.data()), copyDstBuffer, 0,
|
||||
data.size() / 4);
|
||||
|
||||
IgnoreSignalSemaphore(device, nextWrappedTexture);
|
||||
IgnoreSignalSemaphore(nextWrappedTexture);
|
||||
secondDeviceVk->GetFencedDeleter()->DeleteWhenUnused(imageA);
|
||||
secondDeviceVk->GetFencedDeleter()->DeleteWhenUnused(allocationA);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user