2025-07-05 13:28:41 +03:30
|
|
|
#include <engine/events/window.hpp>
|
|
|
|
#include <engine/graphics/blender.hpp" // required for forward declaratio>
|
|
|
|
#include <engine/graphics/buffers.hpp" // required for forward declaratio>
|
|
|
|
#include <engine/graphics/render_command.hpp" // required for forward declaratio>
|
|
|
|
#include <engine/graphics/renderer.hpp" // required for forward declaratio>
|
|
|
|
#include <engine/platform/graphics/directx/graphics_context.hpp>
|
|
|
|
#include <engine/platform/graphics/directx/shared_context.hpp>
|
|
|
|
#include <engine/user_interface/user_interface.hpp" // required for forward declaratio>
|
|
|
|
#include <engine/utils/resource_manager.hpp" // required for forward declaratio>
|
2021-06-02 09:07:45 +04:30
|
|
|
|
|
|
|
#define GLFW_EXPOSE_NATIVE_WIN32
|
2021-07-01 19:25:46 +04:30
|
|
|
#include <glfw/glfw3.h>
|
2021-06-02 09:07:45 +04:30
|
|
|
#include <glfw/glfw3native.h>
|
|
|
|
|
|
|
|
namespace Light {
|
|
|
|
|
2025-07-05 13:28:41 +03:30
|
|
|
dxGraphicsContext::dxGraphicsContext(GLFWwindow *windowHandle)
|
|
|
|
: m_WindowHandle(windowHandle)
|
|
|
|
, m_DebugInterface(nullptr)
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
|
|
|
// set 'GraphicsAPI';
|
|
|
|
m_GraphicsAPI = GraphicsAPI::DirectX;
|
|
|
|
|
|
|
|
m_SharedContext = std::make_shared<dxSharedContext>();
|
|
|
|
|
|
|
|
// setup stuff
|
|
|
|
SetupDeviceAndSwapChain(windowHandle);
|
|
|
|
SetupRenderTargets();
|
|
|
|
SetupDebugInterface();
|
|
|
|
}
|
|
|
|
|
2025-07-05 13:28:41 +03:30
|
|
|
void dxGraphicsContext::SetupDeviceAndSwapChain(GLFWwindow *windowHandle)
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
|
|
|
Ref<dxSharedContext> context = std::static_pointer_cast<dxSharedContext>(m_SharedContext);
|
|
|
|
|
|
|
|
// swap chain desc
|
|
|
|
DXGI_SWAP_CHAIN_DESC sd = { 0 };
|
|
|
|
|
|
|
|
// buffer desc
|
2025-07-05 13:28:41 +03:30
|
|
|
sd.BufferDesc.Width = 1u;
|
|
|
|
sd.BufferDesc.Height = 1u;
|
|
|
|
sd.BufferDesc.RefreshRate.Numerator = NULL; // :#todo
|
2022-03-07 21:57:00 +03:30
|
|
|
sd.BufferDesc.RefreshRate.Denominator = NULL; // :#todo
|
2025-07-05 13:28:41 +03:30
|
|
|
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
|
|
sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
|
|
|
|
sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
2022-03-07 21:57:00 +03:30
|
|
|
|
|
|
|
// sample desc (for multi sampling) #todo: implement multi-samplingz
|
2025-07-05 13:28:41 +03:30
|
|
|
sd.SampleDesc.Count = 1u;
|
2022-03-07 21:57:00 +03:30
|
|
|
sd.SampleDesc.Quality = 0u;
|
|
|
|
|
|
|
|
// #todo: support swap chains with more than 1 back-buffer
|
|
|
|
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
|
|
|
sd.BufferCount = 1u;
|
|
|
|
|
|
|
|
// #todo: don't handle Windows's window with glfw, create it yourself
|
|
|
|
sd.OutputWindow = static_cast<HWND>(glfwGetWin32Window(windowHandle));
|
2025-07-05 13:28:41 +03:30
|
|
|
sd.Windowed = true;
|
2022-03-07 21:57:00 +03:30
|
|
|
|
|
|
|
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
|
|
|
|
|
|
|
sd.Flags = NULL;
|
|
|
|
|
|
|
|
// determine device flags
|
|
|
|
UINT flags = NULL;
|
2021-06-15 09:39:11 +04:30
|
|
|
#ifdef LIGHT_DEBUG
|
2022-03-07 21:57:00 +03:30
|
|
|
flags = D3D11_CREATE_DEVICE_DEBUG;
|
2021-06-15 09:39:11 +04:30
|
|
|
#endif
|
2021-06-02 09:07:45 +04:30
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
// create device and swap chain
|
2025-07-05 13:28:41 +03:30
|
|
|
DXC(D3D11CreateDeviceAndSwapChain(
|
|
|
|
nullptr,
|
|
|
|
D3D_DRIVER_TYPE_HARDWARE,
|
|
|
|
NULL,
|
|
|
|
flags,
|
|
|
|
nullptr,
|
|
|
|
NULL,
|
|
|
|
D3D11_SDK_VERSION,
|
|
|
|
&sd,
|
|
|
|
&context->GetSwapChainRef(),
|
|
|
|
&context->GetDeviceRef(),
|
|
|
|
nullptr,
|
|
|
|
&context->GetDeviceContextRef()
|
|
|
|
));
|
2022-03-07 21:57:00 +03:30
|
|
|
}
|
|
|
|
|
|
|
|
void dxGraphicsContext::SetupRenderTargets()
|
|
|
|
{
|
|
|
|
Ref<dxSharedContext> context = std::static_pointer_cast<dxSharedContext>(m_SharedContext);
|
|
|
|
|
|
|
|
// set primitive topology
|
|
|
|
context->GetDeviceContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
|
|
|
|
|
|
|
// create render target view
|
|
|
|
Microsoft::WRL::ComPtr<ID3D11Resource> backBuffer;
|
|
|
|
|
|
|
|
DXC(context->GetSwapChain()->GetBuffer(0u, __uuidof(ID3D11Resource), &backBuffer));
|
2025-07-05 13:28:41 +03:30
|
|
|
DXC(context->GetDevice()
|
|
|
|
->CreateRenderTargetView(backBuffer.Get(), nullptr, &context->GetRenderTargetViewRef())
|
|
|
|
);
|
2022-03-07 21:57:00 +03:30
|
|
|
|
|
|
|
// set render target view
|
2025-07-05 13:28:41 +03:30
|
|
|
context->GetDeviceContext()
|
|
|
|
->OMSetRenderTargets(1u, context->GetRenderTargetView().GetAddressOf(), nullptr);
|
2022-03-07 21:57:00 +03:30
|
|
|
}
|
|
|
|
|
|
|
|
void dxGraphicsContext::SetupDebugInterface()
|
|
|
|
{
|
2021-06-19 15:12:42 +04:30
|
|
|
#ifdef LIGHT_DEBUG
|
2022-03-07 21:57:00 +03:30
|
|
|
Ref<dxSharedContext> context = std::static_pointer_cast<dxSharedContext>(m_SharedContext);
|
2021-06-15 09:39:11 +04:30
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
HRESULT hr;
|
|
|
|
Microsoft::WRL::ComPtr<ID3D11Debug> debugInterface = nullptr;
|
|
|
|
DXC(context->GetDevice()->QueryInterface(__uuidof(ID3D11Debug), &debugInterface));
|
2021-07-22 13:00:41 +04:30
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
Microsoft::WRL::ComPtr<ID3D11InfoQueue> infoQueue = nullptr;
|
|
|
|
DXC(debugInterface->QueryInterface(__uuidof(ID3D11InfoQueue), &infoQueue));
|
2021-07-22 13:00:41 +04:30
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true);
|
|
|
|
infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true);
|
2021-06-15 09:39:11 +04:30
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
D3D11_MESSAGE_ID hide[] = {
|
|
|
|
D3D11_MESSAGE_ID_UNKNOWN,
|
|
|
|
// #todo: add more messages here as needed
|
|
|
|
};
|
2021-06-15 09:39:11 +04:30
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
D3D11_INFO_QUEUE_FILTER filter = {};
|
2025-07-05 13:28:41 +03:30
|
|
|
filter.DenyList.NumIDs = _countof(hide);
|
|
|
|
filter.DenyList.pIDList = hide;
|
2022-03-07 21:57:00 +03:30
|
|
|
infoQueue->AddStorageFilterEntries(&filter);
|
|
|
|
infoQueue->Release();
|
2021-06-21 18:08:25 +04:30
|
|
|
#endif
|
2022-03-07 21:57:00 +03:30
|
|
|
}
|
|
|
|
|
|
|
|
void dxGraphicsContext::LogDebugData()
|
|
|
|
{
|
|
|
|
Ref<dxSharedContext> context = std::static_pointer_cast<dxSharedContext>(m_SharedContext);
|
|
|
|
|
|
|
|
// locals
|
2025-07-05 13:28:41 +03:30
|
|
|
IDXGIDevice *DXGIDevice;
|
|
|
|
IDXGIAdapter *DXGIAdapter;
|
2022-03-07 21:57:00 +03:30
|
|
|
DXGI_ADAPTER_DESC DXGIAdapterDesc;
|
|
|
|
|
2025-07-05 13:28:41 +03:30
|
|
|
context->GetDevice()->QueryInterface(__uuidof(IDXGIDevice), (void **)&DXGIDevice);
|
2022-03-07 21:57:00 +03:30
|
|
|
DXGIDevice->GetAdapter(&DXGIAdapter);
|
|
|
|
DXGIAdapter->GetDesc(&DXGIAdapterDesc);
|
|
|
|
|
|
|
|
// get the adapter's description
|
|
|
|
char DefChar = ' ';
|
|
|
|
char ch[180];
|
|
|
|
WideCharToMultiByte(CP_ACP, 0, DXGIAdapterDesc.Description, -1, ch, 180, &DefChar, NULL);
|
|
|
|
std::string adapterDesc(ch);
|
|
|
|
|
|
|
|
// release memory
|
|
|
|
DXGIDevice->Release();
|
|
|
|
DXGIAdapter->Release();
|
|
|
|
|
|
|
|
// #todo: log more information
|
|
|
|
LOG(info, "________________________________________");
|
|
|
|
LOG(info, "dxGraphicsContext:");
|
|
|
|
LOG(info, " Renderer: {}", adapterDesc);
|
|
|
|
LOG(info, "________________________________________");
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace Light
|