Add a Reserved state for dawn_wire ObjectId allocations

Functions like CreateReadyRenderPipeline reserve an
ObjectId for the pipeline created but the Id can not be
used until the callback is called successfully.

Bug: chromium:1172774, chromium:1172775
Change-Id: I145c0f033a2bde7957d15da2da8b9b19c6520ceb
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/39840
Reviewed-by: Stephen White <senorblanco@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
Austin Eng
2021-02-03 23:29:43 +00:00
committed by Commit Bot service account
parent 59024a62f6
commit 623d80899b
4 changed files with 74 additions and 61 deletions

View File

@@ -22,21 +22,29 @@ namespace dawn_wire { namespace server {
void HandleCreateReadyRenderPipelineCallbackResult(KnownObjects<Pipeline>* knownObjects,
WGPUCreateReadyPipelineStatus status,
Pipeline pipeline,
const char* message,
CreateReadyPipelineUserData* data) {
auto* pipelineObject = knownObjects->Get(data->pipelineObjectID);
// May be null if the device was destroyed. Device destruction destroys child
// objects on the wire.
auto* pipelineObject =
knownObjects->Get(data->pipelineObjectID, AllocationState::Reserved);
// Should be impossible to fail. ObjectIds can't be freed by a destroy command until
// they move from Reserved to Allocated, or if they are destroyed here.
ASSERT(pipelineObject != nullptr);
if (status == WGPUCreateReadyPipelineStatus_Success) {
ASSERT(pipelineObject != nullptr);
// Assign the handle and allocated status if the pipeline is created successfully.
pipelineObject->state = AllocationState::Allocated;
pipelineObject->handle = pipeline;
} else if (pipelineObject != nullptr) {
// May be null if the device was destroyed. Device destruction destroys child
// objects on the wire.
if (!UntrackDeviceChild(pipelineObject->deviceInfo, objectType,
data->pipelineObjectID)) {
UNREACHABLE();
}
// This should be impossible to fail. It would require a command to be sent that
// creates a duplicate ObjectId, which would fail validation.
bool success = TrackDeviceChild(pipelineObject->deviceInfo, objectType,
data->pipelineObjectID);
ASSERT(success);
} else {
// Otherwise, free the ObjectId which will make it unusable.
knownObjects->Free(data->pipelineObjectID);
ASSERT(pipeline == nullptr);
}
}
@@ -103,17 +111,14 @@ namespace dawn_wire { namespace server {
return false;
}
auto* resultData = ComputePipelineObjects().Allocate(pipelineObjectHandle.id);
auto* resultData =
ComputePipelineObjects().Allocate(pipelineObjectHandle.id, AllocationState::Reserved);
if (resultData == nullptr) {
return false;
}
resultData->generation = pipelineObjectHandle.generation;
resultData->deviceInfo = device->info.get();
if (!TrackDeviceChild(resultData->deviceInfo, ObjectType::ComputePipeline,
pipelineObjectHandle.id)) {
return false;
}
auto userdata = MakeUserdata<CreateReadyPipelineUserData>();
userdata->device = ObjectHandle{deviceId, device->generation};
@@ -133,7 +138,7 @@ namespace dawn_wire { namespace server {
const char* message,
CreateReadyPipelineUserData* data) {
HandleCreateReadyRenderPipelineCallbackResult<ObjectType::ComputePipeline>(
&ComputePipelineObjects(), status, pipeline, message, data);
&ComputePipelineObjects(), status, pipeline, data);
ReturnDeviceCreateReadyComputePipelineCallbackCmd cmd;
cmd.device = data->device;
@@ -153,17 +158,14 @@ namespace dawn_wire { namespace server {
return false;
}
auto* resultData = RenderPipelineObjects().Allocate(pipelineObjectHandle.id);
auto* resultData =
RenderPipelineObjects().Allocate(pipelineObjectHandle.id, AllocationState::Reserved);
if (resultData == nullptr) {
return false;
}
resultData->generation = pipelineObjectHandle.generation;
resultData->deviceInfo = device->info.get();
if (!TrackDeviceChild(resultData->deviceInfo, ObjectType::RenderPipeline,
pipelineObjectHandle.id)) {
return false;
}
auto userdata = MakeUserdata<CreateReadyPipelineUserData>();
userdata->device = ObjectHandle{deviceId, device->generation};
@@ -183,7 +185,7 @@ namespace dawn_wire { namespace server {
const char* message,
CreateReadyPipelineUserData* data) {
HandleCreateReadyRenderPipelineCallbackResult<ObjectType::RenderPipeline>(
&RenderPipelineObjects(), status, pipeline, message, data);
&RenderPipelineObjects(), status, pipeline, data);
ReturnDeviceCreateReadyRenderPipelineCallbackCmd cmd;
cmd.device = data->device;