Finishing fences
+ moved some functions to an internal namespace to tidy stuff a bit
This commit is contained in:
@@ -26,7 +26,7 @@ namespace Juliet::D3D12
|
||||
bool ExtendStagingDescriptorPool(NonNullPtr<D3D12Driver> driver, D3D12StagingDescriptorPool& pool)
|
||||
{
|
||||
D3D12DescriptorHeap* heap =
|
||||
CreateDescriptorHeap(driver, pool.Heaps[0]->HeapType, kStagingHeapDescriptorExpectedCount, true);
|
||||
Internal::CreateDescriptorHeap(driver, pool.Heaps[0]->HeapType, kStagingHeapDescriptorExpectedCount, true);
|
||||
if (!heap)
|
||||
{
|
||||
return false;
|
||||
@@ -47,7 +47,10 @@ namespace Juliet::D3D12
|
||||
}
|
||||
} // namespace
|
||||
|
||||
D3D12DescriptorHeap* CreateDescriptorHeap(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 count, bool isStaging)
|
||||
namespace Internal
|
||||
{
|
||||
D3D12DescriptorHeap* CreateDescriptorHeap(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type,
|
||||
uint32 count, bool isStaging)
|
||||
{
|
||||
ID3D12DescriptorHeap* handle;
|
||||
|
||||
@@ -114,8 +117,8 @@ namespace Juliet::D3D12
|
||||
|
||||
pool->FreeDescriptorCapacity = kStagingHeapDescriptorExpectedCount;
|
||||
pool->FreeDescriptorCount = kStagingHeapDescriptorExpectedCount;
|
||||
pool->FreeDescriptors =
|
||||
static_cast<D3D12StagingDescriptor*>(Malloc(kStagingHeapDescriptorExpectedCount * sizeof(D3D12StagingDescriptor)));
|
||||
pool->FreeDescriptors = static_cast<D3D12StagingDescriptor*>(
|
||||
Malloc(kStagingHeapDescriptorExpectedCount * sizeof(D3D12StagingDescriptor)));
|
||||
|
||||
InitStagingDescriptorPool(heap, pool);
|
||||
|
||||
@@ -165,4 +168,5 @@ namespace Juliet::D3D12
|
||||
Free(pool->FreeDescriptors);
|
||||
Free(pool.Get());
|
||||
}
|
||||
} // namespace Internal
|
||||
} // namespace Juliet::D3D12
|
||||
|
||||
@@ -51,8 +51,10 @@ namespace Juliet::D3D12
|
||||
uint32 CpuHandleIndex;
|
||||
};
|
||||
|
||||
extern D3D12DescriptorHeap* CreateDescriptorHeap(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type,
|
||||
uint32 count, bool isStaging);
|
||||
namespace Internal
|
||||
{
|
||||
extern D3D12DescriptorHeap* CreateDescriptorHeap(NonNullPtr<D3D12Driver> driver,
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 count, bool isStaging);
|
||||
extern void DestroyDescriptorHeap(NonNullPtr<D3D12DescriptorHeap> heap);
|
||||
|
||||
extern D3D12StagingDescriptorPool* CreateStagingDescriptorPool(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type);
|
||||
@@ -60,4 +62,5 @@ namespace Juliet::D3D12
|
||||
D3D12StagingDescriptor& outDescriptor);
|
||||
extern void ReleaseStagingDescriptor(NonNullPtr<D3D12Driver> driver, D3D12StagingDescriptor& cpuDescriptor);
|
||||
extern void DestroyStagingDescriptorPool(NonNullPtr<D3D12StagingDescriptorPool> pool);
|
||||
} // namespace Internal
|
||||
} // namespace Juliet::D3D12
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Juliet::D3D12
|
||||
for (uint32 idx = 0; idx < colorTargetInfoCount; ++idx)
|
||||
{
|
||||
auto* container = reinterpret_cast<D3D12TextureContainer*>(colorTargetInfos[idx].TargetTexture);
|
||||
D3D12TextureSubresource* subresource = PrepareTextureSubresourceForWrite(
|
||||
D3D12TextureSubresource* subresource = Internal::PrepareTextureSubresourceForWrite(
|
||||
d3d12CommandList, container,
|
||||
container->Header.CreateInfo.Type == TextureType::Texture_3D ? 0 : colorTargetInfos[idx].LayerIndex,
|
||||
colorTargetInfos[idx].MipLevel, colorTargetInfos[idx].CycleTexture, D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
@@ -61,8 +61,10 @@ namespace Juliet::D3D12
|
||||
{
|
||||
auto resolveContainer = reinterpret_cast<D3D12TextureContainer*>(colorTargetInfos[idx].ResolveTexture);
|
||||
D3D12TextureSubresource* resolveSubresource =
|
||||
PrepareTextureSubresourceForWrite(d3d12CommandList, resolveContainer, colorTargetInfos[idx].ResolveLayerIndex,
|
||||
colorTargetInfos[idx].ResolveMipLevel, colorTargetInfos[idx].CycleResolveTexture,
|
||||
Internal::PrepareTextureSubresourceForWrite(d3d12CommandList, resolveContainer,
|
||||
colorTargetInfos[idx].ResolveLayerIndex,
|
||||
colorTargetInfos[idx].ResolveMipLevel,
|
||||
colorTargetInfos[idx].CycleResolveTexture,
|
||||
D3D12_RESOURCE_STATE_RESOLVE_DEST);
|
||||
|
||||
d3d12CommandList->ColorResolveSubresources[idx] = resolveSubresource;
|
||||
@@ -114,7 +116,8 @@ namespace Juliet::D3D12
|
||||
{
|
||||
if (d3d12CommandList->ColorResolveSubresources[idx])
|
||||
{
|
||||
TextureSubresourceBarrier(d3d12CommandList, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RESOLVE_SOURCE,
|
||||
Internal::TextureSubresourceBarrier(d3d12CommandList, D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||
D3D12_RESOURCE_STATE_RESOLVE_SOURCE,
|
||||
d3d12CommandList->ColorTargetSubresources[idx]);
|
||||
ID3D12GraphicsCommandList_ResolveSubresource(
|
||||
d3d12CommandList->GraphicsCommandList.CommandList,
|
||||
@@ -122,18 +125,21 @@ namespace Juliet::D3D12
|
||||
d3d12CommandList->ColorResolveSubresources[idx]->Index,
|
||||
d3d12CommandList->ColorTargetSubresources[idx]->Parent->Resource,
|
||||
d3d12CommandList->ColorTargetSubresources[idx]->Index,
|
||||
ConvertToD3D12TextureFormat(
|
||||
Internal::ConvertToD3D12TextureFormat(
|
||||
d3d12CommandList->ColorTargetSubresources[idx]->Parent->Container->Header.CreateInfo.Format));
|
||||
|
||||
TextureSubresourceTransitionToDefaultUsage(d3d12CommandList, d3d12CommandList->ColorTargetSubresources[idx],
|
||||
Internal::TextureSubresourceTransitionToDefaultUsage(d3d12CommandList,
|
||||
d3d12CommandList->ColorTargetSubresources[idx],
|
||||
D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
|
||||
|
||||
TextureSubresourceTransitionToDefaultUsage(d3d12CommandList, d3d12CommandList->ColorResolveSubresources[idx],
|
||||
Internal::TextureSubresourceTransitionToDefaultUsage(d3d12CommandList,
|
||||
d3d12CommandList->ColorResolveSubresources[idx],
|
||||
D3D12_RESOURCE_STATE_RESOLVE_DEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
TextureSubresourceTransitionToDefaultUsage(d3d12CommandList, d3d12CommandList->ColorTargetSubresources[idx],
|
||||
Internal::TextureSubresourceTransitionToDefaultUsage(d3d12CommandList,
|
||||
d3d12CommandList->ColorTargetSubresources[idx],
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,9 +7,89 @@
|
||||
#include <Graphics/D3D12/DX12Utils.h>
|
||||
|
||||
namespace Juliet::D3D12
|
||||
{
|
||||
namespace
|
||||
{
|
||||
void ReleaseFenceToPool(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12Fence> fence)
|
||||
{
|
||||
if (driver->AvailableFenceCount + 1 >= driver->AvailableFenceCapacity)
|
||||
{
|
||||
driver->AvailableFenceCapacity = driver->AvailableFenceCapacity * 2;
|
||||
driver->AvailableFences = static_cast<D3D12Fence**>(
|
||||
Realloc(driver->AvailableFences, sizeof(D3D12Fence*) * driver->AvailableFenceCapacity));
|
||||
}
|
||||
driver->AvailableFences[driver->AvailableFenceCount] = fence;
|
||||
driver->AvailableFenceCount += 1;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool Wait(NonNullPtr<GPUDriver> driver)
|
||||
{
|
||||
auto d3d12driver = static_cast<D3D12Driver*>(driver.Get());
|
||||
D3D12Fence* fence = Internal::AcquireFence(d3d12driver);
|
||||
if (!fence)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (d3d12driver->GraphicsQueue)
|
||||
{
|
||||
// Insert a signal into the end of the command queue...
|
||||
ID3D12CommandQueue_Signal(d3d12driver->GraphicsQueue, fence->Handle, D3D12_FENCE_SIGNAL_VALUE);
|
||||
|
||||
// ...and then block on it.
|
||||
if (ID3D12Fence_GetCompletedValue(fence->Handle) != D3D12_FENCE_SIGNAL_VALUE)
|
||||
{
|
||||
HRESULT result = ID3D12Fence_SetEventOnCompletion(fence->Handle, D3D12_FENCE_SIGNAL_VALUE, fence->Event);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LogError(d3d12driver, "Setting fence event failed!", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD waitResult = WaitForSingleObject(fence->Event, INFINITE);
|
||||
if (waitResult == WAIT_FAILED)
|
||||
{
|
||||
LogError(d3d12driver, "Wait failed!", result);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReleaseFence(driver, reinterpret_cast<Fence*>(fence));
|
||||
|
||||
bool result = true;
|
||||
|
||||
// Clean up
|
||||
for (int32 idx = d3d12driver->SubmittedCommandListCount - 1; idx >= 0; idx -= 1)
|
||||
{
|
||||
result &= Internal::CleanCommandList(d3d12driver, d3d12driver->SubmittedCommandLists[idx], false);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool QueryFence(NonNullPtr<GPUDriver> driver, NonNullPtr<Fence> fence)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void ReleaseFence(NonNullPtr<GPUDriver> driver, NonNullPtr<Fence> fence)
|
||||
{
|
||||
auto d3d12driver = static_cast<D3D12Driver*>(driver.Get());
|
||||
auto d3d12Fence = reinterpret_cast<D3D12Fence*>(fence.Get());
|
||||
|
||||
if (--d3d12Fence->ReferenceCount == 0)
|
||||
{
|
||||
ReleaseFenceToPool(d3d12driver, d3d12Fence);
|
||||
}
|
||||
}
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
void ResourceBarrier(NonNullPtr<D3D12CommandList> commandList, D3D12_RESOURCE_STATES sourceState,
|
||||
D3D12_RESOURCE_STATES destinationState, ID3D12Resource* resource, uint32 subresourceIndex, bool needsUavBarrier)
|
||||
D3D12_RESOURCE_STATES destinationState, ID3D12Resource* resource, uint32 subresourceIndex,
|
||||
bool needsUavBarrier)
|
||||
{
|
||||
D3D12_RESOURCE_BARRIER barrierDesc[2];
|
||||
uint32 numBarriers = 0;
|
||||
@@ -94,5 +174,5 @@ namespace Juliet::D3D12
|
||||
}
|
||||
Free(fence.Get());
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Juliet::D3D12
|
||||
|
||||
@@ -2,6 +2,13 @@
|
||||
|
||||
#include <Core/Common/NonNullPtr.h>
|
||||
#include <Graphics/D3D12/D3D12Common.h>
|
||||
#include <Graphics/GraphicsDevice.h>
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
struct Fence;
|
||||
struct GPUDriver;
|
||||
} // namespace Juliet
|
||||
|
||||
namespace Juliet::D3D12
|
||||
{
|
||||
@@ -18,10 +25,17 @@ namespace Juliet::D3D12
|
||||
int32 ReferenceCount; // TODO : Atomic
|
||||
};
|
||||
|
||||
extern bool Wait(NonNullPtr<GPUDriver> driver);
|
||||
extern bool QueryFence(NonNullPtr<GPUDriver> driver, NonNullPtr<Fence> fence);
|
||||
extern void ReleaseFence(NonNullPtr<GPUDriver> driver, NonNullPtr<Fence> fence);
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
extern void ResourceBarrier(NonNullPtr<D3D12CommandList> commandList, D3D12_RESOURCE_STATES sourceState,
|
||||
D3D12_RESOURCE_STATES destinationState, ID3D12Resource* resource,
|
||||
uint32 subresourceIndex, bool needsUavBarrier);
|
||||
|
||||
extern D3D12Fence* AcquireFence(NonNullPtr<D3D12Driver> driver);
|
||||
extern void DestroyFence(NonNullPtr<D3D12Fence> fence);
|
||||
} // namespace Internal
|
||||
} // namespace Juliet::D3D12
|
||||
|
||||
@@ -157,20 +157,23 @@ namespace Juliet::D3D12
|
||||
}
|
||||
} // namespace
|
||||
|
||||
D3D12TextureSubresource* PrepareTextureSubresourceForWrite(NonNullPtr<D3D12CommandList> commandList,
|
||||
NonNullPtr<D3D12TextureContainer> container, uint32 layer,
|
||||
uint32 level, bool shouldCycle, D3D12_RESOURCE_STATES newTextureUsage)
|
||||
namespace Internal
|
||||
{
|
||||
D3D12TextureSubresource* subresource = FetchTextureSubresource(container, layer, level);
|
||||
D3D12TextureSubresource* PrepareTextureSubresourceForWrite(NonNullPtr<D3D12CommandList> commandList,
|
||||
NonNullPtr<D3D12TextureContainer> container,
|
||||
uint32 layer, uint32 level, bool shouldCycle,
|
||||
D3D12_RESOURCE_STATES newTextureUsage)
|
||||
{
|
||||
D3D12TextureSubresource* subresource = Internal::FetchTextureSubresource(container, layer, level);
|
||||
if (shouldCycle and container->CanBeCycled and subresource->Parent->RefCount > 0)
|
||||
{
|
||||
// TODO: Cycle the active texture to an available one. Not needed for swap chain (current objective)
|
||||
// CycleActiveTexture(commandList->Driver, container);
|
||||
|
||||
subresource = FetchTextureSubresource(container, layer, level);
|
||||
subresource = Internal::FetchTextureSubresource(container, layer, level);
|
||||
}
|
||||
|
||||
TextureSubresourceTransitionFromDefaultUsage(commandList, subresource, newTextureUsage);
|
||||
Internal::TextureSubresourceTransitionFromDefaultUsage(commandList, subresource, newTextureUsage);
|
||||
|
||||
return subresource;
|
||||
}
|
||||
@@ -185,9 +188,10 @@ namespace Juliet::D3D12
|
||||
D3D12_RESOURCE_STATES destinationState, NonNullPtr<D3D12TextureSubresource> textureSubresource)
|
||||
{
|
||||
TextureUsageFlag currentFlag = textureSubresource->Parent->Container->Header.CreateInfo.Flags;
|
||||
bool needsUAVBarrier = ((currentFlag & TextureUsageFlag::ComputeStorageWrite) != TextureUsageFlag::None) ||
|
||||
bool needsUAVBarrier =
|
||||
((currentFlag & TextureUsageFlag::ComputeStorageWrite) != TextureUsageFlag::None) ||
|
||||
((currentFlag & TextureUsageFlag::ComputeStorageSimultaneousReadWrite) != TextureUsageFlag::None);
|
||||
ResourceBarrier(commandList, sourceState, destinationState, textureSubresource->Parent->Resource,
|
||||
Internal::ResourceBarrier(commandList, sourceState, destinationState, textureSubresource->Parent->Resource,
|
||||
textureSubresource->Index, needsUAVBarrier);
|
||||
}
|
||||
|
||||
@@ -200,8 +204,8 @@ namespace Juliet::D3D12
|
||||
TextureSubresourceBarrier(commandList, defaultUsage, toTextureUsage, subresource);
|
||||
}
|
||||
|
||||
void TextureTransitionFromDefaultUsage(NonNullPtr<D3D12CommandList> commandList, NonNullPtr<D3D12Texture> texture,
|
||||
D3D12_RESOURCE_STATES toTextureUsage)
|
||||
void TextureTransitionFromDefaultUsage(NonNullPtr<D3D12CommandList> commandList,
|
||||
NonNullPtr<D3D12Texture> texture, D3D12_RESOURCE_STATES toTextureUsage)
|
||||
{
|
||||
for (uint32 i = 0; i < texture->SubresourceCount; ++i)
|
||||
{
|
||||
@@ -210,7 +214,8 @@ namespace Juliet::D3D12
|
||||
}
|
||||
|
||||
void TextureSubresourceTransitionToDefaultUsage(NonNullPtr<D3D12CommandList> commandList,
|
||||
NonNullPtr<D3D12TextureSubresource> subresource, D3D12_RESOURCE_STATES fromTextureUsage)
|
||||
NonNullPtr<D3D12TextureSubresource> subresource,
|
||||
D3D12_RESOURCE_STATES fromTextureUsage)
|
||||
{
|
||||
D3D12_RESOURCE_STATES defaultUsage =
|
||||
GetDefaultTextureResourceState(subresource->Parent->Container->Header.CreateInfo.Flags);
|
||||
@@ -231,5 +236,5 @@ namespace Juliet::D3D12
|
||||
{
|
||||
return JulietToD3D12_TextureFormat[ToUnderlying(format)];
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Juliet::D3D12
|
||||
|
||||
@@ -62,13 +62,16 @@ namespace Juliet::D3D12
|
||||
int32 RefCount;
|
||||
};
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
extern D3D12TextureSubresource* PrepareTextureSubresourceForWrite(NonNullPtr<D3D12CommandList>,
|
||||
NonNullPtr<D3D12TextureContainer> container,
|
||||
uint32 layer, uint32 level, bool shouldCycle,
|
||||
D3D12_RESOURCE_STATES newTextureUsage);
|
||||
extern D3D12TextureSubresource* FetchTextureSubresource(NonNullPtr<D3D12TextureContainer> container, uint32 layer, uint32 level);
|
||||
extern void TextureSubresourceBarrier(NonNullPtr<D3D12CommandList> commandList, D3D12_RESOURCE_STATES sourceState,
|
||||
D3D12_RESOURCE_STATES destinationState,
|
||||
extern D3D12TextureSubresource* FetchTextureSubresource(NonNullPtr<D3D12TextureContainer> container,
|
||||
uint32 layer, uint32 level);
|
||||
extern void TextureSubresourceBarrier(NonNullPtr<D3D12CommandList> commandList,
|
||||
D3D12_RESOURCE_STATES sourceState, D3D12_RESOURCE_STATES destinationState,
|
||||
NonNullPtr<D3D12TextureSubresource> textureSubresource);
|
||||
|
||||
// Texture usage transition
|
||||
@@ -80,9 +83,10 @@ namespace Juliet::D3D12
|
||||
extern void TextureSubresourceTransitionToDefaultUsage(NonNullPtr<D3D12CommandList> commandList,
|
||||
NonNullPtr<D3D12TextureSubresource> subresource,
|
||||
D3D12_RESOURCE_STATES fromTextureUsage);
|
||||
extern void TextureTransitionToDefaultUsage(NonNullPtr<D3D12CommandList> commandList,
|
||||
NonNullPtr<D3D12Texture> texture, D3D12_RESOURCE_STATES fromTextureUsage);
|
||||
extern void TextureTransitionToDefaultUsage(NonNullPtr<D3D12CommandList> commandList, NonNullPtr<D3D12Texture> texture,
|
||||
D3D12_RESOURCE_STATES fromTextureUsage);
|
||||
|
||||
// Utils
|
||||
extern DXGI_FORMAT ConvertToD3D12TextureFormat(TextureFormat format);
|
||||
} // namespace Internal
|
||||
} // namespace Juliet::D3D12
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Juliet::D3D12
|
||||
{
|
||||
namespace
|
||||
{
|
||||
bool HasD3D12CommandList(NonNullPtr<D3D12CommandList> commandList, QueueType queueType)
|
||||
bool HasD3D12CommandListForQueueType(NonNullPtr<D3D12CommandList> commandList, QueueType queueType)
|
||||
{
|
||||
switch (queueType)
|
||||
{
|
||||
@@ -37,7 +37,7 @@ namespace Juliet::D3D12
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateD3D12CommandList(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12CommandList> commandList, QueueType queueType)
|
||||
bool CreateD3D12CommandListForQueueType(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12CommandList> commandList, QueueType queueType)
|
||||
{
|
||||
// TODO: String library
|
||||
std::wstring wide_str = L"CommandList ID:" + std::to_wstring(commandList->ID);
|
||||
@@ -111,7 +111,7 @@ namespace Juliet::D3D12
|
||||
if (!commandList)
|
||||
{
|
||||
Log(LogLevel::Error, LogCategory::Graphics, "Cannot allocate D3D12CommandList: Out of memory");
|
||||
DestroyCommandList(commandList);
|
||||
Internal::DestroyCommandList(commandList);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -122,14 +122,18 @@ namespace Juliet::D3D12
|
||||
{
|
||||
Log(LogLevel::Error, LogCategory::Graphics,
|
||||
"Error not implemented, out of memory, handle that by deallocating stuff and returning false");
|
||||
DestroyCommandList(commandList);
|
||||
Internal::DestroyCommandList(commandList);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 id = driver->AvailableCommandListCapacity;
|
||||
driver->AvailableCommandListCapacity += 1;
|
||||
driver->AvailableCommandLists = resizedArray;
|
||||
driver->AvailableCommandLists[driver->AvailableCommandListCapacity] = commandList;
|
||||
|
||||
commandList->ID = driver->AvailableCommandListCapacity;
|
||||
driver->AvailableCommandLists[driver->AvailableCommandListCount] = commandList;
|
||||
driver->AvailableCommandListCount += 1;
|
||||
|
||||
commandList->ID = id;
|
||||
commandList->Driver = driver;
|
||||
|
||||
commandList->PresentDataCapacity = 1;
|
||||
@@ -137,35 +141,42 @@ namespace Juliet::D3D12
|
||||
commandList->PresentDatas =
|
||||
static_cast<D3D12PresentData*>(Calloc(commandList->PresentDataCapacity, sizeof(D3D12PresentData)));
|
||||
|
||||
driver->AvailableCommandListCapacity += 1;
|
||||
// TODO : Simplify this
|
||||
if (!HasD3D12CommandListForQueueType(commandList, queueType))
|
||||
{
|
||||
if (!CreateD3D12CommandListForQueueType(driver, commandList, queueType))
|
||||
{
|
||||
Log(LogLevel::Error, LogCategory::Graphics, "Cannot Create D3D12 command list");
|
||||
Internal::DestroyCommandList(commandList);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
D3D12CommandList* AcquireCommandListFromPool(NonNullPtr<D3D12Driver> driver, QueueType queueType)
|
||||
{
|
||||
if (driver->AvailableCommandListCount == 0)
|
||||
{
|
||||
if (!AllocateCommandList(driver, queueType))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
D3D12CommandList* commandList = driver->AvailableCommandLists[driver->AvailableCommandListCount - 1];
|
||||
driver->AvailableCommandListCount -= 1;
|
||||
|
||||
return commandList;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
CommandList* AcquireCommandList(NonNullPtr<GPUDriver> driver, QueueType queueType)
|
||||
{
|
||||
auto* d3d12Driver = static_cast<D3D12Driver*>(driver.Get());
|
||||
|
||||
uint8 currentCommandListIndex = d3d12Driver->AvailableCommandListCount;
|
||||
if (currentCommandListIndex >= d3d12Driver->AvailableCommandListCapacity)
|
||||
{
|
||||
if (!AllocateCommandList(d3d12Driver, queueType))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
D3D12CommandList* commandList = d3d12Driver->AvailableCommandLists[currentCommandListIndex];
|
||||
if (!HasD3D12CommandList(commandList, queueType))
|
||||
{
|
||||
if (!CreateD3D12CommandList(d3d12Driver, commandList, queueType))
|
||||
{
|
||||
Log(LogLevel::Error, LogCategory::Graphics, "Cannot Create D3D12 command list");
|
||||
DestroyCommandList(commandList);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
D3D12CommandList* commandList = AcquireCommandListFromPool(d3d12Driver, queueType);
|
||||
|
||||
// Get Proper allocator for the frame and reset both it and the requested queue
|
||||
uint8 bufferIndex = d3d12Driver->FrameCounter % GPUDriver::kResourceBufferCount;
|
||||
@@ -195,7 +206,8 @@ namespace Juliet::D3D12
|
||||
default: Assert(false && "Unsupported QueueType"); return nullptr;
|
||||
}
|
||||
|
||||
d3d12Driver->AvailableCommandListCount += 1;
|
||||
commandList->AutoReleaseFence = true;
|
||||
|
||||
return reinterpret_cast<CommandList*>(commandList);
|
||||
}
|
||||
|
||||
@@ -212,7 +224,7 @@ namespace Juliet::D3D12
|
||||
uint32 swapchainIndex = d3d12CommandList->PresentDatas[i].SwapChainImageIndex;
|
||||
D3D12TextureContainer* container =
|
||||
&d3d12CommandList->PresentDatas[i].WindowData->SwapChainTextureContainers[swapchainIndex];
|
||||
D3D12TextureSubresource* subresource = FetchTextureSubresource(container, 0, 0);
|
||||
D3D12TextureSubresource* subresource = Internal::FetchTextureSubresource(container, 0, 0);
|
||||
|
||||
D3D12_RESOURCE_BARRIER barrierDesc;
|
||||
barrierDesc.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
@@ -248,7 +260,7 @@ namespace Juliet::D3D12
|
||||
ID3D12CommandList_Release(commandLists[0]);
|
||||
|
||||
// Acquire a fence and set it to the in-flight fence
|
||||
d3d12CommandList->InFlightFence = AcquireFence(d3d12Driver);
|
||||
d3d12CommandList->InFlightFence = Internal::AcquireFence(d3d12Driver);
|
||||
if (!d3d12CommandList->InFlightFence)
|
||||
{
|
||||
return false;
|
||||
@@ -263,16 +275,15 @@ namespace Juliet::D3D12
|
||||
}
|
||||
|
||||
// Mark the command list as submitted
|
||||
if (d3d12Driver->SubmittedCommandBufferCount + 1 >= d3d12Driver->SubmittedCommandListCapacity)
|
||||
if (d3d12Driver->SubmittedCommandListCount + 1 >= d3d12Driver->SubmittedCommandListCapacity)
|
||||
{
|
||||
d3d12Driver->SubmittedCommandListCapacity = d3d12Driver->SubmittedCommandBufferCount + 1;
|
||||
d3d12Driver->SubmittedCommandListCapacity = d3d12Driver->SubmittedCommandListCount + 1;
|
||||
|
||||
d3d12Driver->SubmittedCommandLists = static_cast<D3D12CommandList**>(
|
||||
Realloc(d3d12Driver->SubmittedCommandLists, sizeof(D3D12CommandList*) * d3d12Driver->SubmittedCommandListCapacity));
|
||||
}
|
||||
|
||||
d3d12Driver->SubmittedCommandLists[d3d12Driver->SubmittedCommandBufferCount] = d3d12CommandList;
|
||||
d3d12Driver->SubmittedCommandBufferCount += 1;
|
||||
d3d12Driver->SubmittedCommandLists[d3d12Driver->SubmittedCommandListCount] = d3d12CommandList;
|
||||
d3d12Driver->SubmittedCommandListCount += 1;
|
||||
|
||||
bool success = true;
|
||||
for (uint32 i = 0; i < d3d12CommandList->PresentDataCount; i += 1)
|
||||
@@ -308,19 +319,15 @@ namespace Juliet::D3D12
|
||||
}
|
||||
|
||||
// TODO : Correctly clean up and destroy
|
||||
d3d12Driver->AvailableCommandListCount = 0;
|
||||
// Check for cleanups
|
||||
// for (Sint32 i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1) {
|
||||
// Uint64 fenceValue = ID3D12Fence_GetCompletedValue(
|
||||
// renderer->submittedCommandBuffers[i]->inFlightFence->handle);
|
||||
//
|
||||
// if (fenceValue == D3D12_FENCE_SIGNAL_VALUE) {
|
||||
// result &= D3D12_INTERNAL_CleanCommandBuffer(
|
||||
// renderer,
|
||||
// renderer->submittedCommandBuffers[i],
|
||||
// false);
|
||||
// }
|
||||
// }
|
||||
for (int32 i = d3d12Driver->SubmittedCommandListCount - 1; i >= 0; i -= 1)
|
||||
{
|
||||
uint64 fenceValue = ID3D12Fence_GetCompletedValue(d3d12Driver->SubmittedCommandLists[i]->InFlightFence->Handle);
|
||||
if (fenceValue == D3D12_FENCE_SIGNAL_VALUE)
|
||||
{
|
||||
result &= Internal::CleanCommandList(d3d12Driver, d3d12Driver->SubmittedCommandLists[i], false);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Destroy anything (buffer, texture, etc...)
|
||||
|
||||
@@ -329,26 +336,6 @@ namespace Juliet::D3D12
|
||||
return success;
|
||||
}
|
||||
|
||||
void DestroyCommandList(NonNullPtr<D3D12CommandList> commandList)
|
||||
{
|
||||
// TODO : Handle other kind of command list (copy compute)
|
||||
if (commandList->GraphicsCommandList.CommandList)
|
||||
{
|
||||
ID3D12GraphicsCommandList_Release(commandList->GraphicsCommandList.CommandList);
|
||||
}
|
||||
|
||||
for (auto* allocator : commandList->GraphicsCommandList.Allocator)
|
||||
{
|
||||
if (allocator)
|
||||
{
|
||||
ID3D12CommandAllocator_Release(allocator);
|
||||
}
|
||||
}
|
||||
|
||||
Free(commandList->PresentDatas);
|
||||
Free(commandList.Get());
|
||||
}
|
||||
|
||||
void SetViewPort(NonNullPtr<CommandList> commandList, const GraphicsViewPort& viewPort)
|
||||
{
|
||||
auto* d3d12CommandList = reinterpret_cast<D3D12CommandList*>(commandList.Get());
|
||||
@@ -386,4 +373,66 @@ namespace Juliet::D3D12
|
||||
auto* d3d12CommandList = reinterpret_cast<D3D12CommandList*>(commandList.Get());
|
||||
ID3D12GraphicsCommandList_OMSetStencilRef(d3d12CommandList->GraphicsCommandList.CommandList, reference);
|
||||
}
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
void DestroyCommandList(NonNullPtr<D3D12CommandList> commandList)
|
||||
{
|
||||
// TODO : Handle other kind of command list (copy compute)
|
||||
if (commandList->GraphicsCommandList.CommandList)
|
||||
{
|
||||
ID3D12GraphicsCommandList_Release(commandList->GraphicsCommandList.CommandList);
|
||||
}
|
||||
|
||||
for (auto* allocator : commandList->GraphicsCommandList.Allocator)
|
||||
{
|
||||
if (allocator)
|
||||
{
|
||||
ID3D12CommandAllocator_Release(allocator);
|
||||
}
|
||||
}
|
||||
|
||||
Free(commandList->PresentDatas);
|
||||
Free(commandList.Get());
|
||||
}
|
||||
|
||||
bool CleanCommandList(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12CommandList> commandList, bool cancel)
|
||||
{
|
||||
// No more presentation data
|
||||
commandList->PresentDataCount = 0;
|
||||
|
||||
// Release Fence if needed
|
||||
if (commandList->AutoReleaseFence)
|
||||
{
|
||||
ReleaseFence(driver.Get(), reinterpret_cast<Fence*>(commandList->InFlightFence));
|
||||
commandList->InFlightFence = nullptr;
|
||||
}
|
||||
|
||||
// Return the command list to the pool
|
||||
if (driver->AvailableCommandListCount == driver->AvailableCommandListCapacity)
|
||||
{
|
||||
driver->AvailableCommandListCapacity += 1;
|
||||
driver->AvailableCommandLists = static_cast<D3D12CommandList**>(
|
||||
Realloc(driver->AvailableCommandLists, driver->AvailableCommandListCapacity * sizeof(D3D12CommandList*)));
|
||||
}
|
||||
driver->AvailableCommandLists[driver->AvailableCommandListCount] = commandList;
|
||||
driver->AvailableCommandListCount += 1;
|
||||
|
||||
// Remove this command list from the submitted list
|
||||
if (!cancel)
|
||||
{
|
||||
for (uint32 idx = 0; idx < driver->SubmittedCommandListCount; idx += 1)
|
||||
{
|
||||
if (driver->SubmittedCommandLists[idx] == commandList)
|
||||
{
|
||||
driver->SubmittedCommandLists[idx] = driver->SubmittedCommandLists[driver->SubmittedCommandListCount - 1];
|
||||
driver->SubmittedCommandListCount -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Juliet::D3D12
|
||||
|
||||
@@ -46,6 +46,7 @@ namespace Juliet::D3D12
|
||||
uint32 PresentDataCount;
|
||||
|
||||
D3D12Fence* InFlightFence;
|
||||
bool AutoReleaseFence;
|
||||
|
||||
D3D12GraphicsCommandListData GraphicsCommandList;
|
||||
D3D12GraphicsCommandListData ComputeCommandList;
|
||||
@@ -57,9 +58,14 @@ namespace Juliet::D3D12
|
||||
|
||||
extern CommandList* AcquireCommandList(NonNullPtr<GPUDriver> driver, QueueType queueType);
|
||||
extern bool SubmitCommandLists(NonNullPtr<CommandList> commandList);
|
||||
extern void DestroyCommandList(NonNullPtr<D3D12CommandList> commandList);
|
||||
extern void SetViewPort(NonNullPtr<CommandList> commandList, const GraphicsViewPort& viewPort);
|
||||
extern void SetScissorRect(NonNullPtr<CommandList> commandList, const Rectangle& rectangle);
|
||||
extern void SetBlendConstants(NonNullPtr<CommandList> commandList, FColor blendConstants);
|
||||
extern void SetStencilReference(NonNullPtr<CommandList> commandList, uint8 reference);
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
extern void DestroyCommandList(NonNullPtr<D3D12CommandList> commandList);
|
||||
extern bool CleanCommandList(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12CommandList> commandList, bool cancel);
|
||||
} // namespace Internal
|
||||
} // namespace Juliet::D3D12
|
||||
|
||||
@@ -174,7 +174,7 @@ namespace Juliet::D3D12
|
||||
{
|
||||
if (driver->StagingDescriptorPools[i])
|
||||
{
|
||||
DestroyStagingDescriptorPool(driver->StagingDescriptorPools[i]);
|
||||
Internal::DestroyStagingDescriptorPool(driver->StagingDescriptorPools[i]);
|
||||
driver->StagingDescriptorPools[i] = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -184,7 +184,7 @@ namespace Juliet::D3D12
|
||||
{
|
||||
if (driver->AvailableCommandLists[i])
|
||||
{
|
||||
DestroyCommandList(driver->AvailableCommandLists[i]);
|
||||
Internal::DestroyCommandList(driver->AvailableCommandLists[i]);
|
||||
driver->AvailableCommandLists[i] = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -194,7 +194,7 @@ namespace Juliet::D3D12
|
||||
{
|
||||
if (driver->AvailableFences[i])
|
||||
{
|
||||
DestroyFence(driver->AvailableFences[i]);
|
||||
Internal::DestroyFence(driver->AvailableFences[i]);
|
||||
driver->AvailableFences[i] = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -202,7 +202,7 @@ namespace Juliet::D3D12
|
||||
// Clean allocations
|
||||
Free(driver->AvailableCommandLists);
|
||||
Free(driver->SubmittedCommandLists);
|
||||
Free(driver->WindowData);
|
||||
//Free(driver->WindowData); // TODO Should free the vector of WindowData, but we have only one for now
|
||||
Free(driver->AvailableFences);
|
||||
|
||||
if (driver->IndirectDrawCommandSignature)
|
||||
@@ -278,7 +278,7 @@ namespace Juliet::D3D12
|
||||
|
||||
windowData->Window = window;
|
||||
|
||||
if (!CreateSwapChain(d3d12Driver, windowData, SwapChainComposition::SDR, PresentMode::VSync))
|
||||
if (!Internal::CreateSwapChain(d3d12Driver, windowData, SwapChainComposition::SDR, PresentMode::VSync))
|
||||
{
|
||||
Log(LogLevel::Error, LogCategory::Graphics, "AttachToWindow failure: Cannot create Swap Chain.");
|
||||
Free(windowData);
|
||||
@@ -294,12 +294,21 @@ namespace Juliet::D3D12
|
||||
void DetachFromWindow(NonNullPtr<GPUDriver> driver, NonNullPtr<Window> window)
|
||||
{
|
||||
auto* d3d12Driver = static_cast<D3D12Driver*>(driver.Get());
|
||||
auto* windowData = d3d12Driver->WindowData;
|
||||
Assert(windowData && "Trying to destroy a swapchain but no Window Data exists");
|
||||
|
||||
Assert(d3d12Driver->WindowData && "Trying to destroy a swapchain but no Window Data exists");
|
||||
Wait(driver);
|
||||
|
||||
// TODO : Wait for any remaining work and release the fences.
|
||||
for (uint32 idx = 0; idx < GPUDriver::kMaxFramesInFlight; idx += 1)
|
||||
{
|
||||
if (windowData->InFlightFences[idx] != nullptr)
|
||||
{
|
||||
ReleaseFence(driver, windowData->InFlightFences[idx]);
|
||||
windowData->InFlightFences[idx] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
DestroySwapChain(d3d12Driver, d3d12Driver->WindowData);
|
||||
Internal::DestroySwapChain(d3d12Driver, d3d12Driver->WindowData);
|
||||
|
||||
Free(d3d12Driver->WindowData);
|
||||
d3d12Driver->WindowData = nullptr;
|
||||
@@ -548,7 +557,7 @@ namespace Juliet::D3D12
|
||||
|
||||
// Create Pools
|
||||
driver->SubmittedCommandListCapacity = 4;
|
||||
driver->SubmittedCommandBufferCount = 0;
|
||||
driver->SubmittedCommandListCount = 0;
|
||||
driver->SubmittedCommandLists =
|
||||
static_cast<D3D12CommandList**>(Calloc(driver->SubmittedCommandListCapacity, sizeof(D3D12CommandList*)));
|
||||
if (!driver->SubmittedCommandLists)
|
||||
@@ -570,7 +579,7 @@ namespace Juliet::D3D12
|
||||
for (uint32 i = 0; i < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; i += 1)
|
||||
{
|
||||
driver->StagingDescriptorPools[i] =
|
||||
CreateStagingDescriptorPool(driver, static_cast<D3D12_DESCRIPTOR_HEAP_TYPE>(i));
|
||||
Internal::CreateStagingDescriptorPool(driver, static_cast<D3D12_DESCRIPTOR_HEAP_TYPE>(i));
|
||||
|
||||
if (driver->StagingDescriptorPools[i] == nullptr)
|
||||
{
|
||||
@@ -605,6 +614,10 @@ namespace Juliet::D3D12
|
||||
device->SetBlendConstants = SetBlendConstants;
|
||||
device->SetStencilReference = SetStencilReference;
|
||||
|
||||
device->Wait = Wait;
|
||||
device->QueryFence = QueryFence;
|
||||
device->ReleaseFence = ReleaseFence;
|
||||
|
||||
device->Driver = driver;
|
||||
driver->GraphicsDevice = device;
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace Juliet::D3D12
|
||||
|
||||
D3D12CommandList** SubmittedCommandLists;
|
||||
uint8 SubmittedCommandListCapacity;
|
||||
uint8 SubmittedCommandBufferCount;
|
||||
uint8 SubmittedCommandListCount;
|
||||
|
||||
D3D12Fence** AvailableFences;
|
||||
uint32 AvailableFenceCount;
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
#include <Core/HAL/Display/Win32/Win32Window.h>
|
||||
#include <Core/Memory/Allocator.h>
|
||||
#include <Graphics/D3D12/D3D12Texture.h>
|
||||
#include <Graphics/D3D12/DX12CommandList.h>
|
||||
#include <Graphics/D3D12/DX12GraphicsDevice.h>
|
||||
#include <Graphics/D3D12/DX12Includes.h>
|
||||
#include <Graphics/D3D12/DX12SwapChain.h>
|
||||
#include <Graphics/D3D12/DX12Utils.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <DX12CommandList.h>
|
||||
|
||||
namespace Juliet::D3D12
|
||||
{
|
||||
namespace
|
||||
@@ -105,7 +106,7 @@ namespace Juliet::D3D12
|
||||
texture->IndexInContainer = 0;
|
||||
|
||||
// Assign SRV to the swapchain texture
|
||||
AssignStagingDescriptor(driver, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, texture->SRVHandle);
|
||||
Internal::AssignStagingDescriptor(driver, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, texture->SRVHandle);
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||
srvDesc.Format = SwapchainCompositionToTextureFormat[ToUnderlying(composition)];
|
||||
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||
@@ -118,7 +119,7 @@ namespace Juliet::D3D12
|
||||
|
||||
// Assign RTV to the swapchain texture
|
||||
DXGI_FORMAT swapchainFormat = SwapchainCompositionToTextureFormat[ToUnderlying(composition)];
|
||||
AssignStagingDescriptor(driver, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, texture->Subresources[0].RTVHandles[0]);
|
||||
Internal::AssignStagingDescriptor(driver, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, texture->Subresources[0].RTVHandles[0]);
|
||||
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc;
|
||||
rtvDesc.Format = (composition == SwapChainComposition::SDR_LINEAR) ? DXGI_FORMAT_B8G8R8A8_UNORM_SRGB : swapchainFormat;
|
||||
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
|
||||
@@ -186,6 +187,13 @@ namespace Juliet::D3D12
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool AcquireSwapChainTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Window> window, Texture** swapChainTexture)
|
||||
{
|
||||
return AcquireSwapChainTexture(false, commandList, window, swapChainTexture);
|
||||
}
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
bool CreateSwapChain(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12WindowData> windowData,
|
||||
SwapChainComposition composition, PresentMode presentMode)
|
||||
{
|
||||
@@ -297,17 +305,13 @@ 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)
|
||||
{
|
||||
ReleaseStagingDescriptor(driver, windowData->SwapChainTextureContainers[idx].ActiveTexture->SRVHandle);
|
||||
ReleaseStagingDescriptor(driver, windowData->SwapChainTextureContainers[idx].ActiveTexture->Subresources[0].RTVHandles[0]);
|
||||
ReleaseStagingDescriptor(driver,
|
||||
windowData->SwapChainTextureContainers[idx].ActiveTexture->Subresources[0].RTVHandles[0]);
|
||||
|
||||
Free(windowData->SwapChainTextureContainers[idx].ActiveTexture->Subresources[0].RTVHandles);
|
||||
Free(windowData->SwapChainTextureContainers[idx].ActiveTexture->Subresources);
|
||||
@@ -318,4 +322,5 @@ namespace Juliet::D3D12
|
||||
IDXGISwapChain_Release(windowData->SwapChain);
|
||||
windowData->SwapChain = nullptr;
|
||||
}
|
||||
} // namespace Internal
|
||||
} // namespace Juliet::D3D12
|
||||
|
||||
@@ -7,8 +7,12 @@ namespace Juliet::D3D12
|
||||
struct D3D12Driver;
|
||||
struct D3D12WindowData;
|
||||
|
||||
extern bool AcquireSwapChainTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Window> window, Texture** swapChainTexture);
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
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 Internal
|
||||
} // namespace Juliet::D3D12
|
||||
|
||||
@@ -59,6 +59,11 @@ namespace Juliet
|
||||
void (*SetBlendConstants)(NonNullPtr<CommandList> commandList, FColor blendConstants);
|
||||
void (*SetStencilReference)(NonNullPtr<CommandList> commandList, uint8 reference);
|
||||
|
||||
// Fences
|
||||
bool (*Wait)(NonNullPtr<GPUDriver> driver);
|
||||
bool (*QueryFence)(NonNullPtr<GPUDriver> driver, NonNullPtr<Fence> fence);
|
||||
void (*ReleaseFence)(NonNullPtr<GPUDriver> driver, NonNullPtr<Fence> fence);
|
||||
|
||||
const char* Name = "Unknown";
|
||||
GPUDriver* Driver = nullptr;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user