Added first pass on swap chain. Still needs Render Target View and various stuff.
+ Reformat all files
This commit is contained in:
@@ -30,8 +30,7 @@ namespace Game
|
||||
};
|
||||
|
||||
template <typename EntityType>
|
||||
concept EntityConcept = requires(EntityType entity)
|
||||
{
|
||||
concept EntityConcept = requires(EntityType entity) {
|
||||
requires std::same_as<decltype(entity.Kind), const Juliet::Class*>;
|
||||
requires std::same_as<decltype(entity.Base), Entity*>;
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Game
|
||||
// May be this should contains the allocator for each entity types
|
||||
};
|
||||
|
||||
void InitEntityManager();\
|
||||
void InitEntityManager();
|
||||
EntityManager& GetEntityManager();
|
||||
void RegisterEntity(EntityManager& manager, Entity* entity);
|
||||
}
|
||||
} // namespace Game
|
||||
|
||||
@@ -140,7 +140,6 @@
|
||||
<ClInclude Include="include\pch.h"/>
|
||||
<ClInclude Include="src\Core\HAL\Display\DisplayDevice.h"/>
|
||||
<ClInclude Include="src\Core\HAL\Display\Display_Private.h"/>
|
||||
<ClInclude Include="src\Core\HAL\Display\Win32\Win32DisplayDevice.h" />
|
||||
<ClInclude Include="src\Core\HAL\Display\Win32\Win32DisplayEvent.h"/>
|
||||
<ClInclude Include="src\Core\HAL\Display\Win32\Win32Window.h"/>
|
||||
<ClInclude Include="src\Core\HAL\Display\Window.h"/>
|
||||
@@ -154,6 +153,7 @@
|
||||
<ClInclude Include="src\Graphics\D3D12\DX12CommandList.h"/>
|
||||
<ClInclude Include="src\Graphics\D3D12\DX12GraphicsDevice.h"/>
|
||||
<ClInclude Include="src\Graphics\D3D12\DX12Includes.h"/>
|
||||
<ClInclude Include="src\Graphics\D3D12\DX12SwapChain.h"/>
|
||||
<ClInclude Include="src\Graphics\D3D12\DX12Utils.h"/>
|
||||
<ClInclude Include="src\Graphics\GraphicsDevice.h"/>
|
||||
</ItemGroup>
|
||||
@@ -234,6 +234,8 @@
|
||||
<ClCompile Include="src\Engine\Engine.cpp"/>
|
||||
<ClCompile Include="src\Graphics\D3D12\DX12CommandList.cpp"/>
|
||||
<ClCompile Include="src\Graphics\D3D12\DX12GraphicsDevice.cpp"/>
|
||||
<ClCompile Include="src\Graphics\D3D12\DX12SwapChain.cpp"/>
|
||||
<ClCompile Include="src\Graphics\D3D12\DX12Utils.cpp" />
|
||||
<ClCompile Include="src\Graphics\Graphics.cpp">
|
||||
<RuntimeLibrary>MultiThreadedDebugDll</RuntimeLibrary>
|
||||
<Optimization>Disabled</Optimization>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Juliet.h>
|
||||
#include <Core/Common/CoreTypes.h>
|
||||
#include <Juliet.h>
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
namespace Juliet
|
||||
{
|
||||
// TODO : Create my own Vector class based on https://github.com/niklas-ourmachinery/bitsquid-foundation/blob/master/collection_types.h
|
||||
template <typename T> class Vector : public std::vector<T>
|
||||
template <typename T>
|
||||
class Vector : public std::vector<T>
|
||||
{
|
||||
};
|
||||
} // namespace Juliet
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <Juliet.h>
|
||||
#include <Core/Common/CoreTypes.h>
|
||||
#include <core/Common/NonNullPtr.h>
|
||||
#include <Juliet.h>
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
// Graphics Interface
|
||||
namespace Juliet
|
||||
{
|
||||
struct Window;
|
||||
struct GraphicsDevice;
|
||||
|
||||
// Parameters of an indirect draw command
|
||||
@@ -45,11 +46,16 @@ namespace Juliet
|
||||
};
|
||||
|
||||
// Opaque types
|
||||
struct CommandList {};
|
||||
struct CommandList;
|
||||
|
||||
extern JULIET_API GraphicsDevice* CreateGraphicsDevice(GraphicsConfig config);
|
||||
extern JULIET_API void DestroyGraphicsDevice(NonNullPtr<GraphicsDevice> device);
|
||||
|
||||
// Attach To Window
|
||||
extern JULIET_API bool AttachToWindow(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
|
||||
extern JULIET_API void DetachFromWindow(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
|
||||
|
||||
// Command List
|
||||
extern JULIET_API CommandList* AcquireCommandList(NonNullPtr<GraphicsDevice> device, QueueType queueType = QueueType::Graphics);
|
||||
extern JULIET_API void SubmitCommandLists(NonNullPtr<GraphicsDevice> device);
|
||||
} // namespace Juliet
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
#ifndef PCH_H
|
||||
#define PCH_H
|
||||
|
||||
#include <Juliet.h>
|
||||
#include <Core/Common/CoreTypes.h>
|
||||
#include <Core/Common/CoreUtils.h>
|
||||
#include <Core/Logging/LogManager.h>
|
||||
#include <Core/Logging/LogTypes.h>
|
||||
#include <Juliet.h>
|
||||
|
||||
#endif // PCH_H
|
||||
|
||||
@@ -7,4 +7,4 @@ namespace Juliet
|
||||
Juliet::Log(Juliet::LogLevel::Error, Juliet::LogCategory::Core, expression);
|
||||
__debugbreak();
|
||||
}
|
||||
}
|
||||
} // namespace Juliet
|
||||
|
||||
@@ -21,8 +21,7 @@ namespace Juliet
|
||||
Assert(!CurrentDisplayDevice);
|
||||
|
||||
DisplayDevice* candidateDevice = nullptr;
|
||||
DisplayDeviceFactory*
|
||||
candidateFactory = nullptr;
|
||||
DisplayDeviceFactory* candidateFactory = nullptr;
|
||||
for (DisplayDeviceFactory* factory : Factories)
|
||||
{
|
||||
if (factory)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <pch.h>
|
||||
|
||||
#include <Core/HAL/Display/DisplayDevice.h>
|
||||
#include <Core/HAL/Display/Win32/Win32DisplayDevice.h>
|
||||
#include <Core/HAL/Display/Win32/Win32DisplayEvent.h>
|
||||
#include <Core/HAL/Display/Win32/Win32Window.h>
|
||||
#include <Core/Memory/Allocator.h>
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace Juliet::Win32
|
||||
{
|
||||
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <Core/HAL/Display/Win32/Win32DisplayEvent.h>
|
||||
#include <Core/HAL/Display/Win32/Win32Window.h>
|
||||
#include <Core/HAL/Display/Window.h>
|
||||
#include <Core/HAL/Win32.h>
|
||||
#include <Core/Memory/Allocator.h>
|
||||
|
||||
namespace Juliet::Win32
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <Core/Common/NonNullPtr.h>
|
||||
#include <Core/HAL/Display/Window.h>
|
||||
#include <Core/HAL/Win32.h>
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
|
||||
@@ -7,7 +7,11 @@
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
Socket::Socket(Protocol protocol) : Handle(SocketImpl::GetInvalidSocketHandle()), ProtocolType(protocol) {}
|
||||
Socket::Socket(Protocol protocol)
|
||||
: Handle(SocketImpl::GetInvalidSocketHandle())
|
||||
, ProtocolType(protocol)
|
||||
{
|
||||
}
|
||||
|
||||
Socket::~Socket()
|
||||
{
|
||||
|
||||
@@ -7,7 +7,10 @@
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
TcpListener::TcpListener() : Socket(Protocol::TCP) {}
|
||||
TcpListener::TcpListener()
|
||||
: Socket(Protocol::TCP)
|
||||
{
|
||||
}
|
||||
|
||||
Socket::Status TcpListener::Listen(uint16 port, uint32 address)
|
||||
{
|
||||
|
||||
@@ -8,7 +8,10 @@
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
TcpSocket::TcpSocket() : Socket(Protocol::TCP) {}
|
||||
TcpSocket::TcpSocket()
|
||||
: Socket(Protocol::TCP)
|
||||
{
|
||||
}
|
||||
|
||||
Socket::RequestStatus TcpSocket::Send(NetworkPacket& packet)
|
||||
{
|
||||
|
||||
@@ -54,8 +54,7 @@ Socket::Status GetErrorStatus()
|
||||
case WSAETIMEDOUT: return Socket::Status::Disconnected;
|
||||
case WSAENETRESET: return Socket::Status::Disconnected;
|
||||
case WSAENOTCONN: return Socket::Status::Disconnected;
|
||||
case WSAEISCONN:
|
||||
return Socket::Status::Done; // when connecting a non-blocking socket
|
||||
case WSAEISCONN: return Socket::Status::Done; // when connecting a non-blocking socket
|
||||
default: return Socket::Status::Error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,10 +120,21 @@ namespace Juliet::D3D12
|
||||
return reinterpret_cast<CommandList*>(commandList);
|
||||
}
|
||||
|
||||
void SubmitCommandLists(NonNullPtr<GPUDriver> driver)
|
||||
bool SubmitCommandLists(NonNullPtr<GPUDriver> driver)
|
||||
{
|
||||
auto* d3d12Driver = static_cast<D3D12Driver*>(driver.Get());
|
||||
bool success = true;
|
||||
|
||||
uint8 commandLastIndex = d3d12Driver->CommandListCount;
|
||||
|
||||
// TODO : Get window data from the command list: We associate the swapchain texture to a window with a missing function
|
||||
HRESULT result = IDXGISwapChain_Present(d3d12Driver->WindowData->SwapChain, 0, 1);
|
||||
if (FAILED(result))
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
} // namespace Juliet::D3D12
|
||||
|
||||
@@ -21,5 +21,5 @@ namespace Juliet::D3D12
|
||||
};
|
||||
|
||||
extern CommandList* AcquireCommandList(NonNullPtr<GPUDriver> driver, QueueType queueType);
|
||||
extern void SubmitCommandLists(NonNullPtr<GPUDriver> driver);
|
||||
extern bool SubmitCommandLists(NonNullPtr<GPUDriver> driver);
|
||||
} // namespace Juliet::D3D12
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <Graphics/D3D12/DX12CommandList.h>
|
||||
#include <Graphics/D3D12/DX12GraphicsDevice.h>
|
||||
#include <Graphics/D3D12/DX12Includes.h>
|
||||
#include <Graphics/D3D12/DX12SwapChain.h>
|
||||
#include <Graphics/Graphics.h>
|
||||
#include <Graphics/GraphicsDevice.h>
|
||||
|
||||
@@ -219,6 +220,53 @@ namespace Juliet::D3D12
|
||||
Free(driver.Get());
|
||||
}
|
||||
|
||||
bool AttachToWindow(NonNullPtr<GPUDriver> driver, NonNullPtr<Window> window)
|
||||
{
|
||||
auto* d3d12Driver = static_cast<D3D12Driver*>(driver.Get());
|
||||
|
||||
// TODO : Support more than one window
|
||||
if (d3d12Driver->WindowData)
|
||||
{
|
||||
Assert(false && "D3D12 renderer already attached to the window. Right now we handle only one Window.");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* windowData = static_cast<D3D12WindowData*>(Calloc(1, sizeof(D3D12WindowData)));
|
||||
if (!windowData)
|
||||
{
|
||||
Log(LogLevel::Error, LogCategory::Graphics, "OOM: D3D12WindowData");
|
||||
return false;
|
||||
}
|
||||
|
||||
windowData->Window = window;
|
||||
|
||||
if (!CreateSwapChain(d3d12Driver, windowData))
|
||||
{
|
||||
Log(LogLevel::Error, LogCategory::Graphics, "AttachToWindow failure: Cannot create Swap Chain.");
|
||||
Free(windowData);
|
||||
return false;
|
||||
}
|
||||
|
||||
d3d12Driver->WindowData = windowData;
|
||||
// TODO : React to resize. Need event system.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DetachFromWindow(NonNullPtr<GPUDriver> driver, NonNullPtr<Window> window)
|
||||
{
|
||||
auto* d3d12Driver = static_cast<D3D12Driver*>(driver.Get());
|
||||
|
||||
Assert(d3d12Driver->WindowData && "Trying to destroy a swapchain but no Window Data exists");
|
||||
|
||||
// TODO : Wait for any remaining work and release the fences.
|
||||
|
||||
DestroySwapChain(d3d12Driver, d3d12Driver->WindowData);
|
||||
|
||||
Free(d3d12Driver->WindowData);
|
||||
d3d12Driver->WindowData = nullptr;
|
||||
}
|
||||
|
||||
void DestroyGraphicsDevice(NonNullPtr<GraphicsDevice> device)
|
||||
{
|
||||
// Note: Its a down cast so clang suggest not to do it but we are totally sure about it.
|
||||
@@ -469,12 +517,18 @@ namespace Juliet::D3D12
|
||||
|
||||
// Assign Functions to the device
|
||||
device->DestroyDevice = DestroyGraphicsDevice;
|
||||
|
||||
device->AttachToWindow = AttachToWindow;
|
||||
device->DetachFromWindow = DetachFromWindow;
|
||||
|
||||
device->AcquireCommandList = AcquireCommandList;
|
||||
device->SubmitCommandLists = SubmitCommandLists;
|
||||
|
||||
device->Driver = driver;
|
||||
driver->GraphicsDevice = device;
|
||||
|
||||
driver->FramesInFlight = 2;
|
||||
|
||||
return device;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <DX12Utils.h>
|
||||
#include <Core/Common/EnumUtils.h>
|
||||
#include <Graphics/D3D12/DX12Utils.h>
|
||||
#include <Graphics/GraphicsDevice.h>
|
||||
|
||||
namespace Juliet
|
||||
@@ -10,6 +11,18 @@ namespace Juliet
|
||||
|
||||
namespace Juliet::D3D12
|
||||
{
|
||||
struct D3D12CommandList;
|
||||
|
||||
struct D3D12WindowData
|
||||
{
|
||||
Window* Window;
|
||||
|
||||
IDXGISwapChain3* SwapChain;
|
||||
uint8 SwapChainTextureCount;
|
||||
|
||||
uint32 FrameCounter;
|
||||
};
|
||||
|
||||
struct D3D12Driver : GPUDriver
|
||||
{
|
||||
GraphicsDevice* GraphicsDevice;
|
||||
@@ -35,16 +48,19 @@ namespace Juliet::D3D12
|
||||
IDXGIInfoQueue* DXGIInfoQueue;
|
||||
#endif
|
||||
|
||||
// Windows
|
||||
// TODO: Support more than one window
|
||||
D3D12WindowData* WindowData;
|
||||
|
||||
// Resources
|
||||
D3D12CommandList** AvailableCommandLists;
|
||||
uint8 AvailableCommandListCapacity;
|
||||
|
||||
bool IsTearingSupported : 1;
|
||||
uint8 FramesInFlight;
|
||||
|
||||
// UMA
|
||||
bool IsTearingSupported : 1;
|
||||
bool IsUMAAvailable : 1;
|
||||
bool IsUMACacheCoherent : 1;
|
||||
|
||||
bool GPUUploadHeapSupported : 1;
|
||||
};
|
||||
} // namespace Juliet::D3D12
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
#define CINTERFACE ;
|
||||
|
||||
#include <d3dcompiler.h>
|
||||
#include "d3d12.h"
|
||||
#include <DirectXMath.h>
|
||||
#include <dxgi1_5.h>
|
||||
#include <dxgi1_6.h>
|
||||
#include "d3d12.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#include <dxgidebug.h>
|
||||
|
||||
104
Juliet/src/Graphics/D3D12/DX12SwapChain.cpp
Normal file
104
Juliet/src/Graphics/D3D12/DX12SwapChain.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
#include <pch.h>
|
||||
|
||||
#include <Core/HAL/Display/Win32/Win32Window.h>
|
||||
#include <Graphics/D3D12/DX12GraphicsDevice.h>
|
||||
#include <Graphics/D3D12/DX12SwapChain.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace Juliet::D3D12
|
||||
{
|
||||
bool CreateSwapChain(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12WindowData> windowData)
|
||||
{
|
||||
auto windowWin32State = static_cast<Win32::Window32State*>(windowData->Window->State);
|
||||
HWND windowHandle = windowWin32State->Handle;
|
||||
if (!IsWindow(windowHandle))
|
||||
{
|
||||
Assert(false && "windowWin32State->Handle is not a window handle ???");
|
||||
return false;
|
||||
}
|
||||
|
||||
// SDR.
|
||||
// TODO: Not enough for HDR. but i have no way to test HDR easily except the steamdeck
|
||||
DXGI_FORMAT swapChainFormat = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
|
||||
windowData->SwapChainTextureCount = std::clamp<uint8>(driver->FramesInFlight, 2, 3);
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
|
||||
swapChainDesc.Width = 0; // Use the whole width
|
||||
swapChainDesc.Height = 0; // Use the whole height
|
||||
swapChainDesc.Format = swapChainFormat;
|
||||
swapChainDesc.Stereo = 0;
|
||||
swapChainDesc.SampleDesc.Count = 1;
|
||||
swapChainDesc.SampleDesc.Quality = 0;
|
||||
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
swapChainDesc.BufferCount = windowData->SwapChainTextureCount;
|
||||
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
|
||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
|
||||
if (driver->IsTearingSupported)
|
||||
{
|
||||
swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
|
||||
}
|
||||
else
|
||||
{
|
||||
swapChainDesc.Flags = 0;
|
||||
}
|
||||
|
||||
DXGI_SWAP_CHAIN_FULLSCREEN_DESC swapChainFullscreenDesc = {};
|
||||
swapChainFullscreenDesc.RefreshRate.Numerator = 0;
|
||||
swapChainFullscreenDesc.RefreshRate.Denominator = 0;
|
||||
swapChainFullscreenDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
|
||||
swapChainFullscreenDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
||||
swapChainFullscreenDesc.Windowed = true;
|
||||
|
||||
IDXGISwapChain1* swapChain = nullptr;
|
||||
HRESULT result =
|
||||
IDXGIFactory4_CreateSwapChainForHwnd(driver->DXGIFactory, reinterpret_cast<IUnknown*>(driver->GraphicsQueue),
|
||||
windowHandle, &swapChainDesc, &swapChainFullscreenDesc, nullptr, &swapChain);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LogError(driver, "Failed to create SwapChain", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
IDXGISwapChain3* swapChain3 = nullptr;
|
||||
result = IDXGISwapChain1_QueryInterface(swapChain, IID_IDXGISwapChain3, reinterpret_cast<void**>(&swapChain3));
|
||||
IDXGISwapChain1_Release(swapChain);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LogError(driver, "Could not query IDXGISwapChain3 interface", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
IDXGIFactory1* parentFactory = nullptr;
|
||||
result = IDXGISwapChain3_GetParent(swapChain3, IID_IDXGIFactory1, reinterpret_cast<void**>(&parentFactory));
|
||||
if (FAILED(result))
|
||||
{
|
||||
Log(LogLevel::Warning, LogCategory::Graphics, "Cannot get SwapChain Parent! Error Code: " HRESULT_FMT, result);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Disable DXGI window crap
|
||||
result = IDXGIFactory1_MakeWindowAssociation(parentFactory, windowHandle, DXGI_MWA_NO_WINDOW_CHANGES);
|
||||
if (FAILED(result))
|
||||
{
|
||||
Log(LogLevel::Warning, LogCategory::Graphics, "MakeWindowAssociation failed! Error Code: " HRESULT_FMT, result);
|
||||
}
|
||||
IDXGIFactory1_Release(parentFactory);
|
||||
}
|
||||
|
||||
IDXGISwapChain3_GetDesc1(swapChain3, &swapChainDesc);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LogError(driver, "Failed to retrieve SwapChain descriptor", result);
|
||||
return false;
|
||||
}
|
||||
windowData->SwapChain = swapChain3;
|
||||
windowData->FrameCounter = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DestroySwapChain(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12WindowData> windowData) {}
|
||||
} // namespace Juliet::D3D12
|
||||
11
Juliet/src/Graphics/D3D12/DX12SwapChain.h
Normal file
11
Juliet/src/Graphics/D3D12/DX12SwapChain.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include <Core/Common/NonNullPtr.h>
|
||||
|
||||
namespace Juliet::D3D12
|
||||
{
|
||||
struct D3D12Driver;
|
||||
struct D3D12WindowData;
|
||||
|
||||
extern bool CreateSwapChain(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12WindowData> windowData);
|
||||
extern void DestroySwapChain(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12WindowData> windowData);
|
||||
}
|
||||
61
Juliet/src/Graphics/D3D12/DX12Utils.cpp
Normal file
61
Juliet/src/Graphics/D3D12/DX12Utils.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#include <pch.h>
|
||||
|
||||
#include <Core/Common/NonNullPtr.h>
|
||||
#include <DX12GraphicsDevice.h>
|
||||
#include <Graphics/D3D12/DX12Utils.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace Juliet::D3D12
|
||||
{
|
||||
// From SDLGPU
|
||||
// TODO Do my own version.
|
||||
extern void LogError(NonNullPtr<D3D12Driver> driver, const char* errorMessage, HRESULT result)
|
||||
{
|
||||
#define MAX_ERROR_LEN 1024 // FIXME: Arbitrary!
|
||||
|
||||
// Buffer for text, ensure space for \0 terminator after buffer
|
||||
char wszMsgBuff[MAX_ERROR_LEN + 1];
|
||||
DWORD dwChars; // Number of chars returned.
|
||||
|
||||
if (result == DXGI_ERROR_DEVICE_REMOVED)
|
||||
{
|
||||
if (driver->D3D12Device)
|
||||
{
|
||||
result = ID3D12Device_GetDeviceRemovedReason(driver->D3D12Device);
|
||||
}
|
||||
}
|
||||
|
||||
// Try to get the message from the system errors.
|
||||
dwChars = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, result, 0,
|
||||
wszMsgBuff, MAX_ERROR_LEN, NULL);
|
||||
|
||||
// No message? Screw it, just post the code.
|
||||
if (dwChars == 0)
|
||||
{
|
||||
Log(LogLevel::Error, LogCategory::Graphics, "%s! Error: " HRESULT_FMT, errorMessage, result);
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure valid range
|
||||
dwChars = std::min<DWORD>(dwChars, MAX_ERROR_LEN);
|
||||
|
||||
// Trim whitespace from tail of message
|
||||
while (dwChars > 0)
|
||||
{
|
||||
if (wszMsgBuff[dwChars - 1] <= ' ')
|
||||
{
|
||||
dwChars--;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure null-terminated string
|
||||
wszMsgBuff[dwChars] = '\0';
|
||||
|
||||
Log(LogLevel::Error, LogCategory::Graphics, "%s! Error: %s" HRESULT_FMT, errorMessage, wszMsgBuff, result);
|
||||
}
|
||||
} // namespace Juliet::D3D12
|
||||
@@ -2,8 +2,16 @@
|
||||
|
||||
#include <Graphics/D3D12/DX12Includes.h>
|
||||
|
||||
namespace Juliet
|
||||
#ifdef _WIN32
|
||||
#define HRESULT_FMT "(0x%08lX)"
|
||||
#else
|
||||
#define HRESULT_FMT "(0x%08X)"
|
||||
#endif
|
||||
|
||||
namespace Juliet::D3D12
|
||||
{
|
||||
struct D3D12Driver;
|
||||
|
||||
inline void AssertOnFailure(HRESULT hr)
|
||||
{
|
||||
Assert(!!FAILED(hr));
|
||||
@@ -16,4 +24,6 @@ namespace Juliet
|
||||
case E_POINTER: Assert(false && "Invalid Pointer");
|
||||
}
|
||||
}
|
||||
} // namespace Juliet::RHI::DX12
|
||||
|
||||
extern void LogError(NonNullPtr<D3D12Driver> driver, const char* errorMessage, HRESULT result);
|
||||
} // namespace Juliet::D3D12
|
||||
|
||||
@@ -63,6 +63,20 @@ namespace Juliet
|
||||
device->DestroyDevice(device);
|
||||
}
|
||||
|
||||
bool AttachToWindow(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window)
|
||||
{
|
||||
GPUDriver* driver = device->Driver;
|
||||
bool result = device->AttachToWindow(driver, window);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void DetachFromWindow(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window)
|
||||
{
|
||||
GPUDriver* driver = device->Driver;
|
||||
device->DetachFromWindow(driver, window);
|
||||
}
|
||||
|
||||
CommandList* AcquireCommandList(NonNullPtr<GraphicsDevice> device, QueueType queueType /* = QueueType::Graphics */)
|
||||
{
|
||||
GPUDriver* driver = device->Driver;
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
struct Window;
|
||||
|
||||
struct GPUDriver
|
||||
{
|
||||
uint8 CommandListCount;
|
||||
@@ -16,8 +18,14 @@ namespace Juliet
|
||||
struct GraphicsDevice
|
||||
{
|
||||
void (*DestroyDevice)(NonNullPtr<GraphicsDevice> self);
|
||||
|
||||
// Attach to window
|
||||
bool (*AttachToWindow)(NonNullPtr<GPUDriver> driver, NonNullPtr<Window> window);
|
||||
void (*DetachFromWindow)(NonNullPtr<GPUDriver> driver, NonNullPtr<Window> window);
|
||||
|
||||
// CommandLists
|
||||
CommandList* (*AcquireCommandList)(NonNullPtr<GPUDriver> driver, QueueType queueType);
|
||||
void (*SubmitCommandLists)(NonNullPtr<GPUDriver> driver);
|
||||
bool (*SubmitCommandLists)(NonNullPtr<GPUDriver> driver);
|
||||
|
||||
const char* Name = "Unknown";
|
||||
GPUDriver* Driver = nullptr;
|
||||
|
||||
@@ -31,18 +31,28 @@ void Win32EditorApplication::Init()
|
||||
|
||||
MainWindow = CreatePlatformWindow("Juliet Editor", 1280, 720);
|
||||
|
||||
// TODO : Assign the graphics device to the main window (and detach)
|
||||
|
||||
Running = MainWindow != nullptr && GraphicsDevice != nullptr;
|
||||
|
||||
DynamicLibrary = LoadDynamicLibrary("Game.dll");
|
||||
if (Running)
|
||||
{
|
||||
AttachToWindow(GraphicsDevice, MainWindow);
|
||||
Game = LoadDynamicLibrary("Game.dll");
|
||||
}
|
||||
}
|
||||
|
||||
void Win32EditorApplication::Shutdown()
|
||||
{
|
||||
Log(LogLevel::Message, LogCategory::Editor, "Shutdown Editor Application...");
|
||||
|
||||
UnloadDynamicLibrary(DynamicLibrary);
|
||||
if (Game)
|
||||
{
|
||||
UnloadDynamicLibrary(Game);
|
||||
}
|
||||
|
||||
if (MainWindow && GraphicsDevice)
|
||||
{
|
||||
DetachFromWindow(GraphicsDevice, MainWindow);
|
||||
}
|
||||
|
||||
if (MainWindow)
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Juliet
|
||||
{
|
||||
struct GraphicsDevice;
|
||||
struct Window;
|
||||
}
|
||||
} // namespace Juliet
|
||||
|
||||
class Win32EditorApplication : public Juliet::IApplication
|
||||
{
|
||||
@@ -21,7 +21,7 @@ class Win32EditorApplication : public Juliet::IApplication
|
||||
private:
|
||||
Juliet::Window* MainWindow = {};
|
||||
Juliet::GraphicsDevice* GraphicsDevice = {};
|
||||
Juliet::DynamicLibrary* DynamicLibrary = {};
|
||||
Juliet::DynamicLibrary* Game = {};
|
||||
|
||||
bool Running = false;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user