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:
parent
2ec4038483
commit
96a0bd5bdf
10
dawn.json
10
dawn.json
|
@ -1330,6 +1330,14 @@
|
||||||
{"value": 3, "name": "error"}
|
{"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": {
|
"extent 3D": {
|
||||||
"category": "structure",
|
"category": "structure",
|
||||||
"members": [
|
"members": [
|
||||||
|
@ -1359,10 +1367,12 @@
|
||||||
"category": "structure",
|
"category": "structure",
|
||||||
"extensible": "in",
|
"extensible": "in",
|
||||||
"tags": ["dawn"],
|
"tags": ["dawn"],
|
||||||
|
"_TODO": "crbug.com/1316671: Mark 'visible rect' as must have after chromium side changes landed",
|
||||||
"members": [
|
"members": [
|
||||||
{"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
|
{"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
|
||||||
{"name": "plane 0", "type": "texture view"},
|
{"name": "plane 0", "type": "texture view"},
|
||||||
{"name": "plane 1", "type": "texture view", "optional": true},
|
{"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": "do yuv to rgb conversion only", "type": "bool", "default": "false"},
|
||||||
{"name": "yuv to rgb conversion matrix", "type": "float", "annotation": "const*",
|
{"name": "yuv to rgb conversion matrix", "type": "float", "annotation": "const*",
|
||||||
"length": 12, "optional": true},
|
"length": 12, "optional": true},
|
||||||
|
|
|
@ -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 {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +130,9 @@ ResultOrError<Ref<ExternalTextureBase>> ExternalTextureBase::Create(
|
||||||
|
|
||||||
ExternalTextureBase::ExternalTextureBase(DeviceBase* device,
|
ExternalTextureBase::ExternalTextureBase(DeviceBase* device,
|
||||||
const ExternalTextureDescriptor* descriptor)
|
const ExternalTextureDescriptor* descriptor)
|
||||||
: ApiObjectBase(device, descriptor->label), mState(ExternalTextureState::Alive) {
|
: ApiObjectBase(device, descriptor->label),
|
||||||
|
mVisibleRect(descriptor->visibleRect),
|
||||||
|
mState(ExternalTextureState::Alive) {
|
||||||
GetObjectTrackingList()->Track(this);
|
GetObjectTrackingList()->Track(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,6 +218,13 @@ MaybeError ExternalTextureBase::ValidateCanUseInSubmitNow() const {
|
||||||
ASSERT(!IsError());
|
ASSERT(!IsError());
|
||||||
DAWN_INVALID_IF(mState == ExternalTextureState::Destroyed,
|
DAWN_INVALID_IF(mState == ExternalTextureState::Destroyed,
|
||||||
"Destroyed external texture %s is used in a submit.", this);
|
"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 {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,4 +252,9 @@ ObjectType ExternalTextureBase::GetType() const {
|
||||||
return ObjectType::ExternalTexture;
|
return ObjectType::ExternalTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Extent2D& ExternalTextureBase::GetVisibleRect() const {
|
||||||
|
ASSERT(!IsError());
|
||||||
|
return mVisibleRect;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace dawn::native
|
} // namespace dawn::native
|
||||||
|
|
|
@ -49,6 +49,7 @@ class ExternalTextureBase : public ApiObjectBase {
|
||||||
BufferBase* GetParamsBuffer() const;
|
BufferBase* GetParamsBuffer() const;
|
||||||
const std::array<Ref<TextureViewBase>, kMaxPlanesPerFormat>& GetTextureViews() const;
|
const std::array<Ref<TextureViewBase>, kMaxPlanesPerFormat>& GetTextureViews() const;
|
||||||
ObjectType GetType() const override;
|
ObjectType GetType() const override;
|
||||||
|
const Extent2D& GetVisibleRect() const;
|
||||||
|
|
||||||
MaybeError ValidateCanUseInSubmitNow() const;
|
MaybeError ValidateCanUseInSubmitNow() const;
|
||||||
static ExternalTextureBase* MakeError(DeviceBase* device);
|
static ExternalTextureBase* MakeError(DeviceBase* device);
|
||||||
|
@ -73,6 +74,10 @@ class ExternalTextureBase : public ApiObjectBase {
|
||||||
Ref<BufferBase> mParamsBuffer;
|
Ref<BufferBase> mParamsBuffer;
|
||||||
std::array<Ref<TextureViewBase>, kMaxPlanesPerFormat> mTextureViews;
|
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;
|
ExternalTextureState mState;
|
||||||
};
|
};
|
||||||
} // namespace dawn::native
|
} // namespace dawn::native
|
||||||
|
|
|
@ -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
|
} // namespace
|
||||||
|
|
Loading…
Reference in New Issue