Add reflection APIs for wgpu::Buffer.
Changes dawn::native procs to correctly convert C++ enum and bitmask returns values. Bug: dawn:1451 Change-Id: I39a8d218f76e25b178a83eeb99d653222d39d040 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/92440 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Loko Kung <lokokung@google.com> Commit-Queue: Austin Eng <enga@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
faa64a60ef
commit
d428187d35
|
@ -433,6 +433,14 @@
|
||||||
{"name": "label", "type": "char", "annotation": "const*", "length": "strlen"}
|
{"name": "label", "type": "char", "annotation": "const*", "length": "strlen"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "get usage",
|
||||||
|
"returns": "buffer usage"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "get size",
|
||||||
|
"returns": "uint64_t"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "unmap"
|
"name": "unmap"
|
||||||
},
|
},
|
||||||
|
|
|
@ -189,6 +189,8 @@
|
||||||
"BufferMapAsync",
|
"BufferMapAsync",
|
||||||
"BufferGetConstMappedRange",
|
"BufferGetConstMappedRange",
|
||||||
"BufferGetMappedRange",
|
"BufferGetMappedRange",
|
||||||
|
"BufferGetSize",
|
||||||
|
"BufferGetUsage",
|
||||||
"DeviceCreateBuffer",
|
"DeviceCreateBuffer",
|
||||||
"DeviceCreateComputePipelineAsync",
|
"DeviceCreateComputePipelineAsync",
|
||||||
"DeviceCreateRenderPipelineAsync",
|
"DeviceCreateRenderPipelineAsync",
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace {{native_namespace}} {
|
||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
);
|
);
|
||||||
{% if method.return_type.name.canonical_case() != "void" %}
|
{% if method.return_type.name.canonical_case() != "void" %}
|
||||||
{% if method.return_type.category == "object" %}
|
{% if method.return_type.category in ["object", "enum", "bitmask"] %}
|
||||||
return ToAPI(result);
|
return ToAPI(result);
|
||||||
{% else %}
|
{% else %}
|
||||||
return result;
|
return result;
|
||||||
|
@ -104,7 +104,7 @@ namespace {{native_namespace}} {
|
||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
);
|
);
|
||||||
{% if function.return_type.name.canonical_case() != "void" %}
|
{% if function.return_type.name.canonical_case() != "void" %}
|
||||||
{% if function.return_type.category == "object" %}
|
{% if function.return_type.category in ["object", "enum", "bitmask"] %}
|
||||||
return ToAPI(result);
|
return ToAPI(result);
|
||||||
{% else %}
|
{% else %}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -77,6 +77,16 @@ namespace {{native_namespace}} {
|
||||||
static constexpr uint32_t value = {{len(e.values)}};
|
static constexpr uint32_t value = {{len(e.values)}};
|
||||||
};
|
};
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
{% for type in by_category["enum"] + by_category["bitmask"] %}
|
||||||
|
inline {{as_cType(type.name)}} ToAPI({{namespace}}::{{as_cppType(type.name)}} rhs) {
|
||||||
|
return static_cast<{{as_cType(type.name)}}>(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline {{namespace}}::{{as_cppType(type.name)}} FromAPI({{as_cType(type.name)}} rhs) {
|
||||||
|
return static_cast<{{namespace}}::{{as_cppType(type.name)}}>(rhs);
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // {{NATIVE_DIR}}_{{PREFIX}}_PLATFORM_AUTOGEN_H_
|
#endif // {{NATIVE_DIR}}_{{PREFIX}}_PLATFORM_AUTOGEN_H_
|
||||||
|
|
|
@ -158,7 +158,10 @@ BufferBase::BufferBase(DeviceBase* device, const BufferDescriptor* descriptor)
|
||||||
BufferBase::BufferBase(DeviceBase* device,
|
BufferBase::BufferBase(DeviceBase* device,
|
||||||
const BufferDescriptor* descriptor,
|
const BufferDescriptor* descriptor,
|
||||||
ObjectBase::ErrorTag tag)
|
ObjectBase::ErrorTag tag)
|
||||||
: ApiObjectBase(device, tag), mSize(descriptor->size), mState(BufferState::Unmapped) {
|
: ApiObjectBase(device, tag),
|
||||||
|
mSize(descriptor->size),
|
||||||
|
mUsage(descriptor->usage),
|
||||||
|
mState(BufferState::Unmapped) {
|
||||||
if (descriptor->mappedAtCreation) {
|
if (descriptor->mappedAtCreation) {
|
||||||
mState = BufferState::MappedAtCreation;
|
mState = BufferState::MappedAtCreation;
|
||||||
mMapOffset = 0;
|
mMapOffset = 0;
|
||||||
|
@ -215,9 +218,14 @@ wgpu::BufferUsage BufferBase::GetUsage() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
wgpu::BufferUsage BufferBase::GetUsageExternalOnly() const {
|
wgpu::BufferUsage BufferBase::GetUsageExternalOnly() const {
|
||||||
|
ASSERT(!IsError());
|
||||||
return GetUsage() & ~kAllInternalBufferUsages;
|
return GetUsage() & ~kAllInternalBufferUsages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wgpu::BufferUsage BufferBase::APIGetUsage() const {
|
||||||
|
return mUsage & ~kAllInternalBufferUsages;
|
||||||
|
}
|
||||||
|
|
||||||
MaybeError BufferBase::MapAtCreation() {
|
MaybeError BufferBase::MapAtCreation() {
|
||||||
DAWN_TRY(MapAtCreationInternal());
|
DAWN_TRY(MapAtCreationInternal());
|
||||||
|
|
||||||
|
@ -378,6 +386,10 @@ void BufferBase::APIDestroy() {
|
||||||
Destroy();
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t BufferBase::APIGetSize() const {
|
||||||
|
return mSize;
|
||||||
|
}
|
||||||
|
|
||||||
MaybeError BufferBase::CopyFromStagingBuffer() {
|
MaybeError BufferBase::CopyFromStagingBuffer() {
|
||||||
ASSERT(mStagingBuffer);
|
ASSERT(mStagingBuffer);
|
||||||
if (mSize == 0) {
|
if (mSize == 0) {
|
||||||
|
|
|
@ -48,8 +48,6 @@ class BufferBase : public ApiObjectBase {
|
||||||
MappedAtCreation,
|
MappedAtCreation,
|
||||||
Destroyed,
|
Destroyed,
|
||||||
};
|
};
|
||||||
BufferBase(DeviceBase* device, const BufferDescriptor* descriptor);
|
|
||||||
|
|
||||||
static BufferBase* MakeError(DeviceBase* device, const BufferDescriptor* descriptor);
|
static BufferBase* MakeError(DeviceBase* device, const BufferDescriptor* descriptor);
|
||||||
|
|
||||||
ObjectType GetType() const override;
|
ObjectType GetType() const override;
|
||||||
|
@ -86,12 +84,15 @@ class BufferBase : public ApiObjectBase {
|
||||||
const void* APIGetConstMappedRange(size_t offset, size_t size);
|
const void* APIGetConstMappedRange(size_t offset, size_t size);
|
||||||
void APIUnmap();
|
void APIUnmap();
|
||||||
void APIDestroy();
|
void APIDestroy();
|
||||||
|
wgpu::BufferUsage APIGetUsage() const;
|
||||||
|
uint64_t APIGetSize() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
BufferBase(DeviceBase* device, const BufferDescriptor* descriptor);
|
||||||
BufferBase(DeviceBase* device, const BufferDescriptor* descriptor, ObjectBase::ErrorTag tag);
|
BufferBase(DeviceBase* device, const BufferDescriptor* descriptor, ObjectBase::ErrorTag tag);
|
||||||
|
|
||||||
// Constructor used only for mocking and testing.
|
// Constructor used only for mocking and testing.
|
||||||
BufferBase(DeviceBase* device, BufferState state);
|
BufferBase(DeviceBase* device, BufferState state);
|
||||||
|
|
||||||
void DestroyImpl() override;
|
void DestroyImpl() override;
|
||||||
|
|
||||||
~BufferBase() override;
|
~BufferBase() override;
|
||||||
|
|
|
@ -940,3 +940,74 @@ TEST_F(BufferValidationTest, GetMappedRange_OffsetSizeOOB) {
|
||||||
EXPECT_EQ(buffer.GetMappedRange(0, 0), nullptr);
|
EXPECT_EQ(buffer.GetMappedRange(0, 0), nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test that the buffer creation parameters are correctly reflected for succesfully created buffers.
|
||||||
|
TEST_F(BufferValidationTest, CreationParameterReflectionForValidBuffer) {
|
||||||
|
// Test reflection on two succesfully created but different buffers. The reflected data should
|
||||||
|
// be different!
|
||||||
|
{
|
||||||
|
wgpu::BufferDescriptor desc;
|
||||||
|
desc.size = 16;
|
||||||
|
desc.usage = wgpu::BufferUsage::Uniform;
|
||||||
|
wgpu::Buffer buf = device.CreateBuffer(&desc);
|
||||||
|
|
||||||
|
EXPECT_EQ(wgpu::BufferUsage::Uniform, buf.GetUsage());
|
||||||
|
EXPECT_EQ(16u, buf.GetSize());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
wgpu::BufferDescriptor desc;
|
||||||
|
desc.size = 32;
|
||||||
|
desc.usage = wgpu::BufferUsage::Storage;
|
||||||
|
wgpu::Buffer buf = device.CreateBuffer(&desc);
|
||||||
|
|
||||||
|
EXPECT_EQ(wgpu::BufferUsage::Storage, buf.GetUsage());
|
||||||
|
EXPECT_EQ(32u, buf.GetSize());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that the buffer creation parameters are correctly reflected for buffers invalid because of
|
||||||
|
// validation errors.
|
||||||
|
TEST_F(BufferValidationTest, CreationParameterReflectionForErrorBuffer) {
|
||||||
|
wgpu::BufferDescriptor desc;
|
||||||
|
desc.usage = wgpu::BufferUsage::Uniform;
|
||||||
|
desc.size = 19;
|
||||||
|
desc.mappedAtCreation = true;
|
||||||
|
|
||||||
|
// Error! MappedAtCreation requires size % 4 == 0.
|
||||||
|
wgpu::Buffer buf;
|
||||||
|
ASSERT_DEVICE_ERROR(buf = device.CreateBuffer(&desc));
|
||||||
|
|
||||||
|
// Reflection data is still exactly what was in the descriptor.
|
||||||
|
EXPECT_EQ(wgpu::BufferUsage::Uniform, buf.GetUsage());
|
||||||
|
EXPECT_EQ(19u, buf.GetSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that the buffer creation parameters are correctly reflected for buffers invalid because of
|
||||||
|
// OOM.
|
||||||
|
TEST_F(BufferValidationTest, CreationParameterReflectionForOOMBuffer) {
|
||||||
|
constexpr uint64_t kAmazinglyLargeSize = 0x1234'5678'90AB'CDEF;
|
||||||
|
wgpu::BufferDescriptor desc;
|
||||||
|
desc.usage = wgpu::BufferUsage::Storage;
|
||||||
|
desc.size = kAmazinglyLargeSize;
|
||||||
|
|
||||||
|
// OOM!
|
||||||
|
wgpu::Buffer buf;
|
||||||
|
ASSERT_DEVICE_ERROR(buf = device.CreateBuffer(&desc));
|
||||||
|
|
||||||
|
// Reflection data is still exactly what was in the descriptor.
|
||||||
|
EXPECT_EQ(wgpu::BufferUsage::Storage, buf.GetUsage());
|
||||||
|
EXPECT_EQ(kAmazinglyLargeSize, buf.GetSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that buffer reflection doesn't show internal usages
|
||||||
|
TEST_F(BufferValidationTest, CreationParameterReflectionNoInternalUsage) {
|
||||||
|
wgpu::BufferDescriptor desc;
|
||||||
|
desc.size = 16;
|
||||||
|
// QueryResolve also adds kInternalStorageBuffer for processing of queries.
|
||||||
|
desc.usage = wgpu::BufferUsage::QueryResolve;
|
||||||
|
wgpu::Buffer buf = device.CreateBuffer(&desc);
|
||||||
|
|
||||||
|
// The reflection shouldn't show kInternalStorageBuffer
|
||||||
|
EXPECT_EQ(wgpu::BufferUsage::QueryResolve, buf.GetUsage());
|
||||||
|
EXPECT_EQ(16u, buf.GetSize());
|
||||||
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ WGPUBuffer Buffer::Create(Device* device, const WGPUBufferDescriptor* descriptor
|
||||||
wireClient->GetMemoryTransferService()->CreateReadHandle(descriptor->size));
|
wireClient->GetMemoryTransferService()->CreateReadHandle(descriptor->size));
|
||||||
if (readHandle == nullptr) {
|
if (readHandle == nullptr) {
|
||||||
device->InjectError(WGPUErrorType_OutOfMemory, "Failed to create buffer mapping");
|
device->InjectError(WGPUErrorType_OutOfMemory, "Failed to create buffer mapping");
|
||||||
return device->CreateErrorBuffer();
|
return CreateError(device, descriptor);
|
||||||
}
|
}
|
||||||
cmd.readHandleCreateInfoLength = readHandle->SerializeCreateSize();
|
cmd.readHandleCreateInfoLength = readHandle->SerializeCreateSize();
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ WGPUBuffer Buffer::Create(Device* device, const WGPUBufferDescriptor* descriptor
|
||||||
wireClient->GetMemoryTransferService()->CreateWriteHandle(descriptor->size));
|
wireClient->GetMemoryTransferService()->CreateWriteHandle(descriptor->size));
|
||||||
if (writeHandle == nullptr) {
|
if (writeHandle == nullptr) {
|
||||||
device->InjectError(WGPUErrorType_OutOfMemory, "Failed to create buffer mapping");
|
device->InjectError(WGPUErrorType_OutOfMemory, "Failed to create buffer mapping");
|
||||||
return device->CreateErrorBuffer();
|
return CreateError(device, descriptor);
|
||||||
}
|
}
|
||||||
cmd.writeHandleCreateInfoLength = writeHandle->SerializeCreateSize();
|
cmd.writeHandleCreateInfoLength = writeHandle->SerializeCreateSize();
|
||||||
}
|
}
|
||||||
|
@ -79,6 +79,7 @@ WGPUBuffer Buffer::Create(Device* device, const WGPUBufferDescriptor* descriptor
|
||||||
buffer->mDevice = device;
|
buffer->mDevice = device;
|
||||||
buffer->mDeviceIsAlive = device->GetAliveWeakPtr();
|
buffer->mDeviceIsAlive = device->GetAliveWeakPtr();
|
||||||
buffer->mSize = descriptor->size;
|
buffer->mSize = descriptor->size;
|
||||||
|
buffer->mUsage = static_cast<WGPUBufferUsage>(descriptor->usage);
|
||||||
buffer->mDestructWriteHandleOnUnmap = false;
|
buffer->mDestructWriteHandleOnUnmap = false;
|
||||||
|
|
||||||
if (descriptor->mappedAtCreation) {
|
if (descriptor->mappedAtCreation) {
|
||||||
|
@ -124,10 +125,12 @@ WGPUBuffer Buffer::Create(Device* device, const WGPUBufferDescriptor* descriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
WGPUBuffer Buffer::CreateError(Device* device) {
|
WGPUBuffer Buffer::CreateError(Device* device, const WGPUBufferDescriptor* descriptor) {
|
||||||
auto* allocation = device->client->BufferAllocator().New(device->client);
|
auto* allocation = device->client->BufferAllocator().New(device->client);
|
||||||
allocation->object->mDevice = device;
|
allocation->object->mDevice = device;
|
||||||
allocation->object->mDeviceIsAlive = device->GetAliveWeakPtr();
|
allocation->object->mDeviceIsAlive = device->GetAliveWeakPtr();
|
||||||
|
allocation->object->mSize = descriptor->size;
|
||||||
|
allocation->object->mUsage = static_cast<WGPUBufferUsage>(descriptor->usage);
|
||||||
|
|
||||||
DeviceCreateErrorBufferCmd cmd;
|
DeviceCreateErrorBufferCmd cmd;
|
||||||
cmd.self = ToAPI(device);
|
cmd.self = ToAPI(device);
|
||||||
|
@ -365,6 +368,14 @@ void Buffer::Destroy() {
|
||||||
client->SerializeCommand(cmd);
|
client->SerializeCommand(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WGPUBufferUsage Buffer::GetUsage() const {
|
||||||
|
return mUsage;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t Buffer::GetSize() const {
|
||||||
|
return mSize;
|
||||||
|
}
|
||||||
|
|
||||||
bool Buffer::IsMappedForReading() const {
|
bool Buffer::IsMappedForReading() const {
|
||||||
return mMapState == MapState::MappedForRead;
|
return mMapState == MapState::MappedForRead;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,10 +28,8 @@ class Device;
|
||||||
|
|
||||||
class Buffer final : public ObjectBase {
|
class Buffer final : public ObjectBase {
|
||||||
public:
|
public:
|
||||||
using ObjectBase::ObjectBase;
|
|
||||||
|
|
||||||
static WGPUBuffer Create(Device* device, const WGPUBufferDescriptor* descriptor);
|
static WGPUBuffer Create(Device* device, const WGPUBufferDescriptor* descriptor);
|
||||||
static WGPUBuffer CreateError(Device* device);
|
static WGPUBuffer CreateError(Device* device, const WGPUBufferDescriptor* descriptor);
|
||||||
|
|
||||||
Buffer(Client* client, uint32_t refcount, uint32_t id);
|
Buffer(Client* client, uint32_t refcount, uint32_t id);
|
||||||
~Buffer();
|
~Buffer();
|
||||||
|
@ -51,6 +49,10 @@ class Buffer final : public ObjectBase {
|
||||||
|
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
|
// Note that these values can be arbitrary since they aren't validated in the wire client.
|
||||||
|
WGPUBufferUsage GetUsage() const;
|
||||||
|
uint64_t GetSize() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CancelCallbacksForDisconnect() override;
|
void CancelCallbacksForDisconnect() override;
|
||||||
void ClearAllCallbacks(WGPUBufferMapAsyncStatus status);
|
void ClearAllCallbacks(WGPUBufferMapAsyncStatus status);
|
||||||
|
@ -90,6 +92,7 @@ class Buffer final : public ObjectBase {
|
||||||
};
|
};
|
||||||
RequestTracker<MapRequestData> mRequests;
|
RequestTracker<MapRequestData> mRequests;
|
||||||
uint64_t mSize = 0;
|
uint64_t mSize = 0;
|
||||||
|
WGPUBufferUsage mUsage;
|
||||||
|
|
||||||
// Only one mapped pointer can be active at a time because Unmap clears all the in-flight
|
// Only one mapped pointer can be active at a time because Unmap clears all the in-flight
|
||||||
// requests.
|
// requests.
|
||||||
|
|
|
@ -200,7 +200,8 @@ WGPUBuffer Device::CreateBuffer(const WGPUBufferDescriptor* descriptor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
WGPUBuffer Device::CreateErrorBuffer() {
|
WGPUBuffer Device::CreateErrorBuffer() {
|
||||||
return Buffer::CreateError(this);
|
WGPUBufferDescriptor fakeDescriptor = {};
|
||||||
|
return Buffer::CreateError(this, &fakeDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
WGPUQueue Device::GetQueue() {
|
WGPUQueue Device::GetQueue() {
|
||||||
|
|
Loading…
Reference in New Issue