ValidationTest: Make custom device creation go through a virtual method
Previously tests that needed to use a device that wasn't the default device created a new one via a method that only supported customizing extensions. Instead of adding a second function the device creation is made completely customizable by querying the test's device via a overridable method. This heavily refactors the QuerySet tests to use the new methods (previously they were using 3 different devices in the same fixture) but loses a little bit of coverage of what happens when some query operations are done with mixed devices. This is required for a follow-up CL that adds tests for a device created with the "disallow_unsafe_api" toggle that needs to be set on device creation. Bug: chromium:1138528 Change-Id: Ic2f5d876adca251b34ea594f70f344ac7669910e Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/31442 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
71d2e1d23d
commit
43ef0a365b
|
@ -36,6 +36,8 @@ class BindGroupValidationTest : public ValidationTest {
|
|||
}
|
||||
|
||||
void SetUp() override {
|
||||
ValidationTest::SetUp();
|
||||
|
||||
// Create objects to use as resources inside test bind groups.
|
||||
{
|
||||
wgpu::BufferDescriptor descriptor;
|
||||
|
@ -1069,6 +1071,8 @@ constexpr uint32_t kBindingSize = 9;
|
|||
class SetBindGroupValidationTest : public ValidationTest {
|
||||
public:
|
||||
void SetUp() override {
|
||||
ValidationTest::SetUp();
|
||||
|
||||
mBindGroupLayout = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
|
||||
wgpu::BindingType::UniformBuffer, true},
|
||||
|
@ -1509,6 +1513,8 @@ TEST_F(SetBindGroupValidationTest, ErrorBindGroup) {
|
|||
class SetBindGroupPersistenceValidationTest : public ValidationTest {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
ValidationTest::SetUp();
|
||||
|
||||
mVsModule = utils::CreateShaderModule(device, utils::SingleShaderStage::Vertex, R"(
|
||||
#version 450
|
||||
void main() {
|
||||
|
|
|
@ -1769,12 +1769,13 @@ TEST_F(CopyCommandTest_T2T, CopyWithinSameTexture) {
|
|||
}
|
||||
|
||||
class CopyCommandTest_CompressedTextureFormats : public CopyCommandTest {
|
||||
public:
|
||||
CopyCommandTest_CompressedTextureFormats() : CopyCommandTest() {
|
||||
device = CreateDeviceFromAdapter(adapter, {"texture_compression_bc"});
|
||||
protected:
|
||||
wgpu::Device CreateTestDevice() override {
|
||||
dawn_native::DeviceDescriptor descriptor;
|
||||
descriptor.requiredExtensions = {"texture_compression_bc"};
|
||||
return wgpu::Device::Acquire(adapter.CreateDevice(&descriptor));
|
||||
}
|
||||
|
||||
protected:
|
||||
wgpu::Texture Create2DTexture(wgpu::TextureFormat format,
|
||||
uint32_t mipmapLevels = 1,
|
||||
uint32_t width = kWidth,
|
||||
|
|
|
@ -38,9 +38,10 @@ class ErrorScopeValidationTest : public ValidationTest {
|
|||
}
|
||||
|
||||
void TearDown() override {
|
||||
ValidationTest::TearDown();
|
||||
|
||||
// Delete mocks so that expectations are checked
|
||||
mockDevicePopErrorScopeCallback = nullptr;
|
||||
ValidationTest::TearDown();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -18,15 +18,6 @@
|
|||
|
||||
class QuerySetValidationTest : public ValidationTest {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
ValidationTest::SetUp();
|
||||
|
||||
// Initialize the device with required extensions
|
||||
deviceWithPipelineStatistics =
|
||||
CreateDeviceFromAdapter(adapter, {"pipeline_statistics_query"});
|
||||
deviceWithTimestamp = CreateDeviceFromAdapter(adapter, {"timestamp_query"});
|
||||
}
|
||||
|
||||
wgpu::QuerySet CreateQuerySet(
|
||||
wgpu::Device cDevice,
|
||||
wgpu::QueryType queryType,
|
||||
|
@ -43,43 +34,17 @@ class QuerySetValidationTest : public ValidationTest {
|
|||
|
||||
return cDevice.CreateQuerySet(&descriptor);
|
||||
}
|
||||
|
||||
wgpu::Device deviceWithPipelineStatistics;
|
||||
wgpu::Device deviceWithTimestamp;
|
||||
};
|
||||
|
||||
// Test creating query set with/without extensions
|
||||
TEST_F(QuerySetValidationTest, Creation) {
|
||||
// Create query set for Occlusion query
|
||||
{
|
||||
// Success on default device without any extension enabled
|
||||
// Occlusion query does not require any extension.
|
||||
// Test creating query set without extensions
|
||||
TEST_F(QuerySetValidationTest, CreationWithoutExtensions) {
|
||||
// Creating a query set for occlusion queries succeeds without any extensions enabled.
|
||||
CreateQuerySet(device, wgpu::QueryType::Occlusion, 1);
|
||||
|
||||
// Success on the device with extension enabled.
|
||||
CreateQuerySet(deviceWithPipelineStatistics, wgpu::QueryType::Occlusion, 1);
|
||||
CreateQuerySet(deviceWithTimestamp, wgpu::QueryType::Occlusion, 1);
|
||||
}
|
||||
|
||||
// Create query set for PipelineStatistics query
|
||||
{
|
||||
// Fail on default device without any extension enabled
|
||||
// Creating a query set for other types of queries fails without extensions enabled.
|
||||
ASSERT_DEVICE_ERROR(CreateQuerySet(device, wgpu::QueryType::PipelineStatistics, 1,
|
||||
{wgpu::PipelineStatisticName::VertexShaderInvocations}));
|
||||
|
||||
// Success on the device if the extension is enabled.
|
||||
CreateQuerySet(deviceWithPipelineStatistics, wgpu::QueryType::PipelineStatistics, 1,
|
||||
{wgpu::PipelineStatisticName::VertexShaderInvocations});
|
||||
}
|
||||
|
||||
// Create query set for Timestamp query
|
||||
{
|
||||
// Fail on default device without any extension enabled
|
||||
ASSERT_DEVICE_ERROR(CreateQuerySet(device, wgpu::QueryType::Timestamp, 1));
|
||||
|
||||
// Success on the device if the extension is enabled.
|
||||
CreateQuerySet(deviceWithTimestamp, wgpu::QueryType::Timestamp, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Test creating query set with invalid type
|
||||
|
@ -87,54 +52,10 @@ TEST_F(QuerySetValidationTest, InvalidQueryType) {
|
|||
ASSERT_DEVICE_ERROR(CreateQuerySet(device, static_cast<wgpu::QueryType>(0xFFFFFFFF), 1));
|
||||
}
|
||||
|
||||
// Test creating query set with unnecessary pipeline statistics
|
||||
// Test creating query set with unnecessary pipeline statistics for occlusion queries
|
||||
TEST_F(QuerySetValidationTest, UnnecessaryPipelineStatistics) {
|
||||
// Fail to create with pipeline statistics for Occlusion query
|
||||
{
|
||||
ASSERT_DEVICE_ERROR(CreateQuerySet(device, wgpu::QueryType::Occlusion, 1,
|
||||
{wgpu::PipelineStatisticName::VertexShaderInvocations}));
|
||||
}
|
||||
|
||||
// Fail to create with pipeline statistics for Timestamp query
|
||||
{
|
||||
ASSERT_DEVICE_ERROR(CreateQuerySet(deviceWithTimestamp, wgpu::QueryType::Timestamp, 1,
|
||||
{wgpu::PipelineStatisticName::VertexShaderInvocations}));
|
||||
}
|
||||
}
|
||||
|
||||
// Test creating query set with invalid pipeline statistics
|
||||
TEST_F(QuerySetValidationTest, InvalidPipelineStatistics) {
|
||||
// Success to create with all pipeline statistics names which are not in the same order as
|
||||
// defined in webgpu header file
|
||||
{
|
||||
CreateQuerySet(deviceWithPipelineStatistics, wgpu::QueryType::PipelineStatistics, 1,
|
||||
{wgpu::PipelineStatisticName::ClipperInvocations,
|
||||
wgpu::PipelineStatisticName::ClipperPrimitivesOut,
|
||||
wgpu::PipelineStatisticName::ComputeShaderInvocations,
|
||||
wgpu::PipelineStatisticName::FragmentShaderInvocations,
|
||||
wgpu::PipelineStatisticName::VertexShaderInvocations});
|
||||
}
|
||||
|
||||
// Fail to create with empty pipeline statistics
|
||||
{
|
||||
ASSERT_DEVICE_ERROR(CreateQuerySet(deviceWithPipelineStatistics,
|
||||
wgpu::QueryType::PipelineStatistics, 1, {}));
|
||||
}
|
||||
|
||||
// Fail to create with invalid pipeline statistics
|
||||
{
|
||||
ASSERT_DEVICE_ERROR(CreateQuerySet(deviceWithPipelineStatistics,
|
||||
wgpu::QueryType::PipelineStatistics, 1,
|
||||
{static_cast<wgpu::PipelineStatisticName>(0xFFFFFFFF)}));
|
||||
}
|
||||
|
||||
// Fail to create with duplicate pipeline statistics
|
||||
{
|
||||
ASSERT_DEVICE_ERROR(CreateQuerySet(deviceWithPipelineStatistics,
|
||||
wgpu::QueryType::PipelineStatistics, 1,
|
||||
{wgpu::PipelineStatisticName::VertexShaderInvocations,
|
||||
wgpu::PipelineStatisticName::VertexShaderInvocations}));
|
||||
}
|
||||
}
|
||||
|
||||
// Test destroying a destroyed query set
|
||||
|
@ -147,47 +68,61 @@ TEST_F(QuerySetValidationTest, DestroyDestroyedQuerySet) {
|
|||
querySet.Destroy();
|
||||
}
|
||||
|
||||
class TimestampQueryValidationTest : public QuerySetValidationTest {};
|
||||
class TimestampQueryValidationTest : public QuerySetValidationTest {
|
||||
protected:
|
||||
wgpu::Device CreateTestDevice() override {
|
||||
dawn_native::DeviceDescriptor descriptor;
|
||||
descriptor.requiredExtensions = {"timestamp_query"};
|
||||
return wgpu::Device::Acquire(adapter.CreateDevice(&descriptor));
|
||||
}
|
||||
};
|
||||
|
||||
// Test creating query set with only the timestamp extension enabled.
|
||||
TEST_F(TimestampQueryValidationTest, Creation) {
|
||||
// Creating a query set for occlusion queries succeeds.
|
||||
CreateQuerySet(device, wgpu::QueryType::Occlusion, 1);
|
||||
|
||||
// Creating a query set for pipeline statistics queries fails.
|
||||
ASSERT_DEVICE_ERROR(CreateQuerySet(device, wgpu::QueryType::PipelineStatistics, 1,
|
||||
{wgpu::PipelineStatisticName::VertexShaderInvocations}));
|
||||
|
||||
// Creating a query set for timestamp queries succeeds.
|
||||
CreateQuerySet(device, wgpu::QueryType::Timestamp, 1);
|
||||
|
||||
// Fail to create with pipeline statistics for Timestamp query
|
||||
ASSERT_DEVICE_ERROR(CreateQuerySet(device, wgpu::QueryType::Timestamp, 1,
|
||||
{wgpu::PipelineStatisticName::VertexShaderInvocations}));
|
||||
}
|
||||
|
||||
// Test creating query set with unnecessary pipeline statistics for timestamp queries
|
||||
TEST_F(TimestampQueryValidationTest, UnnecessaryPipelineStatistics) {
|
||||
// Fail to create with pipeline statistics for Occlusion query
|
||||
ASSERT_DEVICE_ERROR(CreateQuerySet(device, wgpu::QueryType::Timestamp, 1,
|
||||
{wgpu::PipelineStatisticName::VertexShaderInvocations}));
|
||||
}
|
||||
|
||||
// Test write timestamp on command encoder
|
||||
TEST_F(TimestampQueryValidationTest, WriteTimestampOnCommandEncoder) {
|
||||
wgpu::QuerySet timestampQuerySet =
|
||||
CreateQuerySet(deviceWithTimestamp, wgpu::QueryType::Timestamp, 2);
|
||||
wgpu::QuerySet occlusionQuerySet =
|
||||
CreateQuerySet(deviceWithTimestamp, wgpu::QueryType::Occlusion, 2);
|
||||
wgpu::QuerySet timestampQuerySet = CreateQuerySet(device, wgpu::QueryType::Timestamp, 2);
|
||||
wgpu::QuerySet occlusionQuerySet = CreateQuerySet(device, wgpu::QueryType::Occlusion, 2);
|
||||
|
||||
// Success on command encoder
|
||||
{
|
||||
wgpu::CommandEncoder encoder = deviceWithTimestamp.CreateCommandEncoder();
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
encoder.WriteTimestamp(timestampQuerySet, 0);
|
||||
encoder.Finish();
|
||||
}
|
||||
|
||||
// Not allow to write timestamp from another device
|
||||
{
|
||||
// Write timestamp from default device
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
encoder.WriteTimestamp(timestampQuerySet, 0);
|
||||
ASSERT_DEVICE_ERROR(encoder.Finish());
|
||||
}
|
||||
|
||||
// Not allow to write timestamp to the query set with other query type
|
||||
{
|
||||
wgpu::CommandEncoder encoder = deviceWithTimestamp.CreateCommandEncoder();
|
||||
encoder.WriteTimestamp(occlusionQuerySet, 0);
|
||||
ASSERT_DEVICE_ERROR(encoder.Finish());
|
||||
}
|
||||
|
||||
// Fail to write timestamp to the index which exceeds the number of queries in query set
|
||||
{
|
||||
wgpu::CommandEncoder encoder = deviceWithTimestamp.CreateCommandEncoder();
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
encoder.WriteTimestamp(timestampQuerySet, 2);
|
||||
ASSERT_DEVICE_ERROR(encoder.Finish());
|
||||
}
|
||||
|
||||
// Fail to write timestamp to the same index twice on command encoder
|
||||
{
|
||||
wgpu::CommandEncoder encoder = deviceWithTimestamp.CreateCommandEncoder();
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
encoder.WriteTimestamp(timestampQuerySet, 0);
|
||||
encoder.WriteTimestamp(timestampQuerySet, 0);
|
||||
ASSERT_DEVICE_ERROR(encoder.Finish());
|
||||
|
@ -195,11 +130,11 @@ TEST_F(TimestampQueryValidationTest, WriteTimestampOnCommandEncoder) {
|
|||
|
||||
// Fail to submit timestamp query with a destroyed query set
|
||||
{
|
||||
wgpu::CommandEncoder encoder = deviceWithTimestamp.CreateCommandEncoder();
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
encoder.WriteTimestamp(timestampQuerySet, 0);
|
||||
wgpu::CommandBuffer commands = encoder.Finish();
|
||||
|
||||
wgpu::Queue queue = deviceWithTimestamp.GetDefaultQueue();
|
||||
wgpu::Queue queue = device.GetDefaultQueue();
|
||||
timestampQuerySet.Destroy();
|
||||
ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
|
||||
}
|
||||
|
@ -207,33 +142,21 @@ TEST_F(TimestampQueryValidationTest, WriteTimestampOnCommandEncoder) {
|
|||
|
||||
// Test write timestamp on compute pass encoder
|
||||
TEST_F(TimestampQueryValidationTest, WriteTimestampOnComputePassEncoder) {
|
||||
wgpu::QuerySet timestampQuerySet =
|
||||
CreateQuerySet(deviceWithTimestamp, wgpu::QueryType::Timestamp, 2);
|
||||
wgpu::QuerySet occlusionQuerySet =
|
||||
CreateQuerySet(deviceWithTimestamp, wgpu::QueryType::Occlusion, 2);
|
||||
wgpu::QuerySet timestampQuerySet = CreateQuerySet(device, wgpu::QueryType::Timestamp, 2);
|
||||
wgpu::QuerySet occlusionQuerySet = CreateQuerySet(device, wgpu::QueryType::Occlusion, 2);
|
||||
|
||||
// Success on compute pass encoder
|
||||
{
|
||||
wgpu::CommandEncoder encoder = deviceWithTimestamp.CreateCommandEncoder();
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
|
||||
pass.WriteTimestamp(timestampQuerySet, 0);
|
||||
pass.EndPass();
|
||||
encoder.Finish();
|
||||
}
|
||||
|
||||
// Not allow to write timestamp from another device
|
||||
{
|
||||
// Write timestamp from default device
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
|
||||
pass.WriteTimestamp(timestampQuerySet, 0);
|
||||
pass.EndPass();
|
||||
ASSERT_DEVICE_ERROR(encoder.Finish());
|
||||
}
|
||||
|
||||
// Not allow to write timestamp to the query set with other query type
|
||||
{
|
||||
wgpu::CommandEncoder encoder = deviceWithTimestamp.CreateCommandEncoder();
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
|
||||
pass.WriteTimestamp(occlusionQuerySet, 0);
|
||||
pass.EndPass();
|
||||
|
@ -242,7 +165,7 @@ TEST_F(TimestampQueryValidationTest, WriteTimestampOnComputePassEncoder) {
|
|||
|
||||
// Fail to write timestamp to the index which exceeds the number of queries in query set
|
||||
{
|
||||
wgpu::CommandEncoder encoder = deviceWithTimestamp.CreateCommandEncoder();
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
|
||||
pass.WriteTimestamp(timestampQuerySet, 2);
|
||||
pass.EndPass();
|
||||
|
@ -251,7 +174,7 @@ TEST_F(TimestampQueryValidationTest, WriteTimestampOnComputePassEncoder) {
|
|||
|
||||
// Fail to write timestamp to the same index twice on compute encoder
|
||||
{
|
||||
wgpu::CommandEncoder encoder = deviceWithTimestamp.CreateCommandEncoder();
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
|
||||
pass.WriteTimestamp(timestampQuerySet, 0);
|
||||
pass.WriteTimestamp(timestampQuerySet, 0);
|
||||
|
@ -261,7 +184,7 @@ TEST_F(TimestampQueryValidationTest, WriteTimestampOnComputePassEncoder) {
|
|||
|
||||
// Fail to write timestamp to the same index twice on command encoder and compute encoder
|
||||
{
|
||||
wgpu::CommandEncoder encoder = deviceWithTimestamp.CreateCommandEncoder();
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
encoder.WriteTimestamp(timestampQuerySet, 0);
|
||||
wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
|
||||
pass.WriteTimestamp(timestampQuerySet, 0);
|
||||
|
@ -271,13 +194,13 @@ TEST_F(TimestampQueryValidationTest, WriteTimestampOnComputePassEncoder) {
|
|||
|
||||
// Fail to submit timestamp query with a destroyed query set
|
||||
{
|
||||
wgpu::CommandEncoder encoder = deviceWithTimestamp.CreateCommandEncoder();
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
|
||||
pass.WriteTimestamp(timestampQuerySet, 0);
|
||||
pass.EndPass();
|
||||
wgpu::CommandBuffer commands = encoder.Finish();
|
||||
|
||||
wgpu::Queue queue = deviceWithTimestamp.GetDefaultQueue();
|
||||
wgpu::Queue queue = device.GetDefaultQueue();
|
||||
timestampQuerySet.Destroy();
|
||||
ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
|
||||
}
|
||||
|
@ -285,35 +208,23 @@ TEST_F(TimestampQueryValidationTest, WriteTimestampOnComputePassEncoder) {
|
|||
|
||||
// Test write timestamp on render pass encoder
|
||||
TEST_F(TimestampQueryValidationTest, WriteTimestampOnRenderPassEncoder) {
|
||||
DummyRenderPass renderPass(deviceWithTimestamp);
|
||||
DummyRenderPass renderPass(device);
|
||||
|
||||
wgpu::QuerySet timestampQuerySet =
|
||||
CreateQuerySet(deviceWithTimestamp, wgpu::QueryType::Timestamp, 2);
|
||||
wgpu::QuerySet occlusionQuerySet =
|
||||
CreateQuerySet(deviceWithTimestamp, wgpu::QueryType::Occlusion, 2);
|
||||
wgpu::QuerySet timestampQuerySet = CreateQuerySet(device, wgpu::QueryType::Timestamp, 2);
|
||||
wgpu::QuerySet occlusionQuerySet = CreateQuerySet(device, wgpu::QueryType::Occlusion, 2);
|
||||
|
||||
// Success on render pass encoder
|
||||
{
|
||||
wgpu::CommandEncoder encoder = deviceWithTimestamp.CreateCommandEncoder();
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
|
||||
pass.WriteTimestamp(timestampQuerySet, 0);
|
||||
pass.EndPass();
|
||||
encoder.Finish();
|
||||
}
|
||||
|
||||
// Not allow to write timestamp from another device
|
||||
{
|
||||
// Write timestamp from default device
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
|
||||
pass.WriteTimestamp(timestampQuerySet, 0);
|
||||
pass.EndPass();
|
||||
ASSERT_DEVICE_ERROR(encoder.Finish());
|
||||
}
|
||||
|
||||
// Not allow to write timestamp to the query set with other query type
|
||||
{
|
||||
wgpu::CommandEncoder encoder = deviceWithTimestamp.CreateCommandEncoder();
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
|
||||
pass.WriteTimestamp(occlusionQuerySet, 0);
|
||||
pass.EndPass();
|
||||
|
@ -322,7 +233,7 @@ TEST_F(TimestampQueryValidationTest, WriteTimestampOnRenderPassEncoder) {
|
|||
|
||||
// Fail to write timestamp to the index which exceeds the number of queries in query set
|
||||
{
|
||||
wgpu::CommandEncoder encoder = deviceWithTimestamp.CreateCommandEncoder();
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
|
||||
pass.WriteTimestamp(timestampQuerySet, 2);
|
||||
pass.EndPass();
|
||||
|
@ -331,7 +242,7 @@ TEST_F(TimestampQueryValidationTest, WriteTimestampOnRenderPassEncoder) {
|
|||
|
||||
// Fail to write timestamp to the same index twice on command encoder and render encoder
|
||||
{
|
||||
wgpu::CommandEncoder encoder = deviceWithTimestamp.CreateCommandEncoder();
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
|
||||
pass.WriteTimestamp(timestampQuerySet, 0);
|
||||
pass.WriteTimestamp(timestampQuerySet, 0);
|
||||
|
@ -341,7 +252,7 @@ TEST_F(TimestampQueryValidationTest, WriteTimestampOnRenderPassEncoder) {
|
|||
|
||||
// Fail to write timestamp to the same index twice on command encoder and render encoder
|
||||
{
|
||||
wgpu::CommandEncoder encoder = deviceWithTimestamp.CreateCommandEncoder();
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
encoder.WriteTimestamp(timestampQuerySet, 0);
|
||||
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
|
||||
pass.WriteTimestamp(timestampQuerySet, 0);
|
||||
|
@ -351,18 +262,70 @@ TEST_F(TimestampQueryValidationTest, WriteTimestampOnRenderPassEncoder) {
|
|||
|
||||
// Fail to submit timestamp query with a destroyed query set
|
||||
{
|
||||
wgpu::CommandEncoder encoder = deviceWithTimestamp.CreateCommandEncoder();
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
|
||||
pass.WriteTimestamp(timestampQuerySet, 0);
|
||||
pass.EndPass();
|
||||
wgpu::CommandBuffer commands = encoder.Finish();
|
||||
|
||||
wgpu::Queue queue = deviceWithTimestamp.GetDefaultQueue();
|
||||
wgpu::Queue queue = device.GetDefaultQueue();
|
||||
timestampQuerySet.Destroy();
|
||||
ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
|
||||
}
|
||||
}
|
||||
|
||||
class PipelineStatisticsQueryValidationTest : public QuerySetValidationTest {
|
||||
protected:
|
||||
wgpu::Device CreateTestDevice() override {
|
||||
dawn_native::DeviceDescriptor descriptor;
|
||||
descriptor.requiredExtensions = {"pipeline_statistics_query"};
|
||||
return wgpu::Device::Acquire(adapter.CreateDevice(&descriptor));
|
||||
}
|
||||
};
|
||||
|
||||
// Test creating query set with only the pipeline statistics extension enabled.
|
||||
TEST_F(PipelineStatisticsQueryValidationTest, Creation) {
|
||||
// Creating a query set for occlusion queries succeeds.
|
||||
CreateQuerySet(device, wgpu::QueryType::Occlusion, 1);
|
||||
|
||||
// Creating a query set for timestamp queries fails.
|
||||
ASSERT_DEVICE_ERROR(CreateQuerySet(device, wgpu::QueryType::Timestamp, 1));
|
||||
|
||||
// Creating a query set for pipeline statistics queries succeeds.
|
||||
CreateQuerySet(device, wgpu::QueryType::PipelineStatistics, 1,
|
||||
{wgpu::PipelineStatisticName::VertexShaderInvocations});
|
||||
}
|
||||
|
||||
// Test creating query set with invalid pipeline statistics
|
||||
TEST_F(PipelineStatisticsQueryValidationTest, InvalidPipelineStatistics) {
|
||||
// Success to create with all pipeline statistics names which are not in the same order as
|
||||
// defined in webgpu header file
|
||||
{
|
||||
CreateQuerySet(device, wgpu::QueryType::PipelineStatistics, 1,
|
||||
{wgpu::PipelineStatisticName::ClipperInvocations,
|
||||
wgpu::PipelineStatisticName::ClipperPrimitivesOut,
|
||||
wgpu::PipelineStatisticName::ComputeShaderInvocations,
|
||||
wgpu::PipelineStatisticName::FragmentShaderInvocations,
|
||||
wgpu::PipelineStatisticName::VertexShaderInvocations});
|
||||
}
|
||||
|
||||
// Fail to create with empty pipeline statistics
|
||||
{ ASSERT_DEVICE_ERROR(CreateQuerySet(device, wgpu::QueryType::PipelineStatistics, 1, {})); }
|
||||
|
||||
// Fail to create with invalid pipeline statistics
|
||||
{
|
||||
ASSERT_DEVICE_ERROR(CreateQuerySet(device, wgpu::QueryType::PipelineStatistics, 1,
|
||||
{static_cast<wgpu::PipelineStatisticName>(0xFFFFFFFF)}));
|
||||
}
|
||||
|
||||
// Fail to create with duplicate pipeline statistics
|
||||
{
|
||||
ASSERT_DEVICE_ERROR(CreateQuerySet(device, wgpu::QueryType::PipelineStatistics, 1,
|
||||
{wgpu::PipelineStatisticName::VertexShaderInvocations,
|
||||
wgpu::PipelineStatisticName::VertexShaderInvocations}));
|
||||
}
|
||||
}
|
||||
|
||||
class ResolveQuerySetValidationTest : public QuerySetValidationTest {
|
||||
protected:
|
||||
wgpu::Buffer CreateBuffer(wgpu::Device cDevice, uint64_t size, wgpu::BufferUsage usage) {
|
||||
|
@ -392,13 +355,6 @@ TEST_F(ResolveQuerySetValidationTest, ResolveInvalidQuerySetAndIndexCount) {
|
|||
queue.Submit(1, &commands);
|
||||
}
|
||||
|
||||
// Fail to resolve query set from another device
|
||||
{
|
||||
wgpu::CommandEncoder encoder = deviceWithTimestamp.CreateCommandEncoder();
|
||||
encoder.ResolveQuerySet(querySet, 0, kQueryCount, destination, 0);
|
||||
ASSERT_DEVICE_ERROR(encoder.Finish());
|
||||
}
|
||||
|
||||
// Fail to resolve query set if first query out of range
|
||||
{
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
|
@ -446,10 +402,11 @@ TEST_F(ResolveQuerySetValidationTest, ResolveToInvalidBufferAndOffset) {
|
|||
|
||||
// Fail to resolve query set to a buffer created from another device
|
||||
{
|
||||
wgpu::Buffer bufferOnTimestamp =
|
||||
CreateBuffer(deviceWithTimestamp, kBufferSize, wgpu::BufferUsage::QueryResolve);
|
||||
wgpu::CommandEncoder encoder = deviceWithTimestamp.CreateCommandEncoder();
|
||||
encoder.ResolveQuerySet(querySet, 0, kQueryCount, bufferOnTimestamp, 0);
|
||||
wgpu::Device otherDevice = adapter.CreateDevice();
|
||||
wgpu::Buffer bufferOnOther =
|
||||
CreateBuffer(otherDevice, kBufferSize, wgpu::BufferUsage::QueryResolve);
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
encoder.ResolveQuerySet(querySet, 0, kQueryCount, bufferOnOther, 0);
|
||||
ASSERT_DEVICE_ERROR(encoder.Finish());
|
||||
}
|
||||
|
||||
|
|
|
@ -520,12 +520,13 @@ namespace {
|
|||
}
|
||||
|
||||
class WriteTextureTest_CompressedTextureFormats : public QueueWriteTextureValidationTest {
|
||||
public:
|
||||
WriteTextureTest_CompressedTextureFormats() : QueueWriteTextureValidationTest() {
|
||||
device = CreateDeviceFromAdapter(adapter, {"texture_compression_bc"});
|
||||
protected:
|
||||
wgpu::Device CreateTestDevice() override {
|
||||
dawn_native::DeviceDescriptor descriptor;
|
||||
descriptor.requiredExtensions = {"texture_compression_bc"};
|
||||
return wgpu::Device::Acquire(adapter.CreateDevice(&descriptor));
|
||||
}
|
||||
|
||||
protected:
|
||||
wgpu::Texture Create2DTexture(wgpu::TextureFormat format,
|
||||
uint32_t mipmapLevels = 1,
|
||||
uint32_t width = kWidth,
|
||||
|
|
|
@ -20,6 +20,22 @@
|
|||
|
||||
class StorageTextureValidationTests : public ValidationTest {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
ValidationTest::SetUp();
|
||||
|
||||
mDefaultVSModule = utils::CreateShaderModule(device, utils::SingleShaderStage::Vertex, R"(
|
||||
#version 450
|
||||
void main() {
|
||||
gl_Position = vec4(0.f, 0.f, 0.f, 1.f);
|
||||
})");
|
||||
mDefaultFSModule = utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment, R"(
|
||||
#version 450
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
void main() {
|
||||
fragColor = vec4(1.f, 0.f, 0.f, 1.f);
|
||||
})");
|
||||
}
|
||||
|
||||
static const char* GetGLSLFloatImageTypeDeclaration(wgpu::TextureViewDimension dimension) {
|
||||
switch (dimension) {
|
||||
case wgpu::TextureViewDimension::e1D:
|
||||
|
@ -97,19 +113,8 @@ class StorageTextureValidationTests : public ValidationTest {
|
|||
return device.CreateTexture(&descriptor);
|
||||
}
|
||||
|
||||
const wgpu::ShaderModule mDefaultVSModule =
|
||||
utils::CreateShaderModule(device, utils::SingleShaderStage::Vertex, R"(
|
||||
#version 450
|
||||
void main() {
|
||||
gl_Position = vec4(0.f, 0.f, 0.f, 1.f);
|
||||
})");
|
||||
const wgpu::ShaderModule mDefaultFSModule =
|
||||
utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment, R"(
|
||||
#version 450
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
void main() {
|
||||
fragColor = vec4(1.f, 0.f, 0.f, 1.f);
|
||||
})");
|
||||
wgpu::ShaderModule mDefaultVSModule;
|
||||
wgpu::ShaderModule mDefaultFSModule;
|
||||
|
||||
const std::array<wgpu::BindingType, 2> kSupportedStorageTextureBindingTypes = {
|
||||
wgpu::BindingType::ReadonlyStorageTexture, wgpu::BindingType::WriteonlyStorageTexture};
|
||||
|
|
|
@ -24,6 +24,8 @@ namespace {
|
|||
class TextureValidationTest : public ValidationTest {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
ValidationTest::SetUp();
|
||||
|
||||
queue = device.GetDefaultQueue();
|
||||
}
|
||||
|
||||
|
@ -377,15 +379,26 @@ namespace {
|
|||
ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
|
||||
}
|
||||
|
||||
// Test that the creation of a texture with BC format will fail when the extension
|
||||
// textureCompressionBC is not enabled.
|
||||
TEST_F(TextureValidationTest, UseBCFormatWithoutEnablingExtension) {
|
||||
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||
wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
|
||||
descriptor.format = format;
|
||||
ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(jiawei.shao@intel.com): add tests to verify we cannot create 1D or 3D textures with
|
||||
// compressed texture formats.
|
||||
class CompressedTextureFormatsValidationTests : public TextureValidationTest {
|
||||
public:
|
||||
CompressedTextureFormatsValidationTests() : TextureValidationTest() {
|
||||
device = CreateDeviceFromAdapter(adapter, {"texture_compression_bc"});
|
||||
protected:
|
||||
wgpu::Device CreateTestDevice() override {
|
||||
dawn_native::DeviceDescriptor descriptor;
|
||||
descriptor.requiredExtensions = {"texture_compression_bc"};
|
||||
return wgpu::Device::Acquire(adapter.CreateDevice(&descriptor));
|
||||
}
|
||||
|
||||
protected:
|
||||
wgpu::TextureDescriptor CreateDefaultTextureDescriptor() {
|
||||
wgpu::TextureDescriptor descriptor =
|
||||
TextureValidationTest::CreateDefaultTextureDescriptor();
|
||||
|
@ -393,22 +406,13 @@ namespace {
|
|||
wgpu::TextureUsage::Sampled;
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
const std::array<wgpu::TextureFormat, 14> kBCFormats = {
|
||||
wgpu::TextureFormat::BC1RGBAUnorm, wgpu::TextureFormat::BC1RGBAUnormSrgb,
|
||||
wgpu::TextureFormat::BC2RGBAUnorm, wgpu::TextureFormat::BC2RGBAUnormSrgb,
|
||||
wgpu::TextureFormat::BC3RGBAUnorm, wgpu::TextureFormat::BC3RGBAUnormSrgb,
|
||||
wgpu::TextureFormat::BC4RUnorm, wgpu::TextureFormat::BC4RSnorm,
|
||||
wgpu::TextureFormat::BC5RGUnorm, wgpu::TextureFormat::BC5RGSnorm,
|
||||
wgpu::TextureFormat::BC6HRGBUfloat, wgpu::TextureFormat::BC6HRGBFloat,
|
||||
wgpu::TextureFormat::BC7RGBAUnorm, wgpu::TextureFormat::BC7RGBAUnormSrgb};
|
||||
};
|
||||
|
||||
// Test the validation of texture size when creating textures in compressed texture formats.
|
||||
TEST_F(CompressedTextureFormatsValidationTests, TextureSize) {
|
||||
// Test that it is invalid to use a number that is not a multiple of 4 (the compressed block
|
||||
// width and height of all BC formats) as the width or height of textures in BC formats.
|
||||
for (wgpu::TextureFormat format : kBCFormats) {
|
||||
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||
{
|
||||
wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
|
||||
descriptor.format = format;
|
||||
|
@ -440,18 +444,6 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
// Test the creation of a texture with BC format will fail when the extension
|
||||
// textureCompressionBC is not enabled.
|
||||
TEST_F(CompressedTextureFormatsValidationTests, UseBCFormatWithoutEnablingExtension) {
|
||||
const std::vector<const char*> kEmptyVector;
|
||||
wgpu::Device deviceWithoutExtension = CreateDeviceFromAdapter(adapter, kEmptyVector);
|
||||
for (wgpu::TextureFormat format : kBCFormats) {
|
||||
wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
|
||||
descriptor.format = format;
|
||||
ASSERT_DEVICE_ERROR(deviceWithoutExtension.CreateTexture(&descriptor));
|
||||
}
|
||||
}
|
||||
|
||||
// Test the validation of texture usages when creating textures in compressed texture formats.
|
||||
TEST_F(CompressedTextureFormatsValidationTests, TextureUsage) {
|
||||
// Test that only CopySrc, CopyDst and Sampled are accepted as the texture usage of the
|
||||
|
@ -461,7 +453,7 @@ namespace {
|
|||
wgpu::TextureUsage::Storage,
|
||||
wgpu::TextureUsage::Present,
|
||||
};
|
||||
for (wgpu::TextureFormat format : kBCFormats) {
|
||||
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||
for (wgpu::TextureUsage usage : invalidUsages) {
|
||||
wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
|
||||
descriptor.format = format;
|
||||
|
@ -475,7 +467,7 @@ namespace {
|
|||
TEST_F(CompressedTextureFormatsValidationTests, SampleCount) {
|
||||
// Test that it is invalid to specify SampleCount > 1 when we create a texture in BC
|
||||
// formats.
|
||||
for (wgpu::TextureFormat format : kBCFormats) {
|
||||
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||
wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
|
||||
descriptor.format = format;
|
||||
descriptor.sampleCount = 4;
|
||||
|
@ -486,7 +478,7 @@ namespace {
|
|||
// Test the validation of creating 2D array textures in compressed texture formats.
|
||||
TEST_F(CompressedTextureFormatsValidationTests, 2DArrayTexture) {
|
||||
// Test that it is allowed to create a 2D array texture in BC formats.
|
||||
for (wgpu::TextureFormat format : kBCFormats) {
|
||||
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||
wgpu::TextureDescriptor descriptor = CreateDefaultTextureDescriptor();
|
||||
descriptor.format = format;
|
||||
descriptor.size.depth = 6;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "dawn/webgpu.h"
|
||||
#include "dawn_native/NullBackend.h"
|
||||
|
||||
ValidationTest::ValidationTest() {
|
||||
void ValidationTest::SetUp() {
|
||||
instance = std::make_unique<dawn_native::Instance>();
|
||||
instance->DiscoverDefaultAdapters();
|
||||
|
||||
|
@ -42,25 +42,8 @@ ValidationTest::ValidationTest() {
|
|||
|
||||
dawnProcSetProcs(&dawn_native::GetProcs());
|
||||
|
||||
device = CreateDeviceFromAdapter(adapter, std::vector<const char*>());
|
||||
}
|
||||
|
||||
wgpu::Device ValidationTest::CreateDeviceFromAdapter(
|
||||
dawn_native::Adapter adapterToTest,
|
||||
const std::vector<const char*>& requiredExtensions) {
|
||||
wgpu::Device deviceToTest;
|
||||
|
||||
// Always keep this code path to test creating a device without a device descriptor.
|
||||
if (requiredExtensions.empty()) {
|
||||
deviceToTest = wgpu::Device::Acquire(adapterToTest.CreateDevice());
|
||||
} else {
|
||||
dawn_native::DeviceDescriptor descriptor;
|
||||
descriptor.requiredExtensions = requiredExtensions;
|
||||
deviceToTest = wgpu::Device::Acquire(adapterToTest.CreateDevice(&descriptor));
|
||||
}
|
||||
|
||||
deviceToTest.SetUncapturedErrorCallback(ValidationTest::OnDeviceError, this);
|
||||
return deviceToTest;
|
||||
device = CreateTestDevice();
|
||||
device.SetUncapturedErrorCallback(ValidationTest::OnDeviceError, this);
|
||||
}
|
||||
|
||||
ValidationTest::~ValidationTest() {
|
||||
|
@ -114,6 +97,10 @@ bool ValidationTest::HasWGSL() const {
|
|||
#endif
|
||||
}
|
||||
|
||||
wgpu::Device ValidationTest::CreateTestDevice() {
|
||||
return wgpu::Device::Acquire(adapter.CreateDevice());
|
||||
}
|
||||
|
||||
// static
|
||||
void ValidationTest::OnDeviceError(WGPUErrorType type, const char* message, void* userdata) {
|
||||
ASSERT(type != WGPUErrorType_NoError);
|
||||
|
|
|
@ -50,12 +50,9 @@
|
|||
|
||||
class ValidationTest : public testing::Test {
|
||||
public:
|
||||
ValidationTest();
|
||||
~ValidationTest() override;
|
||||
|
||||
wgpu::Device CreateDeviceFromAdapter(dawn_native::Adapter adapter,
|
||||
const std::vector<const char*>& requiredExtensions);
|
||||
|
||||
void SetUp() override;
|
||||
void TearDown() override;
|
||||
|
||||
void StartExpectDeviceError();
|
||||
|
@ -81,6 +78,8 @@ class ValidationTest : public testing::Test {
|
|||
bool HasWGSL() const;
|
||||
|
||||
protected:
|
||||
virtual wgpu::Device CreateTestDevice();
|
||||
|
||||
wgpu::Device device;
|
||||
dawn_native::Adapter adapter;
|
||||
std::unique_ptr<dawn_native::Instance> instance;
|
||||
|
|
Loading…
Reference in New Issue