diff --git a/third_party/externals/dawn/src/dawn_native/Toggles.cpp b/third_party/externals/dawn/src/dawn_native/Toggles.cpp index b0e2dea250b9d83936a99e42f58a37eebe3fdcb5..ba182f3b802ff13843dce7f25eb26f9ace1507f5 100644 --- a/third_party/externals/dawn/src/dawn_native/Toggles.cpp +++ b/third_party/externals/dawn/src/dawn_native/Toggles.cpp @@ -90,6 +90,13 @@ namespace dawn_native { "recently used resources local to the GPU. Turning this component off can cause " "allocation failures when application memory exceeds physical device memory.", "https://crbug.com/dawn/193"}}, + {Toggle::DisableResourceSuballocation, + {"disable_resource_suballocation", + "Force the backends to not perform resource suballocation. This may expose " + "allocation " + "patterns which would otherwise only occur with large or specific types of " + "resources.", + "https://crbug.com/1313172"}}, {Toggle::SkipValidation, {"skip_validation", "Skip expensive validation of Dawn commands.", "https://crbug.com/dawn/271"}}, diff --git a/third_party/externals/dawn/src/dawn_native/Toggles.h b/third_party/externals/dawn/src/dawn_native/Toggles.h index 4682cbd57b559d9210da1ebdbcb146ee36410ddd..26e76f2241c6840223580d98fbcf38b19b29214a 100644 --- a/third_party/externals/dawn/src/dawn_native/Toggles.h +++ b/third_party/externals/dawn/src/dawn_native/Toggles.h @@ -33,6 +33,7 @@ namespace dawn_native { UseD3D12ResourceHeapTier2, UseD3D12RenderPass, UseD3D12ResidencyManagement, + DisableResourceSuballocation, SkipValidation, VulkanUseD32S8, MetalDisableSamplerCompare, diff --git a/third_party/externals/dawn/src/dawn_native/d3d12/ResourceAllocatorManagerD3D12.cpp b/third_party/externals/dawn/src/dawn_native/d3d12/ResourceAllocatorManagerD3D12.cpp index 6a10680de4579fc57b7a676f8ffe52e665f6b860..9001efbe17084d33264c35921c64108d3f0c3b4c 100644 --- a/third_party/externals/dawn/src/dawn_native/d3d12/ResourceAllocatorManagerD3D12.cpp +++ b/third_party/externals/dawn/src/dawn_native/d3d12/ResourceAllocatorManagerD3D12.cpp @@ -199,11 +199,13 @@ namespace dawn_native { namespace d3d12 { // For very small resources, it is inefficent to suballocate given the min. heap // size could be much larger then the resource allocation. // Attempt to satisfy the request using sub-allocation (placed resource in a heap). - ResourceHeapAllocation subAllocation; - DAWN_TRY_ASSIGN(subAllocation, CreatePlacedResource(heapType, resourceDescriptor, - optimizedClearValue, initialUsage)); - if (subAllocation.GetInfo().mMethod != AllocationMethod::kInvalid) { - return std::move(subAllocation); + if (!mDevice->IsToggleEnabled(Toggle::DisableResourceSuballocation)) { + ResourceHeapAllocation subAllocation; + DAWN_TRY_ASSIGN(subAllocation, CreatePlacedResource(heapType, resourceDescriptor, + optimizedClearValue, initialUsage)); + if (subAllocation.GetInfo().mMethod != AllocationMethod::kInvalid) { + return std::move(subAllocation); + } } // If sub-allocation fails, fall-back to direct allocation (committed resource). diff --git a/third_party/externals/dawn/src/dawn_native/vulkan/ResourceMemoryAllocatorVk.cpp b/third_party/externals/dawn/src/dawn_native/vulkan/ResourceMemoryAllocatorVk.cpp index 72bb019a29f9ed65152a4eed05574d2d87c8eec3..c9774de00093aa9f803492764cc7679abca20d16 100644 --- a/third_party/externals/dawn/src/dawn_native/vulkan/ResourceMemoryAllocatorVk.cpp +++ b/third_party/externals/dawn/src/dawn_native/vulkan/ResourceMemoryAllocatorVk.cpp @@ -134,7 +134,8 @@ namespace dawn_native { namespace vulkan { // Sub-allocate non-mappable resources because at the moment the mapped pointer // is part of the resource and not the heap, which doesn't match the Vulkan model. // TODO(crbug.com/dawn/849): allow sub-allocating mappable resources, maybe. - if (requirements.size < kMaxSizeForSubAllocation && kind != MemoryKind::LinearMappable) { + if (requirements.size < kMaxSizeForSubAllocation && kind != MemoryKind::LinearMappable && + !mDevice->IsToggleEnabled(Toggle::DisableResourceSuballocation)) { // When sub-allocating, Vulkan requires that we respect bufferImageGranularity. Some // hardware puts information on the memory's page table entry and allocating a linear // resource in the same page as a non-linear (aka opaque) resource can cause issues. diff --git a/third_party/externals/dawn/src/tests/end2end/BufferTests.cpp b/third_party/externals/dawn/src/tests/end2end/BufferTests.cpp index b893c02912016cf43b3dad9cd3200ddd9c3607f5..456379b2cbf95debccb42bf909be192960936afd 100644 --- a/third_party/externals/dawn/src/tests/end2end/BufferTests.cpp +++ b/third_party/externals/dawn/src/tests/end2end/BufferTests.cpp @@ -908,3 +908,29 @@ DAWN_INSTANTIATE_TEST(BufferTests, OpenGLBackend(), OpenGLESBackend(), VulkanBackend()); + +class BufferNoSuballocationTests : public DawnTest {}; +// Regression test for crbug.com/1313172 +// This tests a buffer. It then performs writeBuffer and immediately destroys +// it. Though writeBuffer references a destroyed buffer, it should not crash. +TEST_P(BufferNoSuballocationTests, WriteBufferThenDestroy) { + uint32_t myData = 0x01020304; + wgpu::BufferDescriptor desc; + desc.size = 1024; + desc.usage = wgpu::BufferUsage::CopyDst; + wgpu::Buffer buffer = device.CreateBuffer(&desc); + // Enqueue a pending write into the buffer. + constexpr size_t kSize = sizeof(myData); + queue.WriteBuffer(buffer, 0, &myData, kSize); + // Destroy the buffer. + buffer.Destroy(); + // Flush and wait for all commands. + queue.Submit(0, nullptr); + WaitForAllOperations(); +} +DAWN_INSTANTIATE_TEST(BufferNoSuballocationTests, + D3D12Backend({"disable_resource_suballocation"}), + MetalBackend({"disable_resource_suballocation"}), + OpenGLBackend({"disable_resource_suballocation"}), + OpenGLESBackend({"disable_resource_suballocation"}), + VulkanBackend({"disable_resource_suballocation"})); \ No newline at end of file