mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-05 14:13:39 +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();
|
||||
void SubmitPendingCommandBuffer();
|
||||
|
||||
TextureBase* CreateTextureWrappingIOSurface(const ExternalImageDescriptor* descriptor,
|
||||
Ref<Texture> CreateTextureWrappingIOSurface(const ExternalImageDescriptor* descriptor,
|
||||
IOSurfaceRef ioSurface,
|
||||
uint32_t plane);
|
||||
void WaitForCommandsToBeScheduled();
|
||||
|
@ -409,7 +409,7 @@ namespace dawn_native { namespace metal {
|
||||
return {};
|
||||
}
|
||||
|
||||
TextureBase* Device::CreateTextureWrappingIOSurface(const ExternalImageDescriptor* descriptor,
|
||||
Ref<Texture> Device::CreateTextureWrappingIOSurface(const ExternalImageDescriptor* descriptor,
|
||||
IOSurfaceRef ioSurface,
|
||||
uint32_t plane) {
|
||||
const TextureDescriptor* textureDescriptor =
|
||||
@ -423,7 +423,12 @@ namespace dawn_native { namespace metal {
|
||||
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() {
|
||||
|
@ -17,8 +17,8 @@
|
||||
|
||||
#include "dawn_native/MetalBackend.h"
|
||||
|
||||
#include "dawn_native/Texture.h"
|
||||
#include "dawn_native/metal/DeviceMTL.h"
|
||||
#include "dawn_native/metal/TextureMTL.h"
|
||||
|
||||
namespace dawn_native { namespace metal {
|
||||
|
||||
@ -34,9 +34,9 @@ namespace dawn_native { namespace metal {
|
||||
WGPUTexture WrapIOSurface(WGPUDevice cDevice,
|
||||
const ExternalImageDescriptorIOSurface* cDescriptor) {
|
||||
Device* device = reinterpret_cast<Device*>(cDevice);
|
||||
TextureBase* texture = device->CreateTextureWrappingIOSurface(
|
||||
Ref<TextureBase> texture = device->CreateTextureWrappingIOSurface(
|
||||
cDescriptor, cDescriptor->ioSurface, cDescriptor->plane);
|
||||
return reinterpret_cast<WGPUTexture>(texture);
|
||||
return reinterpret_cast<WGPUTexture>(texture.Detach());
|
||||
}
|
||||
|
||||
void WaitForCommandsToBeScheduled(WGPUDevice cDevice) {
|
||||
|
@ -53,7 +53,8 @@ namespace dawn_native { namespace metal {
|
||||
}
|
||||
|
||||
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*) {
|
||||
@ -131,9 +132,8 @@ namespace dawn_native { namespace metal {
|
||||
|
||||
TextureDescriptor textureDesc = GetSwapChainBaseTextureDescriptor(this);
|
||||
|
||||
// TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
|
||||
mTexture = AcquireRef(
|
||||
new Texture(ToBackend(GetDevice()), &textureDesc, [*mCurrentDrawable texture]));
|
||||
mTexture = Texture::CreateWrapping(ToBackend(GetDevice()), &textureDesc,
|
||||
[*mCurrentDrawable texture]);
|
||||
// TODO(dawn:723): change to not use AcquireRef for reentrant object creation.
|
||||
return mTexture->APICreateView();
|
||||
}
|
||||
|
@ -38,14 +38,14 @@ namespace dawn_native { namespace metal {
|
||||
public:
|
||||
static ResultOrError<Ref<Texture>> Create(Device* device,
|
||||
const TextureDescriptor* descriptor);
|
||||
|
||||
Texture(Device* device,
|
||||
const TextureDescriptor* descriptor,
|
||||
NSPRef<id<MTLTexture>> mtlTexture);
|
||||
Texture(Device* device,
|
||||
const ExternalImageDescriptor* descriptor,
|
||||
IOSurfaceRef ioSurface,
|
||||
uint32_t plane);
|
||||
static ResultOrError<Ref<Texture>> CreateFromIOSurface(
|
||||
Device* device,
|
||||
const ExternalImageDescriptor* descriptor,
|
||||
IOSurfaceRef ioSurface,
|
||||
uint32_t plane);
|
||||
static Ref<Texture> CreateWrapping(Device* device,
|
||||
const TextureDescriptor* descriptor,
|
||||
NSPRef<id<MTLTexture>> wrapped);
|
||||
|
||||
id<MTLTexture> GetMTLTexture();
|
||||
|
||||
@ -53,9 +53,17 @@ namespace dawn_native { namespace metal {
|
||||
const SubresourceRange& range);
|
||||
|
||||
private:
|
||||
Texture(Device* device, const TextureDescriptor* descriptor);
|
||||
using TextureBase::TextureBase;
|
||||
~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;
|
||||
|
||||
MaybeError ClearTexture(CommandRecordingContext* commandContext,
|
||||
@ -74,7 +82,8 @@ namespace dawn_native { namespace metal {
|
||||
id<MTLTexture> GetMTLTexture();
|
||||
|
||||
private:
|
||||
TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor);
|
||||
using TextureViewBase::TextureViewBase;
|
||||
MaybeError Initialize(const TextureViewDescriptor* descriptor);
|
||||
|
||||
NSPRef<id<MTLTexture>> mMtlTextureView;
|
||||
};
|
||||
|
@ -352,49 +352,82 @@ namespace dawn_native { namespace metal {
|
||||
// static
|
||||
ResultOrError<Ref<Texture>> Texture::Create(Device* device,
|
||||
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)
|
||||
: TextureBase(device, descriptor, TextureState::OwnedInternal) {
|
||||
// static
|
||||
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);
|
||||
mMtlUsage = [*mtlDesc usage];
|
||||
mMtlTexture =
|
||||
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)) {
|
||||
device->ConsumedError(ClearTexture(device->GetPendingCommandContext(),
|
||||
GetAllSubresources(),
|
||||
TextureBase::ClearValue::NonZero));
|
||||
DAWN_TRY(ClearTexture(device->GetPendingCommandContext(), GetAllSubresources(),
|
||||
TextureBase::ClearValue::NonZero));
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Texture::Texture(Device* device,
|
||||
const TextureDescriptor* descriptor,
|
||||
NSPRef<id<MTLTexture>> mtlTexture)
|
||||
: TextureBase(device, descriptor, TextureState::OwnedInternal),
|
||||
mMtlTexture(std::move(mtlTexture)) {
|
||||
NSRef<MTLTextureDescriptor> mtlDesc = CreateMetalTextureDescriptor(device, descriptor);
|
||||
void Texture::InitializeAsWrapping(const TextureDescriptor* descriptor,
|
||||
NSPRef<id<MTLTexture>> wrapped) {
|
||||
NSRef<MTLTextureDescriptor> mtlDesc = CreateMetalTextureDescriptor(GetDevice(), descriptor);
|
||||
mMtlUsage = [*mtlDesc usage];
|
||||
mMtlTexture = std::move(wrapped);
|
||||
}
|
||||
|
||||
Texture::Texture(Device* device,
|
||||
const ExternalImageDescriptor* descriptor,
|
||||
IOSurfaceRef ioSurface,
|
||||
uint32_t plane)
|
||||
: TextureBase(device,
|
||||
reinterpret_cast<const TextureDescriptor*>(descriptor->cTextureDescriptor),
|
||||
TextureState::OwnedInternal) {
|
||||
NSRef<MTLTextureDescriptor> mtlDesc = CreateMetalTextureDescriptor(
|
||||
device, reinterpret_cast<const TextureDescriptor*>(descriptor->cTextureDescriptor));
|
||||
MaybeError Texture::InitializeFromIOSurface(const ExternalImageDescriptor* descriptor,
|
||||
const TextureDescriptor* textureDescriptor,
|
||||
IOSurfaceRef ioSurface,
|
||||
uint32_t plane) {
|
||||
Device* device = ToBackend(GetDevice());
|
||||
|
||||
NSRef<MTLTextureDescriptor> mtlDesc =
|
||||
CreateMetalTextureDescriptor(device, textureDescriptor);
|
||||
[*mtlDesc setStorageMode:kIOSurfaceStorageMode];
|
||||
|
||||
mMtlUsage = [*mtlDesc usage];
|
||||
mMtlTexture = AcquireNSPRef([device->GetMTLDevice() newTextureWithDescriptor:mtlDesc.Get()
|
||||
iosurface:ioSurface
|
||||
plane:plane]);
|
||||
mMtlUsage = [*mtlDesc usage];
|
||||
|
||||
SetIsSubresourceContentInitialized(descriptor->isInitialized, GetAllSubresources());
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Texture::~Texture() {
|
||||
@ -625,12 +658,14 @@ namespace dawn_native { namespace metal {
|
||||
// static
|
||||
ResultOrError<Ref<TextureView>> TextureView::Create(TextureBase* texture,
|
||||
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)
|
||||
: TextureViewBase(texture, descriptor) {
|
||||
id<MTLTexture> mtlTexture = ToBackend(texture)->GetMTLTexture();
|
||||
MaybeError TextureView::Initialize(const TextureViewDescriptor* descriptor) {
|
||||
Texture* texture = ToBackend(GetTexture());
|
||||
id<MTLTexture> mtlTexture = texture->GetMTLTexture();
|
||||
|
||||
if (!UsageNeedsTextureView(texture->GetUsage())) {
|
||||
mMtlTextureView = nullptr;
|
||||
@ -663,7 +698,12 @@ namespace dawn_native { namespace metal {
|
||||
textureType:textureViewType
|
||||
levels:mipLevelRange
|
||||
slices:arrayLayerRange]);
|
||||
if (mMtlTextureView == nil) {
|
||||
return DAWN_INTERNAL_ERROR("Failed to create MTLTexture view.");
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
id<MTLTexture> TextureView::GetMTLTexture() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user