Align the size of Uniform and Storage buffer to 16 bytes in Metal

On Metal, it requires the size of the constant buffer to be no less
than the size of the constant buffer block defined in shader, and
the overall size of the constant buffer must be aligned to the
largest alignment of its members.

BUG=dawn:139

Change-Id: I37730b1415baecb6638aaaacec87789decf07606
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/10920
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Hao Li <hao.x.li@intel.com>
This commit is contained in:
Li, Hao 2019-09-07 03:08:45 +00:00 committed by Commit Bot service account
parent 22c3ff73c1
commit 77f091ce46
3 changed files with 13 additions and 16 deletions

View File

@ -14,9 +14,13 @@
#include "dawn_native/metal/BufferMTL.h"
#include "common/Math.h"
#include "dawn_native/metal/DeviceMTL.h"
namespace dawn_native { namespace metal {
// The size of uniform buffer and storage buffer need to be aligned to 16 bytes which is the
// largest alignment of supported data types
static constexpr uint32_t kMinUniformOrStorageBufferAlignment = 16u;
Buffer::Buffer(Device* device, const BufferDescriptor* descriptor)
: BufferBase(device, descriptor) {
@ -27,7 +31,15 @@ namespace dawn_native { namespace metal {
storageMode = MTLResourceStorageModePrivate;
}
mMtlBuffer = [device->GetMTLDevice() newBufferWithLength:GetSize() options:storageMode];
uint32_t currentSize = GetSize();
// Metal validation layer requires the size of uniform buffer and storage buffer to be no
// less than the size of the buffer block defined in shader, and the overall size of the
// buffer must be aligned to the largest alignment of its members.
if (GetUsage() & (dawn::BufferUsage::Uniform | dawn::BufferUsage::Storage)) {
currentSize = Align(currentSize, kMinUniformOrStorageBufferAlignment);
}
mMtlBuffer = [device->GetMTLDevice() newBufferWithLength:currentSize options:storageMode];
}
Buffer::~Buffer() {

View File

@ -105,21 +105,11 @@ void ComputeIndirectTests::BasicTest(std::initializer_list<uint32_t> bufferList,
// Test basic indirect
TEST_P(ComputeIndirectTests, Basic) {
// TODO(hao.x.li@intel.com): Test failing on Metal with validation layer on, which blocks
// end2end tests run with validation layer in bots. Suppress this while we're fixing.
// See https://bugs.chromium.org/p/dawn/issues/detail?id=139
DAWN_SKIP_TEST_IF(IsMetal() && IsBackendValidationEnabled());
BasicTest({2, 3, 4}, 0);
}
// Test indirect with buffer offset
TEST_P(ComputeIndirectTests, IndirectOffset) {
// TODO(hao.x.li@intel.com): Test failing on Metal with validation layer on, which blocks
// end2end tests run with validation layer in bots. Suppress this while we're fixing.
// See https://bugs.chromium.org/p/dawn/issues/detail?id=139
DAWN_SKIP_TEST_IF(IsMetal() && IsBackendValidationEnabled());
BasicTest({0, 0, 0, 2, 3, 4}, 3 * sizeof(uint32_t));
}

View File

@ -255,11 +255,6 @@ TEST_P(MultisampledRenderingTest, ResolveInto2DTexture) {
// Test multisampled rendering with depth test works correctly.
TEST_P(MultisampledRenderingTest, MultisampledRenderingWithDepthTest) {
// TODO(hao.x.li@intel.com): Test failing on Metal with validation layer on, which blocks
// end2end tests run with validation layer in bots. Suppress this while we're fixing.
// See https://bugs.chromium.org/p/dawn/issues/detail?id=139
DAWN_SKIP_TEST_IF(IsMetal() && IsBackendValidationEnabled());
constexpr bool kTestDepth = true;
dawn::CommandEncoder commandEncoder = device.CreateCommandEncoder();
dawn::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(kTestDepth);