diff --git a/src/dawn_native/metal/CommandBufferMTL.mm b/src/dawn_native/metal/CommandBufferMTL.mm index 65a2178bf0..d1c5b7c6c9 100644 --- a/src/dawn_native/metal/CommandBufferMTL.mm +++ b/src/dawn_native/metal/CommandBufferMTL.mm @@ -223,10 +223,11 @@ namespace dawn_native { namespace metal { } // Helper functions for Toggle AlwaysResolveIntoZeroLevelAndLayer - NSPRef> CreateResolveTextureForWorkaround(Device* device, - MTLPixelFormat mtlFormat, - uint32_t width, - uint32_t height) { + ResultOrError>> CreateResolveTextureForWorkaround( + Device* device, + MTLPixelFormat mtlFormat, + uint32_t width, + uint32_t height) { NSRef mtlDescRef = AcquireNSRef([MTLTextureDescriptor new]); MTLTextureDescriptor* mtlDesc = mtlDescRef.Get(); @@ -241,7 +242,12 @@ namespace dawn_native { namespace metal { mtlDesc.storageMode = MTLStorageModePrivate; mtlDesc.sampleCount = 1; - return AcquireNSPRef([device->GetMTLDevice() newTextureWithDescriptor:mtlDesc]); + id texture = [device->GetMTLDevice() newTextureWithDescriptor:mtlDesc]; + if (texture == nil) { + return DAWN_OUT_OF_MEMORY_ERROR("Allocation of temporary texture failed."); + } + + return AcquireNSPRef(texture); } void CopyIntoTrueResolveTarget(CommandRecordingContext* commandContext, @@ -1144,8 +1150,8 @@ namespace dawn_native { namespace metal { trueResolveSlices[i] = mtlRenderPass.colorAttachments[i].resolveSlice; const MTLPixelFormat mtlFormat = trueResolveTextures[i].pixelFormat; - temporaryResolveTextures[i] = - CreateResolveTextureForWorkaround(device, mtlFormat, width, height); + DAWN_TRY_ASSIGN(temporaryResolveTextures[i], CreateResolveTextureForWorkaround( + device, mtlFormat, width, height)); mtlRenderPass.colorAttachments[i].resolveTexture = temporaryResolveTextures[i].Get(); diff --git a/src/dawn_native/metal/ComputePipelineMTL.mm b/src/dawn_native/metal/ComputePipelineMTL.mm index 860aa400db..b98a3694d5 100644 --- a/src/dawn_native/metal/ComputePipelineMTL.mm +++ b/src/dawn_native/metal/ComputePipelineMTL.mm @@ -43,9 +43,10 @@ namespace dawn_native { namespace metal { newComputePipelineStateWithFunction:computeData.function.Get() error:&error]); if (error != nullptr) { - NSLog(@" error => %@", error); - return DAWN_INTERNAL_ERROR("Error creating pipeline state"); + return DAWN_INTERNAL_ERROR("Error creating pipeline state" + + std::string([error.localizedDescription UTF8String])); } + ASSERT(mMtlComputePipelineState != nil); // Copy over the local workgroup size as it is passed to dispatch explicitly in Metal Origin3D localSize = GetStage(SingleShaderStage::Compute).metadata->localWorkgroupSize; diff --git a/src/dawn_native/metal/QuerySetMTL.mm b/src/dawn_native/metal/QuerySetMTL.mm index 07cd786389..dc06045e20 100644 --- a/src/dawn_native/metal/QuerySetMTL.mm +++ b/src/dawn_native/metal/QuerySetMTL.mm @@ -53,8 +53,8 @@ namespace dawn_native { namespace metal { [device->GetMTLDevice() newCounterSampleBufferWithDescriptor:descriptor error:&error]; if (error != nullptr) { - const char* errorString = [error.localizedDescription UTF8String]; - return DAWN_INTERNAL_ERROR(std::string("Error creating query set: ") + errorString); + return DAWN_OUT_OF_MEMORY_ERROR(std::string("Error creating query set: ") + + [error.localizedDescription UTF8String]); } return counterSampleBuffer; @@ -80,6 +80,10 @@ namespace dawn_native { namespace metal { mVisibilityBuffer = AcquireNSPRef([device->GetMTLDevice() newBufferWithLength:bufferSize options:MTLResourceStorageModePrivate]); + + if (mVisibilityBuffer == nil) { + return DAWN_OUT_OF_MEMORY_ERROR("Failed to allocate query set."); + } break; } case wgpu::QueryType::PipelineStatistics: diff --git a/src/dawn_native/metal/RenderPipelineMTL.mm b/src/dawn_native/metal/RenderPipelineMTL.mm index fb596d4271..9ddcb56c85 100644 --- a/src/dawn_native/metal/RenderPipelineMTL.mm +++ b/src/dawn_native/metal/RenderPipelineMTL.mm @@ -406,20 +406,19 @@ namespace dawn_native { namespace metal { descriptorMTL.sampleCount = GetSampleCount(); descriptorMTL.alphaToCoverageEnabled = IsAlphaToCoverageEnabled(); - { - NSError* error = nullptr; - mMtlRenderPipelineState = - AcquireNSPRef([mtlDevice newRenderPipelineStateWithDescriptor:descriptorMTL - error:&error]); - if (error != nullptr) { - NSLog(@" error => %@", error); - return DAWN_INTERNAL_ERROR("Error creating rendering pipeline state"); - } + NSError* error = nullptr; + mMtlRenderPipelineState = + AcquireNSPRef([mtlDevice newRenderPipelineStateWithDescriptor:descriptorMTL + error:&error]); + if (error != nullptr) { + return DAWN_INTERNAL_ERROR(std::string("Error creating pipeline state") + + [error.localizedDescription UTF8String]); } + ASSERT(mMtlRenderPipelineState != nil); // Create depth stencil state and cache it, fetch the cached depth stencil state when we - // call setDepthStencilState() for a given render pipeline in CommandEncoder, in order to - // improve performance. + // call setDepthStencilState() for a given render pipeline in CommandEncoder, in order + // to improve performance. NSRef depthStencilDesc = MakeDepthStencilDesc(GetDepthStencilState()); mMtlDepthStencilState = diff --git a/src/dawn_native/metal/SamplerMTL.h b/src/dawn_native/metal/SamplerMTL.h index 98565aedf3..274ba2033f 100644 --- a/src/dawn_native/metal/SamplerMTL.h +++ b/src/dawn_native/metal/SamplerMTL.h @@ -33,7 +33,8 @@ namespace dawn_native { namespace metal { id GetMTLSamplerState(); private: - Sampler(Device* device, const SamplerDescriptor* descriptor); + using SamplerBase::SamplerBase; + MaybeError Initialize(const SamplerDescriptor* descriptor); NSPRef> mMtlSamplerState; }; diff --git a/src/dawn_native/metal/SamplerMTL.mm b/src/dawn_native/metal/SamplerMTL.mm index f1c477961f..dae8d75bc1 100644 --- a/src/dawn_native/metal/SamplerMTL.mm +++ b/src/dawn_native/metal/SamplerMTL.mm @@ -58,11 +58,12 @@ namespace dawn_native { namespace metal { return DAWN_VALIDATION_ERROR("Sampler compare function not supported."); } - return AcquireRef(new Sampler(device, descriptor)); + Ref sampler = AcquireRef(new Sampler(device, descriptor)); + DAWN_TRY(sampler->Initialize(descriptor)); + return sampler; } - Sampler::Sampler(Device* device, const SamplerDescriptor* descriptor) - : SamplerBase(device, descriptor) { + MaybeError Sampler::Initialize(const SamplerDescriptor* descriptor) { NSRef mtlDescRef = AcquireNSRef([MTLSamplerDescriptor new]); MTLSamplerDescriptor* mtlDesc = mtlDescRef.Get(); @@ -87,8 +88,13 @@ namespace dawn_native { namespace metal { // Metal debug device errors. } - mMtlSamplerState = - AcquireNSPRef([device->GetMTLDevice() newSamplerStateWithDescriptor:mtlDesc]); + mMtlSamplerState = AcquireNSPRef( + [ToBackend(GetDevice())->GetMTLDevice() newSamplerStateWithDescriptor:mtlDesc]); + + if (mMtlSamplerState == nil) { + return DAWN_OUT_OF_MEMORY_ERROR("Failed to allocate sampler."); + } + return {}; } id Sampler::GetMTLSamplerState() { diff --git a/src/dawn_native/metal/ShaderModuleMTL.mm b/src/dawn_native/metal/ShaderModuleMTL.mm index 439e7839da..d9a9d44f98 100644 --- a/src/dawn_native/metal/ShaderModuleMTL.mm +++ b/src/dawn_native/metal/ShaderModuleMTL.mm @@ -332,11 +332,11 @@ namespace dawn_native { namespace metal { error:&error]); if (error != nullptr) { if (error.code != MTLLibraryErrorCompileWarning) { - const char* errorString = [error.localizedDescription UTF8String]; return DAWN_VALIDATION_ERROR(std::string("Unable to create library object: ") + - errorString); + [error.localizedDescription UTF8String]); } } + ASSERT(library != nil); NSRef name = AcquireNSRef([[NSString alloc] initWithUTF8String:remappedEntryPointName.c_str()]);