From 1586b4d73ed1c0a7547945fd500ac464216204a2 Mon Sep 17 00:00:00 2001 From: Corentin Wallez Date: Tue, 17 Dec 2019 17:34:21 +0000 Subject: [PATCH] Vulkan: prevent degenerate buffer sizes from reaching the driver Allocating buffers with sizes close to UINT64_MAX caused issues in all Vulkan drivers. See https://gitlab.khronos.org/vulkan/vulkan/issues/1904 for more context. Do early validation to prevent such cases from reaching the driver. Bug: dawn:241 Fixed: dawn:241 Change-Id: I7edbb25999b4c11767047518b69edc1fa624cd3b Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/14641 Commit-Queue: Corentin Wallez Reviewed-by: Austin Eng --- src/dawn_native/vulkan/BufferVk.cpp | 10 ++++++++++ src/tests/end2end/BufferTests.cpp | 5 ----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/dawn_native/vulkan/BufferVk.cpp b/src/dawn_native/vulkan/BufferVk.cpp index 15571c7c90..8f8b3aa2f0 100644 --- a/src/dawn_native/vulkan/BufferVk.cpp +++ b/src/dawn_native/vulkan/BufferVk.cpp @@ -123,6 +123,16 @@ namespace dawn_native { namespace vulkan { } MaybeError Buffer::Initialize() { + // Avoid passing ludicrously large sizes to drivers because it causes issues: drivers add + // some constants to the size passed and align it, but for values close to the maximum + // VkDeviceSize this can cause overflows and makes drivers crash or return bad sizes in the + // VkmemoryRequirements. See https://gitlab.khronos.org/vulkan/vulkan/issues/1904 + // Any size with one of two top bits of VkDeviceSize set is a HUGE allocation and we can + // safely return an OOM error. + if (GetSize() & (uint64_t(3) << uint64_t(62))) { + return DAWN_OUT_OF_MEMORY_ERROR("Buffer size is HUGE and could cause overflows"); + } + VkBufferCreateInfo createInfo; createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; createInfo.pNext = nullptr; diff --git a/src/tests/end2end/BufferTests.cpp b/src/tests/end2end/BufferTests.cpp index 09640fa080..93fe804ddf 100644 --- a/src/tests/end2end/BufferTests.cpp +++ b/src/tests/end2end/BufferTests.cpp @@ -733,11 +733,6 @@ TEST_P(CreateBufferMappedTests, LargeBufferFails) { // TODO(http://crbug.com/dawn/27): Missing support. DAWN_SKIP_TEST_IF(IsMetal() || IsOpenGL()); - // TODO(http://crbug.com/dawn/241): Fails on NVIDIA cards when Vulkan validation layers are - // enabled becuase the maximum size of a single allocation cannot be larger than or equal to - // 4G on some platforms. - DAWN_SKIP_TEST_IF(IsVulkan() && IsNvidia() && IsBackendValidationEnabled()); - wgpu::BufferDescriptor descriptor; descriptor.size = std::numeric_limits::max(); descriptor.usage = wgpu::BufferUsage::MapRead | wgpu::BufferUsage::CopyDst;