mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-06 22:53:35 +00:00
Metal: Handle failures in Texture and TextureView creation.
This includes OOM as well as internal driver failures when creating a view of an MTLTexture. This required changing the code to use the Create-Initialize pattern used everywhere else. Bug: dawn:801 Change-Id: Ib8a8dec74141aacfa58a55bb8201a83351b3b739 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/58721 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Auto-Submit: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Stephen White <senorblanco@chromium.org>
This commit is contained in:
parent
28497129d5
commit
03f9437ae8
@ -53,7 +53,7 @@ namespace dawn_native { namespace metal {
|
|||||||
CommandRecordingContext* GetPendingCommandContext();
|
CommandRecordingContext* GetPendingCommandContext();
|
||||||
void SubmitPendingCommandBuffer();
|
void SubmitPendingCommandBuffer();
|
||||||
|
|
||||||
TextureBase* CreateTextureWrappingIOSurface(const ExternalImageDescriptor* descriptor,
|
Ref<Texture> CreateTextureWrappingIOSurface(const ExternalImageDescriptor* descriptor,
|
||||||
IOSurfaceRef ioSurface,
|
IOSurfaceRef ioSurface,
|
||||||
uint32_t plane);
|
uint32_t plane);
|
||||||
void WaitForCommandsToBeScheduled();
|
void WaitForCommandsToBeScheduled();
|
||||||
|
@ -409,7 +409,7 @@ namespace dawn_native { namespace metal {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureBase* Device::CreateTextureWrappingIOSurface(const ExternalImageDescriptor* descriptor,
|
Ref<Texture> Device::CreateTextureWrappingIOSurface(const ExternalImageDescriptor* descriptor,
|
||||||
IOSurfaceRef ioSurface,
|
IOSurfaceRef ioSurface,
|
||||||
uint32_t plane) {
|
uint32_t plane) {
|
||||||
const TextureDescriptor* textureDescriptor =
|
const TextureDescriptor* textureDescriptor =
|
||||||
@ -423,7 +423,12 @@ namespace dawn_native { namespace metal {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Texture(this, descriptor, ioSurface, plane);
|
Ref<Texture> result;
|
||||||
|
if (ConsumedError(Texture::CreateFromIOSurface(this, descriptor, ioSurface, plane),
|
||||||
|
&result)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::WaitForCommandsToBeScheduled() {
|
void Device::WaitForCommandsToBeScheduled() {
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
|
|
||||||
#include "dawn_native/MetalBackend.h"
|
#include "dawn_native/MetalBackend.h"
|
||||||
|
|
||||||
#include "dawn_native/Texture.h"
|
|
||||||
#include "dawn_native/metal/DeviceMTL.h"
|
#include "dawn_native/metal/DeviceMTL.h"
|
||||||
|
#include "dawn_native/metal/TextureMTL.h"
|
||||||
|
|
||||||
namespace dawn_native { namespace metal {
|
namespace dawn_native { namespace metal {
|
||||||
|
|
||||||
@ -34,9 +34,9 @@ namespace dawn_native { namespace metal {
|
|||||||
WGPUTexture WrapIOSurface(WGPUDevice cDevice,
|
WGPUTexture WrapIOSurface(WGPUDevice cDevice,
|
||||||
const ExternalImageDescriptorIOSurface* cDescriptor) {
|
const ExternalImageDescriptorIOSurface* cDescriptor) {
|
||||||
Device* device = reinterpret_cast<Device*>(cDevice);
|
Device* device = reinterpret_cast<Device*>(cDevice);
|
||||||
TextureBase* texture = device->CreateTextureWrappingIOSurface(
|
Ref<TextureBase> texture = device->CreateTextureWrappingIOSurface(
|
||||||
cDescriptor, cDescriptor->ioSurface, cDescriptor->plane);
|
cDescriptor, cDescriptor->ioSurface, cDescriptor->plane);
|
||||||
return reinterpret_cast<WGPUTexture>(texture);
|
return reinterpret_cast<WGPUTexture>(texture.Detach());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaitForCommandsToBeScheduled(WGPUDevice cDevice) {
|
void WaitForCommandsToBeScheduled(WGPUDevice cDevice) {
|
||||||
|
@ -53,7 +53,8 @@ namespace dawn_native { namespace metal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
id<MTLTexture> nativeTexture = reinterpret_cast<id<MTLTexture>>(next.texture.ptr);
|
id<MTLTexture> nativeTexture = reinterpret_cast<id<MTLTexture>>(next.texture.ptr);
|
||||||
return new Texture(ToBackend(GetDevice()), descriptor, nativeTexture);
|
|
||||||
|
return Texture::CreateWrapping(ToBackend(GetDevice()), descriptor, nativeTexture).Detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeError OldSwapChain::OnBeforePresent(TextureViewBase*) {
|
MaybeError OldSwapChain::OnBeforePresent(TextureViewBase*) {
|
||||||
@ -131,9 +132,8 @@ namespace dawn_native { namespace metal {
|
|||||||
|
|
||||||
TextureDescriptor textureDesc = GetSwapChainBaseTextureDescriptor(this);
|
TextureDescriptor textureDesc = GetSwapChainBaseTextureDescriptor(this);
|
||||||
|
|
||||||
// TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
|
mTexture = Texture::CreateWrapping(ToBackend(GetDevice()), &textureDesc,
|
||||||
mTexture = AcquireRef(
|
[*mCurrentDrawable texture]);
|
||||||
new Texture(ToBackend(GetDevice()), &textureDesc, [*mCurrentDrawable texture]));
|
|
||||||
// TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
|
// TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
|
||||||
return mTexture->APICreateView();
|
return mTexture->APICreateView();
|
||||||
}
|
}
|
||||||
|
@ -38,14 +38,14 @@ namespace dawn_native { namespace metal {
|
|||||||
public:
|
public:
|
||||||
static ResultOrError<Ref<Texture>> Create(Device* device,
|
static ResultOrError<Ref<Texture>> Create(Device* device,
|
||||||
const TextureDescriptor* descriptor);
|
const TextureDescriptor* descriptor);
|
||||||
|
static ResultOrError<Ref<Texture>> CreateFromIOSurface(
|
||||||
Texture(Device* device,
|
Device* device,
|
||||||
const TextureDescriptor* descriptor,
|
const ExternalImageDescriptor* descriptor,
|
||||||
NSPRef<id<MTLTexture>> mtlTexture);
|
IOSurfaceRef ioSurface,
|
||||||
Texture(Device* device,
|
uint32_t plane);
|
||||||
const ExternalImageDescriptor* descriptor,
|
static Ref<Texture> CreateWrapping(Device* device,
|
||||||
IOSurfaceRef ioSurface,
|
const TextureDescriptor* descriptor,
|
||||||
uint32_t plane);
|
NSPRef<id<MTLTexture>> wrapped);
|
||||||
|
|
||||||
id<MTLTexture> GetMTLTexture();
|
id<MTLTexture> GetMTLTexture();
|
||||||
|
|
||||||
@ -53,9 +53,17 @@ namespace dawn_native { namespace metal {
|
|||||||
const SubresourceRange& range);
|
const SubresourceRange& range);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Texture(Device* device, const TextureDescriptor* descriptor);
|
using TextureBase::TextureBase;
|
||||||
~Texture() override;
|
~Texture() override;
|
||||||
|
|
||||||
|
MaybeError InitializeAsInternalTexture(const TextureDescriptor* descriptor);
|
||||||
|
MaybeError InitializeFromIOSurface(const ExternalImageDescriptor* descriptor,
|
||||||
|
const TextureDescriptor* textureDescriptor,
|
||||||
|
IOSurfaceRef ioSurface,
|
||||||
|
uint32_t plane);
|
||||||
|
void InitializeAsWrapping(const TextureDescriptor* descriptor,
|
||||||
|
NSPRef<id<MTLTexture>> wrapped);
|
||||||
|
|
||||||
void DestroyImpl() override;
|
void DestroyImpl() override;
|
||||||
|
|
||||||
MaybeError ClearTexture(CommandRecordingContext* commandContext,
|
MaybeError ClearTexture(CommandRecordingContext* commandContext,
|
||||||
@ -74,7 +82,8 @@ namespace dawn_native { namespace metal {
|
|||||||
id<MTLTexture> GetMTLTexture();
|
id<MTLTexture> GetMTLTexture();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor);
|
using TextureViewBase::TextureViewBase;
|
||||||
|
MaybeError Initialize(const TextureViewDescriptor* descriptor);
|
||||||
|
|
||||||
NSPRef<id<MTLTexture>> mMtlTextureView;
|
NSPRef<id<MTLTexture>> mMtlTextureView;
|
||||||
};
|
};
|
||||||
|
@ -352,49 +352,82 @@ namespace dawn_native { namespace metal {
|
|||||||
// static
|
// static
|
||||||
ResultOrError<Ref<Texture>> Texture::Create(Device* device,
|
ResultOrError<Ref<Texture>> Texture::Create(Device* device,
|
||||||
const TextureDescriptor* descriptor) {
|
const TextureDescriptor* descriptor) {
|
||||||
return AcquireRef(new Texture(device, descriptor));
|
Ref<Texture> texture =
|
||||||
|
AcquireRef(new Texture(device, descriptor, TextureState::OwnedInternal));
|
||||||
|
DAWN_TRY(texture->InitializeAsInternalTexture(descriptor));
|
||||||
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::Texture(Device* device, const TextureDescriptor* descriptor)
|
// static
|
||||||
: TextureBase(device, descriptor, TextureState::OwnedInternal) {
|
ResultOrError<Ref<Texture>> Texture::CreateFromIOSurface(
|
||||||
|
Device* device,
|
||||||
|
const ExternalImageDescriptor* descriptor,
|
||||||
|
IOSurfaceRef ioSurface,
|
||||||
|
uint32_t plane) {
|
||||||
|
const TextureDescriptor* textureDescriptor =
|
||||||
|
reinterpret_cast<const TextureDescriptor*>(descriptor->cTextureDescriptor);
|
||||||
|
|
||||||
|
Ref<Texture> texture =
|
||||||
|
AcquireRef(new Texture(device, textureDescriptor, TextureState::OwnedInternal));
|
||||||
|
DAWN_TRY(texture->InitializeFromIOSurface(descriptor, textureDescriptor, ioSurface, plane));
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
Ref<Texture> Texture::CreateWrapping(Device* device,
|
||||||
|
const TextureDescriptor* descriptor,
|
||||||
|
NSPRef<id<MTLTexture>> wrapped) {
|
||||||
|
Ref<Texture> texture =
|
||||||
|
AcquireRef(new Texture(device, descriptor, TextureState::OwnedInternal));
|
||||||
|
texture->InitializeAsWrapping(descriptor, std::move(wrapped));
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
MaybeError Texture::InitializeAsInternalTexture(const TextureDescriptor* descriptor) {
|
||||||
|
Device* device = ToBackend(GetDevice());
|
||||||
|
|
||||||
NSRef<MTLTextureDescriptor> mtlDesc = CreateMetalTextureDescriptor(device, descriptor);
|
NSRef<MTLTextureDescriptor> mtlDesc = CreateMetalTextureDescriptor(device, descriptor);
|
||||||
|
mMtlUsage = [*mtlDesc usage];
|
||||||
mMtlTexture =
|
mMtlTexture =
|
||||||
AcquireNSPRef([device->GetMTLDevice() newTextureWithDescriptor:mtlDesc.Get()]);
|
AcquireNSPRef([device->GetMTLDevice() newTextureWithDescriptor:mtlDesc.Get()]);
|
||||||
mMtlUsage = [*mtlDesc usage];
|
|
||||||
|
if (mMtlTexture == nil) {
|
||||||
|
return DAWN_OUT_OF_MEMORY_ERROR("Failed to allocate texture.");
|
||||||
|
}
|
||||||
|
|
||||||
if (device->IsToggleEnabled(Toggle::NonzeroClearResourcesOnCreationForTesting)) {
|
if (device->IsToggleEnabled(Toggle::NonzeroClearResourcesOnCreationForTesting)) {
|
||||||
device->ConsumedError(ClearTexture(device->GetPendingCommandContext(),
|
DAWN_TRY(ClearTexture(device->GetPendingCommandContext(), GetAllSubresources(),
|
||||||
GetAllSubresources(),
|
TextureBase::ClearValue::NonZero));
|
||||||
TextureBase::ClearValue::NonZero));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::Texture(Device* device,
|
void Texture::InitializeAsWrapping(const TextureDescriptor* descriptor,
|
||||||
const TextureDescriptor* descriptor,
|
NSPRef<id<MTLTexture>> wrapped) {
|
||||||
NSPRef<id<MTLTexture>> mtlTexture)
|
NSRef<MTLTextureDescriptor> mtlDesc = CreateMetalTextureDescriptor(GetDevice(), descriptor);
|
||||||
: TextureBase(device, descriptor, TextureState::OwnedInternal),
|
|
||||||
mMtlTexture(std::move(mtlTexture)) {
|
|
||||||
NSRef<MTLTextureDescriptor> mtlDesc = CreateMetalTextureDescriptor(device, descriptor);
|
|
||||||
mMtlUsage = [*mtlDesc usage];
|
mMtlUsage = [*mtlDesc usage];
|
||||||
|
mMtlTexture = std::move(wrapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::Texture(Device* device,
|
MaybeError Texture::InitializeFromIOSurface(const ExternalImageDescriptor* descriptor,
|
||||||
const ExternalImageDescriptor* descriptor,
|
const TextureDescriptor* textureDescriptor,
|
||||||
IOSurfaceRef ioSurface,
|
IOSurfaceRef ioSurface,
|
||||||
uint32_t plane)
|
uint32_t plane) {
|
||||||
: TextureBase(device,
|
Device* device = ToBackend(GetDevice());
|
||||||
reinterpret_cast<const TextureDescriptor*>(descriptor->cTextureDescriptor),
|
|
||||||
TextureState::OwnedInternal) {
|
NSRef<MTLTextureDescriptor> mtlDesc =
|
||||||
NSRef<MTLTextureDescriptor> mtlDesc = CreateMetalTextureDescriptor(
|
CreateMetalTextureDescriptor(device, textureDescriptor);
|
||||||
device, reinterpret_cast<const TextureDescriptor*>(descriptor->cTextureDescriptor));
|
|
||||||
[*mtlDesc setStorageMode:kIOSurfaceStorageMode];
|
[*mtlDesc setStorageMode:kIOSurfaceStorageMode];
|
||||||
|
|
||||||
|
mMtlUsage = [*mtlDesc usage];
|
||||||
mMtlTexture = AcquireNSPRef([device->GetMTLDevice() newTextureWithDescriptor:mtlDesc.Get()
|
mMtlTexture = AcquireNSPRef([device->GetMTLDevice() newTextureWithDescriptor:mtlDesc.Get()
|
||||||
iosurface:ioSurface
|
iosurface:ioSurface
|
||||||
plane:plane]);
|
plane:plane]);
|
||||||
mMtlUsage = [*mtlDesc usage];
|
|
||||||
|
|
||||||
SetIsSubresourceContentInitialized(descriptor->isInitialized, GetAllSubresources());
|
SetIsSubresourceContentInitialized(descriptor->isInitialized, GetAllSubresources());
|
||||||
|
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::~Texture() {
|
Texture::~Texture() {
|
||||||
@ -625,12 +658,14 @@ namespace dawn_native { namespace metal {
|
|||||||
// static
|
// static
|
||||||
ResultOrError<Ref<TextureView>> TextureView::Create(TextureBase* texture,
|
ResultOrError<Ref<TextureView>> TextureView::Create(TextureBase* texture,
|
||||||
const TextureViewDescriptor* descriptor) {
|
const TextureViewDescriptor* descriptor) {
|
||||||
return AcquireRef(new TextureView(texture, descriptor));
|
Ref<TextureView> view = AcquireRef(new TextureView(texture, descriptor));
|
||||||
|
DAWN_TRY(view->Initialize(descriptor));
|
||||||
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureView::TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor)
|
MaybeError TextureView::Initialize(const TextureViewDescriptor* descriptor) {
|
||||||
: TextureViewBase(texture, descriptor) {
|
Texture* texture = ToBackend(GetTexture());
|
||||||
id<MTLTexture> mtlTexture = ToBackend(texture)->GetMTLTexture();
|
id<MTLTexture> mtlTexture = texture->GetMTLTexture();
|
||||||
|
|
||||||
if (!UsageNeedsTextureView(texture->GetUsage())) {
|
if (!UsageNeedsTextureView(texture->GetUsage())) {
|
||||||
mMtlTextureView = nullptr;
|
mMtlTextureView = nullptr;
|
||||||
@ -663,7 +698,12 @@ namespace dawn_native { namespace metal {
|
|||||||
textureType:textureViewType
|
textureType:textureViewType
|
||||||
levels:mipLevelRange
|
levels:mipLevelRange
|
||||||
slices:arrayLayerRange]);
|
slices:arrayLayerRange]);
|
||||||
|
if (mMtlTextureView == nil) {
|
||||||
|
return DAWN_INTERNAL_ERROR("Failed to create MTLTexture view.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
id<MTLTexture> TextureView::GetMTLTexture() {
|
id<MTLTexture> TextureView::GetMTLTexture() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user