diff --git a/Assets/compiled/Triangle.vert.dxil b/Assets/compiled/Triangle.vert.dxil index e9737f9..5ebdfc1 100644 Binary files a/Assets/compiled/Triangle.vert.dxil and b/Assets/compiled/Triangle.vert.dxil differ diff --git a/Assets/source/RootConstants.hlsl b/Assets/source/RootConstants.hlsl index f96e7fa..07c0f32 100644 --- a/Assets/source/RootConstants.hlsl +++ b/Assets/source/RootConstants.hlsl @@ -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 diff --git a/Assets/source/Triangle.vert.hlsl b/Assets/source/Triangle.vert.hlsl index 9fb0cc6..2d2bf78 100644 --- a/Assets/source/Triangle.vert.hlsl +++ b/Assets/source/Triangle.vert.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 ? diff --git a/Juliet/src/Core/HAL/Display/Win32/Win32DisplayEvent.cpp b/Juliet/src/Core/HAL/Display/Win32/Win32DisplayEvent.cpp index baf769e..5b3be09 100644 --- a/Juliet/src/Core/HAL/Display/Win32/Win32DisplayEvent.cpp +++ b/Juliet/src/Core/HAL/Display/Win32/Win32DisplayEvent.cpp @@ -14,6 +14,10 @@ // For GET_X_LPARAM, GET_Y_LPARAM. #include +#include // 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) diff --git a/Juliet/src/Core/Juliet.cpp b/Juliet/src/Core/Juliet.cpp index 4abc22a..7577b64 100644 --- a/Juliet/src/Core/Juliet.cpp +++ b/Juliet/src/Core/Juliet.cpp @@ -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); diff --git a/Juliet/src/Graphics/D3D12/D3D12Buffer.cpp b/Juliet/src/Graphics/D3D12/D3D12Buffer.cpp index f1e9968..358519d 100644 --- a/Juliet/src/Graphics/D3D12/D3D12Buffer.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12Buffer.cpp @@ -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(&handle)); + HRESULT result = d3d12Driver->D3D12Device->CreateCommittedResource(&heapProperties, heapFlags, + &desc, initialState, nullptr, + IID_ID3D12Resource, reinterpret_cast(&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(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( - 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(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 /*driver*/, NonNullPtr buffer) { auto d3d12Buffer = reinterpret_cast(buffer.Get()); - ID3D12Resource_Unmap(d3d12Buffer->Handle, 0, nullptr); + d3d12Buffer->Handle->Unmap(0, nullptr); } uint32 GetDescriptorIndex(NonNullPtr /*driver*/, NonNullPtr 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; } } diff --git a/Juliet/src/Graphics/D3D12/D3D12Buffer.h b/Juliet/src/Graphics/D3D12/D3D12Buffer.h index 8e01995..d132dfc 100644 --- a/Juliet/src/Graphics/D3D12/D3D12Buffer.h +++ b/Juliet/src/Graphics/D3D12/D3D12Buffer.h @@ -1,7 +1,9 @@ #pragma once +#include #include #include +#include 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 driver, size_t size, BufferUsage usage); extern void DestroyGraphicsBuffer(NonNullPtr buffer); diff --git a/Juliet/src/Graphics/D3D12/D3D12CommandList.cpp b/Juliet/src/Graphics/D3D12/D3D12CommandList.cpp index d661f95..dc9d099 100644 --- a/Juliet/src/Graphics/D3D12/D3D12CommandList.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12CommandList.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include #include @@ -26,15 +28,14 @@ namespace Juliet::D3D12 bool CreateAllocator(NonNullPtr driver, NonNullPtr baseData, D3D12_COMMAND_QUEUE_DESC queueDesc) { - HRESULT result = ID3D12Device5_CreateCommandAllocator(driver->D3D12Device, queueDesc.Type, IID_ID3D12CommandAllocator, - reinterpret_cast(&baseData->Allocator)); + HRESULT result = driver->D3D12Device->CreateCommandAllocator(queueDesc.Type, IID_ID3D12CommandAllocator, reinterpret_cast(&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(&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(&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(&d3d12CopyCommandList)); + HRESULT result = driver->D3D12Device->CreateCommandList1(queueDesc.NodeMask, queueDesc.Type, + D3D12_COMMAND_LIST_FLAG_NONE, IID_ID3D12GraphicsCommandList, reinterpret_cast(&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(&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(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, 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, FColor blendConstants) { auto* d3d12CommandList = reinterpret_cast(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, uint8 reference) { auto* d3d12CommandList = reinterpret_cast(commandList.Get()); - ID3D12GraphicsCommandList_OMSetStencilRef(d3d12CommandList->GraphicsCommandList.CommandList, reference); + d3d12CommandList->GraphicsCommandList.CommandList->OMSetStencilRef(reference); + } + + void SetIndexBuffer(NonNullPtr commandList, NonNullPtr buffer, IndexFormat format) + { + auto* d3d12CommandList = reinterpret_cast(commandList.Get()); + auto* d3d12Buffer = reinterpret_cast(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(d3d12Buffer->Size); + ibView.Format = (format == IndexFormat::UInt16) ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT; + + d3d12CommandList->GraphicsCommandList.CommandList->IASetIndexBuffer(&ibView); } void SetPushConstants(NonNullPtr commandList, ShaderStage /*stage*/, uint32 rootParameterIndex, @@ -374,7 +392,7 @@ namespace Juliet::D3D12 { auto d3d12CommandList = reinterpret_cast(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 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)) { diff --git a/Juliet/src/Graphics/D3D12/D3D12CommandList.h b/Juliet/src/Graphics/D3D12/D3D12CommandList.h index fb31cae..4268732 100644 --- a/Juliet/src/Graphics/D3D12/D3D12CommandList.h +++ b/Juliet/src/Graphics/D3D12/D3D12CommandList.h @@ -96,6 +96,7 @@ namespace Juliet::D3D12 extern void SetBlendConstants(NonNullPtr commandList, FColor blendConstants); extern void SetBlendConstants(NonNullPtr commandList, FColor blendConstants); extern void SetStencilReference(NonNullPtr commandList, uint8 reference); + extern void SetIndexBuffer(NonNullPtr commandList, NonNullPtr buffer, IndexFormat format); extern void SetPushConstants(NonNullPtr commandList, ShaderStage stage, uint32 rootParameterIndex, uint32 numConstants, const void* constants); namespace Internal diff --git a/Juliet/src/Graphics/D3D12/D3D12DescriptorHeap.cpp b/Juliet/src/Graphics/D3D12/D3D12DescriptorHeap.cpp index 92304ca..a751449 100644 --- a/Juliet/src/Graphics/D3D12/D3D12DescriptorHeap.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12DescriptorHeap.cpp @@ -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()); diff --git a/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp b/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp index 89e7c9a..176b822 100644 --- a/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp @@ -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(&factory4)); + result = factory1->QueryInterface(IID_IDXGIFactory4, reinterpret_cast(&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(&factory6)); + result = factory1->QueryInterface(IID_IDXGIFactory6, reinterpret_cast(&factory6)); if (SUCCEEDED(result)) { - result = IDXGIFactory6_EnumAdapterByGpuPreference(factory6, 0, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, - IID_IDXGIAdapter1, reinterpret_cast(&adapter)); - IDXGIFactory6_Release(factory6); + result = factory6->EnumAdapterByGpuPreference(0, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, + IID_IDXGIAdapter1, reinterpret_cast(&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(adapter), kD3DFeatureLevel, IID_ID3D12Device5, + result = D3D12CreateDeviceFuncPtr(static_cast(adapter), kD3DFeatureLevel, IID_ID3D12Device5, reinterpret_cast(&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(&rootSignature)); + res = d3d12Driver->D3D12Device->CreateRootSignature(0, serializedRootSignature->GetBufferPointer(), + serializedRootSignature->GetBufferSize(), IID_ID3D12RootSignature, + reinterpret_cast(&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_SUMMARY | DXGI_DEBUG_RLO_DETAIL)); - IDXGIDebug_Release(driver->DXGIDebug); + driver->DXGIDebug->ReportLiveObjects(DXGI_DEBUG_ALL, static_cast( + 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 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(&infoQueue)); + HRESULT result = driver->D3D12Device->QueryInterface(IID_ID3D12InfoQueue, reinterpret_cast(&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(&infoQueue)); + HRESULT result = driver->D3D12Device->QueryInterface(IID_ID3D12InfoQueue1, reinterpret_cast(&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 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, uint32 numIndices, uint32 numInstances, + uint32 firstIndex, uint32 vertexOffset, uint32 firstInstance) + { + auto* d3d12CommandList = reinterpret_cast(commandList.Get()); + d3d12CommandList->GraphicsCommandList.CommandList->DrawIndexedInstanced(numIndices, numInstances, firstIndex, + static_cast(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 driver, NonNullPtr pipeline) + { + auto* d3d12Driver = static_cast(driver.Get()); + d3d12Driver->GraphicsPipelinesToDispose[d3d12Driver->GraphicsPipelinesToDisposeCount] = + reinterpret_cast(pipeline.Get()); + d3d12Driver->GraphicsPipelinesToDisposeCount += 1; + if (d3d12Driver->GraphicsPipelinesToDisposeCount >= d3d12Driver->GraphicsPipelinesToDisposeCapacity) + { + Internal::ReleaseGraphicsPipeline(reinterpret_cast(pipeline.Get())); + } + } + + // Buffer functions are assigned directly from D3D12:: namespace + + void CopyBufferToTexture(NonNullPtr commandList, NonNullPtr dst, NonNullPtr src) + { + auto* d3d12CommandList = reinterpret_cast(commandList.Get()); + auto* d3d12TextureContainer = reinterpret_cast(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(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 device, NonNullPtr buffer) + { + auto* driver = static_cast(device->Driver); + return D3D12::GetDescriptorIndex(driver, buffer); + } + + // GetDescriptorIndexTexture provides custom logic to get SRV handle index + uint32 GetDescriptorIndexTexture(NonNullPtr /*device*/, NonNullPtr texture) + { + auto* textureContainer = reinterpret_cast(texture.Get()); + return textureContainer->ActiveTexture->SRVHandle.CpuHandleIndex; + } + +#if ALLOW_SHADER_HOT_RELOAD + bool UpdateGraphicsPipelineShaders(NonNullPtr /*driver*/, NonNullPtr /*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(Calloc(1, sizeof(D3D12Driver))); @@ -671,7 +768,7 @@ namespace Juliet::D3D12 return nullptr; } - result = IDXGIFactory1_QueryInterface(factory1, IID_IDXGIFactory4, reinterpret_cast(&driver->DXGIFactory)); + result = factory1->QueryInterface(IID_IDXGIFactory4, reinterpret_cast(&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(&factory5)); + result = driver->DXGIFactory->QueryInterface(IID_IDXGIFactory5, reinterpret_cast(&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(&factory6)); + result = driver->DXGIFactory->QueryInterface(IID_IDXGIFactory6, reinterpret_cast(&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(&driver->DXGIAdapter)); - IDXGIFactory6_Release(factory6); + result = factory6->EnumAdapterByGpuPreference(0, useLowPower ? DXGI_GPU_PREFERENCE_MINIMUM_POWER : DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, + IID_IDXGIAdapter1, reinterpret_cast(&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(driver->DXGIAdapter), kD3DFeatureLevel, + result = D3D12CreateDeviceFuncPtr(static_cast(driver->DXGIAdapter), kD3DFeatureLevel, IID_ID3D12Device5, reinterpret_cast(&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(&driver->GraphicsQueue)); + result = driver->D3D12Device->CreateCommandQueue(&queueDesc, IID_ID3D12CommandQueue, + reinterpret_cast(&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(&driver->IndirectDrawCommandSignature)); + result = driver->D3D12Device->CreateCommandSignature(&commandSignatureDesc, nullptr, IID_ID3D12CommandSignature, + reinterpret_cast(&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(&driver->IndirectIndexedDrawCommandSignature)); + result = driver->D3D12Device->CreateCommandSignature(&commandSignatureDesc, nullptr, IID_ID3D12CommandSignature, + reinterpret_cast(&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(&driver->IndirectDispatchCommandSignature)); + result = driver->D3D12Device->CreateCommandSignature(&commandSignatureDesc, nullptr, IID_ID3D12CommandSignature, + reinterpret_cast(&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; } diff --git a/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.h b/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.h index 54d130d..6abb9d9 100644 --- a/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.h +++ b/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.h @@ -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 driver); diff --git a/Juliet/src/Graphics/D3D12/D3D12GraphicsPipeline.cpp b/Juliet/src/Graphics/D3D12/D3D12GraphicsPipeline.cpp index 693679e..53bd778 100644 --- a/Juliet/src/Graphics/D3D12/D3D12GraphicsPipeline.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12GraphicsPipeline.cpp @@ -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(&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(&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 diff --git a/Juliet/src/Graphics/D3D12/D3D12Includes.h b/Juliet/src/Graphics/D3D12/D3D12Includes.h index f0c1c7a..1d96082 100644 --- a/Juliet/src/Graphics/D3D12/D3D12Includes.h +++ b/Juliet/src/Graphics/D3D12/D3D12Includes.h @@ -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 #include +#include #if JULIET_DEBUG #include #endif -//#include - #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 diff --git a/Juliet/src/Graphics/D3D12/D3D12InternalTests.cpp b/Juliet/src/Graphics/D3D12/D3D12InternalTests.cpp index c631273..aa5228b 100644 --- a/Juliet/src/Graphics/D3D12/D3D12InternalTests.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12InternalTests.cpp @@ -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 diff --git a/Juliet/src/Graphics/D3D12/D3D12RenderPass.cpp b/Juliet/src/Graphics/D3D12/D3D12RenderPass.cpp index b3bdd8b..e06e856 100644 --- a/Juliet/src/Graphics/D3D12/D3D12RenderPass.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12RenderPass.cpp @@ -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 diff --git a/Juliet/src/Graphics/D3D12/D3D12SwapChain.cpp b/Juliet/src/Graphics/D3D12/D3D12SwapChain.cpp index 00578d1..58fbae5 100644 --- a/Juliet/src/Graphics/D3D12/D3D12SwapChain.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12SwapChain.cpp @@ -42,7 +42,7 @@ namespace Juliet::D3D12 { ID3D12Resource* swapChainTexture = nullptr; HRESULT result = - IDXGISwapChain_GetBuffer(swapChain, index, IID_ID3D12Resource, reinterpret_cast(&swapChainTexture)); + swapChain->GetBuffer(index, IID_ID3D12Resource, reinterpret_cast(&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(textureDesc.Width); textureContainer->Header.CreateInfo.Height = static_cast(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( - &windowData->SwapChainTextureContainers[swapchainIndex].ActiveTexture->Resource)); + windowData->SwapChain->GetBuffer(swapchainIndex, IID_ID3D12Resource, reinterpret_cast(&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(&windowData->SwapChainTextureContainers[swapchainIndex]); @@ -294,7 +291,7 @@ namespace Juliet::D3D12 IDXGISwapChain1* swapChain = nullptr; HRESULT result = - IDXGIFactory4_CreateSwapChainForHwnd(driver->DXGIFactory, reinterpret_cast(driver->GraphicsQueue), + driver->DXGIFactory->CreateSwapChainForHwnd(static_cast(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(&swapChain3)); - IDXGISwapChain1_Release(swapChain); + result = swapChain->QueryInterface(IID_IDXGISwapChain3, reinterpret_cast(&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(&parentFactory)); + result = swapChain3->GetParent(IID_IDXGIFactory1, reinterpret_cast(&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 diff --git a/Juliet/src/Graphics/D3D12/D3D12Synchronization.cpp b/Juliet/src/Graphics/D3D12/D3D12Synchronization.cpp index 5c2a5d6..2cc8262 100644 --- a/Juliet/src/Graphics/D3D12/D3D12Synchronization.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12Synchronization.cpp @@ -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(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(&handle)); if (FAILED(result)) { @@ -190,7 +190,7 @@ namespace Juliet::D3D12 fence = static_cast(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) diff --git a/Juliet/src/Graphics/D3D12/D3D12Texture.cpp b/Juliet/src/Graphics/D3D12/D3D12Texture.cpp index 9c6903d..ff0d00b 100644 --- a/Juliet/src/Graphics/D3D12/D3D12Texture.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12Texture.cpp @@ -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(&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(textureContainer); + } void DestroyTexture(NonNullPtr driver, NonNullPtr 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); } diff --git a/Juliet/src/Graphics/D3D12/D3D12Utils.cpp b/Juliet/src/Graphics/D3D12/D3D12Utils.cpp index 8b4aae2..2e39798 100644 --- a/Juliet/src/Graphics/D3D12/D3D12Utils.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12Utils.cpp @@ -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. diff --git a/Juliet/src/Graphics/Graphics.cpp b/Juliet/src/Graphics/Graphics.cpp index 61abded..b55c377 100644 --- a/Juliet/src/Graphics/Graphics.cpp +++ b/Juliet/src/Graphics/Graphics.cpp @@ -4,6 +4,8 @@ #include #include #include +#include + 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, NonNullPtr buffer, IndexFormat format) + { + auto* commandListHeader = reinterpret_cast(commandList.Get()); + + if (commandListHeader->Device->SetIndexBuffer) + { + commandListHeader->Device->SetIndexBuffer(commandList, buffer, format); + } + } + void BindGraphicsPipeline(NonNullPtr renderPass, NonNullPtr graphicsPipeline) { auto* commandList = reinterpret_cast(renderPass.Get())->CommandList; @@ -275,6 +289,21 @@ namespace Juliet commandListHeader->Device->DrawPrimitives(commandList, numVertices, numInstances, firstVertex, firstInstance); } + void DrawIndexedPrimitives(NonNullPtr renderPass, uint32 numIndices, uint32 numInstances, + uint32 firstIndex, uint32 vertexOffset, uint32 firstInstance) + { + auto* commandList = reinterpret_cast(renderPass.Get())->CommandList; + auto* commandListHeader = reinterpret_cast(commandList); + + if (commandListHeader->Device->DrawIndexedPrimitives) + { + commandListHeader->Device->DrawIndexedPrimitives(commandList, numIndices, numInstances, firstIndex, vertexOffset, firstInstance); + } + } + + + + void SetPushConstants(NonNullPtr commandList, ShaderStage stage, uint32 rootParameterIndex, uint32 numConstants, const void* constants) { @@ -366,10 +395,21 @@ namespace Juliet void CopyBuffer(NonNullPtr commandList, NonNullPtr dst, NonNullPtr src, size_t size, size_t dstOffset, size_t srcOffset) { - auto* header = reinterpret_cast(commandList.Get()); - header->Device->CopyBuffer(commandList, dst, src, size, dstOffset, srcOffset); + auto* headers = reinterpret_cast(commandList.Get()); + headers->Device->CopyBuffer(commandList, dst, src, size, dstOffset, srcOffset); } + void CopyBufferToTexture(NonNullPtr commandList, NonNullPtr dst, + NonNullPtr src) + { + auto* headers = reinterpret_cast(commandList.Get()); + if (headers->Device->CopyBufferToTexture) + { + headers->Device->CopyBufferToTexture(commandList, dst, src); + } + } + + void TransitionBufferToReadable(NonNullPtr commandList, NonNullPtr buffer) { auto* header = reinterpret_cast(commandList.Get()); @@ -378,9 +418,15 @@ namespace Juliet uint32 GetDescriptorIndex(NonNullPtr device, NonNullPtr buffer) { - return device->GetDescriptorIndex(device->Driver, buffer); + return device->GetDescriptorIndex(device, buffer); } + uint32 GetDescriptorIndex(NonNullPtr device, NonNullPtr texture) + { + return device->GetDescriptorIndexTexture(device, texture); + } + + void DestroyGraphicsBuffer(NonNullPtr device, NonNullPtr buffer) { device->DestroyGraphicsBuffer(buffer); diff --git a/Juliet/src/Graphics/GraphicsDevice.h b/Juliet/src/Graphics/GraphicsDevice.h index 1fe8b43..6086224 100644 --- a/Juliet/src/Graphics/GraphicsDevice.h +++ b/Juliet/src/Graphics/GraphicsDevice.h @@ -66,10 +66,16 @@ namespace Juliet void (*SetScissorRect)(NonNullPtr commandList, const Rectangle& viewPort); void (*SetBlendConstants)(NonNullPtr commandList, FColor blendConstants); void (*SetStencilReference)(NonNullPtr commandList, uint8 reference); + void (*SetIndexBuffer)(NonNullPtr commandList, NonNullPtr buffer, IndexFormat format); void (*BindGraphicsPipeline)(NonNullPtr commandList, NonNullPtr graphicsPipeline); void (*DrawPrimitives)(NonNullPtr commandList, uint32 numVertices, uint32 numInstances, uint32 firstVertex, uint32 firstInstance); + void (*DrawIndexedPrimitives)(NonNullPtr commandList, uint32 numIndices, uint32 numInstances, + uint32 firstIndex, uint32 vertexOffset, uint32 firstInstance); + + + void (*SetPushConstants)(NonNullPtr commandList, ShaderStage stage, uint32 rootParameterIndex, uint32 numConstants, const void* constants); @@ -102,10 +108,14 @@ namespace Juliet void* (*MapGraphicsTransferBuffer)(NonNullPtr driver, NonNullPtr buffer); void (*UnmapGraphicsTransferBuffer)(NonNullPtr driver, NonNullPtr buffer); - void (*CopyBuffer)(NonNullPtr commandList, NonNullPtr dst, - NonNullPtr src, size_t size, size_t dstOffset, size_t srcOffset); + void (*CopyBuffer)(NonNullPtr commandList, NonNullPtr dst, + NonNullPtr src, size_t size, size_t dstOffset, size_t srcOffset); + void (*CopyBufferToTexture)(NonNullPtr commandList, NonNullPtr dst, + NonNullPtr src); // Assume full copy for now + void (*TransitionBufferToReadable)(NonNullPtr commandList, NonNullPtr buffer); - uint32 (*GetDescriptorIndex)(NonNullPtr driver, NonNullPtr buffer); + uint32 (*GetDescriptorIndex)(NonNullPtr device, NonNullPtr buffer); + uint32 (*GetDescriptorIndexTexture)(NonNullPtr device, NonNullPtr texture); const char* Name = "Unknown"; GPUDriver* Driver = nullptr;