diff --git a/src/dawn_native/d3d12/D3D12Backend.cpp b/src/dawn_native/d3d12/D3D12Backend.cpp index fc10fe3a43..0b9c3a82ce 100644 --- a/src/dawn_native/d3d12/D3D12Backend.cpp +++ b/src/dawn_native/d3d12/D3D12Backend.cpp @@ -62,7 +62,13 @@ namespace dawn_native { namespace d3d12 { mFormat(descriptor->format), mMipLevelCount(descriptor->mipLevelCount), mSampleCount(descriptor->sampleCount) { - ASSERT(descriptor->nextInChain == nullptr); + ASSERT(!descriptor->nextInChain || + descriptor->nextInChain->sType == WGPUSType_DawnTextureInternalUsageDescriptor); + if (descriptor->nextInChain) { + mUsageInternal = reinterpret_cast( + descriptor->nextInChain) + ->internalUsage; + } } WGPUTexture ExternalImageDXGI::ProduceTexture( @@ -84,6 +90,13 @@ namespace dawn_native { namespace d3d12 { textureDescriptor.mipLevelCount = mMipLevelCount; textureDescriptor.sampleCount = mSampleCount; + DawnTextureInternalUsageDescriptor internalDesc = {}; + if (mUsageInternal) { + textureDescriptor.nextInChain = &internalDesc; + internalDesc.internalUsage = static_cast(mUsageInternal); + internalDesc.sType = wgpu::SType::DawnTextureInternalUsageDescriptor; + } + Ref texture = backendDevice->CreateExternalTexture( &textureDescriptor, mD3D12Resource, ExternalMutexSerial(descriptor->acquireMutexKey), ExternalMutexSerial(descriptor->releaseMutexKey), descriptor->isSwapChainTexture, diff --git a/src/include/dawn_native/D3D12Backend.h b/src/include/dawn_native/D3D12Backend.h index cfddcc2a67..e21d2d6a7f 100644 --- a/src/include/dawn_native/D3D12Backend.h +++ b/src/include/dawn_native/D3D12Backend.h @@ -79,6 +79,7 @@ namespace dawn_native { namespace d3d12 { // Contents of WGPUTextureDescriptor are stored individually since the descriptor // could outlive this image. WGPUTextureUsageFlags mUsage; + WGPUTextureUsageFlags mUsageInternal = WGPUTextureUsage_None; WGPUTextureDimension mDimension; WGPUExtent3D mSize; WGPUTextureFormat mFormat; diff --git a/src/tests/end2end/D3D12ResourceWrappingTests.cpp b/src/tests/end2end/D3D12ResourceWrappingTests.cpp index ed6b1657af..f6fdf99ae2 100644 --- a/src/tests/end2end/D3D12ResourceWrappingTests.cpp +++ b/src/tests/end2end/D3D12ResourceWrappingTests.cpp @@ -28,6 +28,11 @@ using Microsoft::WRL::ComPtr; namespace { class D3D12ResourceTestBase : public DawnTest { + protected: + std::vector GetRequiredExtensions() override { + return {"dawn-internal-usages"}; + } + public: void SetUp() override { DawnTest::SetUp(); @@ -161,11 +166,28 @@ TEST_P(D3D12SharedHandleValidation, Success) { ASSERT_NE(texture.Get(), nullptr); } -// Test an error occurs if the texture descriptor is invalid +// Test a successful wrapping of an D3D12Resource with DawnTextureInternalUsageDescriptor +TEST_P(D3D12SharedHandleValidation, SuccessWithInternalUsageDescriptor) { + DAWN_TEST_UNSUPPORTED_IF(UsesWire()); + + wgpu::DawnTextureInternalUsageDescriptor internalDesc = {}; + baseDawnDescriptor.nextInChain = &internalDesc; + internalDesc.internalUsage = wgpu::TextureUsage::CopySrc; + internalDesc.sType = wgpu::SType::DawnTextureInternalUsageDescriptor; + + wgpu::Texture texture; + ComPtr d3d11Texture; + WrapSharedHandle(&baseDawnDescriptor, &baseD3dDescriptor, &texture, &d3d11Texture); + + ASSERT_NE(texture.Get(), nullptr); +} + +// Test an error occurs if an invalid sType is the nextInChain TEST_P(D3D12SharedHandleValidation, InvalidTextureDescriptor) { DAWN_TEST_UNSUPPORTED_IF(UsesWire()); wgpu::ChainedStruct chainedDescriptor; + chainedDescriptor.sType = wgpu::SType::SurfaceDescriptorFromWindowsSwapChainPanel; baseDawnDescriptor.nextInChain = &chainedDescriptor; wgpu::Texture texture; diff --git a/src/tests/white_box/EGLImageWrappingTests.cpp b/src/tests/white_box/EGLImageWrappingTests.cpp index fdc4a42bd1..cec291e9a0 100644 --- a/src/tests/white_box/EGLImageWrappingTests.cpp +++ b/src/tests/white_box/EGLImageWrappingTests.cpp @@ -114,6 +114,11 @@ namespace { } // anonymous namespace class EGLImageTestBase : public DawnTest { + protected: + std::vector GetRequiredExtensions() override { + return {"dawn-internal-usages"}; + } + public: ScopedEGLImage CreateEGLImage(uint32_t width, uint32_t height, @@ -177,15 +182,30 @@ TEST_P(EGLImageValidationTests, Success) { ASSERT_NE(texture.Get(), nullptr); } -// Test an error occurs if the texture descriptor is invalid +// Test a successful wrapping of an EGLImage in a texture with DawnTextureInternalUsageDescriptor +TEST_P(EGLImageValidationTests, SuccessWithInternalUsageDescriptor) { + DAWN_TEST_UNSUPPORTED_IF(UsesWire()); + wgpu::DawnTextureInternalUsageDescriptor internalDesc = {}; + descriptor.nextInChain = &internalDesc; + internalDesc.internalUsage = wgpu::TextureUsage::CopySrc; + internalDesc.sType = wgpu::SType::DawnTextureInternalUsageDescriptor; + + ScopedEGLImage image = CreateDefaultEGLImage(); + wgpu::Texture texture = WrapEGLImage(&descriptor, image.getImage()); + ASSERT_NE(texture.Get(), nullptr); +} + +// Test an error occurs if an invalid sType is the nextInChain TEST_P(EGLImageValidationTests, InvalidTextureDescriptor) { DAWN_TEST_UNSUPPORTED_IF(UsesWire()); wgpu::ChainedStruct chainedDescriptor; + chainedDescriptor.sType = wgpu::SType::SurfaceDescriptorFromWindowsSwapChainPanel; descriptor.nextInChain = &chainedDescriptor; ScopedEGLImage image = CreateDefaultEGLImage(); ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapEGLImage(&descriptor, image.getImage())); + ASSERT_EQ(texture.Get(), nullptr); } @@ -291,6 +311,12 @@ class EGLImageUsageTests : public EGLImageTestBase { textureDescriptor.sampleCount = 1; textureDescriptor.mipLevelCount = 1; textureDescriptor.usage = wgpu::TextureUsage::RenderAttachment; + + wgpu::DawnTextureInternalUsageDescriptor internalDesc = {}; + textureDescriptor.nextInChain = &internalDesc; + internalDesc.internalUsage = wgpu::TextureUsage::CopySrc; + internalDesc.sType = wgpu::SType::DawnTextureInternalUsageDescriptor; + wgpu::Texture eglImageTexture = WrapEGLImage(&textureDescriptor, eglImage); ASSERT_NE(eglImageTexture, nullptr); diff --git a/src/tests/white_box/VulkanImageWrappingTestsDmaBuf.cpp b/src/tests/white_box/VulkanImageWrappingTestsDmaBuf.cpp index 1276484bfa..b5353945fb 100644 --- a/src/tests/white_box/VulkanImageWrappingTestsDmaBuf.cpp +++ b/src/tests/white_box/VulkanImageWrappingTestsDmaBuf.cpp @@ -33,6 +33,11 @@ namespace dawn_native { namespace vulkan { namespace { class VulkanImageWrappingTestBase : public DawnTest { + protected: + std::vector GetRequiredExtensions() override { + return {"dawn-internal-usages"}; + } + public: void SetUp() override { DAWN_TEST_UNSUPPORTED_IF(UsesWire()); @@ -180,10 +185,24 @@ namespace dawn_native { namespace vulkan { IgnoreSignalSemaphore(texture); } - // Test an error occurs if the texture descriptor is invalid + // Test no error occurs if the import is valid with DawnTextureInternalUsageDescriptor + TEST_P(VulkanImageWrappingValidationTests, SuccessfulImportWithInternalUsageDescriptor) { + wgpu::DawnTextureInternalUsageDescriptor internalDesc = {}; + defaultDescriptor.nextInChain = &internalDesc; + internalDesc.internalUsage = wgpu::TextureUsage::CopySrc; + internalDesc.sType = wgpu::SType::DawnTextureInternalUsageDescriptor; + + wgpu::Texture texture = WrapVulkanImage(device, &defaultDescriptor, defaultFd, + defaultStride, defaultModifier, {}, true, true); + EXPECT_NE(texture.Get(), nullptr); + IgnoreSignalSemaphore(texture); + } + + // Test an error occurs if an invalid sType is the nextInChain TEST_P(VulkanImageWrappingValidationTests, InvalidTextureDescriptor) { wgpu::ChainedStruct chainedDescriptor; - defaultDescriptor.nextInChain = &chainedDescriptor; + chainedDescriptor.sType = wgpu::SType::SurfaceDescriptorFromWindowsSwapChainPanel; + descriptor.nextInChain = &chainedDescriptor; ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapVulkanImage(device, &defaultDescriptor, defaultFd, diff --git a/src/tests/white_box/VulkanImageWrappingTestsOpaqueFD.cpp b/src/tests/white_box/VulkanImageWrappingTestsOpaqueFD.cpp index caa8f4bb93..c4e4266188 100644 --- a/src/tests/white_box/VulkanImageWrappingTestsOpaqueFD.cpp +++ b/src/tests/white_box/VulkanImageWrappingTestsOpaqueFD.cpp @@ -30,6 +30,11 @@ namespace dawn_native { namespace vulkan { namespace { class VulkanImageWrappingTestBase : public DawnTest { + protected: + std::vector GetRequiredExtensions() override { + return {"dawn-internal-usages"}; + } + public: void SetUp() override { DawnTest::SetUp(); @@ -265,9 +270,24 @@ namespace dawn_native { namespace vulkan { IgnoreSignalSemaphore(texture); } - // Test an error occurs if the texture descriptor is invalid + // Test no error occurs if the import is valid with DawnTextureInternalUsageDescriptor + TEST_P(VulkanImageWrappingValidationTests, SuccessfulImportWithInternalUsageDescriptor) { + wgpu::DawnTextureInternalUsageDescriptor internalDesc = {}; + defaultDescriptor.nextInChain = &internalDesc; + internalDesc.internalUsage = wgpu::TextureUsage::CopySrc; + internalDesc.sType = wgpu::SType::DawnTextureInternalUsageDescriptor; + + wgpu::Texture texture = + WrapVulkanImage(device, &defaultDescriptor, defaultFd, defaultAllocationSize, + defaultMemoryTypeIndex, {}, true, true); + EXPECT_NE(texture.Get(), nullptr); + IgnoreSignalSemaphore(texture); + } + + // Test an error occurs if an invalid sType is the nextInChain TEST_P(VulkanImageWrappingValidationTests, InvalidTextureDescriptor) { wgpu::ChainedStruct chainedDescriptor; + chainedDescriptor.sType = wgpu::SType::SurfaceDescriptorFromWindowsSwapChainPanel; defaultDescriptor.nextInChain = &chainedDescriptor; ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapVulkanImage(