mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-17 17:05:31 +00:00
Implement CreateBufferMapped for non-mappable buffers
This uses an intermediate staging buffer to copy data into the buffer. Bug: dawn:7 Change-Id: I3bda19a8450ef0eddc5b4382ce1b9120f074b917 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/7500 Commit-Queue: Austin Eng <enga@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
committed by
Commit Bot service account
parent
233ce73c50
commit
9cd21f1bf9
@@ -226,10 +226,34 @@ DAWN_INSTANTIATE_TEST(BufferSetSubDataTests,
|
||||
OpenGLBackend,
|
||||
VulkanBackend);
|
||||
|
||||
class CreateBufferMappedTests : public DawnTest {};
|
||||
class CreateBufferMappedTests : public DawnTest {
|
||||
protected:
|
||||
static void MapReadCallback(DawnBufferMapAsyncStatus status,
|
||||
const void* data,
|
||||
uint64_t,
|
||||
void* userdata) {
|
||||
ASSERT_EQ(DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, status);
|
||||
ASSERT_NE(nullptr, data);
|
||||
|
||||
// Test that the simplest CreateBufferMapped works.
|
||||
TEST_P(CreateBufferMappedTests, SmallSyncWrite) {
|
||||
static_cast<CreateBufferMappedTests*>(userdata)->mappedData = data;
|
||||
}
|
||||
|
||||
const void* MapReadAsyncAndWait(const dawn::Buffer& buffer) {
|
||||
buffer.MapReadAsync(MapReadCallback, this);
|
||||
|
||||
while (mappedData == nullptr) {
|
||||
WaitABit();
|
||||
}
|
||||
|
||||
return mappedData;
|
||||
}
|
||||
|
||||
private:
|
||||
const void* mappedData = nullptr;
|
||||
};
|
||||
|
||||
// Test that the simplest CreateBufferMapped works for MapWrite buffers.
|
||||
TEST_P(CreateBufferMappedTests, MapWriteUsageSmall) {
|
||||
dawn::BufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
descriptor.size = 4;
|
||||
@@ -244,8 +268,42 @@ TEST_P(CreateBufferMappedTests, SmallSyncWrite) {
|
||||
EXPECT_BUFFER_U32_EQ(myData, result.buffer, 0);
|
||||
}
|
||||
|
||||
// Test CreateBufferMapped for a large buffer
|
||||
TEST_P(CreateBufferMappedTests, LargeSyncWrite) {
|
||||
// Test that the simplest CreateBufferMapped works for MapRead buffers.
|
||||
TEST_P(CreateBufferMappedTests, MapReadUsageSmall) {
|
||||
dawn::BufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
descriptor.size = 4;
|
||||
descriptor.usage = dawn::BufferUsageBit::MapRead;
|
||||
|
||||
uint32_t myData = 230502;
|
||||
dawn::CreateBufferMappedResult result = device.CreateBufferMapped(&descriptor);
|
||||
ASSERT_EQ(result.dataLength, descriptor.size);
|
||||
memcpy(result.data, &myData, sizeof(myData));
|
||||
result.buffer.Unmap();
|
||||
|
||||
const void* mappedData = MapReadAsyncAndWait(result.buffer);
|
||||
ASSERT_EQ(myData, *reinterpret_cast<const uint32_t*>(mappedData));
|
||||
result.buffer.Unmap();
|
||||
}
|
||||
|
||||
// Test that the simplest CreateBufferMapped works for non-mappable buffers.
|
||||
TEST_P(CreateBufferMappedTests, NonMappableUsageSmall) {
|
||||
dawn::BufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
descriptor.size = 4;
|
||||
descriptor.usage = dawn::BufferUsageBit::TransferSrc;
|
||||
|
||||
uint32_t myData = 4239;
|
||||
dawn::CreateBufferMappedResult result = device.CreateBufferMapped(&descriptor);
|
||||
ASSERT_EQ(result.dataLength, descriptor.size);
|
||||
memcpy(result.data, &myData, sizeof(myData));
|
||||
result.buffer.Unmap();
|
||||
|
||||
EXPECT_BUFFER_U32_EQ(myData, result.buffer, 0);
|
||||
}
|
||||
|
||||
// Test CreateBufferMapped for a large MapWrite buffer
|
||||
TEST_P(CreateBufferMappedTests, MapWriteUsageLarge) {
|
||||
constexpr uint64_t kDataSize = 1000 * 1000;
|
||||
std::vector<uint32_t> myData;
|
||||
for (uint32_t i = 0; i < kDataSize; ++i) {
|
||||
@@ -265,9 +323,53 @@ TEST_P(CreateBufferMappedTests, LargeSyncWrite) {
|
||||
EXPECT_BUFFER_U32_RANGE_EQ(myData.data(), result.buffer, 0, kDataSize);
|
||||
}
|
||||
|
||||
// Test CreateBufferMapped for a large MapRead buffer
|
||||
TEST_P(CreateBufferMappedTests, MapReadUsageLarge) {
|
||||
constexpr uint64_t kDataSize = 1000 * 1000;
|
||||
std::vector<uint32_t> myData;
|
||||
for (uint32_t i = 0; i < kDataSize; ++i) {
|
||||
myData.push_back(i);
|
||||
}
|
||||
|
||||
dawn::BufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
descriptor.size = static_cast<uint64_t>(kDataSize * sizeof(uint32_t));
|
||||
descriptor.usage = dawn::BufferUsageBit::MapRead;
|
||||
|
||||
dawn::CreateBufferMappedResult result = device.CreateBufferMapped(&descriptor);
|
||||
ASSERT_EQ(result.dataLength, descriptor.size);
|
||||
memcpy(result.data, myData.data(), kDataSize * sizeof(uint32_t));
|
||||
result.buffer.Unmap();
|
||||
|
||||
const void* mappedData = MapReadAsyncAndWait(result.buffer);
|
||||
ASSERT_EQ(0, memcmp(mappedData, myData.data(), kDataSize * sizeof(uint32_t)));
|
||||
result.buffer.Unmap();
|
||||
}
|
||||
|
||||
// Test CreateBufferMapped for a large non-mappable buffer
|
||||
TEST_P(CreateBufferMappedTests, NonMappableUsageLarge) {
|
||||
constexpr uint64_t kDataSize = 1000 * 1000;
|
||||
std::vector<uint32_t> myData;
|
||||
for (uint32_t i = 0; i < kDataSize; ++i) {
|
||||
myData.push_back(i);
|
||||
}
|
||||
|
||||
dawn::BufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
descriptor.size = static_cast<uint64_t>(kDataSize * sizeof(uint32_t));
|
||||
descriptor.usage = dawn::BufferUsageBit::TransferSrc;
|
||||
|
||||
dawn::CreateBufferMappedResult result = device.CreateBufferMapped(&descriptor);
|
||||
ASSERT_EQ(result.dataLength, descriptor.size);
|
||||
memcpy(result.data, myData.data(), kDataSize * sizeof(uint32_t));
|
||||
result.buffer.Unmap();
|
||||
|
||||
EXPECT_BUFFER_U32_RANGE_EQ(myData.data(), result.buffer, 0, kDataSize);
|
||||
}
|
||||
|
||||
// Test that CreateBufferMapped returns zero-initialized data
|
||||
// TODO(enga): This should use the testing toggle to initialize resources to 1.
|
||||
TEST_P(CreateBufferMappedTests, ZeroInitialized) {
|
||||
TEST_P(CreateBufferMappedTests, MappableZeroInitialized) {
|
||||
dawn::BufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
descriptor.size = 4;
|
||||
@@ -279,6 +381,20 @@ TEST_P(CreateBufferMappedTests, ZeroInitialized) {
|
||||
result.buffer.Unmap();
|
||||
}
|
||||
|
||||
// Test that CreateBufferMapped returns zero-initialized data
|
||||
// TODO(enga): This should use the testing toggle to initialize resources to 1.
|
||||
TEST_P(CreateBufferMappedTests, NonMappableZeroInitialized) {
|
||||
dawn::BufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
descriptor.size = 4;
|
||||
descriptor.usage = dawn::BufferUsageBit::TransferSrc;
|
||||
|
||||
dawn::CreateBufferMappedResult result = device.CreateBufferMapped(&descriptor);
|
||||
ASSERT_EQ(result.dataLength, descriptor.size);
|
||||
ASSERT_EQ(*result.data, 0);
|
||||
result.buffer.Unmap();
|
||||
}
|
||||
|
||||
// Test that mapping a buffer is valid after CreateBufferMapped and Unmap
|
||||
TEST_P(CreateBufferMappedTests, CreateThenMapSuccess) {
|
||||
dawn::BufferDescriptor descriptor;
|
||||
|
||||
@@ -198,6 +198,15 @@ TEST_F(BufferValidationTest, CreateBufferMappedSuccess) {
|
||||
result.buffer.Unmap();
|
||||
}
|
||||
|
||||
// Test the success case for non-mappable CreateBufferMapped
|
||||
TEST_F(BufferValidationTest, NonMappableCreateBufferMappedSuccess) {
|
||||
dawn::CreateBufferMappedResult result =
|
||||
CreateBufferMapped(4, dawn::BufferUsageBit::TransferSrc);
|
||||
ASSERT_NE(result.data, nullptr);
|
||||
ASSERT_EQ(result.dataLength, 4u);
|
||||
result.buffer.Unmap();
|
||||
}
|
||||
|
||||
// Test map reading a buffer with wrong current usage
|
||||
TEST_F(BufferValidationTest, MapReadWrongUsage) {
|
||||
dawn::BufferDescriptor descriptor;
|
||||
@@ -586,7 +595,7 @@ TEST_F(BufferValidationTest, SetSubDataDestroyedBuffer) {
|
||||
}
|
||||
|
||||
// Test that is is invalid to Map a mapped buffer
|
||||
TEST_F(BufferValidationTest, MapMappedbuffer) {
|
||||
TEST_F(BufferValidationTest, MapMappedBuffer) {
|
||||
{
|
||||
dawn::Buffer buf = CreateMapReadBuffer(4);
|
||||
buf.MapReadAsync(ToMockBufferMapReadCallback, nullptr);
|
||||
@@ -601,6 +610,20 @@ TEST_F(BufferValidationTest, MapMappedbuffer) {
|
||||
}
|
||||
}
|
||||
|
||||
// Test that is is invalid to Map a CreateBufferMapped buffer
|
||||
TEST_F(BufferValidationTest, MapCreateBufferMappedBuffer) {
|
||||
{
|
||||
dawn::Buffer buf = CreateBufferMapped(4, dawn::BufferUsageBit::MapRead).buffer;
|
||||
ASSERT_DEVICE_ERROR(buf.MapReadAsync(ToMockBufferMapReadCallback, nullptr));
|
||||
queue.Submit(0, nullptr);
|
||||
}
|
||||
{
|
||||
dawn::Buffer buf = CreateBufferMapped(4, dawn::BufferUsageBit::MapWrite).buffer;
|
||||
ASSERT_DEVICE_ERROR(buf.MapWriteAsync(ToMockBufferMapWriteCallback, nullptr));
|
||||
queue.Submit(0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
// Test that it is invalid to call SetSubData on a mapped buffer
|
||||
TEST_F(BufferValidationTest, SetSubDataMappedBuffer) {
|
||||
{
|
||||
@@ -665,6 +688,26 @@ TEST_F(BufferValidationTest, SubmitMappedBuffer) {
|
||||
|
||||
bufB.MapReadAsync(ToMockBufferMapReadCallback, nullptr);
|
||||
|
||||
dawn::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
encoder.CopyBufferToBuffer(bufA, 0, bufB, 0, 4);
|
||||
dawn::CommandBuffer commands = encoder.Finish();
|
||||
ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
|
||||
queue.Submit(0, nullptr);
|
||||
}
|
||||
{
|
||||
dawn::Buffer bufA = device.CreateBufferMapped(&descriptorA).buffer;
|
||||
dawn::Buffer bufB = device.CreateBuffer(&descriptorB);
|
||||
|
||||
dawn::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
encoder.CopyBufferToBuffer(bufA, 0, bufB, 0, 4);
|
||||
dawn::CommandBuffer commands = encoder.Finish();
|
||||
ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
|
||||
queue.Submit(0, nullptr);
|
||||
}
|
||||
{
|
||||
dawn::Buffer bufA = device.CreateBuffer(&descriptorA);
|
||||
dawn::Buffer bufB = device.CreateBufferMapped(&descriptorB).buffer;
|
||||
|
||||
dawn::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
encoder.CopyBufferToBuffer(bufA, 0, bufB, 0, 4);
|
||||
dawn::CommandBuffer commands = encoder.Finish();
|
||||
|
||||
Reference in New Issue
Block a user