diff --git a/Juliet/Juliet.vcxproj b/Juliet/Juliet.vcxproj
index 58320fa..7a94569 100644
--- a/Juliet/Juliet.vcxproj
+++ b/Juliet/Juliet.vcxproj
@@ -302,6 +302,7 @@
+
diff --git a/Juliet/include/Graphics/Graphics.h b/Juliet/include/Graphics/Graphics.h
index 8389115..e13bc56 100644
--- a/Juliet/include/Graphics/Graphics.h
+++ b/Juliet/include/Graphics/Graphics.h
@@ -2,6 +2,7 @@
#include
#include
+#include
#include
// Graphics Interface
@@ -74,6 +75,10 @@ namespace Juliet
extern JULIET_API bool AttachToWindow(NonNullPtr device, NonNullPtr window);
extern JULIET_API void DetachFromWindow(NonNullPtr device, NonNullPtr window);
+ // SwapChain
+ extern JULIET_API bool AcquireSwapChainTexture(NonNullPtr commandList, NonNullPtr window,
+ Texture** swapChainTexture);
+
// Command List
extern JULIET_API CommandList* AcquireCommandList(NonNullPtr device, QueueType queueType = QueueType::Graphics);
extern JULIET_API void SubmitCommandLists(NonNullPtr device);
diff --git a/Juliet/include/Graphics/Texture.h b/Juliet/include/Graphics/Texture.h
index 1e724e5..628e8ae 100644
--- a/Juliet/include/Graphics/Texture.h
+++ b/Juliet/include/Graphics/Texture.h
@@ -1,5 +1,4 @@
#pragma once
-#include
namespace Juliet
{
@@ -177,4 +176,5 @@ namespace Juliet
uint32 MipLevelCount;
};
+ struct Texture;
} // namespace Juliet
diff --git a/Juliet/src/Graphics/D3D12/DX12CommandList.cpp b/Juliet/src/Graphics/D3D12/DX12CommandList.cpp
index 4d117cf..1c725c8 100644
--- a/Juliet/src/Graphics/D3D12/DX12CommandList.cpp
+++ b/Juliet/src/Graphics/D3D12/DX12CommandList.cpp
@@ -87,13 +87,26 @@ namespace Juliet::D3D12
driver->AvailableCommandLists = resizedArray;
driver->AvailableCommandLists[driver->AvailableCommandListCapacity] = commandList;
- commandList->ID = driver->AvailableCommandListCapacity;
+
+ commandList->ID = driver->AvailableCommandListCapacity;
+ commandList->Driver = driver;
+
+ commandList->PresentDataCapacity = 1;
+ commandList->PresentDataCount = 0;
+ commandList->PresentDatas =
+ static_cast(Calloc(commandList->PresentDataCapacity, sizeof(D3D12PresentData)));
+
driver->AvailableCommandListCapacity += 1;
return true;
}
} // namespace
+ ID3D12GraphicsCommandList6* GetGraphicsCommandList(NonNullPtr commandList)
+ {
+ return reinterpret_cast(commandList->CommandLists[ToUnderlying(QueueType::Graphics)]);
+ }
+
CommandList* AcquireCommandList(NonNullPtr driver, QueueType queueType)
{
auto* d3d12Driver = static_cast(driver.Get());
diff --git a/Juliet/src/Graphics/D3D12/DX12CommandList.h b/Juliet/src/Graphics/D3D12/DX12CommandList.h
index fb13f31..f794c00 100644
--- a/Juliet/src/Graphics/D3D12/DX12CommandList.h
+++ b/Juliet/src/Graphics/D3D12/DX12CommandList.h
@@ -8,18 +8,32 @@
namespace Juliet::D3D12
{
struct D3D12Driver;
+ struct D3D12WindowData;
+
+ struct D3D12PresentData
+ {
+ D3D12WindowData* WindowData;
+ uint32 SwapChainImageIndex;
+ };
struct D3D12CommandList
{
- D3D12Driver* Driver;
-
uint64 ID;
+ CommandListHeader Common;
+ D3D12Driver* Driver;
+
+ D3D12PresentData* PresentDatas;
+ uint32 PresentDataCapacity;
+ uint32 PresentDataCount;
+
// We create kResourceBufferCount allocator per queue to allow reusing the command list every N frames
ID3D12CommandAllocator* CommandAllocator[GPUDriver::kResourceBufferCount][ToUnderlying(QueueType::Count)];
ID3D12CommandList* CommandLists[ToUnderlying(QueueType::Count)];
};
+ ID3D12GraphicsCommandList6* GetGraphicsCommandList(NonNullPtr commandList);
+
extern CommandList* AcquireCommandList(NonNullPtr driver, QueueType queueType);
extern bool SubmitCommandLists(NonNullPtr driver);
} // namespace Juliet::D3D12
diff --git a/Juliet/src/Graphics/D3D12/DX12GraphicsDevice.cpp b/Juliet/src/Graphics/D3D12/DX12GraphicsDevice.cpp
index 9172af6..63bdcf0 100644
--- a/Juliet/src/Graphics/D3D12/DX12GraphicsDevice.cpp
+++ b/Juliet/src/Graphics/D3D12/DX12GraphicsDevice.cpp
@@ -544,6 +544,8 @@ namespace Juliet::D3D12
device->AttachToWindow = AttachToWindow;
device->DetachFromWindow = DetachFromWindow;
+ device->AcquireSwapChainTexture = AcquireSwapChainTexture;
+
device->AcquireCommandList = AcquireCommandList;
device->SubmitCommandLists = SubmitCommandLists;
diff --git a/Juliet/src/Graphics/D3D12/DX12SwapChain.cpp b/Juliet/src/Graphics/D3D12/DX12SwapChain.cpp
index 3898a97..255f604 100644
--- a/Juliet/src/Graphics/D3D12/DX12SwapChain.cpp
+++ b/Juliet/src/Graphics/D3D12/DX12SwapChain.cpp
@@ -9,6 +9,7 @@
#include
#include
+#include
namespace Juliet::D3D12
{
namespace
@@ -131,6 +132,59 @@ namespace Juliet::D3D12
return true;
}
+
+ bool AcquireSwapChainTexture(bool block, NonNullPtr commandList, NonNullPtr window, Texture** swapchainTexture)
+ {
+ auto d3d12CommandList = reinterpret_cast(commandList.Get());
+
+ auto* driver = d3d12CommandList->Driver;
+ Assert(driver->WindowData);
+
+ // TODO: Find a way to fetch window data more smoothly from the window ptr
+ auto* windowData = driver->WindowData;
+ Assert(windowData->Window == window.Get());
+
+ // TODO : FENCES
+ Assert(!block);
+
+ uint32 swapchainIndex = IDXGISwapChain3_GetCurrentBackBufferIndex(windowData->SwapChain);
+ HRESULT result =
+ IDXGISwapChain_GetBuffer(windowData->SwapChain, swapchainIndex, IID_ID3D12Resource,
+ reinterpret_cast(
+ &windowData->SwapChainTextureContainers[swapchainIndex].ActiveTexture->Resource));
+ if (FAILED(result))
+ {
+ LogError(driver, "Could not acquire swapchain", result);
+ return false;
+ }
+
+ // When the swap chain texture is acquired its time to present
+ if (d3d12CommandList->PresentDataCount == d3d12CommandList->PresentDataCapacity)
+ {
+ d3d12CommandList->PresentDataCapacity += 1;
+ d3d12CommandList->PresentDatas =
+ static_cast(Realloc(d3d12CommandList->PresentDatas,
+ d3d12CommandList->PresentDataCapacity * sizeof(D3D12PresentData)));
+ }
+ d3d12CommandList->PresentDatas[d3d12CommandList->PresentDataCount].WindowData = windowData;
+ d3d12CommandList->PresentDatas[d3d12CommandList->PresentDataCount].SwapChainImageIndex = swapchainIndex;
+ d3d12CommandList->PresentDataCount += 1;
+
+ // Create the presentation barrier.
+ D3D12_RESOURCE_BARRIER barrierDesc;
+ barrierDesc.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
+ barrierDesc.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
+ barrierDesc.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
+ barrierDesc.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
+ barrierDesc.Transition.pResource = windowData->SwapChainTextureContainers[swapchainIndex].ActiveTexture->Resource;
+ barrierDesc.Transition.Subresource = 0;
+
+ ID3D12GraphicsCommandList_ResourceBarrier(GetGraphicsCommandList(d3d12CommandList), 1, &barrierDesc);
+
+ *swapchainTexture = reinterpret_cast(&windowData->SwapChainTextureContainers[swapchainIndex]);
+
+ return true;
+ }
} // namespace
bool CreateSwapChain(NonNullPtr driver, NonNullPtr windowData,
@@ -244,6 +298,11 @@ namespace Juliet::D3D12
return true;
}
+ bool AcquireSwapChainTexture(NonNullPtr commandList, NonNullPtr window, Texture** swapChainTexture)
+ {
+ return AcquireSwapChainTexture(false, commandList, window, swapChainTexture);
+ }
+
void DestroySwapChain(NonNullPtr driver, NonNullPtr windowData)
{
for (uint32 idx = 0; idx < windowData->SwapChainTextureCount; ++idx)
diff --git a/Juliet/src/Graphics/D3D12/DX12SwapChain.h b/Juliet/src/Graphics/D3D12/DX12SwapChain.h
index 478ead4..de08684 100644
--- a/Juliet/src/Graphics/D3D12/DX12SwapChain.h
+++ b/Juliet/src/Graphics/D3D12/DX12SwapChain.h
@@ -8,5 +8,6 @@ namespace Juliet::D3D12
extern bool CreateSwapChain(NonNullPtr driver, NonNullPtr windowData,
SwapChainComposition composition, PresentMode presentMode);
+ extern bool AcquireSwapChainTexture(NonNullPtr commandList, NonNullPtr window, Texture** swapChainTexture);
extern void DestroySwapChain(NonNullPtr driver, NonNullPtr windowData);
} // namespace Juliet::D3D12
diff --git a/Juliet/src/Graphics/Graphics.cpp b/Juliet/src/Graphics/Graphics.cpp
index 91b083e..ee8bcbc 100644
--- a/Juliet/src/Graphics/Graphics.cpp
+++ b/Juliet/src/Graphics/Graphics.cpp
@@ -1,3 +1,4 @@
+#include
#include
#include
@@ -75,11 +76,32 @@ namespace Juliet
device->DetachFromWindow(driver, window);
}
+ bool AcquireSwapChainTexture(NonNullPtr commandList, NonNullPtr window, Texture** swapChainTexture)
+ {
+ auto header = reinterpret_cast(commandList.Get());
+
+ header->Device->AcquireSwapChainTexture(commandList, window, swapChainTexture);
+ if (swapChainTexture)
+ {
+ header->AcquiredSwapChain = true;
+ }
+
+ return true;
+ }
+
CommandList* AcquireCommandList(NonNullPtr device, QueueType queueType /* = QueueType::Graphics */)
{
GPUDriver* driver = device->Driver;
CommandList* cmdList = device->AcquireCommandList(driver, queueType);
+ if (!cmdList)
+ {
+ return nullptr;
+ }
+
+ auto header = reinterpret_cast(cmdList);
+ header->Device = device.Get();
+
driver->CommandListCount += 1;
return cmdList;
diff --git a/Juliet/src/Graphics/GraphicsDevice.h b/Juliet/src/Graphics/GraphicsDevice.h
index 7339b2b..ab04c05 100644
--- a/Juliet/src/Graphics/GraphicsDevice.h
+++ b/Juliet/src/Graphics/GraphicsDevice.h
@@ -14,6 +14,12 @@ namespace Juliet
TextureCreateInfo CreateInfo;
};
+ struct CommandListHeader
+ {
+ GraphicsDevice* Device = nullptr;
+ bool AcquiredSwapChain = false;
+ };
+
struct GPUDriver
{
uint8 CommandListCount;
@@ -30,6 +36,9 @@ namespace Juliet
bool (*AttachToWindow)(NonNullPtr driver, NonNullPtr window);
void (*DetachFromWindow)(NonNullPtr driver, NonNullPtr window);
+ // SwapChain
+ bool (*AcquireSwapChainTexture)(NonNullPtr commandList, NonNullPtr window, Texture** swapChainTexture);
+
// CommandLists
CommandList* (*AcquireCommandList)(NonNullPtr driver, QueueType queueType);
bool (*SubmitCommandLists)(NonNullPtr driver);
diff --git a/Juliet/src/TODO.txt b/Juliet/src/TODO.txt
new file mode 100644
index 0000000..f585166
--- /dev/null
+++ b/Juliet/src/TODO.txt
@@ -0,0 +1 @@
+- Create Simple vector class to make the vector stuff a bit more easier than writing Capacity and Count
\ No newline at end of file
diff --git a/JulietApp/Editor/EditorMain_win32.cpp b/JulietApp/Editor/EditorMain_win32.cpp
index f31cb36..e332fd5 100644
--- a/JulietApp/Editor/EditorMain_win32.cpp
+++ b/JulietApp/Editor/EditorMain_win32.cpp
@@ -82,6 +82,20 @@ void Win32EditorApplication::Update()
// Draw here for now
// 1) Acquire a Command Buffer
CommandList* cmdList = AcquireCommandList(GraphicsDevice, QueueType::Graphics);
+ if (cmdList == nullptr)
+ {
+ Log(LogLevel::Error, LogCategory::Editor, "Failed to acquire command list.");
+ Running = false;
+ return;
+ }
+
+ Texture* swapChainTexture = nullptr;
+ if (!AcquireSwapChainTexture(cmdList, MainWindow, &swapChainTexture))
+ {
+ Log(LogLevel::Error, LogCategory::Editor, "Failed to acquire swapchain texture.");
+ Running = false;
+ return;
+ }
// Submit Commands
SubmitCommandLists(GraphicsDevice);