Add buffer lazy initialization before resolve queries on D3D12
- Reomve buffer initialization at buffer creation in end2end tests, and implement lazy initialization when resolving queries to buffer on D3D12 backend. - Add buffer lazy zero init tests for resolveQuerySet on D3D12. - For other backends, buffer lazy initialization will be added when its resolve method is implemented. Bug: dawn:434 Change-Id: Ib91c004b37ca912135a1c2fbb53bbd16e2d4eac6 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/28461 Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Hao Li <hao.x.li@intel.com>
This commit is contained in:
parent
19b910d796
commit
6419bddd9b
|
@ -892,6 +892,12 @@ namespace dawn_native { namespace d3d12 {
|
||||||
QuerySet* querySet = ToBackend(cmd->querySet.Get());
|
QuerySet* querySet = ToBackend(cmd->querySet.Get());
|
||||||
Buffer* destination = ToBackend(cmd->destination.Get());
|
Buffer* destination = ToBackend(cmd->destination.Get());
|
||||||
|
|
||||||
|
DAWN_TRY(destination->EnsureDataInitializedAsDestination(
|
||||||
|
commandContext, cmd->destinationOffset,
|
||||||
|
cmd->queryCount * sizeof(uint64_t)));
|
||||||
|
destination->TrackUsageAndTransitionNow(commandContext,
|
||||||
|
wgpu::BufferUsage::CopyDst);
|
||||||
|
|
||||||
commandList->ResolveQueryData(
|
commandList->ResolveQueryData(
|
||||||
querySet->GetQueryHeap(), D3D12QueryType(querySet->GetQueryType()),
|
querySet->GetQueryHeap(), D3D12QueryType(querySet->GetQueryType()),
|
||||||
cmd->firstQuery, cmd->queryCount, destination->GetD3D12Resource(),
|
cmd->firstQuery, cmd->queryCount, destination->GetD3D12Resource(),
|
||||||
|
|
|
@ -44,6 +44,15 @@ namespace {
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
class BufferZeroInitTest : public DawnTest {
|
class BufferZeroInitTest : public DawnTest {
|
||||||
|
protected:
|
||||||
|
std::vector<const char*> GetRequiredExtensions() override {
|
||||||
|
std::vector<const char*> requiredExtensions = {};
|
||||||
|
if (SupportsExtensions({"timestamp_query"})) {
|
||||||
|
requiredExtensions.push_back("timestamp_query");
|
||||||
|
}
|
||||||
|
return requiredExtensions;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
wgpu::Buffer CreateBuffer(uint64_t size,
|
wgpu::Buffer CreateBuffer(uint64_t size,
|
||||||
wgpu::BufferUsage usage,
|
wgpu::BufferUsage usage,
|
||||||
|
@ -1160,6 +1169,72 @@ TEST_P(BufferZeroInitTest, IndirectBufferForDispatchIndirect) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test the buffer will be lazily intialized correctly when its first use is in resolveQuerySet
|
||||||
|
TEST_P(BufferZeroInitTest, ResolveQuerySet) {
|
||||||
|
// Timestamp query is not supported on OpenGL
|
||||||
|
DAWN_SKIP_TEST_IF(IsOpenGL());
|
||||||
|
|
||||||
|
// TODO(hao.x.li@intel.com): Remove it after timestamp query is implementated on Vulkan and
|
||||||
|
// Metal
|
||||||
|
DAWN_SKIP_TEST_IF(IsVulkan() || IsMetal());
|
||||||
|
|
||||||
|
// Skip if timestamp extension is not supported on device
|
||||||
|
DAWN_SKIP_TEST_IF(!SupportsExtensions({"timestamp_query"}));
|
||||||
|
|
||||||
|
constexpr uint64_t kBufferSize = 16u;
|
||||||
|
constexpr wgpu::BufferUsage kBufferUsage =
|
||||||
|
wgpu::BufferUsage::QueryResolve | wgpu::BufferUsage::CopyDst;
|
||||||
|
|
||||||
|
wgpu::QuerySetDescriptor descriptor;
|
||||||
|
descriptor.count = 2u;
|
||||||
|
descriptor.type = wgpu::QueryType::Timestamp;
|
||||||
|
wgpu::QuerySet querySet = device.CreateQuerySet(&descriptor);
|
||||||
|
|
||||||
|
// Resolve data to the whole buffer doesn't need lazy initialization.
|
||||||
|
{
|
||||||
|
constexpr uint32_t kQueryCount = 2u;
|
||||||
|
constexpr uint64_t kDestinationOffset = 0u;
|
||||||
|
|
||||||
|
wgpu::Buffer destination = CreateBuffer(kBufferSize, kBufferUsage);
|
||||||
|
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||||
|
encoder.WriteTimestamp(querySet, 0);
|
||||||
|
encoder.WriteTimestamp(querySet, 1);
|
||||||
|
encoder.ResolveQuerySet(querySet, 0, kQueryCount, destination, kDestinationOffset);
|
||||||
|
wgpu::CommandBuffer commands = encoder.Finish();
|
||||||
|
|
||||||
|
EXPECT_LAZY_CLEAR(0u, queue.Submit(1, &commands));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolve data to partial of the buffer needs lazy initialization.
|
||||||
|
// destinationOffset == 0 and destinationOffset + 8 * queryCount < kBufferSize
|
||||||
|
{
|
||||||
|
constexpr uint32_t kQueryCount = 1u;
|
||||||
|
constexpr uint64_t kDestinationOffset = 0u;
|
||||||
|
|
||||||
|
wgpu::Buffer destination = CreateBuffer(kBufferSize, kBufferUsage);
|
||||||
|
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||||
|
encoder.WriteTimestamp(querySet, 0);
|
||||||
|
encoder.ResolveQuerySet(querySet, 0, kQueryCount, destination, kDestinationOffset);
|
||||||
|
wgpu::CommandBuffer commands = encoder.Finish();
|
||||||
|
|
||||||
|
EXPECT_LAZY_CLEAR(1u, queue.Submit(1, &commands));
|
||||||
|
}
|
||||||
|
|
||||||
|
// destinationOffset > 0 and destinationOffset + 8 * queryCount <= kBufferSize
|
||||||
|
{
|
||||||
|
constexpr uint32_t kQueryCount = 1;
|
||||||
|
constexpr uint64_t kDestinationOffset = 8u;
|
||||||
|
|
||||||
|
wgpu::Buffer destination = CreateBuffer(kBufferSize, kBufferUsage);
|
||||||
|
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||||
|
encoder.WriteTimestamp(querySet, 0);
|
||||||
|
encoder.ResolveQuerySet(querySet, 0, kQueryCount, destination, kDestinationOffset);
|
||||||
|
wgpu::CommandBuffer commands = encoder.Finish();
|
||||||
|
|
||||||
|
EXPECT_LAZY_CLEAR(1u, queue.Submit(1, &commands));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DAWN_INSTANTIATE_TEST(BufferZeroInitTest,
|
DAWN_INSTANTIATE_TEST(BufferZeroInitTest,
|
||||||
D3D12Backend({"nonzero_clear_resources_on_creation_for_testing"}),
|
D3D12Backend({"nonzero_clear_resources_on_creation_for_testing"}),
|
||||||
MetalBackend({"nonzero_clear_resources_on_creation_for_testing"}),
|
MetalBackend({"nonzero_clear_resources_on_creation_for_testing"}),
|
||||||
|
|
|
@ -28,13 +28,7 @@ class QueryTests : public DawnTest {
|
||||||
descriptor.size = size;
|
descriptor.size = size;
|
||||||
descriptor.usage = wgpu::BufferUsage::QueryResolve | wgpu::BufferUsage::CopySrc |
|
descriptor.usage = wgpu::BufferUsage::QueryResolve | wgpu::BufferUsage::CopySrc |
|
||||||
wgpu::BufferUsage::CopyDst;
|
wgpu::BufferUsage::CopyDst;
|
||||||
wgpu::Buffer buffer = device.CreateBuffer(&descriptor);
|
return device.CreateBuffer(&descriptor);
|
||||||
|
|
||||||
// Initialize the buffer values to 0.
|
|
||||||
std::vector<uint64_t> myData = {0, 0};
|
|
||||||
device.GetDefaultQueue().WriteBuffer(buffer, 0, myData.data(), size);
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue