D3D12: Align UBO sizes to 256B.

D3D debug layer uses the descriptor size (width) to
validate CBV bounds when directly allocating UBOs.
This causes validation failure when the buffer size
is misaligned (ie. not a multiple of 256B) even
through the underlying resource heap size is always
64KB aligned.

This change always aligns the buffer size to be 256B
to avoid such validation error should sub-allocation
fail.

BUG=dawn:506

Change-Id: Ic9072934cac65cfd25d0e2a20cb364bd3ca88e3b
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/26820
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Bryan Bernhart <bryan.bernhart@intel.com>
This commit is contained in:
Bryan Bernhart
2020-09-17 23:30:40 +00:00
committed by Commit Bot service account
parent 95e715873d
commit ac3765e663
6 changed files with 73 additions and 24 deletions

View File

@@ -396,7 +396,7 @@ source_set("dawn_white_box_tests_sources") {
sources += [
"white_box/D3D12DescriptorHeapTests.cpp",
"white_box/D3D12ResidencyTests.cpp",
"white_box/D3D12SmallTextureTests.cpp",
"white_box/D3D12ResourceHeapTests.cpp",
]
}

View File

@@ -136,17 +136,17 @@ TEST(Math, AlignPtr) {
// Tests for Align
TEST(Math, Align) {
// 0 aligns to 0
ASSERT_EQ(Align(0, 4), 0u);
ASSERT_EQ(Align(0, 256), 0u);
ASSERT_EQ(Align(0, 512), 0u);
ASSERT_EQ(Align(0u, 4), 0u);
ASSERT_EQ(Align(0u, 256), 0u);
ASSERT_EQ(Align(0u, 512), 0u);
// Multiples align to self
ASSERT_EQ(Align(8, 8), 8u);
ASSERT_EQ(Align(16, 8), 16u);
ASSERT_EQ(Align(24, 8), 24u);
ASSERT_EQ(Align(256, 256), 256u);
ASSERT_EQ(Align(512, 256), 512u);
ASSERT_EQ(Align(768, 256), 768u);
ASSERT_EQ(Align(8u, 8), 8u);
ASSERT_EQ(Align(16u, 8), 16u);
ASSERT_EQ(Align(24u, 8), 24u);
ASSERT_EQ(Align(256u, 256), 256u);
ASSERT_EQ(Align(512u, 256), 512u);
ASSERT_EQ(Align(768u, 256), 768u);
// Alignment with 1 is self
for (uint32_t i = 0; i < 128; ++i) {
@@ -157,6 +157,10 @@ TEST(Math, Align) {
for (uint32_t i = 1; i <= 64; ++i) {
ASSERT_EQ(Align(64 + i, 64), 128u);
}
// Test extrema
ASSERT_EQ(Align(static_cast<uint64_t>(0xFFFFFFFF), 4), 0x100000000u);
ASSERT_EQ(Align(static_cast<uint64_t>(0xFFFFFFFFFFFFFFFF), 1), 0xFFFFFFFFFFFFFFFFull);
}
// Tests for IsPtrAligned

View File

@@ -14,12 +14,18 @@
#include "tests/DawnTest.h"
#include "dawn_native/d3d12/BufferD3D12.h"
#include "dawn_native/d3d12/TextureD3D12.h"
using namespace dawn_native::d3d12;
class D3D12SmallTextureTests : public DawnTest {
class D3D12ResourceHeapTests : public DawnTest {
protected:
void SetUp() override {
DawnTest::SetUp();
DAWN_SKIP_TEST_IF(UsesWire());
}
std::vector<const char*> GetRequiredExtensions() override {
mIsBCFormatSupported = SupportsExtensions({"texture_compression_bc"});
if (!mIsBCFormatSupported) {
@@ -38,8 +44,7 @@ class D3D12SmallTextureTests : public DawnTest {
};
// Verify that creating a small compressed textures will be 4KB aligned.
TEST_P(D3D12SmallTextureTests, AlignSmallCompressedTexture) {
DAWN_SKIP_TEST_IF(UsesWire());
TEST_P(D3D12ResourceHeapTests, AlignSmallCompressedTexture) {
DAWN_SKIP_TEST_IF(!IsBCFormatSupported());
// TODO(http://crbug.com/dawn/282): Investigate GPU/driver rejections of small alignment.
@@ -73,4 +78,28 @@ TEST_P(D3D12SmallTextureTests, AlignSmallCompressedTexture) {
static_cast<uint64_t>(D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT));
}
DAWN_INSTANTIATE_TEST(D3D12SmallTextureTests, D3D12Backend());
// Verify creating a UBO will always be 256B aligned.
TEST_P(D3D12ResourceHeapTests, AlignUBO) {
// Create a small UBO
wgpu::BufferDescriptor descriptor;
descriptor.size = 4 * 1024;
descriptor.usage = wgpu::BufferUsage::Uniform;
wgpu::Buffer buffer = device.CreateBuffer(&descriptor);
Buffer* d3dBuffer = reinterpret_cast<Buffer*>(buffer.Get());
EXPECT_TRUE((d3dBuffer->GetD3D12Resource()->GetDesc().Width %
static_cast<uint64_t>(D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT)) == 0u);
// Create a larger UBO
descriptor.size = (4 * 1024 * 1024) + 255;
descriptor.usage = wgpu::BufferUsage::Uniform;
buffer = device.CreateBuffer(&descriptor);
d3dBuffer = reinterpret_cast<Buffer*>(buffer.Get());
EXPECT_TRUE((d3dBuffer->GetD3D12Resource()->GetDesc().Width %
static_cast<uint64_t>(D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT)) == 0u);
}
DAWN_INSTANTIATE_TEST(D3D12ResourceHeapTests, D3D12Backend());