mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-18 17:35:30 +00:00
Implement External Texture Binding Functionality
Adds functionality to BindGroupLayout and BindGroup to allow GPUExternalTexture bindings. Bug: dawn:728 Change-Id: I651b28606dceda15f0a944711ddba639df77c1a3 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/47381 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
committed by
Dawn LUCI CQ
parent
a9e39e11a8
commit
39633e2da2
@@ -53,9 +53,14 @@ class BindGroupValidationTest : public ValidationTest {
|
||||
}
|
||||
{ mSampler = device.CreateSampler(); }
|
||||
{
|
||||
mSampledTexture =
|
||||
CreateTexture(wgpu::TextureUsage::Sampled, wgpu::TextureFormat::RGBA8Unorm, 1);
|
||||
mSampledTexture = CreateTexture(wgpu::TextureUsage::Sampled, kDefaultTextureFormat, 1);
|
||||
mSampledTextureView = mSampledTexture.CreateView();
|
||||
|
||||
wgpu::ExternalTextureDescriptor externalTextureDesc;
|
||||
externalTextureDesc.format = kDefaultTextureFormat;
|
||||
externalTextureDesc.plane0 = mSampledTextureView;
|
||||
mExternalTexture = device.CreateExternalTexture(&externalTextureDesc);
|
||||
mExternalTextureBindingEntry.externalTexture = mExternalTexture;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +70,12 @@ class BindGroupValidationTest : public ValidationTest {
|
||||
wgpu::Sampler mSampler;
|
||||
wgpu::Texture mSampledTexture;
|
||||
wgpu::TextureView mSampledTextureView;
|
||||
wgpu::ExternalTextureBindingEntry mExternalTextureBindingEntry;
|
||||
|
||||
static constexpr wgpu::TextureFormat kDefaultTextureFormat = wgpu::TextureFormat::RGBA8Unorm;
|
||||
|
||||
private:
|
||||
wgpu::ExternalTexture mExternalTexture;
|
||||
};
|
||||
|
||||
// Test the validation of BindGroupDescriptor::nextInChain
|
||||
@@ -159,6 +170,11 @@ TEST_F(BindGroupValidationTest, SamplerBindingType) {
|
||||
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
|
||||
binding.buffer = nullptr;
|
||||
|
||||
// Setting the external texture view as well is an error
|
||||
binding.nextInChain = &mExternalTextureBindingEntry;
|
||||
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
|
||||
binding.nextInChain = nullptr;
|
||||
|
||||
// Setting the sampler to an error sampler is an error.
|
||||
{
|
||||
wgpu::SamplerDescriptor samplerDesc;
|
||||
@@ -208,10 +224,15 @@ TEST_F(BindGroupValidationTest, TextureBindingType) {
|
||||
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
|
||||
binding.buffer = nullptr;
|
||||
|
||||
// Setting the external texture view as well is an error
|
||||
binding.nextInChain = &mExternalTextureBindingEntry;
|
||||
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
|
||||
binding.nextInChain = nullptr;
|
||||
|
||||
// Setting the texture view to an error texture view is an error.
|
||||
{
|
||||
wgpu::TextureViewDescriptor viewDesc;
|
||||
viewDesc.format = wgpu::TextureFormat::RGBA8Unorm;
|
||||
viewDesc.format = kDefaultTextureFormat;
|
||||
viewDesc.dimension = wgpu::TextureViewDimension::e2D;
|
||||
viewDesc.baseMipLevel = 0;
|
||||
viewDesc.mipLevelCount = 0;
|
||||
@@ -262,6 +283,11 @@ TEST_F(BindGroupValidationTest, BufferBindingType) {
|
||||
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
|
||||
binding.sampler = nullptr;
|
||||
|
||||
// Setting the external texture view as well is an error
|
||||
binding.nextInChain = &mExternalTextureBindingEntry;
|
||||
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
|
||||
binding.nextInChain = nullptr;
|
||||
|
||||
// Setting the buffer to an error buffer is an error.
|
||||
{
|
||||
wgpu::BufferDescriptor bufferDesc;
|
||||
@@ -277,6 +303,91 @@ TEST_F(BindGroupValidationTest, BufferBindingType) {
|
||||
}
|
||||
}
|
||||
|
||||
// Check that an external texture binding must contain exactly an external texture
|
||||
TEST_F(BindGroupValidationTest, ExternalTextureBindingType) {
|
||||
// Create an external texture
|
||||
wgpu::Texture texture = CreateTexture(wgpu::TextureUsage::Sampled, kDefaultTextureFormat, 1);
|
||||
wgpu::ExternalTextureDescriptor externalDesc;
|
||||
externalDesc.plane0 = texture.CreateView();
|
||||
externalDesc.format = kDefaultTextureFormat;
|
||||
wgpu::ExternalTexture externalTexture = device.CreateExternalTexture(&externalDesc);
|
||||
|
||||
// Create a bind group layout for a single external texture
|
||||
wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Fragment, &utils::kExternalTextureBindingLayout}});
|
||||
|
||||
wgpu::BindGroupEntry binding;
|
||||
binding.binding = 0;
|
||||
binding.sampler = nullptr;
|
||||
binding.textureView = nullptr;
|
||||
binding.buffer = nullptr;
|
||||
binding.offset = 0;
|
||||
binding.size = 0;
|
||||
|
||||
wgpu::BindGroupDescriptor descriptor;
|
||||
descriptor.layout = layout;
|
||||
descriptor.entryCount = 1;
|
||||
descriptor.entries = &binding;
|
||||
|
||||
// Not setting anything fails
|
||||
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
|
||||
|
||||
// Control case: setting just the external texture works
|
||||
wgpu::ExternalTextureBindingEntry externalBindingEntry;
|
||||
externalBindingEntry.externalTexture = externalTexture;
|
||||
binding.nextInChain = &externalBindingEntry;
|
||||
device.CreateBindGroup(&descriptor);
|
||||
|
||||
// Setting the texture view as well is an error
|
||||
binding.textureView = mSampledTextureView;
|
||||
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
|
||||
binding.textureView = nullptr;
|
||||
|
||||
// Setting the sampler as well is an error
|
||||
binding.sampler = mSampler;
|
||||
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
|
||||
binding.sampler = nullptr;
|
||||
|
||||
// Setting the buffer as well is an error
|
||||
binding.buffer = mUBO;
|
||||
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
|
||||
binding.buffer = nullptr;
|
||||
|
||||
// Setting the external texture to an error external texture is an error.
|
||||
{
|
||||
wgpu::ExternalTextureDescriptor errorExternalDesciptor;
|
||||
errorExternalDesciptor.plane0 = texture.CreateView();
|
||||
errorExternalDesciptor.format = wgpu::TextureFormat::R8Uint;
|
||||
|
||||
wgpu::ExternalTexture errorExternalTexture;
|
||||
ASSERT_DEVICE_ERROR(errorExternalTexture =
|
||||
device.CreateExternalTexture(&errorExternalDesciptor));
|
||||
|
||||
wgpu::ExternalTextureBindingEntry errorExternalBindingEntry;
|
||||
errorExternalBindingEntry.externalTexture = errorExternalTexture;
|
||||
binding.nextInChain = &errorExternalBindingEntry;
|
||||
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
|
||||
binding.nextInChain = nullptr;
|
||||
}
|
||||
|
||||
// Setting an external texture with another external texture chained is an error.
|
||||
{
|
||||
wgpu::ExternalTexture externalTexture2 = device.CreateExternalTexture(&externalDesc);
|
||||
wgpu::ExternalTextureBindingEntry externalBindingEntry2;
|
||||
externalBindingEntry2.externalTexture = externalTexture2;
|
||||
externalBindingEntry.nextInChain = &externalBindingEntry2;
|
||||
|
||||
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
|
||||
}
|
||||
|
||||
// Chaining a struct that isn't an external texture binding entry is an error.
|
||||
{
|
||||
wgpu::ExternalTextureBindingLayout externalBindingLayout;
|
||||
binding.nextInChain = &externalBindingLayout;
|
||||
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
|
||||
}
|
||||
}
|
||||
|
||||
// Check that a texture must have the correct usage
|
||||
TEST_F(BindGroupValidationTest, TextureUsage) {
|
||||
wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
|
||||
@@ -746,7 +857,7 @@ TEST_F(BindGroupLayoutValidationTest, PerStageLimits) {
|
||||
wgpu::BindGroupLayoutEntry otherEntry;
|
||||
};
|
||||
|
||||
std::array<TestInfo, 7> kTestInfos = {
|
||||
std::array<TestInfo, 8> kTestInfos = {
|
||||
TestInfo{kMaxSampledTexturesPerShaderStage, BGLEntryType(wgpu::TextureSampleType::Float),
|
||||
BGLEntryType(wgpu::BufferBindingType::Uniform)},
|
||||
TestInfo{kMaxSamplersPerShaderStage, BGLEntryType(wgpu::SamplerBindingType::Filtering),
|
||||
@@ -765,7 +876,12 @@ TEST_F(BindGroupLayoutValidationTest, PerStageLimits) {
|
||||
BGLEntryType(wgpu::BufferBindingType::Uniform)},
|
||||
TestInfo{kMaxUniformBuffersPerShaderStage, BGLEntryType(wgpu::BufferBindingType::Uniform),
|
||||
BGLEntryType(wgpu::TextureSampleType::Float)},
|
||||
};
|
||||
// External textures use multiple bindings (3 sampled textures, 1 sampler, 1 uniform buffer)
|
||||
// that count towards the per stage binding limits. The number of external textures are
|
||||
// currently restricted by the maximum number of sampled textures.
|
||||
TestInfo{kMaxSampledTexturesPerShaderStage / kSampledTexturesPerExternalTexture,
|
||||
BGLEntryType(&utils::kExternalTextureBindingLayout),
|
||||
BGLEntryType(wgpu::BufferBindingType::Uniform)}};
|
||||
|
||||
for (TestInfo info : kTestInfos) {
|
||||
wgpu::BindGroupLayout bgl[2];
|
||||
@@ -829,6 +945,98 @@ TEST_F(BindGroupLayoutValidationTest, PerStageLimits) {
|
||||
}
|
||||
}
|
||||
|
||||
// External textures require multiple binding slots (3 sampled texture, 1 uniform buffer, 1
|
||||
// sampler), so ensure that these count towards the limit when combined non-external texture
|
||||
// bindings.
|
||||
TEST_F(BindGroupLayoutValidationTest, PerStageLimitsWithExternalTexture) {
|
||||
struct TestInfo {
|
||||
uint32_t maxCount;
|
||||
uint32_t bindingsPerExternalTexture;
|
||||
wgpu::BindGroupLayoutEntry entry;
|
||||
wgpu::BindGroupLayoutEntry otherEntry;
|
||||
};
|
||||
|
||||
std::array<TestInfo, 3> kTestInfos = {
|
||||
TestInfo{kMaxSampledTexturesPerShaderStage, kSampledTexturesPerExternalTexture,
|
||||
BGLEntryType(wgpu::TextureSampleType::Float),
|
||||
BGLEntryType(wgpu::BufferBindingType::Uniform)},
|
||||
TestInfo{kMaxSamplersPerShaderStage, kSamplersPerExternalTexture,
|
||||
BGLEntryType(wgpu::SamplerBindingType::Filtering),
|
||||
BGLEntryType(wgpu::BufferBindingType::Uniform)},
|
||||
TestInfo{kMaxUniformBuffersPerShaderStage, kUniformsPerExternalTexture,
|
||||
BGLEntryType(wgpu::BufferBindingType::Uniform),
|
||||
BGLEntryType(wgpu::TextureSampleType::Float)},
|
||||
};
|
||||
|
||||
for (TestInfo info : kTestInfos) {
|
||||
wgpu::BindGroupLayout bgl[2];
|
||||
std::vector<utils::BindingLayoutEntryInitializationHelper> maxBindings;
|
||||
|
||||
// Create an external texture binding layout entry
|
||||
wgpu::BindGroupLayoutEntry entry = BGLEntryType(&utils::kExternalTextureBindingLayout);
|
||||
entry.binding = 0;
|
||||
maxBindings.push_back(entry);
|
||||
|
||||
// Create the other bindings such that we reach the max bindings per stage when including
|
||||
// the external texture.
|
||||
for (uint32_t i = 1; i <= info.maxCount - info.bindingsPerExternalTexture; ++i) {
|
||||
wgpu::BindGroupLayoutEntry entry = info.entry;
|
||||
entry.binding = i;
|
||||
maxBindings.push_back(entry);
|
||||
}
|
||||
|
||||
// Ensure that creation without the external texture works.
|
||||
bgl[0] = MakeBindGroupLayout(maxBindings.data(), maxBindings.size());
|
||||
|
||||
// Adding an extra binding of a different type works.
|
||||
{
|
||||
std::vector<utils::BindingLayoutEntryInitializationHelper> bindings = maxBindings;
|
||||
wgpu::BindGroupLayoutEntry entry = info.otherEntry;
|
||||
entry.binding = info.maxCount;
|
||||
bindings.push_back(entry);
|
||||
MakeBindGroupLayout(bindings.data(), bindings.size());
|
||||
}
|
||||
|
||||
// Adding an extra binding of the maxed type in a different stage works
|
||||
{
|
||||
std::vector<utils::BindingLayoutEntryInitializationHelper> bindings = maxBindings;
|
||||
wgpu::BindGroupLayoutEntry entry = info.entry;
|
||||
entry.binding = info.maxCount;
|
||||
entry.visibility = wgpu::ShaderStage::Fragment;
|
||||
bindings.push_back(entry);
|
||||
MakeBindGroupLayout(bindings.data(), bindings.size());
|
||||
}
|
||||
|
||||
// Adding an extra binding of the maxed type and stage exceeds the per stage limit.
|
||||
{
|
||||
std::vector<utils::BindingLayoutEntryInitializationHelper> bindings = maxBindings;
|
||||
wgpu::BindGroupLayoutEntry entry = info.entry;
|
||||
entry.binding = info.maxCount;
|
||||
bindings.push_back(entry);
|
||||
ASSERT_DEVICE_ERROR(MakeBindGroupLayout(bindings.data(), bindings.size()));
|
||||
}
|
||||
|
||||
// Creating a pipeline layout from the valid BGL works.
|
||||
TestCreatePipelineLayout(bgl, 1, true);
|
||||
|
||||
// Adding an extra binding of a different type in a different BGL works
|
||||
bgl[1] = utils::MakeBindGroupLayout(device, {info.otherEntry});
|
||||
TestCreatePipelineLayout(bgl, 2, true);
|
||||
|
||||
{
|
||||
// Adding an extra binding of the maxed type in a different stage works
|
||||
wgpu::BindGroupLayoutEntry entry = info.entry;
|
||||
entry.visibility = wgpu::ShaderStage::Fragment;
|
||||
bgl[1] = utils::MakeBindGroupLayout(device, {entry});
|
||||
TestCreatePipelineLayout(bgl, 2, true);
|
||||
}
|
||||
|
||||
// Adding an extra binding of the maxed type in a different BGL exceeds the per stage limit.
|
||||
bgl[1] = utils::MakeBindGroupLayout(device, {info.entry});
|
||||
TestCreatePipelineLayout(bgl, 2, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Check that dynamic buffer numbers exceed maximum value in one bind group layout.
|
||||
TEST_F(BindGroupLayoutValidationTest, DynamicBufferNumberLimit) {
|
||||
wgpu::BindGroupLayout bgl[2];
|
||||
@@ -1847,6 +2055,28 @@ TEST_F(BindGroupLayoutCompatibilityTest, TextureViewDimension) {
|
||||
wgpu::TextureViewDimension::e2D}})}));
|
||||
}
|
||||
|
||||
// TODO(dawn:728) Enable this test when Dawn no longer relies on SPIRV-Cross to extract shader info.
|
||||
TEST_F(BindGroupLayoutCompatibilityTest, DISABLED_ExternalTextureBindGroupLayoutCompatibility) {
|
||||
wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Fragment, &utils::kExternalTextureBindingLayout}});
|
||||
|
||||
// Test that an external texture binding works with a texture_external in the shader.
|
||||
CreateFSRenderPipeline(R"(
|
||||
[[group(0), binding(0)]] var myExternalTexture: texture_external;
|
||||
[[stage(fragment)]] fn main() {
|
||||
textureDimensions(myExternalTexture);
|
||||
})",
|
||||
{bgl});
|
||||
|
||||
// Test that an external texture binding doesn't work with a texture_2d<f32> in the shader.
|
||||
ASSERT_DEVICE_ERROR(CreateFSRenderPipeline(R"(
|
||||
[[group(0), binding(0)]] var myTexture: texture_2d<f32>;
|
||||
[[stage(fragment)]] fn main() {
|
||||
textureDimensions(myTexture);
|
||||
})",
|
||||
{bgl}));
|
||||
}
|
||||
|
||||
class BindingsValidationTest : public BindGroupLayoutCompatibilityTest {
|
||||
public:
|
||||
void TestRenderPassBindings(const wgpu::BindGroup* bg,
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
|
||||
#include "tests/unittests/validation/ValidationTest.h"
|
||||
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/WGPUHelpers.h"
|
||||
|
||||
namespace {
|
||||
class ExternalTextureTest : public ValidationTest {
|
||||
public:
|
||||
@@ -26,11 +29,41 @@ namespace {
|
||||
descriptor.sampleCount = kDefaultSampleCount;
|
||||
descriptor.dimension = wgpu::TextureDimension::e2D;
|
||||
descriptor.format = kDefaultTextureFormat;
|
||||
descriptor.usage = wgpu::TextureUsage::Sampled;
|
||||
descriptor.usage = wgpu::TextureUsage::Sampled | wgpu::TextureUsage::RenderAttachment;
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetUp() override {
|
||||
ValidationTest::SetUp();
|
||||
|
||||
queue = device.GetQueue();
|
||||
}
|
||||
|
||||
wgpu::RenderPipeline CreateBasicRenderPipeline(wgpu::ExternalTexture externalTexture) {
|
||||
wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Fragment, &utils::kExternalTextureBindingLayout}});
|
||||
|
||||
bindGroup = utils::MakeBindGroup(device, bgl, {{0, externalTexture}});
|
||||
|
||||
wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
|
||||
[[stage(vertex)]] fn main() -> [[builtin(position)]] vec4<f32> {
|
||||
return vec4<f32>();
|
||||
})");
|
||||
wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
|
||||
[[group(0), binding(0)]] var myExternalTexture: texture_external;
|
||||
[[stage(fragment)]] fn main() {
|
||||
textureDimensions(myExternalTexture);
|
||||
})");
|
||||
|
||||
utils::ComboRenderPipelineDescriptor pipelineDescriptor;
|
||||
pipelineDescriptor.vertex.module = vsModule;
|
||||
pipelineDescriptor.cFragment.module = fsModule;
|
||||
wgpu::PipelineLayout pipelineLayout = utils::MakeBasicPipelineLayout(device, &bgl);
|
||||
pipelineDescriptor.layout = pipelineLayout;
|
||||
return device.CreateRenderPipeline(&pipelineDescriptor);
|
||||
}
|
||||
|
||||
static constexpr uint32_t kWidth = 32;
|
||||
static constexpr uint32_t kHeight = 32;
|
||||
static constexpr uint32_t kDefaultDepth = 1;
|
||||
@@ -39,6 +72,10 @@ namespace {
|
||||
|
||||
static constexpr wgpu::TextureFormat kDefaultTextureFormat =
|
||||
wgpu::TextureFormat::RGBA8Unorm;
|
||||
|
||||
wgpu::Queue queue;
|
||||
wgpu::RenderPipeline renderPipeline;
|
||||
wgpu::BindGroup bindGroup;
|
||||
};
|
||||
|
||||
TEST_F(ExternalTextureTest, CreateExternalTextureValidation) {
|
||||
@@ -112,4 +149,110 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
// Test that submitting a command encoder that contains a destroyed external texture results in
|
||||
// an error.
|
||||
TEST_F(ExternalTextureTest, SubmitDestroyedExternalTexture) {
|
||||
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);
|
||||
|
||||
wgpu::RenderPipeline pipeline = CreateBasicRenderPipeline(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.SetPipeline(pipeline);
|
||||
pass.SetBindGroup(0, bindGroup);
|
||||
pass.Draw(1);
|
||||
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.SetPipeline(pipeline);
|
||||
pass.SetBindGroup(0, bindGroup);
|
||||
pass.Draw(1);
|
||||
pass.EndPass();
|
||||
}
|
||||
|
||||
wgpu::CommandBuffer commands = encoder.Finish();
|
||||
ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
|
||||
}
|
||||
}
|
||||
|
||||
// Test that submitting a command encoder that contains a destroyed external texture plane
|
||||
// results in an error.
|
||||
TEST_F(ExternalTextureTest, SubmitDestroyedExternalTexturePlane) {
|
||||
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);
|
||||
|
||||
wgpu::RenderPipeline pipeline = CreateBasicRenderPipeline(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.SetPipeline(pipeline);
|
||||
pass.SetBindGroup(0, bindGroup);
|
||||
pass.Draw(1);
|
||||
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.SetPipeline(pipeline);
|
||||
pass.SetBindGroup(0, bindGroup);
|
||||
pass.Draw(1);
|
||||
pass.EndPass();
|
||||
}
|
||||
|
||||
wgpu::CommandBuffer commands = encoder.Finish();
|
||||
ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -274,6 +274,33 @@ TEST_F(GetBindGroupLayoutTests, BindingType) {
|
||||
}
|
||||
}
|
||||
|
||||
// Test that an external texture binding type matches a shader using texture_external.
|
||||
// TODO(dawn:728) Enable this test once Dawn no longer relies on SPIRV-Cross to extract shader info.
|
||||
// Consider combining with the similar test above.
|
||||
TEST_F(GetBindGroupLayoutTests, DISABLED_ExternalTextureBindingType) {
|
||||
// This test works assuming Dawn Native's object deduplication.
|
||||
// Getting the same pointer to equivalent bind group layouts is an implementation detail of Dawn
|
||||
// Native.
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
|
||||
wgpu::BindGroupLayoutEntry binding = {};
|
||||
binding.binding = 0;
|
||||
binding.visibility = wgpu::ShaderStage::Fragment;
|
||||
|
||||
wgpu::BindGroupLayoutDescriptor desc = {};
|
||||
desc.entryCount = 1;
|
||||
desc.entries = &binding;
|
||||
|
||||
binding.nextInChain = &utils::kExternalTextureBindingLayout;
|
||||
wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
|
||||
[[group(0), binding(0)]] var myExternalTexture: texture_external;
|
||||
|
||||
[[stage(fragment)]] fn main() {
|
||||
textureDimensions(myExternalTexture);
|
||||
})");
|
||||
EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get());
|
||||
}
|
||||
|
||||
// Test that texture view dimension matches the shader.
|
||||
TEST_F(GetBindGroupLayoutTests, ViewDimension) {
|
||||
// This test works assuming Dawn Native's object deduplication.
|
||||
|
||||
Reference in New Issue
Block a user