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(
const ExternalTextureDescriptor* descriptor) {
Ref<ExternalTextureBase> 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<Ref<ExternalTextureBase>> DeviceBase::CreateExternalTexture(
ResultOrError<Ref<ExternalTextureBase>> DeviceBase::CreateExternalTextureImpl(
const ExternalTextureDescriptor* descriptor) {
if (IsValidationEnabled()) {
DAWN_TRY_CONTEXT(ValidateExternalTextureDescriptor(this, descriptor), "validating %s",

View File

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

View File

@ -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, &params,
sizeof(ExternalTextureParams)));
return {};
}

View File

@ -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<BufferBase> mParamsBuffer;
std::array<Ref<TextureViewBase>, kMaxPlanesPerFormat> mTextureViews;
ExternalTextureState mState;
};
} // namespace dawn::native

View File

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

View File

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

View File

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

View File

@ -285,14 +285,19 @@ namespace dawn::native { namespace {
EXPECT_FALSE(externalTextureMock.IsAlive());
}
// We can use an actual ExternalTexture object to test the implicit case.
TEST_F(DestroyObjectTests, ExternalTextureImplicit) {
ExternalTextureMock* externalTextureMock = new ExternalTextureMock(&mDevice);
EXPECT_CALL(*externalTextureMock, DestroyImpl).Times(1);
{
ExternalTextureDescriptor desc = {};
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());
}
}
TEST_F(DestroyObjectTests, PipelineLayoutExplicit) {
PipelineLayoutMock pipelineLayoutMock(&mDevice);
@ -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<ExternalTextureBase> 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());
}

View File

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