Add ExternalTexture::Refresh() and ExternalTexture::Expire()
ExternalTexture has active, expired and destroyed states. Only active state external texture is valid to submit. Expired state external texture can be refresh to active but destroyed external texture cannot be refresh. Bug: chromium:1412338 Change-Id: Ic7f12d274d27b644f19ec3ef8b46c110610afa2b Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/120982 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Shaobo Yan <shaobo.yan@intel.com>
This commit is contained in:
parent
dd0332ec91
commit
e958db0490
dawn.json
src/dawn
|
@ -1399,6 +1399,14 @@
|
||||||
{
|
{
|
||||||
"name": "destroy",
|
"name": "destroy",
|
||||||
"returns": "void"
|
"returns": "void"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "expire",
|
||||||
|
"returns": "void"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "refresh",
|
||||||
|
"returns": "void"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -133,7 +133,7 @@ ExternalTextureBase::ExternalTextureBase(DeviceBase* device,
|
||||||
: ApiObjectBase(device, descriptor->label),
|
: ApiObjectBase(device, descriptor->label),
|
||||||
mVisibleOrigin(descriptor->visibleOrigin),
|
mVisibleOrigin(descriptor->visibleOrigin),
|
||||||
mVisibleSize(descriptor->visibleSize),
|
mVisibleSize(descriptor->visibleSize),
|
||||||
mState(ExternalTextureState::Alive) {
|
mState(ExternalTextureState::Active) {
|
||||||
GetObjectTrackingList()->Track(this);
|
GetObjectTrackingList()->Track(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,8 +324,8 @@ const std::array<Ref<TextureViewBase>, kMaxPlanesPerFormat>& ExternalTextureBase
|
||||||
|
|
||||||
MaybeError ExternalTextureBase::ValidateCanUseInSubmitNow() const {
|
MaybeError ExternalTextureBase::ValidateCanUseInSubmitNow() const {
|
||||||
ASSERT(!IsError());
|
ASSERT(!IsError());
|
||||||
DAWN_INVALID_IF(mState == ExternalTextureState::Destroyed,
|
DAWN_INVALID_IF(mState != ExternalTextureState::Active,
|
||||||
"Destroyed external texture %s is used in a submit.", this);
|
"External texture %s used in a submit is not active.", this);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < kMaxPlanesPerFormat; ++i) {
|
for (uint32_t i = 0; i < kMaxPlanesPerFormat; ++i) {
|
||||||
if (mTextureViews[i] != nullptr) {
|
if (mTextureViews[i] != nullptr) {
|
||||||
|
@ -336,10 +336,33 @@ MaybeError ExternalTextureBase::ValidateCanUseInSubmitNow() const {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExternalTextureBase::APIDestroy() {
|
MaybeError ExternalTextureBase::ValidateRefresh() {
|
||||||
if (GetDevice()->ConsumedError(GetDevice()->ValidateObject(this))) {
|
DAWN_TRY(GetDevice()->ValidateObject(this));
|
||||||
|
DAWN_INVALID_IF(mState == ExternalTextureState::Destroyed, "%s is destroyed.", this);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
MaybeError ExternalTextureBase::ValidateExpire() {
|
||||||
|
DAWN_TRY(GetDevice()->ValidateObject(this));
|
||||||
|
DAWN_INVALID_IF(mState != ExternalTextureState::Active, "%s is not active.", this);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExternalTextureBase::APIRefresh() {
|
||||||
|
if (GetDevice()->ConsumedError(ValidateRefresh(), "calling %s.Refresh()", this)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
mState = ExternalTextureState::Active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExternalTextureBase::APIExpire() {
|
||||||
|
if (GetDevice()->ConsumedError(ValidateExpire(), "calling %s.Expire()", this)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mState = ExternalTextureState::Expired;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExternalTextureBase::APIDestroy() {
|
||||||
Destroy();
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,9 @@ class ExternalTextureBase : public ApiObjectBase {
|
||||||
MaybeError ValidateCanUseInSubmitNow() const;
|
MaybeError ValidateCanUseInSubmitNow() const;
|
||||||
static ExternalTextureBase* MakeError(DeviceBase* device);
|
static ExternalTextureBase* MakeError(DeviceBase* device);
|
||||||
|
|
||||||
|
void APIExpire();
|
||||||
void APIDestroy();
|
void APIDestroy();
|
||||||
|
void APIRefresh();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ExternalTextureBase(DeviceBase* device, const ExternalTextureDescriptor* descriptor);
|
ExternalTextureBase(DeviceBase* device, const ExternalTextureDescriptor* descriptor);
|
||||||
|
@ -68,9 +70,12 @@ class ExternalTextureBase : public ApiObjectBase {
|
||||||
~ExternalTextureBase() override;
|
~ExternalTextureBase() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class ExternalTextureState { Alive, Destroyed };
|
enum class ExternalTextureState { Active, Expired, Destroyed };
|
||||||
ExternalTextureBase(DeviceBase* device, ObjectBase::ErrorTag tag);
|
ExternalTextureBase(DeviceBase* device, ObjectBase::ErrorTag tag);
|
||||||
|
|
||||||
|
MaybeError ValidateRefresh();
|
||||||
|
MaybeError ValidateExpire();
|
||||||
|
|
||||||
Ref<TextureBase> mPlaceholderTexture;
|
Ref<TextureBase> mPlaceholderTexture;
|
||||||
Ref<BufferBase> mParamsBuffer;
|
Ref<BufferBase> mParamsBuffer;
|
||||||
std::array<Ref<TextureViewBase>, kMaxPlanesPerFormat> mTextureViews;
|
std::array<Ref<TextureViewBase>, kMaxPlanesPerFormat> mTextureViews;
|
||||||
|
|
|
@ -34,11 +34,68 @@ class ExternalTextureTest : public ValidationTest {
|
||||||
return descriptor;
|
return descriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wgpu::ExternalTexture CreateDefaultExternalTexture() {
|
||||||
|
wgpu::ExternalTextureDescriptor externalDesc = CreateDefaultExternalTextureDescriptor();
|
||||||
|
externalDesc.plane0 = defaultTexture.CreateView();
|
||||||
|
return device.CreateExternalTexture(&externalDesc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SubmitExternalTextureInDefaultRenderPass(wgpu::ExternalTexture externalTexture,
|
||||||
|
bool success) {
|
||||||
|
// 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);
|
||||||
|
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||||
|
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
|
||||||
|
pass.SetBindGroup(0, bindGroup);
|
||||||
|
pass.End();
|
||||||
|
wgpu::CommandBuffer commands = encoder.Finish();
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
queue.Submit(1, &commands);
|
||||||
|
} else {
|
||||||
|
ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SubmitExternalTextureInDefaultComputePass(wgpu::ExternalTexture externalTexture,
|
||||||
|
bool success) {
|
||||||
|
// 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}});
|
||||||
|
|
||||||
|
wgpu::ComputePassDescriptor computePass;
|
||||||
|
|
||||||
|
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||||
|
wgpu::ComputePassEncoder pass = encoder.BeginComputePass(&computePass);
|
||||||
|
pass.SetBindGroup(0, bindGroup);
|
||||||
|
pass.End();
|
||||||
|
wgpu::CommandBuffer commands = encoder.Finish();
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
queue.Submit(1, &commands);
|
||||||
|
} else {
|
||||||
|
ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
ValidationTest::SetUp();
|
ValidationTest::SetUp();
|
||||||
|
|
||||||
queue = device.GetQueue();
|
queue = device.GetQueue();
|
||||||
|
|
||||||
|
wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
|
||||||
|
defaultTexture = device.CreateTexture(&textureDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
wgpu::ExternalTextureDescriptor CreateDefaultExternalTextureDescriptor() {
|
wgpu::ExternalTextureDescriptor CreateDefaultExternalTextureDescriptor() {
|
||||||
|
@ -67,6 +124,7 @@ class ExternalTextureTest : public ValidationTest {
|
||||||
std::array<float, 12> mPlaceholderConstantArray;
|
std::array<float, 12> mPlaceholderConstantArray;
|
||||||
|
|
||||||
wgpu::Queue queue;
|
wgpu::Queue queue;
|
||||||
|
wgpu::Texture defaultTexture;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(ExternalTextureTest, CreateExternalTextureValidation) {
|
TEST_F(ExternalTextureTest, CreateExternalTextureValidation) {
|
||||||
|
@ -273,55 +331,85 @@ TEST_F(ExternalTextureTest, CreateMultiplanarExternalTextureValidation) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that submitting a render pass that contains a destroyed external texture results in
|
// Test that refresh on an expired/active external texture.
|
||||||
// an error.
|
TEST_F(ExternalTextureTest, RefreshExternalTexture) {
|
||||||
|
wgpu::ExternalTexture externalTexture = CreateDefaultExternalTexture();
|
||||||
|
|
||||||
|
externalTexture.Refresh();
|
||||||
|
externalTexture.Expire();
|
||||||
|
externalTexture.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that refresh on a destroyed external texture results in an error.
|
||||||
|
TEST_F(ExternalTextureTest, RefreshDestroyedExternalTexture) {
|
||||||
|
wgpu::ExternalTexture externalTexture = CreateDefaultExternalTexture();
|
||||||
|
|
||||||
|
// Refresh on destroyed external texture should result in an error.
|
||||||
|
externalTexture.Destroy();
|
||||||
|
ASSERT_DEVICE_ERROR(externalTexture.Refresh());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that expire on a destroyed external texture results in an error.
|
||||||
|
TEST_F(ExternalTextureTest, ExpireDestroyedExternalTexture) {
|
||||||
|
wgpu::ExternalTexture externalTexture = CreateDefaultExternalTexture();
|
||||||
|
|
||||||
|
externalTexture.Destroy();
|
||||||
|
ASSERT_DEVICE_ERROR(externalTexture.Expire());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that submitting a render pass that contains an active external texture.
|
||||||
|
TEST_F(ExternalTextureTest, SubmitActiveExternalTextureInRenderPass) {
|
||||||
|
wgpu::ExternalTexture externalTexture = CreateDefaultExternalTexture();
|
||||||
|
SubmitExternalTextureInDefaultRenderPass(externalTexture, true /* success = true */);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that submitting a render pass that contains an expired external texture results in an error.
|
||||||
|
TEST_F(ExternalTextureTest, SubmitExpiredExternalTextureInRenderPass) {
|
||||||
|
wgpu::ExternalTexture externalTexture = CreateDefaultExternalTexture();
|
||||||
|
externalTexture.Expire();
|
||||||
|
SubmitExternalTextureInDefaultRenderPass(externalTexture, false /* success = false */);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that submitting a render pass that contains an destroyed external texture results in an
|
||||||
|
// error.
|
||||||
TEST_F(ExternalTextureTest, SubmitDestroyedExternalTextureInRenderPass) {
|
TEST_F(ExternalTextureTest, SubmitDestroyedExternalTextureInRenderPass) {
|
||||||
wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
|
wgpu::ExternalTexture externalTexture = CreateDefaultExternalTexture();
|
||||||
wgpu::Texture texture = device.CreateTexture(&textureDescriptor);
|
externalTexture.Destroy();
|
||||||
|
SubmitExternalTextureInDefaultRenderPass(externalTexture, false /* success = false */);
|
||||||
|
}
|
||||||
|
|
||||||
wgpu::ExternalTextureDescriptor externalDesc = CreateDefaultExternalTextureDescriptor();
|
// Test that submitting a compute pass that contains an active external.
|
||||||
externalDesc.plane0 = texture.CreateView();
|
TEST_F(ExternalTextureTest, SubmitActiveExternalTextureInComputePass) {
|
||||||
wgpu::ExternalTexture externalTexture = device.CreateExternalTexture(&externalDesc);
|
wgpu::ExternalTexture externalTexture = CreateDefaultExternalTexture();
|
||||||
|
SubmitExternalTextureInDefaultComputePass(externalTexture, true /* success = true */);
|
||||||
|
}
|
||||||
|
|
||||||
// Create a bind group that contains the external texture.
|
// Test that submitting a compute pass that contains an expired external texture results in an
|
||||||
wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
|
// error.
|
||||||
device, {{0, wgpu::ShaderStage::Fragment, &utils::kExternalTextureBindingLayout}});
|
TEST_F(ExternalTextureTest, SubmitExpiredExternalTextureInComputePass) {
|
||||||
wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, bgl, {{0, externalTexture}});
|
wgpu::ExternalTexture externalTexture = CreateDefaultExternalTexture();
|
||||||
|
externalTexture.Expire();
|
||||||
|
SubmitExternalTextureInDefaultComputePass(externalTexture, false /* success = false */);
|
||||||
|
}
|
||||||
|
|
||||||
// Create another texture to use as a color attachment.
|
// Test that submitting a compute pass that contains an active external texture should success.
|
||||||
wgpu::TextureDescriptor renderTextureDescriptor = CreateTextureDescriptor();
|
TEST_F(ExternalTextureTest, SubmitDestroyedExternalTextureInComputePass) {
|
||||||
wgpu::Texture renderTexture = device.CreateTexture(&renderTextureDescriptor);
|
wgpu::ExternalTexture externalTexture = CreateDefaultExternalTexture();
|
||||||
wgpu::TextureView renderView = renderTexture.CreateView();
|
externalTexture.Destroy();
|
||||||
|
SubmitExternalTextureInDefaultComputePass(externalTexture, false /* success = false */);
|
||||||
|
}
|
||||||
|
|
||||||
utils::ComboRenderPassDescriptor renderPass({renderView}, nullptr);
|
// Test that refresh an expired external texture and submit a compute pass with it.
|
||||||
|
TEST_F(ExternalTextureTest, RefreshExpiredExternalTexture) {
|
||||||
|
wgpu::ExternalTexture externalTexture = CreateDefaultExternalTexture();
|
||||||
|
externalTexture.Expire();
|
||||||
|
|
||||||
// Control case should succeed.
|
// Submit with expired external texture results in error
|
||||||
{
|
SubmitExternalTextureInDefaultComputePass(externalTexture, false /* success = false */);
|
||||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
|
||||||
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
|
|
||||||
{
|
|
||||||
pass.SetBindGroup(0, bindGroup);
|
|
||||||
pass.End();
|
|
||||||
}
|
|
||||||
|
|
||||||
wgpu::CommandBuffer commands = encoder.Finish();
|
externalTexture.Refresh();
|
||||||
|
// Refreshed external texture could be submitted.
|
||||||
queue.Submit(1, &commands);
|
SubmitExternalTextureInDefaultComputePass(externalTexture, true /* success = true */);
|
||||||
}
|
|
||||||
|
|
||||||
// Destroying the external texture should result in an error.
|
|
||||||
{
|
|
||||||
externalTexture.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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that submitting a render pass that contains a dereferenced external texture results in
|
// Test that submitting a render pass that contains a dereferenced external texture results in
|
||||||
|
@ -375,148 +463,6 @@ TEST_F(ExternalTextureTest, SubmitDereferencedExternalTextureInRenderPass) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that submitting a render pass that contains a destroyed external texture plane
|
|
||||||
// results in an error.
|
|
||||||
TEST_F(ExternalTextureTest, SubmitDestroyedExternalTexturePlaneInRenderPass) {
|
|
||||||
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 an external texture underlying plane 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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that submitting a compute pass that contains a destroyed external texture results in
|
|
||||||
// an error.
|
|
||||||
TEST_F(ExternalTextureTest, SubmitDestroyedExternalTextureInComputePass) {
|
|
||||||
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}});
|
|
||||||
|
|
||||||
wgpu::ComputePassDescriptor computePass;
|
|
||||||
|
|
||||||
// Control case should succeed.
|
|
||||||
{
|
|
||||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
|
||||||
wgpu::ComputePassEncoder pass = encoder.BeginComputePass(&computePass);
|
|
||||||
{
|
|
||||||
pass.SetBindGroup(0, bindGroup);
|
|
||||||
pass.End();
|
|
||||||
}
|
|
||||||
|
|
||||||
wgpu::CommandBuffer commands = encoder.Finish();
|
|
||||||
|
|
||||||
queue.Submit(1, &commands);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destroying the external texture should result in an error.
|
|
||||||
{
|
|
||||||
externalTexture.Destroy();
|
|
||||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
|
||||||
wgpu::ComputePassEncoder pass = encoder.BeginComputePass(&computePass);
|
|
||||||
{
|
|
||||||
pass.SetBindGroup(0, bindGroup);
|
|
||||||
pass.End();
|
|
||||||
}
|
|
||||||
|
|
||||||
wgpu::CommandBuffer commands = encoder.Finish();
|
|
||||||
ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that submitting a compute pass that contains a destroyed external texture plane
|
|
||||||
// results in an error.
|
|
||||||
TEST_F(ExternalTextureTest, SubmitDestroyedExternalTexturePlaneInComputePass) {
|
|
||||||
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}});
|
|
||||||
|
|
||||||
wgpu::ComputePassDescriptor computePass;
|
|
||||||
|
|
||||||
// Control case should succeed.
|
|
||||||
{
|
|
||||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
|
||||||
wgpu::ComputePassEncoder pass = encoder.BeginComputePass(&computePass);
|
|
||||||
{
|
|
||||||
pass.SetBindGroup(0, bindGroup);
|
|
||||||
pass.End();
|
|
||||||
}
|
|
||||||
|
|
||||||
wgpu::CommandBuffer commands = encoder.Finish();
|
|
||||||
queue.Submit(1, &commands);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destroying an external texture underlying plane should result in an error.
|
|
||||||
{
|
|
||||||
texture.Destroy();
|
|
||||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
|
||||||
wgpu::ComputePassEncoder pass = encoder.BeginComputePass(&computePass);
|
|
||||||
{
|
|
||||||
pass.SetBindGroup(0, bindGroup);
|
|
||||||
pass.End();
|
|
||||||
}
|
|
||||||
|
|
||||||
wgpu::CommandBuffer commands = encoder.Finish();
|
|
||||||
ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure that bind group validation catches external textures mimatched from the BGL.
|
// Ensure that bind group validation catches external textures mimatched from the BGL.
|
||||||
TEST_F(ExternalTextureTest, BindGroupDoesNotMatchLayout) {
|
TEST_F(ExternalTextureTest, BindGroupDoesNotMatchLayout) {
|
||||||
wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
|
wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
|
||||||
|
|
Loading…
Reference in New Issue