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());
|
||||
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(
|
||||
querySet->GetQueryHeap(), D3D12QueryType(querySet->GetQueryType()),
|
||||
cmd->firstQuery, cmd->queryCount, destination->GetD3D12Resource(),
|
||||
|
|
|
@ -44,6 +44,15 @@ namespace {
|
|||
} // anonymous namespace
|
||||
|
||||
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:
|
||||
wgpu::Buffer CreateBuffer(uint64_t size,
|
||||
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,
|
||||
D3D12Backend({"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.usage = wgpu::BufferUsage::QueryResolve | wgpu::BufferUsage::CopySrc |
|
||||
wgpu::BufferUsage::CopyDst;
|
||||
wgpu::Buffer buffer = 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;
|
||||
return device.CreateBuffer(&descriptor);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue