Move dx interface into graphics module.
This commit is contained in:
parent
672b31b603
commit
4bb87de0e6
23 changed files with 130 additions and 64 deletions
|
@ -47,22 +47,26 @@ if(UNIX)
|
|||
endif()
|
||||
else()
|
||||
list(APPEND graphics_LIB_INCLUDES
|
||||
directx/DirectXInterface.cpp
|
||||
directx/DirectXMesh.cpp
|
||||
directx/DirectXPainter.cpp
|
||||
directx/DirectX2dPainter.cpp
|
||||
directx/DirectXTextPainter.cpp
|
||||
directx/DirectXMeshPainter.cpp
|
||||
directx/DirectXShaderProgram.cpp
|
||||
)
|
||||
list(APPEND graphics_HEADERS
|
||||
list(APPEND graphics_HEADERS
|
||||
directx/DirectXInterface.h
|
||||
directx/DirectXMesh.h
|
||||
directx/DirectXPainter.h
|
||||
directx/DirectX2dPainter.h
|
||||
directx/DirectXTextPainter.h
|
||||
directx/DirectXMeshPainter.h
|
||||
directx/DirectXShaderProgram.h
|
||||
)
|
||||
|
||||
find_package(DirectX-Headers REQUIRED)
|
||||
list(APPEND platform_LIBS D3D12.lib D3DCompiler.lib Dwrite.lib D2d1.lib Microsoft::DirectX-Headers)
|
||||
list(APPEND platform_LIBS D3D12.lib D3DCompiler.lib DXGI.lib Dwrite.lib D2d1.lib D3D11.lib Microsoft::DirectX-Headers)
|
||||
endif()
|
||||
|
||||
add_library(${MODULE_NAME} SHARED
|
||||
|
|
|
@ -15,6 +15,9 @@ DrawingContext::DrawingContext(DrawingSurface* surface, FontsManager* fontsManag
|
|||
mFontsManager(fontsManager)
|
||||
{
|
||||
mPainter = PainterFactory::Create(this, mDrawingMode);
|
||||
|
||||
surface->getScene()->setSupportsGeometryPrimitives(mPainter->supportsGeometryPrimitives());
|
||||
surface->getScene()->setFontsManager(fontsManager);
|
||||
}
|
||||
|
||||
std::unique_ptr<DrawingContext> DrawingContext::Create(DrawingSurface* surface, FontsManager* fontsManager, DrawingMode requestedDrawingMode)
|
||||
|
@ -36,7 +39,7 @@ void DrawingContext::paint()
|
|||
{
|
||||
if (mDrawingMode == DrawingMode::GRAPH)
|
||||
{
|
||||
mSurface->getScene()->update(mFontsManager);
|
||||
mSurface->getScene()->update();
|
||||
}
|
||||
mPainter->paint();
|
||||
}
|
||||
|
@ -44,9 +47,4 @@ void DrawingContext::paint()
|
|||
AbstractPainter* DrawingContext::getPainter() const
|
||||
{
|
||||
return mPainter.get();
|
||||
}
|
||||
|
||||
bool DrawingContext::painterSupportsGeometryPrimitives() const
|
||||
{
|
||||
return mPainter->supportsGeometryPrimitives();
|
||||
}
|
||||
}
|
|
@ -28,8 +28,6 @@ public:
|
|||
|
||||
AbstractPainter* getPainter() const;
|
||||
|
||||
bool painterSupportsGeometryPrimitives() const;
|
||||
|
||||
private:
|
||||
DrawingMode mDrawingMode;
|
||||
FontsManager* mFontsManager{nullptr};
|
||||
|
|
6
src/graphics/directx/DirectX2dPainter.cpp
Normal file
6
src/graphics/directx/DirectX2dPainter.cpp
Normal file
|
@ -0,0 +1,6 @@
|
|||
#include "DirectX2dPainter.h"
|
||||
|
||||
void DirectX2dPainter::paint(ID2D1DeviceContext2* context, AbstractGeometricItem* item)
|
||||
{
|
||||
|
||||
}
|
11
src/graphics/directx/DirectX2dPainter.h
Normal file
11
src/graphics/directx/DirectX2dPainter.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
class AbstractGeometricItem;
|
||||
|
||||
struct ID2D1DeviceContext2;
|
||||
|
||||
class DirectX2dPainter
|
||||
{
|
||||
public:
|
||||
void paint(ID2D1DeviceContext2* context, AbstractGeometricItem* item);
|
||||
};
|
198
src/graphics/directx/DirectXInterface.cpp
Normal file
198
src/graphics/directx/DirectXInterface.cpp
Normal file
|
@ -0,0 +1,198 @@
|
|||
#include "DirectXInterface.h"
|
||||
|
||||
#include "FileLogger.h"
|
||||
|
||||
#include <dxgi.h>
|
||||
#include <dxgi1_6.h>
|
||||
#include <d3d11.h>
|
||||
#include <d3d11on12.h>
|
||||
#include <d3d12.h>
|
||||
#include <d3d12sdklayers.h>
|
||||
|
||||
#include <d2d1_3.h>
|
||||
#include <d2d1_1.h>
|
||||
|
||||
#include <dwrite.h>
|
||||
|
||||
void DirectXInterface::getHardwareAdapter(IDXGIAdapter1** ppAdapter)
|
||||
{
|
||||
*ppAdapter = nullptr;
|
||||
for (UINT adapterIndex = 0; ; ++adapterIndex)
|
||||
{
|
||||
IDXGIAdapter1* pAdapter = nullptr;
|
||||
if (mDxgiFactory->EnumAdapters1(adapterIndex, &pAdapter) == DXGI_ERROR_NOT_FOUND)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (SUCCEEDED(::D3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr)))
|
||||
{
|
||||
*ppAdapter = pAdapter;
|
||||
return;
|
||||
}
|
||||
pAdapter->Release();
|
||||
}
|
||||
}
|
||||
|
||||
bool DirectXInterface::isValid() const
|
||||
{
|
||||
return mIsValid;
|
||||
}
|
||||
|
||||
ID3D12Device* DirectXInterface::getD3dDevice() const
|
||||
{
|
||||
return mD3dDevice.Get();
|
||||
}
|
||||
|
||||
ID3D11On12Device* DirectXInterface::get11On12Device() const
|
||||
{
|
||||
return mD3d11On12Device.Get();
|
||||
}
|
||||
|
||||
IDXGIFactory7* DirectXInterface::getDxgiFactory() const
|
||||
{
|
||||
return mDxgiFactory.Get();
|
||||
}
|
||||
|
||||
ID2D1Factory3* DirectXInterface::getD2dFactory() const
|
||||
{
|
||||
return mD2dFactory.Get();
|
||||
}
|
||||
|
||||
IDWriteFactory* DirectXInterface::getDirectWriteFactory() const
|
||||
{
|
||||
return mDWriteFactory.Get();
|
||||
}
|
||||
|
||||
ID2D1DeviceContext2* DirectXInterface::getD2dContext() const
|
||||
{
|
||||
return mD2dDeviceContext.Get();
|
||||
}
|
||||
|
||||
ID3D12CommandQueue* DirectXInterface::getCommandQueue() const
|
||||
{
|
||||
return mCommandQueue.Get();
|
||||
}
|
||||
|
||||
ID3D11DeviceContext* DirectXInterface::getD3d11DeviceContext() const
|
||||
{
|
||||
return mD3d11DeviceContext.Get();
|
||||
}
|
||||
|
||||
void DirectXInterface::initialize()
|
||||
{
|
||||
MLOG_INFO("Initialize DirectX");
|
||||
createD3dFactory();
|
||||
|
||||
Microsoft::WRL::ComPtr<IDXGIAdapter1> pAdapter;
|
||||
getHardwareAdapter(&pAdapter);
|
||||
createD3dDevice(pAdapter.Get());
|
||||
|
||||
createCommandQueue();
|
||||
|
||||
mIsValid = initializeD2d();
|
||||
}
|
||||
|
||||
void DirectXInterface::initializeD2dStandalone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool DirectXInterface::createD3dFactory()
|
||||
{
|
||||
UINT dxgiFactoryFlags = 0;
|
||||
#if defined(DEBUG) || defined(_DEBUG)
|
||||
{
|
||||
Microsoft::WRL::ComPtr<ID3D12Debug> debugController;
|
||||
if (SUCCEEDED(::D3D12GetDebugInterface(IID_PPV_ARGS(&debugController))))
|
||||
{
|
||||
debugController->EnableDebugLayer();
|
||||
dxgiFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (FAILED(::CreateDXGIFactory2(dxgiFactoryFlags, IID_PPV_ARGS(&mDxgiFactory))))
|
||||
{
|
||||
MLOG_ERROR("Failed to create DXGI Factory");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DirectXInterface::createD3dDevice(IDXGIAdapter1* pAdapter)
|
||||
{
|
||||
if (pAdapter)
|
||||
{
|
||||
if (FAILED(::D3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&mD3dDevice))))
|
||||
{
|
||||
MLOG_ERROR("Failed to create D3D12 device, will try WARP.");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Microsoft::WRL::ComPtr<IDXGIAdapter> pWarpAdapter;
|
||||
mDxgiFactory->EnumWarpAdapter(IID_PPV_ARGS(&pWarpAdapter));
|
||||
if (FAILED(::D3D12CreateDevice(pWarpAdapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&mD3dDevice))))
|
||||
{
|
||||
MLOG_ERROR("Failed to create WARP device.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MLOG_ERROR("Failed to get DirectX adapter.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DirectXInterface::createCommandQueue()
|
||||
{
|
||||
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
|
||||
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||
if (FAILED(mD3dDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue))))
|
||||
{
|
||||
MLOG_ERROR("Failed to create command queue.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DirectXInterface::initializeD2d()
|
||||
{
|
||||
if (!initializeD11on12())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
D2D1_FACTORY_OPTIONS d2dFactoryOptions = {};
|
||||
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory3), &d2dFactoryOptions, &mD2dFactory);
|
||||
Microsoft::WRL::ComPtr<IDXGIDevice> dxgiDevice;
|
||||
mD3d11On12Device.As(&dxgiDevice);
|
||||
|
||||
mD2dFactory->CreateDevice(dxgiDevice.Get(), &mD2dDevice);
|
||||
|
||||
D2D1_DEVICE_CONTEXT_OPTIONS deviceOptions = D2D1_DEVICE_CONTEXT_OPTIONS_NONE;
|
||||
mD2dDevice->CreateDeviceContext(deviceOptions, &mD2dDeviceContext);
|
||||
|
||||
return initializeDirectWrite();
|
||||
}
|
||||
|
||||
bool DirectXInterface::initializeD11on12()
|
||||
{
|
||||
Microsoft::WRL::ComPtr<ID3D11Device> d3d11Device;
|
||||
UINT d3d11DeviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
|
||||
auto pCommandQueue = reinterpret_cast<IUnknown**>(mCommandQueue.GetAddressOf());
|
||||
if (FAILED(D3D11On12CreateDevice(mD3dDevice.Get(), d3d11DeviceFlags, nullptr, 0, pCommandQueue, 1, 0, &d3d11Device, &mD3d11DeviceContext, nullptr)))
|
||||
{
|
||||
MLOG_ERROR("Failed to create D3D11 on 12 Device");
|
||||
return false;
|
||||
}
|
||||
d3d11Device.As(&mD3d11On12Device);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DirectXInterface::initializeDirectWrite()
|
||||
{
|
||||
return SUCCEEDED(::DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), &mDWriteFactory));
|
||||
}
|
64
src/graphics/directx/DirectXInterface.h
Normal file
64
src/graphics/directx/DirectXInterface.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
#pragma once
|
||||
|
||||
#include <wrl.h>
|
||||
#include <dwrite.h>
|
||||
#include <d2d1_3.h>
|
||||
#include <d3d11on12.h>
|
||||
#include <dxgi1_6.h>
|
||||
|
||||
struct ID3D12Device;
|
||||
struct IDXGIFactory7;
|
||||
struct IDXGIAdapter1;
|
||||
struct ID3D12CommandQueue;
|
||||
|
||||
struct ID3D11DeviceContext;
|
||||
struct ID3D11On12Device;
|
||||
|
||||
struct IDWriteFactory;
|
||||
struct ID2D1Factory3;
|
||||
struct ID2D1Device2;
|
||||
struct ID2D1DeviceContext2;
|
||||
|
||||
class DirectXInterface
|
||||
{
|
||||
public:
|
||||
IDXGIFactory7* getDxgiFactory() const;
|
||||
ID3D12Device* getD3dDevice() const;
|
||||
ID3D12CommandQueue* getCommandQueue() const;
|
||||
|
||||
ID3D11On12Device* get11On12Device() const;
|
||||
ID3D11DeviceContext* getD3d11DeviceContext() const;
|
||||
ID2D1Factory3* getD2dFactory() const;
|
||||
ID2D1DeviceContext2* getD2dContext() const;
|
||||
IDWriteFactory* getDirectWriteFactory() const;
|
||||
|
||||
void initialize();
|
||||
void initializeD2dStandalone();
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
private:
|
||||
bool createD3dFactory();
|
||||
bool createD3dDevice(IDXGIAdapter1* ppAdapter);
|
||||
bool createCommandQueue();
|
||||
|
||||
void getHardwareAdapter(IDXGIAdapter1** ppAdapter);
|
||||
|
||||
bool initializeD2d();
|
||||
bool initializeD11on12();
|
||||
bool initializeDirectWrite();
|
||||
|
||||
bool mIsValid{ false };
|
||||
|
||||
Microsoft::WRL::ComPtr<IDXGIFactory7> mDxgiFactory;
|
||||
Microsoft::WRL::ComPtr<ID3D12Device> mD3dDevice;
|
||||
Microsoft::WRL::ComPtr<ID3D12CommandQueue> mCommandQueue;
|
||||
|
||||
// 2D Rendering - e.g. text
|
||||
Microsoft::WRL::ComPtr<ID3D11DeviceContext> mD3d11DeviceContext;
|
||||
Microsoft::WRL::ComPtr<ID3D11On12Device> mD3d11On12Device;
|
||||
Microsoft::WRL::ComPtr<ID2D1Factory3> mD2dFactory;
|
||||
Microsoft::WRL::ComPtr<ID2D1Device2> mD2dDevice;
|
||||
Microsoft::WRL::ComPtr<ID2D1DeviceContext2> mD2dDeviceContext;
|
||||
Microsoft::WRL::ComPtr<IDWriteFactory> mDWriteFactory;
|
||||
};
|
|
@ -16,7 +16,9 @@
|
|||
#include "DirectXShaderProgram.h"
|
||||
#include "DirectXMeshPainter.h"
|
||||
#include "DirectXTextPainter.h"
|
||||
#include "DirectX2dPainter.h"
|
||||
#include "DirectXMesh.h"
|
||||
#include "DirectXInterface.h"
|
||||
|
||||
#include "File.h"
|
||||
|
||||
|
@ -27,7 +29,8 @@
|
|||
DirectXPainter::DirectXPainter(DrawingContext* context)
|
||||
: AbstractPainter(context),
|
||||
mMeshPainter(std::make_unique<DirectXMeshPainter>()),
|
||||
mTextPainter(std::make_unique<DirectXTextPainter>())
|
||||
mTextPainter(std::make_unique<DirectXTextPainter>()),
|
||||
m2dPainter(std::make_unique<DirectX2dPainter>())
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -59,6 +62,24 @@ void DirectXPainter::updateMesh(ID3D12Device* device)
|
|||
|
||||
void DirectXPainter::paint()
|
||||
{
|
||||
if (!mDxInterface)
|
||||
{
|
||||
mDxInterface = std::make_unique<DirectXInterface>();
|
||||
mDxInterface->initializeD2dStandalone();
|
||||
}
|
||||
|
||||
auto scene = mDrawingContext->getSurface()->getScene();
|
||||
for (const auto item : scene->getItems())
|
||||
{
|
||||
if (item->getType() == SceneItem::Type::MODEL && item->isVisible())
|
||||
{
|
||||
auto model = dynamic_cast<SceneModel*>(item);
|
||||
if (model->getGeometry())
|
||||
{
|
||||
m2dPainter->paint(mDxInterface->getD2dContext(), model->getGeometry());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DirectXPainter::paintBackground(const D3D12_CPU_DESCRIPTOR_HANDLE& rtvHandle, ID3D12GraphicsCommandList* commandList)
|
||||
|
@ -84,3 +105,8 @@ void DirectXPainter::paintText(ID2D1DeviceContext2* d2dContext, IDWriteFactory*
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool DirectXPainter::supportsGeometryPrimitives() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
class DrawingContext;
|
||||
class DirectXMeshPainter;
|
||||
class DirectXTextPainter;
|
||||
class DirectX2dPainter;
|
||||
class DirectXInterface;
|
||||
|
||||
class DirectXPainter : public AbstractPainter
|
||||
{
|
||||
|
@ -32,9 +34,14 @@ public:
|
|||
|
||||
void paintText(ID2D1DeviceContext2* d2dContext, IDWriteFactory* directWriteFactory);
|
||||
|
||||
bool supportsGeometryPrimitives() const override;
|
||||
|
||||
void updateMesh(ID3D12Device* device);
|
||||
|
||||
private:
|
||||
std::unique_ptr<DirectXMeshPainter> mMeshPainter;
|
||||
std::unique_ptr<DirectXTextPainter> mTextPainter;
|
||||
std::unique_ptr<DirectX2dPainter> m2dPainter;
|
||||
|
||||
std::unique_ptr<DirectXInterface> mDxInterface;
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue