2019.4
This commit is contained in:
parent
70a1778d22
commit
85f90cda62
|
@ -92,11 +92,19 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\CGI\CGI.h" />
|
||||
<ClInclude Include="src\CGI\CommandBufferD3D12.h" />
|
||||
<ClInclude Include="src\CGI\GeometryD3D12.h" />
|
||||
<ClInclude Include="src\CGI\PipelineD3D12.h" />
|
||||
<ClInclude Include="src\CGI\RendererD3D12.h" />
|
||||
<ClInclude Include="src\CGI\ShaderD3D12.h" />
|
||||
<ClInclude Include="src\stdafx.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\CGI\CommandBufferD3D12.cpp" />
|
||||
<ClCompile Include="src\CGI\GeometryD3D12.cpp" />
|
||||
<ClCompile Include="src\CGI\PipelineD3D12.cpp" />
|
||||
<ClCompile Include="src\CGI\RendererD3D12.cpp" />
|
||||
<ClCompile Include="src\CGI\ShaderD3D12.cpp" />
|
||||
<ClCompile Include="src\main.cpp" />
|
||||
<ClCompile Include="src\stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
|
|
|
@ -30,6 +30,18 @@
|
|||
<ClInclude Include="src\CGI\RendererD3D12.h">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\CGI\CommandBufferD3D12.h">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\CGI\GeometryD3D12.h">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\CGI\PipelineD3D12.h">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\CGI\ShaderD3D12.h">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\main.cpp">
|
||||
|
@ -41,5 +53,17 @@
|
|||
<ClCompile Include="src\CGI\RendererD3D12.cpp">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\CGI\CommandBufferD3D12.cpp">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\CGI\GeometryD3D12.cpp">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\CGI\PipelineD3D12.cpp">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\CGI\ShaderD3D12.cpp">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,3 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "CommandBufferD3D12.h"
|
||||
#include "GeometryD3D12.h"
|
||||
#include "PipelineD3D12.h"
|
||||
#include "ShaderD3D12.h"
|
||||
#include "RendererD3D12.h"
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
#include "stdafx.h"
|
||||
|
||||
using namespace verus;
|
||||
using namespace verus::CGI;
|
||||
|
||||
ID3D12GraphicsCommandList* CommandBufferD3D12::GetGraphicsCommandList() const
|
||||
{
|
||||
VERUS_QREF_RENDERER;
|
||||
return _pCommandLists[renderer->GetRingBufferIndex()].Get();
|
||||
}
|
||||
|
||||
CommandBufferD3D12::CommandBufferD3D12()
|
||||
{
|
||||
}
|
||||
|
||||
CommandBufferD3D12::~CommandBufferD3D12()
|
||||
{
|
||||
Done();
|
||||
}
|
||||
|
||||
void CommandBufferD3D12::Init()
|
||||
{
|
||||
VERUS_INIT();
|
||||
}
|
||||
|
||||
void CommandBufferD3D12::Done()
|
||||
{
|
||||
VERUS_DONE(CommandBufferD3D12);
|
||||
}
|
||||
|
||||
void CommandBufferD3D12::Begin()
|
||||
{
|
||||
HRESULT hr = 0;
|
||||
if (FAILED(hr = GetGraphicsCommandList()->Reset(nullptr, nullptr)))
|
||||
throw VERUS_RUNTIME_ERROR << "Reset(), hr=" << VERUS_HR(hr);
|
||||
}
|
||||
|
||||
void CommandBufferD3D12::End()
|
||||
{
|
||||
HRESULT hr = 0;
|
||||
if (FAILED(hr = GetGraphicsCommandList()->Close()))
|
||||
throw VERUS_RUNTIME_ERROR << "Close(), hr=" << VERUS_HR(hr);
|
||||
}
|
||||
|
||||
void CommandBufferD3D12::BindVertexBuffers()
|
||||
{
|
||||
GetGraphicsCommandList()->IASetVertexBuffers(0, 1, nullptr);
|
||||
}
|
||||
|
||||
void CommandBufferD3D12::BindIndexBuffer()
|
||||
{
|
||||
GetGraphicsCommandList()->IASetIndexBuffer(nullptr);
|
||||
}
|
||||
|
||||
void CommandBufferD3D12::SetScissor()
|
||||
{
|
||||
GetGraphicsCommandList()->RSSetScissorRects(1, nullptr);
|
||||
}
|
||||
|
||||
void CommandBufferD3D12::SetViewport()
|
||||
{
|
||||
GetGraphicsCommandList()->RSSetViewports(1, nullptr);
|
||||
}
|
||||
|
||||
void CommandBufferD3D12::BindPipeline()
|
||||
{
|
||||
GetGraphicsCommandList()->SetPipelineState(nullptr);
|
||||
}
|
||||
|
||||
void CommandBufferD3D12::Clear(ClearFlags clearFlags)
|
||||
{
|
||||
VERUS_QREF_RENDERER;
|
||||
|
||||
if (clearFlags & ClearFlags::color)
|
||||
GetGraphicsCommandList()->ClearRenderTargetView({}, renderer.GetClearColor().ToPointer(), 0, nullptr);
|
||||
|
||||
UINT cf = 0;
|
||||
if (clearFlags & ClearFlags::depth) cf |= D3D12_CLEAR_FLAG_DEPTH;
|
||||
if (clearFlags & ClearFlags::stencil) cf |= D3D12_CLEAR_FLAG_STENCIL;
|
||||
if (cf)
|
||||
GetGraphicsCommandList()->ClearDepthStencilView({}, static_cast<D3D12_CLEAR_FLAGS>(cf), 0, 0, 0, nullptr);
|
||||
}
|
||||
|
||||
void CommandBufferD3D12::Draw()
|
||||
{
|
||||
GetGraphicsCommandList()->DrawInstanced(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void CommandBufferD3D12::DrawIndexed()
|
||||
{
|
||||
GetGraphicsCommandList()->DrawIndexedInstanced(0, 0, 0, 0, 0);
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace CGI
|
||||
{
|
||||
class CommandBufferD3D12 : public BaseCommandBuffer
|
||||
{
|
||||
ComPtr<ID3D12GraphicsCommandList> _pCommandLists[BaseRenderer::ringBufferSize];
|
||||
|
||||
ID3D12GraphicsCommandList* GetGraphicsCommandList() const;
|
||||
|
||||
public:
|
||||
CommandBufferD3D12();
|
||||
virtual ~CommandBufferD3D12() override;
|
||||
|
||||
virtual void Init() override;
|
||||
virtual void Done() override;
|
||||
|
||||
virtual void Begin() override;
|
||||
virtual void End() override;
|
||||
|
||||
virtual void BindVertexBuffers() override;
|
||||
virtual void BindIndexBuffer() override;
|
||||
|
||||
virtual void SetScissor() override;
|
||||
virtual void SetViewport() override;
|
||||
|
||||
virtual void BindPipeline() override;
|
||||
virtual void Clear(ClearFlags clearFlags) override;
|
||||
virtual void Draw() override;
|
||||
virtual void DrawIndexed() override;
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#include "stdafx.h"
|
||||
|
||||
using namespace verus;
|
||||
using namespace verus::CGI;
|
||||
|
||||
GeometryD3D12::GeometryD3D12()
|
||||
{
|
||||
}
|
||||
|
||||
GeometryD3D12::~GeometryD3D12()
|
||||
{
|
||||
Done();
|
||||
}
|
||||
|
||||
void GeometryD3D12::Init(RcGeometryDesc desc)
|
||||
{
|
||||
VERUS_INIT();
|
||||
}
|
||||
|
||||
void GeometryD3D12::Done()
|
||||
{
|
||||
VERUS_DONE(GeometryD3D12);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace CGI
|
||||
{
|
||||
class GeometryD3D12 : public BaseGeometry
|
||||
{
|
||||
ComPtr<ID3D12Resource> _pVertexBuffer;
|
||||
ComPtr<ID3D12Resource> _pIndexBuffer;
|
||||
|
||||
public:
|
||||
GeometryD3D12();
|
||||
virtual ~GeometryD3D12() override;
|
||||
|
||||
virtual void Init(RcGeometryDesc desc) override;
|
||||
virtual void Done() override;
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#include "stdafx.h"
|
||||
|
||||
using namespace verus;
|
||||
using namespace verus::CGI;
|
||||
|
||||
PipelineD3D12::PipelineD3D12()
|
||||
{
|
||||
}
|
||||
|
||||
PipelineD3D12::~PipelineD3D12()
|
||||
{
|
||||
Done();
|
||||
}
|
||||
|
||||
void PipelineD3D12::Init()
|
||||
{
|
||||
VERUS_INIT();
|
||||
}
|
||||
|
||||
void PipelineD3D12::Done()
|
||||
{
|
||||
VERUS_DONE(PipelineD3D12);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace CGI
|
||||
{
|
||||
class PipelineD3D12 : public BasePipeline
|
||||
{
|
||||
ComPtr<ID3D12PipelineState> _pPipelineState;
|
||||
|
||||
public:
|
||||
PipelineD3D12();
|
||||
virtual ~PipelineD3D12() override;
|
||||
|
||||
virtual void Init() override;
|
||||
virtual void Done() override;
|
||||
};
|
||||
}
|
||||
}
|
|
@ -27,20 +27,38 @@ void RendererD3D12::Init()
|
|||
|
||||
void RendererD3D12::Done()
|
||||
{
|
||||
if (_pCommandQueue)
|
||||
QueueWaitIdle();
|
||||
if (_hFence != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle(_hFence);
|
||||
_hFence = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
_pFence.Reset();
|
||||
VERUS_FOR(i, ringBufferSize)
|
||||
_pCommandLists[i].Reset();
|
||||
VERUS_FOR(i, ringBufferSize)
|
||||
_mapCommandAllocators[i].clear();
|
||||
_dSwapChainBuffersRTVs.Reset();
|
||||
_vSwapChainBuffers.clear();
|
||||
_pSwapChain.Reset();
|
||||
_pCommandQueue.Reset();
|
||||
_pDevice.Reset();
|
||||
|
||||
VERUS_DONE(RendererD3D12);
|
||||
}
|
||||
|
||||
void RendererD3D12::EnableDebugLayer()
|
||||
{
|
||||
CComPtr<ID3D12Debug> pDebug;
|
||||
ComPtr<ID3D12Debug> pDebug;
|
||||
if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&pDebug))))
|
||||
pDebug->EnableDebugLayer();
|
||||
}
|
||||
|
||||
CComPtr<IDXGIFactory7> RendererD3D12::CreateDXGIFactory()
|
||||
ComPtr<IDXGIFactory6> RendererD3D12::CreateDXGIFactory()
|
||||
{
|
||||
HRESULT hr = 0;
|
||||
CComPtr<IDXGIFactory7> pFactory;
|
||||
ComPtr<IDXGIFactory6> pFactory;
|
||||
UINT flags = 0;
|
||||
#if defined(_DEBUG) || defined(VERUS_DEBUG)
|
||||
flags = DXGI_CREATE_FACTORY_DEBUG;
|
||||
|
@ -50,16 +68,16 @@ CComPtr<IDXGIFactory7> RendererD3D12::CreateDXGIFactory()
|
|||
return pFactory;
|
||||
}
|
||||
|
||||
CComPtr<IDXGIAdapter4> RendererD3D12::GetAdapter(CComPtr<IDXGIFactory7> pFactory)
|
||||
ComPtr<IDXGIAdapter4> RendererD3D12::GetAdapter(ComPtr<IDXGIFactory6> pFactory)
|
||||
{
|
||||
HRESULT hr = 0;
|
||||
CComPtr<IDXGIAdapter4> pAdapter;
|
||||
ComPtr<IDXGIAdapter4> pAdapter;
|
||||
if (FAILED(hr = pFactory->EnumAdapterByGpuPreference(0, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, IID_PPV_ARGS(&pAdapter))))
|
||||
throw VERUS_RUNTIME_ERROR << "EnumAdapterByGpuPreference(), hr=" << VERUS_HR(hr);
|
||||
return pAdapter;
|
||||
}
|
||||
|
||||
bool RendererD3D12::CheckFeatureSupportAllowTearing(CComPtr<IDXGIFactory7> pFactory)
|
||||
bool RendererD3D12::CheckFeatureSupportAllowTearing(ComPtr<IDXGIFactory6> pFactory)
|
||||
{
|
||||
BOOL data = FALSE;
|
||||
if (FAILED(pFactory->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &data, sizeof(data))))
|
||||
|
@ -70,15 +88,15 @@ bool RendererD3D12::CheckFeatureSupportAllowTearing(CComPtr<IDXGIFactory7> pFact
|
|||
void RendererD3D12::CreateSwapChainBuffersRTVs()
|
||||
{
|
||||
HRESULT hr = 0;
|
||||
_swapChainBuffersRTVs = CreateDescriptorHeap(D3D12_DESCRIPTOR_HEAP_TYPE_RTV, _swapChainDesc.BufferCount);
|
||||
_vSwapChainBuffers.resize(_swapChainDesc.BufferCount);
|
||||
auto dh = _swapChainBuffersRTVs->GetCPUDescriptorHandleForHeapStart();
|
||||
VERUS_U_FOR(i, _swapChainDesc.BufferCount)
|
||||
_vSwapChainBuffers.resize(_numSwapChainBuffers);
|
||||
_dSwapChainBuffersRTVs = CreateDescriptorHeap(D3D12_DESCRIPTOR_HEAP_TYPE_RTV, _numSwapChainBuffers);
|
||||
auto dh = _dSwapChainBuffersRTVs->GetCPUDescriptorHandleForHeapStart();
|
||||
VERUS_U_FOR(i, _numSwapChainBuffers)
|
||||
{
|
||||
CComPtr<ID3D12Resource> pBuffer;
|
||||
ComPtr<ID3D12Resource> pBuffer;
|
||||
if (FAILED(hr = _pSwapChain->GetBuffer(i, IID_PPV_ARGS(&pBuffer))))
|
||||
throw VERUS_RUNTIME_ERROR << "GetBuffer(), hr=" << VERUS_HR(hr);
|
||||
_pDevice->CreateRenderTargetView(pBuffer, nullptr, dh);
|
||||
_pDevice->CreateRenderTargetView(pBuffer.Get(), nullptr, dh);
|
||||
_vSwapChainBuffers[i] = pBuffer;
|
||||
dh.ptr += _descHandleIncSizeRTV;
|
||||
}
|
||||
|
@ -86,6 +104,7 @@ void RendererD3D12::CreateSwapChainBuffersRTVs()
|
|||
|
||||
void RendererD3D12::InitD3D()
|
||||
{
|
||||
VERUS_QREF_RENDERER;
|
||||
VERUS_QREF_SETTINGS;
|
||||
|
||||
HRESULT hr = 0;
|
||||
|
@ -94,15 +113,17 @@ void RendererD3D12::InitD3D()
|
|||
EnableDebugLayer();
|
||||
#endif
|
||||
|
||||
CComPtr<IDXGIFactory7> pFactory = CreateDXGIFactory();
|
||||
ComPtr<IDXGIFactory6> pFactory = CreateDXGIFactory();
|
||||
|
||||
CComPtr<IDXGIAdapter4> pAdapter = GetAdapter(pFactory);
|
||||
ComPtr<IDXGIAdapter4> pAdapter = GetAdapter(pFactory);
|
||||
|
||||
if (FAILED(hr = D3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&_pDevice))))
|
||||
if (FAILED(hr = D3D12CreateDevice(pAdapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&_pDevice))))
|
||||
throw VERUS_RUNTIME_ERROR << "D3D12CreateDevice(), hr=" << VERUS_HR(hr);
|
||||
|
||||
_pCommandQueue = CreateCommandQueue(D3D12_COMMAND_LIST_TYPE_DIRECT);
|
||||
|
||||
_numSwapChainBuffers = settings._screenVSync ? 3 : 2;
|
||||
|
||||
_swapChainDesc.Width = settings._screenSizeWidth;
|
||||
_swapChainDesc.Height = settings._screenSizeHeight;
|
||||
_swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
|
@ -110,39 +131,45 @@ void RendererD3D12::InitD3D()
|
|||
_swapChainDesc.SampleDesc.Count = 1;
|
||||
_swapChainDesc.SampleDesc.Quality = 0;
|
||||
_swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
_swapChainDesc.BufferCount = 2;
|
||||
_swapChainDesc.BufferCount = _numSwapChainBuffers;
|
||||
_swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
|
||||
_swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
_swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
|
||||
_swapChainDesc.Flags = CheckFeatureSupportAllowTearing(pFactory) ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0;
|
||||
|
||||
CComPtr<IDXGISwapChain1> pSwapChain1;
|
||||
if (FAILED(hr = pFactory->CreateSwapChainForHwnd(_pCommandQueue, GetActiveWindow(), &_swapChainDesc, nullptr, nullptr, &pSwapChain1)))
|
||||
SDL_Window* pWnd = renderer.GetMainWindow()->GetSDL();
|
||||
VERUS_RT_ASSERT(pWnd);
|
||||
SDL_SysWMinfo wmInfo;
|
||||
SDL_VERSION(&wmInfo.version);
|
||||
SDL_GetWindowWMInfo(pWnd, &wmInfo);
|
||||
HWND hWnd = wmInfo.info.win.window;
|
||||
|
||||
ComPtr<IDXGISwapChain1> pSwapChain1;
|
||||
if (FAILED(hr = pFactory->CreateSwapChainForHwnd(_pCommandQueue.Get(), hWnd, &_swapChainDesc, nullptr, nullptr, &pSwapChain1)))
|
||||
throw VERUS_RUNTIME_ERROR << "CreateSwapChainForHwnd(), hr=" << VERUS_HR(hr);
|
||||
if (FAILED(hr = pSwapChain1.QueryInterface(&_pSwapChain)))
|
||||
if (FAILED(hr = pSwapChain1.As(&_pSwapChain)))
|
||||
throw VERUS_RUNTIME_ERROR << "QueryInterface(), hr=" << VERUS_HR(hr);
|
||||
|
||||
_descHandleIncSizeRTV = _pDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
||||
|
||||
_currentBackBufferIndex = _pSwapChain->GetCurrentBackBufferIndex();
|
||||
_swapChainBufferIndex = _pSwapChain->GetCurrentBackBufferIndex();
|
||||
|
||||
CreateSwapChainBuffersRTVs();
|
||||
|
||||
_vCommandAllocators.resize(_swapChainDesc.BufferCount);
|
||||
VERUS_U_FOR(i, _swapChainDesc.BufferCount)
|
||||
_vCommandAllocators[i] = CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT);
|
||||
VERUS_FOR(i, ringBufferSize)
|
||||
_mapCommandAllocators[i][std::this_thread::get_id()] = CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT);
|
||||
|
||||
_pCommandList = CreateCommandList(D3D12_COMMAND_LIST_TYPE_DIRECT, _vCommandAllocators[_currentBackBufferIndex]);
|
||||
VERUS_FOR(i, ringBufferSize)
|
||||
_pCommandLists[i] = CreateCommandList(D3D12_COMMAND_LIST_TYPE_DIRECT, _mapCommandAllocators[i][std::this_thread::get_id()]);
|
||||
|
||||
_pFence = CreateFence();
|
||||
_hFence = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
||||
_vFenceValues.resize(_swapChainDesc.BufferCount);
|
||||
}
|
||||
|
||||
CComPtr<ID3D12CommandQueue> RendererD3D12::CreateCommandQueue(D3D12_COMMAND_LIST_TYPE type)
|
||||
ComPtr<ID3D12CommandQueue> RendererD3D12::CreateCommandQueue(D3D12_COMMAND_LIST_TYPE type)
|
||||
{
|
||||
HRESULT hr = 0;
|
||||
CComPtr<ID3D12CommandQueue> pCommandQueue;
|
||||
ComPtr<ID3D12CommandQueue> pCommandQueue;
|
||||
D3D12_COMMAND_QUEUE_DESC desc = {};
|
||||
desc.Type = type;
|
||||
desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
|
||||
|
@ -152,30 +179,30 @@ CComPtr<ID3D12CommandQueue> RendererD3D12::CreateCommandQueue(D3D12_COMMAND_LIST
|
|||
return pCommandQueue;
|
||||
}
|
||||
|
||||
CComPtr<ID3D12CommandAllocator> RendererD3D12::CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE type)
|
||||
ComPtr<ID3D12CommandAllocator> RendererD3D12::CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE type)
|
||||
{
|
||||
HRESULT hr = 0;
|
||||
CComPtr<ID3D12CommandAllocator> pCommandAllocator;
|
||||
ComPtr<ID3D12CommandAllocator> pCommandAllocator;
|
||||
if (FAILED(hr = _pDevice->CreateCommandAllocator(type, IID_PPV_ARGS(&pCommandAllocator))))
|
||||
throw VERUS_RUNTIME_ERROR << "CreateCommandAllocator(), hr=" << VERUS_HR(hr);
|
||||
return pCommandAllocator;
|
||||
}
|
||||
|
||||
CComPtr<ID3D12GraphicsCommandList> RendererD3D12::CreateCommandList(D3D12_COMMAND_LIST_TYPE type, CComPtr<ID3D12CommandAllocator> pCommandAllocator)
|
||||
ComPtr<ID3D12GraphicsCommandList> RendererD3D12::CreateCommandList(D3D12_COMMAND_LIST_TYPE type, ComPtr<ID3D12CommandAllocator> pCommandAllocator)
|
||||
{
|
||||
HRESULT hr = 0;
|
||||
CComPtr<ID3D12GraphicsCommandList> pGraphicsCommandList;
|
||||
if (FAILED(hr = _pDevice->CreateCommandList(0, type, pCommandAllocator, nullptr, IID_PPV_ARGS(&pGraphicsCommandList))))
|
||||
ComPtr<ID3D12GraphicsCommandList> pGraphicsCommandList;
|
||||
if (FAILED(hr = _pDevice->CreateCommandList(0, type, pCommandAllocator.Get(), nullptr, IID_PPV_ARGS(&pGraphicsCommandList))))
|
||||
throw VERUS_RUNTIME_ERROR << "CreateCommandList(), hr=" << VERUS_HR(hr);
|
||||
if (FAILED(hr = pGraphicsCommandList->Close()))
|
||||
throw VERUS_RUNTIME_ERROR << "Close(), hr=" << VERUS_HR(hr);
|
||||
return pGraphicsCommandList;
|
||||
}
|
||||
|
||||
CComPtr<ID3D12DescriptorHeap> RendererD3D12::CreateDescriptorHeap(D3D12_DESCRIPTOR_HEAP_TYPE type, UINT num)
|
||||
ComPtr<ID3D12DescriptorHeap> RendererD3D12::CreateDescriptorHeap(D3D12_DESCRIPTOR_HEAP_TYPE type, UINT num)
|
||||
{
|
||||
HRESULT hr = 0;
|
||||
CComPtr<ID3D12DescriptorHeap> pDescriptorHeap;
|
||||
ComPtr<ID3D12DescriptorHeap> pDescriptorHeap;
|
||||
D3D12_DESCRIPTOR_HEAP_DESC desc = {};
|
||||
desc.Type = type;
|
||||
desc.NumDescriptors = num;
|
||||
|
@ -184,20 +211,20 @@ CComPtr<ID3D12DescriptorHeap> RendererD3D12::CreateDescriptorHeap(D3D12_DESCRIPT
|
|||
return pDescriptorHeap;
|
||||
}
|
||||
|
||||
CComPtr<ID3D12Fence> RendererD3D12::CreateFence()
|
||||
ComPtr<ID3D12Fence> RendererD3D12::CreateFence()
|
||||
{
|
||||
HRESULT hr = 0;
|
||||
CComPtr<ID3D12Fence> pFence;
|
||||
ComPtr<ID3D12Fence> pFence;
|
||||
if (FAILED(hr = _pDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&pFence))))
|
||||
throw VERUS_RUNTIME_ERROR << "CreateFence(), hr=" << VERUS_HR(hr);
|
||||
return pFence;
|
||||
}
|
||||
|
||||
UINT64 RendererD3D12::Signal()
|
||||
UINT64 RendererD3D12::QueueSignal()
|
||||
{
|
||||
HRESULT hr = 0;
|
||||
const UINT64 value = ++_fenceValue;
|
||||
if (FAILED(hr = _pCommandQueue->Signal(_pFence, value)))
|
||||
const UINT64 value = _nextFenceValue++;
|
||||
if (FAILED(hr = _pCommandQueue->Signal(_pFence.Get(), value)))
|
||||
throw VERUS_RUNTIME_ERROR << "Signal(), hr=" << VERUS_HR(hr);
|
||||
return value;
|
||||
}
|
||||
|
@ -213,9 +240,9 @@ void RendererD3D12::WaitForFenceValue(UINT64 value)
|
|||
}
|
||||
}
|
||||
|
||||
void RendererD3D12::Flush()
|
||||
void RendererD3D12::QueueWaitIdle()
|
||||
{
|
||||
const UINT64 value = Signal();
|
||||
const UINT64 value = QueueSignal();
|
||||
WaitForFenceValue(value);
|
||||
}
|
||||
|
||||
|
@ -231,29 +258,39 @@ D3D12_RESOURCE_BARRIER RendererD3D12::MakeResourceBarrierTransition(ID3D12Resour
|
|||
return rb;
|
||||
}
|
||||
|
||||
void RendererD3D12::PrepareDraw()
|
||||
void RendererD3D12::BeginFrame()
|
||||
{
|
||||
auto pBackBuffer = _vSwapChainBuffers[_currentBackBufferIndex];
|
||||
auto pCommandAllocator = _vCommandAllocators[_currentBackBufferIndex];
|
||||
HRESULT hr = 0;
|
||||
|
||||
pCommandAllocator->Reset();
|
||||
_pCommandList->Reset(pCommandAllocator, nullptr);
|
||||
WaitForFenceValue(_fenceValues[_ringBufferIndex]);
|
||||
|
||||
const auto rb = MakeResourceBarrierTransition(pBackBuffer, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
_pCommandList->ResourceBarrier(1, &rb);
|
||||
_swapChainBufferIndex = _pSwapChain->GetCurrentBackBufferIndex();
|
||||
|
||||
auto pCommandAllocator = _mapCommandAllocators[_ringBufferIndex][std::this_thread::get_id()];
|
||||
if (FAILED(hr = pCommandAllocator->Reset()))
|
||||
throw VERUS_RUNTIME_ERROR << "Reset(), hr=" << VERUS_HR(hr);
|
||||
|
||||
if (FAILED(hr = _pCommandLists[_ringBufferIndex]->Reset(pCommandAllocator.Get(), nullptr)))
|
||||
throw VERUS_RUNTIME_ERROR << "Reset(), hr=" << VERUS_HR(hr);
|
||||
auto pBackBuffer = _vSwapChainBuffers[_swapChainBufferIndex];
|
||||
const auto rb = MakeResourceBarrierTransition(pBackBuffer.Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
_pCommandLists[_ringBufferIndex]->ResourceBarrier(1, &rb);
|
||||
}
|
||||
|
||||
void RendererD3D12::Clear(UINT32 flags)
|
||||
void RendererD3D12::EndFrame()
|
||||
{
|
||||
static float x = 0;
|
||||
x += 0.0001f;
|
||||
x = fmod(x, 1.f);
|
||||
FLOAT clearColor[] = { x, 0.5f, 0.25f, 1.0f };
|
||||
HRESULT hr = 0;
|
||||
|
||||
auto dh = _swapChainBuffersRTVs->GetCPUDescriptorHandleForHeapStart();
|
||||
dh.ptr += _currentBackBufferIndex * _descHandleIncSizeRTV;
|
||||
auto pBackBuffer = _vSwapChainBuffers[_swapChainBufferIndex];
|
||||
const auto rb = MakeResourceBarrierTransition(pBackBuffer.Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
|
||||
_pCommandLists[_ringBufferIndex]->ResourceBarrier(1, &rb);
|
||||
|
||||
_pCommandList->ClearRenderTargetView(dh, clearColor, 0, nullptr);
|
||||
if (FAILED(hr = _pCommandLists[_ringBufferIndex]->Close()))
|
||||
throw VERUS_RUNTIME_ERROR << "Close(), hr=" << VERUS_HR(hr);
|
||||
ID3D12CommandList* ppCommandLists[] = { _pCommandLists[_ringBufferIndex].Get() };
|
||||
_pCommandQueue->ExecuteCommandLists(VERUS_ARRAY_LENGTH(ppCommandLists), ppCommandLists);
|
||||
|
||||
_fenceValues[_ringBufferIndex] = QueueSignal();
|
||||
}
|
||||
|
||||
void RendererD3D12::Present()
|
||||
|
@ -263,23 +300,20 @@ void RendererD3D12::Present()
|
|||
bool g_VSync = false;
|
||||
bool g_TearingSupported = false;
|
||||
|
||||
auto pBackBuffer = _vSwapChainBuffers[_currentBackBufferIndex];
|
||||
|
||||
const auto rb = MakeResourceBarrierTransition(pBackBuffer, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
|
||||
_pCommandList->ResourceBarrier(1, &rb);
|
||||
|
||||
if (FAILED(hr = _pCommandList->Close()))
|
||||
throw VERUS_RUNTIME_ERROR << "Close(), hr=" << VERUS_HR(hr);
|
||||
|
||||
ID3D12CommandList* ppCommandLists[] = { _pCommandList };
|
||||
_pCommandQueue->ExecuteCommandLists(VERUS_ARRAY_LENGTH(ppCommandLists), ppCommandLists);
|
||||
|
||||
_vFenceValues[_currentBackBufferIndex] = Signal();
|
||||
UINT syncInterval = g_VSync ? 1 : 0;
|
||||
UINT flags = g_TearingSupported && !g_VSync ? DXGI_PRESENT_ALLOW_TEARING : 0;
|
||||
const UINT syncInterval = g_VSync ? 1 : 0;
|
||||
const UINT flags = g_TearingSupported && !g_VSync ? DXGI_PRESENT_ALLOW_TEARING : 0;
|
||||
if (FAILED(hr = _pSwapChain->Present(syncInterval, flags)))
|
||||
throw VERUS_RUNTIME_ERROR << "Present(), hr=" << VERUS_HR(hr);
|
||||
|
||||
_currentBackBufferIndex = _pSwapChain->GetCurrentBackBufferIndex();
|
||||
WaitForFenceValue(_vFenceValues[_currentBackBufferIndex]);
|
||||
_ringBufferIndex = (_ringBufferIndex + 1) % ringBufferSize;
|
||||
}
|
||||
|
||||
void RendererD3D12::Clear(UINT32 flags)
|
||||
{
|
||||
VERUS_QREF_RENDERER;
|
||||
|
||||
auto dh = _dSwapChainBuffersRTVs->GetCPUDescriptorHandleForHeapStart();
|
||||
dh.ptr += _swapChainBufferIndex * _descHandleIncSizeRTV;
|
||||
|
||||
_pCommandLists[_ringBufferIndex]->ClearRenderTargetView(dh, renderer.GetClearColor().ToPointer(), 0, nullptr);
|
||||
}
|
||||
|
|
|
@ -6,20 +6,21 @@ namespace verus
|
|||
{
|
||||
class RendererD3D12 : public Singleton<RendererD3D12>, public BaseRenderer
|
||||
{
|
||||
CComPtr<IDXGISwapChain4> _pSwapChain;
|
||||
CComPtr<ID3D12Device3> _pDevice;
|
||||
CComPtr<ID3D12CommandQueue> _pCommandQueue;
|
||||
CComPtr<ID3D12Fence> _pFence;
|
||||
CComPtr<ID3D12DescriptorHeap> _swapChainBuffersRTVs;
|
||||
Vector<CComPtr<ID3D12Resource>> _vSwapChainBuffers;
|
||||
Vector<CComPtr<ID3D12CommandAllocator>> _vCommandAllocators;
|
||||
Vector<UINT64> _vFenceValues;
|
||||
CComPtr<ID3D12GraphicsCommandList> _pCommandList;
|
||||
DXGI_SWAP_CHAIN_DESC1 _swapChainDesc = {};
|
||||
HANDLE _hFence = 0;
|
||||
UINT64 _fenceValue = 0;
|
||||
UINT _descHandleIncSizeRTV = 0;
|
||||
UINT _currentBackBufferIndex = 0;
|
||||
typedef Map<std::thread::id, ComPtr<ID3D12CommandAllocator>> TMapCommandAllocators;
|
||||
|
||||
ComPtr<ID3D12Device3> _pDevice;
|
||||
ComPtr<ID3D12CommandQueue> _pCommandQueue;
|
||||
ComPtr<IDXGISwapChain4> _pSwapChain;
|
||||
Vector<ComPtr<ID3D12Resource>> _vSwapChainBuffers;
|
||||
ComPtr<ID3D12DescriptorHeap> _dSwapChainBuffersRTVs;
|
||||
TMapCommandAllocators _mapCommandAllocators[ringBufferSize];
|
||||
ComPtr<ID3D12GraphicsCommandList> _pCommandLists[ringBufferSize];
|
||||
ComPtr<ID3D12Fence> _pFence;
|
||||
HANDLE _hFence = INVALID_HANDLE_VALUE;
|
||||
UINT64 _nextFenceValue = 1;
|
||||
UINT64 _fenceValues[ringBufferSize];
|
||||
UINT _descHandleIncSizeRTV = 0;
|
||||
DXGI_SWAP_CHAIN_DESC1 _swapChainDesc = {};
|
||||
|
||||
public:
|
||||
RendererD3D12();
|
||||
|
@ -30,29 +31,34 @@ namespace verus
|
|||
void Init();
|
||||
void Done();
|
||||
|
||||
VERUS_P(static void EnableDebugLayer());
|
||||
VERUS_P(static CComPtr<IDXGIFactory7> CreateDXGIFactory());
|
||||
VERUS_P(static CComPtr<IDXGIAdapter4> GetAdapter(CComPtr<IDXGIFactory7> pFactory));
|
||||
VERUS_P(static bool CheckFeatureSupportAllowTearing(CComPtr<IDXGIFactory7> pFactory));
|
||||
VERUS_P(void CreateSwapChainBuffersRTVs());
|
||||
VERUS_P(void InitD3D());
|
||||
private:
|
||||
static void EnableDebugLayer();
|
||||
static ComPtr<IDXGIFactory6> CreateDXGIFactory();
|
||||
static ComPtr<IDXGIAdapter4> GetAdapter(ComPtr<IDXGIFactory6> pFactory);
|
||||
static bool CheckFeatureSupportAllowTearing(ComPtr<IDXGIFactory6> pFactory);
|
||||
void CreateSwapChainBuffersRTVs();
|
||||
void InitD3D();
|
||||
|
||||
virtual Gapi GetGapi() override { return Gapi::direct3D12; }
|
||||
|
||||
CComPtr<ID3D12CommandQueue> CreateCommandQueue(D3D12_COMMAND_LIST_TYPE type);
|
||||
CComPtr<ID3D12CommandAllocator> CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE type);
|
||||
CComPtr<ID3D12GraphicsCommandList> CreateCommandList(D3D12_COMMAND_LIST_TYPE type, CComPtr<ID3D12CommandAllocator> pCommandAllocator);
|
||||
CComPtr<ID3D12DescriptorHeap> CreateDescriptorHeap(D3D12_DESCRIPTOR_HEAP_TYPE type, UINT num);
|
||||
CComPtr<ID3D12Fence> CreateFence();
|
||||
UINT64 Signal();
|
||||
public:
|
||||
ComPtr<ID3D12CommandQueue> CreateCommandQueue(D3D12_COMMAND_LIST_TYPE type);
|
||||
ComPtr<ID3D12CommandAllocator> CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE type);
|
||||
ComPtr<ID3D12GraphicsCommandList> CreateCommandList(D3D12_COMMAND_LIST_TYPE type, ComPtr<ID3D12CommandAllocator> pCommandAllocator);
|
||||
ComPtr<ID3D12DescriptorHeap> CreateDescriptorHeap(D3D12_DESCRIPTOR_HEAP_TYPE type, UINT num);
|
||||
ComPtr<ID3D12Fence> CreateFence();
|
||||
UINT64 QueueSignal();
|
||||
void WaitForFenceValue(UINT64 value);
|
||||
void Flush();
|
||||
void QueueWaitIdle();
|
||||
|
||||
static D3D12_RESOURCE_BARRIER MakeResourceBarrierTransition(ID3D12Resource* pResource, D3D12_RESOURCE_STATES before, D3D12_RESOURCE_STATES after);
|
||||
|
||||
virtual void PrepareDraw() override;
|
||||
virtual void Clear(UINT32 flags) override;
|
||||
// Which graphics API?
|
||||
virtual Gapi GetGapi() override { return Gapi::direct3D12; }
|
||||
|
||||
// Frame cycle:
|
||||
virtual void BeginFrame() override;
|
||||
virtual void EndFrame() override;
|
||||
virtual void Present() override;
|
||||
virtual void Clear(UINT32 flags) override;
|
||||
};
|
||||
VERUS_TYPEDEFS(RendererD3D12);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
#include "stdafx.h"
|
||||
|
||||
using namespace verus;
|
||||
using namespace verus::CGI;
|
||||
|
||||
// ShaderInclude:
|
||||
|
||||
HRESULT STDMETHODCALLTYPE ShaderInclude::Open(
|
||||
D3D_INCLUDE_TYPE IncludeType,
|
||||
LPCSTR pFileName,
|
||||
LPCVOID pParentData,
|
||||
LPCVOID* ppData,
|
||||
UINT* pBytes)
|
||||
{
|
||||
const String url = String("<Shaders>/") + pFileName;
|
||||
Vector<BYTE> vData;
|
||||
IO::FileSystem::LoadResource(_C(url), vData);
|
||||
char* p = new char[vData.size()];
|
||||
memcpy(p, vData.data(), vData.size());
|
||||
*pBytes = vData.size();
|
||||
*ppData = p;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE ShaderInclude::Close(LPCVOID pData)
|
||||
{
|
||||
delete[] pData;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// ShaderD3D12:
|
||||
|
||||
ShaderD3D12::ShaderD3D12()
|
||||
{
|
||||
}
|
||||
|
||||
ShaderD3D12::~ShaderD3D12()
|
||||
{
|
||||
Done();
|
||||
}
|
||||
|
||||
void ShaderD3D12::Init(CSZ source, CSZ* list)
|
||||
{
|
||||
VERUS_INIT();
|
||||
|
||||
HRESULT hr = 0;
|
||||
|
||||
const size_t len = strlen(source);
|
||||
ShaderInclude inc;
|
||||
String version = "5_0";
|
||||
UINT flags = D3DCOMPILE_ENABLE_STRICTNESS;
|
||||
#ifndef _DEBUG
|
||||
flags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_OPTIMIZATION_LEVEL3;
|
||||
#endif
|
||||
ComPtr<ID3DBlob> pErrorMsgs;
|
||||
|
||||
Vector<D3D_SHADER_MACRO> vDefines;
|
||||
vDefines.reserve(20);
|
||||
|
||||
while (*list)
|
||||
{
|
||||
String entryVS, entryHS, entryDS, entryGS, entryPS;
|
||||
const String entry;
|
||||
|
||||
Compiled compiled;
|
||||
|
||||
hr = D3DCompile(source, len, 0, vDefines.data(), &inc, _C(entryVS), _C("vs_" + version), flags, 0, &compiled._pVS, &pErrorMsgs);
|
||||
|
||||
_mapCompiled[entry] = compiled;
|
||||
|
||||
list++;
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderD3D12::Done()
|
||||
{
|
||||
VERUS_DONE(ShaderD3D12);
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace CGI
|
||||
{
|
||||
struct ShaderInclude : public ID3DInclude
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE Open(
|
||||
D3D_INCLUDE_TYPE IncludeType,
|
||||
LPCSTR pFileName,
|
||||
LPCVOID pParentData,
|
||||
LPCVOID* ppData,
|
||||
UINT* pBytes) override;
|
||||
virtual HRESULT STDMETHODCALLTYPE Close(LPCVOID pData) override;
|
||||
};
|
||||
VERUS_TYPEDEFS(ShaderInclude);
|
||||
|
||||
class ShaderD3D12 : public BaseShader
|
||||
{
|
||||
struct Compiled
|
||||
{
|
||||
ComPtr<ID3DBlob> _pVS;
|
||||
ComPtr<ID3DBlob> _pHS;
|
||||
ComPtr<ID3DBlob> _pDS;
|
||||
ComPtr<ID3DBlob> _pGS;
|
||||
ComPtr<ID3DBlob> _pPS;
|
||||
};
|
||||
VERUS_TYPEDEFS(Compiled);
|
||||
typedef Map<String, Compiled> TMapCompiled;
|
||||
|
||||
TMapCompiled _mapCompiled;
|
||||
|
||||
public:
|
||||
ShaderD3D12();
|
||||
virtual ~ShaderD3D12() override;
|
||||
|
||||
virtual void Init(CSZ source, CSZ* list) override;
|
||||
virtual void Done() override;
|
||||
};
|
||||
VERUS_TYPEDEFS(ShaderD3D12);
|
||||
}
|
||||
}
|
|
@ -91,9 +91,20 @@
|
|||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\CGI\CGI.h" />
|
||||
<ClInclude Include="src\CGI\CommandBufferVulkan.h" />
|
||||
<ClInclude Include="src\CGI\GeometryVulkan.h" />
|
||||
<ClInclude Include="src\CGI\PipelineVulkan.h" />
|
||||
<ClInclude Include="src\CGI\RendererVulkan.h" />
|
||||
<ClInclude Include="src\CGI\ShaderVulkan.h" />
|
||||
<ClInclude Include="src\stdafx.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\CGI\CommandBufferVulkan.cpp" />
|
||||
<ClCompile Include="src\CGI\GeometryVulkan.cpp" />
|
||||
<ClCompile Include="src\CGI\PipelineVulkan.cpp" />
|
||||
<ClCompile Include="src\CGI\RendererVulkan.cpp" />
|
||||
<ClCompile Include="src\CGI\ShaderVulkan.cpp" />
|
||||
<ClCompile Include="src\main.cpp" />
|
||||
<ClCompile Include="src\stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
|
|
|
@ -16,11 +16,32 @@
|
|||
<Filter Include="src">
|
||||
<UniqueIdentifier>{836b7e96-dc7f-4278-832a-6305a03b69e4}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="src\CGI">
|
||||
<UniqueIdentifier>{4abdc4ba-6c11-4cdc-b578-2101f063b0c6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\stdafx.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\CGI\CGI.h">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\CGI\RendererVulkan.h">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\CGI\CommandBufferVulkan.h">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\CGI\GeometryVulkan.h">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\CGI\PipelineVulkan.h">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\CGI\ShaderVulkan.h">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\main.cpp">
|
||||
|
@ -29,5 +50,20 @@
|
|||
<ClCompile Include="src\stdafx.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\CGI\RendererVulkan.cpp">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\CGI\CommandBufferVulkan.cpp">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\CGI\GeometryVulkan.cpp">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\CGI\PipelineVulkan.cpp">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\CGI\ShaderVulkan.cpp">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "CommandBufferVulkan.h"
|
||||
#include "GeometryVulkan.h"
|
||||
#include "PipelineVulkan.h"
|
||||
#include "ShaderVulkan.h"
|
||||
#include "RendererVulkan.h"
|
|
@ -0,0 +1,98 @@
|
|||
#include "stdafx.h"
|
||||
|
||||
using namespace verus;
|
||||
using namespace verus::CGI;
|
||||
|
||||
VkCommandBuffer CommandBufferVulkan::GetCommandBuffer() const
|
||||
{
|
||||
VERUS_QREF_RENDERER;
|
||||
return _commandBuffers[renderer->GetRingBufferIndex()];
|
||||
}
|
||||
|
||||
CommandBufferVulkan::CommandBufferVulkan()
|
||||
{
|
||||
}
|
||||
|
||||
CommandBufferVulkan::~CommandBufferVulkan()
|
||||
{
|
||||
Done();
|
||||
}
|
||||
|
||||
void CommandBufferVulkan::Init()
|
||||
{
|
||||
VERUS_INIT();
|
||||
}
|
||||
|
||||
void CommandBufferVulkan::Done()
|
||||
{
|
||||
VERUS_DONE(CommandBufferVulkan);
|
||||
}
|
||||
|
||||
void CommandBufferVulkan::Begin()
|
||||
{
|
||||
VkResult res = VK_SUCCESS;
|
||||
VkCommandBufferBeginInfo vkcbbi = {};
|
||||
vkcbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
vkcbbi.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
|
||||
if (VK_SUCCESS != (res = vkBeginCommandBuffer(GetCommandBuffer(), &vkcbbi)))
|
||||
throw VERUS_RUNTIME_ERROR << "vkBeginCommandBuffer(), res=" << res;
|
||||
}
|
||||
|
||||
void CommandBufferVulkan::End()
|
||||
{
|
||||
VkResult res = VK_SUCCESS;
|
||||
if (VK_SUCCESS != (res = vkEndCommandBuffer(GetCommandBuffer())))
|
||||
throw VERUS_RUNTIME_ERROR << "vkEndCommandBuffer(), res=" << res;
|
||||
}
|
||||
|
||||
void CommandBufferVulkan::BindVertexBuffers()
|
||||
{
|
||||
vkCmdBindVertexBuffers(GetCommandBuffer(), 0, 1, nullptr, nullptr);
|
||||
}
|
||||
|
||||
void CommandBufferVulkan::BindIndexBuffer()
|
||||
{
|
||||
vkCmdBindIndexBuffer(GetCommandBuffer(), nullptr, 0, VK_INDEX_TYPE_UINT16);
|
||||
}
|
||||
|
||||
void CommandBufferVulkan::SetScissor()
|
||||
{
|
||||
vkCmdSetScissor(GetCommandBuffer(), 0, 1, nullptr);
|
||||
}
|
||||
|
||||
void CommandBufferVulkan::SetViewport()
|
||||
{
|
||||
vkCmdSetViewport(GetCommandBuffer(), 0, 1, nullptr);
|
||||
}
|
||||
|
||||
void CommandBufferVulkan::BindPipeline()
|
||||
{
|
||||
vkCmdBindPipeline(GetCommandBuffer(), VK_PIPELINE_BIND_POINT_GRAPHICS, nullptr);
|
||||
}
|
||||
|
||||
void CommandBufferVulkan::Clear(ClearFlags clearFlags)
|
||||
{
|
||||
VERUS_QREF_RENDERER;
|
||||
if (clearFlags & ClearFlags::color)
|
||||
{
|
||||
VkClearColorValue clearColorValue;
|
||||
memcpy(&clearColorValue, renderer.GetClearColor().ToPointer(), sizeof(clearColorValue));
|
||||
VkImageSubresourceRange vkisr = {};
|
||||
vkisr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
vkisr.baseMipLevel = 0;
|
||||
vkisr.levelCount = 1;
|
||||
vkisr.baseArrayLayer = 0;
|
||||
vkisr.layerCount = 1;
|
||||
vkCmdClearColorImage(GetCommandBuffer(), nullptr, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColorValue, 1, &vkisr);
|
||||
}
|
||||
}
|
||||
|
||||
void CommandBufferVulkan::Draw()
|
||||
{
|
||||
vkCmdDraw(GetCommandBuffer(), 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void CommandBufferVulkan::DrawIndexed()
|
||||
{
|
||||
vkCmdDrawIndexed(GetCommandBuffer(), 0, 0, 0, 0, 0);
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace CGI
|
||||
{
|
||||
class CommandBufferVulkan : public BaseCommandBuffer
|
||||
{
|
||||
VkCommandBuffer _commandBuffers[BaseRenderer::ringBufferSize] = { VK_NULL_HANDLE };
|
||||
|
||||
VkCommandBuffer GetCommandBuffer() const;
|
||||
|
||||
public:
|
||||
CommandBufferVulkan();
|
||||
virtual ~CommandBufferVulkan() override;
|
||||
|
||||
virtual void Init() override;
|
||||
virtual void Done() override;
|
||||
|
||||
virtual void Begin() override;
|
||||
virtual void End() override;
|
||||
|
||||
virtual void BindVertexBuffers() override;
|
||||
virtual void BindIndexBuffer() override;
|
||||
|
||||
virtual void SetScissor() override;
|
||||
virtual void SetViewport() override;
|
||||
|
||||
virtual void BindPipeline() override;
|
||||
virtual void Clear(ClearFlags clearFlags) override;
|
||||
virtual void Draw() override;
|
||||
virtual void DrawIndexed() override;
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#include "stdafx.h"
|
||||
|
||||
using namespace verus;
|
||||
using namespace verus::CGI;
|
||||
|
||||
GeometryVulkan::GeometryVulkan()
|
||||
{
|
||||
}
|
||||
|
||||
GeometryVulkan::~GeometryVulkan()
|
||||
{
|
||||
Done();
|
||||
}
|
||||
|
||||
void GeometryVulkan::Init(RcGeometryDesc desc)
|
||||
{
|
||||
VERUS_INIT();
|
||||
}
|
||||
|
||||
void GeometryVulkan::Done()
|
||||
{
|
||||
VERUS_DONE(GeometryVulkan);
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace CGI
|
||||
{
|
||||
class GeometryVulkan : public BaseGeometry
|
||||
{
|
||||
public:
|
||||
GeometryVulkan();
|
||||
virtual ~GeometryVulkan() override;
|
||||
|
||||
virtual void Init(RcGeometryDesc desc) override;
|
||||
virtual void Done() override;
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#include "stdafx.h"
|
||||
|
||||
using namespace verus;
|
||||
using namespace verus::CGI;
|
||||
|
||||
PipelineVulkan::PipelineVulkan()
|
||||
{
|
||||
}
|
||||
|
||||
PipelineVulkan::~PipelineVulkan()
|
||||
{
|
||||
Done();
|
||||
}
|
||||
|
||||
void PipelineVulkan::Init()
|
||||
{
|
||||
VERUS_INIT();
|
||||
}
|
||||
|
||||
void PipelineVulkan::Done()
|
||||
{
|
||||
VERUS_DONE(PipelineVulkan);
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace CGI
|
||||
{
|
||||
class PipelineVulkan : public BasePipeline
|
||||
{
|
||||
public:
|
||||
PipelineVulkan();
|
||||
virtual ~PipelineVulkan() override;
|
||||
|
||||
virtual void Init() override;
|
||||
virtual void Done() override;
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,631 @@
|
|||
#include "stdafx.h"
|
||||
|
||||
using namespace verus;
|
||||
using namespace verus::CGI;
|
||||
|
||||
static VkResult CreateDebugUtilsMessengerEXT(
|
||||
VkInstance instance,
|
||||
const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkDebugUtilsMessengerEXT* pMessenger)
|
||||
{
|
||||
auto fn = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT");
|
||||
if (fn)
|
||||
return fn(instance, pCreateInfo, pAllocator, pMessenger);
|
||||
else
|
||||
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||
}
|
||||
|
||||
static void DestroyDebugUtilsMessengerEXT(
|
||||
VkInstance instance,
|
||||
VkDebugUtilsMessengerEXT messenger,
|
||||
const VkAllocationCallbacks* pAllocator)
|
||||
{
|
||||
auto fn = (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT");
|
||||
if (fn)
|
||||
fn(instance, messenger, pAllocator);
|
||||
}
|
||||
|
||||
// RendererVulkan:
|
||||
|
||||
CSZ RendererVulkan::s_requiredValidationLayers[] =
|
||||
{
|
||||
"VK_LAYER_LUNARG_standard_validation"
|
||||
};
|
||||
|
||||
CSZ RendererVulkan::s_requiredDeviceExtensions[] =
|
||||
{
|
||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME
|
||||
};
|
||||
|
||||
RendererVulkan::RendererVulkan()
|
||||
{
|
||||
}
|
||||
|
||||
RendererVulkan::~RendererVulkan()
|
||||
{
|
||||
Done();
|
||||
}
|
||||
|
||||
void RendererVulkan::ReleaseMe()
|
||||
{
|
||||
Free();
|
||||
TestAllocCount();
|
||||
}
|
||||
|
||||
void RendererVulkan::Init()
|
||||
{
|
||||
VERUS_INIT();
|
||||
|
||||
CreateInstance();
|
||||
#if defined(_DEBUG) || defined(VERUS_DEBUG)
|
||||
CreateDebugUtilsMessenger();
|
||||
#endif
|
||||
CreateSurface();
|
||||
PickPhysicalDevice();
|
||||
CreateDevice();
|
||||
CreateSwapChain();
|
||||
CreateImageViews();
|
||||
CreateCommandPools();
|
||||
CreateCommandBuffers();
|
||||
CreateSyncObjects();
|
||||
}
|
||||
|
||||
void RendererVulkan::Done()
|
||||
{
|
||||
if (_device)
|
||||
vkDeviceWaitIdle(_device);
|
||||
VERUS_FOR(i, ringBufferSize)
|
||||
{
|
||||
if (VK_NULL_HANDLE != _acquireNextImageSemaphores[i])
|
||||
{
|
||||
vkDestroySemaphore(_device, _acquireNextImageSemaphores[i], nullptr);
|
||||
_acquireNextImageSemaphores[i] = VK_NULL_HANDLE;
|
||||
}
|
||||
if (VK_NULL_HANDLE != _queueSubmitSemaphores[i])
|
||||
{
|
||||
vkDestroySemaphore(_device, _queueSubmitSemaphores[i], nullptr);
|
||||
_queueSubmitSemaphores[i] = VK_NULL_HANDLE;
|
||||
}
|
||||
if (VK_NULL_HANDLE != _queueSubmitFences[i])
|
||||
{
|
||||
vkDestroyFence(_device, _queueSubmitFences[i], nullptr);
|
||||
_queueSubmitFences[i] = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
VERUS_FOR(i, ringBufferSize)
|
||||
{
|
||||
if (VK_NULL_HANDLE != _commandPools[i])
|
||||
{
|
||||
vkDestroyCommandPool(_device, _commandPools[i], nullptr);
|
||||
_commandPools[i] = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
for (auto swapChainImageViews : _vSwapChainImageViews)
|
||||
vkDestroyImageView(_device, swapChainImageViews, nullptr);
|
||||
_vSwapChainImageViews.clear();
|
||||
_vSwapChainImages.clear();
|
||||
if (VK_NULL_HANDLE != _swapChain)
|
||||
{
|
||||
vkDestroySwapchainKHR(_device, _swapChain, nullptr);
|
||||
_swapChain = VK_NULL_HANDLE;
|
||||
}
|
||||
if (VK_NULL_HANDLE != _device)
|
||||
{
|
||||
vkDestroyDevice(_device, nullptr);
|
||||
_device = VK_NULL_HANDLE;
|
||||
}
|
||||
if (VK_NULL_HANDLE != _surface)
|
||||
{
|
||||
vkDestroySurfaceKHR(_instance, _surface, nullptr);
|
||||
_surface = VK_NULL_HANDLE;
|
||||
}
|
||||
#if defined(_DEBUG) || defined(VERUS_DEBUG)
|
||||
if (VK_NULL_HANDLE != _debugUtilsMessenger)
|
||||
{
|
||||
DestroyDebugUtilsMessengerEXT(_instance, _debugUtilsMessenger, nullptr);
|
||||
_debugUtilsMessenger = VK_NULL_HANDLE;
|
||||
}
|
||||
#endif
|
||||
if (VK_NULL_HANDLE != _instance)
|
||||
{
|
||||
vkDestroyInstance(_instance, nullptr);
|
||||
_instance = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
VERUS_DONE(RendererVulkan);
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL RendererVulkan::DebugUtilsMessengerCallback(
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
||||
void* pUserData)
|
||||
{
|
||||
D::Log::Severity severity = D::Log::Severity::error;
|
||||
if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT)
|
||||
severity = D::Log::Severity::debug;
|
||||
if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT)
|
||||
severity = D::Log::Severity::info;
|
||||
if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)
|
||||
severity = D::Log::Severity::warning;
|
||||
if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
|
||||
severity = D::Log::Severity::error;
|
||||
D::Log::I().Write(pCallbackData->pMessage, std::this_thread::get_id(), __FILE__, __LINE__, severity);
|
||||
return VK_FALSE;
|
||||
}
|
||||
|
||||
bool RendererVulkan::CheckRequiredValidationLayers()
|
||||
{
|
||||
uint32_t propertyCount = 0;
|
||||
vkEnumerateInstanceLayerProperties(&propertyCount, nullptr);
|
||||
Vector<VkLayerProperties> vLayerProperties(propertyCount);
|
||||
vkEnumerateInstanceLayerProperties(&propertyCount, vLayerProperties.data());
|
||||
for (CSZ layerName : s_requiredValidationLayers)
|
||||
{
|
||||
bool layerFound = false;
|
||||
for (const auto& layerProperties : vLayerProperties)
|
||||
{
|
||||
if (!strcmp(layerName, layerProperties.layerName))
|
||||
{
|
||||
layerFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!layerFound)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Vector<CSZ> RendererVulkan::GetRequiredExtensions()
|
||||
{
|
||||
VERUS_QREF_RENDERER;
|
||||
SDL_Window* pWnd = renderer.GetMainWindow()->GetSDL();
|
||||
VERUS_RT_ASSERT(pWnd);
|
||||
Vector<CSZ> vExtensions;
|
||||
unsigned int count = 0;
|
||||
if (!SDL_Vulkan_GetInstanceExtensions(pWnd, &count, nullptr))
|
||||
throw VERUS_RUNTIME_ERROR << "SDL_Vulkan_GetInstanceExtensions(nullptr)";
|
||||
vExtensions.reserve(count + 1);
|
||||
vExtensions.resize(count);
|
||||
if (!SDL_Vulkan_GetInstanceExtensions(pWnd, &count, vExtensions.data()))
|
||||
throw VERUS_RUNTIME_ERROR << "SDL_Vulkan_GetInstanceExtensions()";
|
||||
#if defined(_DEBUG) || defined(VERUS_DEBUG)
|
||||
vExtensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
#endif
|
||||
return vExtensions;
|
||||
}
|
||||
|
||||
void RendererVulkan::CreateInstance()
|
||||
{
|
||||
VkResult res = VK_SUCCESS;
|
||||
|
||||
#if defined(_DEBUG) || defined(VERUS_DEBUG)
|
||||
if (!CheckRequiredValidationLayers())
|
||||
throw VERUS_RUNTIME_ERROR << "CheckRequiredValidationLayers()";
|
||||
#endif
|
||||
|
||||
const auto vExtensions = GetRequiredExtensions();
|
||||
|
||||
VkApplicationInfo vkai = {};
|
||||
vkai.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||
vkai.pApplicationName = "Game";
|
||||
vkai.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
|
||||
vkai.pEngineName = "Verus";
|
||||
vkai.engineVersion = VK_MAKE_VERSION(1, 0, 0);
|
||||
vkai.apiVersion = VK_API_VERSION_1_0;
|
||||
VkInstanceCreateInfo vkici = {};
|
||||
vkici.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
vkici.pApplicationInfo = &vkai;
|
||||
#if defined(_DEBUG) || defined(VERUS_DEBUG)
|
||||
vkici.enabledLayerCount = VERUS_ARRAY_LENGTH(s_requiredValidationLayers);
|
||||
vkici.ppEnabledLayerNames = s_requiredValidationLayers;
|
||||
#endif
|
||||
vkici.enabledExtensionCount = Utils::Cast32(vExtensions.size());
|
||||
vkici.ppEnabledExtensionNames = vExtensions.data();
|
||||
if (VK_SUCCESS != (res = vkCreateInstance(&vkici, nullptr, &_instance)))
|
||||
throw VERUS_RUNTIME_ERROR << "vkCreateInstance(), res=" << res;
|
||||
}
|
||||
|
||||
void RendererVulkan::CreateDebugUtilsMessenger()
|
||||
{
|
||||
VkResult res = VK_SUCCESS;
|
||||
VkDebugUtilsMessengerCreateInfoEXT vkdumci = {};
|
||||
vkdumci.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
|
||||
vkdumci.messageSeverity =
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
|
||||
vkdumci.messageType =
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
|
||||
vkdumci.pfnUserCallback = DebugUtilsMessengerCallback;
|
||||
if (VK_SUCCESS != (res = CreateDebugUtilsMessengerEXT(_instance, &vkdumci, nullptr, &_debugUtilsMessenger)))
|
||||
throw VERUS_RUNTIME_ERROR << "CreateDebugUtilsMessengerEXT(), res=" << res;
|
||||
}
|
||||
|
||||
void RendererVulkan::CreateSurface()
|
||||
{
|
||||
VERUS_QREF_RENDERER;
|
||||
SDL_Window* pWnd = renderer.GetMainWindow()->GetSDL();
|
||||
VERUS_RT_ASSERT(pWnd);
|
||||
if (!SDL_Vulkan_CreateSurface(pWnd, _instance, &_surface))
|
||||
throw VERUS_RUNTIME_ERROR << "SDL_Vulkan_CreateSurface()";
|
||||
}
|
||||
|
||||
bool RendererVulkan::CheckRequiredDeviceExtensions(VkPhysicalDevice device)
|
||||
{
|
||||
uint32_t propertyCount = 0;
|
||||
vkEnumerateDeviceExtensionProperties(device, nullptr, &propertyCount, nullptr);
|
||||
Vector<VkExtensionProperties> vExtensionProperties(propertyCount);
|
||||
vkEnumerateDeviceExtensionProperties(device, nullptr, &propertyCount, vExtensionProperties.data());
|
||||
Set<String> setRequiredDeviceExtensions;
|
||||
for (CSZ extensionName : s_requiredDeviceExtensions)
|
||||
setRequiredDeviceExtensions.insert(extensionName);
|
||||
for (const auto& extensionProperties : vExtensionProperties)
|
||||
setRequiredDeviceExtensions.erase(extensionProperties.extensionName);
|
||||
return setRequiredDeviceExtensions.empty();
|
||||
}
|
||||
|
||||
RendererVulkan::QueueFamilyIndices RendererVulkan::FindQueueFamilyIndices(VkPhysicalDevice device)
|
||||
{
|
||||
QueueFamilyIndices ret;
|
||||
uint32_t queueFamilyPropertyCount = 0;
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyPropertyCount, nullptr);
|
||||
Vector<VkQueueFamilyProperties> vQueueFamilyProperties(queueFamilyPropertyCount);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyPropertyCount, vQueueFamilyProperties.data());
|
||||
int i = 0;
|
||||
for (const auto& queueFamilyProperties : vQueueFamilyProperties)
|
||||
{
|
||||
if (queueFamilyProperties.queueCount > 0 && (queueFamilyProperties.queueFlags & VK_QUEUE_GRAPHICS_BIT))
|
||||
ret._graphicsFamilyIndex = i;
|
||||
|
||||
VkBool32 supported = VK_FALSE;
|
||||
vkGetPhysicalDeviceSurfaceSupportKHR(device, i, _surface, &supported);
|
||||
if (queueFamilyProperties.queueCount > 0 && supported)
|
||||
ret._presentFamilyIndex = i;
|
||||
|
||||
if (ret.IsComplete())
|
||||
break;
|
||||
|
||||
i++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool RendererVulkan::IsDeviceSuitable(VkPhysicalDevice device)
|
||||
{
|
||||
const QueueFamilyIndices queueFamilyIndices = FindQueueFamilyIndices(device);
|
||||
if (!queueFamilyIndices.IsComplete())
|
||||
return false;
|
||||
|
||||
const bool extensionsSupported = CheckRequiredDeviceExtensions(device);
|
||||
bool swapChainOK = false;
|
||||
if (extensionsSupported)
|
||||
{
|
||||
const SwapChainInfo swapChainInfo = GetSwapChainInfo(device);
|
||||
swapChainOK = !swapChainInfo._vSurfaceFormats.empty() && !swapChainInfo._vSurfacePresentModes.empty();
|
||||
}
|
||||
return extensionsSupported && swapChainOK;
|
||||
}
|
||||
|
||||
void RendererVulkan::PickPhysicalDevice()
|
||||
{
|
||||
uint32_t physicalDeviceCount = 0;
|
||||
vkEnumeratePhysicalDevices(_instance, &physicalDeviceCount, nullptr);
|
||||
if (!physicalDeviceCount)
|
||||
throw VERUS_RUNTIME_ERROR << "vkEnumeratePhysicalDevices(), physicalDeviceCount=0";
|
||||
Vector<VkPhysicalDevice> vPhysicalDevices(physicalDeviceCount);
|
||||
vkEnumeratePhysicalDevices(_instance, &physicalDeviceCount, vPhysicalDevices.data());
|
||||
for (const auto& physicalDevice : vPhysicalDevices)
|
||||
{
|
||||
if (IsDeviceSuitable(physicalDevice))
|
||||
{
|
||||
_physicalDevice = physicalDevice;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (VK_NULL_HANDLE == _physicalDevice)
|
||||
throw VERUS_RUNTIME_ERROR << "PhysicalDevice not found";
|
||||
}
|
||||
|
||||
void RendererVulkan::CreateDevice()
|
||||
{
|
||||
VkResult res = VK_SUCCESS;
|
||||
|
||||
_queueFamilyIndices = FindQueueFamilyIndices(_physicalDevice);
|
||||
VERUS_RT_ASSERT(_queueFamilyIndices.IsComplete());
|
||||
Set<int> setUniqueQueueFamilies = { _queueFamilyIndices._graphicsFamilyIndex, _queueFamilyIndices._presentFamilyIndex };
|
||||
Vector<VkDeviceQueueCreateInfo> vDeviceQueueCreateInfos;
|
||||
vDeviceQueueCreateInfos.reserve(setUniqueQueueFamilies.size());
|
||||
const float queuePriorities[] = { 1.0f };
|
||||
for (int queueFamilyIndex : setUniqueQueueFamilies)
|
||||
{
|
||||
VkDeviceQueueCreateInfo vkdqci = {};
|
||||
vkdqci.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||
vkdqci.queueFamilyIndex = queueFamilyIndex;
|
||||
vkdqci.queueCount = 1;
|
||||
vkdqci.pQueuePriorities = queuePriorities;
|
||||
vDeviceQueueCreateInfos.push_back(vkdqci);
|
||||
}
|
||||
VkPhysicalDeviceFeatures physicalDeviceFeatures = {};
|
||||
VkDeviceCreateInfo vkdci = {};
|
||||
vkdci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||
vkdci.queueCreateInfoCount = Utils::Cast32(vDeviceQueueCreateInfos.size());
|
||||
vkdci.pQueueCreateInfos = vDeviceQueueCreateInfos.data();
|
||||
#if defined(_DEBUG) || defined(VERUS_DEBUG)
|
||||
vkdci.enabledLayerCount = VERUS_ARRAY_LENGTH(s_requiredValidationLayers);
|
||||
vkdci.ppEnabledLayerNames = s_requiredValidationLayers;
|
||||
#endif
|
||||
vkdci.enabledExtensionCount = VERUS_ARRAY_LENGTH(s_requiredDeviceExtensions);
|
||||
vkdci.ppEnabledExtensionNames = s_requiredDeviceExtensions;
|
||||
vkdci.pEnabledFeatures = &physicalDeviceFeatures;
|
||||
if (VK_SUCCESS != (res = vkCreateDevice(_physicalDevice, &vkdci, nullptr, &_device)))
|
||||
throw VERUS_RUNTIME_ERROR << "vkCreateDevice(), res=" << res;
|
||||
|
||||
vkGetDeviceQueue(_device, _queueFamilyIndices._graphicsFamilyIndex, 0, &_graphicsQueue);
|
||||
vkGetDeviceQueue(_device, _queueFamilyIndices._presentFamilyIndex, 0, &_presentQueue);
|
||||
}
|
||||
|
||||
RendererVulkan::SwapChainInfo RendererVulkan::GetSwapChainInfo(VkPhysicalDevice device)
|
||||
{
|
||||
SwapChainInfo swapChainInfo;
|
||||
|
||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, _surface, &swapChainInfo._surfaceCapabilities);
|
||||
|
||||
uint32_t surfaceFormatCount = 0;
|
||||
vkGetPhysicalDeviceSurfaceFormatsKHR(device, _surface, &surfaceFormatCount, nullptr);
|
||||
if (surfaceFormatCount)
|
||||
{
|
||||
swapChainInfo._vSurfaceFormats.resize(surfaceFormatCount);
|
||||
vkGetPhysicalDeviceSurfaceFormatsKHR(device, _surface, &surfaceFormatCount, swapChainInfo._vSurfaceFormats.data());
|
||||
}
|
||||
|
||||
uint32_t presentModeCount = 0;
|
||||
vkGetPhysicalDeviceSurfacePresentModesKHR(device, _surface, &presentModeCount, nullptr);
|
||||
if (presentModeCount)
|
||||
{
|
||||
swapChainInfo._vSurfacePresentModes.resize(presentModeCount);
|
||||
vkGetPhysicalDeviceSurfacePresentModesKHR(device, _surface, &presentModeCount, swapChainInfo._vSurfacePresentModes.data());
|
||||
}
|
||||
|
||||
return swapChainInfo;
|
||||
}
|
||||
|
||||
void RendererVulkan::CreateSwapChain()
|
||||
{
|
||||
VERUS_QREF_SETTINGS;
|
||||
|
||||
VkResult res = VK_SUCCESS;
|
||||
|
||||
_numSwapChainBuffers = settings._screenVSync ? 3 : 2;
|
||||
|
||||
const SwapChainInfo swapChainInfo = GetSwapChainInfo(_physicalDevice);
|
||||
|
||||
VkSwapchainCreateInfoKHR vksci = {};
|
||||
vksci.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
||||
vksci.surface = _surface;
|
||||
vksci.minImageCount = _numSwapChainBuffers;
|
||||
vksci.imageFormat = VK_FORMAT_B8G8R8A8_UNORM;
|
||||
vksci.imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
|
||||
vksci.imageExtent.width = settings._screenSizeWidth;
|
||||
vksci.imageExtent.height = settings._screenSizeHeight;
|
||||
vksci.imageArrayLayers = 1;
|
||||
vksci.imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
vksci.preTransform = swapChainInfo._surfaceCapabilities.currentTransform;
|
||||
vksci.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||
vksci.presentMode = settings._screenVSync ? VK_PRESENT_MODE_MAILBOX_KHR : VK_PRESENT_MODE_FIFO_KHR;
|
||||
vksci.clipped = VK_TRUE;
|
||||
vksci.oldSwapchain = VK_NULL_HANDLE;
|
||||
const uint32_t queueFamilyIndicesArray[] =
|
||||
{
|
||||
static_cast<uint32_t>(_queueFamilyIndices._graphicsFamilyIndex),
|
||||
static_cast<uint32_t>(_queueFamilyIndices._presentFamilyIndex)
|
||||
};
|
||||
if (_queueFamilyIndices.IsSameQueue())
|
||||
{
|
||||
vksci.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
}
|
||||
else
|
||||
{
|
||||
vksci.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
|
||||
vksci.queueFamilyIndexCount = VERUS_ARRAY_LENGTH(queueFamilyIndicesArray);
|
||||
vksci.pQueueFamilyIndices = queueFamilyIndicesArray;
|
||||
}
|
||||
if (VK_SUCCESS != (res = vkCreateSwapchainKHR(_device, &vksci, nullptr, &_swapChain)))
|
||||
throw VERUS_RUNTIME_ERROR << "vkCreateSwapchainKHR(), res=" << res;
|
||||
|
||||
vkGetSwapchainImagesKHR(_device, _swapChain, &_numSwapChainBuffers, nullptr);
|
||||
_vSwapChainImages.resize(_numSwapChainBuffers);
|
||||
vkGetSwapchainImagesKHR(_device, _swapChain, &_numSwapChainBuffers, _vSwapChainImages.data());
|
||||
}
|
||||
|
||||
void RendererVulkan::CreateImageViews()
|
||||
{
|
||||
VkResult res = VK_SUCCESS;
|
||||
_vSwapChainImageViews.resize(_numSwapChainBuffers);
|
||||
VERUS_U_FOR(i, _numSwapChainBuffers)
|
||||
{
|
||||
VkImageViewCreateInfo vkivci = {};
|
||||
vkivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
vkivci.image = _vSwapChainImages[i];
|
||||
vkivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
vkivci.format = VK_FORMAT_B8G8R8A8_UNORM;
|
||||
vkivci.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
vkivci.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
vkivci.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
vkivci.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
vkivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
vkivci.subresourceRange.baseMipLevel = 0;
|
||||
vkivci.subresourceRange.levelCount = 1;
|
||||
vkivci.subresourceRange.baseArrayLayer = 0;
|
||||
vkivci.subresourceRange.layerCount = 1;
|
||||
if (VK_SUCCESS != (res = vkCreateImageView(_device, &vkivci, nullptr, &_vSwapChainImageViews[i])))
|
||||
throw VERUS_RUNTIME_ERROR << "vkCreateImageView(), res=" << res;
|
||||
}
|
||||
}
|
||||
|
||||
void RendererVulkan::CreateCommandPools()
|
||||
{
|
||||
VkResult res = VK_SUCCESS;
|
||||
VERUS_FOR(i, ringBufferSize)
|
||||
{
|
||||
VkCommandPoolCreateInfo vkcpci = {};
|
||||
vkcpci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||
vkcpci.queueFamilyIndex = _queueFamilyIndices._graphicsFamilyIndex;
|
||||
if (VK_SUCCESS != (res = vkCreateCommandPool(_device, &vkcpci, nullptr, &_commandPools[i])))
|
||||
throw VERUS_RUNTIME_ERROR << "vkCreateCommandPool(), res=" << res;
|
||||
}
|
||||
}
|
||||
|
||||
void RendererVulkan::CreateCommandBuffers()
|
||||
{
|
||||
VkResult res = VK_SUCCESS;
|
||||
VERUS_FOR(i, ringBufferSize)
|
||||
{
|
||||
VkCommandBufferAllocateInfo vkcbai = {};
|
||||
vkcbai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
vkcbai.commandPool = _commandPools[i];
|
||||
vkcbai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||
vkcbai.commandBufferCount = 1;
|
||||
if (VK_SUCCESS != (res = vkAllocateCommandBuffers(_device, &vkcbai, &_commandBuffers[i])))
|
||||
throw VERUS_RUNTIME_ERROR << "vkAllocateCommandBuffers(), res=" << res;
|
||||
}
|
||||
}
|
||||
|
||||
void RendererVulkan::CreateSyncObjects()
|
||||
{
|
||||
VkResult res = VK_SUCCESS;
|
||||
VkSemaphoreCreateInfo vksci = {};
|
||||
vksci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
VkFenceCreateInfo vkfci = {};
|
||||
vkfci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
vkfci.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||
VERUS_U_FOR(i, ringBufferSize)
|
||||
{
|
||||
if (VK_SUCCESS != (res = vkCreateSemaphore(_device, &vksci, nullptr, &_acquireNextImageSemaphores[i])))
|
||||
throw VERUS_RUNTIME_ERROR << "vkCreateSemaphore(), res=" << res;
|
||||
if (VK_SUCCESS != (res = vkCreateSemaphore(_device, &vksci, nullptr, &_queueSubmitSemaphores[i])))
|
||||
throw VERUS_RUNTIME_ERROR << "vkCreateSemaphore(), res=" << res;
|
||||
if (VK_SUCCESS != (res = vkCreateFence(_device, &vkfci, nullptr, &_queueSubmitFences[i])))
|
||||
throw VERUS_RUNTIME_ERROR << "vkCreateFence(), res=" << res;
|
||||
}
|
||||
}
|
||||
|
||||
void RendererVulkan::BeginFrame()
|
||||
{
|
||||
VkResult res = VK_SUCCESS;
|
||||
|
||||
if (VK_SUCCESS != (res = vkWaitForFences(_device, 1, &_queueSubmitFences[_ringBufferIndex], VK_TRUE, UINT64_MAX)))
|
||||
throw VERUS_RUNTIME_ERROR << "vkWaitForFences(), res=" << res;
|
||||
if (VK_SUCCESS != (res = vkResetFences(_device, 1, &_queueSubmitFences[_ringBufferIndex])))
|
||||
throw VERUS_RUNTIME_ERROR << "vkResetFences(), res=" << res;
|
||||
|
||||
if (VK_SUCCESS != (res = vkAcquireNextImageKHR(_device, _swapChain, UINT64_MAX, _acquireNextImageSemaphores[_ringBufferIndex], VK_NULL_HANDLE, &_swapChainBufferIndex)))
|
||||
throw VERUS_RUNTIME_ERROR << "vkAcquireNextImageKHR(), res=" << res;
|
||||
|
||||
if (VK_SUCCESS != (res = vkResetCommandPool(_device, _commandPools[_ringBufferIndex], VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT)))
|
||||
throw VERUS_RUNTIME_ERROR << "vkResetCommandPool(), res=" << res;
|
||||
|
||||
VkCommandBufferBeginInfo vkcbbi = {};
|
||||
vkcbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
vkcbbi.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
|
||||
if (VK_SUCCESS != (res = vkBeginCommandBuffer(_commandBuffers[_ringBufferIndex], &vkcbbi)))
|
||||
throw VERUS_RUNTIME_ERROR << "vkBeginCommandBuffer(), res=" << res;
|
||||
}
|
||||
|
||||
void RendererVulkan::EndFrame()
|
||||
{
|
||||
VkResult res = VK_SUCCESS;
|
||||
|
||||
VkImageMemoryBarrier vkimb = {};
|
||||
vkimb.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
vkimb.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
vkimb.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
vkimb.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
vkimb.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
vkimb.image = _vSwapChainImages[_swapChainBufferIndex];
|
||||
vkimb.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
vkimb.subresourceRange.baseMipLevel = 0;
|
||||
vkimb.subresourceRange.levelCount = 1;
|
||||
vkimb.subresourceRange.baseArrayLayer = 0;
|
||||
vkimb.subresourceRange.layerCount = 1;
|
||||
vkCmdPipelineBarrier(_commandBuffers[_ringBufferIndex], VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &vkimb);
|
||||
|
||||
if (VK_SUCCESS != (res = vkEndCommandBuffer(_commandBuffers[_ringBufferIndex])))
|
||||
throw VERUS_RUNTIME_ERROR << "vkEndCommandBuffer(), res=" << res;
|
||||
|
||||
const VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
||||
const VkSemaphore waitSemaphores[] = { _acquireNextImageSemaphores[_ringBufferIndex] };
|
||||
const VkSemaphore signalSemaphores[] = { _queueSubmitSemaphores[_ringBufferIndex] };
|
||||
|
||||
VkSubmitInfo vksi = {};
|
||||
vksi.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
vksi.waitSemaphoreCount = VERUS_ARRAY_LENGTH(waitSemaphores);
|
||||
vksi.pWaitSemaphores = waitSemaphores;
|
||||
vksi.pWaitDstStageMask = waitStages;
|
||||
vksi.commandBufferCount = 1;
|
||||
vksi.pCommandBuffers = &_commandBuffers[_ringBufferIndex];
|
||||
if (!_queueFamilyIndices.IsSameQueue())
|
||||
{
|
||||
vksi.signalSemaphoreCount = VERUS_ARRAY_LENGTH(signalSemaphores);
|
||||
vksi.pSignalSemaphores = signalSemaphores;
|
||||
}
|
||||
if (VK_SUCCESS != (res = vkQueueSubmit(_graphicsQueue, 1, &vksi, _queueSubmitFences[_ringBufferIndex])))
|
||||
throw VERUS_RUNTIME_ERROR << "vkQueueSubmit(), res=" << res;
|
||||
}
|
||||
|
||||
void RendererVulkan::Present()
|
||||
{
|
||||
VkResult res = VK_SUCCESS;
|
||||
|
||||
const VkSemaphore waitSemaphores[] = { _queueSubmitSemaphores[_ringBufferIndex] };
|
||||
const VkSwapchainKHR swapChains[] = { _swapChain };
|
||||
|
||||
VkPresentInfoKHR vkpi = {};
|
||||
vkpi.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||
if (!_queueFamilyIndices.IsSameQueue())
|
||||
{
|
||||
vkpi.waitSemaphoreCount = VERUS_ARRAY_LENGTH(waitSemaphores);
|
||||
vkpi.pWaitSemaphores = waitSemaphores;
|
||||
}
|
||||
vkpi.swapchainCount = VERUS_ARRAY_LENGTH(swapChains);
|
||||
vkpi.pSwapchains = swapChains;
|
||||
vkpi.pImageIndices = &_swapChainBufferIndex;
|
||||
if (VK_SUCCESS != (res = vkQueuePresentKHR(_presentQueue, &vkpi)))
|
||||
throw VERUS_RUNTIME_ERROR << "vkQueuePresentKHR(), res=" << res;
|
||||
|
||||
_ringBufferIndex = (_ringBufferIndex + 1) % ringBufferSize;
|
||||
}
|
||||
|
||||
void RendererVulkan::Clear(UINT32 flags)
|
||||
{
|
||||
VERUS_QREF_RENDERER;
|
||||
|
||||
VkImageMemoryBarrier vkimb = {};
|
||||
vkimb.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
vkimb.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
vkimb.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
vkimb.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
vkimb.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
vkimb.image = _vSwapChainImages[_swapChainBufferIndex];
|
||||
vkimb.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
vkimb.subresourceRange.baseMipLevel = 0;
|
||||
vkimb.subresourceRange.levelCount = 1;
|
||||
vkimb.subresourceRange.baseArrayLayer = 0;
|
||||
vkimb.subresourceRange.layerCount = 1;
|
||||
vkCmdPipelineBarrier(_commandBuffers[_ringBufferIndex], VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &vkimb);
|
||||
|
||||
VkClearColorValue clearColorValue;
|
||||
memcpy(&clearColorValue, renderer.GetClearColor().ToPointer(), sizeof(clearColorValue));
|
||||
VkImageSubresourceRange vkisr = {};
|
||||
vkisr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
vkisr.baseMipLevel = 0;
|
||||
vkisr.levelCount = 1;
|
||||
vkisr.baseArrayLayer = 0;
|
||||
vkisr.layerCount = 1;
|
||||
vkCmdClearColorImage(_commandBuffers[_ringBufferIndex], _vSwapChainImages[_swapChainBufferIndex], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColorValue, 1, &vkisr);
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace CGI
|
||||
{
|
||||
class RendererVulkan : public Singleton<RendererVulkan>, public BaseRenderer
|
||||
{
|
||||
struct QueueFamilyIndices
|
||||
{
|
||||
int _graphicsFamilyIndex = -1;
|
||||
int _presentFamilyIndex = -1;
|
||||
|
||||
bool IsComplete() const
|
||||
{
|
||||
return _graphicsFamilyIndex >= 0 && _presentFamilyIndex >= 0;
|
||||
}
|
||||
|
||||
bool IsSameQueue() const
|
||||
{
|
||||
return _graphicsFamilyIndex == _presentFamilyIndex;
|
||||
}
|
||||
};
|
||||
|
||||
struct SwapChainInfo
|
||||
{
|
||||
VkSurfaceCapabilitiesKHR _surfaceCapabilities = {};
|
||||
Vector<VkSurfaceFormatKHR> _vSurfaceFormats;
|
||||
Vector<VkPresentModeKHR> _vSurfacePresentModes;
|
||||
};
|
||||
|
||||
static CSZ s_requiredValidationLayers[];
|
||||
static CSZ s_requiredDeviceExtensions[];
|
||||
|
||||
VkInstance _instance = VK_NULL_HANDLE;
|
||||
VkDebugUtilsMessengerEXT _debugUtilsMessenger = VK_NULL_HANDLE;
|
||||
VkSurfaceKHR _surface = VK_NULL_HANDLE;
|
||||
VkPhysicalDevice _physicalDevice = VK_NULL_HANDLE;
|
||||
VkDevice _device = VK_NULL_HANDLE;
|
||||
VkQueue _graphicsQueue = VK_NULL_HANDLE;
|
||||
VkQueue _presentQueue = VK_NULL_HANDLE;
|
||||
VkSwapchainKHR _swapChain = VK_NULL_HANDLE;
|
||||
Vector<VkImage> _vSwapChainImages;
|
||||
Vector<VkImageView> _vSwapChainImageViews;
|
||||
VkCommandPool _commandPools[ringBufferSize] = { VK_NULL_HANDLE };
|
||||
VkCommandBuffer _commandBuffers[ringBufferSize] = { VK_NULL_HANDLE };
|
||||
VkSemaphore _acquireNextImageSemaphores[ringBufferSize] = { VK_NULL_HANDLE };
|
||||
VkSemaphore _queueSubmitSemaphores[ringBufferSize] = { VK_NULL_HANDLE };
|
||||
VkFence _queueSubmitFences[ringBufferSize] = { VK_NULL_HANDLE };
|
||||
QueueFamilyIndices _queueFamilyIndices;
|
||||
|
||||
public:
|
||||
RendererVulkan();
|
||||
~RendererVulkan();
|
||||
|
||||
virtual void ReleaseMe() override;
|
||||
|
||||
void Init();
|
||||
void Done();
|
||||
|
||||
private:
|
||||
static VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsMessengerCallback(
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
||||
void* pUserData);
|
||||
bool CheckRequiredValidationLayers();
|
||||
Vector<CSZ> GetRequiredExtensions();
|
||||
void CreateInstance();
|
||||
void CreateDebugUtilsMessenger();
|
||||
void CreateSurface();
|
||||
bool CheckRequiredDeviceExtensions(VkPhysicalDevice device);
|
||||
QueueFamilyIndices FindQueueFamilyIndices(VkPhysicalDevice device);
|
||||
bool IsDeviceSuitable(VkPhysicalDevice device);
|
||||
void PickPhysicalDevice();
|
||||
void CreateDevice();
|
||||
SwapChainInfo GetSwapChainInfo(VkPhysicalDevice device);
|
||||
void CreateSwapChain();
|
||||
void CreateImageViews();
|
||||
void CreateCommandPools();
|
||||
void CreateCommandBuffers();
|
||||
void CreateSyncObjects();
|
||||
|
||||
public:
|
||||
// Which graphics API?
|
||||
virtual Gapi GetGapi() override { return Gapi::vulkan; }
|
||||
|
||||
// Frame cycle:
|
||||
virtual void BeginFrame() override;
|
||||
virtual void EndFrame() override;
|
||||
virtual void Present() override;
|
||||
virtual void Clear(UINT32 flags) override;
|
||||
};
|
||||
VERUS_TYPEDEFS(RendererVulkan);
|
||||
}
|
||||
}
|
||||
|
||||
#define VERUS_QREF_RENDERER_VULKAN CGI::PRendererVulkan pRendererVulkan = CGI::RendererVulkan::P()
|
|
@ -0,0 +1,23 @@
|
|||
#include "stdafx.h"
|
||||
|
||||
using namespace verus;
|
||||
using namespace verus::CGI;
|
||||
|
||||
ShaderVulkan::ShaderVulkan()
|
||||
{
|
||||
}
|
||||
|
||||
ShaderVulkan::~ShaderVulkan()
|
||||
{
|
||||
Done();
|
||||
}
|
||||
|
||||
void ShaderVulkan::Init(CSZ source, CSZ* list)
|
||||
{
|
||||
VERUS_INIT();
|
||||
}
|
||||
|
||||
void ShaderVulkan::Done()
|
||||
{
|
||||
VERUS_DONE(ShaderVulkan);
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace CGI
|
||||
{
|
||||
class ShaderVulkan : public BaseShader
|
||||
{
|
||||
public:
|
||||
ShaderVulkan();
|
||||
virtual ~ShaderVulkan() override;
|
||||
|
||||
virtual void Init(CSZ source, CSZ* list) override;
|
||||
virtual void Done() override;
|
||||
};
|
||||
}
|
||||
}
|
|
@ -18,32 +18,24 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
|
|||
|
||||
extern "C"
|
||||
{
|
||||
VERUS_DLL_EXPORT void* VerusCreateRenderer(UINT32 version, void* pDesc)
|
||||
VERUS_DLL_EXPORT verus::CGI::PBaseRenderer VerusCreateRenderer(UINT32 version, verus::CGI::PBaseRendererDesc pDesc)
|
||||
{
|
||||
return nullptr;
|
||||
#if 0
|
||||
using namespace verus;
|
||||
|
||||
if (VERUS_SDK_VERSION != version)
|
||||
{
|
||||
VERUS_RT_FAIL("FAIL: wrong version");
|
||||
VERUS_RT_FAIL("VerusCreateRenderer(), Wrong version");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
pDesc->_pack.Paste();
|
||||
pDesc->_gvc.Paste();
|
||||
|
||||
CGI::RendererVulkan::Make();
|
||||
|
||||
VERUS_QREF_RENDERER_VULKAN;
|
||||
|
||||
pRendererVulkan->SetDesc(*pDesc);
|
||||
|
||||
if (pDesc->m_createWindow)
|
||||
pRendererVulkan->InitWindow();
|
||||
|
||||
pRendererVulkan->Init();
|
||||
|
||||
return pRendererVulkan;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,3 +2,5 @@
|
|||
|
||||
#define VERUS_INCLUDE_VULKAN
|
||||
#include <verus.h>
|
||||
|
||||
#include "CGI/CGI.h"
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
<ImportGroup Label="PropertySheets" />
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<IncludePath>C:\Home\Projects\Verus\verus\Verus\src;C:\Home\Middleware\bullet3-2.88\src;C:\Home\Middleware\bullet3-2.88\Extras;C:\Home\Middleware\glm-0.9.9.3\glm;C:\Home\Middleware\json-3.5.0;C:\Home\Middleware\libogg-1.3.3\include;C:\Home\Middleware\libvorbis-1.3.6\include;C:\Home\Middleware\SDL2-2.0.9\include;C:\Home\Middleware\tinyxml2-7.0.1;C:\Home\Middleware\vectormath;C:\Home\Middleware\zlib-1.2.11;C:\Program Files %28x86%29\OpenAL 1.1 SDK\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>C:\Home\Middleware\bullet3-2.88\lib\Debug;C:\Home\Middleware\libogg-1.3.3\lib;C:\Home\Middleware\libvorbis-1.3.6\lib2;C:\Home\Middleware\SDL2-2.0.9\lib\x64;C:\Home\Middleware\tinyxml2-7.0.1;C:\Home\Middleware\zlib-1.2.11;C:\Program Files %28x86%29\OpenAL 1.1 SDK\libs\Win64;$(LibraryPath)</LibraryPath>
|
||||
<IncludePath>C:\Home\Projects\Verus\verus\Verus\src;C:\Home\Middleware\bullet3-2.88\src;C:\Home\Middleware\bullet3-2.88\Extras;C:\Home\Middleware\glm-0.9.9.3\glm;C:\Home\Middleware\json-3.5.0;C:\Home\Middleware\libogg-1.3.3\include;C:\Home\Middleware\libvorbis-1.3.6\include;C:\Home\Middleware\SDL2-2.0.9\include;C:\Home\Middleware\tinyxml2-7.0.1;C:\Home\Middleware\vectormath;C:\Home\Middleware\zlib-1.2.11;C:\Program Files %28x86%29\OpenAL 1.1 SDK\include;C:\VulkanSDK\1.1.101.0\Include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>C:\Home\Middleware\bullet3-2.88\lib\Debug;C:\Home\Middleware\libogg-1.3.3\lib;C:\Home\Middleware\libvorbis-1.3.6\lib2;C:\Home\Middleware\SDL2-2.0.9\lib\x64;C:\Home\Middleware\tinyxml2-7.0.1;C:\Home\Middleware\zlib-1.2.11;C:\Program Files %28x86%29\OpenAL 1.1 SDK\libs\Win64;C:\VulkanSDK\1.1.101.0\Lib;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup />
|
||||
<ItemGroup />
|
||||
|
|
|
@ -104,6 +104,7 @@
|
|||
<ClInclude Include="src\Audio\Sound.h" />
|
||||
<ClInclude Include="src\Audio\Source.h" />
|
||||
<ClInclude Include="src\Audio\StreamPlayer.h" />
|
||||
<ClInclude Include="src\CGI\BaseCommandBuffer.h" />
|
||||
<ClInclude Include="src\CGI\BaseGeometry.h" />
|
||||
<ClInclude Include="src\CGI\BasePipeline.h" />
|
||||
<ClInclude Include="src\CGI\BaseRenderer.h" />
|
||||
|
@ -204,6 +205,7 @@
|
|||
<ClCompile Include="src\Audio\Sound.cpp" />
|
||||
<ClCompile Include="src\Audio\Source.cpp" />
|
||||
<ClCompile Include="src\Audio\StreamPlayer.cpp" />
|
||||
<ClCompile Include="src\CGI\BaseCommandBuffer.cpp" />
|
||||
<ClCompile Include="src\CGI\BaseGeometry.cpp" />
|
||||
<ClCompile Include="src\CGI\BasePipeline.cpp" />
|
||||
<ClCompile Include="src\CGI\BaseRenderer.cpp" />
|
||||
|
|
|
@ -363,6 +363,9 @@
|
|||
<ClInclude Include="src\CGI\Renderer.h">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\CGI\BaseCommandBuffer.h">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\CGI\BaseGeometry.cpp">
|
||||
|
@ -566,5 +569,8 @@
|
|||
<ClCompile Include="src\CGI\CGI.cpp">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\CGI\BaseCommandBuffer.cpp">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -29,7 +29,7 @@ void Settings::Load()
|
|||
Json::Load();
|
||||
|
||||
_quality = static_cast<Quality>(GetI("quality", +_quality));
|
||||
_direct3D = GetI("direct3D", _direct3D);
|
||||
_gapi = GetI("gapi", _gapi);
|
||||
_gpuAnisotropyLevel = GetI("gpuAnisotropyLevel", _gpuAnisotropyLevel);
|
||||
_gpuAntialiasingLevel = GetI("gpuAntialiasingLevel", _gpuAntialiasingLevel);
|
||||
_gpuDepthTexture = GetI("gpuDepthTexture", _gpuDepthTexture);
|
||||
|
@ -58,7 +58,7 @@ void Settings::Load()
|
|||
void Settings::Save()
|
||||
{
|
||||
Set("quality", +_quality);
|
||||
Set("direct3D", _direct3D);
|
||||
Set("gapi", _gapi);
|
||||
Set("gpuAnisotropyLevel", _gpuAnisotropyLevel);
|
||||
Set("gpuAntialiasingLevel", _gpuAntialiasingLevel);
|
||||
Set("gpuDepthTexture", _gpuDepthTexture);
|
||||
|
@ -183,7 +183,6 @@ void Settings::ParseCommandLineArgs(int argc, char* argv[])
|
|||
void Settings::SetQuality(Quality q)
|
||||
{
|
||||
_quality = q;
|
||||
_direct3D = 9;
|
||||
_gpuAnisotropyLevel = 0;
|
||||
_gpuAntialiasingLevel = 0;
|
||||
_gpuDepthTexture = 0;
|
||||
|
@ -221,7 +220,6 @@ void Settings::SetQuality(Quality q)
|
|||
_screenSizeWidth = 1024;
|
||||
break;
|
||||
case Quality::high:
|
||||
_direct3D = 11;
|
||||
_gpuAnisotropyLevel = 8;
|
||||
_gpuTrilinearFilter = true;
|
||||
_postProcessBloom = true;
|
||||
|
@ -234,7 +232,6 @@ void Settings::SetQuality(Quality q)
|
|||
_screenSizeWidth = 1280;
|
||||
break;
|
||||
case Quality::ultra:
|
||||
_direct3D = 11;
|
||||
_gpuAnisotropyLevel = 16;
|
||||
_gpuDepthTexture = 1;
|
||||
_gpuTrilinearFilter = true;
|
||||
|
@ -257,7 +254,7 @@ void Settings::SetQuality(Quality q)
|
|||
_screenWindowed = false;
|
||||
# endif
|
||||
#else // Linux?
|
||||
_direct3D = 0;
|
||||
_gapi = 0;
|
||||
_gpuForcedProfile = "arb1";
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace verus
|
|||
};
|
||||
|
||||
Quality _quality = Quality::medium;
|
||||
int _direct3D = 9;
|
||||
int _gapi = 12;
|
||||
int _gpuAnisotropyLevel = 4;
|
||||
int _gpuAntialiasingLevel = 0;
|
||||
int _gpuDepthTexture = 0;
|
||||
|
|
|
@ -27,6 +27,7 @@ Window::~Window()
|
|||
void Window::Init(RcDesc descConst)
|
||||
{
|
||||
VERUS_INIT();
|
||||
VERUS_QREF_SETTINGS;
|
||||
|
||||
Desc desc = descConst;
|
||||
if (desc._useSettings)
|
||||
|
@ -35,6 +36,8 @@ void Window::Init(RcDesc descConst)
|
|||
Uint32 flags = 0;
|
||||
if (desc._fullscreen)
|
||||
flags |= SDL_WINDOW_FULLSCREEN;
|
||||
if (0 == settings._gapi)
|
||||
flags |= SDL_WINDOW_VULKAN;
|
||||
|
||||
_pWnd = SDL_CreateWindow(
|
||||
desc._title ? desc._title : "",
|
||||
|
|
|
@ -26,6 +26,9 @@ namespace verus
|
|||
|
||||
void Init(RcDesc desc = Desc());
|
||||
void Done();
|
||||
|
||||
SDL_Window* GetSDL() { return _pWnd; }
|
||||
};
|
||||
VERUS_TYPEDEFS(Window);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
#include "verus.h"
|
||||
|
||||
using namespace verus;
|
||||
using namespace verus::CGI;
|
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace CGI
|
||||
{
|
||||
class BaseCommandBuffer : public Object
|
||||
{
|
||||
protected:
|
||||
BaseCommandBuffer() = default;
|
||||
virtual ~BaseCommandBuffer() = default;
|
||||
|
||||
public:
|
||||
virtual void Init() {}
|
||||
virtual void Done() {}
|
||||
|
||||
virtual void Begin() = 0;
|
||||
virtual void End() = 0;
|
||||
|
||||
virtual void BindVertexBuffers() = 0;
|
||||
virtual void BindIndexBuffer() = 0;
|
||||
|
||||
virtual void SetScissor() = 0;
|
||||
virtual void SetViewport() = 0;
|
||||
|
||||
virtual void BindPipeline() = 0;
|
||||
virtual void Clear(ClearFlags clearFlags) = 0;
|
||||
|
||||
virtual void Draw() = 0;
|
||||
virtual void DrawIndexed() = 0;
|
||||
};
|
||||
VERUS_TYPEDEFS(BaseCommandBuffer);
|
||||
}
|
||||
}
|
|
@ -4,8 +4,22 @@ namespace verus
|
|||
{
|
||||
namespace CGI
|
||||
{
|
||||
class BaseGeometry
|
||||
struct GeometryDesc
|
||||
{
|
||||
bool _dwordIndices = false;
|
||||
};
|
||||
VERUS_TYPEDEFS(GeometryDesc);
|
||||
|
||||
class BaseGeometry : public Object
|
||||
{
|
||||
protected:
|
||||
BaseGeometry() = default;
|
||||
virtual ~BaseGeometry() = default;
|
||||
|
||||
public:
|
||||
virtual void Init(RcGeometryDesc desc) = 0;
|
||||
virtual void Done() = 0;
|
||||
};
|
||||
VERUS_TYPEDEFS(BaseGeometry);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,16 @@ namespace verus
|
|||
{
|
||||
namespace CGI
|
||||
{
|
||||
class BasePipeline
|
||||
class BasePipeline : public Object
|
||||
{
|
||||
protected:
|
||||
BasePipeline() = default;
|
||||
virtual ~BasePipeline() = default;
|
||||
|
||||
public:
|
||||
virtual void Init() {}
|
||||
virtual void Done() {}
|
||||
};
|
||||
VERUS_TYPEDEFS(BasePipeline);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,23 +26,47 @@ namespace verus
|
|||
{
|
||||
protected:
|
||||
BaseRendererDesc _desc;
|
||||
UINT32 _numSwapChainBuffers = 0;
|
||||
UINT32 _swapChainBufferIndex = 0;
|
||||
UINT32 _ringBufferIndex = 0;
|
||||
|
||||
BaseRenderer();
|
||||
virtual ~BaseRenderer();
|
||||
|
||||
public:
|
||||
enum { ringBufferSize = 3 };
|
||||
|
||||
static BaseRenderer* Load(CSZ dll, RBaseRendererDesc desc);
|
||||
|
||||
virtual void ReleaseMe() = 0;
|
||||
|
||||
void SetDesc(RBaseRendererDesc desc) { _desc = desc; }
|
||||
|
||||
UINT32 GetNumSwapChainBuffers() const { return _numSwapChainBuffers; }
|
||||
UINT32 GetSwapChainBufferIndex() const { return _swapChainBufferIndex; }
|
||||
UINT32 GetRingBufferIndex() const { return _ringBufferIndex; }
|
||||
|
||||
// Which graphics API?
|
||||
virtual Gapi GetGapi() = 0;
|
||||
|
||||
virtual void PrepareDraw() {}
|
||||
virtual void Clear(UINT32 flags) {}
|
||||
virtual void Present() {}
|
||||
// Frame cycle:
|
||||
virtual void BeginFrame() = 0;
|
||||
virtual void EndFrame() = 0;
|
||||
virtual void Present() = 0;
|
||||
virtual void Clear(UINT32 flags) = 0;
|
||||
|
||||
// Resources:
|
||||
virtual PBaseCommandBuffer InsertCommandBuffer() { return nullptr; }
|
||||
virtual PBaseGeometry InsertGeometry() { return nullptr; }
|
||||
virtual PBasePipeline InsertPipeline() { return nullptr; }
|
||||
virtual PBaseShader InsertShader() { return nullptr; }
|
||||
virtual PBaseTexture InsertTexture() { return nullptr; }
|
||||
|
||||
virtual void DeleteCommandBuffer(PBaseCommandBuffer p) {}
|
||||
virtual void DeleteGeometry(PBaseGeometry p) {}
|
||||
virtual void DeletePipeline(PBasePipeline p) {}
|
||||
virtual void DeleteShader(PBaseShader p) {}
|
||||
virtual void DeleteTexture(PBaseTexture p) {}
|
||||
};
|
||||
VERUS_TYPEDEFS(BaseRenderer);
|
||||
}
|
||||
|
|
|
@ -2,3 +2,28 @@
|
|||
|
||||
using namespace verus;
|
||||
using namespace verus::CGI;
|
||||
|
||||
void BaseShader::Load(CSZ url)
|
||||
{
|
||||
Vector<BYTE> vData;
|
||||
IO::FileSystem::LoadResource(url, vData, IO::FileSystem::LoadDesc(true));
|
||||
|
||||
Vector<String> v;
|
||||
CSZ pText = reinterpret_cast<CSZ>(vData.data());
|
||||
CSZ p = strstr(pText, "//:");
|
||||
while (p)
|
||||
{
|
||||
const size_t span = strcspn(p, VERUS_CRNL);
|
||||
const String value(p + 3, span - 3);
|
||||
v.push_back(value);
|
||||
p = strstr(p + span, "//:");
|
||||
}
|
||||
|
||||
Vector<CSZ> vp;
|
||||
vp.reserve(v.size() + 1);
|
||||
VERUS_FOREACH_CONST(Vector<String>, v, it)
|
||||
vp.push_back(_C(*it));
|
||||
vp.push_back(0);
|
||||
|
||||
Init(reinterpret_cast<CSZ>(vData.data()), vp.data());
|
||||
}
|
||||
|
|
|
@ -4,8 +4,24 @@ namespace verus
|
|||
{
|
||||
namespace CGI
|
||||
{
|
||||
class BaseShader
|
||||
struct ShaderDesc
|
||||
{
|
||||
CSZ _source = nullptr;
|
||||
};
|
||||
VERUS_TYPEDEFS(ShaderDesc);
|
||||
|
||||
class BaseShader : public Object
|
||||
{
|
||||
protected:
|
||||
BaseShader() = default;
|
||||
virtual ~BaseShader() = default;
|
||||
|
||||
public:
|
||||
virtual void Init(CSZ source, CSZ* list) = 0;
|
||||
virtual void Done() = 0;
|
||||
|
||||
void Load(CSZ url);
|
||||
};
|
||||
VERUS_TYPEDEFS(BaseShader);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,16 @@ namespace verus
|
|||
{
|
||||
namespace CGI
|
||||
{
|
||||
class BaseTexture
|
||||
class BaseTexture : public Object
|
||||
{
|
||||
protected:
|
||||
BaseTexture() = default;
|
||||
virtual ~BaseTexture() = default;
|
||||
|
||||
public:
|
||||
virtual void Init() {}
|
||||
virtual void Done() {}
|
||||
};
|
||||
VERUS_TYPEDEFS(BaseTexture);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace CGI
|
||||
{
|
||||
enum class ClearFlags : int
|
||||
{
|
||||
color = (1 << 0),
|
||||
depth = (1 << 1),
|
||||
stencil = (1 << 2)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#include "BaseGeometry.h"
|
||||
#include "BasePipeline.h"
|
||||
#include "BaseShader.h"
|
||||
#include "BaseTexture.h"
|
||||
#include "BaseCommandBuffer.h"
|
||||
#include "BaseRenderer.h"
|
||||
|
||||
#include "Renderer.h"
|
||||
|
|
|
@ -26,14 +26,23 @@ bool Renderer::IsLoaded()
|
|||
void Renderer::Init(PRendererDelegate pDelegate)
|
||||
{
|
||||
VERUS_INIT();
|
||||
|
||||
VERUS_QREF_SETTINGS;
|
||||
|
||||
_pRendererDelegate = pDelegate;
|
||||
|
||||
CSZ dll = "RendererDirect3D12.dll";
|
||||
CSZ dll = "RendererVulkan.dll";
|
||||
switch (settings._gapi)
|
||||
{
|
||||
case 12:
|
||||
{
|
||||
dll = "RendererDirect3D12.dll";
|
||||
VERUS_LOG_INFO("Using Direct3D 12");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
VERUS_LOG_INFO("Using Vulkan");
|
||||
}
|
||||
BaseRendererDesc desc;
|
||||
|
||||
_pBaseRenderer = BaseRenderer::Load(dll, desc);
|
||||
|
||||
_gapi = _pBaseRenderer->GetGapi();
|
||||
|
|
|
@ -15,6 +15,8 @@ namespace verus
|
|||
|
||||
class Renderer : public Singleton<Renderer>, public Object
|
||||
{
|
||||
Vector4 _clearColor = Vector4(0);
|
||||
App::PWindow _pMainWindow = nullptr;
|
||||
PBaseRenderer _pBaseRenderer = nullptr;
|
||||
PRendererDelegate _pRendererDelegate = nullptr;
|
||||
UINT64 _numFrames = 0;
|
||||
|
@ -33,6 +35,12 @@ namespace verus
|
|||
|
||||
void Draw();
|
||||
void Present();
|
||||
|
||||
App::PWindow GetMainWindow() const { return _pMainWindow; }
|
||||
App::PWindow SetMainWindow(App::PWindow p) { return Utils::Swap(_pMainWindow, p); }
|
||||
|
||||
RcVector4 GetClearColor() const { return _clearColor; }
|
||||
void SetClearColor(RcVector4 color) { _clearColor = color; }
|
||||
};
|
||||
VERUS_TYPEDEFS(Renderer);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,10 @@ struct MyRendererDelegate : CGI::RendererDelegate
|
|||
virtual void Renderer_OnDraw() override
|
||||
{
|
||||
VERUS_QREF_RENDERER;
|
||||
renderer->PrepareDraw();
|
||||
VERUS_QREF_TIMER;
|
||||
const float x = fmod(timer.GetTime(), 1.f);
|
||||
renderer.SetClearColor(Vector4(x, 0.5f, 0.25f, 1.f));
|
||||
renderer->BeginFrame();
|
||||
renderer->Clear(0);
|
||||
_p->BaseGame_Draw();
|
||||
}
|
||||
|
@ -26,6 +29,7 @@ struct MyRendererDelegate : CGI::RendererDelegate
|
|||
virtual void Renderer_OnPresent() override
|
||||
{
|
||||
VERUS_QREF_RENDERER;
|
||||
renderer->EndFrame();
|
||||
renderer->Present();
|
||||
}
|
||||
|
||||
|
@ -101,6 +105,7 @@ void BaseGame::Initialize(VERUS_MAIN_DEFAULT_ARGS)
|
|||
#endif
|
||||
|
||||
_window.Init();
|
||||
CGI::Renderer::I().SetMainWindow(&_window);
|
||||
_engineInit.Init(this, new MyRendererDelegate(this));
|
||||
|
||||
// Configure:
|
||||
|
|
Binary file not shown.
|
@ -15,7 +15,7 @@
|
|||
<ProjectGuid>{D7085182-35B9-4689-ADBA-B77087AD16BF}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>VerusTest</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
|
|
Loading…
Reference in New Issue