dawn_native: Use refcount-safe methods for reentrant object creation

Previously all uses of reentrant object creation in Dawn native
needed to manually AcquireRef. Change them to use CreateFooInternal that
returns a ResultOrError<Ref<>> and are renamed to CreateFoo.

Bug: dawn:723

Change-Id: Ifcda3659d02cc5a4c63c248dc53af7fee7c4a61d
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/46626
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Stephen White <senorblanco@chromium.org>
diff --git a/src/dawn_native/CommandEncoder.cpp b/src/dawn_native/CommandEncoder.cpp
index f4c0d88..e460eab 100644
--- a/src/dawn_native/CommandEncoder.cpp
+++ b/src/dawn_native/CommandEncoder.cpp
@@ -451,9 +451,9 @@
             BufferDescriptor availabilityDesc = {};
             availabilityDesc.usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopyDst;
             availabilityDesc.size = querySet->GetQueryCount() * sizeof(uint32_t);
-            // TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
-            Ref<BufferBase> availabilityBuffer =
-                AcquireRef(device->APICreateBuffer(&availabilityDesc));
+            Ref<BufferBase> availabilityBuffer;
+            DAWN_TRY_ASSIGN(availabilityBuffer, device->CreateBuffer(&availabilityDesc));
+
             DAWN_TRY(device->GetQueue()->WriteBuffer(availabilityBuffer.Get(), 0,
                                                      availability.data(),
                                                      availability.size() * sizeof(uint32_t)));
@@ -461,17 +461,18 @@
             // Timestamp params uniform buffer
             TimestampParams params = {queryCount, static_cast<uint32_t>(destinationOffset),
                                       device->GetTimestampPeriodInNS()};
+
             BufferDescriptor parmsDesc = {};
             parmsDesc.usage = wgpu::BufferUsage::Uniform | wgpu::BufferUsage::CopyDst;
             parmsDesc.size = sizeof(params);
-            // TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
-            Ref<BufferBase> paramsBuffer = AcquireRef(device->APICreateBuffer(&parmsDesc));
+            Ref<BufferBase> paramsBuffer;
+            DAWN_TRY_ASSIGN(paramsBuffer, device->CreateBuffer(&parmsDesc));
+
             DAWN_TRY(
                 device->GetQueue()->WriteBuffer(paramsBuffer.Get(), 0, &params, sizeof(params)));
 
-            EncodeConvertTimestampsToNanoseconds(encoder, destination, availabilityBuffer.Get(),
-                                                 paramsBuffer.Get());
-            return {};
+            return EncodeConvertTimestampsToNanoseconds(
+                encoder, destination, availabilityBuffer.Get(), paramsBuffer.Get());
         }
 
     }  // namespace
diff --git a/src/dawn_native/CopyTextureForBrowserHelper.cpp b/src/dawn_native/CopyTextureForBrowserHelper.cpp
index f3b8c61..386127f 100644
--- a/src/dawn_native/CopyTextureForBrowserHelper.cpp
+++ b/src/dawn_native/CopyTextureForBrowserHelper.cpp
@@ -139,7 +139,7 @@
             return nullptr;
         }
 
-        RenderPipelineBase* GetOrCreateCopyTextureForBrowserPipeline(
+        ResultOrError<RenderPipelineBase*> GetOrCreateCopyTextureForBrowserPipeline(
             DeviceBase* device,
             wgpu::TextureFormat dstFormat) {
             InternalPipelineStore* store = device->GetInternalPipelineStore();
@@ -152,9 +152,8 @@
                     wgslDesc.source = sCopyTextureForBrowserVertex;
                     descriptor.nextInChain = reinterpret_cast<ChainedStruct*>(&wgslDesc);
 
-                    // TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
-                    store->copyTextureForBrowserVS =
-                        AcquireRef(device->APICreateShaderModule(&descriptor));
+                    DAWN_TRY_ASSIGN(store->copyTextureForBrowserVS,
+                                    device->CreateShaderModule(&descriptor));
                 }
 
                 ShaderModuleBase* vertexModule = store->copyTextureForBrowserVS.Get();
@@ -165,9 +164,8 @@
                     ShaderModuleWGSLDescriptor wgslDesc;
                     wgslDesc.source = sCopyTextureForBrowserFragment;
                     descriptor.nextInChain = reinterpret_cast<ChainedStruct*>(&wgslDesc);
-                    // TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
-                    store->copyTextureForBrowserFS =
-                        AcquireRef(device->APICreateShaderModule(&descriptor));
+                    DAWN_TRY_ASSIGN(store->copyTextureForBrowserFS,
+                                    device->CreateShaderModule(&descriptor));
                 }
 
                 ShaderModuleBase* fragmentModule = store->copyTextureForBrowserFS.Get();
@@ -200,9 +198,9 @@
                 fragment.targetCount = 1;
                 fragment.targets = &target;
 
-                // TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
-                store->copyTextureForBrowserPipelines.insert(
-                    {dstFormat, AcquireRef(device->APICreateRenderPipeline2(&renderPipelineDesc))});
+                Ref<RenderPipelineBase> pipeline;
+                DAWN_TRY_ASSIGN(pipeline, device->CreateRenderPipeline(&renderPipelineDesc));
+                store->copyTextureForBrowserPipelines.insert({dstFormat, std::move(pipeline)});
             }
 
             return GetCachedPipeline(store, dstFormat);
@@ -245,12 +243,13 @@
         // TODO(shaobo.yan@intel.com): In D3D12 and Vulkan, compatible texture format can directly
         // copy to each other. This can be a potential fast path.
 
