Make SetSubData take size in uint8_t not uint32_t.

Also change data pointer to uint8_t*.
Add a test for a non-aligned SetSubData().
Implemented on all backends.
This commit is contained in:
Stephen White
2018-02-04 11:07:02 -05:00
committed by Corentin Wallez
parent ee66f25c4f
commit e5ae3274a3
27 changed files with 93 additions and 68 deletions

View File

@@ -430,6 +430,7 @@ namespace detail {
return testing::AssertionSuccess();
}
template class ExpectEq<uint8_t>;
template class ExpectEq<uint32_t>;
template class ExpectEq<RGBA8>;
}

View File

@@ -26,6 +26,10 @@
#define EXPECT_BUFFER_U32_RANGE_EQ(expected, buffer, offset, count) \
AddBufferExpectation(__FILE__, __LINE__, buffer, offset, sizeof(uint32_t) * count, new detail::ExpectEq<uint32_t>(expected, count))
#define EXPECT_BUFFER_U8_EQ(expected, buffer, offset) \
AddBufferExpectation(__FILE__, __LINE__, buffer, offset, sizeof(uint8_t), \
new detail::ExpectEq<uint8_t>(expected))
// Test a pixel of the mip level 0 of a 2D texture.
#define EXPECT_PIXEL_RGBA8_EQ(expected, texture, x, y) \
AddTextureExpectation(__FILE__, __LINE__, texture, x, y, 1, 1, 0, sizeof(RGBA8), new detail::ExpectEq<RGBA8>(expected))
@@ -166,6 +170,7 @@ namespace detail {
private:
std::vector<T> mExpected;
};
extern template class ExpectEq<uint8_t>;
extern template class ExpectEq<uint32_t>;
extern template class ExpectEq<RGBA8>;
}

View File

@@ -28,10 +28,10 @@ TEST_P(BasicTests, BufferSetSubData) {
.SetInitialUsage(nxt::BufferUsageBit::TransferDst)
.GetResult();
uint32_t value = 3094587;
buffer.SetSubData(0, 1, &value);
uint8_t value = 187;
buffer.SetSubData(0, sizeof(value), &value);
EXPECT_BUFFER_U32_EQ(value, buffer, 0);
EXPECT_BUFFER_U8_EQ(value, buffer, 0);
}
NXT_INSTANTIATE_TEST(BasicTests, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend)

View File

