diff --git a/src/backend/BindGroup.cpp b/src/backend/BindGroup.cpp index 0946c14d01..63c5c33484 100644 --- a/src/backend/BindGroup.cpp +++ b/src/backend/BindGroup.cpp @@ -19,6 +19,7 @@ #include "backend/Device.h" #include "backend/Texture.h" #include "common/Assert.h" +#include "common/Math.h" namespace backend { @@ -130,6 +131,11 @@ namespace backend { HandleError("Buffer needs to allow the correct usage bit"); return; } + + if (!IsAligned(bufferViews[i]->GetOffset(), 256)) { + HandleError("Buffer view offset for bind group needs to be 256-byte aligned"); + return; + } } SetBindingsBase(start, count, reinterpret_cast(bufferViews)); diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index f81d1609dd..81522c6efe 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -40,6 +40,7 @@ list(APPEND UNITTEST_SOURCES ${UNITTESTS_DIR}/SerialQueueTests.cpp ${UNITTESTS_DIR}/ToBackendTests.cpp ${UNITTESTS_DIR}/WireTests.cpp + ${VALIDATION_TESTS_DIR}/BindGroupValidationTests.cpp ${VALIDATION_TESTS_DIR}/BlendStateValidationTests.cpp ${VALIDATION_TESTS_DIR}/BufferValidationTests.cpp ${VALIDATION_TESTS_DIR}/CommandBufferValidationTests.cpp diff --git a/src/tests/unittests/validation/BindGroupValidationTests.cpp b/src/tests/unittests/validation/BindGroupValidationTests.cpp new file mode 100644 index 0000000000..defa564fa0 --- /dev/null +++ b/src/tests/unittests/validation/BindGroupValidationTests.cpp @@ -0,0 +1,105 @@ +// Copyright 2017 The NXT Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "tests/unittests/validation/ValidationTest.h" + +class BindGroupValidationTest : public ValidationTest { +}; + +TEST_F(BindGroupValidationTest, BufferViewOffset) { + auto layout = device.CreateBindGroupLayoutBuilder() + .SetBindingsType(nxt::ShaderStageBit::Vertex, nxt::BindingType::UniformBuffer, 0, 1) + .GetResult(); + + auto buffer = device.CreateBufferBuilder() + .SetAllowedUsage(nxt::BufferUsageBit::Uniform) + .SetInitialUsage(nxt::BufferUsageBit::Uniform) + .SetSize(512) + .GetResult(); + + // Check that offset 0 is valid + { + auto bufferView = buffer.CreateBufferViewBuilder() + .SetExtent(0, 512) + .GetResult(); + + auto bindGroup = AssertWillBeSuccess(device.CreateBindGroupBuilder()) + .SetLayout(layout) + .SetUsage(nxt::BindGroupUsage::Frozen) + .SetBufferViews(0, 1, &bufferView) + .GetResult(); + } + + // Check that offset 256 (aligned) is valid + { + auto bufferView = buffer.CreateBufferViewBuilder() + .SetExtent(256, 256) + .GetResult(); + + auto bindGroup = AssertWillBeSuccess(device.CreateBindGroupBuilder()) + .SetLayout(layout) + .SetUsage(nxt::BindGroupUsage::Frozen) + .SetBufferViews(0, 1, &bufferView) + .GetResult(); + } + + // Check cases where unaligned buffer view offset is invalid + { + auto bufferView = buffer.CreateBufferViewBuilder() + .SetExtent(1, 256) + .GetResult(); + + auto bindGroup = AssertWillBeError(device.CreateBindGroupBuilder()) + .SetLayout(layout) + .SetUsage(nxt::BindGroupUsage::Frozen) + .SetBufferViews(0, 1, &bufferView) + .GetResult(); + } + + { + auto bufferView = buffer.CreateBufferViewBuilder() + .SetExtent(64, 256) + .GetResult(); + + auto bindGroup = AssertWillBeError(device.CreateBindGroupBuilder()) + .SetLayout(layout) + .SetUsage(nxt::BindGroupUsage::Frozen) + .SetBufferViews(0, 1, &bufferView) + .GetResult(); + } + + { + auto bufferView = buffer.CreateBufferViewBuilder() + .SetExtent(128, 256) + .GetResult(); + + auto bindGroup = AssertWillBeError(device.CreateBindGroupBuilder()) + .SetLayout(layout) + .SetUsage(nxt::BindGroupUsage::Frozen) + .SetBufferViews(0, 1, &bufferView) + .GetResult(); + } + + { + auto bufferView = buffer.CreateBufferViewBuilder() + .SetExtent(255, 256) + .GetResult(); + + auto bindGroup = AssertWillBeError(device.CreateBindGroupBuilder()) + .SetLayout(layout) + .SetUsage(nxt::BindGroupUsage::Frozen) + .SetBufferViews(0, 1, &bufferView) + .GetResult(); + } +}