Compare commits
2 Commits
59ffe1cef8
...
f11f02d0c7
| Author | SHA1 | Date | |
|---|---|---|---|
| f11f02d0c7 | |||
| 8d29fbd111 |
86
AgentData/Imgui.md
Normal file
86
AgentData/Imgui.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# ImGui Integration & Memory Debugger
|
||||
|
||||
## Task List
|
||||
|
||||
- [ ] **Preparation**
|
||||
- [x] Fetch Dear ImGui Source Files (Verified existing submodule)
|
||||
- [x] Create `External/imgui/Imgui.bff`
|
||||
- [x] Update `fbuild.bff` to include `Imgui.bff`
|
||||
- [x] Update `Juliet.bff` to link `ImGui` and include paths
|
||||
- [x] Update `D3D12DescriptorHeap` to support ImGui (SRV for Font)
|
||||
|
||||
- [ ] **Memory Arena Debugging**
|
||||
- [x] Modify `MemoryArena` struct to store allocation tags (Debug builds only)
|
||||
- [x] Update `ArenaPush` signature to accept `const char* tag`
|
||||
- [x] Update call sites (default parameter should minimize churn)
|
||||
|
||||
- [ ] **ImGui Core & TDD**
|
||||
- [x] Create `Core/ImGui/ImGuiService.h/cpp` (Wrapper)
|
||||
- [x] Create `Core/ImGui/ImGuiTests.cpp`
|
||||
- [x] Implement `ImGui::SetAllocatorFunctions` using `EngineArena`
|
||||
- [x] Test context creation and IO setup
|
||||
|
||||
- [ ] **Integration**
|
||||
- [ ] Win32: Integrate `WndProc` in `Win32DisplayEvent.cpp`
|
||||
- [x] DX12: Initialize/Shutdown in `D3D12GraphicsDevice` (Implemented in `ImGuiRenderer.cpp`)
|
||||
- [x] DX12: Render Frame in `D3D12GraphicsDevice` (Fixed Buffer Crash)
|
||||
|
||||
- [ ] **Memory Debugger**
|
||||
- [x] Create `Engine/Debug/MemoryDebugger.h/cpp`
|
||||
- [x] Implement `DrawMemoryArena(const char* name, MemoryArena* arena)` with Allocation Tags
|
||||
- [x] Implement Hex View for Arena Data (Allocations list implemented, Hex view pending/skipped)
|
||||
- [x] Integrate into Main Loop (Toggle with 'Home' key)
|
||||
|
||||
- [ ] **Verification**
|
||||
- [ ] Launch and verify ImGui renders
|
||||
- [x] Verify Memory Debugger shows allocations and tags
|
||||
|
||||
---
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
### Goal Description
|
||||
Integrate Dear ImGui into the Juliet engine.
|
||||
Implement a specialized Test Driven Development (TDD) approach.
|
||||
Create a Memory Debugger panel to visualize `MemoryArena` state with allocation tags.
|
||||
|
||||
### Proposed Changes
|
||||
|
||||
#### Build System
|
||||
**[NEW] [Imgui.bff](file:///w:/Classified/Juliet/External/imgui/Imgui.bff)**
|
||||
- Defines the `ImGui` library configuration.
|
||||
- Includes `imgui.cpp`, `imgui_draw.cpp`, `imgui_tables.cpp`, `imgui_widgets.cpp`, `imgui_demo.cpp`.
|
||||
- Includes backends: `imgui_impl_win32.cpp`, `imgui_impl_dx12.cpp`.
|
||||
|
||||
**[MODIFY] [fbuild.bff](file:///w:/Classified/Juliet/fbuild.bff)**
|
||||
- Include `External/imgui/Imgui.bff`.
|
||||
|
||||
**[MODIFY] [Juliet.bff](file:///w:/Classified/Juliet/Juliet/Juliet.bff)**
|
||||
- Add `ImGui` to `Juliet` library dependencies.
|
||||
- Add `External/imgui` and `External/imgui/backends` to include paths.
|
||||
|
||||
#### Core/Memory
|
||||
**[MODIFY] [MemoryArena.h](file:///w:/Classified/Juliet/Juliet/include/Core/Memory/MemoryArena.h)**
|
||||
**[MODIFY] [MemoryArena.cpp](file:///w:/Classified/Juliet/Juliet/src/Core/Memory/MemoryArena.cpp)**
|
||||
- **Struct Change**: Add `AllocationTracking` vector (likely `std::vector` wrapped or fixed size array) in `JULIET_DEBUG`.
|
||||
- **Function Change**: `ArenaPush(..., const char* tag = nullptr)`.
|
||||
- **Logic**: Store offset + tag on push.
|
||||
|
||||
#### Core/ImGui
|
||||
**[NEW] [ImGuiService.h](file:///w:/Classified/Juliet/Juliet/include/Core/ImGui/ImGuiService.h)**
|
||||
**[NEW] [ImGuiService.cpp](file:///w:/Classified/Juliet/Juliet/src/Core/ImGui/ImGuiService.cpp)**
|
||||
- Wrapper for ImGui lifecycle.
|
||||
- Uses `EngineArena` for internal ImGui allocations.
|
||||
|
||||
**[NEW] [ImGuiTests.cpp](file:///w:/Classified/Juliet/Juliet/src/Core/ImGui/ImGuiTests.cpp)**
|
||||
- TDD suite for ImGui service.
|
||||
|
||||
#### Graphics/D3D12
|
||||
**[MODIFY] [D3D12GraphicsDevice.cpp](file:///w:/Classified/Juliet/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp)**
|
||||
- ImGui backend initialization and rendering.
|
||||
|
||||
#### Engine/Debug
|
||||
**[NEW] [MemoryDebugger.h](file:///w:/Classified/Juliet/Juliet/include/Engine/Debug/MemoryDebugger.h)**
|
||||
**[NEW] [MemoryDebugger.cpp](file:///w:/Classified/Juliet/Juliet/src/Engine/Debug/MemoryDebugger.cpp)**
|
||||
- Draw arena usage bar using tracked tags.
|
||||
- Draw hex dump.
|
||||
Binary file not shown.
@@ -5,7 +5,12 @@ cbuffer RootConstants : register(b0, space0)
|
||||
{
|
||||
row_major float4x4 ViewProjection;
|
||||
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
|
||||
|
||||
@@ -11,9 +11,8 @@ Output main(uint vertexIndex : SV_VertexID)
|
||||
Output output;
|
||||
|
||||
// Retrieve the buffer using SM6.6 bindless syntax
|
||||
// We use index 0 as the sample app doesn't pass push constants yet.
|
||||
uint bufferIndex = 0;
|
||||
ByteAddressBuffer buffer = ResourceDescriptorHeap[bufferIndex];
|
||||
// Use BufferIndex from RootConstants (pushed via SetPushConstants)
|
||||
ByteAddressBuffer buffer = ResourceDescriptorHeap[BufferIndex];
|
||||
|
||||
// Read position from buffer (Index * stride)
|
||||
// Stride = 2 float (pos) + 4 float (color) = 6 * 4 = 24 bytes ?
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
// For GET_X_LPARAM, GET_Y_LPARAM.
|
||||
#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
|
||||
@@ -147,8 +151,14 @@ namespace Juliet::Win32
|
||||
|
||||
LRESULT CALLBACK Win32MainWindowCallback(HWND handle, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (ImGui_ImplWin32_WndProcHandler(handle, message, wParam, lParam))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
LRESULT returnCode = -1;
|
||||
|
||||
|
||||
// Wait until the window state is created before doing anything
|
||||
auto* windowState = GetWindowStateFromHandle(handle);
|
||||
if (!windowState)
|
||||
|
||||
@@ -39,26 +39,15 @@ namespace Juliet
|
||||
}
|
||||
} // namespace
|
||||
|
||||
#if JULIET_DEBUG
|
||||
namespace UnitTest
|
||||
{
|
||||
extern void TestMemoryArena();
|
||||
}
|
||||
#endif
|
||||
|
||||
void JulietInit(JulietInit_Flags flags)
|
||||
{
|
||||
// Mandatory systems
|
||||
MemoryArenasInit();
|
||||
|
||||
#if JULIET_DEBUG
|
||||
UnitTest::TestMemoryArena();
|
||||
#endif
|
||||
|
||||
InitFilesystem();
|
||||
|
||||
// Optional systems
|
||||
if ((flags | JulietInit_Flags::Display) != JulietInit_Flags::None)
|
||||
if ((flags & JulietInit_Flags::Display) != JulietInit_Flags::None)
|
||||
{
|
||||
InitializeDisplaySystem();
|
||||
IncrementSystemRefCount(JulietInit_Flags::Display);
|
||||
|
||||
@@ -12,13 +12,6 @@ namespace Juliet::D3D12
|
||||
{
|
||||
namespace
|
||||
{
|
||||
struct D3D12Buffer
|
||||
{
|
||||
Internal::D3D12Descriptor Descriptor;
|
||||
ID3D12Resource* Handle;
|
||||
D3D12_RESOURCE_STATES CurrentState;
|
||||
};
|
||||
|
||||
enum class D3D12BufferType : uint8
|
||||
{
|
||||
Base,
|
||||
@@ -26,6 +19,30 @@ namespace Juliet::D3D12
|
||||
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)
|
||||
{
|
||||
if (!buffer)
|
||||
@@ -40,7 +57,7 @@ namespace Juliet::D3D12
|
||||
|
||||
if (buffer->Handle)
|
||||
{
|
||||
ID3D12Resource_Release(buffer->Handle);
|
||||
buffer->Handle->Release();
|
||||
}
|
||||
Free(buffer);
|
||||
}
|
||||
@@ -78,6 +95,7 @@ namespace Juliet::D3D12
|
||||
|
||||
case BufferUsage::IndexBuffer:
|
||||
case BufferUsage::StructuredBuffer:
|
||||
case BufferUsage::VertexBuffer:
|
||||
{
|
||||
heapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||
heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||
@@ -99,8 +117,13 @@ namespace Juliet::D3D12
|
||||
heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||
heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -130,7 +153,7 @@ namespace Juliet::D3D12
|
||||
|
||||
D3D12_RESOURCE_DESC desc = {};
|
||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
|
||||
desc.Alignment = 0;
|
||||
desc.Width = size;
|
||||
desc.Height = 1;
|
||||
desc.DepthOrArraySize = 1;
|
||||
@@ -141,13 +164,22 @@ namespace Juliet::D3D12
|
||||
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
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;
|
||||
HRESULT result = ID3D12Device_CreateCommittedResource(d3d12Driver->D3D12Device, &heapProperties, heapFlags,
|
||||
&desc, initialState, nullptr, IID_ID3D12Resource,
|
||||
reinterpret_cast<void**>(&handle));
|
||||
HRESULT result = d3d12Driver->D3D12Device->CreateCommittedResource(&heapProperties, heapFlags,
|
||||
&desc, initialState, nullptr,
|
||||
IID_ID3D12Resource, reinterpret_cast<void**>(&handle));
|
||||
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);
|
||||
return nullptr;
|
||||
}
|
||||
@@ -155,6 +187,7 @@ namespace Juliet::D3D12
|
||||
buffer->Handle = handle;
|
||||
buffer->CurrentState = initialState;
|
||||
buffer->Descriptor.Index = UINT32_MAX;
|
||||
buffer->Size = size;
|
||||
|
||||
if (usage == BufferUsage::ConstantBuffer || usage == BufferUsage::StructuredBuffer)
|
||||
{
|
||||
@@ -169,25 +202,22 @@ namespace Juliet::D3D12
|
||||
|
||||
if (usage == BufferUsage::ConstantBuffer)
|
||||
{
|
||||
cbvDesc.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(handle);
|
||||
cbvDesc.BufferLocation = handle->GetGPUVirtualAddress();
|
||||
cbvDesc.SizeInBytes = static_cast<uint32>(size);
|
||||
ID3D12Device_CreateConstantBufferView(d3d12Driver->D3D12Device, &cbvDesc, cpuHandle);
|
||||
d3d12Driver->D3D12Device->CreateConstantBufferView(&cbvDesc, cpuHandle);
|
||||
}
|
||||
else if (usage == BufferUsage::StructuredBuffer)
|
||||
{
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
|
||||
srvDesc.Format = DXGI_FORMAT_R32_TYPELESS;
|
||||
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
|
||||
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||
srvDesc.Buffer.FirstElement = 0;
|
||||
srvDesc.Buffer.NumElements = static_cast<uint32>(
|
||||
size / 4); // Assuming 4 bytes stride for raw access or similar. Ideally should be provided.
|
||||
srvDesc.Buffer.StructureByteStride = 0; // Raw buffer for simplicity, or 4 if typed?
|
||||
// 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.
|
||||
// Actually, let's treat it as a ByteAddressBuffer (Raw) for most flexibility in bindless.
|
||||
srvDesc.Format = DXGI_FORMAT_R32_TYPELESS;
|
||||
srvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_RAW;
|
||||
|
||||
ID3D12Device_CreateShaderResourceView(d3d12Driver->D3D12Device, handle, &srvDesc, cpuHandle);
|
||||
srvDesc.Buffer.NumElements = static_cast<uint32>(size / 4);
|
||||
srvDesc.Buffer.StructureByteStride = 0;
|
||||
srvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_RAW;
|
||||
d3d12Driver->D3D12Device->CreateShaderResourceView(handle, &srvDesc, cpuHandle);
|
||||
Log(LogLevel::Message, LogCategory::Graphics, " -> SRV DescriptorIndex=%u", descriptor.Index);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -230,7 +260,7 @@ namespace Juliet::D3D12
|
||||
void* ptr = nullptr;
|
||||
// 0-0 range means we don't intend to read anything.
|
||||
D3D12_RANGE readRange = { 0, 0 };
|
||||
if (FAILED(ID3D12Resource_Map(d3d12Buffer->Handle, 0, &readRange, &ptr)))
|
||||
if (FAILED(d3d12Buffer->Handle->Map(0, &readRange, &ptr)))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@@ -240,7 +270,7 @@ namespace Juliet::D3D12
|
||||
void UnmapBuffer(NonNullPtr<GPUDriver> /*driver*/, NonNullPtr<GraphicsTransferBuffer> buffer)
|
||||
{
|
||||
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)
|
||||
@@ -267,7 +297,7 @@ namespace Juliet::D3D12
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -275,7 +305,7 @@ namespace Juliet::D3D12
|
||||
// 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.
|
||||
|
||||
ID3D12GraphicsCommandList_CopyBufferRegion(d3d12CmdList->GraphicsCommandList.CommandList, d3d12Dst->Handle,
|
||||
d3d12CmdList->GraphicsCommandList.CommandList->CopyBufferRegion(d3d12Dst->Handle,
|
||||
dstOffset, d3d12Src->Handle, srcOffset, size);
|
||||
}
|
||||
|
||||
@@ -296,7 +326,7 @@ namespace Juliet::D3D12
|
||||
barrier.Transition.StateAfter = neededState;
|
||||
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||
|
||||
ID3D12GraphicsCommandList_ResourceBarrier(d3d12CmdList->GraphicsCommandList.CommandList, 1, &barrier);
|
||||
d3d12CmdList->GraphicsCommandList.CommandList->ResourceBarrier(1, &barrier);
|
||||
d3d12Buffer->CurrentState = neededState;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <Core/Common/NonNullPtr.h>
|
||||
#include <Core/Common/NonNullPtr.h>
|
||||
#include <Graphics/GraphicsBuffer.h>
|
||||
#include <Graphics/D3D12/D3D12DescriptorHeap.h>
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
@@ -10,6 +12,14 @@ namespace Juliet
|
||||
} // namespace Juliet
|
||||
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 void DestroyGraphicsBuffer(NonNullPtr<GraphicsBuffer> buffer);
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include <Core/Memory/Allocator.h>
|
||||
#include <Graphics/D3D12/D3D12CommandList.h>
|
||||
#include <Graphics/D3D12/D3D12CommandList.h>
|
||||
#include <Graphics/D3D12/D3D12Buffer.h>
|
||||
#include <Graphics/D3D12/D3D12GraphicsDevice.h>
|
||||
#include <Graphics/D3D12/D3D12Synchronization.h>
|
||||
#include <Graphics/D3D12/D3D12Utils.h>
|
||||
@@ -26,15 +28,14 @@ namespace Juliet::D3D12
|
||||
bool CreateAllocator(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12CommandListBaseData> baseData,
|
||||
D3D12_COMMAND_QUEUE_DESC queueDesc)
|
||||
{
|
||||
HRESULT result = ID3D12Device5_CreateCommandAllocator(driver->D3D12Device, queueDesc.Type, IID_ID3D12CommandAllocator,
|
||||
reinterpret_cast<void**>(&baseData->Allocator));
|
||||
HRESULT result = driver->D3D12Device->CreateCommandAllocator(queueDesc.Type, IID_ID3D12CommandAllocator, reinterpret_cast<void**>(&baseData->Allocator));
|
||||
if (FAILED(result))
|
||||
{
|
||||
AssertHR(result, "Cannot create ID3D12CommandAllocator");
|
||||
return false;
|
||||
}
|
||||
|
||||
ID3D12CommandAllocator_Reset(baseData->Allocator);
|
||||
baseData->Allocator->Reset();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -54,7 +55,7 @@ namespace Juliet::D3D12
|
||||
CreateAllocator(driver, &commandList->GraphicsCommandList, queueDesc);
|
||||
ID3D12GraphicsCommandList6* d3d12GraphicsCommandList = nullptr;
|
||||
HRESULT result =
|
||||
ID3D12Device5_CreateCommandList1(driver->D3D12Device, queueDesc.NodeMask, queueDesc.Type,
|
||||
driver->D3D12Device->CreateCommandList1(queueDesc.NodeMask, queueDesc.Type,
|
||||
D3D12_COMMAND_LIST_FLAG_NONE, IID_ID3D12GraphicsCommandList6,
|
||||
reinterpret_cast<void**>(&d3d12GraphicsCommandList));
|
||||
if (FAILED(result))
|
||||
@@ -65,8 +66,8 @@ namespace Juliet::D3D12
|
||||
}
|
||||
|
||||
commandList->GraphicsCommandList.CommandList = d3d12GraphicsCommandList;
|
||||
ID3D12GraphicsCommandList6_SetName(d3d12GraphicsCommandList, wide_str.c_str());
|
||||
ID3D12GraphicsCommandList6_Reset(d3d12GraphicsCommandList, commandList->GraphicsCommandList.Allocator, nullptr);
|
||||
d3d12GraphicsCommandList->SetName(wide_str.c_str());
|
||||
d3d12GraphicsCommandList->Reset(commandList->GraphicsCommandList.Allocator, nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -75,7 +76,7 @@ namespace Juliet::D3D12
|
||||
CreateAllocator(driver, &commandList->ComputeCommandList, queueDesc);
|
||||
ID3D12GraphicsCommandList6* d3d12GraphicsCommandList = nullptr;
|
||||
HRESULT result =
|
||||
ID3D12Device5_CreateCommandList1(driver->D3D12Device, queueDesc.NodeMask, queueDesc.Type,
|
||||
driver->D3D12Device->CreateCommandList1(queueDesc.NodeMask, queueDesc.Type,
|
||||
D3D12_COMMAND_LIST_FLAG_NONE, IID_ID3D12GraphicsCommandList6,
|
||||
reinterpret_cast<void**>(&d3d12GraphicsCommandList));
|
||||
if (FAILED(result))
|
||||
@@ -86,8 +87,8 @@ namespace Juliet::D3D12
|
||||
}
|
||||
|
||||
commandList->ComputeCommandList.CommandList = d3d12GraphicsCommandList;
|
||||
ID3D12GraphicsCommandList6_SetName(d3d12GraphicsCommandList, wide_str.c_str());
|
||||
ID3D12GraphicsCommandList6_Reset(d3d12GraphicsCommandList, commandList->ComputeCommandList.Allocator, nullptr);
|
||||
d3d12GraphicsCommandList->SetName(wide_str.c_str());
|
||||
d3d12GraphicsCommandList->Reset(commandList->ComputeCommandList.Allocator, nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -95,9 +96,8 @@ namespace Juliet::D3D12
|
||||
{
|
||||
CreateAllocator(driver, &commandList->CopyCommandList, queueDesc);
|
||||
ID3D12GraphicsCommandList* d3d12CopyCommandList = nullptr;
|
||||
HRESULT result = ID3D12Device5_CreateCommandList1(driver->D3D12Device, queueDesc.NodeMask, queueDesc.Type,
|
||||
D3D12_COMMAND_LIST_FLAG_NONE, IID_ID3D12GraphicsCommandList,
|
||||
reinterpret_cast<void**>(&d3d12CopyCommandList));
|
||||
HRESULT result = driver->D3D12Device->CreateCommandList1(queueDesc.NodeMask, queueDesc.Type,
|
||||
D3D12_COMMAND_LIST_FLAG_NONE, IID_ID3D12GraphicsCommandList, reinterpret_cast<void**>(&d3d12CopyCommandList));
|
||||
|
||||
if (FAILED(result))
|
||||
{
|
||||
@@ -105,8 +105,8 @@ namespace Juliet::D3D12
|
||||
return false;
|
||||
}
|
||||
commandList->CopyCommandList.CommandList = d3d12CopyCommandList;
|
||||
ID3D12GraphicsCommandList_SetName(d3d12CopyCommandList, wide_str.c_str());
|
||||
ID3D12GraphicsCommandList_Reset(d3d12CopyCommandList, commandList->CopyCommandList.Allocator, nullptr);
|
||||
d3d12CopyCommandList->SetName(wide_str.c_str());
|
||||
d3d12CopyCommandList->Reset(commandList->CopyCommandList.Allocator, nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -227,30 +227,21 @@ namespace Juliet::D3D12
|
||||
barrierDesc.Transition.pResource = subresource->Parent->Resource;
|
||||
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
|
||||
HRESULT result = ID3D12GraphicsCommandList_Close(d3d12CommandList->GraphicsCommandList.CommandList);
|
||||
HRESULT result = d3d12CommandList->GraphicsCommandList.CommandList->Close();
|
||||
if (FAILED(result))
|
||||
{
|
||||
LogError(d3d12Driver->D3D12Device, "Failed to close command list!", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
ID3D12CommandList* commandLists[1];
|
||||
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;
|
||||
}
|
||||
ID3D12CommandList* ppCommandLists[] = { d3d12CommandList->GraphicsCommandList.CommandList };
|
||||
|
||||
// Submit the command list to the queue
|
||||
ID3D12CommandQueue_ExecuteCommandLists(d3d12Driver->GraphicsQueue, 1, commandLists);
|
||||
|
||||
ID3D12CommandList_Release(commandLists[0]);
|
||||
d3d12Driver->GraphicsQueue->ExecuteCommandLists(1, ppCommandLists);
|
||||
|
||||
// Acquire a fence and set it to the in-flight fence
|
||||
d3d12CommandList->InFlightFence = Internal::AcquireFence(d3d12Driver);
|
||||
@@ -260,7 +251,7 @@ namespace Juliet::D3D12
|
||||
}
|
||||
|
||||
// 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))
|
||||
{
|
||||
LogError(d3d12Driver->D3D12Device, "Failed to enqueue fence signal!", result);
|
||||
@@ -299,14 +290,13 @@ namespace Juliet::D3D12
|
||||
presentFlags = DXGI_PRESENT_ALLOW_TEARING;
|
||||
}
|
||||
|
||||
result = IDXGISwapChain_Present(windowData->SwapChain, syncInterval, presentFlags);
|
||||
result = windowData->SwapChain->Present(syncInterval, presentFlags);
|
||||
if (FAILED(result))
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
|
||||
ID3D12Resource_Release(
|
||||
windowData->SwapChainTextureContainers[presentData->SwapChainImageIndex].ActiveTexture->Resource);
|
||||
windowData->SwapChainTextureContainers[presentData->SwapChainImageIndex].ActiveTexture->Resource->Release();
|
||||
|
||||
windowData->InFlightFences[windowData->WindowFrameCounter] = reinterpret_cast<Fence*>(d3d12CommandList->InFlightFence);
|
||||
d3d12CommandList->InFlightFence->ReferenceCount += 1;
|
||||
@@ -317,7 +307,7 @@ namespace Juliet::D3D12
|
||||
// Check for cleanups
|
||||
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)
|
||||
{
|
||||
success &= Internal::CleanCommandList(d3d12Driver, d3d12Driver->SubmittedCommandLists[i], false);
|
||||
@@ -342,7 +332,7 @@ namespace Juliet::D3D12
|
||||
d3d12Viewport.Height = viewPort.Height;
|
||||
d3d12Viewport.MinDepth = viewPort.MinDepth;
|
||||
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)
|
||||
@@ -353,20 +343,48 @@ namespace Juliet::D3D12
|
||||
scissorRect.top = rectangle.Y;
|
||||
scissorRect.right = rectangle.X + rectangle.Width;
|
||||
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)
|
||||
{
|
||||
auto* d3d12CommandList = reinterpret_cast<D3D12CommandList*>(commandList.Get());
|
||||
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)
|
||||
{
|
||||
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,
|
||||
@@ -374,7 +392,7 @@ namespace Juliet::D3D12
|
||||
{
|
||||
auto d3d12CommandList = reinterpret_cast<D3D12CommandList*>(commandList.Get());
|
||||
// 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);
|
||||
}
|
||||
|
||||
@@ -396,7 +414,7 @@ namespace Juliet::D3D12
|
||||
heaps[0] = viewHeap->Handle;
|
||||
heaps[1] = samplerHeap->Handle;
|
||||
|
||||
ID3D12GraphicsCommandList_SetDescriptorHeaps(commandList->GraphicsCommandList.CommandList, 2, heaps);
|
||||
commandList->GraphicsCommandList.CommandList->SetDescriptorHeaps(2, heaps);
|
||||
}
|
||||
|
||||
void DestroyCommandList(NonNullPtr<D3D12CommandList> commandList)
|
||||
@@ -404,10 +422,10 @@ namespace Juliet::D3D12
|
||||
// TODO : Handle other kind of command list (copy compute)
|
||||
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->UsedTextures);
|
||||
@@ -420,14 +438,14 @@ namespace Juliet::D3D12
|
||||
// No more presentation data
|
||||
commandList->PresentDataCount = 0;
|
||||
|
||||
HRESULT result = ID3D12CommandAllocator_Reset(commandList->GraphicsCommandList.Allocator);
|
||||
HRESULT result = commandList->GraphicsCommandList.Allocator->Reset();
|
||||
if (FAILED(result))
|
||||
{
|
||||
LogError(driver->D3D12Device, "Could not reset command allocator", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
result = ID3D12GraphicsCommandList_Reset(commandList->GraphicsCommandList.CommandList,
|
||||
result = commandList->GraphicsCommandList.CommandList->Reset(
|
||||
commandList->GraphicsCommandList.Allocator, nullptr);
|
||||
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 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);
|
||||
|
||||
namespace Internal
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Juliet::D3D12::Internal
|
||||
heapDesc.NodeMask = 0;
|
||||
|
||||
HRESULT result =
|
||||
ID3D12Device_CreateDescriptorHeap(driver->D3D12Device, &heapDesc, IID_ID3D12DescriptorHeap, (void**)&handle);
|
||||
driver->D3D12Device->CreateDescriptorHeap(&heapDesc, IID_ID3D12DescriptorHeap, (void**)&handle);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LogError(driver->D3D12Device, "Failed to create descriptor heap!", result);
|
||||
@@ -40,11 +40,11 @@ namespace Juliet::D3D12::Internal
|
||||
heap->HeapType = type;
|
||||
heap->MaxDescriptors = count;
|
||||
heap->Staging = isStaging;
|
||||
heap->DescriptorSize = ID3D12Device_GetDescriptorHandleIncrementSize(driver->D3D12Device, type);
|
||||
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(handle, &heap->DescriptorHeapCPUStart);
|
||||
heap->DescriptorSize = driver->D3D12Device->GetDescriptorHandleIncrementSize(type);
|
||||
heap->DescriptorHeapCPUStart = handle->GetCPUDescriptorHandleForHeapStart();
|
||||
if (!isStaging)
|
||||
{
|
||||
ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(handle, &heap->DescriptorHeapGPUStart);
|
||||
heap->DescriptorHeapGPUStart = handle->GetGPUDescriptorHandleForHeapStart();
|
||||
}
|
||||
|
||||
return heap;
|
||||
@@ -54,7 +54,7 @@ namespace Juliet::D3D12::Internal
|
||||
{
|
||||
if (heap->Handle)
|
||||
{
|
||||
ID3D12DescriptorHeap_Release(heap->Handle);
|
||||
heap->Handle->Release();
|
||||
}
|
||||
SafeFree(heap->FreeIndices);
|
||||
Free(heap.Get());
|
||||
|
||||
@@ -46,8 +46,8 @@ namespace Juliet::D3D12
|
||||
bool CheckResourceTypeTier(ID3D12Device5* device)
|
||||
{
|
||||
D3D12_FEATURE_DATA_D3D12_OPTIONS options = {};
|
||||
HRESULT result = ID3D12Device5_CheckFeatureSupport(device, D3D12_FEATURE_D3D12_OPTIONS, &options,
|
||||
sizeof(D3D12_FEATURE_DATA_D3D12_OPTIONS));
|
||||
HRESULT result =
|
||||
device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(D3D12_FEATURE_DATA_D3D12_OPTIONS));
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
if (options.ResourceBindingTier < D3D12_RESOURCE_BINDING_TIER_3)
|
||||
@@ -83,8 +83,8 @@ namespace Juliet::D3D12
|
||||
for (auto allModelVersion : allModelVersions)
|
||||
{
|
||||
shaderModel.HighestShaderModel = allModelVersion;
|
||||
HRESULT result = ID3D12Device5_CheckFeatureSupport(device, D3D12_FEATURE_SHADER_MODEL, &shaderModel,
|
||||
sizeof(D3D12_FEATURE_DATA_SHADER_MODEL));
|
||||
HRESULT result = device->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &shaderModel,
|
||||
sizeof(D3D12_FEATURE_DATA_SHADER_MODEL));
|
||||
if (result != E_INVALIDARG)
|
||||
{
|
||||
if (FAILED(result))
|
||||
@@ -142,40 +142,40 @@ namespace Juliet::D3D12
|
||||
|
||||
// Can query the 1.4 factory ?
|
||||
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))
|
||||
{
|
||||
IDXGIFactory1_Release(factory1);
|
||||
factory1->Release();
|
||||
Log(LogLevel::Warning, LogCategory::Graphics, "DX12: Failed to query DXGI1.4.");
|
||||
return false;
|
||||
}
|
||||
IDXGIFactory4_Release(factory4);
|
||||
factory4->Release();
|
||||
|
||||
// Check for 1.6. (It's not mandatory).
|
||||
IDXGIAdapter1* adapter = 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))
|
||||
{
|
||||
result = IDXGIFactory6_EnumAdapterByGpuPreference(factory6, 0, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE,
|
||||
IID_IDXGIAdapter1, reinterpret_cast<void**>(&adapter));
|
||||
IDXGIFactory6_Release(factory6);
|
||||
result = factory6->EnumAdapterByGpuPreference(0, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE,
|
||||
IID_IDXGIAdapter1, reinterpret_cast<void**>(&adapter));
|
||||
factory6->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
result = IDXGIFactory1_EnumAdapters1(factory1, 0, &adapter);
|
||||
result = factory1->EnumAdapters1(0, &adapter);
|
||||
}
|
||||
|
||||
if (FAILED(result))
|
||||
{
|
||||
Log(LogLevel::Warning, LogCategory::Graphics, "DX12: Failed to find an adapter for D3D12.");
|
||||
|
||||
IDXGIFactory1_Release(factory1);
|
||||
factory1->Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
bool driverIsValid = true;
|
||||
@@ -184,7 +184,7 @@ namespace Juliet::D3D12
|
||||
driverIsValid &= CheckShaderModel(device);
|
||||
driverIsValid &= CheckResourceTypeTier(device);
|
||||
|
||||
ID3D12Device5_Release(device);
|
||||
device->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -192,8 +192,8 @@ namespace Juliet::D3D12
|
||||
"DX12: Failed to create a D3D12Device with feature level %s.", kD3DFeatureLevelStr);
|
||||
driverIsValid = false;
|
||||
}
|
||||
IDXGIAdapter1_Release(adapter);
|
||||
IDXGIFactory1_Release(factory1);
|
||||
adapter->Release();
|
||||
factory1->Release();
|
||||
|
||||
return driverIsValid;
|
||||
}
|
||||
@@ -206,7 +206,7 @@ namespace Juliet::D3D12
|
||||
}
|
||||
if (rootSignature->Handle)
|
||||
{
|
||||
ID3D12RootSignature_Release(rootSignature->Handle);
|
||||
rootSignature->Handle->Release();
|
||||
}
|
||||
Free(rootSignature);
|
||||
}
|
||||
@@ -272,9 +272,10 @@ namespace Juliet::D3D12
|
||||
{
|
||||
if (errorBlob)
|
||||
{
|
||||
auto errorBuffer = ID3D10Blob_GetBufferPointer(errorBlob);
|
||||
auto errorBuffer = errorBlob->GetBufferPointer();
|
||||
LogError(LogCategory::Graphics, "Failed to serialize RootSignature: %s", errorBuffer);
|
||||
ID3D10Blob_Release(errorBlob);
|
||||
|
||||
errorBlob->Release();
|
||||
}
|
||||
DestroyGraphicsRootSignature(d3d12GraphicsRootSignature);
|
||||
return nullptr;
|
||||
@@ -282,16 +283,16 @@ namespace Juliet::D3D12
|
||||
|
||||
// Create the root signature
|
||||
ID3D12RootSignature* rootSignature;
|
||||
res = ID3D12Device_CreateRootSignature(d3d12Driver->D3D12Device, 0, ID3D10Blob_GetBufferPointer(serializedRootSignature),
|
||||
ID3D10Blob_GetBufferSize(serializedRootSignature),
|
||||
IID_ID3D12RootSignature, reinterpret_cast<void**>(&rootSignature));
|
||||
res = d3d12Driver->D3D12Device->CreateRootSignature(0, serializedRootSignature->GetBufferPointer(),
|
||||
serializedRootSignature->GetBufferSize(), IID_ID3D12RootSignature,
|
||||
reinterpret_cast<void**>(&rootSignature));
|
||||
if (FAILED(res))
|
||||
{
|
||||
if (errorBlob)
|
||||
{
|
||||
LogError(LogCategory::Graphics, "Failed to create RootSignature: %s",
|
||||
(const char*)ID3D10Blob_GetBufferPointer(errorBlob));
|
||||
ID3D10Blob_Release(errorBlob);
|
||||
(const char*)errorBlob->GetBufferPointer());
|
||||
errorBlob->Release();
|
||||
}
|
||||
DestroyGraphicsRootSignature(d3d12GraphicsRootSignature);
|
||||
return nullptr;
|
||||
@@ -332,12 +333,9 @@ namespace Juliet::D3D12
|
||||
}
|
||||
else
|
||||
{
|
||||
IDXGIInfoQueue_SetBreakOnSeverity(driver->DXGIInfoQueue, DXGI_DEBUG_ALL,
|
||||
DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, TRUE);
|
||||
IDXGIInfoQueue_SetBreakOnSeverity(driver->DXGIInfoQueue, DXGI_DEBUG_ALL,
|
||||
DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, TRUE);
|
||||
IDXGIInfoQueue_SetBreakOnSeverity(driver->DXGIInfoQueue, DXGI_DEBUG_ALL,
|
||||
DXGI_INFO_QUEUE_MESSAGE_SEVERITY_WARNING, TRUE);
|
||||
driver->DXGIInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, TRUE);
|
||||
driver->DXGIInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, TRUE);
|
||||
driver->DXGIInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_WARNING, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -346,9 +344,9 @@ namespace Juliet::D3D12
|
||||
{
|
||||
if (driver->DXGIDebug)
|
||||
{
|
||||
IDXGIDebug_ReportLiveObjects(driver->DXGIDebug, DXGI_DEBUG_ALL,
|
||||
static_cast<DXGI_DEBUG_RLO_FLAGS>(DXGI_DEBUG_RLO_SUMMARY | DXGI_DEBUG_RLO_DETAIL));
|
||||
IDXGIDebug_Release(driver->DXGIDebug);
|
||||
driver->DXGIDebug->ReportLiveObjects(DXGI_DEBUG_ALL, static_cast<DXGI_DEBUG_RLO_FLAGS>(
|
||||
DXGI_DEBUG_RLO_SUMMARY | DXGI_DEBUG_RLO_DETAIL));
|
||||
driver->DXGIDebug->Release();
|
||||
driver->DXGIDebug = nullptr;
|
||||
}
|
||||
|
||||
@@ -380,7 +378,7 @@ namespace Juliet::D3D12
|
||||
return;
|
||||
}
|
||||
|
||||
ID3D12Debug1_EnableDebugLayer(driver->D3D12Debug);
|
||||
driver->D3D12Debug->EnableDebugLayer();
|
||||
}
|
||||
|
||||
bool InitializeD3D12DebugInfoQueue(NonNullPtr<D3D12Driver> driver)
|
||||
@@ -388,8 +386,7 @@ namespace Juliet::D3D12
|
||||
ID3D12InfoQueue* infoQueue = nullptr;
|
||||
D3D12_MESSAGE_SEVERITY severities[] = { D3D12_MESSAGE_SEVERITY_INFO };
|
||||
|
||||
HRESULT result =
|
||||
ID3D12Device_QueryInterface(driver->D3D12Device, IID_ID3D12InfoQueue, reinterpret_cast<void**>(&infoQueue));
|
||||
HRESULT result = driver->D3D12Device->QueryInterface(IID_ID3D12InfoQueue, reinterpret_cast<void**>(&infoQueue));
|
||||
if (FAILED(result))
|
||||
{
|
||||
LogError(driver->D3D12Device, "Failed to convert ID3D12Device to ID3D12InfoQueue", result);
|
||||
@@ -399,14 +396,13 @@ namespace Juliet::D3D12
|
||||
D3D12_INFO_QUEUE_FILTER filter = {};
|
||||
filter.DenyList.NumSeverities = 1;
|
||||
filter.DenyList.pSeverityList = severities;
|
||||
ID3D12InfoQueue_PushStorageFilter(infoQueue, &filter);
|
||||
ID3D12InfoQueue_SetBreakOnSeverity(infoQueue, D3D12_MESSAGE_SEVERITY_CORRUPTION, true);
|
||||
ID3D12InfoQueue_Release(infoQueue);
|
||||
infoQueue->PushStorageFilter(&filter);
|
||||
// infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_CORRUPTION, true);
|
||||
infoQueue->Release();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef ID3D12InfoQueue1_SUPPORTED
|
||||
void WINAPI OnD3D12DebugInfoMsg(D3D12_MESSAGE_CATEGORY category, D3D12_MESSAGE_SEVERITY severity,
|
||||
D3D12_MESSAGE_ID id, LPCSTR description, void* /*context*/)
|
||||
{
|
||||
@@ -451,19 +447,16 @@ namespace Juliet::D3D12
|
||||
{
|
||||
// Only supported on Win 11 apparently
|
||||
ID3D12InfoQueue1* infoQueue = nullptr;
|
||||
HRESULT result =
|
||||
ID3D12Device5_QueryInterface(driver->D3D12Device, IID_ID3D12InfoQueue1, reinterpret_cast<void**>(&infoQueue));
|
||||
HRESULT result = driver->D3D12Device->QueryInterface(IID_ID3D12InfoQueue1, reinterpret_cast<void**>(&infoQueue));
|
||||
if (FAILED(result))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ID3D12InfoQueue1_RegisterMessageCallback(infoQueue, OnD3D12DebugInfoMsg, D3D12_MESSAGE_CALLBACK_FLAG_NONE,
|
||||
nullptr, nullptr);
|
||||
ID3D12InfoQueue1_Release(infoQueue);
|
||||
infoQueue->RegisterMessageCallback(OnD3D12DebugInfoMsg, D3D12_MESSAGE_CALLBACK_FLAG_NONE, nullptr, nullptr);
|
||||
infoQueue->Release();
|
||||
Log(LogLevel::Message, LogCategory::Graphics, "DX12: Debug Info Logger Initialized");
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
void DestroyDriver_Internal(NonNullPtr<D3D12Driver> driver)
|
||||
@@ -520,6 +513,7 @@ namespace Juliet::D3D12
|
||||
Internal::DestroyDescriptorHeap(driver->BindlessDescriptorHeap);
|
||||
|
||||
// Clean allocations
|
||||
|
||||
SafeFree(driver->AvailableCommandLists);
|
||||
SafeFree(driver->SubmittedCommandLists);
|
||||
SafeFree(driver->GraphicsPipelinesToDispose);
|
||||
@@ -528,41 +522,40 @@ namespace Juliet::D3D12
|
||||
|
||||
if (driver->IndirectDrawCommandSignature)
|
||||
{
|
||||
ID3D12CommandSignature_Release(driver->IndirectDrawCommandSignature);
|
||||
driver->IndirectDrawCommandSignature = nullptr;
|
||||
driver->IndirectDrawCommandSignature->Release();
|
||||
}
|
||||
if (driver->IndirectIndexedDrawCommandSignature)
|
||||
{
|
||||
ID3D12CommandSignature_Release(driver->IndirectIndexedDrawCommandSignature);
|
||||
driver->IndirectIndexedDrawCommandSignature->Release();
|
||||
driver->IndirectIndexedDrawCommandSignature = nullptr;
|
||||
}
|
||||
if (driver->IndirectDispatchCommandSignature)
|
||||
{
|
||||
ID3D12CommandSignature_Release(driver->IndirectDispatchCommandSignature);
|
||||
driver->IndirectDispatchCommandSignature->Release();
|
||||
driver->IndirectDispatchCommandSignature = nullptr;
|
||||
}
|
||||
|
||||
if (driver->GraphicsQueue)
|
||||
{
|
||||
ID3D12CommandQueue_Release(driver->GraphicsQueue);
|
||||
driver->GraphicsQueue->Release();
|
||||
driver->GraphicsQueue = nullptr;
|
||||
}
|
||||
|
||||
if (driver->D3D12Device)
|
||||
{
|
||||
ID3D12Device5_Release(driver->D3D12Device);
|
||||
driver->D3D12Device->Release();
|
||||
driver->D3D12Device = nullptr;
|
||||
}
|
||||
|
||||
if (driver->DXGIAdapter)
|
||||
{
|
||||
IDXGIAdapter1_Release(driver->DXGIAdapter);
|
||||
driver->DXGIAdapter->Release();
|
||||
driver->DXGIAdapter = nullptr;
|
||||
}
|
||||
|
||||
if (driver->DXGIFactory)
|
||||
{
|
||||
IDXGIFactory4_Release(driver->DXGIFactory);
|
||||
driver->DXGIFactory->Release();
|
||||
driver->DXGIFactory = nullptr;
|
||||
}
|
||||
|
||||
@@ -598,6 +591,7 @@ namespace Juliet::D3D12
|
||||
Log(LogLevel::Error, LogCategory::Graphics, "OOM: D3D12WindowData");
|
||||
return false;
|
||||
}
|
||||
d3d12Driver->WindowData = windowData;
|
||||
|
||||
windowData->Window = window;
|
||||
|
||||
@@ -609,7 +603,6 @@ namespace Juliet::D3D12
|
||||
}
|
||||
|
||||
d3d12Driver->WindowData = windowData;
|
||||
// TODO : React to resize. Need event system.
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -645,12 +638,116 @@ namespace Juliet::D3D12
|
||||
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)
|
||||
|
||||
{
|
||||
#if JULIET_DEBUG
|
||||
// Unit Tests for D3D12 Logic
|
||||
UnitTest::TestDescriptorHeapPool();
|
||||
|
||||
#endif
|
||||
auto driver = static_cast<D3D12Driver*>(Calloc(1, sizeof(D3D12Driver)));
|
||||
|
||||
@@ -671,7 +768,7 @@ namespace Juliet::D3D12
|
||||
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))
|
||||
{
|
||||
DestroyDriver_Internal(driver);
|
||||
@@ -679,43 +776,40 @@ namespace Juliet::D3D12
|
||||
"checked in CheckDriver");
|
||||
return nullptr;
|
||||
}
|
||||
IDXGIFactory1_Release(factory1);
|
||||
factory1->Release();
|
||||
|
||||
// Query DXGI1.5 and check for monitor Tearing support
|
||||
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))
|
||||
{
|
||||
bool isTearingSupported = false;
|
||||
result = IDXGIFactory5_CheckFeatureSupport(factory5, DXGI_FEATURE_PRESENT_ALLOW_TEARING,
|
||||
&isTearingSupported, sizeof(isTearingSupported));
|
||||
result = factory5->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &isTearingSupported,
|
||||
sizeof(isTearingSupported));
|
||||
driver->IsTearingSupported = isTearingSupported;
|
||||
if (FAILED(result))
|
||||
{
|
||||
driver->IsTearingSupported = false;
|
||||
}
|
||||
IDXGIFactory5_Release(factory5);
|
||||
factory5->Release();
|
||||
}
|
||||
|
||||
// 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.
|
||||
// Lets support not having it for now...
|
||||
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))
|
||||
{
|
||||
// TODO: Put into the config
|
||||
static constexpr bool useLowPower = false;
|
||||
result = IDXGIFactory6_EnumAdapterByGpuPreference(factory6, 0,
|
||||
useLowPower ? DXGI_GPU_PREFERENCE_MINIMUM_POWER
|
||||
: DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE,
|
||||
IID_IDXGIAdapter1,
|
||||
reinterpret_cast<void**>(&driver->DXGIAdapter));
|
||||
IDXGIFactory6_Release(factory6);
|
||||
result = factory6->EnumAdapterByGpuPreference(0, useLowPower ? DXGI_GPU_PREFERENCE_MINIMUM_POWER : DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE,
|
||||
IID_IDXGIAdapter1, reinterpret_cast<void**>(&driver->DXGIAdapter));
|
||||
factory6->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
result = IDXGIFactory4_EnumAdapters1(driver->DXGIFactory, 0, &driver->DXGIAdapter);
|
||||
result = driver->DXGIFactory->EnumAdapters1(0, &driver->DXGIAdapter);
|
||||
}
|
||||
|
||||
if (FAILED(result))
|
||||
@@ -727,7 +821,7 @@ namespace Juliet::D3D12
|
||||
|
||||
// Adapter is setup, get all the relevant info in the descriptor
|
||||
DXGI_ADAPTER_DESC1 adapterDesc;
|
||||
result = IDXGIAdapter1_GetDesc1(driver->DXGIAdapter, &adapterDesc);
|
||||
result = driver->DXGIAdapter->GetDesc1(&adapterDesc);
|
||||
if (FAILED(result))
|
||||
{
|
||||
DestroyDriver_Internal(driver);
|
||||
@@ -737,7 +831,7 @@ namespace Juliet::D3D12
|
||||
|
||||
// Driver version
|
||||
LARGE_INTEGER umdVersion;
|
||||
result = IDXGIAdapter1_CheckInterfaceSupport(driver->DXGIAdapter, IID_IDXGIDevice, &umdVersion);
|
||||
result = driver->DXGIAdapter->CheckInterfaceSupport(IID_IDXGIDevice, &umdVersion);
|
||||
if (FAILED(result))
|
||||
{
|
||||
DestroyDriver_Internal(driver);
|
||||
@@ -784,7 +878,7 @@ namespace Juliet::D3D12
|
||||
}
|
||||
#endif
|
||||
|
||||
result = D3D12CreateDeviceFuncPtr(reinterpret_cast<IUnknown*>(driver->DXGIAdapter), kD3DFeatureLevel,
|
||||
result = D3D12CreateDeviceFuncPtr(static_cast<IUnknown*>(driver->DXGIAdapter), kD3DFeatureLevel,
|
||||
IID_ID3D12Device5, reinterpret_cast<void**>(&driver->D3D12Device));
|
||||
if (FAILED(result))
|
||||
{
|
||||
@@ -793,6 +887,8 @@ namespace Juliet::D3D12
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Log(LogLevel::Message, LogCategory::Graphics, "DX12: D3D12Device Created: %p", (void*)driver->D3D12Device);
|
||||
|
||||
#if JULIET_DEBUG
|
||||
if (enableDebug)
|
||||
{
|
||||
@@ -800,17 +896,15 @@ namespace Juliet::D3D12
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
#ifdef ID3D12InfoQueue1_SUPPORTED
|
||||
InitializeD3D12DebugInfoLogger(driver);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check if UMA (unified memory architecture) is available. Used on APU i think ??
|
||||
D3D12_FEATURE_DATA_ARCHITECTURE architecture;
|
||||
architecture.NodeIndex = 0;
|
||||
result = ID3D12Device5_CheckFeatureSupport(driver->D3D12Device, D3D12_FEATURE_ARCHITECTURE, &architecture,
|
||||
sizeof(D3D12_FEATURE_DATA_ARCHITECTURE));
|
||||
result = driver->D3D12Device->CheckFeatureSupport(D3D12_FEATURE_ARCHITECTURE, &architecture,
|
||||
sizeof(D3D12_FEATURE_DATA_ARCHITECTURE));
|
||||
if (FAILED(result))
|
||||
{
|
||||
DestroyDriver_Internal(driver);
|
||||
@@ -823,8 +917,7 @@ namespace Juliet::D3D12
|
||||
// Check "GPU Upload Heap" support (for fast uniform buffers. Not supported on my 5700xt
|
||||
D3D12_FEATURE_DATA_D3D12_OPTIONS16 options16;
|
||||
driver->GPUUploadHeapSupported = false;
|
||||
result = ID3D12Device5_CheckFeatureSupport(driver->D3D12Device, D3D12_FEATURE_D3D12_OPTIONS16, &options16,
|
||||
sizeof(options16));
|
||||
result = driver->D3D12Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS16, &options16, sizeof(options16));
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
driver->GPUUploadHeapSupported = options16.GPUUploadHeapSupported;
|
||||
@@ -840,17 +933,23 @@ namespace Juliet::D3D12
|
||||
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||
queueDesc.NodeMask = 0;
|
||||
queueDesc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
|
||||
result = ID3D12Device5_CreateCommandQueue(driver->D3D12Device, &queueDesc, IID_ID3D12CommandQueue,
|
||||
reinterpret_cast<void**>(&driver->GraphicsQueue));
|
||||
result = driver->D3D12Device->CreateCommandQueue(&queueDesc, IID_ID3D12CommandQueue,
|
||||
reinterpret_cast<void**>(&driver->GraphicsQueue));
|
||||
if (FAILED(result))
|
||||
{
|
||||
DestroyDriver_Internal(driver);
|
||||
Log(LogLevel::Error, LogCategory::Graphics, "DX12: Could not create D3D12CommandQueue: Graphics");
|
||||
return nullptr;
|
||||
}
|
||||
ID3D12CommandQueue_SetName(driver->GraphicsQueue, L"GRAPHICS_QUEUE");
|
||||
driver->GraphicsQueue->SetName(L"GRAPHICS_QUEUE");
|
||||
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
|
||||
D3D12_COMMAND_SIGNATURE_DESC commandSignatureDesc;
|
||||
D3D12_INDIRECT_ARGUMENT_DESC indirectArgumentDesc;
|
||||
@@ -861,8 +960,8 @@ namespace Juliet::D3D12
|
||||
commandSignatureDesc.ByteStride = sizeof(IndirectDrawCommand);
|
||||
commandSignatureDesc.NumArgumentDescs = 1;
|
||||
commandSignatureDesc.pArgumentDescs = &indirectArgumentDesc;
|
||||
result = ID3D12Device5_CreateCommandSignature(driver->D3D12Device, &commandSignatureDesc, nullptr, IID_ID3D12CommandSignature,
|
||||
reinterpret_cast<void**>(&driver->IndirectDrawCommandSignature));
|
||||
result = driver->D3D12Device->CreateCommandSignature(&commandSignatureDesc, nullptr, IID_ID3D12CommandSignature,
|
||||
reinterpret_cast<void**>(&driver->IndirectDrawCommandSignature));
|
||||
if (FAILED(result))
|
||||
{
|
||||
DestroyDriver_Internal(driver);
|
||||
@@ -874,8 +973,8 @@ namespace Juliet::D3D12
|
||||
commandSignatureDesc.ByteStride = sizeof(IndexedIndirectDrawCommand);
|
||||
commandSignatureDesc.pArgumentDescs = &indirectArgumentDesc;
|
||||
|
||||
result = ID3D12Device5_CreateCommandSignature(driver->D3D12Device, &commandSignatureDesc, nullptr, IID_ID3D12CommandSignature,
|
||||
reinterpret_cast<void**>(&driver->IndirectIndexedDrawCommandSignature));
|
||||
result = driver->D3D12Device->CreateCommandSignature(&commandSignatureDesc, nullptr, IID_ID3D12CommandSignature,
|
||||
reinterpret_cast<void**>(&driver->IndirectIndexedDrawCommandSignature));
|
||||
if (FAILED(result))
|
||||
{
|
||||
|
||||
@@ -888,8 +987,8 @@ namespace Juliet::D3D12
|
||||
commandSignatureDesc.ByteStride = sizeof(IndirectDispatchCommand);
|
||||
commandSignatureDesc.pArgumentDescs = &indirectArgumentDesc;
|
||||
|
||||
result = ID3D12Device5_CreateCommandSignature(driver->D3D12Device, &commandSignatureDesc, nullptr, IID_ID3D12CommandSignature,
|
||||
reinterpret_cast<void**>(&driver->IndirectDispatchCommandSignature));
|
||||
result = driver->D3D12Device->CreateCommandSignature(&commandSignatureDesc, nullptr, IID_ID3D12CommandSignature,
|
||||
reinterpret_cast<void**>(&driver->IndirectDispatchCommandSignature));
|
||||
if (FAILED(result))
|
||||
{
|
||||
DestroyDriver_Internal(driver);
|
||||
@@ -984,35 +1083,42 @@ namespace Juliet::D3D12
|
||||
device->AcquireSwapChainTexture = AcquireSwapChainTexture;
|
||||
device->WaitAndAcquireSwapChainTexture = WaitAndAcquireSwapChainTexture;
|
||||
device->GetSwapChainTextureFormat = GetSwapChainTextureFormat;
|
||||
device->AcquireCommandList = AcquireCommandList;
|
||||
device->SubmitCommandLists = SubmitCommandLists;
|
||||
device->BeginRenderPass = BeginRenderPass;
|
||||
device->EndRenderPass = EndRenderPass;
|
||||
device->SetViewPort = SetViewPort;
|
||||
device->SetScissorRect = SetScissorRect;
|
||||
device->SetBlendConstants = SetBlendConstants;
|
||||
device->SetStencilReference = SetStencilReference;
|
||||
device->BindGraphicsPipeline = BindGraphicsPipeline;
|
||||
device->DrawPrimitives = DrawPrimitives;
|
||||
device->WaitUntilGPUIsIdle = WaitUntilGPUIsIdle;
|
||||
device->SetPushConstants = SetPushConstants;
|
||||
device->QueryFence = QueryFence;
|
||||
device->ReleaseFence = ReleaseFence;
|
||||
device->CreateShader = CreateShader;
|
||||
device->DestroyShader = DestroyShader;
|
||||
device->CreateGraphicsPipeline = CreateGraphicsPipeline;
|
||||
device->DestroyGraphicsPipeline = DestroyGraphicsPipeline;
|
||||
device->CreateGraphicsBuffer = CreateGraphicsBuffer;
|
||||
device->DestroyGraphicsBuffer = DestroyGraphicsBuffer;
|
||||
device->CreateGraphicsTransferBuffer = CreateGraphicsTransferBuffer;
|
||||
device->DestroyGraphicsTransferBuffer = DestroyGraphicsTransferBuffer;
|
||||
device->MapGraphicsTransferBuffer = MapBuffer;
|
||||
device->UnmapGraphicsTransferBuffer = UnmapBuffer;
|
||||
device->CopyBuffer = CopyBuffer;
|
||||
device->TransitionBufferToReadable = TransitionBufferToReadable;
|
||||
device->GetDescriptorIndex = GetDescriptorIndex;
|
||||
device->CreateTexture = CreateTexture;
|
||||
device->DestroyTexture = DestroyTexture;
|
||||
device->AcquireCommandList = D3D12::AcquireCommandList;
|
||||
device->SubmitCommandLists = D3D12::SubmitCommandLists;
|
||||
|
||||
device->BeginRenderPass = D3D12::BeginRenderPass;
|
||||
device->EndRenderPass = D3D12::EndRenderPass;
|
||||
device->SetViewPort = D3D12::SetViewPort;
|
||||
device->SetScissorRect = D3D12::SetScissorRect;
|
||||
device->SetBlendConstants = D3D12::SetBlendConstants;
|
||||
device->SetStencilReference = D3D12::SetStencilReference;
|
||||
device->BindGraphicsPipeline = D3D12::BindGraphicsPipeline;
|
||||
device->DrawPrimitives = D3D12::DrawPrimitives;
|
||||
device->DrawIndexedPrimitives = DrawIndexedPrimitives;
|
||||
device->SetIndexBuffer = D3D12::SetIndexBuffer;
|
||||
device->WaitUntilGPUIsIdle = D3D12::WaitUntilGPUIsIdle;
|
||||
|
||||
device->SetPushConstants = D3D12::SetPushConstants;
|
||||
device->QueryFence = D3D12::QueryFence;
|
||||
device->ReleaseFence = D3D12::ReleaseFence;
|
||||
device->CreateShader = D3D12::CreateShader;
|
||||
device->DestroyShader = D3D12::DestroyShader;
|
||||
device->CreateGraphicsPipeline = D3D12::CreateGraphicsPipeline;
|
||||
device->DestroyGraphicsPipeline = DestroyGraphicsPipeline;
|
||||
device->CreateGraphicsBuffer = D3D12::CreateGraphicsBuffer;
|
||||
device->DestroyGraphicsBuffer = D3D12::DestroyGraphicsBuffer;
|
||||
device->CreateGraphicsTransferBuffer = D3D12::CreateGraphicsTransferBuffer;
|
||||
device->DestroyGraphicsTransferBuffer = D3D12::DestroyGraphicsTransferBuffer;
|
||||
device->MapGraphicsTransferBuffer = D3D12::MapBuffer;
|
||||
device->UnmapGraphicsTransferBuffer = D3D12::UnmapBuffer;
|
||||
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
|
||||
device->UpdateGraphicsPipelineShaders = UpdateGraphicsPipelineShaders;
|
||||
@@ -1024,7 +1130,8 @@ namespace Juliet::D3D12
|
||||
driver->GraphicsDevice = device;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace Juliet::D3D12
|
||||
ID3D12Device5* D3D12Device;
|
||||
PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE D3D12SerializeVersionedRootSignatureFct;
|
||||
ID3D12CommandQueue* GraphicsQueue;
|
||||
D3D12_COMMAND_QUEUE_DESC QueueDesc[ToUnderlying(QueueType::Copy)];
|
||||
D3D12_COMMAND_QUEUE_DESC QueueDesc[ToUnderlying(QueueType::Count)];
|
||||
#if JULIET_DEBUG
|
||||
ID3D12Debug1* D3D12Debug;
|
||||
#endif
|
||||
@@ -112,6 +112,7 @@ namespace Juliet::D3D12
|
||||
bool GPUUploadHeapSupported : 1;
|
||||
};
|
||||
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
void DisposePendingResourcces(NonNullPtr<D3D12Driver> driver);
|
||||
|
||||
@@ -406,7 +406,7 @@ namespace Juliet::D3D12
|
||||
psoDesc.pRootSignature = d3d12Driver->BindlessRootSignature->Handle;
|
||||
|
||||
ID3D12PipelineState* pipelineState;
|
||||
HRESULT res = ID3D12Device_CreateGraphicsPipelineState(d3d12Driver->D3D12Device, &psoDesc, IID_ID3D12PipelineState,
|
||||
HRESULT res = d3d12Driver->D3D12Device->CreateGraphicsPipelineState(&psoDesc, IID_ID3D12PipelineState,
|
||||
reinterpret_cast<void**>(&pipelineState));
|
||||
if (FAILED(res))
|
||||
{
|
||||
@@ -499,7 +499,7 @@ namespace Juliet::D3D12
|
||||
psoDesc.pRootSignature = d3d12Driver->BindlessRootSignature->Handle;
|
||||
|
||||
ID3D12PipelineState* pipelineState;
|
||||
HRESULT res = ID3D12Device_CreateGraphicsPipelineState(d3d12Driver->D3D12Device, &psoDesc, IID_ID3D12PipelineState,
|
||||
HRESULT res = d3d12Driver->D3D12Device->CreateGraphicsPipelineState(&psoDesc, IID_ID3D12PipelineState,
|
||||
reinterpret_cast<void**>(&pipelineState));
|
||||
if (FAILED(res))
|
||||
{
|
||||
@@ -520,7 +520,7 @@ namespace Juliet::D3D12
|
||||
// If everything worked, we patch the graphics pipeline and destroy everything irrelevant
|
||||
if (d3d12GraphicsPipeline->PipelineState)
|
||||
{
|
||||
ID3D12PipelineState_Release(d3d12GraphicsPipeline->PipelineState);
|
||||
d3d12GraphicsPipeline->PipelineState->Release();
|
||||
}
|
||||
d3d12GraphicsPipeline->PipelineState = pipelineState;
|
||||
|
||||
@@ -543,7 +543,7 @@ namespace Juliet::D3D12
|
||||
{
|
||||
if (d3d12GraphicsPipeline->PipelineState)
|
||||
{
|
||||
ID3D12PipelineState_Release(d3d12GraphicsPipeline->PipelineState);
|
||||
d3d12GraphicsPipeline->PipelineState->Release();
|
||||
}
|
||||
|
||||
#if ALLOW_SHADER_HOT_RELOAD
|
||||
|
||||
@@ -8,30 +8,22 @@
|
||||
// Because Microsoft respects nothing
|
||||
// TODO: Create an external dependency with its one fbuild.bff
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wreserved-macro-identifier"
|
||||
#pragma clang diagnostic ignored "-Wreserved-identifier"
|
||||
#pragma clang diagnostic ignored "-Wnonportable-system-include-path"
|
||||
#pragma clang diagnostic ignored "-Wmicrosoft-enum-value"
|
||||
#pragma clang diagnostic ignored "-Wnested-anon-types"
|
||||
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wreserved-macro-identifier"
|
||||
#pragma clang diagnostic ignored "-Wreserved-identifier"
|
||||
#pragma clang diagnostic ignored "-Wnonportable-system-include-path"
|
||||
#pragma clang diagnostic ignored "-Wmicrosoft-enum-value"
|
||||
#pragma clang diagnostic ignored "-Wnested-anon-types"
|
||||
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#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 <Graphics/D3D12/AgilitySDK/d3d12.h>
|
||||
|
||||
#if JULIET_DEBUG
|
||||
#include <dxgidebug.h>
|
||||
#endif
|
||||
|
||||
//#include <dxgi.h>
|
||||
|
||||
#ifdef __IDXGIInfoQueue_INTERFACE_DEFINED__
|
||||
#define IDXGIINFOQUEUE_SUPPORTED
|
||||
#endif
|
||||
@@ -44,5 +36,5 @@
|
||||
#undef max
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
@@ -136,6 +136,9 @@ namespace Juliet::D3D12::UnitTest
|
||||
|
||||
// Note: heap2 is heap1.
|
||||
// Pool array in driver leaked for test scope, acceptable.
|
||||
|
||||
printf("DescriptorHeapPool tests passed.\n");
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace Juliet::D3D12
|
||||
// TODO: Check if texture has 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,
|
||||
depthStencilTargetInfo->ClearStencil, 0, nullptr);
|
||||
}
|
||||
@@ -93,7 +93,7 @@ namespace Juliet::D3D12
|
||||
clearColor[2] = colorTargetInfos[idx].ClearColor.B;
|
||||
clearColor[3] = colorTargetInfos[idx].ClearColor.A;
|
||||
|
||||
ID3D12GraphicsCommandList6_ClearRenderTargetView(d3d12CommandList->GraphicsCommandList.CommandList, rtv,
|
||||
d3d12CommandList->GraphicsCommandList.CommandList->ClearRenderTargetView(rtv,
|
||||
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);
|
||||
|
||||
// Set defaults graphics states
|
||||
@@ -163,8 +163,7 @@ namespace Juliet::D3D12
|
||||
Internal::TextureSubresourceBarrier(d3d12CommandList, D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||
D3D12_RESOURCE_STATE_RESOLVE_SOURCE,
|
||||
d3d12CommandList->ColorTargetSubresources[idx]);
|
||||
ID3D12GraphicsCommandList_ResolveSubresource(
|
||||
d3d12CommandList->GraphicsCommandList.CommandList,
|
||||
d3d12CommandList->GraphicsCommandList.CommandList->ResolveSubresource(
|
||||
d3d12CommandList->ColorResolveSubresources[idx]->Parent->Resource,
|
||||
d3d12CommandList->ColorResolveSubresources[idx]->Index,
|
||||
d3d12CommandList->ColorTargetSubresources[idx]->Parent->Resource,
|
||||
@@ -199,7 +198,7 @@ namespace Juliet::D3D12
|
||||
}
|
||||
d3d12CommandList->CurrentGraphicsPipeline = nullptr;
|
||||
|
||||
ID3D12GraphicsCommandList_OMSetRenderTargets(d3d12CommandList->GraphicsCommandList.CommandList, 0, nullptr, false, nullptr);
|
||||
d3d12CommandList->GraphicsCommandList.CommandList->OMSetRenderTargets(0, nullptr, false, nullptr);
|
||||
|
||||
// Reset bind states
|
||||
ZeroArray(d3d12CommandList->ColorTargetSubresources);
|
||||
@@ -236,10 +235,10 @@ namespace Juliet::D3D12
|
||||
Internal::SetDescriptorHeaps(d3d12CommandList);
|
||||
|
||||
// Set the pipeline state
|
||||
ID3D12GraphicsCommandList_SetPipelineState(d3d12CommandList->GraphicsCommandList.CommandList, pipeline->PipelineState);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootSignature(d3d12CommandList->GraphicsCommandList.CommandList,
|
||||
d3d12CommandList->GraphicsCommandList.CommandList->SetPipelineState(pipeline->PipelineState);
|
||||
d3d12CommandList->GraphicsCommandList.CommandList->SetGraphicsRootSignature(
|
||||
pipeline->RootSignature->Handle);
|
||||
ID3D12GraphicsCommandList_IASetPrimitiveTopology(d3d12CommandList->GraphicsCommandList.CommandList,
|
||||
d3d12CommandList->GraphicsCommandList.CommandList->IASetPrimitiveTopology(
|
||||
JulietToD3D12_PrimitiveType[ToUnderlying(pipeline->PrimitiveType)]);
|
||||
|
||||
// Mark that bindings are needed
|
||||
@@ -281,7 +280,7 @@ namespace Juliet::D3D12
|
||||
// TODO : Last missing piece
|
||||
// D3D12_INTERNAL_BindGraphicsResources(d3d12CommandBuffer);
|
||||
|
||||
ID3D12GraphicsCommandList_DrawInstanced(d3d12CommandList->GraphicsCommandList.CommandList, numVertices,
|
||||
d3d12CommandList->GraphicsCommandList.CommandList->DrawInstanced(numVertices,
|
||||
numInstances, firstVertex, firstInstance);
|
||||
}
|
||||
} // namespace Juliet::D3D12
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace Juliet::D3D12
|
||||
{
|
||||
ID3D12Resource* swapChainTexture = nullptr;
|
||||
HRESULT result =
|
||||
IDXGISwapChain_GetBuffer(swapChain, index, IID_ID3D12Resource, reinterpret_cast<void**>(&swapChainTexture));
|
||||
swapChain->GetBuffer(index, IID_ID3D12Resource, reinterpret_cast<void**>(&swapChainTexture));
|
||||
if (FAILED(result))
|
||||
{
|
||||
LogError(driver->D3D12Device, "Cannot get buffer from SwapChain", result);
|
||||
@@ -53,7 +53,7 @@ namespace Juliet::D3D12
|
||||
if (!texture)
|
||||
{
|
||||
LogError(driver->D3D12Device, "Cannot allocate D3D12Texture (out of memory)", result);
|
||||
ID3D12Resource_Release(swapChainTexture);
|
||||
swapChainTexture->Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace Juliet::D3D12
|
||||
{
|
||||
LogError(driver->D3D12Device, "Cannot allocate D3D12TextureSubresource (out of memory)", result);
|
||||
Free(texture);
|
||||
ID3D12Resource_Release(swapChainTexture);
|
||||
swapChainTexture->Release();
|
||||
return false;
|
||||
}
|
||||
texture->Subresources[0].RTVHandles =
|
||||
@@ -77,8 +77,7 @@ namespace Juliet::D3D12
|
||||
texture->Subresources[0].Depth = 1;
|
||||
texture->Subresources[0].Level = 0;
|
||||
|
||||
D3D12_RESOURCE_DESC textureDesc;
|
||||
ID3D12Resource_GetDesc(swapChainTexture, &textureDesc);
|
||||
D3D12_RESOURCE_DESC textureDesc = swapChainTexture->GetDesc();
|
||||
textureContainer->Header.CreateInfo.Width = static_cast<uint32>(textureDesc.Width);
|
||||
textureContainer->Header.CreateInfo.Height = static_cast<uint32>(textureDesc.Height);
|
||||
textureContainer->Header.CreateInfo.LayerCount = 1;
|
||||
@@ -93,7 +92,7 @@ namespace Juliet::D3D12
|
||||
{
|
||||
Free(texture->Subresources);
|
||||
Free(texture);
|
||||
ID3D12Resource_Release(swapChainTexture);
|
||||
swapChainTexture->Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -115,10 +114,10 @@ namespace Juliet::D3D12
|
||||
rtvDesc.Texture2D.MipSlice = 0;
|
||||
rtvDesc.Texture2D.PlaneSlice = 0;
|
||||
|
||||
ID3D12Device_CreateRenderTargetView(driver->D3D12Device, swapChainTexture, &rtvDesc,
|
||||
driver->D3D12Device->CreateRenderTargetView(swapChainTexture, &rtvDesc,
|
||||
texture->Subresources[0].RTVHandles[0].CpuHandle);
|
||||
|
||||
ID3D12Resource_Release(swapChainTexture);
|
||||
swapChainTexture->Release();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -161,11 +160,9 @@ namespace Juliet::D3D12
|
||||
windowData->InFlightFences[windowData->WindowFrameCounter] = nullptr;
|
||||
}
|
||||
|
||||
uint32 swapchainIndex = IDXGISwapChain3_GetCurrentBackBufferIndex(windowData->SwapChain);
|
||||
uint32 swapchainIndex = windowData->SwapChain->GetCurrentBackBufferIndex();
|
||||
HRESULT result =
|
||||
IDXGISwapChain_GetBuffer(windowData->SwapChain, swapchainIndex, IID_ID3D12Resource,
|
||||
reinterpret_cast<void**>(
|
||||
&windowData->SwapChainTextureContainers[swapchainIndex].ActiveTexture->Resource));
|
||||
windowData->SwapChain->GetBuffer(swapchainIndex, IID_ID3D12Resource, reinterpret_cast<void**>(&windowData->SwapChainTextureContainers[swapchainIndex].ActiveTexture->Resource));
|
||||
if (FAILED(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.Subresource = 0;
|
||||
|
||||
ID3D12GraphicsCommandList_ResourceBarrier(d3d12CommandList->GraphicsCommandList.CommandList, 1, &barrierDesc);
|
||||
d3d12CommandList->GraphicsCommandList.CommandList->ResourceBarrier(1, &barrierDesc);
|
||||
|
||||
*swapchainTexture = reinterpret_cast<Texture*>(&windowData->SwapChainTextureContainers[swapchainIndex]);
|
||||
|
||||
@@ -294,7 +291,7 @@ namespace Juliet::D3D12
|
||||
|
||||
IDXGISwapChain1* swapChain = nullptr;
|
||||
HRESULT result =
|
||||
IDXGIFactory4_CreateSwapChainForHwnd(driver->DXGIFactory, reinterpret_cast<IUnknown*>(driver->GraphicsQueue),
|
||||
driver->DXGIFactory->CreateSwapChainForHwnd(static_cast<IUnknown*>(driver->GraphicsQueue),
|
||||
windowHandle, &swapChainDesc, &swapChainFullscreenDesc, nullptr, &swapChain);
|
||||
if (FAILED(result))
|
||||
{
|
||||
@@ -303,8 +300,8 @@ namespace Juliet::D3D12
|
||||
}
|
||||
|
||||
IDXGISwapChain3* swapChain3 = nullptr;
|
||||
result = IDXGISwapChain1_QueryInterface(swapChain, IID_IDXGISwapChain3, reinterpret_cast<void**>(&swapChain3));
|
||||
IDXGISwapChain1_Release(swapChain);
|
||||
result = swapChain->QueryInterface(IID_IDXGISwapChain3, reinterpret_cast<void**>(&swapChain3));
|
||||
swapChain->Release();
|
||||
if (FAILED(result))
|
||||
{
|
||||
LogError(driver->D3D12Device, "Could not query IDXGISwapChain3 interface", result);
|
||||
@@ -313,11 +310,11 @@ namespace Juliet::D3D12
|
||||
|
||||
if (composition != SwapChainComposition::SDR)
|
||||
{
|
||||
IDXGISwapChain3_SetColorSpace1(swapChain3, SwapchainCompositionToColorSpace[ToUnderlying(composition)]);
|
||||
swapChain3->SetColorSpace1(SwapchainCompositionToColorSpace[ToUnderlying(composition)]);
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
Log(LogLevel::Warning, LogCategory::Graphics, "Cannot get SwapChain Parent! Error Code: " HRESULT_FMT, result);
|
||||
@@ -325,15 +322,15 @@ namespace Juliet::D3D12
|
||||
else
|
||||
{
|
||||
// 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))
|
||||
{
|
||||
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))
|
||||
{
|
||||
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))
|
||||
{
|
||||
IDXGISwapChain3_Release(swapChain3);
|
||||
swapChain3->Release();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -372,7 +369,7 @@ namespace Juliet::D3D12
|
||||
Free(windowData->SwapChainTextureContainers[idx].Textures);
|
||||
}
|
||||
|
||||
IDXGISwapChain_Release(windowData->SwapChain);
|
||||
windowData->SwapChain->Release();
|
||||
windowData->SwapChain = nullptr;
|
||||
}
|
||||
} // namespace Internal
|
||||
|
||||
@@ -35,12 +35,12 @@ namespace Juliet::D3D12
|
||||
if (d3d12driver->GraphicsQueue)
|
||||
{
|
||||
// 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.
|
||||
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))
|
||||
{
|
||||
LogError(d3d12driver->D3D12Device, "Setting fence event failed!", result);
|
||||
@@ -82,7 +82,7 @@ namespace Juliet::D3D12
|
||||
{
|
||||
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))
|
||||
{
|
||||
LogError(d3d12driver->D3D12Device, "Setting fence event failed!", res);
|
||||
@@ -104,7 +104,7 @@ namespace Juliet::D3D12
|
||||
// Clean up
|
||||
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)
|
||||
{
|
||||
result &= Internal::CleanCommandList(d3d12driver, d3d12driver->SubmittedCommandLists[idx], false);
|
||||
@@ -166,7 +166,7 @@ namespace Juliet::D3D12
|
||||
|
||||
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)
|
||||
{
|
||||
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));
|
||||
if (FAILED(result))
|
||||
{
|
||||
@@ -190,7 +190,7 @@ namespace Juliet::D3D12
|
||||
fence = static_cast<D3D12Fence*>(Calloc(1, sizeof(D3D12Fence)));
|
||||
if (!fence)
|
||||
{
|
||||
ID3D12Fence_Release(handle);
|
||||
handle->Release();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@@ -202,7 +202,7 @@ namespace Juliet::D3D12
|
||||
{
|
||||
fence = driver->AvailableFences[driver->AvailableFenceCount - 1];
|
||||
driver->AvailableFenceCount -= 1;
|
||||
ID3D12Fence_Signal(fence->Handle, D3D12_FENCE_UNSIGNALED_VALUE);
|
||||
fence->Handle->Signal(D3D12_FENCE_UNSIGNALED_VALUE);
|
||||
}
|
||||
|
||||
fence->ReferenceCount += 1;
|
||||
@@ -213,7 +213,7 @@ namespace Juliet::D3D12
|
||||
{
|
||||
if (fence->Handle)
|
||||
{
|
||||
ID3D12Fence_Release(fence->Handle);
|
||||
fence->Handle->Release();
|
||||
}
|
||||
|
||||
if (fence->Event)
|
||||
|
||||
@@ -426,7 +426,7 @@ namespace Juliet::D3D12
|
||||
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,
|
||||
reinterpret_cast<void**>(&resource));
|
||||
|
||||
@@ -477,7 +477,7 @@ namespace Juliet::D3D12
|
||||
rtvDesc.Format = desc.Format;
|
||||
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
|
||||
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)
|
||||
@@ -488,12 +488,48 @@ namespace Juliet::D3D12
|
||||
dsvDesc.Format = Internal::ConvertToD3D12DepthFormat(createInfo.Format);
|
||||
dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
void DestroyTexture(NonNullPtr<GPUDriver> driver, NonNullPtr<Texture> texture)
|
||||
@@ -517,7 +553,7 @@ namespace Juliet::D3D12
|
||||
Internal::ReleaseStagingDescriptor(d3d12Driver, sub.DSVHandle);
|
||||
}
|
||||
}
|
||||
ID3D12Resource_Release(d3d12Texture->Resource);
|
||||
d3d12Texture->Resource->Release();
|
||||
Free(d3d12Texture->Subresources);
|
||||
Free(d3d12Texture);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Juliet::D3D12
|
||||
|
||||
if (result == DXGI_ERROR_DEVICE_REMOVED)
|
||||
{
|
||||
result = ID3D12Device_GetDeviceRemovedReason(D3D12Device);
|
||||
result = D3D12Device->GetDeviceRemovedReason();
|
||||
}
|
||||
|
||||
// Try to get the message from the system errors.
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <Core/Logging/LogTypes.h>
|
||||
#include <Graphics/Graphics.h>
|
||||
#include <Graphics/GraphicsDevice.h>
|
||||
#include <Core/ImGui/ImGuiTests.h>
|
||||
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
@@ -57,9 +59,11 @@ namespace Juliet
|
||||
{
|
||||
if (GraphicsDevice* newDevice = chosenFactory->CreateGraphicsDevice(config.EnableDebug))
|
||||
{
|
||||
|
||||
newDevice->Name = chosenFactory->Name;
|
||||
return newDevice;
|
||||
}
|
||||
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -259,6 +263,16 @@ namespace Juliet
|
||||
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)
|
||||
{
|
||||
auto* commandList = reinterpret_cast<GPUPass*>(renderPass.Get())->CommandList;
|
||||
@@ -275,6 +289,21 @@ namespace Juliet
|
||||
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,
|
||||
uint32 numConstants, const void* constants)
|
||||
{
|
||||
@@ -366,10 +395,21 @@ namespace Juliet
|
||||
void CopyBuffer(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> dst,
|
||||
NonNullPtr<GraphicsTransferBuffer> src, size_t size, size_t dstOffset, size_t srcOffset)
|
||||
{
|
||||
auto* header = reinterpret_cast<CommandListHeader*>(commandList.Get());
|
||||
header->Device->CopyBuffer(commandList, dst, src, size, dstOffset, srcOffset);
|
||||
auto* headers = reinterpret_cast<CommandListHeader*>(commandList.Get());
|
||||
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)
|
||||
{
|
||||
auto* header = reinterpret_cast<CommandListHeader*>(commandList.Get());
|
||||
@@ -378,9 +418,15 @@ namespace Juliet
|
||||
|
||||
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)
|
||||
{
|
||||
device->DestroyGraphicsBuffer(buffer);
|
||||
|
||||
@@ -66,10 +66,16 @@ namespace Juliet
|
||||
void (*SetScissorRect)(NonNullPtr<CommandList> commandList, const Rectangle& viewPort);
|
||||
void (*SetBlendConstants)(NonNullPtr<CommandList> commandList, FColor blendConstants);
|
||||
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 (*DrawPrimitives)(NonNullPtr<CommandList> commandList, uint32 numVertices, uint32 numInstances,
|
||||
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,
|
||||
uint32 numConstants, const void* constants);
|
||||
@@ -102,10 +108,14 @@ namespace Juliet
|
||||
|
||||
void* (*MapGraphicsTransferBuffer)(NonNullPtr<GPUDriver> driver, NonNullPtr<GraphicsTransferBuffer> buffer);
|
||||
void (*UnmapGraphicsTransferBuffer)(NonNullPtr<GPUDriver> driver, NonNullPtr<GraphicsTransferBuffer> buffer);
|
||||
void (*CopyBuffer)(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> dst,
|
||||
NonNullPtr<GraphicsTransferBuffer> src, size_t size, size_t dstOffset, size_t srcOffset);
|
||||
void (*CopyBuffer)(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> dst,
|
||||
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);
|
||||
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";
|
||||
GPUDriver* Driver = nullptr;
|
||||
|
||||
Reference in New Issue
Block a user