Add visibleRect to ExternalTextureDescriptor

Add visibleRect in ExternalTextureDescriptor to create ExternalTexture.
This helps ExternalTexture present the content correctly if needed.

Bug: chromium:1361363
Change-Id: I54b1912305080943babd7558ef40bca8528c932c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/106181
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Shaobo Yan <shaobo.yan@intel.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
Yan,Shaobo 2022-10-24 04:19:43 +00:00 committed by Dawn LUCI CQ
parent 2ec4038483
commit 96a0bd5bdf
4 changed files with 132 additions and 1 deletions

View File

@ -1330,6 +1330,14 @@
{"value": 3, "name": "error"}
]
},
"extent 2D": {
"category": "structure",
"_TODO": "crbug.com/1316671: Remove default value of 'width' after chromium side chagnes landed",
"members": [
{"name": "width", "type": "uint32_t", "default": 0},
{"name": "height", "type": "uint32_t", "default": 1}
]
},
"extent 3D": {
"category": "structure",
"members": [
@ -1359,10 +1367,12 @@
"category": "structure",
"extensible": "in",
"tags": ["dawn"],
"_TODO": "crbug.com/1316671: Mark 'visible rect' as must have after chromium side changes landed",
"members": [
{"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
{"name": "plane 0", "type": "texture view"},
{"name": "plane 1", "type": "texture view", "optional": true},
{"name": "visible rect", "type": "extent 2D"},
{"name": "do yuv to rgb conversion only", "type": "bool", "default": "false"},
{"name": "yuv to rgb conversion matrix", "type": "float", "annotation": "const*",
"length": 12, "optional": true},

View File

@ -99,6 +99,22 @@ MaybeError ValidateExternalTextureDescriptor(const DeviceBase* device,
}
}
// TODO(crbug.com/1316671): visibleRect must have valid value after chromium side changes
// landed.
if (descriptor->visibleRect.width > 0) {
DAWN_INVALID_IF(descriptor->visibleRect.width == 0 || descriptor->visibleRect.height == 0,
"VisibleRect(%u, %u) have 0 on width or height.",
descriptor->visibleRect.width, descriptor->visibleRect.height);
Extent3D maxVisibleRectSize = descriptor->plane0->GetTexture()->GetSize();
DAWN_INVALID_IF(descriptor->visibleRect.width > maxVisibleRectSize.width ||
descriptor->visibleRect.height > maxVisibleRectSize.height,
"VisibleRect(%u, %u) is exceed the max visible rect size, defined by "
"Plane0 size (%u, %u).",
descriptor->visibleRect.width, descriptor->visibleRect.height,
maxVisibleRectSize.width, maxVisibleRectSize.height);
}
return {};
}
@ -114,7 +130,9 @@ ResultOrError<Ref<ExternalTextureBase>> ExternalTextureBase::Create(
ExternalTextureBase::ExternalTextureBase(DeviceBase* device,
const ExternalTextureDescriptor* descriptor)
: ApiObjectBase(device, descriptor->label), mState(ExternalTextureState::Alive) {
: ApiObjectBase(device, descriptor->label),
mVisibleRect(descriptor->visibleRect),
mState(ExternalTextureState::Alive) {
GetObjectTrackingList()->Track(this);
}
@ -200,6 +218,13 @@ MaybeError ExternalTextureBase::ValidateCanUseInSubmitNow() const {
ASSERT(!IsError());
DAWN_INVALID_IF(mState == ExternalTextureState::Destroyed,
"Destroyed external texture %s is used in a submit.", this);
for (uint32_t i = 0; i < kMaxPlanesPerFormat; ++i) {
if (mTextureViews[i] != nullptr) {
DAWN_TRY_CONTEXT(mTextureViews[i]->GetTexture()->ValidateCanUseInSubmitNow(),
"Validate plane %u of %s can be used in a submit.", i, this);
}
}
return {};
}
@ -227,4 +252,9 @@ ObjectType ExternalTextureBase::GetType() const {
return ObjectType::ExternalTexture;
}
const Extent2D& ExternalTextureBase::GetVisibleRect() const {
ASSERT(!IsError());
return mVisibleRect;
}
} // namespace dawn::native

View File

@ -49,6 +49,7 @@ class ExternalTextureBase : public ApiObjectBase {
BufferBase* GetParamsBuffer() const;
const std::array<Ref<TextureViewBase>, kMaxPlanesPerFormat>& GetTextureViews() const;
ObjectType GetType() const override;
const Extent2D& GetVisibleRect() const;
MaybeError ValidateCanUseInSubmitNow() const;
static ExternalTextureBase* MakeError(DeviceBase* device);
@ -73,6 +74,10 @@ class ExternalTextureBase : public ApiObjectBase {
Ref<BufferBase> mParamsBuffer;
std::array<Ref<TextureViewBase>, kMaxPlanesPerFormat> mTextureViews;
// TODO(dawn:1082) Use the visible rect in the external texture shader code to sample
// video content.
Extent2D mVisibleRect;
ExternalTextureState mState;
};
} // namespace dawn::native

View File

@ -581,4 +581,90 @@ TEST_F(ExternalTextureTest, UseErrorExternalTextureInBindGroup) {
}
}
// Test create external texture with too large visible rect results in error.
TEST_F(ExternalTextureTest, CreateExternalTextureWithErrorVisibleRect) {
// Control case should succeed.
{
wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
wgpu::Texture texture = device.CreateTexture(&textureDescriptor);
wgpu::ExternalTextureDescriptor externalDesc = CreateDefaultExternalTextureDescriptor();
externalDesc.plane0 = texture.CreateView();
externalDesc.visibleRect = {texture.GetWidth(), texture.GetHeight()};
device.CreateExternalTexture(&externalDesc);
}
// VisibleRect is OOB on width
{
wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
wgpu::Texture texture = device.CreateTexture(&textureDescriptor);
wgpu::ExternalTextureDescriptor externalDesc = CreateDefaultExternalTextureDescriptor();
externalDesc.plane0 = texture.CreateView();
externalDesc.visibleRect = {texture.GetWidth() + 1, texture.GetHeight()};
ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
}
// VisibleRect is OOB on height
{
wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
wgpu::Texture texture = device.CreateTexture(&textureDescriptor);
wgpu::ExternalTextureDescriptor externalDesc = CreateDefaultExternalTextureDescriptor();
externalDesc.plane0 = texture.CreateView();
externalDesc.visibleRect = {texture.GetWidth(), texture.GetHeight() + 1};
ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
}
}
// Test that submitting an external texture with a plane that is not submittable results in error.
TEST_F(ExternalTextureTest, SubmitExternalTextureWithDestroyedPlane) {
wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
wgpu::Texture texture = device.CreateTexture(&textureDescriptor);
wgpu::ExternalTextureDescriptor externalDesc = CreateDefaultExternalTextureDescriptor();
externalDesc.plane0 = texture.CreateView();
wgpu::ExternalTexture externalTexture = device.CreateExternalTexture(&externalDesc);
// Create a bind group that contains the external texture.
wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, &utils::kExternalTextureBindingLayout}});
wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, bgl, {{0, externalTexture}});
// Create another texture to use as a color attachment.
wgpu::TextureDescriptor renderTextureDescriptor = CreateTextureDescriptor();
wgpu::Texture renderTexture = device.CreateTexture(&renderTextureDescriptor);
wgpu::TextureView renderView = renderTexture.CreateView();
utils::ComboRenderPassDescriptor renderPass({renderView}, nullptr);
// Control case should succeed.
{
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
{
pass.SetBindGroup(0, bindGroup);
pass.End();
}
wgpu::CommandBuffer commands = encoder.Finish();
queue.Submit(1, &commands);
}
// Destroying the plane0 backed texture should result in an error.
{
texture.Destroy();
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
{
pass.SetBindGroup(0, bindGroup);
pass.End();
}
wgpu::CommandBuffer commands = encoder.Finish();
ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
}
}
} // namespace