-
Notifications
You must be signed in to change notification settings - Fork 0
Dev/nissekaka directx #33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
6ef53fc
1cc002a
d5024c4
ccbaa84
e64d2a3
9429e74
d939312
d01a584
93b4ac9
94ffaf3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| #include "stdafx.h" | ||
| #include "DX11.h" | ||
|
|
||
| #include <stdexcept> | ||
|
|
||
| using namespace Microsoft::WRL; | ||
|
|
||
| RF::DX11::~DX11() { | ||
| } | ||
|
|
||
| void RF::DX11::Init(const HWND hwnd, const uint32_t width, const uint32_t height) { | ||
| mWidth = width; | ||
| mHeight = height; | ||
|
|
||
| CreateDeviceAndSwapChain(hwnd, width, height); | ||
| CreateRenderTargetView(); | ||
| CreateViewport(width, height); | ||
|
|
||
| mInitialized = true; | ||
| } | ||
|
|
||
| void RF::DX11::CreateDeviceAndSwapChain(const HWND hwnd, const uint32_t width, const uint32_t height) { | ||
| DXGI_SWAP_CHAIN_DESC scd = {}; | ||
| scd.BufferDesc.Width = width; | ||
| scd.BufferDesc.Height = height; | ||
| scd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; | ||
| scd.BufferDesc.RefreshRate.Numerator = 0u; | ||
| scd.BufferDesc.RefreshRate.Denominator = 0u; | ||
| scd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; | ||
| scd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; | ||
| scd.SampleDesc.Count = 1u; // Anti-aliasing | ||
| scd.SampleDesc.Quality = 0u; // Anti-aliasing | ||
| scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; | ||
| scd.BufferCount = 1u; // 1 back buffer and 1 front buffer | ||
| scd.OutputWindow = hwnd; | ||
| scd.Windowed = true; | ||
| scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; | ||
| scd.Flags = 0u; | ||
|
OlleKReutercrona marked this conversation as resolved.
|
||
|
|
||
| UINT swapCreateFlags = 0u; | ||
| #ifndef NDEBUG | ||
| swapCreateFlags |= D3D11_CREATE_DEVICE_DEBUG; | ||
| #endif | ||
|
|
||
| D3D11CreateDeviceAndSwapChain( | ||
| nullptr, | ||
| D3D_DRIVER_TYPE_HARDWARE, | ||
| nullptr, | ||
| swapCreateFlags, | ||
| nullptr, | ||
| 0, | ||
| D3D11_SDK_VERSION, | ||
| &scd, | ||
| &pSwap, | ||
| &pDevice, | ||
| nullptr, | ||
| &pContext | ||
| ); | ||
|
||
| } | ||
|
|
||
| void RF::DX11::CreateRenderTargetView() { | ||
| // Gain access to texture subresource in swap chains (back buffer) | ||
| Microsoft::WRL::ComPtr<ID3D11Resource> pBackBuffer; | ||
| pSwap->GetBuffer(0u, __uuidof(ID3D11Resource), &pBackBuffer); | ||
| pDevice->CreateRenderTargetView(pBackBuffer.Get(), nullptr, &pDefaultTarget); | ||
|
||
| } | ||
|
|
||
| void RF::DX11::CreateViewport(const uint32_t width, const uint32_t height) { | ||
| D3D11_VIEWPORT vp = {}; | ||
| vp.Width = static_cast<FLOAT>(width); | ||
| vp.Height = static_cast<FLOAT>(height); | ||
| vp.MinDepth = 0.0f; | ||
| vp.MaxDepth = 1.0f; | ||
| vp.TopLeftX = 0.0f; | ||
| vp.TopLeftY = 0.0f; | ||
| pContext->RSSetViewports(1u, &vp); | ||
| } | ||
|
|
||
| void RF::DX11::Render(const FrameData& frameData) { | ||
| frameData; | ||
|
|
||
| if (!mInitialized) { | ||
| throw std::runtime_error("Renderer not initialized"); | ||
| } | ||
|
|
||
| // Clear the back buffer to a color (RGBA) | ||
| const FLOAT clearColor[] = { 0.2f, 0.4f, 0.6f, 1.0f }; | ||
|
OlleKReutercrona marked this conversation as resolved.
|
||
| pContext->ClearRenderTargetView(pDefaultTarget.Get(), clearColor); | ||
| // Present the back buffer to the screen | ||
| pSwap->Present(1u, 0u); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| #pragma once | ||
| #include <wrl.h> | ||
| #include <d3d11.h> | ||
| #include <dxgi1_6.h> | ||
| #include "IRenderer.h" | ||
|
|
||
| namespace RF { | ||
| class DX11 : public IRenderer { | ||
| public: | ||
| DX11() = default; | ||
| ~DX11(); | ||
|
|
||
| virtual void Init(const HWND hwnd, const uint32_t width, const uint32_t height); | ||
| virtual void Render(const FrameData& frameData); | ||
| private: | ||
| void CreateDeviceAndSwapChain(const HWND hwnd, const uint32_t width, const uint32_t height); | ||
| void CreateRenderTargetView(); | ||
| void CreateViewport(const uint32_t width, const uint32_t height); | ||
|
|
||
| bool mInitialized = false; | ||
|
|
||
| uint32_t mWidth; | ||
| uint32_t mHeight; | ||
|
|
||
| Microsoft::WRL::ComPtr<ID3D11Device> pDevice; | ||
| Microsoft::WRL::ComPtr<IDXGISwapChain> pSwap; | ||
| Microsoft::WRL::ComPtr<ID3D11DeviceContext> pContext; | ||
| Microsoft::WRL::ComPtr<ID3D11RenderTargetView> pDefaultTarget; | ||
| }; | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,200 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "stdafx.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "DX12.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "d3dx12.h" // helper classes for barriers, handles, etc. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <stdexcept> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| using namespace Microsoft::WRL; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| RF::DX12::~DX12() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Ensure GPU is finished before destroying resources | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| mFenceValue++; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| HRESULT hr = mCommandQueue->Signal(mFence.Get(), mFenceValue); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (mFence->GetCompletedValue() < mFenceValue) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| hr = mFence->SetEventOnCompletion(mFenceValue, mFenceEvent); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| WaitForSingleObject(mFenceEvent, INFINITE); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CloseHandle(mFenceEvent); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Ensure GPU is finished before destroying resources | |
| mFenceValue++; | |
| HRESULT hr = mCommandQueue->Signal(mFence.Get(), mFenceValue); | |
| if (mFence->GetCompletedValue() < mFenceValue) { | |
| hr = mFence->SetEventOnCompletion(mFenceValue, mFenceEvent); | |
| WaitForSingleObject(mFenceEvent, INFINITE); | |
| } | |
| CloseHandle(mFenceEvent); | |
| // Only perform GPU synchronization/handle cleanup if initialization completed | |
| // and the corresponding resources were actually created. | |
| if (!mInitialized) | |
| return; | |
| if (mCommandQueue && mFence) { | |
| // Ensure GPU is finished before destroying resources | |
| mFenceValue++; | |
| HRESULT hr = mCommandQueue->Signal(mFence.Get(), mFenceValue); | |
| if (SUCCEEDED(hr) && mFence->GetCompletedValue() < mFenceValue && mFenceEvent) { | |
| hr = mFence->SetEventOnCompletion(mFenceValue, mFenceEvent); | |
| if (SUCCEEDED(hr)) | |
| WaitForSingleObject(mFenceEvent, INFINITE); | |
| } | |
| } | |
| if (mFenceEvent) | |
| CloseHandle(mFenceEvent); |
Copilot
AI
May 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HRESULTs returned from Reset/Close/Present/Signal/SetEventOnCompletion are assigned to hr but never validated. When these fail (e.g., device removed, invalid state, allocator still in use), the renderer will continue issuing commands with undefined behavior. Check each HRESULT and fail fast (throw/log/return) so errors are surfaced and you don't proceed with an invalid command list or swap chain state.
Copilot
AI
May 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CreateSwapChain creates a new DXGI factory via CreateDXGIFactory1 even though Init already created a factory with debug flags. This duplicates work and (in _DEBUG) can drop DXGI debug factory behavior. Consider passing the factory created in Init into CreateSwapChain or storing it as a member and reusing it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Det här borde vara en preprocessor check i och med att vi aldrig kommer byta api i runtime