Make SwapChainImpl a function and move it to common/
For the Vulkan backend it will make sense to have the SwapChain be implemented inside the backend as it will need to interact with a lot of things there. It will need SwapChainImpl and cannot see utils/ so SwapChainImpl has to be moved in common/ Also makes SwapChainImpl a function called CreateSwapChainImplementation as the inheritance was only used to share a static method.
This commit is contained in:
parent
395bf15599
commit
cc407ae787
|
@ -26,6 +26,7 @@ list(APPEND COMMON_SOURCES
|
||||||
${COMMON_DIR}/Platform.h
|
${COMMON_DIR}/Platform.h
|
||||||
${COMMON_DIR}/Serial.h
|
${COMMON_DIR}/Serial.h
|
||||||
${COMMON_DIR}/SerialQueue.h
|
${COMMON_DIR}/SerialQueue.h
|
||||||
|
${COMMON_DIR}/SwapChainUtils.h
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(nxt_common STATIC ${COMMON_SOURCES})
|
add_library(nxt_common STATIC ${COMMON_SOURCES})
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
// Copyright 2017 The NXT Authors
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#ifndef COMMON_SWAPCHAINUTILS_H_
|
||||||
|
#define COMMON_SWAPCHAINUTILS_H_
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
nxtSwapChainImplementation CreateSwapChainImplementation(T* swapChain) {
|
||||||
|
nxtSwapChainImplementation impl = {};
|
||||||
|
impl.userData = swapChain;
|
||||||
|
impl.Init = [](void* userData, void* wsiContext) {
|
||||||
|
auto* ctx = reinterpret_cast<typename T::WSIContext*>(wsiContext);
|
||||||
|
reinterpret_cast<T*>(userData)->Init(ctx);
|
||||||
|
};
|
||||||
|
impl.Destroy = [](void* userData) { delete reinterpret_cast<T*>(userData); };
|
||||||
|
impl.Configure = [](void* userData, nxtTextureFormat format, nxtTextureUsageBit allowedUsage,
|
||||||
|
uint32_t width, uint32_t height) {
|
||||||
|
return reinterpret_cast<T*>(userData)->Configure(format, allowedUsage, width, height);
|
||||||
|
};
|
||||||
|
impl.GetNextTexture = [](void* userData, nxtSwapChainNextTexture* nextTexture) {
|
||||||
|
return reinterpret_cast<T*>(userData)->GetNextTexture(nextTexture);
|
||||||
|
};
|
||||||
|
impl.Present = [](void* userData) { return reinterpret_cast<T*>(userData)->Present(); };
|
||||||
|
return impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // COMMON_SWAPCHAINUTILS_H_
|
|
@ -19,7 +19,6 @@ list(APPEND UTILS_SOURCES
|
||||||
${UTILS_DIR}/BackendBinding.h
|
${UTILS_DIR}/BackendBinding.h
|
||||||
${UTILS_DIR}/NXTHelpers.cpp
|
${UTILS_DIR}/NXTHelpers.cpp
|
||||||
${UTILS_DIR}/NXTHelpers.h
|
${UTILS_DIR}/NXTHelpers.h
|
||||||
${UTILS_DIR}/SwapChainImpl.h
|
|
||||||
${UTILS_DIR}/SystemUtils.cpp
|
${UTILS_DIR}/SystemUtils.cpp
|
||||||
${UTILS_DIR}/SystemUtils.h
|
${UTILS_DIR}/SystemUtils.h
|
||||||
)
|
)
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
#include "utils/BackendBinding.h"
|
#include "utils/BackendBinding.h"
|
||||||
|
|
||||||
#include "common/Assert.h"
|
#include "common/Assert.h"
|
||||||
|
#include "common/SwapChainUtils.h"
|
||||||
#include "nxt/nxt_wsi.h"
|
#include "nxt/nxt_wsi.h"
|
||||||
#include "utils/SwapChainImpl.h"
|
|
||||||
|
|
||||||
#define GLFW_EXPOSE_NATIVE_WIN32
|
#define GLFW_EXPOSE_NATIVE_WIN32
|
||||||
#include "GLFW/glfw3.h"
|
#include "GLFW/glfw3.h"
|
||||||
|
@ -116,32 +116,9 @@ namespace utils {
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class SwapChainImplD3D12 : SwapChainImpl {
|
class SwapChainImplD3D12 {
|
||||||
public:
|
public:
|
||||||
static nxtSwapChainImplementation Create(HWND window, const nxtProcTable& procs) {
|
using WSIContext = nxtWSIContextD3D12;
|
||||||
auto impl = GenerateSwapChainImplementation<SwapChainImplD3D12, nxtWSIContextD3D12>();
|
|
||||||
impl.userData = new SwapChainImplD3D12(window, procs);
|
|
||||||
return impl;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
nxtDevice mBackendDevice = nullptr;
|
|
||||||
nxtProcTable mProcs = {};
|
|
||||||
|
|
||||||
static constexpr unsigned int kFrameCount = 2;
|
|
||||||
|
|
||||||
HWND mWindow = 0;
|
|
||||||
ComPtr<IDXGIFactory4> mFactory = {};
|
|
||||||
ComPtr<ID3D12CommandQueue> mCommandQueue = {};
|
|
||||||
ComPtr<IDXGISwapChain3> mSwapChain = {};
|
|
||||||
ComPtr<ID3D12Resource> mRenderTargetResources[kFrameCount] = {};
|
|
||||||
|
|
||||||
// Frame synchronization. Updated every frame
|
|
||||||
uint32_t mRenderTargetIndex = 0;
|
|
||||||
uint32_t mPreviousRenderTargetIndex = 0;
|
|
||||||
uint64_t mLastSerialRenderTargetWasUsed[kFrameCount] = {};
|
|
||||||
|
|
||||||
D3D12_RESOURCE_STATES mRenderTargetResourceState;
|
|
||||||
|
|
||||||
SwapChainImplD3D12(HWND window, nxtProcTable procs)
|
SwapChainImplD3D12(HWND window, nxtProcTable procs)
|
||||||
: mWindow(window), mProcs(procs), mFactory(CreateFactory()) {
|
: mWindow(window), mProcs(procs), mFactory(CreateFactory()) {
|
||||||
|
@ -150,9 +127,6 @@ namespace utils {
|
||||||
~SwapChainImplD3D12() {
|
~SwapChainImplD3D12() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// For GenerateSwapChainImplementation
|
|
||||||
friend class SwapChainImpl;
|
|
||||||
|
|
||||||
void Init(nxtWSIContextD3D12* ctx) {
|
void Init(nxtWSIContextD3D12* ctx) {
|
||||||
mBackendDevice = ctx->device;
|
mBackendDevice = ctx->device;
|
||||||
mCommandQueue = backend::d3d12::GetCommandQueue(mBackendDevice);
|
mCommandQueue = backend::d3d12::GetCommandQueue(mBackendDevice);
|
||||||
|
@ -249,6 +223,25 @@ namespace utils {
|
||||||
|
|
||||||
return NXT_SWAP_CHAIN_NO_ERROR;
|
return NXT_SWAP_CHAIN_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
nxtDevice mBackendDevice = nullptr;
|
||||||
|
nxtProcTable mProcs = {};
|
||||||
|
|
||||||
|
static constexpr unsigned int kFrameCount = 2;
|
||||||
|
|
||||||
|
HWND mWindow = 0;
|
||||||
|
ComPtr<IDXGIFactory4> mFactory = {};
|
||||||
|
ComPtr<ID3D12CommandQueue> mCommandQueue = {};
|
||||||
|
ComPtr<IDXGISwapChain3> mSwapChain = {};
|
||||||
|
ComPtr<ID3D12Resource> mRenderTargetResources[kFrameCount] = {};
|
||||||
|
|
||||||
|
// Frame synchronization. Updated every frame
|
||||||
|
uint32_t mRenderTargetIndex = 0;
|
||||||
|
uint32_t mPreviousRenderTargetIndex = 0;
|
||||||
|
uint64_t mLastSerialRenderTargetWasUsed[kFrameCount] = {};
|
||||||
|
|
||||||
|
D3D12_RESOURCE_STATES mRenderTargetResourceState;
|
||||||
};
|
};
|
||||||
|
|
||||||
class D3D12Binding : public BackendBinding {
|
class D3D12Binding : public BackendBinding {
|
||||||
|
@ -271,7 +264,8 @@ namespace utils {
|
||||||
uint64_t GetSwapChainImplementation() override {
|
uint64_t GetSwapChainImplementation() override {
|
||||||
if (mSwapchainImpl.userData == nullptr) {
|
if (mSwapchainImpl.userData == nullptr) {
|
||||||
HWND win32Window = glfwGetWin32Window(mWindow);
|
HWND win32Window = glfwGetWin32Window(mWindow);
|
||||||
mSwapchainImpl = SwapChainImplD3D12::Create(win32Window, mProcTable);
|
mSwapchainImpl =
|
||||||
|
CreateSwapChainImplementation(new SwapChainImplD3D12(win32Window, mProcTable));
|
||||||
}
|
}
|
||||||
return reinterpret_cast<uint64_t>(&mSwapchainImpl);
|
return reinterpret_cast<uint64_t>(&mSwapchainImpl);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
#include "utils/BackendBinding.h"
|
#include "utils/BackendBinding.h"
|
||||||
|
|
||||||
#include "common/Assert.h"
|
#include "common/Assert.h"
|
||||||
|
#include "common/SwapChainUtils.h"
|
||||||
#include "nxt/nxt_wsi.h"
|
#include "nxt/nxt_wsi.h"
|
||||||
#include "utils/SwapChainImpl.h"
|
|
||||||
|
|
||||||
#define GLFW_EXPOSE_NATIVE_COCOA
|
#define GLFW_EXPOSE_NATIVE_COCOA
|
||||||
#include "GLFW/glfw3.h"
|
#include "GLFW/glfw3.h"
|
||||||
|
@ -32,22 +32,9 @@ namespace backend { namespace metal {
|
||||||
}}
|
}}
|
||||||
|
|
||||||
namespace utils {
|
namespace utils {
|
||||||
class SwapChainImplMTL : SwapChainImpl {
|
class SwapChainImplMTL {
|
||||||
public:
|
public:
|
||||||
static nxtSwapChainImplementation Create(id nswindow) {
|
using WSIContext = nxtWSIContextMetal;
|
||||||
auto impl = GenerateSwapChainImplementation<SwapChainImplMTL, nxtWSIContextMetal>();
|
|
||||||
impl.userData = new SwapChainImplMTL(nswindow);
|
|
||||||
return impl;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
id mNsWindow = nil;
|
|
||||||
id<MTLDevice> mMtlDevice = nil;
|
|
||||||
id<MTLCommandQueue> mCommandQueue = nil;
|
|
||||||
|
|
||||||
CAMetalLayer* mLayer = nullptr;
|
|
||||||
id<CAMetalDrawable> mCurrentDrawable = nil;
|
|
||||||
id<MTLTexture> mCurrentTexture = nil;
|
|
||||||
|
|
||||||
SwapChainImplMTL(id nsWindow) : mNsWindow(nsWindow) {
|
SwapChainImplMTL(id nsWindow) : mNsWindow(nsWindow) {
|
||||||
}
|
}
|
||||||
|
@ -57,9 +44,6 @@ namespace utils {
|
||||||
[mCurrentDrawable release];
|
[mCurrentDrawable release];
|
||||||
}
|
}
|
||||||
|
|
||||||
// For GenerateSwapChainImplementation
|
|
||||||
friend class SwapChainImpl;
|
|
||||||
|
|
||||||
void Init(nxtWSIContextMetal* ctx) {
|
void Init(nxtWSIContextMetal* ctx) {
|
||||||
mMtlDevice = ctx->device;
|
mMtlDevice = ctx->device;
|
||||||
mCommandQueue = [mMtlDevice newCommandQueue];
|
mCommandQueue = [mMtlDevice newCommandQueue];
|
||||||
|
@ -114,6 +98,15 @@ namespace utils {
|
||||||
|
|
||||||
return NXT_SWAP_CHAIN_NO_ERROR;
|
return NXT_SWAP_CHAIN_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
id mNsWindow = nil;
|
||||||
|
id<MTLDevice> mMtlDevice = nil;
|
||||||
|
id<MTLCommandQueue> mCommandQueue = nil;
|
||||||
|
|
||||||
|
CAMetalLayer* mLayer = nullptr;
|
||||||
|
id<CAMetalDrawable> mCurrentDrawable = nil;
|
||||||
|
id<MTLTexture> mCurrentTexture = nil;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MetalBinding : public BackendBinding {
|
class MetalBinding : public BackendBinding {
|
||||||
|
@ -130,7 +123,8 @@ namespace utils {
|
||||||
|
|
||||||
uint64_t GetSwapChainImplementation() override {
|
uint64_t GetSwapChainImplementation() override {
|
||||||
if (mSwapchainImpl.userData == nullptr) {
|
if (mSwapchainImpl.userData == nullptr) {
|
||||||
mSwapchainImpl = SwapChainImplMTL::Create(glfwGetCocoaWindow(mWindow));
|
mSwapchainImpl = CreateSwapChainImplementation(
|
||||||
|
new SwapChainImplMTL(glfwGetCocoaWindow(mWindow)));
|
||||||
}
|
}
|
||||||
return reinterpret_cast<uint64_t>(&mSwapchainImpl);
|
return reinterpret_cast<uint64_t>(&mSwapchainImpl);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
|
|
||||||
#include "common/Assert.h"
|
#include "common/Assert.h"
|
||||||
#include "common/Platform.h"
|
#include "common/Platform.h"
|
||||||
|
#include "common/SwapChainUtils.h"
|
||||||
#include "nxt/nxt_wsi.h"
|
#include "nxt/nxt_wsi.h"
|
||||||
#include "utils/SwapChainImpl.h"
|
|
||||||
|
|
||||||
// Glad needs to be included before GLFW otherwise it complain that GL.h was already included
|
// Glad needs to be included before GLFW otherwise it complain that GL.h was already included
|
||||||
#include "glad/glad.h"
|
#include "glad/glad.h"
|
||||||
|
@ -30,20 +30,9 @@ namespace backend { namespace opengl {
|
||||||
}} // namespace backend::opengl
|
}} // namespace backend::opengl
|
||||||
|
|
||||||
namespace utils {
|
namespace utils {
|
||||||
class SwapChainImplGL : SwapChainImpl {
|
class SwapChainImplGL {
|
||||||
public:
|
public:
|
||||||
static nxtSwapChainImplementation Create(GLFWwindow* window) {
|
using WSIContext = nxtWSIContextGL;
|
||||||
auto impl = GenerateSwapChainImplementation<SwapChainImplGL, nxtWSIContextGL>();
|
|
||||||
impl.userData = new SwapChainImplGL(window);
|
|
||||||
return impl;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
GLFWwindow* mWindow = nullptr;
|
|
||||||
uint32_t mWidth = 0;
|
|
||||||
uint32_t mHeight = 0;
|
|
||||||
GLuint mBackFBO = 0;
|
|
||||||
GLuint mBackTexture = 0;
|
|
||||||
|
|
||||||
SwapChainImplGL(GLFWwindow* window) : mWindow(window) {
|
SwapChainImplGL(GLFWwindow* window) : mWindow(window) {
|
||||||
}
|
}
|
||||||
|
@ -53,9 +42,6 @@ namespace utils {
|
||||||
glDeleteFramebuffers(1, &mBackFBO);
|
glDeleteFramebuffers(1, &mBackFBO);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For GenerateSwapChainImplementation
|
|
||||||
friend class SwapChainImpl;
|
|
||||||
|
|
||||||
void Init(nxtWSIContextGL*) {
|
void Init(nxtWSIContextGL*) {
|
||||||
glGenTextures(1, &mBackTexture);
|
glGenTextures(1, &mBackTexture);
|
||||||
glBindTexture(GL_TEXTURE_2D, mBackTexture);
|
glBindTexture(GL_TEXTURE_2D, mBackTexture);
|
||||||
|
@ -101,6 +87,13 @@ namespace utils {
|
||||||
|
|
||||||
return NXT_SWAP_CHAIN_NO_ERROR;
|
return NXT_SWAP_CHAIN_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLFWwindow* mWindow = nullptr;
|
||||||
|
uint32_t mWidth = 0;
|
||||||
|
uint32_t mHeight = 0;
|
||||||
|
GLuint mBackFBO = 0;
|
||||||
|
GLuint mBackTexture = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OpenGLBinding : public BackendBinding {
|
class OpenGLBinding : public BackendBinding {
|
||||||
|
@ -128,7 +121,7 @@ namespace utils {
|
||||||
|
|
||||||
uint64_t GetSwapChainImplementation() override {
|
uint64_t GetSwapChainImplementation() override {
|
||||||
if (mSwapchainImpl.userData == nullptr) {
|
if (mSwapchainImpl.userData == nullptr) {
|
||||||
mSwapchainImpl = SwapChainImplGL::Create(mWindow);
|
mSwapchainImpl = CreateSwapChainImplementation(new SwapChainImplGL(mWindow));
|
||||||
}
|
}
|
||||||
return reinterpret_cast<uint64_t>(&mSwapchainImpl);
|
return reinterpret_cast<uint64_t>(&mSwapchainImpl);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
// Copyright 2017 The NXT Authors
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#ifndef UTILS_SWAPCHAINIMPL_H_
|
|
||||||
#define UTILS_SWAPCHAINIMPL_H_
|
|
||||||
|
|
||||||
namespace utils {
|
|
||||||
class SwapChainImpl {
|
|
||||||
protected:
|
|
||||||
template <class TImpl, typename TWSIContext>
|
|
||||||
static nxtSwapChainImplementation GenerateSwapChainImplementation() {
|
|
||||||
nxtSwapChainImplementation impl = {};
|
|
||||||
impl.Init = [](void* userData, void* wsiContext) {
|
|
||||||
auto* ctx = reinterpret_cast<TWSIContext*>(wsiContext);
|
|
||||||
reinterpret_cast<TImpl*>(userData)->Init(ctx);
|
|
||||||
};
|
|
||||||
impl.Destroy = [](void* userData) { delete reinterpret_cast<TImpl*>(userData); };
|
|
||||||
impl.Configure = [](void* userData, nxtTextureFormat format,
|
|
||||||
nxtTextureUsageBit allowedUsage, uint32_t width, uint32_t height) {
|
|
||||||
return reinterpret_cast<TImpl*>(userData)->Configure(format, allowedUsage, width,
|
|
||||||
height);
|
|
||||||
};
|
|
||||||
impl.GetNextTexture = [](void* userData, nxtSwapChainNextTexture* nextTexture) {
|
|
||||||
return reinterpret_cast<TImpl*>(userData)->GetNextTexture(nextTexture);
|
|
||||||
};
|
|
||||||
impl.Present = [](void* userData) {
|
|
||||||
return reinterpret_cast<TImpl*>(userData)->Present();
|
|
||||||
};
|
|
||||||
return impl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace utils
|
|
||||||
|
|
||||||
#endif // UTILS_SWAPCHAINIMPL_H_
|
|
|
@ -14,8 +14,8 @@
|
||||||
|
|
||||||
#include "utils/BackendBinding.h"
|
#include "utils/BackendBinding.h"
|
||||||
|
|
||||||
|
#include "common/SwapChainUtils.h"
|
||||||
#include "nxt/nxt_wsi.h"
|
#include "nxt/nxt_wsi.h"
|
||||||
#include "utils/SwapChainImpl.h"
|
|
||||||
|
|
||||||
namespace backend { namespace vulkan {
|
namespace backend { namespace vulkan {
|
||||||
void Init(nxtProcTable* procs, nxtDevice* device);
|
void Init(nxtProcTable* procs, nxtDevice* device);
|
||||||
|
@ -23,24 +23,16 @@ namespace backend { namespace vulkan {
|
||||||
|
|
||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
class SwapChainImplVulkan : SwapChainImpl {
|
class SwapChainImplVulkan {
|
||||||
public:
|
public:
|
||||||
static nxtSwapChainImplementation Create(GLFWwindow* window) {
|
using WSIContext = nxtWSIContextVulkan;
|
||||||
auto impl = GenerateSwapChainImplementation<SwapChainImplVulkan, nxtWSIContextVulkan>();
|
|
||||||
impl.userData = new SwapChainImplVulkan(window);
|
|
||||||
return impl;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
SwapChainImplVulkan(GLFWwindow* /*window*/) {
|
SwapChainImplVulkan(GLFWwindow* /*window*/) {
|
||||||
}
|
}
|
||||||
|
|
||||||
~SwapChainImplVulkan() {
|
~SwapChainImplVulkan() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// For GenerateSwapChainImplementation
|
|
||||||
friend class SwapChainImpl;
|
|
||||||
|
|
||||||
void Init(nxtWSIContextVulkan*) {
|
void Init(nxtWSIContextVulkan*) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +58,7 @@ namespace utils {
|
||||||
}
|
}
|
||||||
uint64_t GetSwapChainImplementation() override {
|
uint64_t GetSwapChainImplementation() override {
|
||||||
if (mSwapchainImpl.userData == nullptr) {
|
if (mSwapchainImpl.userData == nullptr) {
|
||||||
mSwapchainImpl = SwapChainImplVulkan::Create(mWindow);
|
mSwapchainImpl = CreateSwapChainImplementation(new SwapChainImplVulkan(mWindow));
|
||||||
}
|
}
|
||||||
return reinterpret_cast<uint64_t>(&mSwapchainImpl);
|
return reinterpret_cast<uint64_t>(&mSwapchainImpl);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue