mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-26 08:23:34 +00:00
Also adds a label to ExternalTextureDescriptor to match the pattern of all other descriptors. Also adds missing validation that the planes must not be multisampled (with a test) and fixes the validation unittests to not leak state from one test to another (so they test exactly what they need to). Bug: dawn:563 Change-Id: I88a4d7a859e67e5af85efd5ba16572c9014df6ad Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/65562 Reviewed-by: Brandon Jones <bajones@google.com> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
359 lines
15 KiB
C++
359 lines
15 KiB
C++
// Copyright 2021 The Dawn Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "tests/unittests/validation/ValidationTest.h"
|
|
|
|
#include "utils/ComboRenderPipelineDescriptor.h"
|
|
#include "utils/WGPUHelpers.h"
|
|
|
|
namespace {
|
|
class ExternalTextureTest : public ValidationTest {
|
|
public:
|
|
wgpu::TextureDescriptor CreateDefaultTextureDescriptor() {
|
|
wgpu::TextureDescriptor descriptor;
|
|
descriptor.size.width = kWidth;
|
|
descriptor.size.height = kHeight;
|
|
descriptor.size.depthOrArrayLayers = kDefaultDepth;
|
|
descriptor.mipLevelCount = kDefaultMipLevels;
|
|
descriptor.sampleCount = kDefaultSampleCount;
|
|
descriptor.dimension = wgpu::TextureDimension::e2D;
|
|
descriptor.format = kDefaultTextureFormat;
|
|
descriptor.usage =
|
|
wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::RenderAttachment;
|
|
return descriptor;
|
|
}
|
|
|
|
protected:
|
|
void SetUp() override {
|
|
ValidationTest::SetUp();
|
|
|
|
queue = device.GetQueue();
|
|
}
|
|
|
|
static constexpr uint32_t kWidth = 32;
|
|
static constexpr uint32_t kHeight = 32;
|
|
static constexpr uint32_t kDefaultDepth = 1;
|
|
static constexpr uint32_t kDefaultMipLevels = 1;
|
|
static constexpr uint32_t kDefaultSampleCount = 1;
|
|
|
|
static constexpr wgpu::TextureFormat kDefaultTextureFormat =
|
|
wgpu::TextureFormat::RGBA8Unorm;
|
|
|
|
wgpu::Queue queue;
|
|
};
|
|
|
|
TEST_F(ExternalTextureTest, CreateExternalTextureValidation) {
|
|
// Creating an external texture from a 2D, single-subresource texture should succeed.
|
|
{
|
|
wgpu::TextureDescriptor textureDescriptor = CreateDefaultTextureDescriptor();
|
|
wgpu::Texture texture = device.CreateTexture(&textureDescriptor);
|
|
|
|
wgpu::ExternalTextureDescriptor externalDesc;
|
|
externalDesc.format = kDefaultTextureFormat;
|
|
externalDesc.plane0 = texture.CreateView();
|
|
device.CreateExternalTexture(&externalDesc);
|
|
}
|
|
|
|
// Creating an external texture with a mismatched texture view format should fail.
|
|
{
|
|
wgpu::TextureDescriptor textureDescriptor = CreateDefaultTextureDescriptor();
|
|
textureDescriptor.format = wgpu::TextureFormat::RGBA8Uint;
|
|
wgpu::Texture texture = device.CreateTexture(&textureDescriptor);
|
|
|
|
wgpu::ExternalTextureDescriptor externalDesc;
|
|
externalDesc.format = kDefaultTextureFormat;
|
|
externalDesc.plane0 = texture.CreateView();
|
|
ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
|
|
}
|
|
|
|
// Creating an external texture from a non-2D texture should fail.
|
|
{
|
|
wgpu::TextureDescriptor textureDescriptor = CreateDefaultTextureDescriptor();
|
|
textureDescriptor.dimension = wgpu::TextureDimension::e3D;
|
|
wgpu::Texture internalTexture = device.CreateTexture(&textureDescriptor);
|
|
|
|
wgpu::ExternalTextureDescriptor externalDesc;
|
|
externalDesc.format = kDefaultTextureFormat;
|
|
externalDesc.plane0 = internalTexture.CreateView();
|
|
ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
|
|
}
|
|
|
|
// Creating an external texture from a texture with mip count > 1 should fail.
|
|
{
|
|
wgpu::TextureDescriptor textureDescriptor = CreateDefaultTextureDescriptor();
|
|
textureDescriptor.mipLevelCount = 2;
|
|
wgpu::Texture internalTexture = device.CreateTexture(&textureDescriptor);
|
|
|
|
wgpu::ExternalTextureDescriptor externalDesc;
|
|
externalDesc.format = kDefaultTextureFormat;
|
|
externalDesc.plane0 = internalTexture.CreateView();
|
|
ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
|
|
}
|
|
|
|
// Creating an external texture from a texture without TextureUsage::TextureBinding should
|
|
// fail.
|
|
{
|
|
wgpu::TextureDescriptor textureDescriptor = CreateDefaultTextureDescriptor();
|
|
textureDescriptor.mipLevelCount = 2;
|
|
wgpu::Texture internalTexture = device.CreateTexture(&textureDescriptor);
|
|
|
|
wgpu::ExternalTextureDescriptor externalDesc;
|
|
externalDesc.format = kDefaultTextureFormat;
|
|
externalDesc.plane0 = internalTexture.CreateView();
|
|
ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
|
|
}
|
|
|
|
// Creating an external texture with an unsupported format should fail.
|
|
{
|
|
wgpu::TextureDescriptor textureDescriptor = CreateDefaultTextureDescriptor();
|
|
textureDescriptor.format = wgpu::TextureFormat::R8Uint;
|
|
wgpu::Texture internalTexture = device.CreateTexture(&textureDescriptor);
|
|
|
|
wgpu::ExternalTextureDescriptor externalDesc;
|
|
externalDesc.plane0 = internalTexture.CreateView();
|
|
externalDesc.format = textureDescriptor.format;
|
|
ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
|
|
}
|
|
|
|
// Creating an external texture with an multisampled texture should fail.
|
|
{
|
|
wgpu::TextureDescriptor textureDescriptor = CreateDefaultTextureDescriptor();
|
|
textureDescriptor.sampleCount = 4;
|
|
wgpu::Texture internalTexture = device.CreateTexture(&textureDescriptor);
|
|
|
|
wgpu::ExternalTextureDescriptor externalDesc;
|
|
externalDesc.format = kDefaultTextureFormat;
|
|
externalDesc.plane0 = internalTexture.CreateView();
|
|
ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
|
|
}
|
|
|
|
// Creating an external texture with an error texture view should fail.
|
|
{
|
|
wgpu::TextureDescriptor textureDescriptor = CreateDefaultTextureDescriptor();
|
|
wgpu::Texture internalTexture = device.CreateTexture(&textureDescriptor);
|
|
|
|
wgpu::TextureViewDescriptor errorViewDescriptor;
|
|
errorViewDescriptor.format = kDefaultTextureFormat;
|
|
errorViewDescriptor.dimension = wgpu::TextureViewDimension::e2D;
|
|
errorViewDescriptor.mipLevelCount = 1;
|
|
errorViewDescriptor.arrayLayerCount = 2;
|
|
ASSERT_DEVICE_ERROR(wgpu::TextureView errorTextureView =
|
|
internalTexture.CreateView(&errorViewDescriptor));
|
|
|
|
wgpu::ExternalTextureDescriptor externalDesc;
|
|
externalDesc.format = kDefaultTextureFormat;
|
|
externalDesc.plane0 = errorTextureView;
|
|
externalDesc.format = kDefaultTextureFormat;
|
|
ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
|
|
}
|
|
}
|
|
|
|
// Test that submitting a render pass that contains a destroyed external texture results in
|
|
// an error.
|
|
TEST_F(ExternalTextureTest, SubmitDestroyedExternalTextureInRenderPass) {
|
|
wgpu::TextureDescriptor textureDescriptor = CreateDefaultTextureDescriptor();
|
|
wgpu::Texture texture = device.CreateTexture(&textureDescriptor);
|
|
|
|
wgpu::ExternalTextureDescriptor externalDesc;
|
|
externalDesc.format = kDefaultTextureFormat;
|
|
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 = CreateDefaultTextureDescriptor();
|
|
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.EndPass();
|
|
}
|
|
|
|
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::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
|
|
{
|
|
pass.SetBindGroup(0, bindGroup);
|
|
pass.EndPass();
|
|
}
|
|
|
|
wgpu::CommandBuffer commands = encoder.Finish();
|
|
ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
|
|
}
|
|
}
|
|
|
|
// Test that submitting a render pass that contains a destroyed external texture plane
|
|
// results in an error.
|
|
TEST_F(ExternalTextureTest, SubmitDestroyedExternalTexturePlaneInRenderPass) {
|
|
wgpu::TextureDescriptor textureDescriptor = CreateDefaultTextureDescriptor();
|
|
wgpu::Texture texture = device.CreateTexture(&textureDescriptor);
|
|
|
|
wgpu::ExternalTextureDescriptor externalDesc;
|
|
externalDesc.format = kDefaultTextureFormat;
|
|
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 = CreateDefaultTextureDescriptor();
|
|
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.EndPass();
|
|
}
|
|
|
|
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.EndPass();
|
|
}
|
|
|
|
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 = CreateDefaultTextureDescriptor();
|
|
wgpu::Texture texture = device.CreateTexture(&textureDescriptor);
|
|
|
|
wgpu::ExternalTextureDescriptor externalDesc;
|
|
externalDesc.format = kDefaultTextureFormat;
|
|
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.EndPass();
|
|
}
|
|
|
|
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.EndPass();
|
|
}
|
|
|
|
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 = CreateDefaultTextureDescriptor();
|
|
wgpu::Texture texture = device.CreateTexture(&textureDescriptor);
|
|
|
|
wgpu::ExternalTextureDescriptor externalDesc;
|
|
externalDesc.format = kDefaultTextureFormat;
|
|
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.EndPass();
|
|
}
|
|
|
|
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.EndPass();
|
|
}
|
|
|
|
wgpu::CommandBuffer commands = encoder.Finish();
|
|
ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
|
|
}
|
|
}
|
|
} // namespace
|