Validate compute pass timestamp queries are unique

This validation existed for render passes but not for compute passes,
and it's not clear why.

Bug: dawn:1809
Change-Id: I8babb6ddf455a915f5a0c85ad1a7d741fdb467a8
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/132481
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Brandon Jones <bajones@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Brandon Jones 2023-05-11 22:36:36 +00:00 committed by Dawn LUCI CQ
parent a03e55d577
commit d5611aa7c2
3 changed files with 24 additions and 33 deletions

View File

@ -508,6 +508,9 @@ MaybeError ValidateComputePassDescriptor(const DeviceBase* device,
if (descriptor->timestampWriteCount > 0) { if (descriptor->timestampWriteCount > 0) {
DAWN_ASSERT(descriptor->timestampWrites != nullptr); DAWN_ASSERT(descriptor->timestampWrites != nullptr);
// Record the query set and query index used on compute passes for validating query
// index overwrite.
QueryAvailabilityMap usedQueries;
// TODO(https://crbug.com/dawn/1452): // TODO(https://crbug.com/dawn/1452):
// 1. Add an enum that's TimestampLocationMask and has bit values. // 1. Add an enum that's TimestampLocationMask and has bit values.
// 2. Add a function with a switch that converts from one to the other. // 2. Add a function with a switch that converts from one to the other.
@ -515,14 +518,25 @@ MaybeError ValidateComputePassDescriptor(const DeviceBase* device,
// 4. Use it here. // 4. Use it here.
std::unordered_set<wgpu::ComputePassTimestampLocation> writtenLocations; std::unordered_set<wgpu::ComputePassTimestampLocation> writtenLocations;
for (uint32_t i = 0; i < descriptor->timestampWriteCount; ++i) { for (uint32_t i = 0; i < descriptor->timestampWriteCount; ++i) {
DAWN_ASSERT(descriptor->timestampWrites[i].querySet != nullptr); QuerySetBase* querySet = descriptor->timestampWrites[i].querySet;
DAWN_TRY_CONTEXT(ValidateTimestampQuery(device, descriptor->timestampWrites[i].querySet, DAWN_ASSERT(querySet != nullptr);
descriptor->timestampWrites[i].queryIndex), uint32_t queryIndex = descriptor->timestampWrites[i].queryIndex;
DAWN_TRY_CONTEXT(ValidateTimestampQuery(device, querySet, queryIndex),
"validating querySet and queryIndex of timestampWrites[%u].", i); "validating querySet and queryIndex of timestampWrites[%u].", i);
DAWN_TRY_CONTEXT(ValidateTimestampLocationOnComputePass( DAWN_TRY_CONTEXT(ValidateTimestampLocationOnComputePass(
descriptor->timestampWrites[i].location, writtenLocations), descriptor->timestampWrites[i].location, writtenLocations),
"validating location of timestampWrites[%u].", i); "validating location of timestampWrites[%u].", i);
writtenLocations.insert(descriptor->timestampWrites[i].location); writtenLocations.insert(descriptor->timestampWrites[i].location);
auto checkIt = usedQueries.find(querySet);
DAWN_INVALID_IF(checkIt != usedQueries.end() && checkIt->second[queryIndex],
"Query index %u of %s is written to twice in a compute pass.",
queryIndex, querySet);
// Gets the iterator for that querySet or create a new vector of bool set to
// false if the querySet wasn't registered.
auto addIt = usedQueries.emplace(querySet, querySet->GetQueryCount()).first;
addIt->second[queryIndex] = true;
} }
} }

View File

@ -864,37 +864,14 @@ TEST_P(TimestampQueryTests, TimestampWritesQuerySetOnComputePass) {
// Test timestampWrites with query index in compute pass descriptor // Test timestampWrites with query index in compute pass descriptor
TEST_P(TimestampQueryTests, TimestampWritesQueryIndexOnComputePass) { TEST_P(TimestampQueryTests, TimestampWritesQueryIndexOnComputePass) {
constexpr uint32_t kQueryCount = 2; // Set timestampWrites with different query indexes and locations, not need test write same
// query index due to it's not allowed on compute pass.
wgpu::QuerySet querySet = CreateQuerySetForTimestamp(2);
// Set timestampWrites with different query indexes on same compute pass TestTimestampWritesOnComputePass({{querySet, 0, wgpu::ComputePassTimestampLocation::Beginning},
{
wgpu::QuerySet querySet = CreateQuerySetForTimestamp(kQueryCount);
TestTimestampWritesOnComputePass(
{{querySet, 0, wgpu::ComputePassTimestampLocation::Beginning},
{querySet, 1, wgpu::ComputePassTimestampLocation::End}}); {querySet, 1, wgpu::ComputePassTimestampLocation::End}});
} }
// Set timestampWrites with same query index on same compute pass
{
wgpu::QuerySet querySet = CreateQuerySetForTimestamp(kQueryCount);
TestTimestampWritesOnComputePass(
{{querySet, 0, wgpu::ComputePassTimestampLocation::Beginning},
{querySet, 0, wgpu::ComputePassTimestampLocation::End}});
}
// Set timestampWrites with same query indexes on different compute pass
{
wgpu::QuerySet querySet0 = CreateQuerySetForTimestamp(kQueryCount);
wgpu::QuerySet querySet1 = CreateQuerySetForTimestamp(kQueryCount);
TestTimestampWritesOnComputePass(
{{querySet0, 0, wgpu::ComputePassTimestampLocation::Beginning}},
{{querySet1, 0, wgpu::ComputePassTimestampLocation::End}});
}
}
// Test timestampWrites with timestamp location in compute pass descriptor // Test timestampWrites with timestamp location in compute pass descriptor
TEST_P(TimestampQueryTests, TimestampWritesLocationOnComputePass) { TEST_P(TimestampQueryTests, TimestampWritesLocationOnComputePass) {
constexpr uint32_t kQueryCount = 2; constexpr uint32_t kQueryCount = 2;

View File

@ -385,13 +385,13 @@ TEST_F(TimestampQueryValidationTest, TimestampWritesOnComputePass) {
ASSERT_DEVICE_ERROR(encoder.Finish()); ASSERT_DEVICE_ERROR(encoder.Finish());
} }
// Success to write timestamps to the same query index twice on same compute pass // Fail to write timestamps to the same query index twice on same compute pass
{ {
wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
EncodeComputePassWithTimestampWrites( EncodeComputePassWithTimestampWrites(
encoder, {{querySet, 0, wgpu::ComputePassTimestampLocation::Beginning}, encoder, {{querySet, 0, wgpu::ComputePassTimestampLocation::Beginning},
{querySet, 0, wgpu::ComputePassTimestampLocation::End}}); {querySet, 0, wgpu::ComputePassTimestampLocation::End}});
encoder.Finish(); ASSERT_DEVICE_ERROR(encoder.Finish());
} }
// Success to write timestamps at same location of different compute pass // Success to write timestamps at same location of different compute pass