2019.4
This commit is contained in:
parent
70a1778d22
commit
85f90cda62
|
@ -92,11 +92,19 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="src\CGI\CGI.h" />
|
<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\RendererD3D12.h" />
|
||||||
|
<ClInclude Include="src\CGI\ShaderD3D12.h" />
|
||||||
<ClInclude Include="src\stdafx.h" />
|
<ClInclude Include="src\stdafx.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<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\RendererD3D12.cpp" />
|
||||||
|
<ClCompile Include="src\CGI\ShaderD3D12.cpp" />
|
||||||
<ClCompile Include="src\main.cpp" />
|
<ClCompile Include="src\main.cpp" />
|
||||||
<ClCompile Include="src\stdafx.cpp">
|
<ClCompile Include="src\stdafx.cpp">
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||||
|
|
|
@ -30,6 +30,18 @@
|
||||||
<ClInclude Include="src\CGI\RendererD3D12.h">
|
<ClInclude Include="src\CGI\RendererD3D12.h">
|
||||||
<Filter>src\CGI</Filter>
|
<Filter>src\CGI</Filter>
|
||||||
</ClInclude>
|
</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>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\main.cpp">
|
<ClCompile Include="src\main.cpp">
|
||||||
|
@ -41,5 +53,17 @@
|
||||||
<ClCompile Include="src\CGI\RendererD3D12.cpp">
|
<ClCompile Include="src\CGI\RendererD3D12.cpp">
|
||||||
<Filter>src\CGI</Filter>
|
<Filter>src\CGI</Filter>
|
||||||
</ClCompile>
|
</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>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -1,3 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "CommandBufferD3D12.h"
|
||||||
|
#include "GeometryD3D12.h"
|
||||||
|
#include "PipelineD3D12.h"
|
||||||
|
#include "ShaderD3D12.h"
|
||||||
#include "RendererD3D12.h"
|
#include "RendererD3D12.h"
|
||||||
|
|
92
RendererDirect3D12/src/CGI/CommandBufferD3D12.cpp
Normal file
92
RendererDirect3D12/src/CGI/CommandBufferD3D12.cpp
Normal file
|
@ -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);
|
||||||
|
}
|
35
RendererDirect3D12/src/CGI/CommandBufferD3D12.h
Normal file
35
RendererDirect3D12/src/CGI/CommandBufferD3D12.h
Normal file
|
@ -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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
23
RendererDirect3D12/src/CGI/GeometryD3D12.cpp
Normal file
23
RendererDirect3D12/src/CGI/GeometryD3D12.cpp
Normal file
|
@ -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);
|
||||||
|
}
|
20
RendererDirect3D12/src/CGI/GeometryD3D12.h
Normal file
20
RendererDirect3D12/src/CGI/GeometryD3D12.h
Normal file
|
@ -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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
23
RendererDirect3D12/src/CGI/PipelineD3D12.cpp
Normal file
23
RendererDirect3D12/src/CGI/PipelineD3D12.cpp
Normal file
|
@ -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);
|
||||||
|
}
|
19
RendererDirect3D12/src/CGI/PipelineD3D12.h
Normal file
19
RendererDirect3D12/src/CGI/PipelineD3D12.h
Normal file
|
@ -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()
|
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);
|
VERUS_DONE(RendererD3D12);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererD3D12::EnableDebugLayer()
|
void RendererD3D12::EnableDebugLayer()
|
||||||
{
|
{
|
||||||
CComPtr<ID3D12Debug> pDebug;
|
ComPtr<ID3D12Debug> pDebug;
|
||||||
if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&pDebug))))
|
if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&pDebug))))
|
||||||
pDebug->EnableDebugLayer();
|
pDebug->EnableDebugLayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
CComPtr<IDXGIFactory7> RendererD3D12::CreateDXGIFactory()
|
ComPtr<IDXGIFactory6> RendererD3D12::CreateDXGIFactory()
|
||||||
{
|
{
|
||||||
HRESULT hr = 0;
|
HRESULT hr = 0;
|
||||||
CComPtr<IDXGIFactory7> pFactory;
|
ComPtr<IDXGIFactory6> pFactory;
|
||||||
UINT flags = 0;
|
UINT flags = 0;
|
||||||
#if defined(_DEBUG) || defined(VERUS_DEBUG)
|
#if defined(_DEBUG) || defined(VERUS_DEBUG)
|
||||||
flags = DXGI_CREATE_FACTORY_DEBUG;
|
flags = DXGI_CREATE_FACTORY_DEBUG;
|
||||||
|
@ -50,16 +68,16 @@ CComPtr<IDXGIFactory7> RendererD3D12::CreateDXGIFactory()
|
||||||
return pFactory;
|
return pFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
CComPtr<IDXGIAdapter4> RendererD3D12::GetAdapter(CComPtr<IDXGIFactory7> pFactory)
|
ComPtr<IDXGIAdapter4> RendererD3D12::GetAdapter(ComPtr<IDXGIFactory6> pFactory)
|
||||||
{
|
{
|
||||||
HRESULT hr = 0;
|
HRESULT hr = 0;
|
||||||
CComPtr<IDXGIAdapter4> pAdapter;
|
ComPtr<IDXGIAdapter4> pAdapter;
|
||||||
if (FAILED(hr = pFactory->EnumAdapterByGpuPreference(0, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, IID_PPV_ARGS(&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);
|
throw VERUS_RUNTIME_ERROR << "EnumAdapterByGpuPreference(), hr=" << VERUS_HR(hr);
|
||||||
return pAdapter;
|
return pAdapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RendererD3D12::CheckFeatureSupportAllowTearing(CComPtr<IDXGIFactory7> pFactory)
|
bool RendererD3D12::CheckFeatureSupportAllowTearing(ComPtr<IDXGIFactory6> pFactory)
|
||||||
{
|
{
|
||||||
BOOL data = FALSE;
|
BOOL data = FALSE;
|
||||||
if (FAILED(pFactory->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &data, sizeof(data))))
|
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()
|
void RendererD3D12::CreateSwapChainBuffersRTVs()
|
||||||
{
|
{
|
||||||
HRESULT hr = 0;
|
HRESULT hr = 0;
|
||||||
_swapChainBuffersRTVs = CreateDescriptorHeap(D3D12_DESCRIPTOR_HEAP_TYPE_RTV, _swapChainDesc.BufferCount);
|
_vSwapChainBuffers.resize(_numSwapChainBuffers);
|
||||||
_vSwapChainBuffers.resize(_swapChainDesc.BufferCount);
|
_dSwapChainBuffersRTVs = CreateDescriptorHeap(D3D12_DESCRIPTOR_HEAP_TYPE_RTV, _numSwapChainBuffers);
|
||||||
auto dh = _swapChainBuffersRTVs->GetCPUDescriptorHandleForHeapStart();
|
auto dh = _dSwapChainBuffersRTVs->GetCPUDescriptorHandleForHeapStart();
|
||||||
VERUS_U_FOR(i, _swapChainDesc.BufferCount)
|
VERUS_U_FOR(i, _numSwapChainBuffers)
|
||||||
{
|
{
|
||||||
CComPtr<ID3D12Resource> pBuffer;
|
ComPtr<ID3D12Resource> pBuffer;
|
||||||
if (FAILED(hr = _pSwapChain->GetBuffer(i, IID_PPV_ARGS(&pBuffer))))
|
if (FAILED(hr = _pSwapChain->GetBuffer(i, IID_PPV_ARGS(&pBuffer))))
|
||||||
throw VERUS_RUNTIME_ERROR << "GetBuffer(), hr=" << VERUS_HR(hr);
|
throw VERUS_RUNTIME_ERROR << "GetBuffer(), hr=" << VERUS_HR(hr);
|
||||||
_pDevice->CreateRenderTargetView(pBuffer, nullptr, dh);
|
_pDevice->CreateRenderTargetView(pBuffer.Get(), nullptr, dh);
|
||||||
_vSwapChainBuffers[i] = pBuffer;
|
_vSwapChainBuffers[i] = pBuffer;
|
||||||
dh.ptr += _descHandleIncSizeRTV;
|
dh.ptr += _descHandleIncSizeRTV;
|
||||||
}
|
}
|
||||||
|
@ -86,6 +104,7 @@ void RendererD3D12::CreateSwapChainBuffersRTVs()
|
||||||
|
|
||||||
void RendererD3D12::InitD3D()
|
void RendererD3D12::InitD3D()
|
||||||
{
|
{
|
||||||
|
VERUS_QREF_RENDERER;
|
||||||
VERUS_QREF_SETTINGS;
|
VERUS_QREF_SETTINGS;
|
||||||
|
|
||||||
HRESULT hr = 0;
|
HRESULT hr = 0;
|
||||||
|
@ -94,15 +113,17 @@ void RendererD3D12::InitD3D()
|
||||||
EnableDebugLayer();
|
EnableDebugLayer();
|
||||||
#endif
|
#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);
|
throw VERUS_RUNTIME_ERROR << "D3D12CreateDevice(), hr=" << VERUS_HR(hr);
|
||||||
|
|
||||||
_pCommandQueue = CreateCommandQueue(D3D12_COMMAND_LIST_TYPE_DIRECT);
|
_pCommandQueue = CreateCommandQueue(D3D12_COMMAND_LIST_TYPE_DIRECT);
|
||||||
|
|
||||||
|
_numSwapChainBuffers = settings._screenVSync ? 3 : 2;
|
||||||
|
|
||||||
_swapChainDesc.Width = settings._screenSizeWidth;
|
_swapChainDesc.Width = settings._screenSizeWidth;
|
||||||
_swapChainDesc.Height = settings._screenSizeHeight;
|
_swapChainDesc.Height = settings._screenSizeHeight;
|
||||||
_swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
_swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
@ -110,39 +131,45 @@ void RendererD3D12::InitD3D()
|
||||||
_swapChainDesc.SampleDesc.Count = 1;
|
_swapChainDesc.SampleDesc.Count = 1;
|
||||||
_swapChainDesc.SampleDesc.Quality = 0;
|
_swapChainDesc.SampleDesc.Quality = 0;
|
||||||
_swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
_swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||||
_swapChainDesc.BufferCount = 2;
|
_swapChainDesc.BufferCount = _numSwapChainBuffers;
|
||||||
_swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
|
_swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
|
||||||
_swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
_swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||||
_swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
|
_swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
|
||||||
_swapChainDesc.Flags = CheckFeatureSupportAllowTearing(pFactory) ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0;
|
_swapChainDesc.Flags = CheckFeatureSupportAllowTearing(pFactory) ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0;
|
||||||
|
|
||||||
CComPtr<IDXGISwapChain1> pSwapChain1;
|
SDL_Window* pWnd = renderer.GetMainWindow()->GetSDL();
|
||||||
if (FAILED(hr = pFactory->CreateSwapChainForHwnd(_pCommandQueue, GetActiveWindow(), &_swapChainDesc, nullptr, nullptr, &pSwapChain1)))
|
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);
|
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);
|
throw VERUS_RUNTIME_ERROR << "QueryInterface(), hr=" << VERUS_HR(hr);
|
||||||
|
|
||||||
_descHandleIncSizeRTV = _pDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
_descHandleIncSizeRTV = _pDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
||||||
|
|
||||||
_currentBackBufferIndex = _pSwapChain->GetCurrentBackBufferIndex();
|
_swapChainBufferIndex = _pSwapChain->GetCurrentBackBufferIndex();
|
||||||
|
|
||||||
CreateSwapChainBuffersRTVs();
|
CreateSwapChainBuffersRTVs();
|
||||||
|
|
||||||
_vCommandAllocators.resize(_swapChainDesc.BufferCount);
|
VERUS_FOR(i, ringBufferSize)
|
||||||
VERUS_U_FOR(i, _swapChainDesc.BufferCount)
|
_mapCommandAllocators[i][std::this_thread::get_id()] = CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT);
|
||||||
_vCommandAllocators[i] = 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();
|
_pFence = CreateFence();
|
||||||
_hFence = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
_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;
|
HRESULT hr = 0;
|
||||||
CComPtr<ID3D12CommandQueue> pCommandQueue;
|
ComPtr<ID3D12CommandQueue> pCommandQueue;
|
||||||
D3D12_COMMAND_QUEUE_DESC desc = {};
|
D3D12_COMMAND_QUEUE_DESC desc = {};
|
||||||
desc.Type = type;
|
desc.Type = type;
|
||||||
desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
|
desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
|
||||||
|
@ -152,30 +179,30 @@ CComPtr<ID3D12CommandQueue> RendererD3D12::CreateCommandQueue(D3D12_COMMAND_LIST
|
||||||
return pCommandQueue;
|
return pCommandQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
CComPtr<ID3D12CommandAllocator> RendererD3D12::CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE type)
|
ComPtr<ID3D12CommandAllocator> RendererD3D12::CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE type)
|
||||||
{
|
{
|
||||||
HRESULT hr = 0;
|
HRESULT hr = 0;
|
||||||
CComPtr<ID3D12CommandAllocator> pCommandAllocator;
|
ComPtr<ID3D12CommandAllocator> pCommandAllocator;
|
||||||
if (FAILED(hr = _pDevice->CreateCommandAllocator(type, IID_PPV_ARGS(&pCommandAllocator))))
|
if (FAILED(hr = _pDevice->CreateCommandAllocator(type, IID_PPV_ARGS(&pCommandAllocator))))
|
||||||
throw VERUS_RUNTIME_ERROR << "CreateCommandAllocator(), hr=" << VERUS_HR(hr);
|
throw VERUS_RUNTIME_ERROR << "CreateCommandAllocator(), hr=" << VERUS_HR(hr);
|
||||||
return pCommandAllocator;
|
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;
|
HRESULT hr = 0;
|
||||||
CComPtr<ID3D12GraphicsCommandList> pGraphicsCommandList;
|
ComPtr<ID3D12GraphicsCommandList> pGraphicsCommandList;
|
||||||
if (FAILED(hr = _pDevice->CreateCommandList(0, type, pCommandAllocator, nullptr, IID_PPV_ARGS(&pGraphicsCommandList))))
|
if (FAILED(hr = _pDevice->CreateCommandList(0, type, pCommandAllocator.Get(), nullptr, IID_PPV_ARGS(&pGraphicsCommandList))))
|
||||||
throw VERUS_RUNTIME_ERROR << "CreateCommandList(), hr=" << VERUS_HR(hr);
|
throw VERUS_RUNTIME_ERROR << "CreateCommandList(), hr=" << VERUS_HR(hr);
|
||||||
if (FAILED(hr = pGraphicsCommandList->Close()))
|
if (FAILED(hr = pGraphicsCommandList->Close()))
|
||||||
throw VERUS_RUNTIME_ERROR << "Close(), hr=" << VERUS_HR(hr);
|
throw VERUS_RUNTIME_ERROR << "Close(), hr=" << VERUS_HR(hr);
|
||||||
return pGraphicsCommandList;
|
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;
|
HRESULT hr = 0;
|
||||||
CComPtr<ID3D12DescriptorHeap> pDescriptorHeap;
|
ComPtr<ID3D12DescriptorHeap> pDescriptorHeap;
|
||||||
D3D12_DESCRIPTOR_HEAP_DESC desc = {};
|
D3D12_DESCRIPTOR_HEAP_DESC desc = {};
|
||||||
desc.Type = type;
|
desc.Type = type;
|
||||||
desc.NumDescriptors = num;
|
desc.NumDescriptors = num;
|
||||||
|
@ -184,20 +211,20 @@ CComPtr<ID3D12DescriptorHeap> RendererD3D12::CreateDescriptorHeap(D3D12_DESCRIPT
|
||||||
return pDescriptorHeap;
|
return pDescriptorHeap;
|
||||||
}
|
}
|
||||||
|
|
||||||
CComPtr<ID3D12Fence> RendererD3D12::CreateFence()
|
ComPtr<ID3D12Fence> RendererD3D12::CreateFence()
|
||||||
{
|
{
|
||||||
HRESULT hr = 0;
|
HRESULT hr = 0;
|
||||||
CComPtr<ID3D12Fence> pFence;
|
ComPtr<ID3D12Fence> pFence;
|
||||||
if (FAILED(hr = _pDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&pFence))))
|
if (FAILED(hr = _pDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&pFence))))
|
||||||
throw VERUS_RUNTIME_ERROR << "CreateFence(), hr=" << VERUS_HR(hr);
|
throw VERUS_RUNTIME_ERROR << "CreateFence(), hr=" << VERUS_HR(hr);
|
||||||
return pFence;
|
return pFence;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT64 RendererD3D12::Signal()
|
UINT64 RendererD3D12::QueueSignal()
|
||||||
{
|
{
|
||||||
HRESULT hr = 0;
|
HRESULT hr = 0;
|
||||||
const UINT64 value = ++_fenceValue;
|
const UINT64 value = _nextFenceValue++;
|
||||||
if (FAILED(hr = _pCommandQueue->Signal(_pFence, value)))
|
if (FAILED(hr = _pCommandQueue->Signal(_pFence.Get(), value)))
|
||||||
throw VERUS_RUNTIME_ERROR << "Signal(), hr=" << VERUS_HR(hr);
|
throw VERUS_RUNTIME_ERROR << "Signal(), hr=" << VERUS_HR(hr);
|
||||||
return value;
|
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);
|
WaitForFenceValue(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,29 +258,39 @@ D3D12_RESOURCE_BARRIER RendererD3D12::MakeResourceBarrierTransition(ID3D12Resour
|
||||||
return rb;
|
return rb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererD3D12::PrepareDraw()
|
void RendererD3D12::BeginFrame()
|
||||||
{
|
{
|
||||||
auto pBackBuffer = _vSwapChainBuffers[_currentBackBufferIndex];
|
HRESULT hr = 0;
|
||||||
auto pCommandAllocator = _vCommandAllocators[_currentBackBufferIndex];
|
|
||||||
|
|
||||||
pCommandAllocator->Reset();
|
WaitForFenceValue(_fenceValues[_ringBufferIndex]);
|
||||||
_pCommandList->Reset(pCommandAllocator, nullptr);
|
|
||||||
|
|
||||||
const auto rb = MakeResourceBarrierTransition(pBackBuffer, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET);
|
_swapChainBufferIndex = _pSwapChain->GetCurrentBackBufferIndex();
|
||||||
_pCommandList->ResourceBarrier(1, &rb);
|
|
||||||
|
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;
|
HRESULT hr = 0;
|
||||||
x += 0.0001f;
|
|
||||||
x = fmod(x, 1.f);
|
|
||||||
FLOAT clearColor[] = { x, 0.5f, 0.25f, 1.0f };
|
|
||||||
|
|
||||||
auto dh = _swapChainBuffersRTVs->GetCPUDescriptorHandleForHeapStart();
|
auto pBackBuffer = _vSwapChainBuffers[_swapChainBufferIndex];
|
||||||
dh.ptr += _currentBackBufferIndex * _descHandleIncSizeRTV;
|
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()
|
void RendererD3D12::Present()
|
||||||
|
@ -263,23 +300,20 @@ void RendererD3D12::Present()
|
||||||
bool g_VSync = false;
|
bool g_VSync = false;
|
||||||
bool g_TearingSupported = false;
|
bool g_TearingSupported = false;
|
||||||
|
|
||||||
auto pBackBuffer = _vSwapChainBuffers[_currentBackBufferIndex];
|
const UINT syncInterval = g_VSync ? 1 : 0;
|
||||||
|
const UINT flags = g_TearingSupported && !g_VSync ? DXGI_PRESENT_ALLOW_TEARING : 0;
|
||||||
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;
|
|
||||||
if (FAILED(hr = _pSwapChain->Present(syncInterval, flags)))
|
if (FAILED(hr = _pSwapChain->Present(syncInterval, flags)))
|
||||||
throw VERUS_RUNTIME_ERROR << "Present(), hr=" << VERUS_HR(hr);
|
throw VERUS_RUNTIME_ERROR << "Present(), hr=" << VERUS_HR(hr);
|
||||||
|
|
||||||
_currentBackBufferIndex = _pSwapChain->GetCurrentBackBufferIndex();
|
_ringBufferIndex = (_ringBufferIndex + 1) % ringBufferSize;
|
||||||
WaitForFenceValue(_vFenceValues[_currentBackBufferIndex]);
|
}
|
||||||
|
|
||||||
|
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
|
class RendererD3D12 : public Singleton<RendererD3D12>, public BaseRenderer
|
||||||
{
|
{
|
||||||
CComPtr<IDXGISwapChain4> _pSwapChain;
|
typedef Map<std::thread::id, ComPtr<ID3D12CommandAllocator>> TMapCommandAllocators;
|
||||||
CComPtr<ID3D12Device3> _pDevice;
|
|
||||||
CComPtr<ID3D12CommandQueue> _pCommandQueue;
|
ComPtr<ID3D12Device3> _pDevice;
|
||||||
CComPtr<ID3D12Fence> _pFence;
|
ComPtr<ID3D12CommandQueue> _pCommandQueue;
|
||||||
CComPtr<ID3D12DescriptorHeap> _swapChainBuffersRTVs;
|
ComPtr<IDXGISwapChain4> _pSwapChain;
|
||||||
Vector<CComPtr<ID3D12Resource>> _vSwapChainBuffers;
|
Vector<ComPtr<ID3D12Resource>> _vSwapChainBuffers;
|
||||||
Vector<CComPtr<ID3D12CommandAllocator>> _vCommandAllocators;
|
ComPtr<ID3D12DescriptorHeap> _dSwapChainBuffersRTVs;
|
||||||
Vector<UINT64> _vFenceValues;
|
TMapCommandAllocators _mapCommandAllocators[ringBufferSize];
|
||||||
CComPtr<ID3D12GraphicsCommandList> _pCommandList;
|
ComPtr<ID3D12GraphicsCommandList> _pCommandLists[ringBufferSize];
|
||||||
DXGI_SWAP_CHAIN_DESC1 _swapChainDesc = {};
|
ComPtr<ID3D12Fence> _pFence;
|
||||||
HANDLE _hFence = 0;
|
HANDLE _hFence = INVALID_HANDLE_VALUE;
|
||||||
UINT64 _fenceValue = 0;
|
UINT64 _nextFenceValue = 1;
|
||||||
UINT _descHandleIncSizeRTV = 0;
|
UINT64 _fenceValues[ringBufferSize];
|
||||||
UINT _currentBackBufferIndex = 0;
|
UINT _descHandleIncSizeRTV = 0;
|
||||||
|
DXGI_SWAP_CHAIN_DESC1 _swapChainDesc = {};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RendererD3D12();
|
RendererD3D12();
|
||||||
|
@ -30,29 +31,34 @@ namespace verus
|
||||||
void Init();
|
void Init();
|
||||||
void Done();
|
void Done();
|
||||||
|
|
||||||
VERUS_P(static void EnableDebugLayer());
|
private:
|
||||||
VERUS_P(static CComPtr<IDXGIFactory7> CreateDXGIFactory());
|
static void EnableDebugLayer();
|
||||||
VERUS_P(static CComPtr<IDXGIAdapter4> GetAdapter(CComPtr<IDXGIFactory7> pFactory));
|
static ComPtr<IDXGIFactory6> CreateDXGIFactory();
|
||||||
VERUS_P(static bool CheckFeatureSupportAllowTearing(CComPtr<IDXGIFactory7> pFactory));
|
static ComPtr<IDXGIAdapter4> GetAdapter(ComPtr<IDXGIFactory6> pFactory);
|
||||||
VERUS_P(void CreateSwapChainBuffersRTVs());
|
static bool CheckFeatureSupportAllowTearing(ComPtr<IDXGIFactory6> pFactory);
|
||||||
VERUS_P(void InitD3D());
|
void CreateSwapChainBuffersRTVs();
|
||||||
|
void InitD3D();
|
||||||
|
|
||||||
virtual Gapi GetGapi() override { return Gapi::direct3D12; }
|
public:
|
||||||
|
ComPtr<ID3D12CommandQueue> CreateCommandQueue(D3D12_COMMAND_LIST_TYPE type);
|
||||||
CComPtr<ID3D12CommandQueue> CreateCommandQueue(D3D12_COMMAND_LIST_TYPE type);
|
ComPtr<ID3D12CommandAllocator> CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE type);
|
||||||
CComPtr<ID3D12CommandAllocator> CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE type);
|
ComPtr<ID3D12GraphicsCommandList> CreateCommandList(D3D12_COMMAND_LIST_TYPE type, ComPtr<ID3D12CommandAllocator> pCommandAllocator);
|
||||||
CComPtr<ID3D12GraphicsCommandList> CreateCommandList(D3D12_COMMAND_LIST_TYPE type, CComPtr<ID3D12CommandAllocator> pCommandAllocator);
|
ComPtr<ID3D12DescriptorHeap> CreateDescriptorHeap(D3D12_DESCRIPTOR_HEAP_TYPE type, UINT num);
|
||||||
CComPtr<ID3D12DescriptorHeap> CreateDescriptorHeap(D3D12_DESCRIPTOR_HEAP_TYPE type, UINT num);
|
ComPtr<ID3D12Fence> CreateFence();
|
||||||
CComPtr<ID3D12Fence> CreateFence();
|
UINT64 QueueSignal();
|
||||||
UINT64 Signal();
|
|
||||||
void WaitForFenceValue(UINT64 value);
|
void WaitForFenceValue(UINT64 value);
|
||||||
void Flush();
|
void QueueWaitIdle();
|
||||||
|
|
||||||
static D3D12_RESOURCE_BARRIER MakeResourceBarrierTransition(ID3D12Resource* pResource, D3D12_RESOURCE_STATES before, D3D12_RESOURCE_STATES after);
|
static D3D12_RESOURCE_BARRIER MakeResourceBarrierTransition(ID3D12Resource* pResource, D3D12_RESOURCE_STATES before, D3D12_RESOURCE_STATES after);
|
||||||
|
|
||||||
virtual void PrepareDraw() override;
|
// Which graphics API?
|
||||||
virtual void Clear(UINT32 flags) override;
|
virtual Gapi GetGapi() override { return Gapi::direct3D12; }
|
||||||
|
|
||||||
|
// Frame cycle:
|
||||||
|
virtual void BeginFrame() override;
|
||||||
|
virtual void EndFrame() override;
|
||||||
virtual void Present() override;
|
virtual void Present() override;
|
||||||
|
virtual void Clear(UINT32 flags) override;
|
||||||
};
|
};
|
||||||
VERUS_TYPEDEFS(RendererD3D12);
|
VERUS_TYPEDEFS(RendererD3D12);
|
||||||
}
|
}
|
||||||
|
|
78
RendererDirect3D12/src/CGI/ShaderD3D12.cpp
Normal file
78
RendererDirect3D12/src/CGI/ShaderD3D12.cpp
Normal file
|
@ -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);
|
||||||
|
}
|
44
RendererDirect3D12/src/CGI/ShaderD3D12.h
Normal file
44
RendererDirect3D12/src/CGI/ShaderD3D12.h
Normal file
|
@ -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>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<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" />
|
<ClInclude Include="src\stdafx.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<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\main.cpp" />
|
||||||
<ClCompile Include="src\stdafx.cpp">
|
<ClCompile Include="src\stdafx.cpp">
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||||
|
|
|
@ -16,11 +16,32 @@
|
||||||
<Filter Include="src">
|
<Filter Include="src">
|
||||||
<UniqueIdentifier>{836b7e96-dc7f-4278-832a-6305a03b69e4}</UniqueIdentifier>
|
<UniqueIdentifier>{836b7e96-dc7f-4278-832a-6305a03b69e4}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="src\CGI">
|
||||||
|
<UniqueIdentifier>{4abdc4ba-6c11-4cdc-b578-2101f063b0c6}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="src\stdafx.h">
|
<ClInclude Include="src\stdafx.h">
|
||||||
<Filter>src</Filter>
|
<Filter>src</Filter>
|
||||||
</ClInclude>
|
</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>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\main.cpp">
|
<ClCompile Include="src\main.cpp">
|
||||||
|
@ -29,5 +50,20 @@
|
||||||
<ClCompile Include="src\stdafx.cpp">
|
<ClCompile Include="src\stdafx.cpp">
|
||||||
<Filter>src</Filter>
|
<Filter>src</Filter>
|
||||||
</ClCompile>
|
</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>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
7
RendererVulkan/src/CGI/CGI.h
Normal file
7
RendererVulkan/src/CGI/CGI.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CommandBufferVulkan.h"
|
||||||
|
#include "GeometryVulkan.h"
|
||||||
|
#include "PipelineVulkan.h"
|
||||||
|
#include "ShaderVulkan.h"
|
||||||
|
#include "RendererVulkan.h"
|
98
RendererVulkan/src/CGI/CommandBufferVulkan.cpp
Normal file
98
RendererVulkan/src/CGI/CommandBufferVulkan.cpp
Normal file
|
@ -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);
|
||||||
|
}
|
35
RendererVulkan/src/CGI/CommandBufferVulkan.h
Normal file
35
RendererVulkan/src/CGI/CommandBufferVulkan.h
Normal file
|
@ -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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
23
RendererVulkan/src/CGI/GeometryVulkan.cpp
Normal file
23
RendererVulkan/src/CGI/GeometryVulkan.cpp
Normal file
|
@ -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);
|
||||||
|
}
|
17
RendererVulkan/src/CGI/GeometryVulkan.h
Normal file
17
RendererVulkan/src/CGI/GeometryVulkan.h
Normal file
|
@ -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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
23
RendererVulkan/src/CGI/PipelineVulkan.cpp
Normal file
23
RendererVulkan/src/CGI/PipelineVulkan.cpp
Normal file
|
@ -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);
|
||||||
|
}
|
17
RendererVulkan/src/CGI/PipelineVulkan.h
Normal file
17
RendererVulkan/src/CGI/PipelineVulkan.h
Normal file
|
@ -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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
631
RendererVulkan/src/CGI/RendererVulkan.cpp
Normal file
631
RendererVulkan/src/CGI/RendererVulkan.cpp
Normal file
|
@ -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);
|
||||||
|
}
|
98
RendererVulkan/src/CGI/RendererVulkan.h
Normal file
98
RendererVulkan/src/CGI/RendererVulkan.h
Normal file
|
@ -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()
|
23
RendererVulkan/src/CGI/ShaderVulkan.cpp
Normal file
23
RendererVulkan/src/CGI/ShaderVulkan.cpp
Normal file
|
@ -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);
|
||||||
|
}
|
17
RendererVulkan/src/CGI/ShaderVulkan.h
Normal file
17
RendererVulkan/src/CGI/ShaderVulkan.h
Normal file
|
@ -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"
|
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;
|
using namespace verus;
|
||||||
|
|
||||||
if (VERUS_SDK_VERSION != version)
|
if (VERUS_SDK_VERSION != version)
|
||||||
{
|
{
|
||||||
VERUS_RT_FAIL("FAIL: wrong version");
|
VERUS_RT_FAIL("VerusCreateRenderer(), Wrong version");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
pDesc->_pack.Paste();
|
pDesc->_gvc.Paste();
|
||||||
|
|
||||||
CGI::RendererVulkan::Make();
|
CGI::RendererVulkan::Make();
|
||||||
|
|
||||||
VERUS_QREF_RENDERER_VULKAN;
|
VERUS_QREF_RENDERER_VULKAN;
|
||||||
|
|
||||||
pRendererVulkan->SetDesc(*pDesc);
|
pRendererVulkan->SetDesc(*pDesc);
|
||||||
|
|
||||||
if (pDesc->m_createWindow)
|
|
||||||
pRendererVulkan->InitWindow();
|
|
||||||
|
|
||||||
pRendererVulkan->Init();
|
pRendererVulkan->Init();
|
||||||
|
|
||||||
return pRendererVulkan;
|
return pRendererVulkan;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,3 +2,5 @@
|
||||||
|
|
||||||
#define VERUS_INCLUDE_VULKAN
|
#define VERUS_INCLUDE_VULKAN
|
||||||
#include <verus.h>
|
#include <verus.h>
|
||||||
|
|
||||||
|
#include "CGI/CGI.h"
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
<ImportGroup Label="PropertySheets" />
|
<ImportGroup Label="PropertySheets" />
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup>
|
<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>
|
<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;$(LibraryPath)</LibraryPath>
|
<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>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup />
|
<ItemDefinitionGroup />
|
||||||
<ItemGroup />
|
<ItemGroup />
|
||||||
|
|
|
@ -104,6 +104,7 @@
|
||||||
<ClInclude Include="src\Audio\Sound.h" />
|
<ClInclude Include="src\Audio\Sound.h" />
|
||||||
<ClInclude Include="src\Audio\Source.h" />
|
<ClInclude Include="src\Audio\Source.h" />
|
||||||
<ClInclude Include="src\Audio\StreamPlayer.h" />
|
<ClInclude Include="src\Audio\StreamPlayer.h" />
|
||||||
|
<ClInclude Include="src\CGI\BaseCommandBuffer.h" />
|
||||||
<ClInclude Include="src\CGI\BaseGeometry.h" />
|
<ClInclude Include="src\CGI\BaseGeometry.h" />
|
||||||
<ClInclude Include="src\CGI\BasePipeline.h" />
|
<ClInclude Include="src\CGI\BasePipeline.h" />
|
||||||
<ClInclude Include="src\CGI\BaseRenderer.h" />
|
<ClInclude Include="src\CGI\BaseRenderer.h" />
|
||||||
|
@ -204,6 +205,7 @@
|
||||||
<ClCompile Include="src\Audio\Sound.cpp" />
|
<ClCompile Include="src\Audio\Sound.cpp" />
|
||||||
<ClCompile Include="src\Audio\Source.cpp" />
|
<ClCompile Include="src\Audio\Source.cpp" />
|
||||||
<ClCompile Include="src\Audio\StreamPlayer.cpp" />
|
<ClCompile Include="src\Audio\StreamPlayer.cpp" />
|
||||||
|
<ClCompile Include="src\CGI\BaseCommandBuffer.cpp" />
|
||||||
<ClCompile Include="src\CGI\BaseGeometry.cpp" />
|
<ClCompile Include="src\CGI\BaseGeometry.cpp" />
|
||||||
<ClCompile Include="src\CGI\BasePipeline.cpp" />
|
<ClCompile Include="src\CGI\BasePipeline.cpp" />
|
||||||
<ClCompile Include="src\CGI\BaseRenderer.cpp" />
|
<ClCompile Include="src\CGI\BaseRenderer.cpp" />
|
||||||
|
|
|
@ -363,6 +363,9 @@
|
||||||
<ClInclude Include="src\CGI\Renderer.h">
|
<ClInclude Include="src\CGI\Renderer.h">
|
||||||
<Filter>src\CGI</Filter>
|
<Filter>src\CGI</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\CGI\BaseCommandBuffer.h">
|
||||||
|
<Filter>src\CGI</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\CGI\BaseGeometry.cpp">
|
<ClCompile Include="src\CGI\BaseGeometry.cpp">
|
||||||
|
@ -566,5 +569,8 @@
|
||||||
<ClCompile Include="src\CGI\CGI.cpp">
|
<ClCompile Include="src\CGI\CGI.cpp">
|
||||||
<Filter>src\CGI</Filter>
|
<Filter>src\CGI</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\CGI\BaseCommandBuffer.cpp">
|
||||||
|
<Filter>src\CGI</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -29,7 +29,7 @@ void Settings::Load()
|
||||||
Json::Load();
|
Json::Load();
|
||||||
|
|
||||||
_quality = static_cast<Quality>(GetI("quality", +_quality));
|
_quality = static_cast<Quality>(GetI("quality", +_quality));
|
||||||
_direct3D = GetI("direct3D", _direct3D);
|
_gapi = GetI("gapi", _gapi);
|
||||||
_gpuAnisotropyLevel = GetI("gpuAnisotropyLevel", _gpuAnisotropyLevel);
|
_gpuAnisotropyLevel = GetI("gpuAnisotropyLevel", _gpuAnisotropyLevel);
|
||||||
_gpuAntialiasingLevel = GetI("gpuAntialiasingLevel", _gpuAntialiasingLevel);
|
_gpuAntialiasingLevel = GetI("gpuAntialiasingLevel", _gpuAntialiasingLevel);
|
||||||
_gpuDepthTexture = GetI("gpuDepthTexture", _gpuDepthTexture);
|
_gpuDepthTexture = GetI("gpuDepthTexture", _gpuDepthTexture);
|
||||||
|
@ -58,7 +58,7 @@ void Settings::Load()
|
||||||
void Settings::Save()
|
void Settings::Save()
|
||||||
{
|
{
|
||||||
Set("quality", +_quality);
|
Set("quality", +_quality);
|
||||||
Set("direct3D", _direct3D);
|
Set("gapi", _gapi);
|
||||||
Set("gpuAnisotropyLevel", _gpuAnisotropyLevel);
|
Set("gpuAnisotropyLevel", _gpuAnisotropyLevel);
|
||||||
Set("gpuAntialiasingLevel", _gpuAntialiasingLevel);
|
Set("gpuAntialiasingLevel", _gpuAntialiasingLevel);
|
||||||
Set("gpuDepthTexture", _gpuDepthTexture);
|
Set("gpuDepthTexture", _gpuDepthTexture);
|
||||||
|
@ -183,7 +183,6 @@ void Settings::ParseCommandLineArgs(int argc, char* argv[])
|
||||||
void Settings::SetQuality(Quality q)
|
void Settings::SetQuality(Quality q)
|
||||||
{
|
{
|
||||||
_quality = q;
|
_quality = q;
|
||||||
_direct3D = 9;
|
|
||||||
_gpuAnisotropyLevel = 0;
|
_gpuAnisotropyLevel = 0;
|
||||||
_gpuAntialiasingLevel = 0;
|
_gpuAntialiasingLevel = 0;
|
||||||
_gpuDepthTexture = 0;
|
_gpuDepthTexture = 0;
|
||||||
|
@ -221,7 +220,6 @@ void Settings::SetQuality(Quality q)
|
||||||
_screenSizeWidth = 1024;
|
_screenSizeWidth = 1024;
|
||||||
break;
|
break;
|
||||||
case Quality::high:
|
case Quality::high:
|
||||||
_direct3D = 11;
|
|
||||||
_gpuAnisotropyLevel = 8;
|
_gpuAnisotropyLevel = 8;
|
||||||
_gpuTrilinearFilter = true;
|
_gpuTrilinearFilter = true;
|
||||||
_postProcessBloom = true;
|
_postProcessBloom = true;
|
||||||
|
@ -234,7 +232,6 @@ void Settings::SetQuality(Quality q)
|
||||||
_screenSizeWidth = 1280;
|
_screenSizeWidth = 1280;
|
||||||
break;
|
break;
|
||||||
case Quality::ultra:
|
case Quality::ultra:
|
||||||
_direct3D = 11;
|
|
||||||
_gpuAnisotropyLevel = 16;
|
_gpuAnisotropyLevel = 16;
|
||||||
_gpuDepthTexture = 1;
|
_gpuDepthTexture = 1;
|
||||||
_gpuTrilinearFilter = true;
|
_gpuTrilinearFilter = true;
|
||||||
|
@ -257,7 +254,7 @@ void Settings::SetQuality(Quality q)
|
||||||
_screenWindowed = false;
|
_screenWindowed = false;
|
||||||
# endif
|
# endif
|
||||||
#else // Linux?
|
#else // Linux?
|
||||||
_direct3D = 0;
|
_gapi = 0;
|
||||||
_gpuForcedProfile = "arb1";
|
_gpuForcedProfile = "arb1";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace verus
|
||||||
};
|
};
|
||||||
|
|
||||||
Quality _quality = Quality::medium;
|
Quality _quality = Quality::medium;
|
||||||
int _direct3D = 9;
|
int _gapi = 12;
|
||||||
int _gpuAnisotropyLevel = 4;
|
int _gpuAnisotropyLevel = 4;
|
||||||
int _gpuAntialiasingLevel = 0;
|
int _gpuAntialiasingLevel = 0;
|
||||||
int _gpuDepthTexture = 0;
|
int _gpuDepthTexture = 0;
|
||||||
|
|
|
@ -27,6 +27,7 @@ Window::~Window()
|
||||||
void Window::Init(RcDesc descConst)
|
void Window::Init(RcDesc descConst)
|
||||||
{
|
{
|
||||||
VERUS_INIT();
|
VERUS_INIT();
|
||||||
|
VERUS_QREF_SETTINGS;
|
||||||
|
|
||||||
Desc desc = descConst;
|
Desc desc = descConst;
|
||||||
if (desc._useSettings)
|
if (desc._useSettings)
|
||||||
|
@ -35,6 +36,8 @@ void Window::Init(RcDesc descConst)
|
||||||
Uint32 flags = 0;
|
Uint32 flags = 0;
|
||||||
if (desc._fullscreen)
|
if (desc._fullscreen)
|
||||||
flags |= SDL_WINDOW_FULLSCREEN;
|
flags |= SDL_WINDOW_FULLSCREEN;
|
||||||
|
if (0 == settings._gapi)
|
||||||
|
flags |= SDL_WINDOW_VULKAN;
|
||||||
|
|
||||||
_pWnd = SDL_CreateWindow(
|
_pWnd = SDL_CreateWindow(
|
||||||
desc._title ? desc._title : "",
|
desc._title ? desc._title : "",
|
||||||
|
|
|
@ -26,6 +26,9 @@ namespace verus
|
||||||
|
|
||||||
void Init(RcDesc desc = Desc());
|
void Init(RcDesc desc = Desc());
|
||||||
void Done();
|
void Done();
|
||||||
|
|
||||||
|
SDL_Window* GetSDL() { return _pWnd; }
|
||||||
};
|
};
|
||||||
|
VERUS_TYPEDEFS(Window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
4
Verus/src/CGI/BaseCommandBuffer.cpp
Normal file
4
Verus/src/CGI/BaseCommandBuffer.cpp
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#include "verus.h"
|
||||||
|
|
||||||
|
using namespace verus;
|
||||||
|
using namespace verus::CGI;
|
34
Verus/src/CGI/BaseCommandBuffer.h
Normal file
34
Verus/src/CGI/BaseCommandBuffer.h
Normal file
|
@ -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
|
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
|
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:
|
protected:
|
||||||
BaseRendererDesc _desc;
|
BaseRendererDesc _desc;
|
||||||
|
UINT32 _numSwapChainBuffers = 0;
|
||||||
|
UINT32 _swapChainBufferIndex = 0;
|
||||||
|
UINT32 _ringBufferIndex = 0;
|
||||||
|
|
||||||
BaseRenderer();
|
BaseRenderer();
|
||||||
virtual ~BaseRenderer();
|
virtual ~BaseRenderer();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum { ringBufferSize = 3 };
|
||||||
|
|
||||||
static BaseRenderer* Load(CSZ dll, RBaseRendererDesc desc);
|
static BaseRenderer* Load(CSZ dll, RBaseRendererDesc desc);
|
||||||
|
|
||||||
virtual void ReleaseMe() = 0;
|
virtual void ReleaseMe() = 0;
|
||||||
|
|
||||||
void SetDesc(RBaseRendererDesc desc) { _desc = desc; }
|
void SetDesc(RBaseRendererDesc desc) { _desc = desc; }
|
||||||
|
|
||||||
|
UINT32 GetNumSwapChainBuffers() const { return _numSwapChainBuffers; }
|
||||||
|
UINT32 GetSwapChainBufferIndex() const { return _swapChainBufferIndex; }
|
||||||
|
UINT32 GetRingBufferIndex() const { return _ringBufferIndex; }
|
||||||
|
|
||||||
// Which graphics API?
|
// Which graphics API?
|
||||||
virtual Gapi GetGapi() = 0;
|
virtual Gapi GetGapi() = 0;
|
||||||
|
|
||||||
virtual void PrepareDraw() {}
|
// Frame cycle:
|
||||||
virtual void Clear(UINT32 flags) {}
|
virtual void BeginFrame() = 0;
|
||||||
virtual void Present() {}
|
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);
|
VERUS_TYPEDEFS(BaseRenderer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,3 +2,28 @@
|
||||||
|
|
||||||
using namespace verus;
|
using namespace verus;
|
||||||
using namespace verus::CGI;
|
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
|
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
|
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
|
#pragma once
|
||||||
|
|
||||||
|
namespace verus
|
||||||
|
{
|
||||||
|
namespace CGI
|
||||||
|
{
|
||||||
|
enum class ClearFlags : int
|
||||||
|
{
|
||||||
|
color = (1 << 0),
|
||||||
|
depth = (1 << 1),
|
||||||
|
stencil = (1 << 2)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#include "BaseGeometry.h"
|
#include "BaseGeometry.h"
|
||||||
#include "BasePipeline.h"
|
#include "BasePipeline.h"
|
||||||
#include "BaseShader.h"
|
#include "BaseShader.h"
|
||||||
#include "BaseTexture.h"
|
#include "BaseTexture.h"
|
||||||
|
#include "BaseCommandBuffer.h"
|
||||||
#include "BaseRenderer.h"
|
#include "BaseRenderer.h"
|
||||||
|
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
|
|
|
@ -26,14 +26,23 @@ bool Renderer::IsLoaded()
|
||||||
void Renderer::Init(PRendererDelegate pDelegate)
|
void Renderer::Init(PRendererDelegate pDelegate)
|
||||||
{
|
{
|
||||||
VERUS_INIT();
|
VERUS_INIT();
|
||||||
|
|
||||||
VERUS_QREF_SETTINGS;
|
VERUS_QREF_SETTINGS;
|
||||||
|
|
||||||
_pRendererDelegate = pDelegate;
|
_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;
|
BaseRendererDesc desc;
|
||||||
|
|
||||||
_pBaseRenderer = BaseRenderer::Load(dll, desc);
|
_pBaseRenderer = BaseRenderer::Load(dll, desc);
|
||||||
|
|
||||||
_gapi = _pBaseRenderer->GetGapi();
|
_gapi = _pBaseRenderer->GetGapi();
|
||||||
|
|
|
@ -15,6 +15,8 @@ namespace verus
|
||||||
|
|
||||||
class Renderer : public Singleton<Renderer>, public Object
|
class Renderer : public Singleton<Renderer>, public Object
|
||||||
{
|
{
|
||||||
|
Vector4 _clearColor = Vector4(0);
|
||||||
|
App::PWindow _pMainWindow = nullptr;
|
||||||
PBaseRenderer _pBaseRenderer = nullptr;
|
PBaseRenderer _pBaseRenderer = nullptr;
|
||||||
PRendererDelegate _pRendererDelegate = nullptr;
|
PRendererDelegate _pRendererDelegate = nullptr;
|
||||||
UINT64 _numFrames = 0;
|
UINT64 _numFrames = 0;
|
||||||
|
@ -33,6 +35,12 @@ namespace verus
|
||||||
|
|
||||||
void Draw();
|
void Draw();
|
||||||
void Present();
|
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);
|
VERUS_TYPEDEFS(Renderer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,10 @@ struct MyRendererDelegate : CGI::RendererDelegate
|
||||||
virtual void Renderer_OnDraw() override
|
virtual void Renderer_OnDraw() override
|
||||||
{
|
{
|
||||||
VERUS_QREF_RENDERER;
|
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);
|
renderer->Clear(0);
|
||||||
_p->BaseGame_Draw();
|
_p->BaseGame_Draw();
|
||||||
}
|
}
|
||||||
|
@ -26,6 +29,7 @@ struct MyRendererDelegate : CGI::RendererDelegate
|
||||||
virtual void Renderer_OnPresent() override
|
virtual void Renderer_OnPresent() override
|
||||||
{
|
{
|
||||||
VERUS_QREF_RENDERER;
|
VERUS_QREF_RENDERER;
|
||||||
|
renderer->EndFrame();
|
||||||
renderer->Present();
|
renderer->Present();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,6 +105,7 @@ void BaseGame::Initialize(VERUS_MAIN_DEFAULT_ARGS)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_window.Init();
|
_window.Init();
|
||||||
|
CGI::Renderer::I().SetMainWindow(&_window);
|
||||||
_engineInit.Init(this, new MyRendererDelegate(this));
|
_engineInit.Init(this, new MyRendererDelegate(this));
|
||||||
|
|
||||||
// Configure:
|
// Configure:
|
||||||
|
|
Binary file not shown.
|
@ -15,7 +15,7 @@
|
||||||
<ProjectGuid>{D7085182-35B9-4689-ADBA-B77087AD16BF}</ProjectGuid>
|
<ProjectGuid>{D7085182-35B9-4689-ADBA-B77087AD16BF}</ProjectGuid>
|
||||||
<Keyword>Win32Proj</Keyword>
|
<Keyword>Win32Proj</Keyword>
|
||||||
<RootNamespace>VerusTest</RootNamespace>
|
<RootNamespace>VerusTest</RootNamespace>
|
||||||
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
|
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
|
Loading…
Reference in a new issue