Metal: Handle potential OOM in other places.
This commit adds checks to (hopefully) all the remaining places in the Metal backend where object creation can fail. Bug: dawn:801 Change-Id: Ic27803e956beef822f94ca8449f7816ddd17c1bc Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/58722 Commit-Queue: Stephen White <senorblanco@chromium.org> Auto-Submit: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org> Reviewed-by: Stephen White <senorblanco@chromium.org>
This commit is contained in:
parent
b24e1320fc
commit
02a603b613
|
@ -223,7 +223,8 @@ namespace dawn_native { namespace metal {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper functions for Toggle AlwaysResolveIntoZeroLevelAndLayer
|
// Helper functions for Toggle AlwaysResolveIntoZeroLevelAndLayer
|
||||||
NSPRef<id<MTLTexture>> CreateResolveTextureForWorkaround(Device* device,
|
ResultOrError<NSPRef<id<MTLTexture>>> CreateResolveTextureForWorkaround(
|
||||||
|
Device* device,
|
||||||
MTLPixelFormat mtlFormat,
|
MTLPixelFormat mtlFormat,
|
||||||
uint32_t width,
|
uint32_t width,
|
||||||
uint32_t height) {
|
uint32_t height) {
|
||||||
|
@ -241,7 +242,12 @@ namespace dawn_native { namespace metal {
|
||||||
mtlDesc.storageMode = MTLStorageModePrivate;
|
mtlDesc.storageMode = MTLStorageModePrivate;
|
||||||
mtlDesc.sampleCount = 1;
|
mtlDesc.sampleCount = 1;
|
||||||
|
|
||||||
return AcquireNSPRef([device->GetMTLDevice() newTextureWithDescriptor:mtlDesc]);
|
id<MTLTexture> 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,
|
void CopyIntoTrueResolveTarget(CommandRecordingContext* commandContext,
|
||||||
|
@ -1144,8 +1150,8 @@ namespace dawn_native { namespace metal {
|
||||||
trueResolveSlices[i] = mtlRenderPass.colorAttachments[i].resolveSlice;
|
trueResolveSlices[i] = mtlRenderPass.colorAttachments[i].resolveSlice;
|
||||||
|
|
||||||
const MTLPixelFormat mtlFormat = trueResolveTextures[i].pixelFormat;
|
const MTLPixelFormat mtlFormat = trueResolveTextures[i].pixelFormat;
|
||||||
temporaryResolveTextures[i] =
|
DAWN_TRY_ASSIGN(temporaryResolveTextures[i], CreateResolveTextureForWorkaround(
|
||||||
CreateResolveTextureForWorkaround(device, mtlFormat, width, height);
|
device, mtlFormat, width, height));
|
||||||
|
|
||||||
mtlRenderPass.colorAttachments[i].resolveTexture =
|
mtlRenderPass.colorAttachments[i].resolveTexture =
|
||||||
temporaryResolveTextures[i].Get();
|
temporaryResolveTextures[i].Get();
|
||||||
|
|
|
@ -43,9 +43,10 @@ namespace dawn_native { namespace metal {
|
||||||
newComputePipelineStateWithFunction:computeData.function.Get()
|
newComputePipelineStateWithFunction:computeData.function.Get()
|
||||||
error:&error]);
|
error:&error]);
|
||||||
if (error != nullptr) {
|
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
|
// Copy over the local workgroup size as it is passed to dispatch explicitly in Metal
|
||||||
Origin3D localSize = GetStage(SingleShaderStage::Compute).metadata->localWorkgroupSize;
|
Origin3D localSize = GetStage(SingleShaderStage::Compute).metadata->localWorkgroupSize;
|
||||||
|
|
|
@ -53,8 +53,8 @@ namespace dawn_native { namespace metal {
|
||||||
[device->GetMTLDevice() newCounterSampleBufferWithDescriptor:descriptor
|
[device->GetMTLDevice() newCounterSampleBufferWithDescriptor:descriptor
|
||||||
error:&error];
|
error:&error];
|
||||||
if (error != nullptr) {
|
if (error != nullptr) {
|
||||||
const char* errorString = [error.localizedDescription UTF8String];
|
return DAWN_OUT_OF_MEMORY_ERROR(std::string("Error creating query set: ") +
|
||||||
return DAWN_INTERNAL_ERROR(std::string("Error creating query set: ") + errorString);
|
[error.localizedDescription UTF8String]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return counterSampleBuffer;
|
return counterSampleBuffer;
|
||||||
|
@ -80,6 +80,10 @@ namespace dawn_native { namespace metal {
|
||||||
mVisibilityBuffer = AcquireNSPRef([device->GetMTLDevice()
|
mVisibilityBuffer = AcquireNSPRef([device->GetMTLDevice()
|
||||||
newBufferWithLength:bufferSize
|
newBufferWithLength:bufferSize
|
||||||
options:MTLResourceStorageModePrivate]);
|
options:MTLResourceStorageModePrivate]);
|
||||||
|
|
||||||
|
if (mVisibilityBuffer == nil) {
|
||||||
|
return DAWN_OUT_OF_MEMORY_ERROR("Failed to allocate query set.");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case wgpu::QueryType::PipelineStatistics:
|
case wgpu::QueryType::PipelineStatistics:
|
||||||
|
|
|
@ -406,20 +406,19 @@ namespace dawn_native { namespace metal {
|
||||||
descriptorMTL.sampleCount = GetSampleCount();
|
descriptorMTL.sampleCount = GetSampleCount();
|
||||||
descriptorMTL.alphaToCoverageEnabled = IsAlphaToCoverageEnabled();
|
descriptorMTL.alphaToCoverageEnabled = IsAlphaToCoverageEnabled();
|
||||||
|
|
||||||
{
|
|
||||||
NSError* error = nullptr;
|
NSError* error = nullptr;
|
||||||
mMtlRenderPipelineState =
|
mMtlRenderPipelineState =
|
||||||
AcquireNSPRef([mtlDevice newRenderPipelineStateWithDescriptor:descriptorMTL
|
AcquireNSPRef([mtlDevice newRenderPipelineStateWithDescriptor:descriptorMTL
|
||||||
error:&error]);
|
error:&error]);
|
||||||
if (error != nullptr) {
|
if (error != nullptr) {
|
||||||
NSLog(@" error => %@", error);
|
return DAWN_INTERNAL_ERROR(std::string("Error creating pipeline state") +
|
||||||
return DAWN_INTERNAL_ERROR("Error creating rendering pipeline state");
|
[error.localizedDescription UTF8String]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
ASSERT(mMtlRenderPipelineState != nil);
|
||||||
|
|
||||||
// Create depth stencil state and cache it, fetch the cached depth stencil state when we
|
// 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
|
// call setDepthStencilState() for a given render pipeline in CommandEncoder, in order
|
||||||
// improve performance.
|
// to improve performance.
|
||||||
NSRef<MTLDepthStencilDescriptor> depthStencilDesc =
|
NSRef<MTLDepthStencilDescriptor> depthStencilDesc =
|
||||||
MakeDepthStencilDesc(GetDepthStencilState());
|
MakeDepthStencilDesc(GetDepthStencilState());
|
||||||
mMtlDepthStencilState =
|
mMtlDepthStencilState =
|
||||||
|
|
|
@ -33,7 +33,8 @@ namespace dawn_native { namespace metal {
|
||||||
id<MTLSamplerState> GetMTLSamplerState();
|
id<MTLSamplerState> GetMTLSamplerState();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Sampler(Device* device, const SamplerDescriptor* descriptor);
|
using SamplerBase::SamplerBase;
|
||||||
|
MaybeError Initialize(const SamplerDescriptor* descriptor);
|
||||||
|
|
||||||
NSPRef<id<MTLSamplerState>> mMtlSamplerState;
|
NSPRef<id<MTLSamplerState>> mMtlSamplerState;
|
||||||
};
|
};
|
||||||
|
|
|
@ -58,11 +58,12 @@ namespace dawn_native { namespace metal {
|
||||||
return DAWN_VALIDATION_ERROR("Sampler compare function not supported.");
|
return DAWN_VALIDATION_ERROR("Sampler compare function not supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return AcquireRef(new Sampler(device, descriptor));
|
Ref<Sampler> sampler = AcquireRef(new Sampler(device, descriptor));
|
||||||
|
DAWN_TRY(sampler->Initialize(descriptor));
|
||||||
|
return sampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sampler::Sampler(Device* device, const SamplerDescriptor* descriptor)
|
MaybeError Sampler::Initialize(const SamplerDescriptor* descriptor) {
|
||||||
: SamplerBase(device, descriptor) {
|
|
||||||
NSRef<MTLSamplerDescriptor> mtlDescRef = AcquireNSRef([MTLSamplerDescriptor new]);
|
NSRef<MTLSamplerDescriptor> mtlDescRef = AcquireNSRef([MTLSamplerDescriptor new]);
|
||||||
MTLSamplerDescriptor* mtlDesc = mtlDescRef.Get();
|
MTLSamplerDescriptor* mtlDesc = mtlDescRef.Get();
|
||||||
|
|
||||||
|
@ -87,8 +88,13 @@ namespace dawn_native { namespace metal {
|
||||||
// Metal debug device errors.
|
// Metal debug device errors.
|
||||||
}
|
}
|
||||||
|
|
||||||
mMtlSamplerState =
|
mMtlSamplerState = AcquireNSPRef(
|
||||||
AcquireNSPRef([device->GetMTLDevice() newSamplerStateWithDescriptor:mtlDesc]);
|
[ToBackend(GetDevice())->GetMTLDevice() newSamplerStateWithDescriptor:mtlDesc]);
|
||||||
|
|
||||||
|
if (mMtlSamplerState == nil) {
|
||||||
|
return DAWN_OUT_OF_MEMORY_ERROR("Failed to allocate sampler.");
|
||||||
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
id<MTLSamplerState> Sampler::GetMTLSamplerState() {
|
id<MTLSamplerState> Sampler::GetMTLSamplerState() {
|
||||||
|
|
|
@ -332,11 +332,11 @@ namespace dawn_native { namespace metal {
|
||||||
error:&error]);
|
error:&error]);
|
||||||
if (error != nullptr) {
|
if (error != nullptr) {
|
||||||
if (error.code != MTLLibraryErrorCompileWarning) {
|
if (error.code != MTLLibraryErrorCompileWarning) {
|
||||||
const char* errorString = [error.localizedDescription UTF8String];
|
|
||||||
return DAWN_VALIDATION_ERROR(std::string("Unable to create library object: ") +
|
return DAWN_VALIDATION_ERROR(std::string("Unable to create library object: ") +
|
||||||
errorString);
|
[error.localizedDescription UTF8String]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ASSERT(library != nil);
|
||||||
|
|
||||||
NSRef<NSString> name =
|
NSRef<NSString> name =
|
||||||
AcquireNSRef([[NSString alloc] initWithUTF8String:remappedEntryPointName.c_str()]);
|
AcquireNSRef([[NSString alloc] initWithUTF8String:remappedEntryPointName.c_str()]);
|
||||||
|
|
Loading…
Reference in New Issue