Implement CreateBufferMapped in dawn_native for MAP_WRITE buffers only.
This is the first command to return a struct. This patch also
updates the code generator to support structure return values.
Bug: dawn:7
Change-Id: Ie8acec895c0ec88429672138ffc900032fbbc447
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/4780
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
diff --git a/dawn.json b/dawn.json
index 6044c96..b7a18ce 100644
--- a/dawn.json
+++ b/dawn.json
@@ -213,6 +213,14 @@
"char": {
"category": "native"
},
+ "create buffer mapped result": {
+ "category": "structure",
+ "members": [
+ {"name": "buffer", "type": "buffer"},
+ {"name": "data length", "type": "uint64_t"},
+ {"name": "data", "type": "uint8_t", "annotation": "*", "length": "data length"}
+ ]
+ },
"color": {
"category": "structure",
"members": [
@@ -411,6 +419,13 @@
]
},
{
+ "name": "create buffer mapped",
+ "returns": "create buffer mapped result",
+ "args": [
+ {"name": "descriptor", "type": "buffer descriptor", "annotation": "const*"}
+ ]
+ },
+ {
"name": "create command encoder",
"returns": "command encoder"
},
diff --git a/dawn_wire.json b/dawn_wire.json
index f2c1dce..02338b4 100644
--- a/dawn_wire.json
+++ b/dawn_wire.json
@@ -58,6 +58,7 @@
],
"client_handwritten_commands": [
"BufferUnmap",
+ "DeviceCreateBufferMapped",
"QueueCreateFence",
"FenceGetCompletedValue",
"QueueSignal"
diff --git a/generator/main.py b/generator/main.py
index 8518e5d..2d63c08 100644
--- a/generator/main.py
+++ b/generator/main.py
@@ -230,9 +230,34 @@
else:
return name.CamelCase()
+def convert_cType_to_cppType(typ, annotation, arg, indent=0):
+ if typ.category == 'native':
+ return arg
+ if annotation == 'value':
+ if typ.category == 'object':
+ return '{}::Acquire({})'.format(as_cppType(typ.name), arg)
+ elif typ.category == 'structure':
+ converted_members = [
+ convert_cType_to_cppType(
+ member.type, member.annotation,
+ '{}.{}'.format(arg, as_varName(member.name)),
+ indent + 1)
+ for member in typ.members]
+
+ converted_members = [(' ' * 4) + m for m in converted_members ]
+ converted_members = ',\n'.join(converted_members)
+
+ return as_cppType(typ.name) + ' {\n' + converted_members + '\n}'
+ else:
+ return 'static_cast<{}>({})'.format(as_cppType(typ.name), arg)
+ else:
+ return 'reinterpret_cast<{} {}>({})'.format(as_cppType(typ.name), annotation, arg)
+
def decorate(name, typ, arg):
if arg.annotation == 'value':
return typ + ' ' + name
+ elif arg.annotation == '*':
+ return typ + ' * ' + name
elif arg.annotation == 'const*':
return typ + ' const * ' + name
elif arg.annotation == 'const*const*':
@@ -314,6 +339,7 @@
'as_cProc': as_cProc,
'as_cType': as_cType,
'as_cppType': as_cppType,
+ 'convert_cType_to_cppType': convert_cType_to_cppType,
'as_varName': as_varName,
'decorate': decorate,
}
diff --git a/generator/templates/apicpp.cpp b/generator/templates/apicpp.cpp
index b353a8b..5b61b2f 100644
--- a/generator/templates/apicpp.cpp
+++ b/generator/templates/apicpp.cpp
@@ -96,13 +96,7 @@
{{render_cpp_to_c_method_call(type, method)}};
{% else %}
auto result = {{render_cpp_to_c_method_call(type, method)}};
- {% if method.return_type.category == "native" %}
- return result;
- {% elif method.return_type.category == "object" %}
- return {{as_cppType(method.return_type.name)}}::Acquire(result);
- {% else %}
- return static_cast<{{as_cppType(method.return_type.name)}}>(result);
- {% endif%}
+ return {{convert_cType_to_cppType(method.return_type, 'value', 'result') | indent(8)}};
{% endif %}
}
{% endfor %}
diff --git a/generator/templates/dawn_wire/WireCmd.cpp b/generator/templates/dawn_wire/WireCmd.cpp
index b1c952f..ca7a35f 100644
--- a/generator/templates/dawn_wire/WireCmd.cpp
+++ b/generator/templates/dawn_wire/WireCmd.cpp
@@ -152,7 +152,7 @@
//* Serializes `record` into `transfer`, using `buffer` to get more space for pointed-to data
//* and `provider` to serialize objects.
- void {{Return}}{{name}}Serialize(const {{Return}}{{name}}{{Cmd}}& record, {{Return}}{{name}}Transfer* transfer,
+ DAWN_DECLARE_UNUSED void {{Return}}{{name}}Serialize(const {{Return}}{{name}}{{Cmd}}& record, {{Return}}{{name}}Transfer* transfer,
char** buffer
{%- if record.has_dawn_object -%}
, const ObjectIdProvider& provider
@@ -200,11 +200,12 @@
}
{% endfor %}
}
+ DAWN_UNUSED_FUNC({{Return}}{{name}}Serialize);
//* Deserializes `transfer` into `record` getting more serialized data from `buffer` and `size`
//* if needed, using `allocator` to store pointed-to values and `resolver` to translate object
//* Ids to actual objects.
- DeserializeResult {{Return}}{{name}}Deserialize({{Return}}{{name}}{{Cmd}}* record, const {{Return}}{{name}}Transfer* transfer,
+ DAWN_DECLARE_UNUSED DeserializeResult {{Return}}{{name}}Deserialize({{Return}}{{name}}{{Cmd}}* record, const {{Return}}{{name}}Transfer* transfer,
const char** buffer, size_t* size, DeserializeAllocator* allocator
{%- if record.has_dawn_object -%}
, const ObjectIdResolver& resolver
@@ -283,6 +284,7 @@
return DeserializeResult::Success;
}
+ DAWN_UNUSED_FUNC({{Return}}{{name}}Deserialize);
{% endmacro %}
{% macro write_command_serialization_methods(command, is_return) %}
diff --git a/src/dawn_native/Buffer.cpp b/src/dawn_native/Buffer.cpp
index 74ac084..08cb8719 100644
--- a/src/dawn_native/Buffer.cpp
+++ b/src/dawn_native/Buffer.cpp
@@ -31,7 +31,24 @@
ErrorBuffer(DeviceBase* device) : BufferBase(device, ObjectBase::kError) {
}
+ static ErrorBuffer* MakeMapped(DeviceBase* device,
+ uint64_t size,
+ uint8_t** mappedPointer) {
+ ASSERT(mappedPointer != nullptr);
+
+ ErrorBuffer* buffer = new ErrorBuffer(device);
+ buffer->mFakeMappedData = std::unique_ptr<uint8_t[]>(new uint8_t[size]);
+ *mappedPointer = buffer->mFakeMappedData.get();
+
+ return buffer;
+ }
+
private:
+ MaybeError MapAtCreationImpl(uint8_t** mappedPointer) override {
+ UNREACHABLE();
+ return {};
+ }
+
MaybeError SetSubDataImpl(uint32_t start,
uint32_t count,
const uint8_t* data) override {
@@ -45,11 +62,14 @@
UNREACHABLE();
}
void UnmapImpl() override {
- UNREACHABLE();
+ ASSERT(mFakeMappedData);
+ mFakeMappedData.reset();
}
void DestroyImpl() override {
UNREACHABLE();
}
+
+ std::unique_ptr<uint8_t[]> mFakeMappedData;
};
} // anonymous namespace
@@ -104,6 +124,13 @@
return new ErrorBuffer(device);
}
+ // static
+ BufferBase* BufferBase::MakeErrorMapped(DeviceBase* device,
+ uint64_t size,
+ uint8_t** mappedPointer) {
+ return ErrorBuffer::MakeMapped(device, size, mappedPointer);
+ }
+
uint32_t BufferBase::GetSize() const {
ASSERT(!IsError());
return mSize;
@@ -114,6 +141,22 @@
return mUsage;
}
+ MaybeError BufferBase::MapAtCreation(uint8_t** mappedPointer) {
+ ASSERT(!IsError());
+ ASSERT(mappedPointer != nullptr);
+
+ mState = BufferState::Mapped;
+ if ((mUsage & dawn::BufferUsageBit::MapWrite) == 0) {
+ // TODO(enga): Support non-mappable buffers with a staging buffer.
+ return DAWN_VALIDATION_ERROR("MapWrite usage required");
+ }
+
+ DAWN_TRY(MapAtCreationImpl(mappedPointer));
+ ASSERT(*mappedPointer != nullptr);
+
+ return {};
+ }
+
MaybeError BufferBase::ValidateCanUseInSubmitNow() const {
ASSERT(!IsError());
@@ -239,6 +282,11 @@
}
void BufferBase::Unmap() {
+ if (IsError()) {
+ // It is an error to call Unmap() on an ErrorBuffer, but we still need to reclaim the
+ // fake mapped staging data.
+ UnmapImpl();
+ }
if (GetDevice()->ConsumedError(ValidateUnmap())) {
return;
}
diff --git a/src/dawn_native/Buffer.h b/src/dawn_native/Buffer.h
index 46fe1fa..70ae0e5 100644
--- a/src/dawn_native/Buffer.h
+++ b/src/dawn_native/Buffer.h
@@ -45,10 +45,15 @@
~BufferBase();
static BufferBase* MakeError(DeviceBase* device);
+ static BufferBase* MakeErrorMapped(DeviceBase* device,
+ uint64_t size,
+ uint8_t** mappedPointer);
uint32_t GetSize() const;
dawn::BufferUsageBit GetUsage() const;
+ MaybeError MapAtCreation(uint8_t** mappedPointer);
+
MaybeError ValidateCanUseInSubmitNow() const;
// Dawn API
@@ -73,6 +78,7 @@
void DestroyInternal();
private:
+ virtual MaybeError MapAtCreationImpl(uint8_t** mappedPointer) = 0;
virtual MaybeError SetSubDataImpl(uint32_t start, uint32_t count, const uint8_t* data);
virtual void MapReadAsyncImpl(uint32_t serial) = 0;
virtual void MapWriteAsyncImpl(uint32_t serial) = 0;
diff --git a/src/dawn_native/Device.cpp b/src/dawn_native/Device.cpp
index 753f709..7d7c222 100644
--- a/src/dawn_native/Device.cpp
+++ b/src/dawn_native/Device.cpp
@@ -237,6 +237,30 @@
return result;
}
+ DawnCreateBufferMappedResult DeviceBase::CreateBufferMapped(
+ const BufferDescriptor* descriptor) {
+ BufferBase* buffer = nullptr;
+ uint8_t* data = nullptr;
+
+ if (ConsumedError(CreateBufferInternal(&buffer, descriptor)) ||
+ ConsumedError(buffer->MapAtCreation(&data))) {
+ // Map failed. Replace the buffer with an error buffer.
+ if (buffer != nullptr) {
+ delete buffer;
+ }
+ buffer = BufferBase::MakeErrorMapped(this, descriptor->size, &data);
+ }
+
+ ASSERT(buffer != nullptr);
+ ASSERT(data != nullptr);
+
+ DawnCreateBufferMappedResult result = {};
+ result.buffer = reinterpret_cast<DawnBuffer>(buffer);
+ result.data = data;
+ result.dataLength = descriptor->size;
+
+ return result;
+ }
CommandEncoderBase* DeviceBase::CreateCommandEncoder() {
return new CommandEncoderBase(this);
}
diff --git a/src/dawn_native/Device.h b/src/dawn_native/Device.h
index b9039e4..998e035 100644
--- a/src/dawn_native/Device.h
+++ b/src/dawn_native/Device.h
@@ -104,6 +104,7 @@
BindGroupBase* CreateBindGroup(const BindGroupDescriptor* descriptor);
BindGroupLayoutBase* CreateBindGroupLayout(const BindGroupLayoutDescriptor* descriptor);
BufferBase* CreateBuffer(const BufferDescriptor* descriptor);
+ DawnCreateBufferMappedResult CreateBufferMapped(const BufferDescriptor* descriptor);
CommandEncoderBase* CreateCommandEncoder();
ComputePipelineBase* CreateComputePipeline(const ComputePipelineDescriptor* descriptor);
PipelineLayoutBase* CreatePipelineLayout(const PipelineLayoutDescriptor* descriptor);
diff --git a/src/dawn_native/d3d12/BufferD3D12.cpp b/src/dawn_native/d3d12/BufferD3D12.cpp
index b0b5a1e..3a5ed9b 100644
--- a/src/dawn_native/d3d12/BufferD3D12.cpp
+++ b/src/dawn_native/d3d12/BufferD3D12.cpp
@@ -160,6 +160,13 @@
}
}
+ MaybeError Buffer::MapAtCreationImpl(uint8_t** mappedPointer) {
+ mWrittenMappedRange = {0, GetSize()};
+ ASSERT_SUCCESS(
+ mResource->Map(0, &mWrittenMappedRange, reinterpret_cast<void**>(mappedPointer)));
+ return {};
+ }
+
void Buffer::MapReadAsyncImpl(uint32_t serial) {
mWrittenMappedRange = {};
D3D12_RANGE readRange = {0, GetSize()};
diff --git a/src/dawn_native/d3d12/BufferD3D12.h b/src/dawn_native/d3d12/BufferD3D12.h
index 9667085..9208f53 100644
--- a/src/dawn_native/d3d12/BufferD3D12.h
+++ b/src/dawn_native/d3d12/BufferD3D12.h
@@ -44,6 +44,8 @@
void UnmapImpl() override;
void DestroyImpl() override;
+ virtual MaybeError MapAtCreationImpl(uint8_t** mappedPointer) override;
+
ComPtr<ID3D12Resource> mResource;
bool mFixedResourceState = false;
dawn::BufferUsageBit mLastUsage = dawn::BufferUsageBit::None;
diff --git a/src/dawn_native/metal/BufferMTL.h b/src/dawn_native/metal/BufferMTL.h
index 4cdbb5a..7fb8c35 100644
--- a/src/dawn_native/metal/BufferMTL.h
+++ b/src/dawn_native/metal/BufferMTL.h
@@ -34,11 +34,14 @@
void OnMapCommandSerialFinished(uint32_t mapSerial, bool isWrite);
private:
+ // Dawn API
void MapReadAsyncImpl(uint32_t serial) override;
void MapWriteAsyncImpl(uint32_t serial) override;
void UnmapImpl() override;
void DestroyImpl() override;
+ MaybeError MapAtCreationImpl(uint8_t** mappedPointer) override;
+
id<MTLBuffer> mMtlBuffer = nil;
};
diff --git a/src/dawn_native/metal/BufferMTL.mm b/src/dawn_native/metal/BufferMTL.mm
index 1d0828a..7cc999a 100644
--- a/src/dawn_native/metal/BufferMTL.mm
+++ b/src/dawn_native/metal/BufferMTL.mm
@@ -47,6 +47,11 @@
}
}
+ MaybeError Buffer::MapAtCreationImpl(uint8_t** mappedPointer) {
+ *mappedPointer = reinterpret_cast<uint8_t*>([mMtlBuffer contents]);
+ return {};
+ }
+
void Buffer::MapReadAsyncImpl(uint32_t serial) {
MapRequestTracker* tracker = ToBackend(GetDevice())->GetMapTracker();
tracker->Track(this, serial, false);
diff --git a/src/dawn_native/null/DeviceNull.cpp b/src/dawn_native/null/DeviceNull.cpp
index 15db5c2..eeaae7e 100644
--- a/src/dawn_native/null/DeviceNull.cpp
+++ b/src/dawn_native/null/DeviceNull.cpp
@@ -184,13 +184,18 @@
: BufferBase(device, descriptor) {
if (GetUsage() & (dawn::BufferUsageBit::TransferDst | dawn::BufferUsageBit::MapRead |
dawn::BufferUsageBit::MapWrite)) {
- mBackingData = std::unique_ptr<char[]>(new char[GetSize()]);
+ mBackingData = std::unique_ptr<uint8_t[]>(new uint8_t[GetSize()]);
}
}
Buffer::~Buffer() {
}
+ MaybeError Buffer::MapAtCreationImpl(uint8_t** mappedPointer) {
+ *mappedPointer = mBackingData.get();
+ return {};
+ }
+
void Buffer::MapReadOperationCompleted(uint32_t serial, void* ptr, bool isWrite) {
if (isWrite) {
CallMapWriteCallback(serial, DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, ptr, GetSize());
diff --git a/src/dawn_native/null/DeviceNull.h b/src/dawn_native/null/DeviceNull.h
index a523f3d..0c770fc 100644
--- a/src/dawn_native/null/DeviceNull.h
+++ b/src/dawn_native/null/DeviceNull.h
@@ -138,15 +138,17 @@
void MapReadOperationCompleted(uint32_t serial, void* ptr, bool isWrite);
private:
+ // Dawn API
MaybeError SetSubDataImpl(uint32_t start, uint32_t count, const uint8_t* data) override;
void MapReadAsyncImpl(uint32_t serial) override;
void MapWriteAsyncImpl(uint32_t serial) override;
void UnmapImpl() override;
void DestroyImpl() override;
+ MaybeError MapAtCreationImpl(uint8_t** mappedPointer) override;
void MapAsyncImplCommon(uint32_t serial, bool isWrite);
- std::unique_ptr<char[]> mBackingData;
+ std::unique_ptr<uint8_t[]> mBackingData;
};
class CommandBuffer : public CommandBufferBase {
diff --git a/src/dawn_native/opengl/BufferGL.cpp b/src/dawn_native/opengl/BufferGL.cpp
index 225a583..92fa601 100644
--- a/src/dawn_native/opengl/BufferGL.cpp
+++ b/src/dawn_native/opengl/BufferGL.cpp
@@ -35,6 +35,13 @@
return mBuffer;
}
+ MaybeError Buffer::MapAtCreationImpl(uint8_t** mappedPointer) {
+ glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
+ void* data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+ *mappedPointer = reinterpret_cast<uint8_t*>(data);
+ return {};
+ }
+
MaybeError Buffer::SetSubDataImpl(uint32_t start, uint32_t count, const uint8_t* data) {
glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
glBufferSubData(GL_ARRAY_BUFFER, start, count, data);
diff --git a/src/dawn_native/opengl/BufferGL.h b/src/dawn_native/opengl/BufferGL.h
index 5a2b4a5..1ad582f 100644
--- a/src/dawn_native/opengl/BufferGL.h
+++ b/src/dawn_native/opengl/BufferGL.h
@@ -31,12 +31,15 @@
GLuint GetHandle() const;
private:
+ // Dawn API
MaybeError SetSubDataImpl(uint32_t start, uint32_t count, const uint8_t* data) override;
void MapReadAsyncImpl(uint32_t serial) override;
void MapWriteAsyncImpl(uint32_t serial) override;
void UnmapImpl() override;
void DestroyImpl() override;
+ MaybeError MapAtCreationImpl(uint8_t** mappedPointer) override;
+
GLuint mBuffer = 0;
};
diff --git a/src/dawn_native/vulkan/BufferVk.cpp b/src/dawn_native/vulkan/BufferVk.cpp
index 137f1ad..01e08bd 100644
--- a/src/dawn_native/vulkan/BufferVk.cpp
+++ b/src/dawn_native/vulkan/BufferVk.cpp
@@ -188,6 +188,11 @@
mLastUsage = usage;
}
+ MaybeError Buffer::MapAtCreationImpl(uint8_t** mappedPointer) {
+ *mappedPointer = mMemoryAllocation.GetMappedPointer();
+ return {};
+ }
+
void Buffer::MapReadAsyncImpl(uint32_t serial) {
Device* device = ToBackend(GetDevice());
diff --git a/src/dawn_native/vulkan/BufferVk.h b/src/dawn_native/vulkan/BufferVk.h
index 348f9be..5cfb7c5 100644
--- a/src/dawn_native/vulkan/BufferVk.h
+++ b/src/dawn_native/vulkan/BufferVk.h
@@ -41,11 +41,14 @@
void TransitionUsageNow(VkCommandBuffer commands, dawn::BufferUsageBit usage);
private:
+ // Dawn API
void MapReadAsyncImpl(uint32_t serial) override;
void MapWriteAsyncImpl(uint32_t serial) override;
void UnmapImpl() override;
void DestroyImpl() override;
+ MaybeError MapAtCreationImpl(uint8_t** mappedPointer) override;
+
VkBuffer mHandle = VK_NULL_HANDLE;
DeviceMemoryAllocation mMemoryAllocation;
diff --git a/src/dawn_wire/client/ApiProcs.cpp b/src/dawn_wire/client/ApiProcs.cpp
index 4289c17..04c46ff 100644
--- a/src/dawn_wire/client/ApiProcs.cpp
+++ b/src/dawn_wire/client/ApiProcs.cpp
@@ -68,6 +68,14 @@
cmd.Serialize(allocatedBuffer);
}
+ DawnCreateBufferMappedResult ClientDeviceCreateBufferMapped(
+ DawnDevice cDevice,
+ const DawnBufferDescriptor* descriptor) {
+ // TODO(enga): Not implemented
+ UNREACHABLE();
+ return {};
+ }
+
uint64_t ClientFenceGetCompletedValue(DawnFence cSelf) {
auto fence = reinterpret_cast<Fence*>(cSelf);
return fence->completedValue;
diff --git a/src/tests/end2end/BufferTests.cpp b/src/tests/end2end/BufferTests.cpp
index eac536c..5872f41 100644
--- a/src/tests/end2end/BufferTests.cpp
+++ b/src/tests/end2end/BufferTests.cpp
@@ -229,3 +229,48 @@
MetalBackend,
OpenGLBackend,
VulkanBackend);
+
+class CreateBufferMappedTests : public DawnTest {};
+
+// Test that the simplest CreateBufferMapped works.
+TEST_P(CreateBufferMappedTests, SmallSyncWrite) {
+ dawn::BufferDescriptor descriptor;
+ descriptor.nextInChain = nullptr;
+ descriptor.size = 4;
+ descriptor.usage = dawn::BufferUsageBit::MapWrite | dawn::BufferUsageBit::TransferSrc;
+
+ 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();
+
+ EXPECT_BUFFER_U32_EQ(myData, result.buffer, 0);
+}
+
+// Test CreateBufferMapped for a large buffer
+TEST_P(CreateBufferMappedTests, LargeSyncWrite) {
+ 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::MapWrite | 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);
+}
+
+DAWN_INSTANTIATE_TEST(CreateBufferMappedTests,
+ D3D12Backend,
+ MetalBackend,
+ OpenGLBackend,
+ VulkanBackend);
diff --git a/src/tests/unittests/validation/BufferValidationTests.cpp b/src/tests/unittests/validation/BufferValidationTests.cpp
index 3d25d67..69efe5d 100644
--- a/src/tests/unittests/validation/BufferValidationTests.cpp
+++ b/src/tests/unittests/validation/BufferValidationTests.cpp
@@ -82,6 +82,15 @@
return device.CreateBuffer(&descriptor);
}
+ dawn::CreateBufferMappedResult CreateBufferMapped(uint64_t size,
+ dawn::BufferUsageBit usage) {
+ dawn::BufferDescriptor descriptor;
+ descriptor.size = size;
+ descriptor.usage = usage;
+
+ return device.CreateBufferMapped(&descriptor);
+ }
+
dawn::Queue queue;
private:
@@ -183,6 +192,14 @@
buf.Unmap();
}
+// Test the success case for CreateBufferMapped
+TEST_F(BufferValidationTest, CreateBufferMappedSuccess) {
+ dawn::CreateBufferMappedResult result = CreateBufferMapped(4, dawn::BufferUsageBit::MapWrite);
+ 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;