-        RenderPipelineBase* pipeline = GetOrCreateCopyTextureForBrowserPipeline(
-            device, destination->texture->GetFormat().format);
+        RenderPipelineBase* pipeline;
+        DAWN_TRY_ASSIGN(pipeline, GetOrCreateCopyTextureForBrowserPipeline(
+                                      device, destination->texture->GetFormat().format));
 
         // Prepare bind group layout.
-        // TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
-        Ref<BindGroupLayoutBase> layout = AcquireRef(pipeline->APIGetBindGroupLayout(0));
+        Ref<BindGroupLayoutBase> layout;
+        DAWN_TRY_ASSIGN(layout, pipeline->GetBindGroupLayout(0));
 
         // Prepare bind group descriptor
         BindGroupEntry bindGroupEntries[3] = {};
@@ -280,8 +279,8 @@
         BufferDescriptor uniformDesc = {};
         uniformDesc.usage = wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::Uniform;
         uniformDesc.size = sizeof(uniformData);
-        // TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
-        Ref<BufferBase> uniformBuffer = AcquireRef(device->APICreateBuffer(&uniformDesc));
+        Ref<BufferBase> uniformBuffer;
+        DAWN_TRY_ASSIGN(uniformBuffer, device->CreateBuffer(&uniformDesc));
 
         DAWN_TRY(device->GetQueue()->WriteBuffer(uniformBuffer.Get(), 0, uniformData,
                                                  sizeof(uniformData)));
@@ -289,16 +288,16 @@
         // Prepare binding 1 resource: sampler
         // Use default configuration, filterMode set to Nearest for min and mag.
         SamplerDescriptor samplerDesc = {};
-        // TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
-        Ref<SamplerBase> sampler = AcquireRef(device->APICreateSampler(&samplerDesc));
+        Ref<SamplerBase> sampler;
+        DAWN_TRY_ASSIGN(sampler, device->CreateSampler(&samplerDesc));
 
         // Prepare binding 2 resource: sampled texture
         TextureViewDescriptor srcTextureViewDesc = {};
         srcTextureViewDesc.baseMipLevel = source->mipLevel;
         srcTextureViewDesc.mipLevelCount = 1;
-        // TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
-        Ref<TextureViewBase> srcTextureView =
-            AcquireRef(source->texture->APICreateView(&srcTextureViewDesc));
+        Ref<TextureViewBase> srcTextureView;
+        DAWN_TRY_ASSIGN(srcTextureView,
+                        device->CreateTextureView(source->texture, &srcTextureViewDesc));
 
         // Set bind group entries.
         bindGroupEntries[0].binding = 0;
@@ -310,8 +309,8 @@
         bindGroupEntries[2].textureView = srcTextureView.Get();
 
         // Create bind group after all binding entries are set.
-        // TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
-        Ref<BindGroupBase> bindGroup = AcquireRef(device->APICreateBindGroup(&bgDesc));
+        Ref<BindGroupBase> bindGroup;
+        DAWN_TRY_ASSIGN(bindGroup, device->CreateBindGroup(&bgDesc));
 
         // Create command encoder.
         CommandEncoderDescriptor encoderDesc = {};
@@ -322,9 +321,9 @@
         TextureViewDescriptor dstTextureViewDesc;
         dstTextureViewDesc.baseMipLevel = destination->mipLevel;
         dstTextureViewDesc.mipLevelCount = 1;
-        // TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
-        Ref<TextureViewBase> dstView =
-            AcquireRef(destination->texture->APICreateView(&dstTextureViewDesc));
+        Ref<TextureViewBase> dstView;
+        DAWN_TRY_ASSIGN(dstView,
+                        device->CreateTextureView(destination->texture, &dstTextureViewDesc));
 
         // Prepare render pass color attachment descriptor.
         RenderPassColorAttachmentDescriptor colorAttachmentDesc;
