Command to acquire swap chain texture

This commit is contained in:
2025-02-16 11:54:04 -05:00
parent 3e7caa2c7c
commit 7e8aaaa891
12 changed files with 145 additions and 4 deletions

View File

@@ -302,6 +302,7 @@
</ItemGroup>
<ItemGroup>
<Content Include="include\Core\Thread\Mutex.h"/>
<Content Include="src\TODO.txt" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets">

View File

@@ -2,6 +2,7 @@
#include <core/Common/NonNullPtr.h>
#include <Graphics/GraphicsConfig.h>
#include <Graphics/Texture.h>
#include <Juliet.h>
// Graphics Interface
@@ -74,6 +75,10 @@ namespace Juliet
extern JULIET_API bool AttachToWindow(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
extern JULIET_API void DetachFromWindow(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
// SwapChain
extern JULIET_API bool AcquireSwapChainTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Window> window,
Texture** swapChainTexture);
// Command List
extern JULIET_API CommandList* AcquireCommandList(NonNullPtr<GraphicsDevice> device, QueueType queueType = QueueType::Graphics);
extern JULIET_API void SubmitCommandLists(NonNullPtr<GraphicsDevice> device);

View File

@@ -1,5 +1,4 @@
#pragma once
#include <D3D12Common.h>
namespace Juliet
{
@@ -177,4 +176,5 @@ namespace Juliet
uint32 MipLevelCount;
};
struct Texture;
} // namespace Juliet

View File

@@ -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<D3D12PresentData*>(Calloc(commandList->PresentDataCapacity, sizeof(D3D12PresentData)));
driver->AvailableCommandListCapacity += 1;
return true;
}
} // namespace
ID3D12GraphicsCommandList6* GetGraphicsCommandList(NonNullPtr<D3D12CommandList> commandList)
{
return reinterpret_cast<ID3D12GraphicsCommandList6*>(commandList->CommandLists[ToUnderlying(QueueType::Graphics)]);
}
CommandList* AcquireCommandList(NonNullPtr<GPUDriver> driver, QueueType queueType)
{
auto* d3d12Driver = static_cast<D3D12Driver*>(driver.Get());

View File

@@ -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<D3D12CommandList> commandList);
extern CommandList* AcquireCommandList(NonNullPtr<GPUDriver> driver, QueueType queueType);
extern bool SubmitCommandLists(NonNullPtr<GPUDriver> driver);
} // namespace Juliet::D3D12

View File

@@ -544,6 +544,8 @@ namespace Juliet::D3D12
device->AttachToWindow = AttachToWindow;
device->DetachFromWindow = DetachFromWindow;
device->AcquireSwapChainTexture = AcquireSwapChainTexture;
device->AcquireCommandList = AcquireCommandList;
device->SubmitCommandLists = SubmitCommandLists;

View File

@@ -9,6 +9,7 @@
#include <Graphics/D3D12/DX12Utils.h>
#include <algorithm>
#include <DX12CommandList.h>
namespace Juliet::D3D12
{
namespace
@@ -131,6 +132,59 @@ namespace Juliet::D3D12
return true;
}
bool AcquireSwapChainTexture(bool block, NonNullPtr<CommandList> commandList, NonNullPtr<Window> window, Texture** swapchainTexture)
{
auto d3d12CommandList = reinterpret_cast<D3D12CommandList*>(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<void**>(
&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<D3D12PresentData*>(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<Texture*>(&windowData->SwapChainTextureContainers[swapchainIndex]);
return true;
}
} // namespace
bool CreateSwapChain(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12WindowData> windowData,
@@ -244,6 +298,11 @@ namespace Juliet::D3D12
return true;
}
bool AcquireSwapChainTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Window> window, Texture** swapChainTexture)
{
return AcquireSwapChainTexture(false, commandList, window, swapChainTexture);
}
void DestroySwapChain(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12WindowData> windowData)
{
for (uint32 idx = 0; idx < windowData->SwapChainTextureCount; ++idx)

View File

@@ -8,5 +8,6 @@ namespace Juliet::D3D12
extern bool CreateSwapChain(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12WindowData> windowData,
SwapChainComposition composition, PresentMode presentMode);
extern bool AcquireSwapChainTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Window> window, Texture** swapChainTexture);
extern void DestroySwapChain(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12WindowData> windowData);
} // namespace Juliet::D3D12

View File

@@ -1,3 +1,4 @@
#include <DX12CommandList.h>
#include <pch.h>
#include <Graphics/Graphics.h>
@@ -75,11 +76,32 @@ namespace Juliet
device->DetachFromWindow(driver, window);
}
bool AcquireSwapChainTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Window> window, Texture** swapChainTexture)
{
auto header = reinterpret_cast<CommandListHeader*>(commandList.Get());
header->Device->AcquireSwapChainTexture(commandList, window, swapChainTexture);
if (swapChainTexture)
{
header->AcquiredSwapChain = true;
}
return true;
}
CommandList* AcquireCommandList(NonNullPtr<GraphicsDevice> device, QueueType queueType /* = QueueType::Graphics */)
{
GPUDriver* driver = device->Driver;
CommandList* cmdList = device->AcquireCommandList(driver, queueType);
if (!cmdList)
{
return nullptr;
}
auto header = reinterpret_cast<CommandListHeader*>(cmdList);
header->Device = device.Get();
driver->CommandListCount += 1;
return cmdList;

View File

@@ -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<GPUDriver> driver, NonNullPtr<Window> window);
void (*DetachFromWindow)(NonNullPtr<GPUDriver> driver, NonNullPtr<Window> window);
// SwapChain
bool (*AcquireSwapChainTexture)(NonNullPtr<CommandList> commandList, NonNullPtr<Window> window, Texture** swapChainTexture);
// CommandLists
CommandList* (*AcquireCommandList)(NonNullPtr<GPUDriver> driver, QueueType queueType);
bool (*SubmitCommandLists)(NonNullPtr<GPUDriver> driver);

1
Juliet/src/TODO.txt Normal file
View File

@@ -0,0 +1 @@
- Create Simple vector class to make the vector stuff a bit more easier than writing Capacity and Count

View File

@@ -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);