From 9f1579469dbed64f122b1d4f1d286a7360e32c12 Mon Sep 17 00:00:00 2001 From: Brandon Jones Date: Thu, 27 Jan 2022 18:05:28 +0000 Subject: [PATCH] Initialize External Texture's Internal Params Buffer Initializes a uniform buffer on ExternalTexture objects that holds data used by in shaders. Includes modifications to some Mock tests, which should be using mock external texture objects instead of real ones. Bug: dawn:1082 Change-Id: I34c02eadaf38aebf22630ac99098e0637ca1279c Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/78240 Reviewed-by: Kai Ninomiya Commit-Queue: Brandon1 Jones --- src/dawn_native/Device.cpp | 4 +- src/dawn_native/Device.h | 5 ++- src/dawn_native/ExternalTexture.cpp | 39 +++++++++++++++++++ src/dawn_native/ExternalTexture.h | 11 ++++++ src/dawn_native/d3d12/D3D12Backend.cpp | 2 +- src/dawn_native/d3d12/DeviceD3D12.cpp | 2 +- src/dawn_native/d3d12/DeviceD3D12.h | 11 +++--- .../unittests/native/DestroyObjectTests.cpp | 21 +++++++--- src/tests/unittests/native/mocks/DeviceMock.h | 4 ++ 9 files changed, 82 insertions(+), 17 deletions(-) diff --git a/src/dawn_native/Device.cpp b/src/dawn_native/Device.cpp index fe9722df53..582ec87670 100644 --- a/src/dawn_native/Device.cpp +++ b/src/dawn_native/Device.cpp @@ -1152,7 +1152,7 @@ namespace dawn::native { ExternalTextureBase* DeviceBase::APICreateExternalTexture( const ExternalTextureDescriptor* descriptor) { Ref result = nullptr; - if (ConsumedError(CreateExternalTexture(descriptor), &result, + if (ConsumedError(CreateExternalTextureImpl(descriptor), &result, "calling %s.CreateExternalTexture(%s).", this, descriptor)) { return ExternalTextureBase::MakeError(this); } @@ -1418,7 +1418,7 @@ namespace dawn::native { return GetOrCreatePipelineLayout(descriptor); } - ResultOrError> DeviceBase::CreateExternalTexture( + ResultOrError> DeviceBase::CreateExternalTextureImpl( const ExternalTextureDescriptor* descriptor) { if (IsValidationEnabled()) { DAWN_TRY_CONTEXT(ValidateExternalTextureDescriptor(this, descriptor), "validating %s", diff --git a/src/dawn_native/Device.h b/src/dawn_native/Device.h index 75e293ff73..6c6a3657ac 100644 --- a/src/dawn_native/Device.h +++ b/src/dawn_native/Device.h @@ -206,8 +206,7 @@ namespace dawn::native { const ComputePipelineDescriptor* descriptor, WGPUCreateComputePipelineAsyncCallback callback, void* userdata); - ResultOrError> CreateExternalTexture( - const ExternalTextureDescriptor* descriptor); + ResultOrError> CreatePipelineLayout( const PipelineLayoutDescriptor* descriptor); ResultOrError> CreateQuerySet(const QuerySetDescriptor* descriptor); @@ -394,6 +393,8 @@ namespace dawn::native { PipelineCompatibilityToken pipelineCompatibilityToken) = 0; virtual ResultOrError> CreateBufferImpl( const BufferDescriptor* descriptor) = 0; + virtual ResultOrError> CreateExternalTextureImpl( + const ExternalTextureDescriptor* descriptor); virtual ResultOrError> CreatePipelineLayoutImpl( const PipelineLayoutDescriptor* descriptor) = 0; virtual ResultOrError> CreateQuerySetImpl( diff --git a/src/dawn_native/ExternalTexture.cpp b/src/dawn_native/ExternalTexture.cpp index 61a9c4d453..ed157bc135 100644 --- a/src/dawn_native/ExternalTexture.cpp +++ b/src/dawn_native/ExternalTexture.cpp @@ -14,8 +14,10 @@ #include "dawn_native/ExternalTexture.h" +#include "dawn_native/Buffer.h" #include "dawn_native/Device.h" #include "dawn_native/ObjectType_autogen.h" +#include "dawn_native/Queue.h" #include "dawn_native/Texture.h" #include "dawn_native/dawn_platform.h" @@ -123,6 +125,43 @@ namespace dawn::native { mTextureViews[0] = descriptor->plane0; mTextureViews[1] = descriptor->plane1; + // We must create a buffer to store parameters needed by a shader that operates on this + // external texture. + BufferDescriptor bufferDesc; + bufferDesc.size = sizeof(ExternalTextureParams); + bufferDesc.usage = wgpu::BufferUsage::Uniform | wgpu::BufferUsage::CopyDst; + bufferDesc.label = "Dawn_External_Texture_Params_Buffer"; + + DAWN_TRY_ASSIGN(mParamsBuffer, device->CreateBuffer(&bufferDesc)); + + // Dawn & Tint's YUV to RGB conversion implementation was inspired by the conversions found + // in libYUV. If this implementation needs expanded to support more colorspaces, this file + // is an excellent reference: chromium/src/third_party/libyuv/source/row_common.cc. + // + // The conversion from YUV to RGB looks like this: + // r = Y * 1.164 + V * vr + // g = Y * 1.164 - U * ug - V * vg + // b = Y * 1.164 + U * ub + // + // By changing the values of vr, vg, ub, and ug we can change the destination color space. + ExternalTextureParams params; + params.numPlanes = descriptor->plane1 == nullptr ? 1 : 2; + + switch (descriptor->colorSpace) { + case wgpu::PredefinedColorSpace::Srgb: + // Numbers derived from ITU-R recommendation for limited range BT.709 + params.vr = 1.793; + params.vg = 0.392; + params.ub = 0.813; + params.ug = 2.017; + break; + case wgpu::PredefinedColorSpace::Undefined: + break; + } + + DAWN_TRY(device->GetQueue()->WriteBuffer(mParamsBuffer.Get(), 0, ¶ms, + sizeof(ExternalTextureParams))); + return {}; } diff --git a/src/dawn_native/ExternalTexture.h b/src/dawn_native/ExternalTexture.h index c66ef1e027..0b8b28c528 100644 --- a/src/dawn_native/ExternalTexture.h +++ b/src/dawn_native/ExternalTexture.h @@ -26,6 +26,14 @@ namespace dawn::native { class TextureViewBase; + struct ExternalTextureParams { + uint32_t numPlanes; + float vr; + float vg; + float ub; + float ug; + }; + MaybeError ValidateExternalTextureDescriptor(const DeviceBase* device, const ExternalTextureDescriptor* descriptor); @@ -54,7 +62,10 @@ namespace dawn::native { enum class ExternalTextureState { Alive, Destroyed }; ExternalTextureBase(DeviceBase* device, const ExternalTextureDescriptor* descriptor); ExternalTextureBase(DeviceBase* device, ObjectBase::ErrorTag tag); + + Ref mParamsBuffer; std::array, kMaxPlanesPerFormat> mTextureViews; + ExternalTextureState mState; }; } // namespace dawn::native diff --git a/src/dawn_native/d3d12/D3D12Backend.cpp b/src/dawn_native/d3d12/D3D12Backend.cpp index a79be15b78..4510453986 100644 --- a/src/dawn_native/d3d12/D3D12Backend.cpp +++ b/src/dawn_native/d3d12/D3D12Backend.cpp @@ -106,7 +106,7 @@ namespace dawn::native::d3d12 { return nullptr; } - Ref texture = backendDevice->CreateExternalTexture( + Ref texture = backendDevice->CreateD3D12ExternalTexture( &textureDescriptor, mD3D12Resource, std::move(d3d11on12Resource), descriptor->isSwapChainTexture, descriptor->isInitialized); diff --git a/src/dawn_native/d3d12/DeviceD3D12.cpp b/src/dawn_native/d3d12/DeviceD3D12.cpp index fd68df36f7..7a72f6e3e8 100644 --- a/src/dawn_native/d3d12/DeviceD3D12.cpp +++ b/src/dawn_native/d3d12/DeviceD3D12.cpp @@ -530,7 +530,7 @@ namespace dawn::native::d3d12 { initialUsage); } - Ref Device::CreateExternalTexture( + Ref Device::CreateD3D12ExternalTexture( const TextureDescriptor* descriptor, ComPtr d3d12Texture, Ref d3d11on12Resource, diff --git a/src/dawn_native/d3d12/DeviceD3D12.h b/src/dawn_native/d3d12/DeviceD3D12.h index 09b2246578..609de05bf9 100644 --- a/src/dawn_native/d3d12/DeviceD3D12.h +++ b/src/dawn_native/d3d12/DeviceD3D12.h @@ -128,11 +128,12 @@ namespace dawn::native::d3d12 { StagingDescriptorAllocator* GetDepthStencilViewAllocator() const; - Ref CreateExternalTexture(const TextureDescriptor* descriptor, - ComPtr d3d12Texture, - Ref d3d11on12Resource, - bool isSwapChainTexture, - bool isInitialized); + Ref CreateD3D12ExternalTexture( + const TextureDescriptor* descriptor, + ComPtr d3d12Texture, + Ref d3d11on12Resource, + bool isSwapChainTexture, + bool isInitialized); ComPtr GetOrCreateD3D11on12Device(); diff --git a/src/tests/unittests/native/DestroyObjectTests.cpp b/src/tests/unittests/native/DestroyObjectTests.cpp index 548dbb4e25..4b6b0319a1 100644 --- a/src/tests/unittests/native/DestroyObjectTests.cpp +++ b/src/tests/unittests/native/DestroyObjectTests.cpp @@ -285,13 +285,18 @@ namespace dawn::native { namespace { EXPECT_FALSE(externalTextureMock.IsAlive()); } - // We can use an actual ExternalTexture object to test the implicit case. TEST_F(DestroyObjectTests, ExternalTextureImplicit) { - ExternalTextureDescriptor desc = {}; - Ref externalTexture; - DAWN_ASSERT_AND_ASSIGN(externalTexture, mDevice.CreateExternalTexture(&desc)); + ExternalTextureMock* externalTextureMock = new ExternalTextureMock(&mDevice); + EXPECT_CALL(*externalTextureMock, DestroyImpl).Times(1); + { + ExternalTextureDescriptor desc = {}; + Ref externalTexture; + EXPECT_CALL(mDevice, CreateExternalTextureImpl) + .WillOnce(Return(ByMove(AcquireRef(externalTextureMock)))); + DAWN_ASSERT_AND_ASSIGN(externalTexture, mDevice.CreateExternalTextureImpl(&desc)); - EXPECT_TRUE(externalTexture->IsAlive()); + EXPECT_TRUE(externalTexture->IsAlive()); + } } TEST_F(DestroyObjectTests, PipelineLayoutExplicit) { @@ -552,6 +557,7 @@ namespace dawn::native { namespace { BufferMock* bufferMock = new BufferMock(&mDevice, BufferBase::BufferState::Unmapped); CommandBufferMock* commandBufferMock = new CommandBufferMock(&mDevice); ComputePipelineMock* computePipelineMock = new ComputePipelineMock(&mDevice); + ExternalTextureMock* externalTextureMock = new ExternalTextureMock(&mDevice); PipelineLayoutMock* pipelineLayoutMock = new PipelineLayoutMock(&mDevice); QuerySetMock* querySetMock = new QuerySetMock(&mDevice); RenderPipelineMock* renderPipelineMock = new RenderPipelineMock(&mDevice); @@ -571,6 +577,7 @@ namespace dawn::native { namespace { EXPECT_CALL(*bindGroupMock, DestroyImpl).Times(1); EXPECT_CALL(*bindGroupLayoutMock, DestroyImpl).Times(1); EXPECT_CALL(*shaderModuleMock, DestroyImpl).Times(1); + EXPECT_CALL(*externalTextureMock, DestroyImpl).Times(1); EXPECT_CALL(*textureViewMock, DestroyImpl).Times(1); EXPECT_CALL(*textureMock, DestroyImpl).Times(1); EXPECT_CALL(*querySetMock, DestroyImpl).Times(1); @@ -638,7 +645,9 @@ namespace dawn::native { namespace { Ref externalTexture; { ExternalTextureDescriptor desc = {}; - DAWN_ASSERT_AND_ASSIGN(externalTexture, mDevice.CreateExternalTexture(&desc)); + EXPECT_CALL(mDevice, CreateExternalTextureImpl) + .WillOnce(Return(ByMove(AcquireRef(externalTextureMock)))); + DAWN_ASSERT_AND_ASSIGN(externalTexture, mDevice.CreateExternalTextureImpl(&desc)); EXPECT_TRUE(externalTexture->IsAlive()); } diff --git a/src/tests/unittests/native/mocks/DeviceMock.h b/src/tests/unittests/native/mocks/DeviceMock.h index 4e673f34d2..6ba104fcfb 100644 --- a/src/tests/unittests/native/mocks/DeviceMock.h +++ b/src/tests/unittests/native/mocks/DeviceMock.h @@ -68,6 +68,10 @@ namespace dawn::native { CreateUninitializedComputePipelineImpl, (const ComputePipelineDescriptor*), (override)); + MOCK_METHOD(ResultOrError>, + CreateExternalTextureImpl, + (const ExternalTextureDescriptor*), + (override)); MOCK_METHOD(ResultOrError>, CreatePipelineLayoutImpl, (const PipelineLayoutDescriptor*),