diff --git a/src/dawn_native/Device.cpp b/src/dawn_native/Device.cpp
index 0b91e83..2a493c7 100644
--- a/src/dawn_native/Device.cpp
+++ b/src/dawn_native/Device.cpp
@@ -683,7 +683,7 @@
 
     BindGroupBase* DeviceBase::APICreateBindGroup(const BindGroupDescriptor* descriptor) {
         Ref<BindGroupBase> result;
-        if (ConsumedError(CreateBindGroupInternal(descriptor), &result)) {
+        if (ConsumedError(CreateBindGroup(descriptor), &result)) {
             return BindGroupBase::MakeError(this);
         }
         return result.Detach();
@@ -691,14 +691,14 @@
     BindGroupLayoutBase* DeviceBase::APICreateBindGroupLayout(
         const BindGroupLayoutDescriptor* descriptor) {
         Ref<BindGroupLayoutBase> result;
-        if (ConsumedError(CreateBindGroupLayoutInternal(descriptor), &result)) {
+        if (ConsumedError(CreateBindGroupLayout(descriptor), &result)) {
             return BindGroupLayoutBase::MakeError(this);
         }
         return result.Detach();
     }
     BufferBase* DeviceBase::APICreateBuffer(const BufferDescriptor* descriptor) {
         Ref<BufferBase> result = nullptr;
-        if (ConsumedError(CreateBufferInternal(descriptor), &result)) {
+        if (ConsumedError(CreateBuffer(descriptor), &result)) {
             ASSERT(result == nullptr);
             return BufferBase::MakeError(this, descriptor);
         }
@@ -711,7 +711,7 @@
     ComputePipelineBase* DeviceBase::APICreateComputePipeline(
         const ComputePipelineDescriptor* descriptor) {
         Ref<ComputePipelineBase> result;
-        if (ConsumedError(CreateComputePipelineInternal(descriptor), &result)) {
+        if (ConsumedError(CreateComputePipeline(descriptor), &result)) {
             return ComputePipelineBase::MakeError(this);
         }
         return result.Detach();
@@ -719,10 +719,10 @@
     void DeviceBase::APICreateComputePipelineAsync(const ComputePipelineDescriptor* descriptor,
                                                    WGPUCreateComputePipelineAsyncCallback callback,
                                                    void* userdata) {
-        MaybeError maybeResult = CreateComputePipelineAsyncInternal(descriptor, callback, userdata);
+        MaybeError maybeResult = CreateComputePipelineAsync(descriptor, callback, userdata);
 
         // Call the callback directly when a validation error has been found in the front-end
-        // validations. If there is no error, then CreateComputePipelineAsyncInternal will call the
+        // validations. If there is no error, then CreateComputePipelineAsync will call the
         // callback.
         if (maybeResult.IsError()) {
             std::unique_ptr<ErrorData> error = maybeResult.AcquireError();
@@ -733,21 +733,21 @@
     PipelineLayoutBase* DeviceBase::APICreatePipelineLayout(
         const PipelineLayoutDescriptor* descriptor) {
         Ref<PipelineLayoutBase> result;
-        if (ConsumedError(CreatePipelineLayoutInternal(descriptor), &result)) {
+        if (ConsumedError(CreatePipelineLayout(descriptor), &result)) {
             return PipelineLayoutBase::MakeError(this);
         }
         return result.Detach();
     }
     QuerySetBase* DeviceBase::APICreateQuerySet(const QuerySetDescriptor* descriptor) {
         Ref<QuerySetBase> result;
-        if (ConsumedError(CreateQuerySetInternal(descriptor), &result)) {
+        if (ConsumedError(CreateQuerySet(descriptor), &result)) {
             return QuerySetBase::MakeError(this);
         }
         return result.Detach();
     }
     SamplerBase* DeviceBase::APICreateSampler(const SamplerDescriptor* descriptor) {
         Ref<SamplerBase> result;
-        if (ConsumedError(CreateSamplerInternal(descriptor), &result)) {
+        if (ConsumedError(CreateSampler(descriptor), &result)) {
             return SamplerBase::MakeError(this);
         }
         return result.Detach();
@@ -756,7 +756,7 @@
                                                   WGPUCreateRenderPipelineAsyncCallback callback,
                                                   void* userdata) {
         ResultOrError<Ref<RenderPipelineBase>> maybeResult =
-            CreateRenderPipelineInternal(descriptor);
+            CreateRenderPipeline(descriptor);
         if (maybeResult.IsError()) {
             std::unique_ptr<ErrorData> error = maybeResult.AcquireError();
             callback(WGPUCreatePipelineAsyncStatus_Error, nullptr, error->GetMessage().c_str(),
@@ -773,7 +773,7 @@
     RenderBundleEncoder* DeviceBase::APICreateRenderBundleEncoder(
         const RenderBundleEncoderDescriptor* descriptor) {
         Ref<RenderBundleEncoder> result;
-        if (ConsumedError(CreateRenderBundleEncoderInternal(descriptor), &result)) {
+        if (ConsumedError(CreateRenderBundleEncoder(descriptor), &result)) {
             return RenderBundleEncoder::MakeError(this);
         }
         return result.Detach();
@@ -873,7 +873,7 @@
         }
 
         Ref<RenderPipelineBase> result;
-        if (ConsumedError(CreateRenderPipelineInternal(&normalizedDescriptor), &result)) {
+        if (ConsumedError(CreateRenderPipeline(&normalizedDescriptor), &result)) {
             return RenderPipelineBase::MakeError(this);
         }
         return result.Detach();
@@ -881,7 +881,7 @@
     RenderPipelineBase* DeviceBase::APICreateRenderPipeline2(
         const RenderPipelineDescriptor2* descriptor) {
         Ref<RenderPipelineBase> result;
-        if (ConsumedError(CreateRenderPipelineInternal(descriptor), &result)) {
+        if (ConsumedError(CreateRenderPipeline(descriptor), &result)) {
             return RenderPipelineBase::MakeError(this);
         }
         return result.Detach();
@@ -889,7 +889,7 @@
     ShaderModuleBase* DeviceBase::APICreateShaderModule(const ShaderModuleDescriptor* descriptor) {
         Ref<ShaderModuleBase> result;
         ShaderModuleParseResult parseResult = {};
-        if (ConsumedError(CreateShaderModuleInternal(descriptor, &parseResult), &result)) {
+        if (ConsumedError(CreateShaderModule(descriptor, &parseResult), &result)) {
             return ShaderModuleBase::MakeError(this, std::move(parseResult.compilationMessages));
         }
         return result.Detach();
@@ -897,26 +897,18 @@
     SwapChainBase* DeviceBase::APICreateSwapChain(Surface* surface,
                                                   const SwapChainDescriptor* descriptor) {
         Ref<SwapChainBase> result;
-        if (ConsumedError(CreateSwapChainInternal(surface, descriptor), &result)) {
+        if (ConsumedError(CreateSwapChain(surface, descriptor), &result)) {
             return SwapChainBase::MakeError(this);
         }
         return result.Detach();
     }
     TextureBase* DeviceBase::APICreateTexture(const TextureDescriptor* descriptor) {
         Ref<TextureBase> result;
-        if (ConsumedError(CreateTextureInternal(descriptor), &result)) {
+        if (ConsumedError(CreateTexture(descriptor), &result)) {
             return TextureBase::MakeError(this);
         }
         return result.Detach();
     }
-    TextureViewBase* DeviceBase::CreateTextureView(TextureBase* texture,
-                                                   const TextureViewDescriptor* descriptor) {
-        Ref<TextureViewBase> result;
-        if (ConsumedError(CreateTextureViewInternal(texture, descriptor), &result)) {
-            return TextureViewBase::MakeError(this);
-        }
-        return result.Detach();
-    }
 
     // For Dawn Wire
 
@@ -983,7 +975,7 @@
     ExternalTextureBase* DeviceBase::APICreateExternalTexture(
         const ExternalTextureDescriptor* descriptor) {
         Ref<ExternalTextureBase> result = nullptr;
-        if (ConsumedError(CreateExternalTextureInternal(descriptor), &result)) {
+        if (ConsumedError(CreateExternalTexture(descriptor), &result)) {
             return ExternalTextureBase::MakeError(this);
         }
 
@@ -1039,7 +1031,7 @@
 
     // Implementation details of object creation
 
-    ResultOrError<Ref<BindGroupBase>> DeviceBase::CreateBindGroupInternal(
+    ResultOrError<Ref<BindGroupBase>> DeviceBase::CreateBindGroup(
         const BindGroupDescriptor* descriptor) {
         DAWN_TRY(ValidateIsAlive());
         if (IsValidationEnabled()) {
@@ -1048,7 +1040,7 @@
         return CreateBindGroupImpl(descriptor);
     }
 
-    ResultOrError<Ref<BindGroupLayoutBase>> DeviceBase::CreateBindGroupLayoutInternal(
+    ResultOrError<Ref<BindGroupLayoutBase>> DeviceBase::CreateBindGroupLayout(
         const BindGroupLayoutDescriptor* descriptor) {
         DAWN_TRY(ValidateIsAlive());
         if (IsValidationEnabled()) {
@@ -1057,8 +1049,7 @@
         return GetOrCreateBindGroupLayout(descriptor);
     }
 
-    ResultOrError<Ref<BufferBase>> DeviceBase::CreateBufferInternal(
-        const BufferDescriptor* descriptor) {
+    ResultOrError<Ref<BufferBase>> DeviceBase::CreateBuffer(const BufferDescriptor* descriptor) {
         DAWN_TRY(ValidateIsAlive());
         if (IsValidationEnabled()) {
             DAWN_TRY(ValidateBufferDescriptor(this, descriptor));
@@ -1074,7 +1065,7 @@
         return std::move(buffer);
     }
 
-    ResultOrError<Ref<ComputePipelineBase>> DeviceBase::CreateComputePipelineInternal(
+    ResultOrError<Ref<ComputePipelineBase>> DeviceBase::CreateComputePipeline(
         const ComputePipelineDescriptor* descriptor) {
         DAWN_TRY(ValidateIsAlive());
         if (IsValidationEnabled()) {
@@ -1099,7 +1090,7 @@
         return AddOrGetCachedPipeline(backendObj, blueprintHash);
     }
 
-    MaybeError DeviceBase::CreateComputePipelineAsyncInternal(
+    MaybeError DeviceBase::CreateComputePipelineAsync(
         const ComputePipelineDescriptor* descriptor,
         WGPUCreateComputePipelineAsyncCallback callback,
         void* userdata) {
@@ -1172,7 +1163,7 @@
         mCreatePipelineAsyncTracker->TrackTask(std::move(request), GetPendingCommandSerial());
     }
 
-    ResultOrError<Ref<PipelineLayoutBase>> DeviceBase::CreatePipelineLayoutInternal(
+    ResultOrError<Ref<PipelineLayoutBase>> DeviceBase::CreatePipelineLayout(
         const PipelineLayoutDescriptor* descriptor) {
         DAWN_TRY(ValidateIsAlive());
         if (IsValidationEnabled()) {
@@ -1181,7 +1172,7 @@
         return GetOrCreatePipelineLayout(descriptor);
     }
 
-    ResultOrError<Ref<ExternalTextureBase>> DeviceBase::CreateExternalTextureInternal(
+    ResultOrError<Ref<ExternalTextureBase>> DeviceBase::CreateExternalTexture(
         const ExternalTextureDescriptor* descriptor) {
         if (IsValidationEnabled()) {
             DAWN_TRY(ValidateExternalTextureDescriptor(this, descriptor));
@@ -1190,7 +1181,7 @@
         return ExternalTextureBase::Create(this, descriptor);
     }
 
-    ResultOrError<Ref<QuerySetBase>> DeviceBase::CreateQuerySetInternal(
+    ResultOrError<Ref<QuerySetBase>> DeviceBase::CreateQuerySet(
         const QuerySetDescriptor* descriptor) {
         DAWN_TRY(ValidateIsAlive());
         if (IsValidationEnabled()) {
@@ -1199,7 +1190,7 @@
         return CreateQuerySetImpl(descriptor);
     }
 
-    ResultOrError<Ref<RenderBundleEncoder>> DeviceBase::CreateRenderBundleEncoderInternal(
+    ResultOrError<Ref<RenderBundleEncoder>> DeviceBase::CreateRenderBundleEncoder(
         const RenderBundleEncoderDescriptor* descriptor) {
         DAWN_TRY(ValidateIsAlive());
         if (IsValidationEnabled()) {
@@ -1208,7 +1199,7 @@
         return RenderBundleEncoder::Create(this, descriptor);
     }
 
-    ResultOrError<Ref<RenderPipelineBase>> DeviceBase::CreateRenderPipelineInternal(
+    ResultOrError<Ref<RenderPipelineBase>> DeviceBase::CreateRenderPipeline(
         const RenderPipelineDescriptor2* descriptor) {
         DAWN_TRY(ValidateIsAlive());
         if (IsValidationEnabled()) {
@@ -1231,7 +1222,7 @@
         }
     }
 
-    ResultOrError<Ref<SamplerBase>> DeviceBase::CreateSamplerInternal(
+    ResultOrError<Ref<SamplerBase>> DeviceBase::CreateSampler(
         const SamplerDescriptor* descriptor) {
         const SamplerDescriptor defaultDescriptor = {};
         DAWN_TRY(ValidateIsAlive());
@@ -1242,11 +1233,19 @@
         return GetOrCreateSampler(descriptor);
     }
 
-    ResultOrError<Ref<ShaderModuleBase>> DeviceBase::CreateShaderModuleInternal(
+    ResultOrError<Ref<ShaderModuleBase>> DeviceBase::CreateShaderModule(
         const ShaderModuleDescriptor* descriptor,
         ShaderModuleParseResult* parseResult) {
         DAWN_TRY(ValidateIsAlive());
 
+        // ShaderModule can be called from inside dawn_native. If that's the case handle the error
+        // directly in Dawn and don't need the parse results since there should be no validation
+        // errors.
+        ShaderModuleParseResult ignoredResults;
+        if (parseResult == nullptr) {
+            parseResult = &ignoredResults;
+        }
+
         if (IsValidationEnabled()) {
             DAWN_TRY(ValidateShaderModuleDescriptor(this, descriptor, parseResult));
         }
@@ -1254,7 +1253,7 @@
         return GetOrCreateShaderModule(descriptor, parseResult);
     }
 
-    ResultOrError<Ref<SwapChainBase>> DeviceBase::CreateSwapChainInternal(
+    ResultOrError<Ref<SwapChainBase>> DeviceBase::CreateSwapChain(
         Surface* surface,
         const SwapChainDescriptor* descriptor) {
         DAWN_TRY(ValidateIsAlive());
@@ -1285,8 +1284,7 @@
         }
     }
 
-    ResultOrError<Ref<TextureBase>> DeviceBase::CreateTextureInternal(
-        const TextureDescriptor* descriptor) {
+    ResultOrError<Ref<TextureBase>> DeviceBase::CreateTexture(const TextureDescriptor* descriptor) {
         DAWN_TRY(ValidateIsAlive());
         TextureDescriptor fixedDescriptor = *descriptor;
         DAWN_TRY(FixUpDeprecatedGPUExtent3DDepth(this, &(fixedDescriptor.size)));
@@ -1296,7 +1294,7 @@
         return CreateTextureImpl(&fixedDescriptor);
     }
 
-    ResultOrError<Ref<TextureViewBase>> DeviceBase::CreateTextureViewInternal(
+    ResultOrError<Ref<TextureViewBase>> DeviceBase::CreateTextureView(
         TextureBase* texture,
         const TextureViewDescriptor* descriptor) {
         DAWN_TRY(ValidateIsAlive());
diff --git a/src/dawn_native/Device.h b/src/dawn_native/Device.h
index c5e7ad8..2340cf3 100644
--- a/src/dawn_native/Device.h
+++ b/src/dawn_native/Device.h
@@ -140,7 +140,40 @@
         Ref<AttachmentState> GetOrCreateAttachmentState(const RenderPassDescriptor* descriptor);
         void UncacheAttachmentState(AttachmentState* obj);
 
-        // Dawn API
+        // Object creation methods that be used in a reentrant manner.
+        ResultOrError<Ref<BindGroupBase>> CreateBindGroup(const BindGroupDescriptor* descriptor);
+        ResultOrError<Ref<BindGroupLayoutBase>> CreateBindGroupLayout(
+            const BindGroupLayoutDescriptor* descriptor);
+        ResultOrError<Ref<BufferBase>> CreateBuffer(const BufferDescriptor* descriptor);
+        ResultOrError<Ref<ComputePipelineBase>> CreateComputePipeline(
+            const ComputePipelineDescriptor* descriptor);
+        MaybeError CreateComputePipelineAsync(
+            const ComputePipelineDescriptor* descriptor,
+            WGPUCreateComputePipelineAsyncCallback callback,
+            void* userdata);
+        ResultOrError<Ref<ExternalTextureBase>> CreateExternalTexture(
+            const ExternalTextureDescriptor* descriptor);
+        ResultOrError<Ref<PipelineLayoutBase>> CreatePipelineLayout(
+            const PipelineLayoutDescriptor* descriptor);
+        ResultOrError<Ref<QuerySetBase>> CreateQuerySet(const QuerySetDescriptor* descriptor);
+        ResultOrError<Ref<RenderBundleEncoder>> CreateRenderBundleEncoder(
+            const RenderBundleEncoderDescriptor* descriptor);
+        ResultOrError<Ref<RenderPipelineBase>> CreateRenderPipeline(
+            const RenderPipelineDescriptor2* descriptor);
+        ResultOrError<Ref<RenderPipelineBase>> CreateRenderPipeline(
+            const RenderPipelineDescriptor* descriptor);
+        ResultOrError<Ref<SamplerBase>> CreateSampler(const SamplerDescriptor* descriptor);
+        ResultOrError<Ref<ShaderModuleBase>> CreateShaderModule(
+            const ShaderModuleDescriptor* descriptor,
+            ShaderModuleParseResult* parseResult = nullptr);
+        ResultOrError<Ref<SwapChainBase>> CreateSwapChain(Surface* surface,
+                                                          const SwapChainDescriptor* descriptor);
+        ResultOrError<Ref<TextureBase>> CreateTexture(const TextureDescriptor* descriptor);
+        ResultOrError<Ref<TextureViewBase>> CreateTextureView(
+            TextureBase* texture,
+            const TextureViewDescriptor* descriptor);
+
+        // Implementation of API object creation methods. DO NOT use them in a reentrant manner.
         BindGroupBase* APICreateBindGroup(const BindGroupDescriptor* descriptor);
         BindGroupLayoutBase* APICreateBindGroupLayout(const BindGroupLayoutDescriptor* descriptor);
         BufferBase* APICreateBuffer(const BufferDescriptor* descriptor);
@@ -163,8 +196,7 @@
         ShaderModuleBase* APICreateShaderModule(const ShaderModuleDescriptor* descriptor);
         SwapChainBase* APICreateSwapChain(Surface* surface, const SwapChainDescriptor* descriptor);
         TextureBase* APICreateTexture(const TextureDescriptor* descriptor);
-        TextureViewBase* CreateTextureView(TextureBase* texture,
-                                           const TextureViewDescriptor* descriptor);
+
         InternalPipelineStore* GetInternalPipelineStore();
 
         // For Dawn Wire
@@ -299,39 +331,6 @@
 
         ResultOrError<Ref<BindGroupLayoutBase>> CreateEmptyBindGroupLayout();
 
-        ResultOrError<Ref<BindGroupBase>> CreateBindGroupInternal(
-            const BindGroupDescriptor* descriptor);
-        ResultOrError<Ref<BindGroupLayoutBase>> CreateBindGroupLayoutInternal(
-            const BindGroupLayoutDescriptor* descriptor);
-        ResultOrError<Ref<BufferBase>> CreateBufferInternal(const BufferDescriptor* descriptor);
-        MaybeError CreateComputePipelineAsyncInternal(
-            const ComputePipelineDescriptor* descriptor,
-            WGPUCreateComputePipelineAsyncCallback callback,
-            void* userdata);
-        ResultOrError<Ref<ComputePipelineBase>> CreateComputePipelineInternal(
-            const ComputePipelineDescriptor* descriptor);
-        ResultOrError<Ref<PipelineLayoutBase>> CreatePipelineLayoutInternal(
-            const PipelineLayoutDescriptor* descriptor);
-        ResultOrError<Ref<ExternalTextureBase>> CreateExternalTextureInternal(
-            const ExternalTextureDescriptor* descriptor);
-        ResultOrError<Ref<QuerySetBase>> CreateQuerySetInternal(
-            const QuerySetDescriptor* descriptor);
-        ResultOrError<Ref<RenderBundleEncoder>> CreateRenderBundleEncoderInternal(
-            const RenderBundleEncoderDescriptor* descriptor);
-        ResultOrError<Ref<RenderPipelineBase>> CreateRenderPipelineInternal(
-            const RenderPipelineDescriptor2* descriptor);
-        ResultOrError<Ref<SamplerBase>> CreateSamplerInternal(const SamplerDescriptor* descriptor);
-        ResultOrError<Ref<ShaderModuleBase>> CreateShaderModuleInternal(
-            const ShaderModuleDescriptor* descriptor,
-            ShaderModuleParseResult* parseResult);
-        ResultOrError<Ref<SwapChainBase>> CreateSwapChainInternal(
-            Surface* surface,
-            const SwapChainDescriptor* descriptor);
-        ResultOrError<Ref<TextureBase>> CreateTextureInternal(const TextureDescriptor* descriptor);
-        ResultOrError<Ref<TextureViewBase>> CreateTextureViewInternal(
-            TextureBase* texture,
-            const TextureViewDescriptor* descriptor);
-
         ResultOrError<Ref<PipelineLayoutBase>> ValidateAndGetComputePipelineDescriptorWithDefaults(
             const ComputePipelineDescriptor& descriptor,
             ComputePipelineDescriptor* outDescriptor);
diff --git a/src/dawn_native/Pipeline.cpp b/src/dawn_native/Pipeline.cpp
index e5933f5..c650afa 100644
--- a/src/dawn_native/Pipeline.cpp
+++ b/src/dawn_native/Pipeline.cpp
@@ -125,21 +125,24 @@
         return {};
     }
 
-    BindGroupLayoutBase* PipelineBase::APIGetBindGroupLayout(uint32_t groupIndexIn) {
-        if (GetDevice()->ConsumedError(ValidateGetBindGroupLayout(groupIndexIn))) {
-            return BindGroupLayoutBase::MakeError(GetDevice());
-        }
+    ResultOrError<Ref<BindGroupLayoutBase>> PipelineBase::GetBindGroupLayout(
+        uint32_t groupIndexIn) {
+        DAWN_TRY(ValidateGetBindGroupLayout(groupIndexIn));
 
         BindGroupIndex groupIndex(groupIndexIn);
-
-        BindGroupLayoutBase* bgl = nullptr;
         if (!mLayout->GetBindGroupLayoutsMask()[groupIndex]) {
-            bgl = GetDevice()->GetEmptyBindGroupLayout();
+            return Ref<BindGroupLayoutBase>(GetDevice()->GetEmptyBindGroupLayout());
         } else {
-            bgl = mLayout->GetBindGroupLayout(groupIndex);
+            return Ref<BindGroupLayoutBase>(mLayout->GetBindGroupLayout(groupIndex));
         }
-        bgl->Reference();
-        return bgl;
+    }
+
+    BindGroupLayoutBase* PipelineBase::APIGetBindGroupLayout(uint32_t groupIndexIn) {
+        Ref<BindGroupLayoutBase> result;
+        if (GetDevice()->ConsumedError(GetBindGroupLayout(groupIndexIn), &result)) {
+            return BindGroupLayoutBase::MakeError(GetDevice());
+        }
+        return result.Detach();
     }
 
     size_t PipelineBase::ComputeContentHash() {
diff --git a/src/dawn_native/Pipeline.h b/src/dawn_native/Pipeline.h
index 008845d..3ed80f1 100644
--- a/src/dawn_native/Pipeline.h
+++ b/src/dawn_native/Pipeline.h
@@ -50,12 +50,15 @@
         const ProgrammableStage& GetStage(SingleShaderStage stage) const;
         const PerStage<ProgrammableStage>& GetAllStages() const;
 
-        BindGroupLayoutBase* APIGetBindGroupLayout(uint32_t groupIndex);
+        ResultOrError<Ref<BindGroupLayoutBase>> GetBindGroupLayout(uint32_t groupIndex);
 
         // Helper functions for std::unordered_map-based pipeline caches.
         size_t ComputeContentHash() override;
         static bool EqualForCache(const PipelineBase* a, const PipelineBase* b);
 
+        // Implementation of the API entrypoint. Do not use in a reentrant manner.
+        BindGroupLayoutBase* APIGetBindGroupLayout(uint32_t groupIndex);
+
       protected:
         PipelineBase(DeviceBase* device,
                      PipelineLayoutBase* layout,
diff --git a/src/dawn_native/QueryHelper.cpp b/src/dawn_native/QueryHelper.cpp
index cf24c57..177dcc0 100644
--- a/src/dawn_native/QueryHelper.cpp
+++ b/src/dawn_native/QueryHelper.cpp
@@ -105,7 +105,8 @@
             }
         )";
 
-        ComputePipelineBase* GetOrCreateTimestampComputePipeline(DeviceBase* device) {
+        ResultOrError<ComputePipelineBase*> GetOrCreateTimestampComputePipeline(
+            DeviceBase* device) {
             InternalPipelineStore* store = device->GetInternalPipelineStore();
 
             if (store->timestampComputePipeline == nullptr) {
@@ -116,8 +117,7 @@
                     wgslDesc.source = sConvertTimestampsToNanoseconds;
                     descriptor.nextInChain = reinterpret_cast<ChainedStruct*>(&wgslDesc);
 
-                    // TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
-                    store->timestampCS = AcquireRef(device->APICreateShaderModule(&descriptor));
+                    DAWN_TRY_ASSIGN(store->timestampCS, device->CreateShaderModule(&descriptor));
                 }
 
                 // Create ComputePipeline.
@@ -127,9 +127,8 @@
                 computePipelineDesc.computeStage.module = store->timestampCS.Get();
                 computePipelineDesc.computeStage.entryPoint = "main";
 
-                // TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
-                store->timestampComputePipeline =
-                    AcquireRef(device->APICreateComputePipeline(&computePipelineDesc));
+                DAWN_TRY_ASSIGN(store->timestampComputePipeline,
+                                device->CreateComputePipeline(&computePipelineDesc));
             }
 
             return store->timestampComputePipeline.Get();
@@ -137,17 +136,18 @@
 
     }  // anonymous namespace
 
-    void EncodeConvertTimestampsToNanoseconds(CommandEncoder* encoder,
-                                              BufferBase* timestamps,
-                                              BufferBase* availability,
-                                              BufferBase* params) {
+    MaybeError EncodeConvertTimestampsToNanoseconds(CommandEncoder* encoder,
+                                                    BufferBase* timestamps,
+                                                    BufferBase* availability,
+                                                    BufferBase* params) {
         DeviceBase* device = encoder->GetDevice();
 
-        ComputePipelineBase* pipeline = GetOrCreateTimestampComputePipeline(device);
+        ComputePipelineBase* pipeline;
+        DAWN_TRY_ASSIGN(pipeline, GetOrCreateTimestampComputePipeline(device));
 
         // Prepare bind group layout.
-        // TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
-        Ref<BindGroupLayoutBase> layout = AcquireRef(pipeline->APIGetBindGroupLayout(0));
+        Ref<BindGroupLayoutBase> layout;
+        DAWN_TRY_ASSIGN(layout, pipeline->GetBindGroupLayout(0));
 
         // Prepare bind group descriptor
         std::array<BindGroupEntry, 3> bindGroupEntries = {};
@@ -168,8 +168,8 @@
         bindGroupEntries[2].size = params->GetSize();
 
         // Create bind group after all binding entries are set.
-        // TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
-        Ref<BindGroupBase> bindGroup = AcquireRef(device->APICreateBindGroup(&bgDesc));
+        Ref<BindGroupBase> bindGroup;
+        DAWN_TRY_ASSIGN(bindGroup, device->CreateBindGroup(&bgDesc));
 
         // Create compute encoder and issue dispatch.
         ComputePassDescriptor passDesc = {};
@@ -180,6 +180,8 @@
         pass->APIDispatch(
             static_cast<uint32_t>((timestamps->GetSize() / sizeof(uint64_t) + 7) / 8));
         pass->APIEndPass();
+
+        return {};
     }
 
 }  // namespace dawn_native
diff --git a/src/dawn_native/QueryHelper.h b/src/dawn_native/QueryHelper.h
index 6e31beb..82ed5e1 100644
--- a/src/dawn_native/QueryHelper.h
+++ b/src/dawn_native/QueryHelper.h
@@ -15,6 +15,7 @@
 #ifndef DAWNNATIVE_QUERYHELPER_H_
 #define DAWNNATIVE_QUERYHELPER_H_
 
+#include "dawn_native/Error.h"
 #include "dawn_native/ObjectBase.h"
 
 namespace dawn_native {
@@ -28,10 +29,10 @@
         float period;
     };
 
-    void EncodeConvertTimestampsToNanoseconds(CommandEncoder* encoder,
-                                              BufferBase* timestamps,
-                                              BufferBase* availability,
-                                              BufferBase* params);
+    MaybeError EncodeConvertTimestampsToNanoseconds(CommandEncoder* encoder,
+                                                    BufferBase* timestamps,
+                                                    BufferBase* availability,
+                                                    BufferBase* params);
 
 }  // namespace dawn_native
 
diff --git a/src/dawn_native/Texture.cpp b/src/dawn_native/Texture.cpp
index 9b89880..2e6eafb 100644
--- a/src/dawn_native/Texture.cpp
+++ b/src/dawn_native/Texture.cpp
@@ -626,7 +626,13 @@
     }
 
     TextureViewBase* TextureBase::APICreateView(const TextureViewDescriptor* descriptor) {
-        return GetDevice()->CreateTextureView(this, descriptor);
+        DeviceBase* device = GetDevice();
+
+        Ref<TextureViewBase> result;
+        if (device->ConsumedError(device->CreateTextureView(this, descriptor), &result)) {
+            return TextureViewBase::MakeError(device);
+        }
+        return result.Detach();
     }
 
     void TextureBase::APIDestroy() {
diff --git a/src/dawn_native/ToBackend.h b/src/dawn_native/ToBackend.h
index 3cc0715..5b0f049 100644
--- a/src/dawn_native/ToBackend.h
+++ b/src/dawn_native/ToBackend.h
@@ -127,6 +127,12 @@
     }
 
     template <typename BackendTraits, typename T>
+    Ref<typename ToBackendTraits<T, BackendTraits>::BackendType>&& ToBackendBase(Ref<T>&& common) {
+        return reinterpret_cast<Ref<typename ToBackendTraits<T, BackendTraits>::BackendType>&&>(
+            common);
+    }
+
+    template <typename BackendTraits, typename T>
     const Ref<typename ToBackendTraits<T, BackendTraits>::BackendType>& ToBackendBase(
         const Ref<T>& common) {
         return reinterpret_cast<
diff --git a/src/dawn_native/d3d12/CommandBufferD3D12.cpp b/src/dawn_native/d3d12/CommandBufferD3D12.cpp
index 08b181c..d09f2ee 100644
--- a/src/dawn_native/d3d12/CommandBufferD3D12.cpp
+++ b/src/dawn_native/d3d12/CommandBufferD3D12.cpp
@@ -139,10 +139,10 @@
             return false;
         }
 
-        void RecordCopyTextureWithTemporaryBuffer(CommandRecordingContext* recordingContext,
-                                                  const TextureCopy& srcCopy,
-                                                  const TextureCopy& dstCopy,
-                                                  const Extent3D& copySize) {
+        MaybeError RecordCopyTextureWithTemporaryBuffer(CommandRecordingContext* recordingContext,
+                                                        const TextureCopy& srcCopy,
+                                                        const TextureCopy& dstCopy,
+                                                        const Extent3D& copySize) {
             ASSERT(srcCopy.texture->GetFormat().format == dstCopy.texture->GetFormat().format);
             ASSERT(srcCopy.aspect == dstCopy.aspect);
             dawn_native::Format format = srcCopy.texture->GetFormat();
@@ -166,9 +166,9 @@
             tempBufferDescriptor.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
             tempBufferDescriptor.size = tempBufferSize.AcquireSuccess();
             Device* device = ToBackend(srcCopy.texture->GetDevice());
-            // TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
-            Ref<Buffer> tempBuffer =
-                AcquireRef(ToBackend(device->APICreateBuffer(&tempBufferDescriptor)));
+            Ref<BufferBase> tempBufferBase;
+            DAWN_TRY_ASSIGN(tempBufferBase, device->CreateBuffer(&tempBufferDescriptor));
+            Ref<Buffer> tempBuffer = ToBackend(std::move(tempBufferBase));
 
             // Copy from source texture into tempBuffer
             Texture* srcTexture = ToBackend(srcCopy.texture).Get();
@@ -190,6 +190,8 @@
 
             // Save tempBuffer into recordingContext
             recordingContext->AddToTempBuffers(std::move(tempBuffer));
+
+            return {};
         }
     }  // anonymous namespace
 
@@ -824,8 +826,8 @@
                     ASSERT(srcRange.aspects == dstRange.aspects);
                     if (ShouldCopyUsingTemporaryBuffer(GetDevice(), copy->source,
                                                        copy->destination)) {
-                        RecordCopyTextureWithTemporaryBuffer(commandContext, copy->source,
-                                                             copy->destination, copy->copySize);
+                        DAWN_TRY(RecordCopyTextureWithTemporaryBuffer(
+                            commandContext, copy->source, copy->destination, copy->copySize));
                         break;
                     }
 
diff --git a/src/tests/white_box/QueryInternalShaderTests.cpp b/src/tests/white_box/QueryInternalShaderTests.cpp
index c6ffbe3..11b9a12 100644
--- a/src/tests/white_box/QueryInternalShaderTests.cpp
+++ b/src/tests/white_box/QueryInternalShaderTests.cpp
@@ -25,11 +25,11 @@
                                               wgpu::Buffer timestamps,
                                               wgpu::Buffer availability,
                                               wgpu::Buffer params) {
-        dawn_native::EncodeConvertTimestampsToNanoseconds(
+        ASSERT_TRUE(dawn_native::EncodeConvertTimestampsToNanoseconds(
             reinterpret_cast<dawn_native::CommandEncoder*>(encoder.Get()),
             reinterpret_cast<dawn_native::BufferBase*>(timestamps.Get()),
             reinterpret_cast<dawn_native::BufferBase*>(availability.Get()),
-            reinterpret_cast<dawn_native::BufferBase*>(params.Get()));
+            reinterpret_cast<dawn_native::BufferBase*>(params.Get())).IsSuccess());
     }
 
     class InternalShaderExpectation : public detail::Expectation {