diff --git a/src/dawn_native/metal/DeviceMTL.h b/src/dawn_native/metal/DeviceMTL.h index 72c6443df8..442741809b 100644 --- a/src/dawn_native/metal/DeviceMTL.h +++ b/src/dawn_native/metal/DeviceMTL.h @@ -53,7 +53,7 @@ namespace dawn_native { namespace metal { CommandRecordingContext* GetPendingCommandContext(); void SubmitPendingCommandBuffer(); - TextureBase* CreateTextureWrappingIOSurface(const ExternalImageDescriptor* descriptor, + Ref CreateTextureWrappingIOSurface(const ExternalImageDescriptor* descriptor, IOSurfaceRef ioSurface, uint32_t plane); void WaitForCommandsToBeScheduled(); diff --git a/src/dawn_native/metal/DeviceMTL.mm b/src/dawn_native/metal/DeviceMTL.mm index 30e7f2a1db..0359698a25 100644 --- a/src/dawn_native/metal/DeviceMTL.mm +++ b/src/dawn_native/metal/DeviceMTL.mm @@ -409,7 +409,7 @@ namespace dawn_native { namespace metal { return {}; } - TextureBase* Device::CreateTextureWrappingIOSurface(const ExternalImageDescriptor* descriptor, + Ref 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 result; + if (ConsumedError(Texture::CreateFromIOSurface(this, descriptor, ioSurface, plane), + &result)) { + return nullptr; + } + return result; } void Device::WaitForCommandsToBeScheduled() { diff --git a/src/dawn_native/metal/MetalBackend.mm b/src/dawn_native/metal/MetalBackend.mm index 74265a23e9..b8fffaf16c 100644 --- a/src/dawn_native/metal/MetalBackend.mm +++ b/src/dawn_native/metal/MetalBackend.mm @@ -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(cDevice); - TextureBase* texture = device->CreateTextureWrappingIOSurface( + Ref texture = device->CreateTextureWrappingIOSurface( cDescriptor, cDescriptor->ioSurface, cDescriptor->plane); - return reinterpret_cast(texture); + return reinterpret_cast(texture.Detach()); } void WaitForCommandsToBeScheduled(WGPUDevice cDevice) { diff --git a/src/dawn_native/metal/SwapChainMTL.mm b/src/dawn_native/metal/SwapChainMTL.mm index d49ed702dc..84eb649bb0 100644 --- a/src/dawn_native/metal/SwapChainMTL.mm +++ b/src/dawn_native/metal/SwapChainMTL.mm @@ -53,7 +53,8 @@ namespace dawn_native { namespace metal { } id nativeTexture = reinterpret_cast>(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(); } diff --git a/src/dawn_native/metal/TextureMTL.h b/src/dawn_native/metal/TextureMTL.h index c03adbf6f9..07ffe2392c 100644 --- a/src/dawn_native/metal/TextureMTL.h +++ b/src/dawn_native/metal/TextureMTL.h @@ -38,14 +38,14 @@ namespace dawn_native { namespace metal { public: static ResultOrError> Create(Device* device, const TextureDescriptor* descriptor); - - Texture(Device* device, - const TextureDescriptor* descriptor, - NSPRef> mtlTexture); - Texture(Device* device, - const ExternalImageDescriptor* descriptor, - IOSurfaceRef ioSurface, - uint32_t plane); + static ResultOrError> CreateFromIOSurface( + Device* device, + const ExternalImageDescriptor* descriptor, + IOSurfaceRef ioSurface, + uint32_t plane); + static Ref CreateWrapping(Device* device, + const TextureDescriptor* descriptor, + NSPRef> wrapped); id 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> wrapped); + void DestroyImpl() override; MaybeError ClearTexture(CommandRecordingContext* commandContext, @@ -74,7 +82,8 @@ namespace dawn_native { namespace metal { id GetMTLTexture(); private: - TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor); + using TextureViewBase::TextureViewBase; + MaybeError Initialize(const TextureViewDescriptor* descriptor); NSPRef> mMtlTextureView; }; diff --git a/src/dawn_native/metal/TextureMTL.mm b/src/dawn_native/metal/TextureMTL.mm index 8cc642e351..356773808a 100644 --- a/src/dawn_native/metal/TextureMTL.mm +++ b/src/dawn_native/metal/TextureMTL.mm @@ -352,49 +352,82 @@ namespace dawn_native { namespace metal { // static ResultOrError> Texture::Create(Device* device, const TextureDescriptor* descriptor) { - return AcquireRef(new Texture(device, descriptor)); + Ref 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> Texture::CreateFromIOSurface( + Device* device, + const ExternalImageDescriptor* descriptor, + IOSurfaceRef ioSurface, + uint32_t plane) { + const TextureDescriptor* textureDescriptor = + reinterpret_cast(descriptor->cTextureDescriptor); + + Ref texture = + AcquireRef(new Texture(device, textureDescriptor, TextureState::OwnedInternal)); + DAWN_TRY(texture->InitializeFromIOSurface(descriptor, textureDescriptor, ioSurface, plane)); + return texture; + } + + // static + Ref Texture::CreateWrapping(Device* device, + const TextureDescriptor* descriptor, + NSPRef> wrapped) { + Ref 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 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> mtlTexture) - : TextureBase(device, descriptor, TextureState::OwnedInternal), - mMtlTexture(std::move(mtlTexture)) { - NSRef mtlDesc = CreateMetalTextureDescriptor(device, descriptor); + void Texture::InitializeAsWrapping(const TextureDescriptor* descriptor, + NSPRef> wrapped) { + NSRef 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(descriptor->cTextureDescriptor), - TextureState::OwnedInternal) { - NSRef mtlDesc = CreateMetalTextureDescriptor( - device, reinterpret_cast(descriptor->cTextureDescriptor)); + MaybeError Texture::InitializeFromIOSurface(const ExternalImageDescriptor* descriptor, + const TextureDescriptor* textureDescriptor, + IOSurfaceRef ioSurface, + uint32_t plane) { + Device* device = ToBackend(GetDevice()); + + NSRef 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> TextureView::Create(TextureBase* texture, const TextureViewDescriptor* descriptor) { - return AcquireRef(new TextureView(texture, descriptor)); + Ref 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 = ToBackend(texture)->GetMTLTexture(); + MaybeError TextureView::Initialize(const TextureViewDescriptor* descriptor) { + Texture* texture = ToBackend(GetTexture()); + id 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 TextureView::GetMTLTexture() {