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 <kainino@chromium.org>
Commit-Queue: Brandon1 Jones <brandon1.jones@intel.com>
This commit is contained in:
Brandon Jones 2022-01-27 18:05:28 +00:00 committed by Dawn LUCI CQ
parent 47829d806b
commit 9f1579469d
9 changed files with 82 additions and 17 deletions

View File

@ -1152,7 +1152,7 @@ namespace dawn::native {
ExternalTextureBase* DeviceBase::APICreateExternalTexture( ExternalTextureBase* DeviceBase::APICreateExternalTexture(
const ExternalTextureDescriptor* descriptor) { const ExternalTextureDescriptor* descriptor) {
Ref<ExternalTextureBase> result = nullptr; Ref<ExternalTextureBase> result = nullptr;
if (ConsumedError(CreateExternalTexture(descriptor), &result, if (ConsumedError(CreateExternalTextureImpl(descriptor), &result,
"calling %s.CreateExternalTexture(%s).", this, descriptor)) { "calling %s.CreateExternalTexture(%s).", this, descriptor)) {
return ExternalTextureBase::MakeError(this); return ExternalTextureBase::MakeError(this);
} }
@ -1418,7 +1418,7 @@ namespace dawn::native {
return GetOrCreatePipelineLayout(descriptor); return GetOrCreatePipelineLayout(descriptor);
} }
ResultOrError<Ref<ExternalTextureBase>> DeviceBase::CreateExternalTexture( ResultOrError<Ref<ExternalTextureBase>> DeviceBase::CreateExternalTextureImpl(
const ExternalTextureDescriptor* descriptor) { const ExternalTextureDescriptor* descriptor) {
if (IsValidationEnabled()) { if (IsValidationEnabled()) {
DAWN_TRY_CONTEXT(ValidateExternalTextureDescriptor(this, descriptor), "validating %s", DAWN_TRY_CONTEXT(ValidateExternalTextureDescriptor(this, descriptor), "validating %s",

View File

@ -206,8 +206,7 @@ namespace dawn::native {
const ComputePipelineDescriptor* descriptor, const ComputePipelineDescriptor* descriptor,
WGPUCreateComputePipelineAsyncCallback callback, WGPUCreateComputePipelineAsyncCallback callback,
void* userdata); void* userdata);
ResultOrError<Ref<ExternalTextureBase>> CreateExternalTexture(
const ExternalTextureDescriptor* descriptor);
ResultOrError<Ref<PipelineLayoutBase>> CreatePipelineLayout( ResultOrError<Ref<PipelineLayoutBase>> CreatePipelineLayout(
const PipelineLayoutDescriptor* descriptor); const PipelineLayoutDescriptor* descriptor);
ResultOrError<Ref<QuerySetBase>> CreateQuerySet(const QuerySetDescriptor* descriptor); ResultOrError<Ref<QuerySetBase>> CreateQuerySet(const QuerySetDescriptor* descriptor);
@ -394,6 +393,8 @@ namespace dawn::native {
PipelineCompatibilityToken pipelineCompatibilityToken) = 0; PipelineCompatibilityToken pipelineCompatibilityToken) = 0;
virtual ResultOrError<Ref<BufferBase>> CreateBufferImpl( virtual ResultOrError<Ref<BufferBase>> CreateBufferImpl(
const BufferDescriptor* descriptor) = 0; const BufferDescriptor* descriptor) = 0;
virtual ResultOrError<Ref<ExternalTextureBase>> CreateExternalTextureImpl(
const ExternalTextureDescriptor* descriptor);
virtual ResultOrError<Ref<PipelineLayoutBase>> CreatePipelineLayoutImpl( virtual ResultOrError<Ref<PipelineLayoutBase>> CreatePipelineLayoutImpl(
const PipelineLayoutDescriptor* descriptor) = 0; const PipelineLayoutDescriptor* descriptor) = 0;
virtual ResultOrError<Ref<QuerySetBase>> CreateQuerySetImpl( virtual ResultOrError<Ref<QuerySetBase>> CreateQuerySetImpl(

View File

@ -14,8 +14,10 @@
#include "dawn_native/ExternalTexture.h" #include "dawn_native/ExternalTexture.h"
#include "dawn_native/Buffer.h"
#include "dawn_native/Device.h" #include "dawn_native/Device.h"
#include "dawn_native/ObjectType_autogen.h" #include "dawn_native/ObjectType_autogen.h"
#include "dawn_native/Queue.h"
#include "dawn_native/Texture.h" #include "dawn_native/Texture.h"
#include "dawn_native/dawn_platform.h" #include "dawn_native/dawn_platform.h"
@ -123,6 +125,43 @@ namespace dawn::native {
mTextureViews[0] = descriptor->plane0; mTextureViews[0] = descriptor->plane0;
mTextureViews[1] = descriptor->plane1; 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, &params,
sizeof(ExternalTextureParams)));
return {}; return {};
} }

View File

@ -26,6 +26,14 @@ namespace dawn::native {
class TextureViewBase; class TextureViewBase;
struct ExternalTextureParams {
uint32_t numPlanes;
float vr;
float vg;
float ub;
float ug;
};
MaybeError ValidateExternalTextureDescriptor(const DeviceBase* device, MaybeError ValidateExternalTextureDescriptor(const DeviceBase* device,
const ExternalTextureDescriptor* descriptor); const ExternalTextureDescriptor* descriptor);
@ -54,7 +62,10 @@ namespace dawn::native {
enum class ExternalTextureState { Alive, Destroyed }; enum class ExternalTextureState { Alive, Destroyed };
ExternalTextureBase(DeviceBase* device, const ExternalTextureDescriptor* descriptor); ExternalTextureBase(DeviceBase* device, const ExternalTextureDescriptor* descriptor);
ExternalTextureBase(DeviceBase* device, ObjectBase::ErrorTag tag); ExternalTextureBase(DeviceBase* device, ObjectBase::ErrorTag tag);
Ref<BufferBase> mParamsBuffer;
std::array<Ref<TextureViewBase>, kMaxPlanesPerFormat> mTextureViews; std::array<Ref<TextureViewBase>, kMaxPlanesPerFormat> mTextureViews;
ExternalTextureState mState; ExternalTextureState mState;
}; };
} // namespace dawn::native } // namespace dawn::native

View File

@ -106,7 +106,7 @@ namespace dawn::native::d3d12 {
return nullptr; return nullptr;
} }
Ref<TextureBase> texture = backendDevice->CreateExternalTexture( Ref<TextureBase> texture = backendDevice->CreateD3D12ExternalTexture(
&textureDescriptor, mD3D12Resource, std::move(d3d11on12Resource), &textureDescriptor, mD3D12Resource, std::move(d3d11on12Resource),
descriptor->isSwapChainTexture, descriptor->isInitialized); descriptor->isSwapChainTexture, descriptor->isInitialized);

View File

@ -530,7 +530,7 @@ namespace dawn::native::d3d12 {
initialUsage); initialUsage);
} }
Ref<TextureBase> Device::CreateExternalTexture( Ref<TextureBase> Device::CreateD3D12ExternalTexture(
const TextureDescriptor* descriptor, const TextureDescriptor* descriptor,
ComPtr<ID3D12Resource> d3d12Texture, ComPtr<ID3D12Resource> d3d12Texture,
Ref<D3D11on12ResourceCacheEntry> d3d11on12Resource, Ref<D3D11on12ResourceCacheEntry> d3d11on12Resource,

View File

@ -128,7 +128,8 @@ namespace dawn::native::d3d12 {
StagingDescriptorAllocator* GetDepthStencilViewAllocator() const; StagingDescriptorAllocator* GetDepthStencilViewAllocator() const;
Ref<TextureBase> CreateExternalTexture(const TextureDescriptor* descriptor, Ref<TextureBase> CreateD3D12ExternalTexture(
const TextureDescriptor* descriptor,
ComPtr<ID3D12Resource> d3d12Texture, ComPtr<ID3D12Resource> d3d12Texture,
Ref<D3D11on12ResourceCacheEntry> d3d11on12Resource, Ref<D3D11on12ResourceCacheEntry> d3d11on12Resource,
bool isSwapChainTexture, bool isSwapChainTexture,

View File

@ -285,14 +285,19 @@ namespace dawn::native { namespace {
EXPECT_FALSE(externalTextureMock.IsAlive()); EXPECT_FALSE(externalTextureMock.IsAlive());
} }
// We can use an actual ExternalTexture object to test the implicit case.
TEST_F(DestroyObjectTests, ExternalTextureImplicit) { TEST_F(DestroyObjectTests, ExternalTextureImplicit) {
ExternalTextureMock* externalTextureMock = new ExternalTextureMock(&mDevice);
EXPECT_CALL(*externalTextureMock, DestroyImpl).Times(1);
{
ExternalTextureDescriptor desc = {}; ExternalTextureDescriptor desc = {};
Ref<ExternalTextureBase> externalTexture; Ref<ExternalTextureBase> externalTexture;
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()); EXPECT_TRUE(externalTexture->IsAlive());
} }
}
TEST_F(DestroyObjectTests, PipelineLayoutExplicit) { TEST_F(DestroyObjectTests, PipelineLayoutExplicit) {
PipelineLayoutMock pipelineLayoutMock(&mDevice); PipelineLayoutMock pipelineLayoutMock(&mDevice);
@ -552,6 +557,7 @@ namespace dawn::native { namespace {
BufferMock* bufferMock = new BufferMock(&mDevice, BufferBase::BufferState::Unmapped); BufferMock* bufferMock = new BufferMock(&mDevice, BufferBase::BufferState::Unmapped);
CommandBufferMock* commandBufferMock = new CommandBufferMock(&mDevice); CommandBufferMock* commandBufferMock = new CommandBufferMock(&mDevice);
ComputePipelineMock* computePipelineMock = new ComputePipelineMock(&mDevice); ComputePipelineMock* computePipelineMock = new ComputePipelineMock(&mDevice);
ExternalTextureMock* externalTextureMock = new ExternalTextureMock(&mDevice);
PipelineLayoutMock* pipelineLayoutMock = new PipelineLayoutMock(&mDevice); PipelineLayoutMock* pipelineLayoutMock = new PipelineLayoutMock(&mDevice);
QuerySetMock* querySetMock = new QuerySetMock(&mDevice); QuerySetMock* querySetMock = new QuerySetMock(&mDevice);
RenderPipelineMock* renderPipelineMock = new RenderPipelineMock(&mDevice); RenderPipelineMock* renderPipelineMock = new RenderPipelineMock(&mDevice);
@ -571,6 +577,7 @@ namespace dawn::native { namespace {
EXPECT_CALL(*bindGroupMock, DestroyImpl).Times(1); EXPECT_CALL(*bindGroupMock, DestroyImpl).Times(1);
EXPECT_CALL(*bindGroupLayoutMock, DestroyImpl).Times(1); EXPECT_CALL(*bindGroupLayoutMock, DestroyImpl).Times(1);
EXPECT_CALL(*shaderModuleMock, DestroyImpl).Times(1); EXPECT_CALL(*shaderModuleMock, DestroyImpl).Times(1);
EXPECT_CALL(*externalTextureMock, DestroyImpl).Times(1);
EXPECT_CALL(*textureViewMock, DestroyImpl).Times(1); EXPECT_CALL(*textureViewMock, DestroyImpl).Times(1);
EXPECT_CALL(*textureMock, DestroyImpl).Times(1); EXPECT_CALL(*textureMock, DestroyImpl).Times(1);
EXPECT_CALL(*querySetMock, DestroyImpl).Times(1); EXPECT_CALL(*querySetMock, DestroyImpl).Times(1);
@ -638,7 +645,9 @@ namespace dawn::native { namespace {
Ref<ExternalTextureBase> externalTexture; Ref<ExternalTextureBase> externalTexture;
{ {
ExternalTextureDescriptor desc = {}; 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()); EXPECT_TRUE(externalTexture->IsAlive());
} }

View File

@ -68,6 +68,10 @@ namespace dawn::native {
CreateUninitializedComputePipelineImpl, CreateUninitializedComputePipelineImpl,
(const ComputePipelineDescriptor*), (const ComputePipelineDescriptor*),
(override)); (override));
MOCK_METHOD(ResultOrError<Ref<ExternalTextureBase>>,
CreateExternalTextureImpl,
(const ExternalTextureDescriptor*),
(override));
MOCK_METHOD(ResultOrError<Ref<PipelineLayoutBase>>, MOCK_METHOD(ResultOrError<Ref<PipelineLayoutBase>>,
CreatePipelineLayoutImpl, CreatePipelineLayoutImpl,
(const PipelineLayoutDescriptor*), (const PipelineLayoutDescriptor*),