@@ -41,20 +41,20 @@ class BufferMapReadTests : public NXTTest {
const void* mappedData = nullptr;
};
// Test that the simplest map read (one u32 at offset 0) works.
// Test that the simplest map read (one u8 at offset 0) works.
TEST_P(BufferMapReadTests, SmallReadAtZero) {
nxt::Buffer buffer = device.CreateBufferBuilder()
.SetSize(4)
.SetSize(1)
.SetAllowedUsage(nxt::BufferUsageBit::MapRead | nxt::BufferUsageBit::TransferDst)
.SetInitialUsage(nxt::BufferUsageBit::TransferDst)
.GetResult();
uint32_t myData = 2934875;
buffer.SetSubData(0, 1, &myData);
uint8_t myData = 187;
buffer.SetSubData(0, sizeof(myData), &myData);
buffer.TransitionUsage(nxt::BufferUsageBit::MapRead);
const void* mappedData = MapReadAsyncAndWait(buffer, 0, 4);
ASSERT_EQ(myData, *reinterpret_cast<const uint32_t*>(mappedData));
const void* mappedData = MapReadAsyncAndWait(buffer, 0, 1);
ASSERT_EQ(myData, *reinterpret_cast<const uint8_t*>(mappedData));
buffer.Unmap();
}
@@ -67,12 +67,30 @@ TEST_P(BufferMapReadTests, SmallReadAtOffset) {
.SetInitialUsage(nxt::BufferUsageBit::TransferDst)
.GetResult();
uint32_t myData = 2934875;
buffer.SetSubData(2048 / sizeof(uint32_t), 1, &myData);
uint8_t myData = 234;
buffer.SetSubData(2048, sizeof(myData), &myData);
buffer.TransitionUsage(nxt::BufferUsageBit::MapRead);
const void* mappedData = MapReadAsyncAndWait(buffer, 2048, 4);
ASSERT_EQ(myData, *reinterpret_cast<const uint32_t*>(mappedData));
ASSERT_EQ(myData, *reinterpret_cast<const uint8_t*>(mappedData));
buffer.Unmap();
}
// Test mapping a buffer at an offset that's not uint32-aligned.
TEST_P(BufferMapReadTests, SmallReadAtUnalignedOffset) {
nxt::Buffer buffer = device.CreateBufferBuilder()
.SetSize(4000)
.SetAllowedUsage(nxt::BufferUsageBit::MapRead | nxt::BufferUsageBit::TransferDst)
.SetInitialUsage(nxt::BufferUsageBit::TransferDst)
.GetResult();
uint8_t myData = 213;
buffer.SetSubData(3, 1, &myData);
buffer.TransitionUsage(nxt::BufferUsageBit::MapRead);
const void* mappedData = MapReadAsyncAndWait(buffer, 3, 1);
ASSERT_EQ(myData, *reinterpret_cast<const uint8_t*>(mappedData));
buffer.Unmap();
}
@@ -91,7 +109,7 @@ TEST_P(BufferMapReadTests, LargeRead) {
.SetInitialUsage(nxt::BufferUsageBit::TransferDst)
.GetResult();
buffer.SetSubData(0, static_cast<uint32_t>(kDataSize), myData.data());
buffer.SetSubData(0, kDataSize * sizeof(uint32_t), reinterpret_cast<uint8_t*>(myData.data()));
buffer.TransitionUsage(nxt::BufferUsageBit::MapRead);
const void* mappedData = MapReadAsyncAndWait(buffer, 0, static_cast<uint32_t>(kDataSize * sizeof(uint32_t)));
@@ -185,18 +203,18 @@ NXT_INSTANTIATE_TEST(BufferMapWriteTests, D3D12Backend, MetalBackend, OpenGLBack
class BufferSetSubDataTests : public NXTTest {
};
// Test the simplest set sub data: setting one u32 at offset 0.
// Test the simplest set sub data: setting one u8 at offset 0.
TEST_P(BufferSetSubDataTests, SmallDataAtZero) {
nxt::Buffer buffer = device.CreateBufferBuilder()
.SetSize(4)
.SetSize(1)
.SetAllowedUsage(nxt::BufferUsageBit::TransferSrc | nxt::BufferUsageBit::TransferDst)
.SetInitialUsage(nxt::BufferUsageBit::TransferDst)
.GetResult();
uint32_t value = 298371;
buffer.SetSubData(0, 1, &value);
uint8_t value = 171;
buffer.SetSubData(0, sizeof(value), &value);
EXPECT_BUFFER_U32_EQ(value, buffer, 0);
EXPECT_BUFFER_U8_EQ(value, buffer, 0);
}
// Test that SetSubData offset works.
@@ -208,10 +226,10 @@ TEST_P(BufferSetSubDataTests, SmallDataAtOffset) {
.GetResult();
constexpr uint32_t kOffset = 2000;
uint32_t value = 298371;
buffer.SetSubData(kOffset / 4, 1, &value);
uint8_t value = 231;
buffer.SetSubData(kOffset, sizeof(value), &value);
EXPECT_BUFFER_U32_EQ(value, buffer, kOffset);
EXPECT_BUFFER_U8_EQ(value, buffer, kOffset);
}
// Stress test for many calls to SetSubData
@@ -233,7 +251,7 @@ TEST_P(BufferSetSubDataTests, ManySetSubData) {
std::vector<uint32_t> expectedData;
for (uint32_t i = 0; i < kElements; ++i) {
buffer.SetSubData(i, 1, &i);
buffer.SetSubData(i * sizeof(uint32_t), sizeof(i), reinterpret_cast<uint8_t*>(&i));
expectedData.push_back(i);
}
@@ -255,7 +273,7 @@ TEST_P(BufferSetSubDataTests, LargeSetSubData) {
expectedData.push_back(i);
}
buffer.SetSubData(0, kElements, expectedData.data());
buffer.SetSubData(0, kElements * sizeof(uint32_t), reinterpret_cast<uint8_t*>(expectedData.data()));
EXPECT_BUFFER_U32_RANGE_EQ(expectedData.data(), buffer, 0, kElements);
}

View File

@@ -107,7 +107,7 @@ class CopyTests_T2B : public CopyTests {
.SetInitialUsage(nxt::BufferUsageBit::TransferDst)
.GetResult();
std::vector<RGBA8> emptyData(bufferSpec.size / kBytesPerTexel);
buffer.SetSubData(0, static_cast<uint32_t>(emptyData.size()), reinterpret_cast<const uint32_t*>(emptyData.data()));
buffer.SetSubData(0, static_cast<uint32_t>(emptyData.size() * sizeof(RGBA8)), reinterpret_cast<const uint8_t*>(emptyData.data()));
// Copy the region [(`x`, `y`), (`x + copyWidth, `y + copyWidth`)] from the `level` mip into the buffer at the specified `offset` and `rowPitch`
commands[1] = device.CreateCommandBufferBuilder()
@@ -158,7 +158,7 @@ protected:
.GetResult();
std::vector<RGBA8> bufferData(bufferSpec.size / kBytesPerTexel);
FillBufferData(bufferData.data(), bufferData.size());
buffer.SetSubData(0, static_cast<uint32_t>(bufferData.size()), reinterpret_cast<const uint32_t*>(bufferData.data()));
buffer.SetSubData(0, static_cast<uint32_t>(bufferData.size() * sizeof(RGBA8)), reinterpret_cast<const uint8_t*>(bufferData.data()));
// Create a texture that is `width` x `height` with (`level` + 1) mip levels.
nxt::Texture texture = device.CreateTextureBuilder()

View File

@@ -36,7 +36,7 @@ class PushConstantTest: public NXTTest {
.SetInitialUsage(nxt::BufferUsageBit::TransferDst)
.GetResult();
uint32_t one = 1;
buf1.SetSubData(0, 1, &one);
buf1.SetSubData(0, sizeof(one), reinterpret_cast<uint8_t*>(&one));
nxt::Buffer buf2 = device.CreateBufferBuilder()
.SetSize(4)

View File

@@ -487,28 +487,28 @@ TEST_F(BufferValidationTest, DestroyInsideMapWriteCallback) {
// Test the success case for Buffer::SetSubData
TEST_F(BufferValidationTest, SetSubDataSuccess) {
nxt::Buffer buf = CreateSetSubDataBuffer(4);
nxt::Buffer buf = CreateSetSubDataBuffer(1);
uint32_t foo = 0;
buf.SetSubData(0, 1, &foo);
uint8_t foo = 0;
buf.SetSubData(0, sizeof(foo), &foo);
}
// Test error case for SetSubData out of bounds
TEST_F(BufferValidationTest, SetSubDataOutOfBounds) {
nxt::Buffer buf = CreateSetSubDataBuffer(4);
nxt::Buffer buf = CreateSetSubDataBuffer(1);
uint32_t foo = 0;
uint8_t foo = 0;
ASSERT_DEVICE_ERROR(buf.SetSubData(0, 2, &foo));
}
// Test error case for SetSubData with the wrong usage
TEST_F(BufferValidationTest, SetSubDataWrongUsage) {
nxt::Buffer buf = device.CreateBufferBuilder()
.SetSize(4)
.SetSize(1)
.SetAllowedUsage(nxt::BufferUsageBit::TransferDst | nxt::BufferUsageBit::Vertex)
.SetInitialUsage(nxt::BufferUsageBit::Vertex)
.GetResult();
uint32_t foo = 0;
ASSERT_DEVICE_ERROR(buf.SetSubData(0, 1, &foo));
uint8_t foo = 0;
ASSERT_DEVICE_ERROR(buf.SetSubData(0, sizeof(foo), &foo));
}

View File

@@ -35,16 +35,16 @@ TEST_F(UsageValidationTest, UsageAfterCommandBuffer) {
// Should we make an end2end test that tests this as well?
nxt::Buffer buf = device.CreateBufferBuilder()
.SetSize(4)
.SetSize(1)
.SetAllowedUsage(nxt::BufferUsageBit::TransferDst | nxt::BufferUsageBit::Vertex)
.SetInitialUsage(nxt::BufferUsageBit::TransferDst)
.GetResult();
uint32_t foo = 0;
buf.SetSubData(0, 1, &foo);
uint8_t foo = 0;
buf.SetSubData(0, sizeof(foo), &foo);
buf.TransitionUsage(nxt::BufferUsageBit::Vertex);
ASSERT_DEVICE_ERROR(buf.SetSubData(0, 1, &foo));
ASSERT_DEVICE_ERROR(buf.SetSubData(0, sizeof(foo), &foo));
nxt::CommandBuffer cmdbuf = device.CreateCommandBufferBuilder()
.TransitionBufferUsage(buf, nxt::BufferUsageBit::TransferDst)
@@ -52,5 +52,5 @@ TEST_F(UsageValidationTest, UsageAfterCommandBuffer) {
queue.Submit(1, &cmdbuf);
// buf should be in TransferDst usage
buf.SetSubData(0, 1, &foo);
buf.SetSubData(0, sizeof(foo), &foo);
}