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:
Corentin Wallez 2018-01-15 15:44:38 -05:00 committed by Corentin Wallez
parent 395bf15599
commit cc407ae787
8 changed files with 92 additions and 126 deletions

View File

@ -26,6 +26,7 @@ list(APPEND COMMON_SOURCES
${COMMON_DIR}/Platform.h
${COMMON_DIR}/Serial.h
${COMMON_DIR}/SerialQueue.h
${COMMON_DIR}/SwapChainUtils.h
)
add_library(nxt_common STATIC ${COMMON_SOURCES})

View File

@ -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_

View File

@ -19,7 +19,6 @@ list(APPEND UTILS_SOURCES
${UTILS_DIR}/BackendBinding.h
${UTILS_DIR}/NXTHelpers.cpp
${UTILS_DIR}/NXTHelpers.h
${UTILS_DIR}/SwapChainImpl.h
${UTILS_DIR}/SystemUtils.cpp
${UTILS_DIR}/SystemUtils.h
)

View File

@ -15,8 +15,8 @@
#include "utils/BackendBinding.h"
#include "common/Assert.h"
#include "common/SwapChainUtils.h"
#include "nxt/nxt_wsi.h"
#include "utils/SwapChainImpl.h"
#define GLFW_EXPOSE_NATIVE_WIN32
#include "GLFW/glfw3.h"
@ -116,32 +116,9 @@ namespace utils {
}
} // namespace
class SwapChainImplD3D12 : SwapChainImpl {
class SwapChainImplD3D12 {
public:
static nxtSwapChainImplementation Create(HWND window, const nxtProcTable& procs) {
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;
using WSIContext = nxtWSIContextD3D12;
SwapChainImplD3D12(HWND window, nxtProcTable procs)
: mWindow(window), mProcs(procs), mFactory(CreateFactory()) {
@ -150,9 +127,6 @@ namespace utils {
~SwapChainImplD3D12() {
}
// For GenerateSwapChainImplementation
friend class SwapChainImpl;
void Init(nxtWSIContextD3D12* ctx) {
mBackendDevice = ctx->device;
mCommandQueue = backend::d3d12::GetCommandQueue(mBackendDevice);
@ -249,6 +223,25 @@ namespace utils {
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 {
@ -271,7 +264,8 @@ namespace utils {
uint64_t GetSwapChainImplementation() override {
if (mSwapchainImpl.userData == nullptr) {
HWND win32Window = glfwGetWin32Window(mWindow);
mSwapchainImpl = SwapChainImplD3D12::Create(win32Window, mProcTable);
mSwapchainImpl =
CreateSwapChainImplementation(new SwapChainImplD3D12(win32Window, mProcTable));
}
return reinterpret_cast<uint64_t>(&mSwapchainImpl);
}

View File

@ -15,8 +15,8 @@
#include "utils/BackendBinding.h"
#include "common/Assert.h"
#include "common/SwapChainUtils.h"
#include "nxt/nxt_wsi.h"
#include "utils/SwapChainImpl.h"
#define GLFW_EXPOSE_NATIVE_COCOA
#include "GLFW/glfw3.h"
@ -32,22 +32,9 @@ namespace backend { namespace metal {
}}
namespace utils {
class SwapChainImplMTL : SwapChainImpl {
class SwapChainImplMTL {
public:
static nxtSwapChainImplementation Create(id nswindow) {
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;
using WSIContext = nxtWSIContextMetal;
SwapChainImplMTL(id nsWindow) : mNsWindow(nsWindow) {
}
@ -57,9 +44,6 @@ namespace utils {
[mCurrentDrawable release];
}
// For GenerateSwapChainImplementation
friend class SwapChainImpl;
void Init(nxtWSIContextMetal* ctx) {
mMtlDevice = ctx->device;
mCommandQueue = [mMtlDevice newCommandQueue];
@ -114,6 +98,15 @@ namespace utils {
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 {
@ -130,7 +123,8 @@ namespace utils {
uint64_t GetSwapChainImplementation() override {
if (mSwapchainImpl.userData == nullptr) {
mSwapchainImpl = SwapChainImplMTL::Create(glfwGetCocoaWindow(mWindow));
mSwapchainImpl = CreateSwapChainImplementation(
new SwapChainImplMTL(glfwGetCocoaWindow(mWindow)));
}
return reinterpret_cast<uint64_t>(&mSwapchainImpl);
}

View File

@ -16,8 +16,8 @@
#include "common/Assert.h"
#include "common/Platform.h"
#include "common/SwapChainUtils.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
#include "glad/glad.h"
@ -30,20 +30,9 @@ namespace backend { namespace opengl {
}} // namespace backend::opengl
namespace utils {
class SwapChainImplGL : SwapChainImpl {
class SwapChainImplGL {
public:
static nxtSwapChainImplementation Create(GLFWwindow* window) {
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;
using WSIContext = nxtWSIContextGL;
SwapChainImplGL(GLFWwindow* window) : mWindow(window) {
}
@ -53,9 +42,6 @@ namespace utils {
glDeleteFramebuffers(1, &mBackFBO);
}
// For GenerateSwapChainImplementation
friend class SwapChainImpl;
void Init(nxtWSIContextGL*) {
glGenTextures(1, &mBackTexture);
glBindTexture(GL_TEXTURE_2D, mBackTexture);
@ -101,6 +87,13 @@ namespace utils {
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 {
@ -128,7 +121,7 @@ namespace utils {
uint64_t GetSwapChainImplementation() override {
if (mSwapchainImpl.userData == nullptr) {
mSwapchainImpl = SwapChainImplGL::Create(mWindow);
mSwapchainImpl = CreateSwapChainImplementation(new SwapChainImplGL(mWindow));
}
return reinterpret_cast<uint64_t>(&mSwapchainImpl);
}

View File

@ -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_

View File

@ -14,8 +14,8 @@
#include "utils/BackendBinding.h"
#include "common/SwapChainUtils.h"
#include "nxt/nxt_wsi.h"
#include "utils/SwapChainImpl.h"
namespace backend { namespace vulkan {
void Init(nxtProcTable* procs, nxtDevice* device);
@ -23,24 +23,16 @@ namespace backend { namespace vulkan {
namespace utils {
class SwapChainImplVulkan : SwapChainImpl {
class SwapChainImplVulkan {
public:
static nxtSwapChainImplementation Create(GLFWwindow* window) {
auto impl = GenerateSwapChainImplementation<SwapChainImplVulkan, nxtWSIContextVulkan>();
impl.userData = new SwapChainImplVulkan(window);
return impl;
}
using WSIContext = nxtWSIContextVulkan;
private:
SwapChainImplVulkan(GLFWwindow* /*window*/) {
}
~SwapChainImplVulkan() {
}
// For GenerateSwapChainImplementation
friend class SwapChainImpl;
void Init(nxtWSIContextVulkan*) {
}
@ -66,7 +58,7 @@ namespace utils {
}
uint64_t GetSwapChainImplementation() override {
if (mSwapchainImpl.userData == nullptr) {
mSwapchainImpl = SwapChainImplVulkan::Create(mWindow);
mSwapchainImpl = CreateSwapChainImplementation(new SwapChainImplVulkan(mWindow));
}
return reinterpret_cast<uint64_t>(&mSwapchainImpl);
}