From 261869609fc566e74bc989919d5a204c76421f66 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Tue, 5 Mar 2019 20:01:30 -0800 Subject: Fixed Metal backend stub --- Graphics/GraphicsEngineMetal/CMakeLists.txt | 7 +- .../interface/EngineFactoryMtl.h | 66 ++++++ .../interface/EngineMtlAttribs.h | 38 ---- .../interface/RenderDeviceFactoryMtl.h | 66 ------ .../GraphicsEngineMetal/src/EngineFactoryMtl.mm | 249 +++++++++++++++++++++ .../src/RenderDeviceFactoryMtl.mm | 249 --------------------- 6 files changed, 318 insertions(+), 357 deletions(-) create mode 100644 Graphics/GraphicsEngineMetal/interface/EngineFactoryMtl.h delete mode 100644 Graphics/GraphicsEngineMetal/interface/EngineMtlAttribs.h delete mode 100644 Graphics/GraphicsEngineMetal/interface/RenderDeviceFactoryMtl.h create mode 100644 Graphics/GraphicsEngineMetal/src/EngineFactoryMtl.mm delete mode 100644 Graphics/GraphicsEngineMetal/src/RenderDeviceFactoryMtl.mm (limited to 'Graphics/GraphicsEngineMetal') diff --git a/Graphics/GraphicsEngineMetal/CMakeLists.txt b/Graphics/GraphicsEngineMetal/CMakeLists.txt index 6a2bb29d..294d7276 100644 --- a/Graphics/GraphicsEngineMetal/CMakeLists.txt +++ b/Graphics/GraphicsEngineMetal/CMakeLists.txt @@ -9,7 +9,7 @@ set(INCLUDE include/CommandListMtlImpl.h include/MtlTypeConversions.h include/DeviceContextMtlImpl.h - include/FenceMtlImpl.h + include/FenceMtlImpl.h include/PipelineStateMtlImpl.h include/RenderDeviceMtlImpl.h include/SamplerMtlImpl.h @@ -24,11 +24,10 @@ set(INTERFACE interface/BufferMtl.h interface/BufferViewMtl.h interface/DeviceContextMtl.h - interface/EngineMtlAttribs.h + interface/EngineFactoryMtl.h interface/FenceMtl.h interface/PipelineStateMtl.h interface/RenderDeviceMtl.h - interface/RenderDeviceFactoryMtl.h interface/SamplerMtl.h interface/ShaderMtl.h interface/ShaderResourceBindingMtl.h @@ -44,10 +43,10 @@ set(SRC src/CommandListMtlImpl.mm src/MtlTypeConversions.mm src/DeviceContextMtlImpl.mm + src/EngineFactoryMtl.mm src/FenceMtlImpl.mm src/PipelineStateMtlImpl.mm src/RenderDeviceMtlImpl.mm - src/RenderDeviceFactoryMtl.mm src/SamplerMtlImpl.mm src/ShaderMtlImpl.mm src/ShaderResourceBindingMtlImpl.mm diff --git a/Graphics/GraphicsEngineMetal/interface/EngineFactoryMtl.h b/Graphics/GraphicsEngineMetal/interface/EngineFactoryMtl.h new file mode 100644 index 00000000..01888518 --- /dev/null +++ b/Graphics/GraphicsEngineMetal/interface/EngineFactoryMtl.h @@ -0,0 +1,66 @@ +/* Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of functions that initialize Vulkan-based engine implementation + +#include + +#include "../../GraphicsEngine/interface/RenderDevice.h" +#include "../../GraphicsEngine/interface/DeviceContext.h" +#include "../../GraphicsEngine/interface/SwapChain.h" +#include "EngineMtlAttribs.h" + +// https://gcc.gnu.org/wiki/Visibility +#define API_QUALIFIER __attribute__((visibility("default"))) + +namespace Diligent +{ + +class IEngineFactoryMtl +{ +public: + virtual void CreateDeviceAndContextsMtl(const EngineMtlCreateInfo& Attribs, + IRenderDevice** ppDevice, + IDeviceContext** ppContexts, + Uint32 NumDeferredContexts ) = 0; + + virtual void CreateSwapChainMtl( IRenderDevice* pDevice, + IDeviceContext* pImmediateContext, + const SwapChainDesc& SCDesc, + void* pView, + ISwapChain** ppSwapChain ) = 0; + + virtual void AttachToMtlDevice(void* pMtlNativeDevice, + const EngineMtlCreateInfo& EngineAttribs, + IRenderDevice** ppDevice, + IDeviceContext** ppContexts, + Uint32 NumDeferredContexts) = 0; +}; + + +API_QUALIFIER IEngineFactoryMtl* GetEngineFactoryMtl(); + +} diff --git a/Graphics/GraphicsEngineMetal/interface/EngineMtlAttribs.h b/Graphics/GraphicsEngineMetal/interface/EngineMtlAttribs.h deleted file mode 100644 index 935716df..00000000 --- a/Graphics/GraphicsEngineMetal/interface/EngineMtlAttribs.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Definition of the Engine Mtl attribs - -#include "../../GraphicsEngine/interface/GraphicsTypes.h" - -namespace Diligent -{ - /// Attributes of the Metal-based engine implementation - struct EngineMtlAttribs : public EngineCreationAttribs - { - - }; -} diff --git a/Graphics/GraphicsEngineMetal/interface/RenderDeviceFactoryMtl.h b/Graphics/GraphicsEngineMetal/interface/RenderDeviceFactoryMtl.h deleted file mode 100644 index e0e9bffc..00000000 --- a/Graphics/GraphicsEngineMetal/interface/RenderDeviceFactoryMtl.h +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of functions that initialize Vulkan-based engine implementation - -#include - -#include "../../GraphicsEngine/interface/RenderDevice.h" -#include "../../GraphicsEngine/interface/DeviceContext.h" -#include "../../GraphicsEngine/interface/SwapChain.h" -#include "EngineMtlAttribs.h" - -// https://gcc.gnu.org/wiki/Visibility -#define API_QUALIFIER __attribute__((visibility("default"))) - -namespace Diligent -{ - -class IEngineFactoryMtl -{ -public: - virtual void CreateDeviceAndContextsMtl( const EngineMtlAttribs& Attribs, - IRenderDevice** ppDevice, - IDeviceContext** ppContexts, - Uint32 NumDeferredContexts ) = 0; - - virtual void CreateSwapChainMtl( IRenderDevice* pDevice, - IDeviceContext* pImmediateContext, - const SwapChainDesc& SCDesc, - void* pView, - ISwapChain** ppSwapChain ) = 0; - - virtual void AttachToMtlDevice(void* pMtlNativeDevice, - const EngineMtlAttribs& EngineAttribs, - IRenderDevice** ppDevice, - IDeviceContext** ppContexts, - Uint32 NumDeferredContexts) = 0; -}; - - -API_QUALIFIER IEngineFactoryMtl* GetEngineFactoryMtl(); - -} diff --git a/Graphics/GraphicsEngineMetal/src/EngineFactoryMtl.mm b/Graphics/GraphicsEngineMetal/src/EngineFactoryMtl.mm new file mode 100644 index 00000000..7516d45e --- /dev/null +++ b/Graphics/GraphicsEngineMetal/src/EngineFactoryMtl.mm @@ -0,0 +1,249 @@ +/* Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +/// \file +/// Routines that initialize Mtl-based engine implementation + +#include "EngineFactoryMtl.h" +#include "RenderDeviceMtlImpl.h" +#include "DeviceContextMtlImpl.h" +#include "SwapChainMtlImpl.h" +#include "MtlTypeConversions.h" +#include "EngineMemory.h" + +namespace Diligent +{ + +/// Engine factory for Mtl implementation +class EngineFactoryMtlImpl : public IEngineFactoryMtl +{ +public: + static EngineFactoryMtlImpl* GetInstance() + { + static EngineFactoryMtlImpl TheFactory; + return &TheFactory; + } + + void CreateDeviceAndContextsMtl(const EngineMtlCreateInfo& EngineAttribs, + IRenderDevice** ppDevice, + IDeviceContext** ppContexts, + Uint32 NumDeferredContexts )override final; + + void CreateSwapChainMtl( IRenderDevice* pDevice, + IDeviceContext* pImmediateContext, + const SwapChainDesc& SCDesc, + void* pView, + ISwapChain** ppSwapChain )override final; + + void AttachToMtlDevice(void* pMtlNativeDevice, + const EngineMtlCreateInfo& EngineAttribs, + IRenderDevice** ppDevice, + IDeviceContext** ppContexts, + Uint32 NumDeferredContexts)override final; +}; + + +/// Creates render device and device contexts for Metal-based engine implementation + +/// \param [in] EngineAttribs - Engine creation attributes. +/// \param [out] ppDevice - Address of the memory location where pointer to +/// the created device will be written +/// \param [out] ppContexts - Address of the memory location where pointers to +/// the contexts will be written. Pointer to the immediate +/// context goes at position 0. If NumDeferredContexts > 0, +/// pointers to the deferred contexts go afterwards. +/// \param [in] NumDeferredContexts - Number of deferred contexts. If non-zero number +/// of deferred contexts is requested, pointers to the +/// contexts are written to ppContexts array starting +/// at position 1 +void EngineFactoryMtlImpl::CreateDeviceAndContextsMtl(const EngineMtlCreateInfo& EngineAttribs, + IRenderDevice** ppDevice, + IDeviceContext** ppContexts, + Uint32 NumDeferredContexts ) +{ + if (EngineAttribs.DebugMessageCallback != nullptr) + SetDebugMessageCallback(EngineAttribs.DebugMessageCallback); + + VERIFY( ppDevice && ppContexts, "Null pointer provided" ); + if( !ppDevice || !ppContexts ) + return; + + *ppDevice = nullptr; + memset(ppContexts, 0, sizeof(*ppContexts) * (1+NumDeferredContexts)); + + void* pMtlDevice = nullptr; + AttachToMtlDevice(pMtlDevice, EngineAttribs, ppDevice, ppContexts, NumDeferredContexts); +} + + +/// Attaches to existing Mtl render device and immediate context + +/// \param [in] pMtlNativeDevice - pointer to native Mtl device +/// \param [in] pMtlImmediateContext - pointer to native Mtl immediate context +/// \param [in] EngineAttribs - Engine creation attributes. +/// \param [out] ppDevice - Address of the memory location where pointer to +/// the created device will be written +/// \param [out] ppContexts - Address of the memory location where pointers to +/// the contexts will be written. Pointer to the immediate +/// context goes at position 0. If NumDeferredContexts > 0, +/// pointers to deferred contexts go afterwards. +/// \param [in] NumDeferredContexts - Number of deferred contexts. If non-zero number +/// of deferred contexts is requested, pointers to the +/// contexts are written to ppContexts array starting +/// at position 1 +void EngineFactoryMtlImpl::AttachToMtlDevice(void* pMtlNativeDevice, + const EngineMtlCreateInfo& EngineAttribs, + IRenderDevice** ppDevice, + IDeviceContext** ppContexts, + Uint32 NumDeferredContexts) +{ + if (EngineAttribs.DebugMessageCallback != nullptr) + SetDebugMessageCallback(EngineAttribs.DebugMessageCallback); + + VERIFY( ppDevice && ppContexts, "Null pointer provided" ); + if( !ppDevice || !ppContexts ) + return; + + try + { + SetRawAllocator(EngineAttribs.pRawMemAllocator); + auto &RawAlloctor = GetRawAllocator(); + RenderDeviceMtlImpl *pRenderDeviceMtl(NEW_RC_OBJ(RawAlloctor, "RenderDeviceMtlImpl instance", RenderDeviceMtlImpl) + (RawAlloctor, EngineAttribs, pMtlNativeDevice, NumDeferredContexts)); + pRenderDeviceMtl->QueryInterface(IID_RenderDevice, reinterpret_cast(ppDevice)); + + RefCntAutoPtr pDeviceContextMtl(NEW_RC_OBJ(RawAlloctor, "DeviceContextMtlImpl instance", DeviceContextMtlImpl) + (RawAlloctor, pRenderDeviceMtl, EngineAttribs, false)); + + // We must call AddRef() (implicitly through QueryInterface()) because pRenderDeviceMtl will + // keep a weak reference to the context + pDeviceContextMtl->QueryInterface(IID_DeviceContext, reinterpret_cast(ppContexts)); + pRenderDeviceMtl->SetImmediateContext(pDeviceContextMtl); + + for (Uint32 DeferredCtx = 0; DeferredCtx < NumDeferredContexts; ++DeferredCtx) + { + RefCntAutoPtr pDeferredCtxMtl( + NEW_RC_OBJ(RawAlloctor, "DeviceContextMtlImpl instance", DeviceContextMtlImpl) + (RawAlloctor, pRenderDeviceMtl, EngineAttribs, true)); + // We must call AddRef() (implicitly through QueryInterface()) because pRenderDeviceD3D12 will + // keep a weak reference to the context + pDeferredCtxMtl->QueryInterface(IID_DeviceContext, reinterpret_cast(ppContexts + 1 + DeferredCtx)); + pRenderDeviceMtl->SetDeferredContext(DeferredCtx, pDeferredCtxMtl); + } + } + catch( const std::runtime_error & ) + { + if( *ppDevice ) + { + (*ppDevice)->Release(); + *ppDevice = nullptr; + } + for(Uint32 ctx=0; ctx < 1 + NumDeferredContexts; ++ctx) + { + if( ppContexts[ctx] != nullptr ) + { + ppContexts[ctx]->Release(); + ppContexts[ctx] = nullptr; + } + } + + LOG_ERROR( "Failed to initialize Mtl device and contexts" ); + } +} + +/// Creates a swap chain for Direct3D11-based engine implementation + +/// \param [in] pDevice - Pointer to the render device +/// \param [in] pImmediateContext - Pointer to the immediate device context +/// \param [in] SCDesc - Swap chain description +/// \param [in] FSDesc - Fullscreen mode description +/// \param [in] pNativeWndHandle - Platform-specific native handle of the window +/// the swap chain will be associated with: +/// * On Win32 platform, this should be window handle (HWND) +/// * On Universal Windows Platform, this should be reference to the +/// core window (Windows::UI::Core::CoreWindow) +/// +/// \param [out] ppSwapChain - Address of the memory location where pointer to the new +/// swap chain will be written +void EngineFactoryMtlImpl::CreateSwapChainMtl(IRenderDevice* pDevice, + IDeviceContext* pImmediateContext, + const SwapChainDesc& SCDesc, + void* pView, + ISwapChain** ppSwapChain ) +{ + VERIFY( ppSwapChain, "Null pointer provided" ); + if( !ppSwapChain ) + return; + + *ppSwapChain = nullptr; + + try + { + auto *pDeviceMtl = ValidatedCast( pDevice ); + auto *pDeviceContextMtl = ValidatedCast(pImmediateContext); + auto &RawMemAllocator = GetRawAllocator(); + + auto *pSwapChainMtl = NEW_RC_OBJ(RawMemAllocator, "SwapChainMtlImpl instance", SwapChainMtlImpl) + (SCDesc, pDeviceMtl, pDeviceContextMtl, pView); + pSwapChainMtl->QueryInterface( IID_SwapChain, reinterpret_cast(ppSwapChain) ); + + pDeviceContextMtl->SetSwapChain(pSwapChainMtl); + // Bind default render target + pDeviceContextMtl->SetRenderTargets( 0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION ); + // Set default viewport + pDeviceContextMtl->SetViewports( 1, nullptr, 0, 0 ); + + auto NumDeferredCtx = pDeviceMtl->GetNumDeferredContexts(); + for (size_t ctx = 0; ctx < NumDeferredCtx; ++ctx) + { + if (auto pDeferredCtx = pDeviceMtl->GetDeferredContext(ctx)) + { + auto *pDeferredCtxMtl = pDeferredCtx.RawPtr(); + pDeferredCtxMtl->SetSwapChain(pSwapChainMtl); + // Do not bind default render target and viewport to be + // consistent with D3D12 + //// Bind default render target + //pDeferredCtxMtl->SetRenderTargets( 0, nullptr, nullptr ); + //// Set default viewport + //pDeferredCtxMtl->SetViewports( 1, nullptr, 0, 0 ); + } + } + } + catch( const std::runtime_error & ) + { + if( *ppSwapChain ) + { + (*ppSwapChain)->Release(); + *ppSwapChain = nullptr; + } + + LOG_ERROR( "Failed to create the swap chain" ); + } +} + +IEngineFactoryMtl* GetEngineFactoryMtl() +{ + return EngineFactoryMtlImpl::GetInstance(); +} + +} diff --git a/Graphics/GraphicsEngineMetal/src/RenderDeviceFactoryMtl.mm b/Graphics/GraphicsEngineMetal/src/RenderDeviceFactoryMtl.mm deleted file mode 100644 index 900a288b..00000000 --- a/Graphics/GraphicsEngineMetal/src/RenderDeviceFactoryMtl.mm +++ /dev/null @@ -1,249 +0,0 @@ -/* Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -/// \file -/// Routines that initialize Mtl-based engine implementation - -#include "RenderDeviceFactoryMtl.h" -#include "RenderDeviceMtlImpl.h" -#include "DeviceContextMtlImpl.h" -#include "SwapChainMtlImpl.h" -#include "MtlTypeConversions.h" -#include "EngineMemory.h" - -namespace Diligent -{ - -/// Engine factory for Mtl implementation -class EngineFactoryMtlImpl : public IEngineFactoryMtl -{ -public: - static EngineFactoryMtlImpl* GetInstance() - { - static EngineFactoryMtlImpl TheFactory; - return &TheFactory; - } - - void CreateDeviceAndContextsMtl( const EngineMtlAttribs& EngineAttribs, - IRenderDevice** ppDevice, - IDeviceContext** ppContexts, - Uint32 NumDeferredContexts )override final; - - void CreateSwapChainMtl( IRenderDevice* pDevice, - IDeviceContext* pImmediateContext, - const SwapChainDesc& SCDesc, - void* pView, - ISwapChain** ppSwapChain )override final; - - void AttachToMtlDevice(void* pMtlNativeDevice, - const EngineMtlAttribs& EngineAttribs, - IRenderDevice** ppDevice, - IDeviceContext** ppContexts, - Uint32 NumDeferredContexts)override final; -}; - - -/// Creates render device and device contexts for Metal-based engine implementation - -/// \param [in] EngineAttribs - Engine creation attributes. -/// \param [out] ppDevice - Address of the memory location where pointer to -/// the created device will be written -/// \param [out] ppContexts - Address of the memory location where pointers to -/// the contexts will be written. Pointer to the immediate -/// context goes at position 0. If NumDeferredContexts > 0, -/// pointers to the deferred contexts go afterwards. -/// \param [in] NumDeferredContexts - Number of deferred contexts. If non-zero number -/// of deferred contexts is requested, pointers to the -/// contexts are written to ppContexts array starting -/// at position 1 -void EngineFactoryMtlImpl::CreateDeviceAndContextsMtl( const EngineMtlAttribs& EngineAttribs, - IRenderDevice** ppDevice, - IDeviceContext** ppContexts, - Uint32 NumDeferredContexts ) -{ - if (EngineAttribs.DebugMessageCallback != nullptr) - SetDebugMessageCallback(EngineAttribs.DebugMessageCallback); - - VERIFY( ppDevice && ppContexts, "Null pointer provided" ); - if( !ppDevice || !ppContexts ) - return; - - *ppDevice = nullptr; - memset(ppContexts, 0, sizeof(*ppContexts) * (1+NumDeferredContexts)); - - void* pMtlDevice = nullptr; - AttachToMtlDevice(pMtlDevice, EngineAttribs, ppDevice, ppContexts, NumDeferredContexts); -} - - -/// Attaches to existing Mtl render device and immediate context - -/// \param [in] pMtlNativeDevice - pointer to native Mtl device -/// \param [in] pMtlImmediateContext - pointer to native Mtl immediate context -/// \param [in] EngineAttribs - Engine creation attributes. -/// \param [out] ppDevice - Address of the memory location where pointer to -/// the created device will be written -/// \param [out] ppContexts - Address of the memory location where pointers to -/// the contexts will be written. Pointer to the immediate -/// context goes at position 0. If NumDeferredContexts > 0, -/// pointers to deferred contexts go afterwards. -/// \param [in] NumDeferredContexts - Number of deferred contexts. If non-zero number -/// of deferred contexts is requested, pointers to the -/// contexts are written to ppContexts array starting -/// at position 1 -void EngineFactoryMtlImpl::AttachToMtlDevice(void* pMtlNativeDevice, - const EngineMtlAttribs& EngineAttribs, - IRenderDevice** ppDevice, - IDeviceContext** ppContexts, - Uint32 NumDeferredContexts) -{ - if (EngineAttribs.DebugMessageCallback != nullptr) - SetDebugMessageCallback(EngineAttribs.DebugMessageCallback); - - VERIFY( ppDevice && ppContexts, "Null pointer provided" ); - if( !ppDevice || !ppContexts ) - return; - - try - { - SetRawAllocator(EngineAttribs.pRawMemAllocator); - auto &RawAlloctor = GetRawAllocator(); - RenderDeviceMtlImpl *pRenderDeviceMtl(NEW_RC_OBJ(RawAlloctor, "RenderDeviceMtlImpl instance", RenderDeviceMtlImpl) - (RawAlloctor, EngineAttribs, pMtlNativeDevice, NumDeferredContexts)); - pRenderDeviceMtl->QueryInterface(IID_RenderDevice, reinterpret_cast(ppDevice)); - - RefCntAutoPtr pDeviceContextMtl(NEW_RC_OBJ(RawAlloctor, "DeviceContextMtlImpl instance", DeviceContextMtlImpl) - (RawAlloctor, pRenderDeviceMtl, EngineAttribs, false)); - - // We must call AddRef() (implicitly through QueryInterface()) because pRenderDeviceMtl will - // keep a weak reference to the context - pDeviceContextMtl->QueryInterface(IID_DeviceContext, reinterpret_cast(ppContexts)); - pRenderDeviceMtl->SetImmediateContext(pDeviceContextMtl); - - for (Uint32 DeferredCtx = 0; DeferredCtx < NumDeferredContexts; ++DeferredCtx) - { - RefCntAutoPtr pDeferredCtxMtl( - NEW_RC_OBJ(RawAlloctor, "DeviceContextMtlImpl instance", DeviceContextMtlImpl) - (RawAlloctor, pRenderDeviceMtl, EngineAttribs, true)); - // We must call AddRef() (implicitly through QueryInterface()) because pRenderDeviceD3D12 will - // keep a weak reference to the context - pDeferredCtxMtl->QueryInterface(IID_DeviceContext, reinterpret_cast(ppContexts + 1 + DeferredCtx)); - pRenderDeviceMtl->SetDeferredContext(DeferredCtx, pDeferredCtxMtl); - } - } - catch( const std::runtime_error & ) - { - if( *ppDevice ) - { - (*ppDevice)->Release(); - *ppDevice = nullptr; - } - for(Uint32 ctx=0; ctx < 1 + NumDeferredContexts; ++ctx) - { - if( ppContexts[ctx] != nullptr ) - { - ppContexts[ctx]->Release(); - ppContexts[ctx] = nullptr; - } - } - - LOG_ERROR( "Failed to initialize Mtl device and contexts" ); - } -} - -/// Creates a swap chain for Direct3D11-based engine implementation - -/// \param [in] pDevice - Pointer to the render device -/// \param [in] pImmediateContext - Pointer to the immediate device context -/// \param [in] SCDesc - Swap chain description -/// \param [in] FSDesc - Fullscreen mode description -/// \param [in] pNativeWndHandle - Platform-specific native handle of the window -/// the swap chain will be associated with: -/// * On Win32 platform, this should be window handle (HWND) -/// * On Universal Windows Platform, this should be reference to the -/// core window (Windows::UI::Core::CoreWindow) -/// -/// \param [out] ppSwapChain - Address of the memory location where pointer to the new -/// swap chain will be written -void EngineFactoryMtlImpl::CreateSwapChainMtl( IRenderDevice* pDevice, - IDeviceContext* pImmediateContext, - const SwapChainDesc& SCDesc, - void* pView, - ISwapChain** ppSwapChain ) -{ - VERIFY( ppSwapChain, "Null pointer provided" ); - if( !ppSwapChain ) - return; - - *ppSwapChain = nullptr; - - try - { - auto *pDeviceMtl = ValidatedCast( pDevice ); - auto *pDeviceContextMtl = ValidatedCast(pImmediateContext); - auto &RawMemAllocator = GetRawAllocator(); - - auto *pSwapChainMtl = NEW_RC_OBJ(RawMemAllocator, "SwapChainMtlImpl instance", SwapChainMtlImpl) - (SCDesc, pDeviceMtl, pDeviceContextMtl, pView); - pSwapChainMtl->QueryInterface( IID_SwapChain, reinterpret_cast(ppSwapChain) ); - - pDeviceContextMtl->SetSwapChain(pSwapChainMtl); - // Bind default render target - pDeviceContextMtl->SetRenderTargets( 0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION ); - // Set default viewport - pDeviceContextMtl->SetViewports( 1, nullptr, 0, 0 ); - - auto NumDeferredCtx = pDeviceMtl->GetNumDeferredContexts(); - for (size_t ctx = 0; ctx < NumDeferredCtx; ++ctx) - { - if (auto pDeferredCtx = pDeviceMtl->GetDeferredContext(ctx)) - { - auto *pDeferredCtxMtl = pDeferredCtx.RawPtr(); - pDeferredCtxMtl->SetSwapChain(pSwapChainMtl); - // Do not bind default render target and viewport to be - // consistent with D3D12 - //// Bind default render target - //pDeferredCtxMtl->SetRenderTargets( 0, nullptr, nullptr ); - //// Set default viewport - //pDeferredCtxMtl->SetViewports( 1, nullptr, 0, 0 ); - } - } - } - catch( const std::runtime_error & ) - { - if( *ppSwapChain ) - { - (*ppSwapChain)->Release(); - *ppSwapChain = nullptr; - } - - LOG_ERROR( "Failed to create the swap chain" ); - } -} - -IEngineFactoryMtl* GetEngineFactoryMtl() -{ - return EngineFactoryMtlImpl::GetInstance(); -} - -} -- cgit v1.2.3