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>
This commit is contained in:
parent
0195dbf908
commit
740995c0b1
15
dawn.json
15
dawn.json
|
@ -213,6 +213,14 @@
|
||||||
"char": {
|
"char": {
|
||||||
"category": "native"
|
"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": {
|
"color": {
|
||||||
"category": "structure",
|
"category": "structure",
|
||||||
"members": [
|
"members": [
|
||||||
|
@ -410,6 +418,13 @@
|
||||||
{"name": "descriptor", "type": "buffer descriptor", "annotation": "const*"}
|
{"name": "descriptor", "type": "buffer descriptor", "annotation": "const*"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "create buffer mapped",
|
||||||
|
"returns": "create buffer mapped result",
|
||||||
|
"args": [
|
||||||
|
{"name": "descriptor", "type": "buffer descriptor", "annotation": "const*"}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "create command encoder",
|
"name": "create command encoder",
|
||||||
"returns": "command encoder"
|
"returns": "command encoder"
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
],
|
],
|
||||||
"client_handwritten_commands": [
|
"client_handwritten_commands": [
|
||||||
"BufferUnmap",
|
"BufferUnmap",
|
||||||
|
"DeviceCreateBufferMapped",
|
||||||
"QueueCreateFence",
|
"QueueCreateFence",
|
||||||
"FenceGetCompletedValue",
|
"FenceGetCompletedValue",
|
||||||
"QueueSignal"
|
"QueueSignal"
|
||||||
|
|
|
@ -230,9 +230,34 @@ def as_cppType(name):
|
||||||
else:
|
else:
|
||||||
return name.CamelCase()
|
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):
|
def decorate(name, typ, arg):
|
||||||
if arg.annotation == 'value':
|
if arg.annotation == 'value':
|
||||||
return typ + ' ' + name
|
return typ + ' ' + name
|
||||||
|
elif arg.annotation == '*':
|
||||||
|
return typ + ' * ' + name
|
||||||
elif arg.annotation == 'const*':
|
elif arg.annotation == 'const*':
|
||||||
return typ + ' const * ' + name
|
return typ + ' const * ' + name
|
||||||
elif arg.annotation == 'const*const*':
|
elif arg.annotation == 'const*const*':
|
||||||
|
@ -314,6 +339,7 @@ def get_renders_for_targets(api_params, wire_json, targets):
|
||||||
'as_cProc': as_cProc,
|
'as_cProc': as_cProc,
|
||||||
'as_cType': as_cType,
|
'as_cType': as_cType,
|
||||||
'as_cppType': as_cppType,
|
'as_cppType': as_cppType,
|
||||||
|
'convert_cType_to_cppType': convert_cType_to_cppType,
|
||||||
'as_varName': as_varName,
|
'as_varName': as_varName,
|
||||||
'decorate': decorate,
|
'decorate': decorate,
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,13 +96,7 @@ namespace dawn {
|
||||||
{{render_cpp_to_c_method_call(type, method)}};
|
{{render_cpp_to_c_method_call(type, method)}};
|
||||||
{% else %}
|
{% else %}
|
||||||
auto result = {{render_cpp_to_c_method_call(type, method)}};
|
auto result = {{render_cpp_to_c_method_call(type, method)}};
|
||||||
{% if method.return_type.category == "native" %}
|
return {{convert_cType_to_cppType(method.return_type, 'value', 'result') | indent(8)}};
|
||||||
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%}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
}
|
}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -152,7 +152,7 @@
|
||||||
|
|
||||||
//* Serializes `record` into `transfer`, using `buffer` to get more space for pointed-to data
|
//* Serializes `record` into `transfer`, using `buffer` to get more space for pointed-to data
|
||||||
//* and `provider` to serialize objects.
|
//* 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
|
char** buffer
|
||||||
{%- if record.has_dawn_object -%}
|
{%- if record.has_dawn_object -%}
|
||||||
, const ObjectIdProvider& provider
|
, const ObjectIdProvider& provider
|
||||||
|
@ -200,11 +200,12 @@
|
||||||
}
|
}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
}
|
}
|
||||||
|
DAWN_UNUSED_FUNC({{Return}}{{name}}Serialize);
|
||||||
|
|
||||||
//* Deserializes `transfer` into `record` getting more serialized data from `buffer` and `size`
|
//* 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
|
//* if needed, using `allocator` to store pointed-to values and `resolver` to translate object
|
||||||
//* Ids to actual objects.
|
//* 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
|
const char** buffer, size_t* size, DeserializeAllocator* allocator
|
||||||
{%- if record.has_dawn_object -%}
|
{%- if record.has_dawn_object -%}
|
||||||
, const ObjectIdResolver& resolver
|
, const ObjectIdResolver& resolver
|
||||||
|
@ -283,6 +284,7 @@
|
||||||
|
|
||||||
return DeserializeResult::Success;
|
return DeserializeResult::Success;
|
||||||
}
|
}
|
||||||
|
DAWN_UNUSED_FUNC({{Return}}{{name}}Deserialize);
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro write_command_serialization_methods(command, is_return) %}
|
{% macro write_command_serialization_methods(command, is_return) %}
|
||||||
|
|
|
@ -31,7 +31,24 @@ namespace dawn_native {
|
||||||
ErrorBuffer(DeviceBase* device) : BufferBase(device, ObjectBase::kError) {
|
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:
|
private:
|
||||||
|
MaybeError MapAtCreationImpl(uint8_t** mappedPointer) override {
|
||||||
|
UNREACHABLE();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
MaybeError SetSubDataImpl(uint32_t start,
|
MaybeError SetSubDataImpl(uint32_t start,
|
||||||
uint32_t count,
|
uint32_t count,
|
||||||
const uint8_t* data) override {
|
const uint8_t* data) override {
|
||||||
|
@ -45,11 +62,14 @@ namespace dawn_native {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
void UnmapImpl() override {
|
void UnmapImpl() override {
|
||||||
UNREACHABLE();
|
ASSERT(mFakeMappedData);
|
||||||
|
mFakeMappedData.reset();
|
||||||
}
|
}
|
||||||
void DestroyImpl() override {
|
void DestroyImpl() override {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<uint8_t[]> mFakeMappedData;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
@ -104,6 +124,13 @@ namespace dawn_native {
|
||||||
return new ErrorBuffer(device);
|
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 {
|
uint32_t BufferBase::GetSize() const {
|
||||||
ASSERT(!IsError());
|
ASSERT(!IsError());
|
||||||
return mSize;
|
return mSize;
|
||||||
|
@ -114,6 +141,22 @@ namespace dawn_native {
|
||||||
return mUsage;
|
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 {
|
MaybeError BufferBase::ValidateCanUseInSubmitNow() const {
|
||||||
ASSERT(!IsError());
|
ASSERT(!IsError());
|
||||||
|
|
||||||
|
@ -239,6 +282,11 @@ namespace dawn_native {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BufferBase::Unmap() {
|
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())) {
|
if (GetDevice()->ConsumedError(ValidateUnmap())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,10 +45,15 @@ namespace dawn_native {
|
||||||
~BufferBase();
|
~BufferBase();
|
||||||
|
|
||||||
static BufferBase* MakeError(DeviceBase* device);
|
static BufferBase* MakeError(DeviceBase* device);
|
||||||
|
static BufferBase* MakeErrorMapped(DeviceBase* device,
|
||||||
|
uint64_t size,
|
||||||
|
uint8_t** mappedPointer);
|
||||||
|
|
||||||
uint32_t GetSize() const;
|
uint32_t GetSize() const;
|
||||||
dawn::BufferUsageBit GetUsage() const;
|
dawn::BufferUsageBit GetUsage() const;
|
||||||
|
|
||||||
|
MaybeError MapAtCreation(uint8_t** mappedPointer);
|
||||||
|
|
||||||
MaybeError ValidateCanUseInSubmitNow() const;
|
MaybeError ValidateCanUseInSubmitNow() const;
|
||||||
|
|
||||||
// Dawn API
|
// Dawn API
|
||||||
|
@ -73,6 +78,7 @@ namespace dawn_native {
|
||||||
void DestroyInternal();
|
void DestroyInternal();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
virtual MaybeError MapAtCreationImpl(uint8_t** mappedPointer) = 0;
|
||||||
virtual MaybeError SetSubDataImpl(uint32_t start, uint32_t count, const uint8_t* data);
|
virtual MaybeError SetSubDataImpl(uint32_t start, uint32_t count, const uint8_t* data);
|
||||||
virtual void MapReadAsyncImpl(uint32_t serial) = 0;
|
virtual void MapReadAsyncImpl(uint32_t serial) = 0;
|
||||||
virtual void MapWriteAsyncImpl(uint32_t serial) = 0;
|
virtual void MapWriteAsyncImpl(uint32_t serial) = 0;
|
||||||
|
|
|
@ -237,6 +237,30 @@ namespace dawn_native {
|
||||||
|
|
||||||
return result;
|
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() {
|
CommandEncoderBase* DeviceBase::CreateCommandEncoder() {
|
||||||
return new CommandEncoderBase(this);
|
return new CommandEncoderBase(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,6 +104,7 @@ namespace dawn_native {
|
||||||
BindGroupBase* CreateBindGroup(const BindGroupDescriptor* descriptor);
|
BindGroupBase* CreateBindGroup(const BindGroupDescriptor* descriptor);
|
||||||
BindGroupLayoutBase* CreateBindGroupLayout(const BindGroupLayoutDescriptor* descriptor);
|
BindGroupLayoutBase* CreateBindGroupLayout(const BindGroupLayoutDescriptor* descriptor);
|
||||||
BufferBase* CreateBuffer(const BufferDescriptor* descriptor);
|
BufferBase* CreateBuffer(const BufferDescriptor* descriptor);
|
||||||
|
DawnCreateBufferMappedResult CreateBufferMapped(const BufferDescriptor* descriptor);
|
||||||
CommandEncoderBase* CreateCommandEncoder();
|
CommandEncoderBase* CreateCommandEncoder();
|
||||||
ComputePipelineBase* CreateComputePipeline(const ComputePipelineDescriptor* descriptor);
|
ComputePipelineBase* CreateComputePipeline(const ComputePipelineDescriptor* descriptor);
|
||||||
PipelineLayoutBase* CreatePipelineLayout(const PipelineLayoutDescriptor* descriptor);
|
PipelineLayoutBase* CreatePipelineLayout(const PipelineLayoutDescriptor* descriptor);
|
||||||
|
|
|
@ -160,6 +160,13 @@ namespace dawn_native { namespace d3d12 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
void Buffer::MapReadAsyncImpl(uint32_t serial) {
|
||||||
mWrittenMappedRange = {};
|
mWrittenMappedRange = {};
|
||||||
D3D12_RANGE readRange = {0, GetSize()};
|
D3D12_RANGE readRange = {0, GetSize()};
|
||||||
|
|
|
@ -44,6 +44,8 @@ namespace dawn_native { namespace d3d12 {
|
||||||
void UnmapImpl() override;
|
void UnmapImpl() override;
|
||||||
void DestroyImpl() override;
|
void DestroyImpl() override;
|
||||||
|
|
||||||
|
virtual MaybeError MapAtCreationImpl(uint8_t** mappedPointer) override;
|
||||||
|
|
||||||
ComPtr<ID3D12Resource> mResource;
|
ComPtr<ID3D12Resource> mResource;
|
||||||
bool mFixedResourceState = false;
|
bool mFixedResourceState = false;
|
||||||
dawn::BufferUsageBit mLastUsage = dawn::BufferUsageBit::None;
|
dawn::BufferUsageBit mLastUsage = dawn::BufferUsageBit::None;
|
||||||
|
|
|
@ -34,11 +34,14 @@ namespace dawn_native { namespace metal {
|
||||||
void OnMapCommandSerialFinished(uint32_t mapSerial, bool isWrite);
|
void OnMapCommandSerialFinished(uint32_t mapSerial, bool isWrite);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Dawn API
|
||||||
void MapReadAsyncImpl(uint32_t serial) override;
|
void MapReadAsyncImpl(uint32_t serial) override;
|
||||||
void MapWriteAsyncImpl(uint32_t serial) override;
|
void MapWriteAsyncImpl(uint32_t serial) override;
|
||||||
void UnmapImpl() override;
|
void UnmapImpl() override;
|
||||||
void DestroyImpl() override;
|
void DestroyImpl() override;
|
||||||
|
|
||||||
|
MaybeError MapAtCreationImpl(uint8_t** mappedPointer) override;
|
||||||
|
|
||||||
id<MTLBuffer> mMtlBuffer = nil;
|
id<MTLBuffer> mMtlBuffer = nil;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,11 @@ namespace dawn_native { namespace metal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaybeError Buffer::MapAtCreationImpl(uint8_t** mappedPointer) {
|
||||||
|
*mappedPointer = reinterpret_cast<uint8_t*>([mMtlBuffer contents]);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
void Buffer::MapReadAsyncImpl(uint32_t serial) {
|
void Buffer::MapReadAsyncImpl(uint32_t serial) {
|
||||||
MapRequestTracker* tracker = ToBackend(GetDevice())->GetMapTracker();
|
MapRequestTracker* tracker = ToBackend(GetDevice())->GetMapTracker();
|
||||||
tracker->Track(this, serial, false);
|
tracker->Track(this, serial, false);
|
||||||
|
|
|
@ -184,13 +184,18 @@ namespace dawn_native { namespace null {
|
||||||
: BufferBase(device, descriptor) {
|
: BufferBase(device, descriptor) {
|
||||||
if (GetUsage() & (dawn::BufferUsageBit::TransferDst | dawn::BufferUsageBit::MapRead |
|
if (GetUsage() & (dawn::BufferUsageBit::TransferDst | dawn::BufferUsageBit::MapRead |
|
||||||
dawn::BufferUsageBit::MapWrite)) {
|
dawn::BufferUsageBit::MapWrite)) {
|
||||||
mBackingData = std::unique_ptr<char[]>(new char[GetSize()]);
|
mBackingData = std::unique_ptr<uint8_t[]>(new uint8_t[GetSize()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer::~Buffer() {
|
Buffer::~Buffer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaybeError Buffer::MapAtCreationImpl(uint8_t** mappedPointer) {
|
||||||
|
*mappedPointer = mBackingData.get();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
void Buffer::MapReadOperationCompleted(uint32_t serial, void* ptr, bool isWrite) {
|
void Buffer::MapReadOperationCompleted(uint32_t serial, void* ptr, bool isWrite) {
|
||||||
if (isWrite) {
|
if (isWrite) {
|
||||||
CallMapWriteCallback(serial, DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, ptr, GetSize());
|
CallMapWriteCallback(serial, DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, ptr, GetSize());
|
||||||
|
|
|
@ -138,15 +138,17 @@ namespace dawn_native { namespace null {
|
||||||
void MapReadOperationCompleted(uint32_t serial, void* ptr, bool isWrite);
|
void MapReadOperationCompleted(uint32_t serial, void* ptr, bool isWrite);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Dawn API
|
||||||
MaybeError SetSubDataImpl(uint32_t start, uint32_t count, const uint8_t* data) override;
|
MaybeError SetSubDataImpl(uint32_t start, uint32_t count, const uint8_t* data) override;
|
||||||
void MapReadAsyncImpl(uint32_t serial) override;
|
void MapReadAsyncImpl(uint32_t serial) override;
|
||||||
void MapWriteAsyncImpl(uint32_t serial) override;
|
void MapWriteAsyncImpl(uint32_t serial) override;
|
||||||
void UnmapImpl() override;
|
void UnmapImpl() override;
|
||||||
void DestroyImpl() override;
|
void DestroyImpl() override;
|
||||||
|
|
||||||
|
MaybeError MapAtCreationImpl(uint8_t** mappedPointer) override;
|
||||||
void MapAsyncImplCommon(uint32_t serial, bool isWrite);
|
void MapAsyncImplCommon(uint32_t serial, bool isWrite);
|
||||||
|
|
||||||
std::unique_ptr<char[]> mBackingData;
|
std::unique_ptr<uint8_t[]> mBackingData;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CommandBuffer : public CommandBufferBase {
|
class CommandBuffer : public CommandBufferBase {
|
||||||
|
|
|
@ -35,6 +35,13 @@ namespace dawn_native { namespace opengl {
|
||||||
return mBuffer;
|
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) {
|
MaybeError Buffer::SetSubDataImpl(uint32_t start, uint32_t count, const uint8_t* data) {
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
|
glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, start, count, data);
|
glBufferSubData(GL_ARRAY_BUFFER, start, count, data);
|
||||||
|
|
|
@ -31,12 +31,15 @@ namespace dawn_native { namespace opengl {
|
||||||
GLuint GetHandle() const;
|
GLuint GetHandle() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Dawn API
|
||||||
MaybeError SetSubDataImpl(uint32_t start, uint32_t count, const uint8_t* data) override;
|
MaybeError SetSubDataImpl(uint32_t start, uint32_t count, const uint8_t* data) override;
|
||||||
void MapReadAsyncImpl(uint32_t serial) override;
|
void MapReadAsyncImpl(uint32_t serial) override;
|
||||||
void MapWriteAsyncImpl(uint32_t serial) override;
|
void MapWriteAsyncImpl(uint32_t serial) override;
|
||||||
void UnmapImpl() override;
|
void UnmapImpl() override;
|
||||||
void DestroyImpl() override;
|
void DestroyImpl() override;
|
||||||
|
|
||||||
|
MaybeError MapAtCreationImpl(uint8_t** mappedPointer) override;
|
||||||
|
|
||||||
GLuint mBuffer = 0;
|
GLuint mBuffer = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -188,6 +188,11 @@ namespace dawn_native { namespace vulkan {
|
||||||
mLastUsage = usage;
|
mLastUsage = usage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaybeError Buffer::MapAtCreationImpl(uint8_t** mappedPointer) {
|
||||||
|
*mappedPointer = mMemoryAllocation.GetMappedPointer();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
void Buffer::MapReadAsyncImpl(uint32_t serial) {
|
void Buffer::MapReadAsyncImpl(uint32_t serial) {
|
||||||
Device* device = ToBackend(GetDevice());
|
Device* device = ToBackend(GetDevice());
|
||||||
|
|
||||||
|
|
|
@ -41,11 +41,14 @@ namespace dawn_native { namespace vulkan {
|
||||||
void TransitionUsageNow(VkCommandBuffer commands, dawn::BufferUsageBit usage);
|
void TransitionUsageNow(VkCommandBuffer commands, dawn::BufferUsageBit usage);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Dawn API
|
||||||
void MapReadAsyncImpl(uint32_t serial) override;
|
void MapReadAsyncImpl(uint32_t serial) override;
|
||||||
void MapWriteAsyncImpl(uint32_t serial) override;
|
void MapWriteAsyncImpl(uint32_t serial) override;
|
||||||
void UnmapImpl() override;
|
void UnmapImpl() override;
|
||||||
void DestroyImpl() override;
|
void DestroyImpl() override;
|
||||||
|
|
||||||
|
MaybeError MapAtCreationImpl(uint8_t** mappedPointer) override;
|
||||||
|
|
||||||
VkBuffer mHandle = VK_NULL_HANDLE;
|
VkBuffer mHandle = VK_NULL_HANDLE;
|
||||||
DeviceMemoryAllocation mMemoryAllocation;
|
DeviceMemoryAllocation mMemoryAllocation;
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,14 @@ namespace dawn_wire { namespace client {
|
||||||
cmd.Serialize(allocatedBuffer);
|
cmd.Serialize(allocatedBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DawnCreateBufferMappedResult ClientDeviceCreateBufferMapped(
|
||||||
|
DawnDevice cDevice,
|
||||||
|
const DawnBufferDescriptor* descriptor) {
|
||||||
|
// TODO(enga): Not implemented
|
||||||
|
UNREACHABLE();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t ClientFenceGetCompletedValue(DawnFence cSelf) {
|
uint64_t ClientFenceGetCompletedValue(DawnFence cSelf) {
|
||||||
auto fence = reinterpret_cast<Fence*>(cSelf);
|
auto fence = reinterpret_cast<Fence*>(cSelf);
|
||||||
return fence->completedValue;
|
return fence->completedValue;
|
||||||
|
|
|
@ -229,3 +229,48 @@ DAWN_INSTANTIATE_TEST(BufferSetSubDataTests,
|
||||||
MetalBackend,
|
MetalBackend,
|
||||||
OpenGLBackend,
|
OpenGLBackend,
|
||||||
VulkanBackend);
|
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);
|
||||||
|
|
|
@ -82,6 +82,15 @@ class BufferValidationTest : public ValidationTest {
|
||||||
return device.CreateBuffer(&descriptor);
|
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;
|
dawn::Queue queue;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -183,6 +192,14 @@ TEST_F(BufferValidationTest, MapWriteSuccess) {
|
||||||
buf.Unmap();
|
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 map reading a buffer with wrong current usage
|
||||||
TEST_F(BufferValidationTest, MapReadWrongUsage) {
|
TEST_F(BufferValidationTest, MapReadWrongUsage) {
|
||||||
dawn::BufferDescriptor descriptor;
|
dawn::BufferDescriptor descriptor;
|
||||||
|
|
Loading…
Reference in New Issue