Refactored dx12 to use c++ versions of the api and not C + various tweaks (using antigravity + gemini)
This commit is contained in:
Binary file not shown.
@@ -5,7 +5,12 @@ cbuffer RootConstants : register(b0, space0)
|
|||||||
{
|
{
|
||||||
row_major float4x4 ViewProjection;
|
row_major float4x4 ViewProjection;
|
||||||
uint BufferIndex;
|
uint BufferIndex;
|
||||||
uint _Padding[3];
|
uint TextureIndex;
|
||||||
|
uint VertexOffset; // Base vertex for indexed drawing with bindless buffers
|
||||||
|
uint _Padding; // Padding for alignment
|
||||||
|
float2 Scale; // 2D scale factor
|
||||||
|
float2 Translate; // 2D translation
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // ROOT_CONSTANTS_HLSL
|
#endif // ROOT_CONSTANTS_HLSL
|
||||||
|
|||||||
@@ -11,9 +11,8 @@ Output main(uint vertexIndex : SV_VertexID)
|
|||||||
Output output;
|
Output output;
|
||||||
|
|
||||||
// Retrieve the buffer using SM6.6 bindless syntax
|
// Retrieve the buffer using SM6.6 bindless syntax
|
||||||
// We use index 0 as the sample app doesn't pass push constants yet.
|
// Use BufferIndex from RootConstants (pushed via SetPushConstants)
|
||||||
uint bufferIndex = 0;
|
ByteAddressBuffer buffer = ResourceDescriptorHeap[BufferIndex];
|
||||||
ByteAddressBuffer buffer = ResourceDescriptorHeap[bufferIndex];
|
|
||||||
|
|
||||||
// Read position from buffer (Index * stride)
|
// Read position from buffer (Index * stride)
|
||||||
// Stride = 2 float (pos) + 4 float (color) = 6 * 4 = 24 bytes ?
|
// Stride = 2 float (pos) + 4 float (color) = 6 * 4 = 24 bytes ?
|
||||||
|
|||||||
@@ -14,6 +14,10 @@
|
|||||||
// For GET_X_LPARAM, GET_Y_LPARAM.
|
// For GET_X_LPARAM, GET_Y_LPARAM.
|
||||||
#include <windowsx.h>
|
#include <windowsx.h>
|
||||||
|
|
||||||
|
#include <imgui.h> // Need For IMGUI_IMPL_API
|
||||||
|
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
|
|
||||||
namespace Juliet::Win32
|
namespace Juliet::Win32
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
@@ -147,8 +151,14 @@ namespace Juliet::Win32
|
|||||||
|
|
||||||
LRESULT CALLBACK Win32MainWindowCallback(HWND handle, UINT message, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK Win32MainWindowCallback(HWND handle, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
if (ImGui_ImplWin32_WndProcHandler(handle, message, wParam, lParam))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT returnCode = -1;
|
LRESULT returnCode = -1;
|
||||||
|
|
||||||
|
|
||||||
// Wait until the window state is created before doing anything
|
// Wait until the window state is created before doing anything
|
||||||
auto* windowState = GetWindowStateFromHandle(handle);
|
auto* windowState = GetWindowStateFromHandle(handle);
|
||||||
if (!windowState)
|
if (!windowState)
|
||||||
|
|||||||
@@ -39,26 +39,15 @@ namespace Juliet
|
|||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
#if JULIET_DEBUG
|
|
||||||
namespace UnitTest
|
|
||||||
{
|
|
||||||
extern void TestMemoryArena();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void JulietInit(JulietInit_Flags flags)
|
void JulietInit(JulietInit_Flags flags)
|
||||||
{
|
{
|
||||||
// Mandatory systems
|
// Mandatory systems
|
||||||
MemoryArenasInit();
|
MemoryArenasInit();
|
||||||
|
|
||||||
#if JULIET_DEBUG
|
|
||||||
UnitTest::TestMemoryArena();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
InitFilesystem();
|
InitFilesystem();
|
||||||
|
|
||||||
// Optional systems
|
// Optional systems
|
||||||
if ((flags | JulietInit_Flags::Display) != JulietInit_Flags::None)
|
if ((flags & JulietInit_Flags::Display) != JulietInit_Flags::None)
|
||||||
{
|
{
|
||||||
InitializeDisplaySystem();
|
InitializeDisplaySystem();
|
||||||
IncrementSystemRefCount(JulietInit_Flags::Display);
|
IncrementSystemRefCount(JulietInit_Flags::Display);
|
||||||
|
|||||||
@@ -12,13 +12,6 @@ namespace Juliet::D3D12
|
|||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
struct D3D12Buffer
|
|
||||||
{
|
|
||||||
Internal::D3D12Descriptor Descriptor;
|
|
||||||
ID3D12Resource* Handle;
|
|
||||||
D3D12_RESOURCE_STATES CurrentState;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class D3D12BufferType : uint8
|
enum class D3D12BufferType : uint8
|
||||||
{
|
{
|
||||||
Base,
|
Base,
|
||||||
@@ -26,6 +19,30 @@ namespace Juliet::D3D12
|
|||||||
TransferUpload,
|
TransferUpload,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] const char* D3D12BufferTypeToString(D3D12BufferType type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case D3D12BufferType::Base: return "Base";
|
||||||
|
case D3D12BufferType::TransferDownload: return "TransferDownload";
|
||||||
|
case D3D12BufferType::TransferUpload: return "TransferUpload";
|
||||||
|
}
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] const char* BufferUsageToString(BufferUsage usage)
|
||||||
|
{
|
||||||
|
switch (usage)
|
||||||
|
{
|
||||||
|
case BufferUsage::None: return "None";
|
||||||
|
case BufferUsage::ConstantBuffer: return "ConstantBuffer";
|
||||||
|
case BufferUsage::StructuredBuffer: return "StructuredBuffer";
|
||||||
|
case BufferUsage::IndexBuffer: return "IndexBuffer";
|
||||||
|
case BufferUsage::VertexBuffer: return "VertexBuffer";
|
||||||
|
}
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
void DestroyBuffer(D3D12Buffer* buffer)
|
void DestroyBuffer(D3D12Buffer* buffer)
|
||||||
{
|
{
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
@@ -40,7 +57,7 @@ namespace Juliet::D3D12
|
|||||||
|
|
||||||
if (buffer->Handle)
|
if (buffer->Handle)
|
||||||
{
|
{
|
||||||
ID3D12Resource_Release(buffer->Handle);
|
buffer->Handle->Release();
|
||||||
}
|
}
|
||||||
Free(buffer);
|
Free(buffer);
|
||||||
}
|
}
|
||||||
@@ -78,6 +95,7 @@ namespace Juliet::D3D12
|
|||||||
|
|
||||||
case BufferUsage::IndexBuffer:
|
case BufferUsage::IndexBuffer:
|
||||||
case BufferUsage::StructuredBuffer:
|
case BufferUsage::StructuredBuffer:
|
||||||
|
case BufferUsage::VertexBuffer:
|
||||||
{
|
{
|
||||||
heapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
|
heapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||||
heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||||
@@ -99,8 +117,13 @@ namespace Juliet::D3D12
|
|||||||
heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||||
heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||||
initialState = D3D12_RESOURCE_STATE_GENERIC_READ;
|
initialState = D3D12_RESOURCE_STATE_GENERIC_READ;
|
||||||
|
heapFlags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
|
||||||
|
}
|
||||||
|
// heapFlags = D3D12_HEAP_FLAG_NONE; // Avoid overwriting if set above
|
||||||
|
if (heapProperties.Type == D3D12_HEAP_TYPE_GPU_UPLOAD)
|
||||||
|
{
|
||||||
|
heapFlags = D3D12_HEAP_FLAG_NONE; // Or appropriate flags
|
||||||
}
|
}
|
||||||
heapFlags = D3D12_HEAP_FLAG_NONE;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,7 +153,7 @@ namespace Juliet::D3D12
|
|||||||
|
|
||||||
D3D12_RESOURCE_DESC desc = {};
|
D3D12_RESOURCE_DESC desc = {};
|
||||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||||
desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
|
desc.Alignment = 0;
|
||||||
desc.Width = size;
|
desc.Width = size;
|
||||||
desc.Height = 1;
|
desc.Height = 1;
|
||||||
desc.DepthOrArraySize = 1;
|
desc.DepthOrArraySize = 1;
|
||||||
@@ -141,13 +164,22 @@ namespace Juliet::D3D12
|
|||||||
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||||
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||||
|
|
||||||
|
Log(LogLevel::Message, LogCategory::Graphics, "CreateBuffer: Device=%p, Size=%zu, Type=%s Use=%s", (void*)d3d12Driver->D3D12Device, size, D3D12BufferTypeToString(type), BufferUsageToString(usage));
|
||||||
ID3D12Resource* handle = nullptr;
|
ID3D12Resource* handle = nullptr;
|
||||||
HRESULT result = ID3D12Device_CreateCommittedResource(d3d12Driver->D3D12Device, &heapProperties, heapFlags,
|
HRESULT result = d3d12Driver->D3D12Device->CreateCommittedResource(&heapProperties, heapFlags,
|
||||||
&desc, initialState, nullptr, IID_ID3D12Resource,
|
&desc, initialState, nullptr,
|
||||||
reinterpret_cast<void**>(&handle));
|
IID_ID3D12Resource, reinterpret_cast<void**>(&handle));
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
LogError(d3d12Driver->D3D12Device, "Could not create buffer!", result);
|
Log(LogLevel::Error, LogCategory::Graphics, "Could not create buffer! HRESULT=0x%08X", (uint32)result);
|
||||||
|
Log(LogLevel::Error, LogCategory::Graphics, "Failed Desc: Width=%llu Layout=%d HeapType=%d", (unsigned long long)desc.Width, (int)desc.Layout, (int)heapProperties.Type);
|
||||||
|
|
||||||
|
HRESULT removeReason = d3d12Driver->D3D12Device->GetDeviceRemovedReason();
|
||||||
|
if (FAILED(removeReason))
|
||||||
|
{
|
||||||
|
Log(LogLevel::Error, LogCategory::Graphics, "Device Removed Reason: 0x%08X", (uint32)removeReason);
|
||||||
|
}
|
||||||
|
|
||||||
DestroyBuffer(buffer);
|
DestroyBuffer(buffer);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -155,6 +187,7 @@ namespace Juliet::D3D12
|
|||||||
buffer->Handle = handle;
|
buffer->Handle = handle;
|
||||||
buffer->CurrentState = initialState;
|
buffer->CurrentState = initialState;
|
||||||
buffer->Descriptor.Index = UINT32_MAX;
|
buffer->Descriptor.Index = UINT32_MAX;
|
||||||
|
buffer->Size = size;
|
||||||
|
|
||||||
if (usage == BufferUsage::ConstantBuffer || usage == BufferUsage::StructuredBuffer)
|
if (usage == BufferUsage::ConstantBuffer || usage == BufferUsage::StructuredBuffer)
|
||||||
{
|
{
|
||||||
@@ -169,25 +202,22 @@ namespace Juliet::D3D12
|
|||||||
|
|
||||||
if (usage == BufferUsage::ConstantBuffer)
|
if (usage == BufferUsage::ConstantBuffer)
|
||||||
{
|
{
|
||||||
cbvDesc.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(handle);
|
cbvDesc.BufferLocation = handle->GetGPUVirtualAddress();
|
||||||
cbvDesc.SizeInBytes = static_cast<uint32>(size);
|
cbvDesc.SizeInBytes = static_cast<uint32>(size);
|
||||||
ID3D12Device_CreateConstantBufferView(d3d12Driver->D3D12Device, &cbvDesc, cpuHandle);
|
d3d12Driver->D3D12Device->CreateConstantBufferView(&cbvDesc, cpuHandle);
|
||||||
}
|
}
|
||||||
else if (usage == BufferUsage::StructuredBuffer)
|
else if (usage == BufferUsage::StructuredBuffer)
|
||||||
{
|
{
|
||||||
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
|
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
|
||||||
|
srvDesc.Format = DXGI_FORMAT_R32_TYPELESS;
|
||||||
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
|
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
|
||||||
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||||
srvDesc.Buffer.FirstElement = 0;
|
srvDesc.Buffer.FirstElement = 0;
|
||||||
srvDesc.Buffer.NumElements = static_cast<uint32>(
|
srvDesc.Buffer.NumElements = static_cast<uint32>(size / 4);
|
||||||
size / 4); // Assuming 4 bytes stride for raw access or similar. Ideally should be provided.
|
srvDesc.Buffer.StructureByteStride = 0;
|
||||||
srvDesc.Buffer.StructureByteStride = 0; // Raw buffer for simplicity, or 4 if typed?
|
srvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_RAW;
|
||||||
// If it's a Structured Buffer, we typically need stride. For now let's assume raw ByteAddressBuffer (R32_TYPELESS) or similar if stride is 0.
|
d3d12Driver->D3D12Device->CreateShaderResourceView(handle, &srvDesc, cpuHandle);
|
||||||
// Actually, let's treat it as a ByteAddressBuffer (Raw) for most flexibility in bindless.
|
Log(LogLevel::Message, LogCategory::Graphics, " -> SRV DescriptorIndex=%u", descriptor.Index);
|
||||||
srvDesc.Format = DXGI_FORMAT_R32_TYPELESS;
|
|
||||||
srvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_RAW;
|
|
||||||
|
|
||||||
ID3D12Device_CreateShaderResourceView(d3d12Driver->D3D12Device, handle, &srvDesc, cpuHandle);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -230,7 +260,7 @@ namespace Juliet::D3D12
|
|||||||
void* ptr = nullptr;
|
void* ptr = nullptr;
|
||||||
// 0-0 range means we don't intend to read anything.
|
// 0-0 range means we don't intend to read anything.
|
||||||
D3D12_RANGE readRange = { 0, 0 };
|
D3D12_RANGE readRange = { 0, 0 };
|
||||||
if (FAILED(ID3D12Resource_Map(d3d12Buffer->Handle, 0, &readRange, &ptr)))
|
if (FAILED(d3d12Buffer->Handle->Map(0, &readRange, &ptr)))
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -240,7 +270,7 @@ namespace Juliet::D3D12
|
|||||||
void UnmapBuffer(NonNullPtr<GPUDriver> /*driver*/, NonNullPtr<GraphicsTransferBuffer> buffer)
|
void UnmapBuffer(NonNullPtr<GPUDriver> /*driver*/, NonNullPtr<GraphicsTransferBuffer> buffer)
|
||||||
{
|
{
|
||||||
auto d3d12Buffer = reinterpret_cast<D3D12Buffer*>(buffer.Get());
|
auto d3d12Buffer = reinterpret_cast<D3D12Buffer*>(buffer.Get());
|
||||||
ID3D12Resource_Unmap(d3d12Buffer->Handle, 0, nullptr);
|
d3d12Buffer->Handle->Unmap(0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 GetDescriptorIndex(NonNullPtr<GPUDriver> /*driver*/, NonNullPtr<GraphicsBuffer> buffer)
|
uint32 GetDescriptorIndex(NonNullPtr<GPUDriver> /*driver*/, NonNullPtr<GraphicsBuffer> buffer)
|
||||||
@@ -267,7 +297,7 @@ namespace Juliet::D3D12
|
|||||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST;
|
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||||
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||||
|
|
||||||
ID3D12GraphicsCommandList_ResourceBarrier(d3d12CmdList->GraphicsCommandList.CommandList, 1, &barrier);
|
d3d12CmdList->GraphicsCommandList.CommandList->ResourceBarrier(1, &barrier);
|
||||||
d3d12Dst->CurrentState = D3D12_RESOURCE_STATE_COPY_DEST;
|
d3d12Dst->CurrentState = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,7 +305,7 @@ namespace Juliet::D3D12
|
|||||||
// We assume Upload buffers are always in state GENERIC_READ or similar suitable for CopySrc.
|
// We assume Upload buffers are always in state GENERIC_READ or similar suitable for CopySrc.
|
||||||
// D3D12 Upload heaps start in GENERIC_READ and cannot transition.
|
// D3D12 Upload heaps start in GENERIC_READ and cannot transition.
|
||||||
|
|
||||||
ID3D12GraphicsCommandList_CopyBufferRegion(d3d12CmdList->GraphicsCommandList.CommandList, d3d12Dst->Handle,
|
d3d12CmdList->GraphicsCommandList.CommandList->CopyBufferRegion(d3d12Dst->Handle,
|
||||||
dstOffset, d3d12Src->Handle, srcOffset, size);
|
dstOffset, d3d12Src->Handle, srcOffset, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,7 +326,7 @@ namespace Juliet::D3D12
|
|||||||
barrier.Transition.StateAfter = neededState;
|
barrier.Transition.StateAfter = neededState;
|
||||||
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||||
|
|
||||||
ID3D12GraphicsCommandList_ResourceBarrier(d3d12CmdList->GraphicsCommandList.CommandList, 1, &barrier);
|
d3d12CmdList->GraphicsCommandList.CommandList->ResourceBarrier(1, &barrier);
|
||||||
d3d12Buffer->CurrentState = neededState;
|
d3d12Buffer->CurrentState = neededState;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <Core/Common/NonNullPtr.h>
|
||||||
#include <Core/Common/NonNullPtr.h>
|
#include <Core/Common/NonNullPtr.h>
|
||||||
#include <Graphics/GraphicsBuffer.h>
|
#include <Graphics/GraphicsBuffer.h>
|
||||||
|
#include <Graphics/D3D12/D3D12DescriptorHeap.h>
|
||||||
|
|
||||||
namespace Juliet
|
namespace Juliet
|
||||||
{
|
{
|
||||||
@@ -10,6 +12,14 @@ namespace Juliet
|
|||||||
} // namespace Juliet
|
} // namespace Juliet
|
||||||
namespace Juliet::D3D12
|
namespace Juliet::D3D12
|
||||||
{
|
{
|
||||||
|
struct D3D12Buffer
|
||||||
|
{
|
||||||
|
Internal::D3D12Descriptor Descriptor;
|
||||||
|
ID3D12Resource* Handle;
|
||||||
|
D3D12_RESOURCE_STATES CurrentState;
|
||||||
|
size_t Size;
|
||||||
|
};
|
||||||
|
|
||||||
extern GraphicsBuffer* CreateGraphicsBuffer(NonNullPtr<GPUDriver> driver, size_t size, BufferUsage usage);
|
extern GraphicsBuffer* CreateGraphicsBuffer(NonNullPtr<GPUDriver> driver, size_t size, BufferUsage usage);
|
||||||
extern void DestroyGraphicsBuffer(NonNullPtr<GraphicsBuffer> buffer);
|
extern void DestroyGraphicsBuffer(NonNullPtr<GraphicsBuffer> buffer);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#include <Core/Memory/Allocator.h>
|
#include <Core/Memory/Allocator.h>
|
||||||
#include <Graphics/D3D12/D3D12CommandList.h>
|
#include <Graphics/D3D12/D3D12CommandList.h>
|
||||||
|
#include <Graphics/D3D12/D3D12CommandList.h>
|
||||||
|
#include <Graphics/D3D12/D3D12Buffer.h>
|
||||||
#include <Graphics/D3D12/D3D12GraphicsDevice.h>
|
#include <Graphics/D3D12/D3D12GraphicsDevice.h>
|
||||||
#include <Graphics/D3D12/D3D12Synchronization.h>
|
#include <Graphics/D3D12/D3D12Synchronization.h>
|
||||||
#include <Graphics/D3D12/D3D12Utils.h>
|
#include <Graphics/D3D12/D3D12Utils.h>
|
||||||
@@ -26,15 +28,14 @@ namespace Juliet::D3D12
|
|||||||
bool CreateAllocator(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12CommandListBaseData> baseData,
|
bool CreateAllocator(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12CommandListBaseData> baseData,
|
||||||
D3D12_COMMAND_QUEUE_DESC queueDesc)
|
D3D12_COMMAND_QUEUE_DESC queueDesc)
|
||||||
{
|
{
|
||||||
HRESULT result = ID3D12Device5_CreateCommandAllocator(driver->D3D12Device, queueDesc.Type, IID_ID3D12CommandAllocator,
|
HRESULT result = driver->D3D12Device->CreateCommandAllocator(queueDesc.Type, IID_ID3D12CommandAllocator, reinterpret_cast<void**>(&baseData->Allocator));
|
||||||
reinterpret_cast<void**>(&baseData->Allocator));
|
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
AssertHR(result, "Cannot create ID3D12CommandAllocator");
|
AssertHR(result, "Cannot create ID3D12CommandAllocator");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D12CommandAllocator_Reset(baseData->Allocator);
|
baseData->Allocator->Reset();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +55,7 @@ namespace Juliet::D3D12
|
|||||||
CreateAllocator(driver, &commandList->GraphicsCommandList, queueDesc);
|
CreateAllocator(driver, &commandList->GraphicsCommandList, queueDesc);
|
||||||
ID3D12GraphicsCommandList6* d3d12GraphicsCommandList = nullptr;
|
ID3D12GraphicsCommandList6* d3d12GraphicsCommandList = nullptr;
|
||||||
HRESULT result =
|
HRESULT result =
|
||||||
ID3D12Device5_CreateCommandList1(driver->D3D12Device, queueDesc.NodeMask, queueDesc.Type,
|
driver->D3D12Device->CreateCommandList1(queueDesc.NodeMask, queueDesc.Type,
|
||||||
D3D12_COMMAND_LIST_FLAG_NONE, IID_ID3D12GraphicsCommandList6,
|
D3D12_COMMAND_LIST_FLAG_NONE, IID_ID3D12GraphicsCommandList6,
|
||||||
reinterpret_cast<void**>(&d3d12GraphicsCommandList));
|
reinterpret_cast<void**>(&d3d12GraphicsCommandList));
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
@@ -65,8 +66,8 @@ namespace Juliet::D3D12
|
|||||||
}
|
}
|
||||||
|
|
||||||
commandList->GraphicsCommandList.CommandList = d3d12GraphicsCommandList;
|
commandList->GraphicsCommandList.CommandList = d3d12GraphicsCommandList;
|
||||||
ID3D12GraphicsCommandList6_SetName(d3d12GraphicsCommandList, wide_str.c_str());
|
d3d12GraphicsCommandList->SetName(wide_str.c_str());
|
||||||
ID3D12GraphicsCommandList6_Reset(d3d12GraphicsCommandList, commandList->GraphicsCommandList.Allocator, nullptr);
|
d3d12GraphicsCommandList->Reset(commandList->GraphicsCommandList.Allocator, nullptr);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -75,7 +76,7 @@ namespace Juliet::D3D12
|
|||||||
CreateAllocator(driver, &commandList->ComputeCommandList, queueDesc);
|
CreateAllocator(driver, &commandList->ComputeCommandList, queueDesc);
|
||||||
ID3D12GraphicsCommandList6* d3d12GraphicsCommandList = nullptr;
|
ID3D12GraphicsCommandList6* d3d12GraphicsCommandList = nullptr;
|
||||||
HRESULT result =
|
HRESULT result =
|
||||||
ID3D12Device5_CreateCommandList1(driver->D3D12Device, queueDesc.NodeMask, queueDesc.Type,
|
driver->D3D12Device->CreateCommandList1(queueDesc.NodeMask, queueDesc.Type,
|
||||||
D3D12_COMMAND_LIST_FLAG_NONE, IID_ID3D12GraphicsCommandList6,
|
D3D12_COMMAND_LIST_FLAG_NONE, IID_ID3D12GraphicsCommandList6,
|
||||||
reinterpret_cast<void**>(&d3d12GraphicsCommandList));
|
reinterpret_cast<void**>(&d3d12GraphicsCommandList));
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
@@ -86,8 +87,8 @@ namespace Juliet::D3D12
|
|||||||
}
|
}
|
||||||
|
|
||||||
commandList->ComputeCommandList.CommandList = d3d12GraphicsCommandList;
|
commandList->ComputeCommandList.CommandList = d3d12GraphicsCommandList;
|
||||||
ID3D12GraphicsCommandList6_SetName(d3d12GraphicsCommandList, wide_str.c_str());
|
d3d12GraphicsCommandList->SetName(wide_str.c_str());
|
||||||
ID3D12GraphicsCommandList6_Reset(d3d12GraphicsCommandList, commandList->ComputeCommandList.Allocator, nullptr);
|
d3d12GraphicsCommandList->Reset(commandList->ComputeCommandList.Allocator, nullptr);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -95,9 +96,8 @@ namespace Juliet::D3D12
|
|||||||
{
|
{
|
||||||
CreateAllocator(driver, &commandList->CopyCommandList, queueDesc);
|
CreateAllocator(driver, &commandList->CopyCommandList, queueDesc);
|
||||||
ID3D12GraphicsCommandList* d3d12CopyCommandList = nullptr;
|
ID3D12GraphicsCommandList* d3d12CopyCommandList = nullptr;
|
||||||
HRESULT result = ID3D12Device5_CreateCommandList1(driver->D3D12Device, queueDesc.NodeMask, queueDesc.Type,
|
HRESULT result = driver->D3D12Device->CreateCommandList1(queueDesc.NodeMask, queueDesc.Type,
|
||||||
D3D12_COMMAND_LIST_FLAG_NONE, IID_ID3D12GraphicsCommandList,
|
D3D12_COMMAND_LIST_FLAG_NONE, IID_ID3D12GraphicsCommandList, reinterpret_cast<void**>(&d3d12CopyCommandList));
|
||||||
reinterpret_cast<void**>(&d3d12CopyCommandList));
|
|
||||||
|
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
@@ -105,8 +105,8 @@ namespace Juliet::D3D12
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
commandList->CopyCommandList.CommandList = d3d12CopyCommandList;
|
commandList->CopyCommandList.CommandList = d3d12CopyCommandList;
|
||||||
ID3D12GraphicsCommandList_SetName(d3d12CopyCommandList, wide_str.c_str());
|
d3d12CopyCommandList->SetName(wide_str.c_str());
|
||||||
ID3D12GraphicsCommandList_Reset(d3d12CopyCommandList, commandList->CopyCommandList.Allocator, nullptr);
|
d3d12CopyCommandList->Reset(commandList->CopyCommandList.Allocator, nullptr);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -227,30 +227,21 @@ namespace Juliet::D3D12
|
|||||||
barrierDesc.Transition.pResource = subresource->Parent->Resource;
|
barrierDesc.Transition.pResource = subresource->Parent->Resource;
|
||||||
barrierDesc.Transition.Subresource = subresource->Index;
|
barrierDesc.Transition.Subresource = subresource->Index;
|
||||||
|
|
||||||
ID3D12GraphicsCommandList_ResourceBarrier(d3d12CommandList->GraphicsCommandList.CommandList, 1, &barrierDesc);
|
d3d12CommandList->GraphicsCommandList.CommandList->ResourceBarrier(1, &barrierDesc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify the command buffer that we have completed recording
|
// Notify the command buffer that we have completed recording
|
||||||
HRESULT result = ID3D12GraphicsCommandList_Close(d3d12CommandList->GraphicsCommandList.CommandList);
|
HRESULT result = d3d12CommandList->GraphicsCommandList.CommandList->Close();
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
LogError(d3d12Driver->D3D12Device, "Failed to close command list!", result);
|
LogError(d3d12Driver->D3D12Device, "Failed to close command list!", result);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D12CommandList* commandLists[1];
|
ID3D12CommandList* ppCommandLists[] = { d3d12CommandList->GraphicsCommandList.CommandList };
|
||||||
result = ID3D12GraphicsCommandList_QueryInterface(d3d12CommandList->GraphicsCommandList.CommandList,
|
|
||||||
IID_ID3D12CommandList, reinterpret_cast<void**>(&commandLists[0]));
|
|
||||||
if (FAILED(result))
|
|
||||||
{
|
|
||||||
LogError(d3d12Driver->D3D12Device, "Failed to convert command list!", result);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Submit the command list to the queue
|
// Submit the command list to the queue
|
||||||
ID3D12CommandQueue_ExecuteCommandLists(d3d12Driver->GraphicsQueue, 1, commandLists);
|
d3d12Driver->GraphicsQueue->ExecuteCommandLists(1, ppCommandLists);
|
||||||
|
|
||||||
ID3D12CommandList_Release(commandLists[0]);
|
|
||||||
|
|
||||||
// Acquire a fence and set it to the in-flight fence
|
// Acquire a fence and set it to the in-flight fence
|
||||||
d3d12CommandList->InFlightFence = Internal::AcquireFence(d3d12Driver);
|
d3d12CommandList->InFlightFence = Internal::AcquireFence(d3d12Driver);
|
||||||
@@ -260,7 +251,7 @@ namespace Juliet::D3D12
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mark that a fence should be signaled after command list execution
|
// Mark that a fence should be signaled after command list execution
|
||||||
result = ID3D12CommandQueue_Signal(d3d12Driver->GraphicsQueue, d3d12CommandList->InFlightFence->Handle, D3D12_FENCE_SIGNAL_VALUE);
|
result = d3d12Driver->GraphicsQueue->Signal(d3d12CommandList->InFlightFence->Handle, D3D12_FENCE_SIGNAL_VALUE);
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
LogError(d3d12Driver->D3D12Device, "Failed to enqueue fence signal!", result);
|
LogError(d3d12Driver->D3D12Device, "Failed to enqueue fence signal!", result);
|
||||||
@@ -299,14 +290,13 @@ namespace Juliet::D3D12
|
|||||||
presentFlags = DXGI_PRESENT_ALLOW_TEARING;
|
presentFlags = DXGI_PRESENT_ALLOW_TEARING;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = IDXGISwapChain_Present(windowData->SwapChain, syncInterval, presentFlags);
|
result = windowData->SwapChain->Present(syncInterval, presentFlags);
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D12Resource_Release(
|
windowData->SwapChainTextureContainers[presentData->SwapChainImageIndex].ActiveTexture->Resource->Release();
|
||||||
windowData->SwapChainTextureContainers[presentData->SwapChainImageIndex].ActiveTexture->Resource);
|
|
||||||
|
|
||||||
windowData->InFlightFences[windowData->WindowFrameCounter] = reinterpret_cast<Fence*>(d3d12CommandList->InFlightFence);
|
windowData->InFlightFences[windowData->WindowFrameCounter] = reinterpret_cast<Fence*>(d3d12CommandList->InFlightFence);
|
||||||
d3d12CommandList->InFlightFence->ReferenceCount += 1;
|
d3d12CommandList->InFlightFence->ReferenceCount += 1;
|
||||||
@@ -317,7 +307,7 @@ namespace Juliet::D3D12
|
|||||||
// Check for cleanups
|
// Check for cleanups
|
||||||
for (int32 i = d3d12Driver->SubmittedCommandListCount - 1; i >= 0; i -= 1)
|
for (int32 i = d3d12Driver->SubmittedCommandListCount - 1; i >= 0; i -= 1)
|
||||||
{
|
{
|
||||||
uint64 fenceValue = ID3D12Fence_GetCompletedValue(d3d12Driver->SubmittedCommandLists[i]->InFlightFence->Handle);
|
uint64 fenceValue = d3d12Driver->SubmittedCommandLists[i]->InFlightFence->Handle->GetCompletedValue();
|
||||||
if (fenceValue == D3D12_FENCE_SIGNAL_VALUE)
|
if (fenceValue == D3D12_FENCE_SIGNAL_VALUE)
|
||||||
{
|
{
|
||||||
success &= Internal::CleanCommandList(d3d12Driver, d3d12Driver->SubmittedCommandLists[i], false);
|
success &= Internal::CleanCommandList(d3d12Driver, d3d12Driver->SubmittedCommandLists[i], false);
|
||||||
@@ -342,7 +332,7 @@ namespace Juliet::D3D12
|
|||||||
d3d12Viewport.Height = viewPort.Height;
|
d3d12Viewport.Height = viewPort.Height;
|
||||||
d3d12Viewport.MinDepth = viewPort.MinDepth;
|
d3d12Viewport.MinDepth = viewPort.MinDepth;
|
||||||
d3d12Viewport.MaxDepth = viewPort.MaxDepth;
|
d3d12Viewport.MaxDepth = viewPort.MaxDepth;
|
||||||
ID3D12GraphicsCommandList_RSSetViewports(d3d12CommandList->GraphicsCommandList.CommandList, 1, &d3d12Viewport);
|
d3d12CommandList->GraphicsCommandList.CommandList->RSSetViewports(1, &d3d12Viewport);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetScissorRect(NonNullPtr<CommandList> commandList, const Rectangle& rectangle)
|
void SetScissorRect(NonNullPtr<CommandList> commandList, const Rectangle& rectangle)
|
||||||
@@ -353,20 +343,48 @@ namespace Juliet::D3D12
|
|||||||
scissorRect.top = rectangle.Y;
|
scissorRect.top = rectangle.Y;
|
||||||
scissorRect.right = rectangle.X + rectangle.Width;
|
scissorRect.right = rectangle.X + rectangle.Width;
|
||||||
scissorRect.bottom = rectangle.Y + rectangle.Height;
|
scissorRect.bottom = rectangle.Y + rectangle.Height;
|
||||||
ID3D12GraphicsCommandList_RSSetScissorRects(d3d12CommandList->GraphicsCommandList.CommandList, 1, &scissorRect);
|
d3d12CommandList->GraphicsCommandList.CommandList->RSSetScissorRects(1, &scissorRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetBlendConstants(NonNullPtr<CommandList> commandList, FColor blendConstants)
|
void SetBlendConstants(NonNullPtr<CommandList> commandList, FColor blendConstants)
|
||||||
{
|
{
|
||||||
auto* d3d12CommandList = reinterpret_cast<D3D12CommandList*>(commandList.Get());
|
auto* d3d12CommandList = reinterpret_cast<D3D12CommandList*>(commandList.Get());
|
||||||
FLOAT blendFactor[4] = { blendConstants.R, blendConstants.G, blendConstants.B, blendConstants.A };
|
FLOAT blendFactor[4] = { blendConstants.R, blendConstants.G, blendConstants.B, blendConstants.A };
|
||||||
ID3D12GraphicsCommandList_OMSetBlendFactor(d3d12CommandList->GraphicsCommandList.CommandList, blendFactor);
|
d3d12CommandList->GraphicsCommandList.CommandList->OMSetBlendFactor(blendFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetStencilReference(NonNullPtr<CommandList> commandList, uint8 reference)
|
void SetStencilReference(NonNullPtr<CommandList> commandList, uint8 reference)
|
||||||
{
|
{
|
||||||
auto* d3d12CommandList = reinterpret_cast<D3D12CommandList*>(commandList.Get());
|
auto* d3d12CommandList = reinterpret_cast<D3D12CommandList*>(commandList.Get());
|
||||||
ID3D12GraphicsCommandList_OMSetStencilRef(d3d12CommandList->GraphicsCommandList.CommandList, reference);
|
d3d12CommandList->GraphicsCommandList.CommandList->OMSetStencilRef(reference);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetIndexBuffer(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> buffer, IndexFormat format)
|
||||||
|
{
|
||||||
|
auto* d3d12CommandList = reinterpret_cast<D3D12CommandList*>(commandList.Get());
|
||||||
|
auto* d3d12Buffer = reinterpret_cast<D3D12Buffer*>(buffer.Get());
|
||||||
|
|
||||||
|
// Transition to INDEX_BUFFER state if needed
|
||||||
|
if (d3d12Buffer->CurrentState != D3D12_RESOURCE_STATE_INDEX_BUFFER)
|
||||||
|
{
|
||||||
|
D3D12_RESOURCE_BARRIER barrier = {};
|
||||||
|
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||||
|
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||||
|
barrier.Transition.pResource = d3d12Buffer->Handle;
|
||||||
|
barrier.Transition.StateBefore = d3d12Buffer->CurrentState;
|
||||||
|
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_INDEX_BUFFER;
|
||||||
|
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||||
|
|
||||||
|
d3d12CommandList->GraphicsCommandList.CommandList->ResourceBarrier(1, &barrier);
|
||||||
|
d3d12Buffer->CurrentState = D3D12_RESOURCE_STATE_INDEX_BUFFER;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12_INDEX_BUFFER_VIEW ibView;
|
||||||
|
ibView.BufferLocation = d3d12Buffer->Handle->GetGPUVirtualAddress();
|
||||||
|
ibView.SizeInBytes = static_cast<UINT>(d3d12Buffer->Size);
|
||||||
|
ibView.Format = (format == IndexFormat::UInt16) ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT;
|
||||||
|
|
||||||
|
d3d12CommandList->GraphicsCommandList.CommandList->IASetIndexBuffer(&ibView);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetPushConstants(NonNullPtr<CommandList> commandList, ShaderStage /*stage*/, uint32 rootParameterIndex,
|
void SetPushConstants(NonNullPtr<CommandList> commandList, ShaderStage /*stage*/, uint32 rootParameterIndex,
|
||||||
@@ -374,7 +392,7 @@ namespace Juliet::D3D12
|
|||||||
{
|
{
|
||||||
auto d3d12CommandList = reinterpret_cast<D3D12CommandList*>(commandList.Get());
|
auto d3d12CommandList = reinterpret_cast<D3D12CommandList*>(commandList.Get());
|
||||||
// For now we assume Graphics Root Signature. Compute support would need a check or separate function.
|
// For now we assume Graphics Root Signature. Compute support would need a check or separate function.
|
||||||
ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(d3d12CommandList->GraphicsCommandList.CommandList,
|
d3d12CommandList->GraphicsCommandList.CommandList->SetGraphicsRoot32BitConstants(
|
||||||
rootParameterIndex, numConstants, constants, 0);
|
rootParameterIndex, numConstants, constants, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,7 +414,7 @@ namespace Juliet::D3D12
|
|||||||
heaps[0] = viewHeap->Handle;
|
heaps[0] = viewHeap->Handle;
|
||||||
heaps[1] = samplerHeap->Handle;
|
heaps[1] = samplerHeap->Handle;
|
||||||
|
|
||||||
ID3D12GraphicsCommandList_SetDescriptorHeaps(commandList->GraphicsCommandList.CommandList, 2, heaps);
|
commandList->GraphicsCommandList.CommandList->SetDescriptorHeaps(2, heaps);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DestroyCommandList(NonNullPtr<D3D12CommandList> commandList)
|
void DestroyCommandList(NonNullPtr<D3D12CommandList> commandList)
|
||||||
@@ -404,10 +422,10 @@ namespace Juliet::D3D12
|
|||||||
// TODO : Handle other kind of command list (copy compute)
|
// TODO : Handle other kind of command list (copy compute)
|
||||||
if (commandList->GraphicsCommandList.CommandList)
|
if (commandList->GraphicsCommandList.CommandList)
|
||||||
{
|
{
|
||||||
ID3D12GraphicsCommandList_Release(commandList->GraphicsCommandList.CommandList);
|
commandList->GraphicsCommandList.CommandList->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D12CommandAllocator_Release(commandList->GraphicsCommandList.Allocator);
|
commandList->GraphicsCommandList.Allocator->Release();
|
||||||
|
|
||||||
SafeFree(commandList->PresentDatas);
|
SafeFree(commandList->PresentDatas);
|
||||||
SafeFree(commandList->UsedTextures);
|
SafeFree(commandList->UsedTextures);
|
||||||
@@ -420,14 +438,14 @@ namespace Juliet::D3D12
|
|||||||
// No more presentation data
|
// No more presentation data
|
||||||
commandList->PresentDataCount = 0;
|
commandList->PresentDataCount = 0;
|
||||||
|
|
||||||
HRESULT result = ID3D12CommandAllocator_Reset(commandList->GraphicsCommandList.Allocator);
|
HRESULT result = commandList->GraphicsCommandList.Allocator->Reset();
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
LogError(driver->D3D12Device, "Could not reset command allocator", result);
|
LogError(driver->D3D12Device, "Could not reset command allocator", result);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = ID3D12GraphicsCommandList_Reset(commandList->GraphicsCommandList.CommandList,
|
result = commandList->GraphicsCommandList.CommandList->Reset(
|
||||||
commandList->GraphicsCommandList.Allocator, nullptr);
|
commandList->GraphicsCommandList.Allocator, nullptr);
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ namespace Juliet::D3D12
|
|||||||
extern void SetBlendConstants(NonNullPtr<CommandList> commandList, FColor blendConstants);
|
extern void SetBlendConstants(NonNullPtr<CommandList> commandList, FColor blendConstants);
|
||||||
extern void SetBlendConstants(NonNullPtr<CommandList> commandList, FColor blendConstants);
|
extern void SetBlendConstants(NonNullPtr<CommandList> commandList, FColor blendConstants);
|
||||||
extern void SetStencilReference(NonNullPtr<CommandList> commandList, uint8 reference);
|
extern void SetStencilReference(NonNullPtr<CommandList> commandList, uint8 reference);
|
||||||
|
extern void SetIndexBuffer(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> buffer, IndexFormat format);
|
||||||
extern void SetPushConstants(NonNullPtr<CommandList> commandList, ShaderStage stage, uint32 rootParameterIndex, uint32 numConstants, const void* constants);
|
extern void SetPushConstants(NonNullPtr<CommandList> commandList, ShaderStage stage, uint32 rootParameterIndex, uint32 numConstants, const void* constants);
|
||||||
|
|
||||||
namespace Internal
|
namespace Internal
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace Juliet::D3D12::Internal
|
|||||||
heapDesc.NodeMask = 0;
|
heapDesc.NodeMask = 0;
|
||||||
|
|
||||||
HRESULT result =
|
HRESULT result =
|
||||||
ID3D12Device_CreateDescriptorHeap(driver->D3D12Device, &heapDesc, IID_ID3D12DescriptorHeap, (void**)&handle);
|
driver->D3D12Device->CreateDescriptorHeap(&heapDesc, IID_ID3D12DescriptorHeap, (void**)&handle);
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
LogError(driver->D3D12Device, "Failed to create descriptor heap!", result);
|
LogError(driver->D3D12Device, "Failed to create descriptor heap!", result);
|
||||||
@@ -40,11 +40,11 @@ namespace Juliet::D3D12::Internal
|
|||||||
heap->HeapType = type;
|
heap->HeapType = type;
|
||||||
heap->MaxDescriptors = count;
|
heap->MaxDescriptors = count;
|
||||||
heap->Staging = isStaging;
|
heap->Staging = isStaging;
|
||||||
heap->DescriptorSize = ID3D12Device_GetDescriptorHandleIncrementSize(driver->D3D12Device, type);
|
heap->DescriptorSize = driver->D3D12Device->GetDescriptorHandleIncrementSize(type);
|
||||||
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(handle, &heap->DescriptorHeapCPUStart);
|
heap->DescriptorHeapCPUStart = handle->GetCPUDescriptorHandleForHeapStart();
|
||||||
if (!isStaging)
|
if (!isStaging)
|
||||||
{
|
{
|
||||||
ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(handle, &heap->DescriptorHeapGPUStart);
|
heap->DescriptorHeapGPUStart = handle->GetGPUDescriptorHandleForHeapStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
return heap;
|
return heap;
|
||||||
@@ -54,7 +54,7 @@ namespace Juliet::D3D12::Internal
|
|||||||
{
|
{
|
||||||
if (heap->Handle)
|
if (heap->Handle)
|
||||||
{
|
{
|
||||||
ID3D12DescriptorHeap_Release(heap->Handle);
|
heap->Handle->Release();
|
||||||
}
|
}
|
||||||
SafeFree(heap->FreeIndices);
|
SafeFree(heap->FreeIndices);
|
||||||
Free(heap.Get());
|
Free(heap.Get());
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ namespace Juliet::D3D12
|
|||||||
bool CheckResourceTypeTier(ID3D12Device5* device)
|
bool CheckResourceTypeTier(ID3D12Device5* device)
|
||||||
{
|
{
|
||||||
D3D12_FEATURE_DATA_D3D12_OPTIONS options = {};
|
D3D12_FEATURE_DATA_D3D12_OPTIONS options = {};
|
||||||
HRESULT result = ID3D12Device5_CheckFeatureSupport(device, D3D12_FEATURE_D3D12_OPTIONS, &options,
|
HRESULT result =
|
||||||
sizeof(D3D12_FEATURE_DATA_D3D12_OPTIONS));
|
device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(D3D12_FEATURE_DATA_D3D12_OPTIONS));
|
||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
if (options.ResourceBindingTier < D3D12_RESOURCE_BINDING_TIER_3)
|
if (options.ResourceBindingTier < D3D12_RESOURCE_BINDING_TIER_3)
|
||||||
@@ -83,8 +83,8 @@ namespace Juliet::D3D12
|
|||||||
for (auto allModelVersion : allModelVersions)
|
for (auto allModelVersion : allModelVersions)
|
||||||
{
|
{
|
||||||
shaderModel.HighestShaderModel = allModelVersion;
|
shaderModel.HighestShaderModel = allModelVersion;
|
||||||
HRESULT result = ID3D12Device5_CheckFeatureSupport(device, D3D12_FEATURE_SHADER_MODEL, &shaderModel,
|
HRESULT result = device->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &shaderModel,
|
||||||
sizeof(D3D12_FEATURE_DATA_SHADER_MODEL));
|
sizeof(D3D12_FEATURE_DATA_SHADER_MODEL));
|
||||||
if (result != E_INVALIDARG)
|
if (result != E_INVALIDARG)
|
||||||
{
|
{
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
@@ -142,40 +142,40 @@ namespace Juliet::D3D12
|
|||||||
|
|
||||||
// Can query the 1.4 factory ?
|
// Can query the 1.4 factory ?
|
||||||
IDXGIFactory4* factory4 = nullptr;
|
IDXGIFactory4* factory4 = nullptr;
|
||||||
result = IDXGIFactory1_QueryInterface(factory1, IID_IDXGIFactory4, reinterpret_cast<void**>(&factory4));
|
result = factory1->QueryInterface(IID_IDXGIFactory4, reinterpret_cast<void**>(&factory4));
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
IDXGIFactory1_Release(factory1);
|
factory1->Release();
|
||||||
Log(LogLevel::Warning, LogCategory::Graphics, "DX12: Failed to query DXGI1.4.");
|
Log(LogLevel::Warning, LogCategory::Graphics, "DX12: Failed to query DXGI1.4.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
IDXGIFactory4_Release(factory4);
|
factory4->Release();
|
||||||
|
|
||||||
// Check for 1.6. (It's not mandatory).
|
// Check for 1.6. (It's not mandatory).
|
||||||
IDXGIAdapter1* adapter = nullptr;
|
IDXGIAdapter1* adapter = nullptr;
|
||||||
IDXGIFactory6* factory6 = nullptr;
|
IDXGIFactory6* factory6 = nullptr;
|
||||||
result = IDXGIFactory1_QueryInterface(factory1, IID_IDXGIFactory6, reinterpret_cast<void**>(&factory6));
|
result = factory1->QueryInterface(IID_IDXGIFactory6, reinterpret_cast<void**>(&factory6));
|
||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
result = IDXGIFactory6_EnumAdapterByGpuPreference(factory6, 0, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE,
|
result = factory6->EnumAdapterByGpuPreference(0, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE,
|
||||||
IID_IDXGIAdapter1, reinterpret_cast<void**>(&adapter));
|
IID_IDXGIAdapter1, reinterpret_cast<void**>(&adapter));
|
||||||
IDXGIFactory6_Release(factory6);
|
factory6->Release();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = IDXGIFactory1_EnumAdapters1(factory1, 0, &adapter);
|
result = factory1->EnumAdapters1(0, &adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
Log(LogLevel::Warning, LogCategory::Graphics, "DX12: Failed to find an adapter for D3D12.");
|
Log(LogLevel::Warning, LogCategory::Graphics, "DX12: Failed to find an adapter for D3D12.");
|
||||||
|
|
||||||
IDXGIFactory1_Release(factory1);
|
factory1->Release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D12Device5* device = nullptr;
|
ID3D12Device5* device = nullptr;
|
||||||
result = D3D12CreateDeviceFuncPtr(reinterpret_cast<IUnknown*>(adapter), kD3DFeatureLevel, IID_ID3D12Device5,
|
result = D3D12CreateDeviceFuncPtr(static_cast<IUnknown*>(adapter), kD3DFeatureLevel, IID_ID3D12Device5,
|
||||||
reinterpret_cast<void**>(&device));
|
reinterpret_cast<void**>(&device));
|
||||||
|
|
||||||
bool driverIsValid = true;
|
bool driverIsValid = true;
|
||||||
@@ -184,7 +184,7 @@ namespace Juliet::D3D12
|
|||||||
driverIsValid &= CheckShaderModel(device);
|
driverIsValid &= CheckShaderModel(device);
|
||||||
driverIsValid &= CheckResourceTypeTier(device);
|
driverIsValid &= CheckResourceTypeTier(device);
|
||||||
|
|
||||||
ID3D12Device5_Release(device);
|
device->Release();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -192,8 +192,8 @@ namespace Juliet::D3D12
|
|||||||
"DX12: Failed to create a D3D12Device with feature level %s.", kD3DFeatureLevelStr);
|
"DX12: Failed to create a D3D12Device with feature level %s.", kD3DFeatureLevelStr);
|
||||||
driverIsValid = false;
|
driverIsValid = false;
|
||||||
}
|
}
|
||||||
IDXGIAdapter1_Release(adapter);
|
adapter->Release();
|
||||||
IDXGIFactory1_Release(factory1);
|
factory1->Release();
|
||||||
|
|
||||||
return driverIsValid;
|
return driverIsValid;
|
||||||
}
|
}
|
||||||
@@ -206,7 +206,7 @@ namespace Juliet::D3D12
|
|||||||
}
|
}
|
||||||
if (rootSignature->Handle)
|
if (rootSignature->Handle)
|
||||||
{
|
{
|
||||||
ID3D12RootSignature_Release(rootSignature->Handle);
|
rootSignature->Handle->Release();
|
||||||
}
|
}
|
||||||
Free(rootSignature);
|
Free(rootSignature);
|
||||||
}
|
}
|
||||||
@@ -272,9 +272,10 @@ namespace Juliet::D3D12
|
|||||||
{
|
{
|
||||||
if (errorBlob)
|
if (errorBlob)
|
||||||
{
|
{
|
||||||
auto errorBuffer = ID3D10Blob_GetBufferPointer(errorBlob);
|
auto errorBuffer = errorBlob->GetBufferPointer();
|
||||||
LogError(LogCategory::Graphics, "Failed to serialize RootSignature: %s", errorBuffer);
|
LogError(LogCategory::Graphics, "Failed to serialize RootSignature: %s", errorBuffer);
|
||||||
ID3D10Blob_Release(errorBlob);
|
|
||||||
|
errorBlob->Release();
|
||||||
}
|
}
|
||||||
DestroyGraphicsRootSignature(d3d12GraphicsRootSignature);
|
DestroyGraphicsRootSignature(d3d12GraphicsRootSignature);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -282,16 +283,16 @@ namespace Juliet::D3D12
|
|||||||
|
|
||||||
// Create the root signature
|
// Create the root signature
|
||||||
ID3D12RootSignature* rootSignature;
|
ID3D12RootSignature* rootSignature;
|
||||||
res = ID3D12Device_CreateRootSignature(d3d12Driver->D3D12Device, 0, ID3D10Blob_GetBufferPointer(serializedRootSignature),
|
res = d3d12Driver->D3D12Device->CreateRootSignature(0, serializedRootSignature->GetBufferPointer(),
|
||||||
ID3D10Blob_GetBufferSize(serializedRootSignature),
|
serializedRootSignature->GetBufferSize(), IID_ID3D12RootSignature,
|
||||||
IID_ID3D12RootSignature, reinterpret_cast<void**>(&rootSignature));
|
reinterpret_cast<void**>(&rootSignature));
|
||||||
if (FAILED(res))
|
if (FAILED(res))
|
||||||
{
|
{
|
||||||
if (errorBlob)
|
if (errorBlob)
|
||||||
{
|
{
|
||||||
LogError(LogCategory::Graphics, "Failed to create RootSignature: %s",
|
LogError(LogCategory::Graphics, "Failed to create RootSignature: %s",
|
||||||
(const char*)ID3D10Blob_GetBufferPointer(errorBlob));
|
(const char*)errorBlob->GetBufferPointer());
|
||||||
ID3D10Blob_Release(errorBlob);
|
errorBlob->Release();
|
||||||
}
|
}
|
||||||
DestroyGraphicsRootSignature(d3d12GraphicsRootSignature);
|
DestroyGraphicsRootSignature(d3d12GraphicsRootSignature);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -332,12 +333,9 @@ namespace Juliet::D3D12
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IDXGIInfoQueue_SetBreakOnSeverity(driver->DXGIInfoQueue, DXGI_DEBUG_ALL,
|
driver->DXGIInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, TRUE);
|
||||||
DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, TRUE);
|
driver->DXGIInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, TRUE);
|
||||||
IDXGIInfoQueue_SetBreakOnSeverity(driver->DXGIInfoQueue, DXGI_DEBUG_ALL,
|
driver->DXGIInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_WARNING, TRUE);
|
||||||
DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, TRUE);
|
|
||||||
IDXGIInfoQueue_SetBreakOnSeverity(driver->DXGIInfoQueue, DXGI_DEBUG_ALL,
|
|
||||||
DXGI_INFO_QUEUE_MESSAGE_SEVERITY_WARNING, TRUE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -346,9 +344,9 @@ namespace Juliet::D3D12
|
|||||||
{
|
{
|
||||||
if (driver->DXGIDebug)
|
if (driver->DXGIDebug)
|
||||||
{
|
{
|
||||||
IDXGIDebug_ReportLiveObjects(driver->DXGIDebug, DXGI_DEBUG_ALL,
|
driver->DXGIDebug->ReportLiveObjects(DXGI_DEBUG_ALL, static_cast<DXGI_DEBUG_RLO_FLAGS>(
|
||||||
static_cast<DXGI_DEBUG_RLO_FLAGS>(DXGI_DEBUG_RLO_SUMMARY | DXGI_DEBUG_RLO_DETAIL));
|
DXGI_DEBUG_RLO_SUMMARY | DXGI_DEBUG_RLO_DETAIL));
|
||||||
IDXGIDebug_Release(driver->DXGIDebug);
|
driver->DXGIDebug->Release();
|
||||||
driver->DXGIDebug = nullptr;
|
driver->DXGIDebug = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,7 +378,7 @@ namespace Juliet::D3D12
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D12Debug1_EnableDebugLayer(driver->D3D12Debug);
|
driver->D3D12Debug->EnableDebugLayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InitializeD3D12DebugInfoQueue(NonNullPtr<D3D12Driver> driver)
|
bool InitializeD3D12DebugInfoQueue(NonNullPtr<D3D12Driver> driver)
|
||||||
@@ -388,8 +386,7 @@ namespace Juliet::D3D12
|
|||||||
ID3D12InfoQueue* infoQueue = nullptr;
|
ID3D12InfoQueue* infoQueue = nullptr;
|
||||||
D3D12_MESSAGE_SEVERITY severities[] = { D3D12_MESSAGE_SEVERITY_INFO };
|
D3D12_MESSAGE_SEVERITY severities[] = { D3D12_MESSAGE_SEVERITY_INFO };
|
||||||
|
|
||||||
HRESULT result =
|
HRESULT result = driver->D3D12Device->QueryInterface(IID_ID3D12InfoQueue, reinterpret_cast<void**>(&infoQueue));
|
||||||
ID3D12Device_QueryInterface(driver->D3D12Device, IID_ID3D12InfoQueue, reinterpret_cast<void**>(&infoQueue));
|
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
LogError(driver->D3D12Device, "Failed to convert ID3D12Device to ID3D12InfoQueue", result);
|
LogError(driver->D3D12Device, "Failed to convert ID3D12Device to ID3D12InfoQueue", result);
|
||||||
@@ -399,14 +396,13 @@ namespace Juliet::D3D12
|
|||||||
D3D12_INFO_QUEUE_FILTER filter = {};
|
D3D12_INFO_QUEUE_FILTER filter = {};
|
||||||
filter.DenyList.NumSeverities = 1;
|
filter.DenyList.NumSeverities = 1;
|
||||||
filter.DenyList.pSeverityList = severities;
|
filter.DenyList.pSeverityList = severities;
|
||||||
ID3D12InfoQueue_PushStorageFilter(infoQueue, &filter);
|
infoQueue->PushStorageFilter(&filter);
|
||||||
ID3D12InfoQueue_SetBreakOnSeverity(infoQueue, D3D12_MESSAGE_SEVERITY_CORRUPTION, true);
|
// infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_CORRUPTION, true);
|
||||||
ID3D12InfoQueue_Release(infoQueue);
|
infoQueue->Release();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ID3D12InfoQueue1_SUPPORTED
|
|
||||||
void WINAPI OnD3D12DebugInfoMsg(D3D12_MESSAGE_CATEGORY category, D3D12_MESSAGE_SEVERITY severity,
|
void WINAPI OnD3D12DebugInfoMsg(D3D12_MESSAGE_CATEGORY category, D3D12_MESSAGE_SEVERITY severity,
|
||||||
D3D12_MESSAGE_ID id, LPCSTR description, void* /*context*/)
|
D3D12_MESSAGE_ID id, LPCSTR description, void* /*context*/)
|
||||||
{
|
{
|
||||||
@@ -451,19 +447,16 @@ namespace Juliet::D3D12
|
|||||||
{
|
{
|
||||||
// Only supported on Win 11 apparently
|
// Only supported on Win 11 apparently
|
||||||
ID3D12InfoQueue1* infoQueue = nullptr;
|
ID3D12InfoQueue1* infoQueue = nullptr;
|
||||||
HRESULT result =
|
HRESULT result = driver->D3D12Device->QueryInterface(IID_ID3D12InfoQueue1, reinterpret_cast<void**>(&infoQueue));
|
||||||
ID3D12Device5_QueryInterface(driver->D3D12Device, IID_ID3D12InfoQueue1, reinterpret_cast<void**>(&infoQueue));
|
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D12InfoQueue1_RegisterMessageCallback(infoQueue, OnD3D12DebugInfoMsg, D3D12_MESSAGE_CALLBACK_FLAG_NONE,
|
infoQueue->RegisterMessageCallback(OnD3D12DebugInfoMsg, D3D12_MESSAGE_CALLBACK_FLAG_NONE, nullptr, nullptr);
|
||||||
nullptr, nullptr);
|
infoQueue->Release();
|
||||||
ID3D12InfoQueue1_Release(infoQueue);
|
Log(LogLevel::Message, LogCategory::Graphics, "DX12: Debug Info Logger Initialized");
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void DestroyDriver_Internal(NonNullPtr<D3D12Driver> driver)
|
void DestroyDriver_Internal(NonNullPtr<D3D12Driver> driver)
|
||||||
@@ -520,6 +513,7 @@ namespace Juliet::D3D12
|
|||||||
Internal::DestroyDescriptorHeap(driver->BindlessDescriptorHeap);
|
Internal::DestroyDescriptorHeap(driver->BindlessDescriptorHeap);
|
||||||
|
|
||||||
// Clean allocations
|
// Clean allocations
|
||||||
|
|
||||||
SafeFree(driver->AvailableCommandLists);
|
SafeFree(driver->AvailableCommandLists);
|
||||||
SafeFree(driver->SubmittedCommandLists);
|
SafeFree(driver->SubmittedCommandLists);
|
||||||
SafeFree(driver->GraphicsPipelinesToDispose);
|
SafeFree(driver->GraphicsPipelinesToDispose);
|
||||||
@@ -528,41 +522,40 @@ namespace Juliet::D3D12
|
|||||||
|
|
||||||
if (driver->IndirectDrawCommandSignature)
|
if (driver->IndirectDrawCommandSignature)
|
||||||
{
|
{
|
||||||
ID3D12CommandSignature_Release(driver->IndirectDrawCommandSignature);
|
driver->IndirectDrawCommandSignature->Release();
|
||||||
driver->IndirectDrawCommandSignature = nullptr;
|
|
||||||
}
|
}
|
||||||
if (driver->IndirectIndexedDrawCommandSignature)
|
if (driver->IndirectIndexedDrawCommandSignature)
|
||||||
{
|
{
|
||||||
ID3D12CommandSignature_Release(driver->IndirectIndexedDrawCommandSignature);
|
driver->IndirectIndexedDrawCommandSignature->Release();
|
||||||
driver->IndirectIndexedDrawCommandSignature = nullptr;
|
driver->IndirectIndexedDrawCommandSignature = nullptr;
|
||||||
}
|
}
|
||||||
if (driver->IndirectDispatchCommandSignature)
|
if (driver->IndirectDispatchCommandSignature)
|
||||||
{
|
{
|
||||||
ID3D12CommandSignature_Release(driver->IndirectDispatchCommandSignature);
|
driver->IndirectDispatchCommandSignature->Release();
|
||||||
driver->IndirectDispatchCommandSignature = nullptr;
|
driver->IndirectDispatchCommandSignature = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (driver->GraphicsQueue)
|
if (driver->GraphicsQueue)
|
||||||
{
|
{
|
||||||
ID3D12CommandQueue_Release(driver->GraphicsQueue);
|
driver->GraphicsQueue->Release();
|
||||||
driver->GraphicsQueue = nullptr;
|
driver->GraphicsQueue = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (driver->D3D12Device)
|
if (driver->D3D12Device)
|
||||||
{
|
{
|
||||||
ID3D12Device5_Release(driver->D3D12Device);
|
driver->D3D12Device->Release();
|
||||||
driver->D3D12Device = nullptr;
|
driver->D3D12Device = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (driver->DXGIAdapter)
|
if (driver->DXGIAdapter)
|
||||||
{
|
{
|
||||||
IDXGIAdapter1_Release(driver->DXGIAdapter);
|
driver->DXGIAdapter->Release();
|
||||||
driver->DXGIAdapter = nullptr;
|
driver->DXGIAdapter = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (driver->DXGIFactory)
|
if (driver->DXGIFactory)
|
||||||
{
|
{
|
||||||
IDXGIFactory4_Release(driver->DXGIFactory);
|
driver->DXGIFactory->Release();
|
||||||
driver->DXGIFactory = nullptr;
|
driver->DXGIFactory = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -598,6 +591,7 @@ namespace Juliet::D3D12
|
|||||||
Log(LogLevel::Error, LogCategory::Graphics, "OOM: D3D12WindowData");
|
Log(LogLevel::Error, LogCategory::Graphics, "OOM: D3D12WindowData");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
d3d12Driver->WindowData = windowData;
|
||||||
|
|
||||||
windowData->Window = window;
|
windowData->Window = window;
|
||||||
|
|
||||||
@@ -609,7 +603,6 @@ namespace Juliet::D3D12
|
|||||||
}
|
}
|
||||||
|
|
||||||
d3d12Driver->WindowData = windowData;
|
d3d12Driver->WindowData = windowData;
|
||||||
// TODO : React to resize. Need event system.
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -645,12 +638,116 @@ namespace Juliet::D3D12
|
|||||||
Free(device.Get());
|
Free(device.Get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note: SetViewPort, SetScissorRect, SetBlendConstants, SetStencilReference
|
||||||
|
// are defined in D3D12CommandList.cpp and used directly via D3D12:: namespace
|
||||||
|
|
||||||
|
// BindGraphicsPipeline is now assigned directly from D3D12:: namespace
|
||||||
|
|
||||||
|
// DrawPrimitives is now assigned directly from D3D12:: namespace
|
||||||
|
|
||||||
|
void DrawIndexedPrimitives(NonNullPtr<CommandList> commandList, uint32 numIndices, uint32 numInstances,
|
||||||
|
uint32 firstIndex, uint32 vertexOffset, uint32 firstInstance)
|
||||||
|
{
|
||||||
|
auto* d3d12CommandList = reinterpret_cast<D3D12CommandList*>(commandList.Get());
|
||||||
|
d3d12CommandList->GraphicsCommandList.CommandList->DrawIndexedInstanced(numIndices, numInstances, firstIndex,
|
||||||
|
static_cast<INT>(vertexOffset), firstInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaitUntilGPUIsIdle, SetPushConstants are now assigned directly from D3D12:: namespace
|
||||||
|
|
||||||
|
// QueryFence, ReleaseFence, CreateShader, DestroyShader are now assigned directly from D3D12:: namespace
|
||||||
|
|
||||||
|
// CreateGraphicsPipeline is assigned directly from D3D12:: namespace
|
||||||
|
|
||||||
|
void DestroyGraphicsPipeline(NonNullPtr<GPUDriver> driver, NonNullPtr<GraphicsPipeline> pipeline)
|
||||||
|
{
|
||||||
|
auto* d3d12Driver = static_cast<D3D12Driver*>(driver.Get());
|
||||||
|
d3d12Driver->GraphicsPipelinesToDispose[d3d12Driver->GraphicsPipelinesToDisposeCount] =
|
||||||
|
reinterpret_cast<D3D12GraphicsPipeline*>(pipeline.Get());
|
||||||
|
d3d12Driver->GraphicsPipelinesToDisposeCount += 1;
|
||||||
|
if (d3d12Driver->GraphicsPipelinesToDisposeCount >= d3d12Driver->GraphicsPipelinesToDisposeCapacity)
|
||||||
|
{
|
||||||
|
Internal::ReleaseGraphicsPipeline(reinterpret_cast<D3D12GraphicsPipeline*>(pipeline.Get()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffer functions are assigned directly from D3D12:: namespace
|
||||||
|
|
||||||
|
void CopyBufferToTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Texture> dst, NonNullPtr<GraphicsTransferBuffer> src)
|
||||||
|
{
|
||||||
|
auto* d3d12CommandList = reinterpret_cast<D3D12CommandList*>(commandList.Get());
|
||||||
|
auto* d3d12TextureContainer = reinterpret_cast<D3D12TextureContainer*>(dst.Get());
|
||||||
|
auto* d3d12Texture = d3d12TextureContainer->ActiveTexture;
|
||||||
|
|
||||||
|
Internal::TextureTransitionFromDefaultUsage(d3d12CommandList, d3d12Texture, D3D12_RESOURCE_STATE_COPY_DEST);
|
||||||
|
|
||||||
|
// Get resource desc using C++ API
|
||||||
|
D3D12_RESOURCE_DESC desc = d3d12Texture->Resource->GetDesc();
|
||||||
|
|
||||||
|
D3D12_TEXTURE_COPY_LOCATION dstLoc = {};
|
||||||
|
dstLoc.pResource = d3d12Texture->Resource;
|
||||||
|
dstLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||||
|
dstLoc.SubresourceIndex = 0;
|
||||||
|
|
||||||
|
// Get buffer resource - D3D12Buffer is anonymous, access Handle directly
|
||||||
|
// The GraphicsTransferBuffer IS a D3D12Buffer internally
|
||||||
|
struct D3D12TransferBuffer
|
||||||
|
{
|
||||||
|
Internal::D3D12Descriptor Descriptor;
|
||||||
|
ID3D12Resource* Handle;
|
||||||
|
D3D12_RESOURCE_STATES CurrentState;
|
||||||
|
};
|
||||||
|
auto* d3d12BufferSrc = reinterpret_cast<D3D12TransferBuffer*>(src.Get());
|
||||||
|
|
||||||
|
D3D12_TEXTURE_COPY_LOCATION srcLoc = {};
|
||||||
|
srcLoc.pResource = d3d12BufferSrc->Handle;
|
||||||
|
srcLoc.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||||
|
srcLoc.PlacedFootprint.Offset = 0;
|
||||||
|
srcLoc.PlacedFootprint.Footprint.Format = desc.Format;
|
||||||
|
srcLoc.PlacedFootprint.Footprint.Width = (UINT)desc.Width;
|
||||||
|
srcLoc.PlacedFootprint.Footprint.Height = desc.Height;
|
||||||
|
srcLoc.PlacedFootprint.Footprint.Depth = 1;
|
||||||
|
|
||||||
|
uint32 rowPitch = (uint32)desc.Width * 4;
|
||||||
|
rowPitch = (rowPitch + 255u) & ~255u;
|
||||||
|
|
||||||
|
srcLoc.PlacedFootprint.Footprint.RowPitch = rowPitch;
|
||||||
|
|
||||||
|
d3d12CommandList->GraphicsCommandList.CommandList->CopyTextureRegion(&dstLoc, 0, 0, 0, &srcLoc, nullptr);
|
||||||
|
|
||||||
|
Internal::TextureTransitionToDefaultUsage(d3d12CommandList, d3d12Texture, D3D12_RESOURCE_STATE_COPY_DEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDescriptorIndex wrapper needed to adapt signature from GPUDriver* to GraphicsDevice*
|
||||||
|
uint32 GetDescriptorIndex(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer)
|
||||||
|
{
|
||||||
|
auto* driver = static_cast<D3D12Driver*>(device->Driver);
|
||||||
|
return D3D12::GetDescriptorIndex(driver, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDescriptorIndexTexture provides custom logic to get SRV handle index
|
||||||
|
uint32 GetDescriptorIndexTexture(NonNullPtr<GraphicsDevice> /*device*/, NonNullPtr<Texture> texture)
|
||||||
|
{
|
||||||
|
auto* textureContainer = reinterpret_cast<D3D12TextureContainer*>(texture.Get());
|
||||||
|
return textureContainer->ActiveTexture->SRVHandle.CpuHandleIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ALLOW_SHADER_HOT_RELOAD
|
||||||
|
bool UpdateGraphicsPipelineShaders(NonNullPtr<GPUDriver> /*driver*/, NonNullPtr<GraphicsPipeline> /*graphicsPipeline*/,
|
||||||
|
Shader* /*optional_vertexShader*/, Shader* /*optional_fragmentShader*/)
|
||||||
|
{
|
||||||
|
// Missing implementation, skipping for now
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
GraphicsDevice* CreateGraphicsDevice(bool enableDebug)
|
GraphicsDevice* CreateGraphicsDevice(bool enableDebug)
|
||||||
|
|
||||||
{
|
{
|
||||||
#if JULIET_DEBUG
|
#if JULIET_DEBUG
|
||||||
// Unit Tests for D3D12 Logic
|
// Unit Tests for D3D12 Logic
|
||||||
UnitTest::TestDescriptorHeapPool();
|
UnitTest::TestDescriptorHeapPool();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
auto driver = static_cast<D3D12Driver*>(Calloc(1, sizeof(D3D12Driver)));
|
auto driver = static_cast<D3D12Driver*>(Calloc(1, sizeof(D3D12Driver)));
|
||||||
|
|
||||||
@@ -671,7 +768,7 @@ namespace Juliet::D3D12
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = IDXGIFactory1_QueryInterface(factory1, IID_IDXGIFactory4, reinterpret_cast<void**>(&driver->DXGIFactory));
|
result = factory1->QueryInterface(IID_IDXGIFactory4, reinterpret_cast<void**>(&driver->DXGIFactory));
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
DestroyDriver_Internal(driver);
|
DestroyDriver_Internal(driver);
|
||||||
@@ -679,43 +776,40 @@ namespace Juliet::D3D12
|
|||||||
"checked in CheckDriver");
|
"checked in CheckDriver");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
IDXGIFactory1_Release(factory1);
|
factory1->Release();
|
||||||
|
|
||||||
// Query DXGI1.5 and check for monitor Tearing support
|
// Query DXGI1.5 and check for monitor Tearing support
|
||||||
IDXGIFactory5* factory5 = nullptr;
|
IDXGIFactory5* factory5 = nullptr;
|
||||||
result = IDXGIFactory4_QueryInterface(driver->DXGIFactory, IID_IDXGIFactory5, reinterpret_cast<void**>(&factory5));
|
result = driver->DXGIFactory->QueryInterface(IID_IDXGIFactory5, reinterpret_cast<void**>(&factory5));
|
||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
bool isTearingSupported = false;
|
bool isTearingSupported = false;
|
||||||
result = IDXGIFactory5_CheckFeatureSupport(factory5, DXGI_FEATURE_PRESENT_ALLOW_TEARING,
|
result = factory5->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &isTearingSupported,
|
||||||
&isTearingSupported, sizeof(isTearingSupported));
|
sizeof(isTearingSupported));
|
||||||
driver->IsTearingSupported = isTearingSupported;
|
driver->IsTearingSupported = isTearingSupported;
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
driver->IsTearingSupported = false;
|
driver->IsTearingSupported = false;
|
||||||
}
|
}
|
||||||
IDXGIFactory5_Release(factory5);
|
factory5->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If available use DXGI1.6 to fetch the good graphics card.
|
// If available use DXGI1.6 to fetch the good graphics card.
|
||||||
// 1.6 should be available on most Win10 PC if they didnt their windows update.
|
// 1.6 should be available on most Win10 PC if they didnt their windows update.
|
||||||
// Lets support not having it for now...
|
// Lets support not having it for now...
|
||||||
IDXGIFactory6* factory6 = nullptr;
|
IDXGIFactory6* factory6 = nullptr;
|
||||||
result = IDXGIFactory4_QueryInterface(driver->DXGIFactory, IID_IDXGIFactory6, reinterpret_cast<void**>(&factory6));
|
result = driver->DXGIFactory->QueryInterface(IID_IDXGIFactory6, reinterpret_cast<void**>(&factory6));
|
||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
// TODO: Put into the config
|
// TODO: Put into the config
|
||||||
static constexpr bool useLowPower = false;
|
static constexpr bool useLowPower = false;
|
||||||
result = IDXGIFactory6_EnumAdapterByGpuPreference(factory6, 0,
|
result = factory6->EnumAdapterByGpuPreference(0, useLowPower ? DXGI_GPU_PREFERENCE_MINIMUM_POWER : DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE,
|
||||||
useLowPower ? DXGI_GPU_PREFERENCE_MINIMUM_POWER
|
IID_IDXGIAdapter1, reinterpret_cast<void**>(&driver->DXGIAdapter));
|
||||||
: DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE,
|
factory6->Release();
|
||||||
IID_IDXGIAdapter1,
|
|
||||||
reinterpret_cast<void**>(&driver->DXGIAdapter));
|
|
||||||
IDXGIFactory6_Release(factory6);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = IDXGIFactory4_EnumAdapters1(driver->DXGIFactory, 0, &driver->DXGIAdapter);
|
result = driver->DXGIFactory->EnumAdapters1(0, &driver->DXGIAdapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
@@ -727,7 +821,7 @@ namespace Juliet::D3D12
|
|||||||
|
|
||||||
// Adapter is setup, get all the relevant info in the descriptor
|
// Adapter is setup, get all the relevant info in the descriptor
|
||||||
DXGI_ADAPTER_DESC1 adapterDesc;
|
DXGI_ADAPTER_DESC1 adapterDesc;
|
||||||
result = IDXGIAdapter1_GetDesc1(driver->DXGIAdapter, &adapterDesc);
|
result = driver->DXGIAdapter->GetDesc1(&adapterDesc);
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
DestroyDriver_Internal(driver);
|
DestroyDriver_Internal(driver);
|
||||||
@@ -737,7 +831,7 @@ namespace Juliet::D3D12
|
|||||||
|
|
||||||
// Driver version
|
// Driver version
|
||||||
LARGE_INTEGER umdVersion;
|
LARGE_INTEGER umdVersion;
|
||||||
result = IDXGIAdapter1_CheckInterfaceSupport(driver->DXGIAdapter, IID_IDXGIDevice, &umdVersion);
|
result = driver->DXGIAdapter->CheckInterfaceSupport(IID_IDXGIDevice, &umdVersion);
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
DestroyDriver_Internal(driver);
|
DestroyDriver_Internal(driver);
|
||||||
@@ -784,7 +878,7 @@ namespace Juliet::D3D12
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
result = D3D12CreateDeviceFuncPtr(reinterpret_cast<IUnknown*>(driver->DXGIAdapter), kD3DFeatureLevel,
|
result = D3D12CreateDeviceFuncPtr(static_cast<IUnknown*>(driver->DXGIAdapter), kD3DFeatureLevel,
|
||||||
IID_ID3D12Device5, reinterpret_cast<void**>(&driver->D3D12Device));
|
IID_ID3D12Device5, reinterpret_cast<void**>(&driver->D3D12Device));
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
@@ -793,6 +887,8 @@ namespace Juliet::D3D12
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log(LogLevel::Message, LogCategory::Graphics, "DX12: D3D12Device Created: %p", (void*)driver->D3D12Device);
|
||||||
|
|
||||||
#if JULIET_DEBUG
|
#if JULIET_DEBUG
|
||||||
if (enableDebug)
|
if (enableDebug)
|
||||||
{
|
{
|
||||||
@@ -800,17 +896,15 @@ namespace Juliet::D3D12
|
|||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
#ifdef ID3D12InfoQueue1_SUPPORTED
|
|
||||||
InitializeD3D12DebugInfoLogger(driver);
|
InitializeD3D12DebugInfoLogger(driver);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Check if UMA (unified memory architecture) is available. Used on APU i think ??
|
// Check if UMA (unified memory architecture) is available. Used on APU i think ??
|
||||||
D3D12_FEATURE_DATA_ARCHITECTURE architecture;
|
D3D12_FEATURE_DATA_ARCHITECTURE architecture;
|
||||||
architecture.NodeIndex = 0;
|
architecture.NodeIndex = 0;
|
||||||
result = ID3D12Device5_CheckFeatureSupport(driver->D3D12Device, D3D12_FEATURE_ARCHITECTURE, &architecture,
|
result = driver->D3D12Device->CheckFeatureSupport(D3D12_FEATURE_ARCHITECTURE, &architecture,
|
||||||
sizeof(D3D12_FEATURE_DATA_ARCHITECTURE));
|
sizeof(D3D12_FEATURE_DATA_ARCHITECTURE));
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
DestroyDriver_Internal(driver);
|
DestroyDriver_Internal(driver);
|
||||||
@@ -823,8 +917,7 @@ namespace Juliet::D3D12
|
|||||||
// Check "GPU Upload Heap" support (for fast uniform buffers. Not supported on my 5700xt
|
// Check "GPU Upload Heap" support (for fast uniform buffers. Not supported on my 5700xt
|
||||||
D3D12_FEATURE_DATA_D3D12_OPTIONS16 options16;
|
D3D12_FEATURE_DATA_D3D12_OPTIONS16 options16;
|
||||||
driver->GPUUploadHeapSupported = false;
|
driver->GPUUploadHeapSupported = false;
|
||||||
result = ID3D12Device5_CheckFeatureSupport(driver->D3D12Device, D3D12_FEATURE_D3D12_OPTIONS16, &options16,
|
result = driver->D3D12Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS16, &options16, sizeof(options16));
|
||||||
sizeof(options16));
|
|
||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
driver->GPUUploadHeapSupported = options16.GPUUploadHeapSupported;
|
driver->GPUUploadHeapSupported = options16.GPUUploadHeapSupported;
|
||||||
@@ -840,17 +933,23 @@ namespace Juliet::D3D12
|
|||||||
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||||
queueDesc.NodeMask = 0;
|
queueDesc.NodeMask = 0;
|
||||||
queueDesc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
|
queueDesc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
|
||||||
result = ID3D12Device5_CreateCommandQueue(driver->D3D12Device, &queueDesc, IID_ID3D12CommandQueue,
|
result = driver->D3D12Device->CreateCommandQueue(&queueDesc, IID_ID3D12CommandQueue,
|
||||||
reinterpret_cast<void**>(&driver->GraphicsQueue));
|
reinterpret_cast<void**>(&driver->GraphicsQueue));
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
DestroyDriver_Internal(driver);
|
DestroyDriver_Internal(driver);
|
||||||
Log(LogLevel::Error, LogCategory::Graphics, "DX12: Could not create D3D12CommandQueue: Graphics");
|
Log(LogLevel::Error, LogCategory::Graphics, "DX12: Could not create D3D12CommandQueue: Graphics");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
ID3D12CommandQueue_SetName(driver->GraphicsQueue, L"GRAPHICS_QUEUE");
|
driver->GraphicsQueue->SetName(L"GRAPHICS_QUEUE");
|
||||||
driver->QueueDesc[ToUnderlying(QueueType::Graphics)] = queueDesc;
|
driver->QueueDesc[ToUnderlying(QueueType::Graphics)] = queueDesc;
|
||||||
|
|
||||||
|
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_COMPUTE;
|
||||||
|
driver->QueueDesc[ToUnderlying(QueueType::Compute)] = queueDesc;
|
||||||
|
|
||||||
|
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_COPY;
|
||||||
|
driver->QueueDesc[ToUnderlying(QueueType::Copy)] = queueDesc;
|
||||||
|
|
||||||
// Indirect Commands
|
// Indirect Commands
|
||||||
D3D12_COMMAND_SIGNATURE_DESC commandSignatureDesc;
|
D3D12_COMMAND_SIGNATURE_DESC commandSignatureDesc;
|
||||||
D3D12_INDIRECT_ARGUMENT_DESC indirectArgumentDesc;
|
D3D12_INDIRECT_ARGUMENT_DESC indirectArgumentDesc;
|
||||||
@@ -861,8 +960,8 @@ namespace Juliet::D3D12
|
|||||||
commandSignatureDesc.ByteStride = sizeof(IndirectDrawCommand);
|
commandSignatureDesc.ByteStride = sizeof(IndirectDrawCommand);
|
||||||
commandSignatureDesc.NumArgumentDescs = 1;
|
commandSignatureDesc.NumArgumentDescs = 1;
|
||||||
commandSignatureDesc.pArgumentDescs = &indirectArgumentDesc;
|
commandSignatureDesc.pArgumentDescs = &indirectArgumentDesc;
|
||||||
result = ID3D12Device5_CreateCommandSignature(driver->D3D12Device, &commandSignatureDesc, nullptr, IID_ID3D12CommandSignature,
|
result = driver->D3D12Device->CreateCommandSignature(&commandSignatureDesc, nullptr, IID_ID3D12CommandSignature,
|
||||||
reinterpret_cast<void**>(&driver->IndirectDrawCommandSignature));
|
reinterpret_cast<void**>(&driver->IndirectDrawCommandSignature));
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
DestroyDriver_Internal(driver);
|
DestroyDriver_Internal(driver);
|
||||||
@@ -874,8 +973,8 @@ namespace Juliet::D3D12
|
|||||||
commandSignatureDesc.ByteStride = sizeof(IndexedIndirectDrawCommand);
|
commandSignatureDesc.ByteStride = sizeof(IndexedIndirectDrawCommand);
|
||||||
commandSignatureDesc.pArgumentDescs = &indirectArgumentDesc;
|
commandSignatureDesc.pArgumentDescs = &indirectArgumentDesc;
|
||||||
|
|
||||||
result = ID3D12Device5_CreateCommandSignature(driver->D3D12Device, &commandSignatureDesc, nullptr, IID_ID3D12CommandSignature,
|
result = driver->D3D12Device->CreateCommandSignature(&commandSignatureDesc, nullptr, IID_ID3D12CommandSignature,
|
||||||
reinterpret_cast<void**>(&driver->IndirectIndexedDrawCommandSignature));
|
reinterpret_cast<void**>(&driver->IndirectIndexedDrawCommandSignature));
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -888,8 +987,8 @@ namespace Juliet::D3D12
|
|||||||
commandSignatureDesc.ByteStride = sizeof(IndirectDispatchCommand);
|
commandSignatureDesc.ByteStride = sizeof(IndirectDispatchCommand);
|
||||||
commandSignatureDesc.pArgumentDescs = &indirectArgumentDesc;
|
commandSignatureDesc.pArgumentDescs = &indirectArgumentDesc;
|
||||||
|
|
||||||
result = ID3D12Device5_CreateCommandSignature(driver->D3D12Device, &commandSignatureDesc, nullptr, IID_ID3D12CommandSignature,
|
result = driver->D3D12Device->CreateCommandSignature(&commandSignatureDesc, nullptr, IID_ID3D12CommandSignature,
|
||||||
reinterpret_cast<void**>(&driver->IndirectDispatchCommandSignature));
|
reinterpret_cast<void**>(&driver->IndirectDispatchCommandSignature));
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
DestroyDriver_Internal(driver);
|
DestroyDriver_Internal(driver);
|
||||||
@@ -984,35 +1083,42 @@ namespace Juliet::D3D12
|
|||||||
device->AcquireSwapChainTexture = AcquireSwapChainTexture;
|
device->AcquireSwapChainTexture = AcquireSwapChainTexture;
|
||||||
device->WaitAndAcquireSwapChainTexture = WaitAndAcquireSwapChainTexture;
|
device->WaitAndAcquireSwapChainTexture = WaitAndAcquireSwapChainTexture;
|
||||||
device->GetSwapChainTextureFormat = GetSwapChainTextureFormat;
|
device->GetSwapChainTextureFormat = GetSwapChainTextureFormat;
|
||||||
device->AcquireCommandList = AcquireCommandList;
|
device->AcquireCommandList = D3D12::AcquireCommandList;
|
||||||
device->SubmitCommandLists = SubmitCommandLists;
|
device->SubmitCommandLists = D3D12::SubmitCommandLists;
|
||||||
device->BeginRenderPass = BeginRenderPass;
|
|
||||||
device->EndRenderPass = EndRenderPass;
|
device->BeginRenderPass = D3D12::BeginRenderPass;
|
||||||
device->SetViewPort = SetViewPort;
|
device->EndRenderPass = D3D12::EndRenderPass;
|
||||||
device->SetScissorRect = SetScissorRect;
|
device->SetViewPort = D3D12::SetViewPort;
|
||||||
device->SetBlendConstants = SetBlendConstants;
|
device->SetScissorRect = D3D12::SetScissorRect;
|
||||||
device->SetStencilReference = SetStencilReference;
|
device->SetBlendConstants = D3D12::SetBlendConstants;
|
||||||
device->BindGraphicsPipeline = BindGraphicsPipeline;
|
device->SetStencilReference = D3D12::SetStencilReference;
|
||||||
device->DrawPrimitives = DrawPrimitives;
|
device->BindGraphicsPipeline = D3D12::BindGraphicsPipeline;
|
||||||
device->WaitUntilGPUIsIdle = WaitUntilGPUIsIdle;
|
device->DrawPrimitives = D3D12::DrawPrimitives;
|
||||||
device->SetPushConstants = SetPushConstants;
|
device->DrawIndexedPrimitives = DrawIndexedPrimitives;
|
||||||
device->QueryFence = QueryFence;
|
device->SetIndexBuffer = D3D12::SetIndexBuffer;
|
||||||
device->ReleaseFence = ReleaseFence;
|
device->WaitUntilGPUIsIdle = D3D12::WaitUntilGPUIsIdle;
|
||||||
device->CreateShader = CreateShader;
|
|
||||||
device->DestroyShader = DestroyShader;
|
device->SetPushConstants = D3D12::SetPushConstants;
|
||||||
device->CreateGraphicsPipeline = CreateGraphicsPipeline;
|
device->QueryFence = D3D12::QueryFence;
|
||||||
device->DestroyGraphicsPipeline = DestroyGraphicsPipeline;
|
device->ReleaseFence = D3D12::ReleaseFence;
|
||||||
device->CreateGraphicsBuffer = CreateGraphicsBuffer;
|
device->CreateShader = D3D12::CreateShader;
|
||||||
device->DestroyGraphicsBuffer = DestroyGraphicsBuffer;
|
device->DestroyShader = D3D12::DestroyShader;
|
||||||
device->CreateGraphicsTransferBuffer = CreateGraphicsTransferBuffer;
|
device->CreateGraphicsPipeline = D3D12::CreateGraphicsPipeline;
|
||||||
device->DestroyGraphicsTransferBuffer = DestroyGraphicsTransferBuffer;
|
device->DestroyGraphicsPipeline = DestroyGraphicsPipeline;
|
||||||
device->MapGraphicsTransferBuffer = MapBuffer;
|
device->CreateGraphicsBuffer = D3D12::CreateGraphicsBuffer;
|
||||||
device->UnmapGraphicsTransferBuffer = UnmapBuffer;
|
device->DestroyGraphicsBuffer = D3D12::DestroyGraphicsBuffer;
|
||||||
device->CopyBuffer = CopyBuffer;
|
device->CreateGraphicsTransferBuffer = D3D12::CreateGraphicsTransferBuffer;
|
||||||
device->TransitionBufferToReadable = TransitionBufferToReadable;
|
device->DestroyGraphicsTransferBuffer = D3D12::DestroyGraphicsTransferBuffer;
|
||||||
device->GetDescriptorIndex = GetDescriptorIndex;
|
device->MapGraphicsTransferBuffer = D3D12::MapBuffer;
|
||||||
device->CreateTexture = CreateTexture;
|
device->UnmapGraphicsTransferBuffer = D3D12::UnmapBuffer;
|
||||||
device->DestroyTexture = DestroyTexture;
|
device->CopyBuffer = CopyBuffer;
|
||||||
|
device->CopyBufferToTexture = CopyBufferToTexture;
|
||||||
|
device->TransitionBufferToReadable = D3D12::TransitionBufferToReadable;
|
||||||
|
|
||||||
|
device->GetDescriptorIndex = GetDescriptorIndex;
|
||||||
|
device->GetDescriptorIndexTexture = GetDescriptorIndexTexture;
|
||||||
|
device->CreateTexture = D3D12::CreateTexture;
|
||||||
|
device->DestroyTexture = D3D12::DestroyTexture;
|
||||||
|
|
||||||
#if ALLOW_SHADER_HOT_RELOAD
|
#if ALLOW_SHADER_HOT_RELOAD
|
||||||
device->UpdateGraphicsPipelineShaders = UpdateGraphicsPipelineShaders;
|
device->UpdateGraphicsPipelineShaders = UpdateGraphicsPipelineShaders;
|
||||||
@@ -1024,7 +1130,8 @@ namespace Juliet::D3D12
|
|||||||
driver->GraphicsDevice = device;
|
driver->GraphicsDevice = device;
|
||||||
|
|
||||||
// Create Global Bindless Heap that stays alive for the driver whole lifetime
|
// Create Global Bindless Heap that stays alive for the driver whole lifetime
|
||||||
driver->BindlessDescriptorHeap = Internal::CreateDescriptorHeap(driver, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, GPUDriver::kCBV_SRV_UAV_HeapDescriptorCount, false);
|
driver->BindlessDescriptorHeap = Internal::CreateDescriptorHeap(driver, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
|
||||||
|
GPUDriver::kCBV_SRV_UAV_HeapDescriptorCount, false);
|
||||||
|
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ namespace Juliet::D3D12
|
|||||||
ID3D12Device5* D3D12Device;
|
ID3D12Device5* D3D12Device;
|
||||||
PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE D3D12SerializeVersionedRootSignatureFct;
|
PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE D3D12SerializeVersionedRootSignatureFct;
|
||||||
ID3D12CommandQueue* GraphicsQueue;
|
ID3D12CommandQueue* GraphicsQueue;
|
||||||
D3D12_COMMAND_QUEUE_DESC QueueDesc[ToUnderlying(QueueType::Copy)];
|
D3D12_COMMAND_QUEUE_DESC QueueDesc[ToUnderlying(QueueType::Count)];
|
||||||
#if JULIET_DEBUG
|
#if JULIET_DEBUG
|
||||||
ID3D12Debug1* D3D12Debug;
|
ID3D12Debug1* D3D12Debug;
|
||||||
#endif
|
#endif
|
||||||
@@ -112,6 +112,7 @@ namespace Juliet::D3D12
|
|||||||
bool GPUUploadHeapSupported : 1;
|
bool GPUUploadHeapSupported : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
namespace Internal
|
namespace Internal
|
||||||
{
|
{
|
||||||
void DisposePendingResourcces(NonNullPtr<D3D12Driver> driver);
|
void DisposePendingResourcces(NonNullPtr<D3D12Driver> driver);
|
||||||
|
|||||||
@@ -406,7 +406,7 @@ namespace Juliet::D3D12
|
|||||||
psoDesc.pRootSignature = d3d12Driver->BindlessRootSignature->Handle;
|
psoDesc.pRootSignature = d3d12Driver->BindlessRootSignature->Handle;
|
||||||
|
|
||||||
ID3D12PipelineState* pipelineState;
|
ID3D12PipelineState* pipelineState;
|
||||||
HRESULT res = ID3D12Device_CreateGraphicsPipelineState(d3d12Driver->D3D12Device, &psoDesc, IID_ID3D12PipelineState,
|
HRESULT res = d3d12Driver->D3D12Device->CreateGraphicsPipelineState(&psoDesc, IID_ID3D12PipelineState,
|
||||||
reinterpret_cast<void**>(&pipelineState));
|
reinterpret_cast<void**>(&pipelineState));
|
||||||
if (FAILED(res))
|
if (FAILED(res))
|
||||||
{
|
{
|
||||||
@@ -499,7 +499,7 @@ namespace Juliet::D3D12
|
|||||||
psoDesc.pRootSignature = d3d12Driver->BindlessRootSignature->Handle;
|
psoDesc.pRootSignature = d3d12Driver->BindlessRootSignature->Handle;
|
||||||
|
|
||||||
ID3D12PipelineState* pipelineState;
|
ID3D12PipelineState* pipelineState;
|
||||||
HRESULT res = ID3D12Device_CreateGraphicsPipelineState(d3d12Driver->D3D12Device, &psoDesc, IID_ID3D12PipelineState,
|
HRESULT res = d3d12Driver->D3D12Device->CreateGraphicsPipelineState(&psoDesc, IID_ID3D12PipelineState,
|
||||||
reinterpret_cast<void**>(&pipelineState));
|
reinterpret_cast<void**>(&pipelineState));
|
||||||
if (FAILED(res))
|
if (FAILED(res))
|
||||||
{
|
{
|
||||||
@@ -520,7 +520,7 @@ namespace Juliet::D3D12
|
|||||||
// If everything worked, we patch the graphics pipeline and destroy everything irrelevant
|
// If everything worked, we patch the graphics pipeline and destroy everything irrelevant
|
||||||
if (d3d12GraphicsPipeline->PipelineState)
|
if (d3d12GraphicsPipeline->PipelineState)
|
||||||
{
|
{
|
||||||
ID3D12PipelineState_Release(d3d12GraphicsPipeline->PipelineState);
|
d3d12GraphicsPipeline->PipelineState->Release();
|
||||||
}
|
}
|
||||||
d3d12GraphicsPipeline->PipelineState = pipelineState;
|
d3d12GraphicsPipeline->PipelineState = pipelineState;
|
||||||
|
|
||||||
@@ -543,7 +543,7 @@ namespace Juliet::D3D12
|
|||||||
{
|
{
|
||||||
if (d3d12GraphicsPipeline->PipelineState)
|
if (d3d12GraphicsPipeline->PipelineState)
|
||||||
{
|
{
|
||||||
ID3D12PipelineState_Release(d3d12GraphicsPipeline->PipelineState);
|
d3d12GraphicsPipeline->PipelineState->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ALLOW_SHADER_HOT_RELOAD
|
#if ALLOW_SHADER_HOT_RELOAD
|
||||||
|
|||||||
@@ -8,30 +8,22 @@
|
|||||||
// Because Microsoft respects nothing
|
// Because Microsoft respects nothing
|
||||||
// TODO: Create an external dependency with its one fbuild.bff
|
// TODO: Create an external dependency with its one fbuild.bff
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
#pragma clang diagnostic ignored "-Wreserved-macro-identifier"
|
#pragma clang diagnostic ignored "-Wreserved-macro-identifier"
|
||||||
#pragma clang diagnostic ignored "-Wreserved-identifier"
|
#pragma clang diagnostic ignored "-Wreserved-identifier"
|
||||||
#pragma clang diagnostic ignored "-Wnonportable-system-include-path"
|
#pragma clang diagnostic ignored "-Wnonportable-system-include-path"
|
||||||
#pragma clang diagnostic ignored "-Wmicrosoft-enum-value"
|
#pragma clang diagnostic ignored "-Wmicrosoft-enum-value"
|
||||||
#pragma clang diagnostic ignored "-Wnested-anon-types"
|
#pragma clang diagnostic ignored "-Wnested-anon-types"
|
||||||
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
|
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// We will use the C interface of DX12.
|
|
||||||
// Those define disable the C++ API.
|
|
||||||
// It also prevents using d3dx12 because it only supports C++ :(
|
|
||||||
#define COBJMACROS
|
|
||||||
#define CINTERFACE
|
|
||||||
|
|
||||||
#include <Graphics/D3D12/AgilitySDK/d3d12.h>
|
|
||||||
#include <dxgi1_6.h>
|
#include <dxgi1_6.h>
|
||||||
|
#include <Graphics/D3D12/AgilitySDK/d3d12.h>
|
||||||
|
|
||||||
#if JULIET_DEBUG
|
#if JULIET_DEBUG
|
||||||
#include <dxgidebug.h>
|
#include <dxgidebug.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//#include <dxgi.h>
|
|
||||||
|
|
||||||
#ifdef __IDXGIInfoQueue_INTERFACE_DEFINED__
|
#ifdef __IDXGIInfoQueue_INTERFACE_DEFINED__
|
||||||
#define IDXGIINFOQUEUE_SUPPORTED
|
#define IDXGIINFOQUEUE_SUPPORTED
|
||||||
#endif
|
#endif
|
||||||
@@ -44,5 +36,5 @@
|
|||||||
#undef max
|
#undef max
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -136,6 +136,9 @@ namespace Juliet::D3D12::UnitTest
|
|||||||
|
|
||||||
// Note: heap2 is heap1.
|
// Note: heap2 is heap1.
|
||||||
// Pool array in driver leaked for test scope, acceptable.
|
// Pool array in driver leaked for test scope, acceptable.
|
||||||
|
|
||||||
|
printf("DescriptorHeapPool tests passed.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ namespace Juliet::D3D12
|
|||||||
// TODO: Check if texture has stencil
|
// TODO: Check if texture has stencil
|
||||||
// if (HasStencil(container->Header.CreateInfo.Format)) clearFlags |= D3D12_CLEAR_FLAG_STENCIL;
|
// if (HasStencil(container->Header.CreateInfo.Format)) clearFlags |= D3D12_CLEAR_FLAG_STENCIL;
|
||||||
|
|
||||||
ID3D12GraphicsCommandList_ClearDepthStencilView(d3d12CommandList->GraphicsCommandList.CommandList, DSV,
|
d3d12CommandList->GraphicsCommandList.CommandList->ClearDepthStencilView(DSV,
|
||||||
clearFlags, depthStencilTargetInfo->ClearDepth,
|
clearFlags, depthStencilTargetInfo->ClearDepth,
|
||||||
depthStencilTargetInfo->ClearStencil, 0, nullptr);
|
depthStencilTargetInfo->ClearStencil, 0, nullptr);
|
||||||
}
|
}
|
||||||
@@ -93,7 +93,7 @@ namespace Juliet::D3D12
|
|||||||
clearColor[2] = colorTargetInfos[idx].ClearColor.B;
|
clearColor[2] = colorTargetInfos[idx].ClearColor.B;
|
||||||
clearColor[3] = colorTargetInfos[idx].ClearColor.A;
|
clearColor[3] = colorTargetInfos[idx].ClearColor.A;
|
||||||
|
|
||||||
ID3D12GraphicsCommandList6_ClearRenderTargetView(d3d12CommandList->GraphicsCommandList.CommandList, rtv,
|
d3d12CommandList->GraphicsCommandList.CommandList->ClearRenderTargetView(rtv,
|
||||||
clearColor, 0, nullptr);
|
clearColor, 0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ namespace Juliet::D3D12
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D12GraphicsCommandList_OMSetRenderTargets(d3d12CommandList->GraphicsCommandList.CommandList,
|
d3d12CommandList->GraphicsCommandList.CommandList->OMSetRenderTargets(
|
||||||
colorTargetInfoCount, RTVs, false, hasDSV ? &DSV : nullptr);
|
colorTargetInfoCount, RTVs, false, hasDSV ? &DSV : nullptr);
|
||||||
|
|
||||||
// Set defaults graphics states
|
// Set defaults graphics states
|
||||||
@@ -163,8 +163,7 @@ namespace Juliet::D3D12
|
|||||||
Internal::TextureSubresourceBarrier(d3d12CommandList, D3D12_RESOURCE_STATE_RENDER_TARGET,
|
Internal::TextureSubresourceBarrier(d3d12CommandList, D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||||
D3D12_RESOURCE_STATE_RESOLVE_SOURCE,
|
D3D12_RESOURCE_STATE_RESOLVE_SOURCE,
|
||||||
d3d12CommandList->ColorTargetSubresources[idx]);
|
d3d12CommandList->ColorTargetSubresources[idx]);
|
||||||
ID3D12GraphicsCommandList_ResolveSubresource(
|
d3d12CommandList->GraphicsCommandList.CommandList->ResolveSubresource(
|
||||||
d3d12CommandList->GraphicsCommandList.CommandList,
|
|
||||||
d3d12CommandList->ColorResolveSubresources[idx]->Parent->Resource,
|
d3d12CommandList->ColorResolveSubresources[idx]->Parent->Resource,
|
||||||
d3d12CommandList->ColorResolveSubresources[idx]->Index,
|
d3d12CommandList->ColorResolveSubresources[idx]->Index,
|
||||||
d3d12CommandList->ColorTargetSubresources[idx]->Parent->Resource,
|
d3d12CommandList->ColorTargetSubresources[idx]->Parent->Resource,
|
||||||
@@ -199,7 +198,7 @@ namespace Juliet::D3D12
|
|||||||
}
|
}
|
||||||
d3d12CommandList->CurrentGraphicsPipeline = nullptr;
|
d3d12CommandList->CurrentGraphicsPipeline = nullptr;
|
||||||
|
|
||||||
ID3D12GraphicsCommandList_OMSetRenderTargets(d3d12CommandList->GraphicsCommandList.CommandList, 0, nullptr, false, nullptr);
|
d3d12CommandList->GraphicsCommandList.CommandList->OMSetRenderTargets(0, nullptr, false, nullptr);
|
||||||
|
|
||||||
// Reset bind states
|
// Reset bind states
|
||||||
ZeroArray(d3d12CommandList->ColorTargetSubresources);
|
ZeroArray(d3d12CommandList->ColorTargetSubresources);
|
||||||
@@ -236,10 +235,10 @@ namespace Juliet::D3D12
|
|||||||
Internal::SetDescriptorHeaps(d3d12CommandList);
|
Internal::SetDescriptorHeaps(d3d12CommandList);
|
||||||
|
|
||||||
// Set the pipeline state
|
// Set the pipeline state
|
||||||
ID3D12GraphicsCommandList_SetPipelineState(d3d12CommandList->GraphicsCommandList.CommandList, pipeline->PipelineState);
|
d3d12CommandList->GraphicsCommandList.CommandList->SetPipelineState(pipeline->PipelineState);
|
||||||
ID3D12GraphicsCommandList_SetGraphicsRootSignature(d3d12CommandList->GraphicsCommandList.CommandList,
|
d3d12CommandList->GraphicsCommandList.CommandList->SetGraphicsRootSignature(
|
||||||
pipeline->RootSignature->Handle);
|
pipeline->RootSignature->Handle);
|
||||||
ID3D12GraphicsCommandList_IASetPrimitiveTopology(d3d12CommandList->GraphicsCommandList.CommandList,
|
d3d12CommandList->GraphicsCommandList.CommandList->IASetPrimitiveTopology(
|
||||||
JulietToD3D12_PrimitiveType[ToUnderlying(pipeline->PrimitiveType)]);
|
JulietToD3D12_PrimitiveType[ToUnderlying(pipeline->PrimitiveType)]);
|
||||||
|
|
||||||
// Mark that bindings are needed
|
// Mark that bindings are needed
|
||||||
@@ -281,7 +280,7 @@ namespace Juliet::D3D12
|
|||||||
// TODO : Last missing piece
|
// TODO : Last missing piece
|
||||||
// D3D12_INTERNAL_BindGraphicsResources(d3d12CommandBuffer);
|
// D3D12_INTERNAL_BindGraphicsResources(d3d12CommandBuffer);
|
||||||
|
|
||||||
ID3D12GraphicsCommandList_DrawInstanced(d3d12CommandList->GraphicsCommandList.CommandList, numVertices,
|
d3d12CommandList->GraphicsCommandList.CommandList->DrawInstanced(numVertices,
|
||||||
numInstances, firstVertex, firstInstance);
|
numInstances, firstVertex, firstInstance);
|
||||||
}
|
}
|
||||||
} // namespace Juliet::D3D12
|
} // namespace Juliet::D3D12
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ namespace Juliet::D3D12
|
|||||||
{
|
{
|
||||||
ID3D12Resource* swapChainTexture = nullptr;
|
ID3D12Resource* swapChainTexture = nullptr;
|
||||||
HRESULT result =
|
HRESULT result =
|
||||||
IDXGISwapChain_GetBuffer(swapChain, index, IID_ID3D12Resource, reinterpret_cast<void**>(&swapChainTexture));
|
swapChain->GetBuffer(index, IID_ID3D12Resource, reinterpret_cast<void**>(&swapChainTexture));
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
LogError(driver->D3D12Device, "Cannot get buffer from SwapChain", result);
|
LogError(driver->D3D12Device, "Cannot get buffer from SwapChain", result);
|
||||||
@@ -53,7 +53,7 @@ namespace Juliet::D3D12
|
|||||||
if (!texture)
|
if (!texture)
|
||||||
{
|
{
|
||||||
LogError(driver->D3D12Device, "Cannot allocate D3D12Texture (out of memory)", result);
|
LogError(driver->D3D12Device, "Cannot allocate D3D12Texture (out of memory)", result);
|
||||||
ID3D12Resource_Release(swapChainTexture);
|
swapChainTexture->Release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ namespace Juliet::D3D12
|
|||||||
{
|
{
|
||||||
LogError(driver->D3D12Device, "Cannot allocate D3D12TextureSubresource (out of memory)", result);
|
LogError(driver->D3D12Device, "Cannot allocate D3D12TextureSubresource (out of memory)", result);
|
||||||
Free(texture);
|
Free(texture);
|
||||||
ID3D12Resource_Release(swapChainTexture);
|
swapChainTexture->Release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
texture->Subresources[0].RTVHandles =
|
texture->Subresources[0].RTVHandles =
|
||||||
@@ -77,8 +77,7 @@ namespace Juliet::D3D12
|
|||||||
texture->Subresources[0].Depth = 1;
|
texture->Subresources[0].Depth = 1;
|
||||||
texture->Subresources[0].Level = 0;
|
texture->Subresources[0].Level = 0;
|
||||||
|
|
||||||
D3D12_RESOURCE_DESC textureDesc;
|
D3D12_RESOURCE_DESC textureDesc = swapChainTexture->GetDesc();
|
||||||
ID3D12Resource_GetDesc(swapChainTexture, &textureDesc);
|
|
||||||
textureContainer->Header.CreateInfo.Width = static_cast<uint32>(textureDesc.Width);
|
textureContainer->Header.CreateInfo.Width = static_cast<uint32>(textureDesc.Width);
|
||||||
textureContainer->Header.CreateInfo.Height = static_cast<uint32>(textureDesc.Height);
|
textureContainer->Header.CreateInfo.Height = static_cast<uint32>(textureDesc.Height);
|
||||||
textureContainer->Header.CreateInfo.LayerCount = 1;
|
textureContainer->Header.CreateInfo.LayerCount = 1;
|
||||||
@@ -93,7 +92,7 @@ namespace Juliet::D3D12
|
|||||||
{
|
{
|
||||||
Free(texture->Subresources);
|
Free(texture->Subresources);
|
||||||
Free(texture);
|
Free(texture);
|
||||||
ID3D12Resource_Release(swapChainTexture);
|
swapChainTexture->Release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,10 +114,10 @@ namespace Juliet::D3D12
|
|||||||
rtvDesc.Texture2D.MipSlice = 0;
|
rtvDesc.Texture2D.MipSlice = 0;
|
||||||
rtvDesc.Texture2D.PlaneSlice = 0;
|
rtvDesc.Texture2D.PlaneSlice = 0;
|
||||||
|
|
||||||
ID3D12Device_CreateRenderTargetView(driver->D3D12Device, swapChainTexture, &rtvDesc,
|
driver->D3D12Device->CreateRenderTargetView(swapChainTexture, &rtvDesc,
|
||||||
texture->Subresources[0].RTVHandles[0].CpuHandle);
|
texture->Subresources[0].RTVHandles[0].CpuHandle);
|
||||||
|
|
||||||
ID3D12Resource_Release(swapChainTexture);
|
swapChainTexture->Release();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -161,11 +160,9 @@ namespace Juliet::D3D12
|
|||||||
windowData->InFlightFences[windowData->WindowFrameCounter] = nullptr;
|
windowData->InFlightFences[windowData->WindowFrameCounter] = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 swapchainIndex = IDXGISwapChain3_GetCurrentBackBufferIndex(windowData->SwapChain);
|
uint32 swapchainIndex = windowData->SwapChain->GetCurrentBackBufferIndex();
|
||||||
HRESULT result =
|
HRESULT result =
|
||||||
IDXGISwapChain_GetBuffer(windowData->SwapChain, swapchainIndex, IID_ID3D12Resource,
|
windowData->SwapChain->GetBuffer(swapchainIndex, IID_ID3D12Resource, reinterpret_cast<void**>(&windowData->SwapChainTextureContainers[swapchainIndex].ActiveTexture->Resource));
|
||||||
reinterpret_cast<void**>(
|
|
||||||
&windowData->SwapChainTextureContainers[swapchainIndex].ActiveTexture->Resource));
|
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
LogError(driver->D3D12Device, "Could not acquire swapchain", result);
|
LogError(driver->D3D12Device, "Could not acquire swapchain", result);
|
||||||
@@ -192,7 +189,7 @@ namespace Juliet::D3D12
|
|||||||
barrierDesc.Transition.pResource = windowData->SwapChainTextureContainers[swapchainIndex].ActiveTexture->Resource;
|
barrierDesc.Transition.pResource = windowData->SwapChainTextureContainers[swapchainIndex].ActiveTexture->Resource;
|
||||||
barrierDesc.Transition.Subresource = 0;
|
barrierDesc.Transition.Subresource = 0;
|
||||||
|
|
||||||
ID3D12GraphicsCommandList_ResourceBarrier(d3d12CommandList->GraphicsCommandList.CommandList, 1, &barrierDesc);
|
d3d12CommandList->GraphicsCommandList.CommandList->ResourceBarrier(1, &barrierDesc);
|
||||||
|
|
||||||
*swapchainTexture = reinterpret_cast<Texture*>(&windowData->SwapChainTextureContainers[swapchainIndex]);
|
*swapchainTexture = reinterpret_cast<Texture*>(&windowData->SwapChainTextureContainers[swapchainIndex]);
|
||||||
|
|
||||||
@@ -294,7 +291,7 @@ namespace Juliet::D3D12
|
|||||||
|
|
||||||
IDXGISwapChain1* swapChain = nullptr;
|
IDXGISwapChain1* swapChain = nullptr;
|
||||||
HRESULT result =
|
HRESULT result =
|
||||||
IDXGIFactory4_CreateSwapChainForHwnd(driver->DXGIFactory, reinterpret_cast<IUnknown*>(driver->GraphicsQueue),
|
driver->DXGIFactory->CreateSwapChainForHwnd(static_cast<IUnknown*>(driver->GraphicsQueue),
|
||||||
windowHandle, &swapChainDesc, &swapChainFullscreenDesc, nullptr, &swapChain);
|
windowHandle, &swapChainDesc, &swapChainFullscreenDesc, nullptr, &swapChain);
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
@@ -303,8 +300,8 @@ namespace Juliet::D3D12
|
|||||||
}
|
}
|
||||||
|
|
||||||
IDXGISwapChain3* swapChain3 = nullptr;
|
IDXGISwapChain3* swapChain3 = nullptr;
|
||||||
result = IDXGISwapChain1_QueryInterface(swapChain, IID_IDXGISwapChain3, reinterpret_cast<void**>(&swapChain3));
|
result = swapChain->QueryInterface(IID_IDXGISwapChain3, reinterpret_cast<void**>(&swapChain3));
|
||||||
IDXGISwapChain1_Release(swapChain);
|
swapChain->Release();
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
LogError(driver->D3D12Device, "Could not query IDXGISwapChain3 interface", result);
|
LogError(driver->D3D12Device, "Could not query IDXGISwapChain3 interface", result);
|
||||||
@@ -313,11 +310,11 @@ namespace Juliet::D3D12
|
|||||||
|
|
||||||
if (composition != SwapChainComposition::SDR)
|
if (composition != SwapChainComposition::SDR)
|
||||||
{
|
{
|
||||||
IDXGISwapChain3_SetColorSpace1(swapChain3, SwapchainCompositionToColorSpace[ToUnderlying(composition)]);
|
swapChain3->SetColorSpace1(SwapchainCompositionToColorSpace[ToUnderlying(composition)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
IDXGIFactory1* parentFactory = nullptr;
|
IDXGIFactory1* parentFactory = nullptr;
|
||||||
result = IDXGISwapChain3_GetParent(swapChain3, IID_IDXGIFactory1, reinterpret_cast<void**>(&parentFactory));
|
result = swapChain3->GetParent(IID_IDXGIFactory1, reinterpret_cast<void**>(&parentFactory));
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
Log(LogLevel::Warning, LogCategory::Graphics, "Cannot get SwapChain Parent! Error Code: " HRESULT_FMT, result);
|
Log(LogLevel::Warning, LogCategory::Graphics, "Cannot get SwapChain Parent! Error Code: " HRESULT_FMT, result);
|
||||||
@@ -325,15 +322,15 @@ namespace Juliet::D3D12
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Disable DXGI window crap
|
// Disable DXGI window crap
|
||||||
result = IDXGIFactory1_MakeWindowAssociation(parentFactory, windowHandle, DXGI_MWA_NO_WINDOW_CHANGES);
|
result = parentFactory->MakeWindowAssociation(windowHandle, DXGI_MWA_NO_WINDOW_CHANGES);
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
Log(LogLevel::Warning, LogCategory::Graphics, "MakeWindowAssociation failed! Error Code: " HRESULT_FMT, result);
|
Log(LogLevel::Warning, LogCategory::Graphics, "MakeWindowAssociation failed! Error Code: " HRESULT_FMT, result);
|
||||||
}
|
}
|
||||||
IDXGIFactory1_Release(parentFactory);
|
parentFactory->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
IDXGISwapChain3_GetDesc1(swapChain3, &swapChainDesc);
|
swapChain3->GetDesc1(&swapChainDesc);
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
LogError(driver->D3D12Device, "Failed to retrieve SwapChain descriptor", result);
|
LogError(driver->D3D12Device, "Failed to retrieve SwapChain descriptor", result);
|
||||||
@@ -351,7 +348,7 @@ namespace Juliet::D3D12
|
|||||||
{
|
{
|
||||||
if (!CreateSwapChainTexture(driver, swapChain3, composition, &windowData->SwapChainTextureContainers[idx], idx))
|
if (!CreateSwapChainTexture(driver, swapChain3, composition, &windowData->SwapChainTextureContainers[idx], idx))
|
||||||
{
|
{
|
||||||
IDXGISwapChain3_Release(swapChain3);
|
swapChain3->Release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -372,7 +369,7 @@ namespace Juliet::D3D12
|
|||||||
Free(windowData->SwapChainTextureContainers[idx].Textures);
|
Free(windowData->SwapChainTextureContainers[idx].Textures);
|
||||||
}
|
}
|
||||||
|
|
||||||
IDXGISwapChain_Release(windowData->SwapChain);
|
windowData->SwapChain->Release();
|
||||||
windowData->SwapChain = nullptr;
|
windowData->SwapChain = nullptr;
|
||||||
}
|
}
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -35,12 +35,12 @@ namespace Juliet::D3D12
|
|||||||
if (d3d12driver->GraphicsQueue)
|
if (d3d12driver->GraphicsQueue)
|
||||||
{
|
{
|
||||||
// Insert a signal into the end of the command queue...
|
// Insert a signal into the end of the command queue...
|
||||||
ID3D12CommandQueue_Signal(d3d12driver->GraphicsQueue, fence->Handle, D3D12_FENCE_SIGNAL_VALUE);
|
d3d12driver->GraphicsQueue->Signal(fence->Handle, D3D12_FENCE_SIGNAL_VALUE);
|
||||||
|
|
||||||
// ...and then block on it.
|
// ...and then block on it.
|
||||||
if (ID3D12Fence_GetCompletedValue(fence->Handle) != D3D12_FENCE_SIGNAL_VALUE)
|
if (fence->Handle->GetCompletedValue() != D3D12_FENCE_SIGNAL_VALUE)
|
||||||
{
|
{
|
||||||
HRESULT result = ID3D12Fence_SetEventOnCompletion(fence->Handle, D3D12_FENCE_SIGNAL_VALUE, fence->Event);
|
HRESULT result = fence->Handle->SetEventOnCompletion(D3D12_FENCE_SIGNAL_VALUE, fence->Event);
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
LogError(d3d12driver->D3D12Device, "Setting fence event failed!", result);
|
LogError(d3d12driver->D3D12Device, "Setting fence event failed!", result);
|
||||||
@@ -82,7 +82,7 @@ namespace Juliet::D3D12
|
|||||||
{
|
{
|
||||||
auto fence = reinterpret_cast<D3D12Fence*>(fences[i]);
|
auto fence = reinterpret_cast<D3D12Fence*>(fences[i]);
|
||||||
|
|
||||||
HRESULT res = ID3D12Fence_SetEventOnCompletion(fence->Handle, D3D12_FENCE_SIGNAL_VALUE, fence->Event);
|
HRESULT res = fence->Handle->SetEventOnCompletion(D3D12_FENCE_SIGNAL_VALUE, fence->Event);
|
||||||
if (FAILED(res))
|
if (FAILED(res))
|
||||||
{
|
{
|
||||||
LogError(d3d12driver->D3D12Device, "Setting fence event failed!", res);
|
LogError(d3d12driver->D3D12Device, "Setting fence event failed!", res);
|
||||||
@@ -104,7 +104,7 @@ namespace Juliet::D3D12
|
|||||||
// Clean up
|
// Clean up
|
||||||
for (int32 idx = d3d12driver->SubmittedCommandListCount - 1; idx >= 0; --idx -= 1)
|
for (int32 idx = d3d12driver->SubmittedCommandListCount - 1; idx >= 0; --idx -= 1)
|
||||||
{
|
{
|
||||||
uint64 fenceValue = ID3D12Fence_GetCompletedValue(d3d12driver->SubmittedCommandLists[idx]->InFlightFence->Handle);
|
uint64 fenceValue = d3d12driver->SubmittedCommandLists[idx]->InFlightFence->Handle->GetCompletedValue();
|
||||||
if (fenceValue == D3D12_FENCE_SIGNAL_VALUE)
|
if (fenceValue == D3D12_FENCE_SIGNAL_VALUE)
|
||||||
{
|
{
|
||||||
result &= Internal::CleanCommandList(d3d12driver, d3d12driver->SubmittedCommandLists[idx], false);
|
result &= Internal::CleanCommandList(d3d12driver, d3d12driver->SubmittedCommandLists[idx], false);
|
||||||
@@ -166,7 +166,7 @@ namespace Juliet::D3D12
|
|||||||
|
|
||||||
if (numBarriers > 0)
|
if (numBarriers > 0)
|
||||||
{
|
{
|
||||||
ID3D12GraphicsCommandList_ResourceBarrier(commandList->GraphicsCommandList.CommandList, numBarriers, barrierDesc);
|
commandList->GraphicsCommandList.CommandList->ResourceBarrier(numBarriers, barrierDesc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +179,7 @@ namespace Juliet::D3D12
|
|||||||
|
|
||||||
if (driver->AvailableFenceCount == 0)
|
if (driver->AvailableFenceCount == 0)
|
||||||
{
|
{
|
||||||
HRESULT result = ID3D12Device_CreateFence(driver->D3D12Device, D3D12_FENCE_UNSIGNALED_VALUE, D3D12_FENCE_FLAG_NONE,
|
HRESULT result = driver->D3D12Device->CreateFence(D3D12_FENCE_UNSIGNALED_VALUE, D3D12_FENCE_FLAG_NONE,
|
||||||
IID_ID3D12Fence, reinterpret_cast<void**>(&handle));
|
IID_ID3D12Fence, reinterpret_cast<void**>(&handle));
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
@@ -190,7 +190,7 @@ namespace Juliet::D3D12
|
|||||||
fence = static_cast<D3D12Fence*>(Calloc(1, sizeof(D3D12Fence)));
|
fence = static_cast<D3D12Fence*>(Calloc(1, sizeof(D3D12Fence)));
|
||||||
if (!fence)
|
if (!fence)
|
||||||
{
|
{
|
||||||
ID3D12Fence_Release(handle);
|
handle->Release();
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -202,7 +202,7 @@ namespace Juliet::D3D12
|
|||||||
{
|
{
|
||||||
fence = driver->AvailableFences[driver->AvailableFenceCount - 1];
|
fence = driver->AvailableFences[driver->AvailableFenceCount - 1];
|
||||||
driver->AvailableFenceCount -= 1;
|
driver->AvailableFenceCount -= 1;
|
||||||
ID3D12Fence_Signal(fence->Handle, D3D12_FENCE_UNSIGNALED_VALUE);
|
fence->Handle->Signal(D3D12_FENCE_UNSIGNALED_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
fence->ReferenceCount += 1;
|
fence->ReferenceCount += 1;
|
||||||
@@ -213,7 +213,7 @@ namespace Juliet::D3D12
|
|||||||
{
|
{
|
||||||
if (fence->Handle)
|
if (fence->Handle)
|
||||||
{
|
{
|
||||||
ID3D12Fence_Release(fence->Handle);
|
fence->Handle->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fence->Event)
|
if (fence->Event)
|
||||||
|
|||||||
@@ -426,7 +426,7 @@ namespace Juliet::D3D12
|
|||||||
pClearValue = &clearValue;
|
pClearValue = &clearValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT hr = ID3D12Device_CreateCommittedResource(d3d12Driver->D3D12Device, &heapProps, D3D12_HEAP_FLAG_NONE, &desc,
|
HRESULT hr = d3d12Driver->D3D12Device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &desc,
|
||||||
D3D12_RESOURCE_STATE_COMMON, pClearValue, IID_ID3D12Resource,
|
D3D12_RESOURCE_STATE_COMMON, pClearValue, IID_ID3D12Resource,
|
||||||
reinterpret_cast<void**>(&resource));
|
reinterpret_cast<void**>(&resource));
|
||||||
|
|
||||||
@@ -477,7 +477,7 @@ namespace Juliet::D3D12
|
|||||||
rtvDesc.Format = desc.Format;
|
rtvDesc.Format = desc.Format;
|
||||||
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
|
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
|
||||||
rtvDesc.Texture2D.MipSlice = mip;
|
rtvDesc.Texture2D.MipSlice = mip;
|
||||||
ID3D12Device_CreateRenderTargetView(d3d12Driver->D3D12Device, resource, &rtvDesc, sub.RTVHandles[0].CpuHandle);
|
d3d12Driver->D3D12Device->CreateRenderTargetView(resource, &rtvDesc, sub.RTVHandles[0].CpuHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((createInfo.Flags & TextureUsageFlag::DepthStencilTarget) != TextureUsageFlag::None)
|
if ((createInfo.Flags & TextureUsageFlag::DepthStencilTarget) != TextureUsageFlag::None)
|
||||||
@@ -488,12 +488,48 @@ namespace Juliet::D3D12
|
|||||||
dsvDesc.Format = Internal::ConvertToD3D12DepthFormat(createInfo.Format);
|
dsvDesc.Format = Internal::ConvertToD3D12DepthFormat(createInfo.Format);
|
||||||
dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
|
dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
|
||||||
dsvDesc.Texture2D.MipSlice = mip;
|
dsvDesc.Texture2D.MipSlice = mip;
|
||||||
ID3D12Device_CreateDepthStencilView(d3d12Driver->D3D12Device, resource, &dsvDesc, sub.DSVHandle.CpuHandle);
|
d3d12Driver->D3D12Device->CreateDepthStencilView(resource, &dsvDesc, sub.DSVHandle.CpuHandle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create SRV for sampled/readable textures (bindless access)
|
||||||
|
// Assign to the bindless CBV_SRV_UAV heap
|
||||||
|
{
|
||||||
|
Internal::D3D12Descriptor descriptor;
|
||||||
|
if (Internal::AssignDescriptor(d3d12Driver->BindlessDescriptorHeap, descriptor))
|
||||||
|
{
|
||||||
|
texture->SRVHandle = D3D12StagingDescriptor{};
|
||||||
|
texture->SRVHandle.CpuHandleIndex = descriptor.Index;
|
||||||
|
texture->SRVHandle.CpuHandle = descriptor.CpuHandle;
|
||||||
|
texture->SRVHandle.Heap = descriptor.Heap;
|
||||||
|
|
||||||
|
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
|
||||||
|
srvDesc.Format = desc.Format;
|
||||||
|
|
||||||
|
// Fix SRV format for Depth Buffers (TypeLess -> Typed)
|
||||||
|
if (createInfo.Format == TextureFormat::D32_FLOAT)
|
||||||
|
srvDesc.Format = DXGI_FORMAT_R32_FLOAT;
|
||||||
|
else if (createInfo.Format == TextureFormat::D16_UNORM)
|
||||||
|
srvDesc.Format = DXGI_FORMAT_R16_UNORM;
|
||||||
|
else if (createInfo.Format == TextureFormat::D24_UNORM_S8_UINT)
|
||||||
|
srvDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
|
||||||
|
else if (createInfo.Format == TextureFormat::D32_FLOAT_S8_UINT)
|
||||||
|
srvDesc.Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
|
||||||
|
|
||||||
|
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||||
|
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
|
||||||
|
srvDesc.Texture2D.MostDetailedMip = 0;
|
||||||
|
srvDesc.Texture2D.MipLevels = numMips;
|
||||||
|
srvDesc.Texture2D.PlaneSlice = 0;
|
||||||
|
srvDesc.Texture2D.ResourceMinLODClamp = 0.0f;
|
||||||
|
|
||||||
|
d3d12Driver->D3D12Device->CreateShaderResourceView(resource, &srvDesc, descriptor.CpuHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return reinterpret_cast<Texture*>(textureContainer);
|
return reinterpret_cast<Texture*>(textureContainer);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DestroyTexture(NonNullPtr<GPUDriver> driver, NonNullPtr<Texture> texture)
|
void DestroyTexture(NonNullPtr<GPUDriver> driver, NonNullPtr<Texture> texture)
|
||||||
@@ -517,7 +553,7 @@ namespace Juliet::D3D12
|
|||||||
Internal::ReleaseStagingDescriptor(d3d12Driver, sub.DSVHandle);
|
Internal::ReleaseStagingDescriptor(d3d12Driver, sub.DSVHandle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ID3D12Resource_Release(d3d12Texture->Resource);
|
d3d12Texture->Resource->Release();
|
||||||
Free(d3d12Texture->Subresources);
|
Free(d3d12Texture->Subresources);
|
||||||
Free(d3d12Texture);
|
Free(d3d12Texture);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace Juliet::D3D12
|
|||||||
|
|
||||||
if (result == DXGI_ERROR_DEVICE_REMOVED)
|
if (result == DXGI_ERROR_DEVICE_REMOVED)
|
||||||
{
|
{
|
||||||
result = ID3D12Device_GetDeviceRemovedReason(D3D12Device);
|
result = D3D12Device->GetDeviceRemovedReason();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to get the message from the system errors.
|
// Try to get the message from the system errors.
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
#include <Core/Logging/LogTypes.h>
|
#include <Core/Logging/LogTypes.h>
|
||||||
#include <Graphics/Graphics.h>
|
#include <Graphics/Graphics.h>
|
||||||
#include <Graphics/GraphicsDevice.h>
|
#include <Graphics/GraphicsDevice.h>
|
||||||
|
#include <Core/ImGui/ImGuiTests.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Juliet
|
namespace Juliet
|
||||||
{
|
{
|
||||||
@@ -57,9 +59,11 @@ namespace Juliet
|
|||||||
{
|
{
|
||||||
if (GraphicsDevice* newDevice = chosenFactory->CreateGraphicsDevice(config.EnableDebug))
|
if (GraphicsDevice* newDevice = chosenFactory->CreateGraphicsDevice(config.EnableDebug))
|
||||||
{
|
{
|
||||||
|
|
||||||
newDevice->Name = chosenFactory->Name;
|
newDevice->Name = chosenFactory->Name;
|
||||||
return newDevice;
|
return newDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -259,6 +263,16 @@ namespace Juliet
|
|||||||
commandListHeader->Device->SetStencilReference(commandList, reference);
|
commandListHeader->Device->SetStencilReference(commandList, reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetIndexBuffer(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> buffer, IndexFormat format)
|
||||||
|
{
|
||||||
|
auto* commandListHeader = reinterpret_cast<CommandListHeader*>(commandList.Get());
|
||||||
|
|
||||||
|
if (commandListHeader->Device->SetIndexBuffer)
|
||||||
|
{
|
||||||
|
commandListHeader->Device->SetIndexBuffer(commandList, buffer, format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BindGraphicsPipeline(NonNullPtr<RenderPass> renderPass, NonNullPtr<GraphicsPipeline> graphicsPipeline)
|
void BindGraphicsPipeline(NonNullPtr<RenderPass> renderPass, NonNullPtr<GraphicsPipeline> graphicsPipeline)
|
||||||
{
|
{
|
||||||
auto* commandList = reinterpret_cast<GPUPass*>(renderPass.Get())->CommandList;
|
auto* commandList = reinterpret_cast<GPUPass*>(renderPass.Get())->CommandList;
|
||||||
@@ -275,6 +289,21 @@ namespace Juliet
|
|||||||
commandListHeader->Device->DrawPrimitives(commandList, numVertices, numInstances, firstVertex, firstInstance);
|
commandListHeader->Device->DrawPrimitives(commandList, numVertices, numInstances, firstVertex, firstInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DrawIndexedPrimitives(NonNullPtr<RenderPass> renderPass, uint32 numIndices, uint32 numInstances,
|
||||||
|
uint32 firstIndex, uint32 vertexOffset, uint32 firstInstance)
|
||||||
|
{
|
||||||
|
auto* commandList = reinterpret_cast<GPUPass*>(renderPass.Get())->CommandList;
|
||||||
|
auto* commandListHeader = reinterpret_cast<CommandListHeader*>(commandList);
|
||||||
|
|
||||||
|
if (commandListHeader->Device->DrawIndexedPrimitives)
|
||||||
|
{
|
||||||
|
commandListHeader->Device->DrawIndexedPrimitives(commandList, numIndices, numInstances, firstIndex, vertexOffset, firstInstance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SetPushConstants(NonNullPtr<CommandList> commandList, ShaderStage stage, uint32 rootParameterIndex,
|
void SetPushConstants(NonNullPtr<CommandList> commandList, ShaderStage stage, uint32 rootParameterIndex,
|
||||||
uint32 numConstants, const void* constants)
|
uint32 numConstants, const void* constants)
|
||||||
{
|
{
|
||||||
@@ -366,10 +395,21 @@ namespace Juliet
|
|||||||
void CopyBuffer(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> dst,
|
void CopyBuffer(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> dst,
|
||||||
NonNullPtr<GraphicsTransferBuffer> src, size_t size, size_t dstOffset, size_t srcOffset)
|
NonNullPtr<GraphicsTransferBuffer> src, size_t size, size_t dstOffset, size_t srcOffset)
|
||||||
{
|
{
|
||||||
auto* header = reinterpret_cast<CommandListHeader*>(commandList.Get());
|
auto* headers = reinterpret_cast<CommandListHeader*>(commandList.Get());
|
||||||
header->Device->CopyBuffer(commandList, dst, src, size, dstOffset, srcOffset);
|
headers->Device->CopyBuffer(commandList, dst, src, size, dstOffset, srcOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CopyBufferToTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Texture> dst,
|
||||||
|
NonNullPtr<GraphicsTransferBuffer> src)
|
||||||
|
{
|
||||||
|
auto* headers = reinterpret_cast<CommandListHeader*>(commandList.Get());
|
||||||
|
if (headers->Device->CopyBufferToTexture)
|
||||||
|
{
|
||||||
|
headers->Device->CopyBufferToTexture(commandList, dst, src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void TransitionBufferToReadable(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> buffer)
|
void TransitionBufferToReadable(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> buffer)
|
||||||
{
|
{
|
||||||
auto* header = reinterpret_cast<CommandListHeader*>(commandList.Get());
|
auto* header = reinterpret_cast<CommandListHeader*>(commandList.Get());
|
||||||
@@ -378,9 +418,15 @@ namespace Juliet
|
|||||||
|
|
||||||
uint32 GetDescriptorIndex(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer)
|
uint32 GetDescriptorIndex(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer)
|
||||||
{
|
{
|
||||||
return device->GetDescriptorIndex(device->Driver, buffer);
|
return device->GetDescriptorIndex(device, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 GetDescriptorIndex(NonNullPtr<GraphicsDevice> device, NonNullPtr<Texture> texture)
|
||||||
|
{
|
||||||
|
return device->GetDescriptorIndexTexture(device, texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DestroyGraphicsBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer)
|
void DestroyGraphicsBuffer(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer)
|
||||||
{
|
{
|
||||||
device->DestroyGraphicsBuffer(buffer);
|
device->DestroyGraphicsBuffer(buffer);
|
||||||
|
|||||||
@@ -66,10 +66,16 @@ namespace Juliet
|
|||||||
void (*SetScissorRect)(NonNullPtr<CommandList> commandList, const Rectangle& viewPort);
|
void (*SetScissorRect)(NonNullPtr<CommandList> commandList, const Rectangle& viewPort);
|
||||||
void (*SetBlendConstants)(NonNullPtr<CommandList> commandList, FColor blendConstants);
|
void (*SetBlendConstants)(NonNullPtr<CommandList> commandList, FColor blendConstants);
|
||||||
void (*SetStencilReference)(NonNullPtr<CommandList> commandList, uint8 reference);
|
void (*SetStencilReference)(NonNullPtr<CommandList> commandList, uint8 reference);
|
||||||
|
void (*SetIndexBuffer)(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> buffer, IndexFormat format);
|
||||||
|
|
||||||
void (*BindGraphicsPipeline)(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsPipeline> graphicsPipeline);
|
void (*BindGraphicsPipeline)(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsPipeline> graphicsPipeline);
|
||||||
void (*DrawPrimitives)(NonNullPtr<CommandList> commandList, uint32 numVertices, uint32 numInstances,
|
void (*DrawPrimitives)(NonNullPtr<CommandList> commandList, uint32 numVertices, uint32 numInstances,
|
||||||
uint32 firstVertex, uint32 firstInstance);
|
uint32 firstVertex, uint32 firstInstance);
|
||||||
|
void (*DrawIndexedPrimitives)(NonNullPtr<CommandList> commandList, uint32 numIndices, uint32 numInstances,
|
||||||
|
uint32 firstIndex, uint32 vertexOffset, uint32 firstInstance);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void (*SetPushConstants)(NonNullPtr<CommandList> commandList, ShaderStage stage, uint32 rootParameterIndex,
|
void (*SetPushConstants)(NonNullPtr<CommandList> commandList, ShaderStage stage, uint32 rootParameterIndex,
|
||||||
uint32 numConstants, const void* constants);
|
uint32 numConstants, const void* constants);
|
||||||
@@ -102,10 +108,14 @@ namespace Juliet
|
|||||||
|
|
||||||
void* (*MapGraphicsTransferBuffer)(NonNullPtr<GPUDriver> driver, NonNullPtr<GraphicsTransferBuffer> buffer);
|
void* (*MapGraphicsTransferBuffer)(NonNullPtr<GPUDriver> driver, NonNullPtr<GraphicsTransferBuffer> buffer);
|
||||||
void (*UnmapGraphicsTransferBuffer)(NonNullPtr<GPUDriver> driver, NonNullPtr<GraphicsTransferBuffer> buffer);
|
void (*UnmapGraphicsTransferBuffer)(NonNullPtr<GPUDriver> driver, NonNullPtr<GraphicsTransferBuffer> buffer);
|
||||||
void (*CopyBuffer)(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> dst,
|
void (*CopyBuffer)(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> dst,
|
||||||
NonNullPtr<GraphicsTransferBuffer> src, size_t size, size_t dstOffset, size_t srcOffset);
|
NonNullPtr<GraphicsTransferBuffer> src, size_t size, size_t dstOffset, size_t srcOffset);
|
||||||
|
void (*CopyBufferToTexture)(NonNullPtr<CommandList> commandList, NonNullPtr<Texture> dst,
|
||||||
|
NonNullPtr<GraphicsTransferBuffer> src); // Assume full copy for now
|
||||||
|
|
||||||
void (*TransitionBufferToReadable)(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> buffer);
|
void (*TransitionBufferToReadable)(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> buffer);
|
||||||
uint32 (*GetDescriptorIndex)(NonNullPtr<GPUDriver> driver, NonNullPtr<GraphicsBuffer> buffer);
|
uint32 (*GetDescriptorIndex)(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsBuffer> buffer);
|
||||||
|
uint32 (*GetDescriptorIndexTexture)(NonNullPtr<GraphicsDevice> device, NonNullPtr<Texture> texture);
|
||||||
|
|
||||||
const char* Name = "Unknown";
|
const char* Name = "Unknown";
|
||||||
GPUDriver* Driver = nullptr;
|
GPUDriver* Driver = nullptr;
|
||||||
|
|||||||
Reference in New Issue
Block a user