diff --git a/rpcs3/Emu/RSX/D3D12/D3D12.h b/rpcs3/Emu/RSX/D3D12/D3D12.h index 08d6547c74..7467544ca5 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12.h @@ -67,46 +67,6 @@ void streamBuffer(void* dst, void* src, size_t sizeInBytes) memcpy((char*)dst + offset, (char*)src + offset, sizeInBytes - offset); } -inline -D3D12_RESOURCE_DESC getBufferResourceDesc(size_t sizeInByte) -{ - D3D12_RESOURCE_DESC BufferDesc = {}; - BufferDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - BufferDesc.Width = (UINT)sizeInByte; - BufferDesc.Height = 1; - BufferDesc.DepthOrArraySize = 1; - BufferDesc.SampleDesc.Count = 1; - BufferDesc.MipLevels = 1; - BufferDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - return BufferDesc; -} - -inline -D3D12_RESOURCE_DESC getTexture2DResourceDesc(size_t width, size_t height, DXGI_FORMAT dxgiFormat, size_t mipmapLevels) -{ - D3D12_RESOURCE_DESC result; - result = {}; - result.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; - result.Width = (UINT)width; - result.Height = (UINT)height; - result.Format = dxgiFormat; - result.DepthOrArraySize = 1; - result.SampleDesc.Count = 1; - result.MipLevels = (UINT16)mipmapLevels; - return result; -} - -inline -D3D12_RESOURCE_BARRIER getResourceBarrierTransition(ID3D12Resource *res, D3D12_RESOURCE_STATES stateBefore, D3D12_RESOURCE_STATES stateAfter) -{ - D3D12_RESOURCE_BARRIER barrier = {}; - barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - barrier.Transition.pResource = res; - barrier.Transition.StateBefore = stateBefore; - barrier.Transition.StateAfter = stateAfter; - return barrier; -} - /** * Convert GCM blend operator code to D3D12 one */ @@ -323,20 +283,4 @@ inline DXGI_FORMAT getTextureDXGIFormat(int format) } } -inline -D3D12_CPU_DESCRIPTOR_HANDLE getCPUDescriptorHandle(ID3D12DescriptorHeap *descriptors, size_t offset) -{ - D3D12_CPU_DESCRIPTOR_HANDLE result = descriptors->GetCPUDescriptorHandleForHeapStart(); - result.ptr += offset; - return result; -} - -inline -D3D12_GPU_DESCRIPTOR_HANDLE getGPUDescriptorHandle(ID3D12DescriptorHeap *descriptors, size_t offset) -{ - D3D12_GPU_DESCRIPTOR_HANDLE result = descriptors->GetGPUDescriptorHandleForHeapStart(); - result.ptr += offset; - return result; -} - #endif diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp index a9e6cd7e91..72ca461ddb 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp @@ -4,6 +4,7 @@ #include "Utilities/Log.h" #include "D3D12GSRender.h" +#include "d3dx12.h" const int g_vertexCount = 32; @@ -205,10 +206,10 @@ std::vector FormatVertexData(const RSXVertexData *m_vertex_d } /** - * Create a new vertex buffer with attributes from vbf using vertexIndexHeap as storage heap. + * Suballocate a new vertex buffer with attributes from vbf using vertexIndexHeap as storage heap. */ static -ComPtr createVertexBuffer(const VertexBufferFormat &vbf, const RSXVertexData *vertexData, size_t baseOffset, ID3D12Device *device, DataHeap &vertexIndexHeap) +D3D12_GPU_VIRTUAL_ADDRESS createVertexBuffer(const VertexBufferFormat &vbf, const RSXVertexData *vertexData, size_t baseOffset, ID3D12Device *device, DataHeap &vertexIndexHeap) { size_t subBufferSize = vbf.range.second - vbf.range.first + 1; // Make multiple of stride @@ -217,19 +218,9 @@ ComPtr createVertexBuffer(const VertexBufferFormat &vbf, const R assert(vertexIndexHeap.canAlloc(subBufferSize)); size_t heapOffset = vertexIndexHeap.alloc(subBufferSize); - ComPtr vertexBuffer; - ThrowIfFailed(device->CreatePlacedResource( - vertexIndexHeap.m_heap, - heapOffset, - &getBufferResourceDesc(subBufferSize), - D3D12_RESOURCE_STATE_GENERIC_READ, - nullptr, - IID_PPV_ARGS(vertexBuffer.GetAddressOf()) - )); - void *bufferMap; - ThrowIfFailed(vertexBuffer->Map(0, nullptr, (void**)&bufferMap)); - memset(bufferMap, -1, subBufferSize); - #pragma omp parallel for + void *buffer; + ThrowIfFailed(vertexIndexHeap.m_heap->Map(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize), (void**)&buffer)); + void *bufferMap = (char*)buffer + heapOffset; for (int vertex = 0; vertex < vbf.elementCount; vertex++) { for (size_t attributeId : vbf.attributeId) @@ -242,7 +233,7 @@ ComPtr createVertexBuffer(const VertexBufferFormat &vbf, const R size_t offset = (size_t)vertexData[attributeId].addr + baseOffset - vbf.range.first; size_t tsize = vertexData[attributeId].GetTypeSize(); size_t size = vertexData[attributeId].size; - auto src = vm::get_ptr(vertexData[attributeId].addr + baseOffset + (int)vbf.stride * vertex); + auto src = vm::get_ptr(vertexData[attributeId].addr + (u32)baseOffset + (u32)vbf.stride * vertex); char* dst = (char*)bufferMap + offset + vbf.stride * vertex; switch (tsize) @@ -272,8 +263,8 @@ ComPtr createVertexBuffer(const VertexBufferFormat &vbf, const R } } - vertexBuffer->Unmap(0, nullptr); - return vertexBuffer; + vertexIndexHeap.m_heap->Unmap(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize)); + return vertexIndexHeap.m_heap->GetGPUVirtualAddress() + heapOffset; } static bool @@ -303,25 +294,11 @@ std::vector D3D12GSRender::UploadVertexBuffers(bool in if (vbf.stride) subBufferSize = ((subBufferSize + vbf.stride - 1) / vbf.stride) * vbf.stride; - u64 key = vbf.range.first; - key = key << 32; - key = key | vbf.range.second; - auto It = m_vertexCache.find(key); - - ID3D12Resource *vertexBuffer; - if (vbf.range.first != 0 && // Attribute is stored in a buffer, not inline in command buffer - It != m_vertexCache.end()) - vertexBuffer = It->second; - else - { - ComPtr newVertexBuffer = createVertexBuffer(vbf, m_vertex_data, m_vertex_data_base_offset, m_device.Get(), m_vertexIndexData); - vertexBuffer = newVertexBuffer.Get(); - m_vertexCache[key] = newVertexBuffer.Get(); - getCurrentResourceStorage().m_singleFrameLifetimeResources.push_back(newVertexBuffer); - } + D3D12_GPU_VIRTUAL_ADDRESS virtualAddress = createVertexBuffer(vbf, m_vertex_data, m_vertex_data_base_offset, m_device.Get(), m_vertexIndexData); + m_timers.m_bufferUploadSize += subBufferSize; D3D12_VERTEX_BUFFER_VIEW vertexBufferView = {}; - vertexBufferView.BufferLocation = vertexBuffer->GetGPUVirtualAddress(); + vertexBufferView.BufferLocation = virtualAddress; vertexBufferView.SizeInBytes = (UINT)subBufferSize; vertexBufferView.StrideInBytes = (UINT)vbf.stride; result.push_back(vertexBufferView); @@ -428,18 +405,9 @@ D3D12_INDEX_BUFFER_VIEW D3D12GSRender::uploadIndexBuffers(bool indexed_draw) assert(m_vertexIndexData.canAlloc(subBufferSize)); size_t heapOffset = m_vertexIndexData.alloc(subBufferSize); - ComPtr indexBuffer; - ThrowIfFailed(m_device->CreatePlacedResource( - m_vertexIndexData.m_heap, - heapOffset, - &getBufferResourceDesc(subBufferSize), - D3D12_RESOURCE_STATE_GENERIC_READ, - nullptr, - IID_PPV_ARGS(indexBuffer.GetAddressOf()) - )); - - void *bufferMap; - ThrowIfFailed(indexBuffer->Map(0, nullptr, (void**)&bufferMap)); + void *buffer; + ThrowIfFailed(m_vertexIndexData.m_heap->Map(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize), (void**)&buffer)); + void *bufferMap = (char*)buffer + heapOffset; if (indexed_draw && !forcedIndexBuffer) streamBuffer(bufferMap, m_indexed_array.m_data.data(), subBufferSize); else if (indexed_draw && forcedIndexBuffer) @@ -500,11 +468,12 @@ D3D12_INDEX_BUFFER_VIEW D3D12GSRender::uploadIndexBuffers(bool indexed_draw) } } - indexBuffer->Unmap(0, nullptr); - getCurrentResourceStorage().m_singleFrameLifetimeResources.push_back(indexBuffer); + m_vertexIndexData.m_heap->Unmap(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize)); + + m_timers.m_bufferUploadSize += subBufferSize; indexBufferView.SizeInBytes = (UINT)subBufferSize; - indexBufferView.BufferLocation = indexBuffer->GetGPUVirtualAddress(); + indexBufferView.BufferLocation = m_vertexIndexData.m_heap->GetGPUVirtualAddress() + heapOffset; return indexBufferView; } diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index a9e01a53c2..a50c5c3e83 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -6,6 +6,7 @@ #include #include #include +#include "d3dx12.h" PFN_D3D12_CREATE_DEVICE wrapD3D12CreateDevice; PFN_D3D12_GET_DEBUG_INTERFACE wrapD3D12GetDebugInterface; @@ -63,28 +64,14 @@ void D3D12GSRender::ResourceStorage::Init(ID3D12Device *device) ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocator.Get(), nullptr, IID_PPV_ARGS(m_commandList.GetAddressOf()))); ThrowIfFailed(m_commandList->Close()); - D3D12_DESCRIPTOR_HEAP_DESC descriptorHeapDesc = {}; - descriptorHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; - descriptorHeapDesc.NumDescriptors = 10000; // For safety - descriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + D3D12_DESCRIPTOR_HEAP_DESC descriptorHeapDesc = { D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 10000, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE }; ThrowIfFailed(device->CreateDescriptorHeap(&descriptorHeapDesc, IID_PPV_ARGS(&m_constantsBufferDescriptorsHeap))); - - descriptorHeapDesc = {}; - descriptorHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; - descriptorHeapDesc.NumDescriptors = 10000; // For safety - descriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; ThrowIfFailed(device->CreateDescriptorHeap(&descriptorHeapDesc, IID_PPV_ARGS(&m_scaleOffsetDescriptorHeap))); + ThrowIfFailed(device->CreateDescriptorHeap(&descriptorHeapDesc, IID_PPV_ARGS(&m_textureDescriptorsHeap))); - D3D12_DESCRIPTOR_HEAP_DESC textureDescriptorDesc = {}; - textureDescriptorDesc.NumDescriptors = 10000; // For safety - textureDescriptorDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; - textureDescriptorDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; - ThrowIfFailed(device->CreateDescriptorHeap(&textureDescriptorDesc, IID_PPV_ARGS(&m_textureDescriptorsHeap))); - - textureDescriptorDesc.NumDescriptors = 2048; // For safety - textureDescriptorDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; - ThrowIfFailed(device->CreateDescriptorHeap(&textureDescriptorDesc, IID_PPV_ARGS(&m_samplerDescriptorHeap[0]))); - ThrowIfFailed(device->CreateDescriptorHeap(&textureDescriptorDesc, IID_PPV_ARGS(&m_samplerDescriptorHeap[1]))); + D3D12_DESCRIPTOR_HEAP_DESC samplerHeapDesc = { D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER , 2048, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE }; + ThrowIfFailed(device->CreateDescriptorHeap(&samplerHeapDesc, IID_PPV_ARGS(&m_samplerDescriptorHeap[0]))); + ThrowIfFailed(device->CreateDescriptorHeap(&samplerHeapDesc, IID_PPV_ARGS(&m_samplerDescriptorHeap[1]))); m_frameFinishedHandle = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS); m_fenceValue = 0; @@ -225,9 +212,7 @@ D3D12GSRender::D3D12GSRender() m_swapChain->GetBuffer(0, IID_PPV_ARGS(&m_backBuffer[0])); m_swapChain->GetBuffer(1, IID_PPV_ARGS(&m_backBuffer[1])); - D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {}; - heapDesc.NumDescriptors = 1; - heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; + D3D12_DESCRIPTOR_HEAP_DESC heapDesc = { D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1}; D3D12_RENDER_TARGET_VIEW_DESC rttDesc = {}; rttDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; rttDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; @@ -295,15 +280,13 @@ D3D12GSRender::D3D12GSRender() m_perFrameStorage[1].Reset(); initConvertShader(); - m_outputScalingPass.Init(m_device.Get()); + m_outputScalingPass.Init(m_device.Get(), m_commandQueueGraphic.Get()); - D3D12_HEAP_PROPERTIES hp = {}; - hp.Type = D3D12_HEAP_TYPE_DEFAULT; ThrowIfFailed( m_device->CreateCommittedResource( - &hp, + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, - &getTexture2DResourceDesc(2, 2, DXGI_FORMAT_R8G8B8A8_UNORM, 1), + &CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, 2, 2, 1, 1), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_dummyTexture)) @@ -315,7 +298,7 @@ D3D12GSRender::D3D12GSRender() m_rtts.Init(m_device.Get()); m_constantsData.Init(m_device.Get(), 1024 * 1024 * 64, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_NONE); - m_vertexIndexData.Init(m_device.Get(), 1024 * 1024 * 384, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS); + m_vertexIndexData.Init(m_device.Get(), 1024 * 1024 * 384, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_NONE); m_textureUploadData.Init(m_device.Get(), 1024 * 1024 * 256, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS); if (Ini.GSOverlay.GetValue()) @@ -324,7 +307,15 @@ D3D12GSRender::D3D12GSRender() D3D12GSRender::~D3D12GSRender() { - getNonCurrentResourceStorage().WaitAndClean(); + // wait until queue has completed + ComPtr fence; + ThrowIfFailed(m_device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(fence.GetAddressOf()))); + HANDLE handle = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS); + fence->SetEventOnCompletion(1, handle); + + m_commandQueueGraphic->Signal(fence.Get(), 1); + WaitForSingleObjectEx(handle, INFINITE, FALSE); + CloseHandle(handle); { std::lock_guard lock(mut); @@ -390,11 +381,14 @@ void D3D12GSRender::OnReset() void D3D12GSRender::Clear(u32 cmd) { std::chrono::time_point startDuration = std::chrono::system_clock::now(); - PrepareRenderTargets(getCurrentResourceStorage().m_commandList.Get()); assert(cmd == NV4097_CLEAR_SURFACE); + std::chrono::time_point rttDurationStart = std::chrono::system_clock::now(); PrepareRenderTargets(getCurrentResourceStorage().m_commandList.Get()); + std::chrono::time_point rttDurationEnd = std::chrono::system_clock::now(); + m_timers.m_rttDuration += std::chrono::duration_cast(rttDurationEnd - rttDurationStart).count(); + /* if (m_set_color_mask) { glColorMask(m_color_mask_r, m_color_mask_g, m_color_mask_b, m_color_mask_a); @@ -427,7 +421,6 @@ void D3D12GSRender::Clear(u32 cmd) m_clear_surface_color_a / 255.0f }; - D3D12_CPU_DESCRIPTOR_HANDLE handle = m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart(); size_t g_RTTIncrement = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); switch (m_surface_color_target) { @@ -435,26 +428,22 @@ void D3D12GSRender::Clear(u32 cmd) case CELL_GCM_SURFACE_TARGET_0: case CELL_GCM_SURFACE_TARGET_1: - getCurrentResourceStorage().m_commandList->ClearRenderTargetView(getCPUDescriptorHandle(m_rtts.m_renderTargetsDescriptorsHeap, 0), clearColor, 0, nullptr); + getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()), clearColor, 0, nullptr); break; case CELL_GCM_SURFACE_TARGET_MRT1: - getCurrentResourceStorage().m_commandList->ClearRenderTargetView(getCPUDescriptorHandle(m_rtts.m_renderTargetsDescriptorsHeap, 0), clearColor, 0, nullptr); - getCurrentResourceStorage().m_commandList->ClearRenderTargetView(getCPUDescriptorHandle(m_rtts.m_renderTargetsDescriptorsHeap, g_descriptorStrideRTV), clearColor, 0, nullptr); + getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()), clearColor, 0, nullptr); + getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()).Offset(1, g_descriptorStrideRTV), clearColor, 0, nullptr); break; case CELL_GCM_SURFACE_TARGET_MRT2: - getCurrentResourceStorage().m_commandList->ClearRenderTargetView(getCPUDescriptorHandle(m_rtts.m_renderTargetsDescriptorsHeap, 0), clearColor, 0, nullptr); - getCurrentResourceStorage().m_commandList->ClearRenderTargetView(getCPUDescriptorHandle(m_rtts.m_renderTargetsDescriptorsHeap, g_descriptorStrideRTV), clearColor, 0, nullptr); - handle.ptr += g_RTTIncrement; - getCurrentResourceStorage().m_commandList->ClearRenderTargetView(getCPUDescriptorHandle(m_rtts.m_renderTargetsDescriptorsHeap, 2 * g_descriptorStrideRTV), clearColor, 0, nullptr); + getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()), clearColor, 0, nullptr); + getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()).Offset(1, g_descriptorStrideRTV), clearColor, 0, nullptr); + getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()).Offset(2, g_descriptorStrideRTV), clearColor, 0, nullptr); break; case CELL_GCM_SURFACE_TARGET_MRT3: - getCurrentResourceStorage().m_commandList->ClearRenderTargetView(getCPUDescriptorHandle(m_rtts.m_renderTargetsDescriptorsHeap, 0), clearColor, 0, nullptr); - handle.ptr += g_RTTIncrement; - getCurrentResourceStorage().m_commandList->ClearRenderTargetView(getCPUDescriptorHandle(m_rtts.m_renderTargetsDescriptorsHeap, g_descriptorStrideRTV), clearColor, 0, nullptr); - handle.ptr += g_RTTIncrement; - getCurrentResourceStorage().m_commandList->ClearRenderTargetView(getCPUDescriptorHandle(m_rtts.m_renderTargetsDescriptorsHeap, 2 * g_descriptorStrideRTV), clearColor, 0, nullptr); - handle.ptr += g_RTTIncrement; - getCurrentResourceStorage().m_commandList->ClearRenderTargetView(getCPUDescriptorHandle(m_rtts.m_renderTargetsDescriptorsHeap, 3 * g_descriptorStrideRTV), clearColor, 0, nullptr); + getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()), clearColor, 0, nullptr); + getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()).Offset(1, g_descriptorStrideRTV), clearColor, 0, nullptr); + getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()).Offset(2, g_descriptorStrideRTV), clearColor, 0, nullptr); + getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()).Offset(3, g_descriptorStrideRTV), clearColor, 0, nullptr); break; default: LOG_ERROR(RSX, "Bad surface color target: %d", m_surface_color_target); @@ -476,8 +465,15 @@ void D3D12GSRender::Clear(u32 cmd) void D3D12GSRender::Draw() { std::chrono::time_point startDuration = std::chrono::system_clock::now(); + + std::chrono::time_point rttDurationStart = std::chrono::system_clock::now(); PrepareRenderTargets(getCurrentResourceStorage().m_commandList.Get()); + std::chrono::time_point rttDurationEnd = std::chrono::system_clock::now(); + m_timers.m_rttDuration += std::chrono::duration_cast(rttDurationEnd - rttDurationStart).count(); + + std::chrono::time_point vertexIndexDurationStart = std::chrono::system_clock::now(); + // Init vertex count // TODO: Very hackish, clean this if (m_indexed_array.m_count) @@ -513,22 +509,30 @@ void D3D12GSRender::Draw() getCurrentResourceStorage().m_commandList->IASetIndexBuffer(&indexBufferView); } + std::chrono::time_point vertexIndexDurationEnd = std::chrono::system_clock::now(); + m_timers.m_vertexIndexDuration += std::chrono::duration_cast(vertexIndexDurationEnd - vertexIndexDurationStart).count(); + + std::chrono::time_point programLoadStart = std::chrono::system_clock::now(); if (!LoadProgram()) { LOG_ERROR(RSX, "LoadProgram failed."); Emu.Pause(); return; } + std::chrono::time_point programLoadEnd = std::chrono::system_clock::now(); + m_timers.m_programLoadDuration += std::chrono::duration_cast(programLoadEnd - programLoadStart).count(); getCurrentResourceStorage().m_commandList->SetGraphicsRootSignature(m_rootSignatures[m_PSO->second].Get()); getCurrentResourceStorage().m_commandList->OMSetStencilRef(m_stencil_func_ref); + std::chrono::time_point constantsDurationStart = std::chrono::system_clock::now(); + // Constants setScaleOffset(); getCurrentResourceStorage().m_commandList->SetDescriptorHeaps(1, getCurrentResourceStorage().m_scaleOffsetDescriptorHeap.GetAddressOf()); getCurrentResourceStorage().m_commandList->SetGraphicsRootDescriptorTable(0, - getGPUDescriptorHandle(getCurrentResourceStorage().m_scaleOffsetDescriptorHeap.Get(), - getCurrentResourceStorage().m_currentScaleOffsetBufferIndex * g_descriptorStrideSRVCBVUAV) + CD3DX12_GPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_scaleOffsetDescriptorHeap->GetGPUDescriptorHandleForHeapStart()) + .Offset((INT)getCurrentResourceStorage().m_currentScaleOffsetBufferIndex, g_descriptorStrideSRVCBVUAV) ); getCurrentResourceStorage().m_currentScaleOffsetBufferIndex++; @@ -540,11 +544,16 @@ void D3D12GSRender::Draw() getCurrentResourceStorage().m_commandList->SetDescriptorHeaps(1, getCurrentResourceStorage().m_constantsBufferDescriptorsHeap.GetAddressOf()); getCurrentResourceStorage().m_commandList->SetGraphicsRootDescriptorTable(1, - getGPUDescriptorHandle(getCurrentResourceStorage().m_constantsBufferDescriptorsHeap.Get(), - currentBufferIndex * g_descriptorStrideSRVCBVUAV) + CD3DX12_GPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_constantsBufferDescriptorsHeap->GetGPUDescriptorHandleForHeapStart()) + .Offset((INT)currentBufferIndex, g_descriptorStrideSRVCBVUAV) ); + + std::chrono::time_point constantsDurationEnd = std::chrono::system_clock::now(); + m_timers.m_constantsDuration += std::chrono::duration_cast(constantsDurationEnd - constantsDurationStart).count(); + getCurrentResourceStorage().m_commandList->SetPipelineState(m_PSO->first); + std::chrono::time_point textureDurationStart = std::chrono::system_clock::now(); if (m_PSO->second > 0) { size_t usedTexture = UploadTextures(getCurrentResourceStorage().m_commandList.Get()); @@ -561,9 +570,9 @@ void D3D12GSRender::Draw() D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0, D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0, D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0); - m_device->CreateShaderResourceView(m_dummyTexture, &srvDesc, - getCPUDescriptorHandle(getCurrentResourceStorage().m_textureDescriptorsHeap.Get(), - (getCurrentResourceStorage().m_currentTextureIndex + usedTexture) * g_descriptorStrideSRVCBVUAV) + m_device->CreateShaderResourceView(m_dummyTexture, &srvDesc, + CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_textureDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()) + .Offset((INT)getCurrentResourceStorage().m_currentTextureIndex + (INT)usedTexture, g_descriptorStrideSRVCBVUAV) ); D3D12_SAMPLER_DESC samplerDesc = {}; @@ -572,26 +581,28 @@ void D3D12GSRender::Draw() samplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP; samplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; m_device->CreateSampler(&samplerDesc, - getCPUDescriptorHandle(getCurrentResourceStorage().m_samplerDescriptorHeap[getCurrentResourceStorage().m_samplerDescriptorHeapIndex].Get(), - (getCurrentResourceStorage().m_currentSamplerIndex + usedTexture) * g_descriptorStrideSamplers) + CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_samplerDescriptorHeap[getCurrentResourceStorage().m_samplerDescriptorHeapIndex]->GetCPUDescriptorHandleForHeapStart()) + .Offset((INT)getCurrentResourceStorage().m_currentSamplerIndex + (INT)usedTexture, g_descriptorStrideSamplers) ); } getCurrentResourceStorage().m_commandList->SetDescriptorHeaps(1, getCurrentResourceStorage().m_textureDescriptorsHeap.GetAddressOf()); getCurrentResourceStorage().m_commandList->SetGraphicsRootDescriptorTable(2, - getGPUDescriptorHandle(getCurrentResourceStorage().m_textureDescriptorsHeap.Get(), - getCurrentResourceStorage().m_currentTextureIndex * g_descriptorStrideSRVCBVUAV) + CD3DX12_GPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_textureDescriptorsHeap->GetGPUDescriptorHandleForHeapStart()) + .Offset((INT)getCurrentResourceStorage().m_currentTextureIndex, g_descriptorStrideSRVCBVUAV) ); getCurrentResourceStorage().m_commandList->SetDescriptorHeaps(1, getCurrentResourceStorage().m_samplerDescriptorHeap[getCurrentResourceStorage().m_samplerDescriptorHeapIndex].GetAddressOf()); getCurrentResourceStorage().m_commandList->SetGraphicsRootDescriptorTable(3, - getGPUDescriptorHandle(getCurrentResourceStorage().m_samplerDescriptorHeap[getCurrentResourceStorage().m_samplerDescriptorHeapIndex].Get(), - getCurrentResourceStorage().m_currentSamplerIndex * g_descriptorStrideSamplers) + CD3DX12_GPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_samplerDescriptorHeap[getCurrentResourceStorage().m_samplerDescriptorHeapIndex]->GetGPUDescriptorHandleForHeapStart()) + .Offset((INT)getCurrentResourceStorage().m_currentSamplerIndex, g_descriptorStrideSamplers) ); getCurrentResourceStorage().m_currentTextureIndex += usedTexture; getCurrentResourceStorage().m_currentSamplerIndex += usedTexture; } + std::chrono::time_point textureDurationEnd = std::chrono::system_clock::now(); + m_timers.m_textureDuration += std::chrono::duration_cast(textureDurationEnd - textureDurationStart).count(); size_t numRTT; switch (m_surface_color_target) @@ -615,7 +626,7 @@ void D3D12GSRender::Draw() } getCurrentResourceStorage().m_commandList->OMSetRenderTargets((UINT)numRTT, &m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart(), true, - &getCPUDescriptorHandle(m_rtts.m_depthStencilDescriptorHeap, 0)); + &CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_depthStencilDescriptorHeap->GetCPUDescriptorHandleForHeapStart())); D3D12_VIEWPORT viewport = { @@ -714,9 +725,6 @@ void D3D12GSRender::Flip() ResourceStorage &storage = getCurrentResourceStorage(); assert(storage.m_RAMFramebuffer == nullptr); - D3D12_HEAP_PROPERTIES heapProp = {}; - heapProp.Type = D3D12_HEAP_TYPE_DEFAULT; - size_t w = 0, h = 0, rowPitch = 0; ID3D12Resource *stagingTexture; @@ -736,7 +744,7 @@ void D3D12GSRender::Flip() ThrowIfFailed(m_device->CreatePlacedResource( m_textureUploadData.m_heap, heapOffset, - &getBufferResourceDesc(textureSize), + &CD3DX12_RESOURCE_DESC::Buffer(textureSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&stagingTexture) @@ -752,38 +760,29 @@ void D3D12GSRender::Flip() ThrowIfFailed( m_device->CreateCommittedResource( - &heapProp, + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, - &getTexture2DResourceDesc(w, h, DXGI_FORMAT_R8G8B8A8_UNORM, 1), + &CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, (UINT)w, (UINT)h, 1, 1), D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(storage.m_RAMFramebuffer.GetAddressOf()) ) ); - D3D12_TEXTURE_COPY_LOCATION src = {}, dst = {}; - dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - dst.pResource = storage.m_RAMFramebuffer.Get(); - src.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; - src.pResource = stagingTexture; - src.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - src.PlacedFootprint.Footprint.Width = (UINT)w; - src.PlacedFootprint.Footprint.Height = (UINT)h; - src.PlacedFootprint.Footprint.Depth = (UINT)1; - src.PlacedFootprint.Footprint.RowPitch = (UINT)rowPitch; - getCurrentResourceStorage().m_commandList->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr); + getCurrentResourceStorage().m_commandList->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(storage.m_RAMFramebuffer.Get(), 0), 0, 0, 0, + &CD3DX12_TEXTURE_COPY_LOCATION(stagingTexture, { 0, { DXGI_FORMAT_R8G8B8A8_UNORM, (UINT)w, (UINT)h, 1, (UINT)rowPitch} }), nullptr); - getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &getResourceBarrierTransition(storage.m_RAMFramebuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_GENERIC_READ)); + getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(storage.m_RAMFramebuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_GENERIC_READ)); resourceToFlip = storage.m_RAMFramebuffer.Get(); viewport_w = (float)w, viewport_h = (float)h; } else { if (m_rtts.m_currentlyBoundRenderTargets[0] != nullptr) - getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &getResourceBarrierTransition(m_rtts.m_currentlyBoundRenderTargets[0], D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_GENERIC_READ)); + getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_rtts.m_currentlyBoundRenderTargets[0], D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_GENERIC_READ)); resourceToFlip = m_rtts.m_currentlyBoundRenderTargets[0]; } - getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &getResourceBarrierTransition(m_backBuffer[m_swapChain->GetCurrentBackBufferIndex()].Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET)); + getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_backBuffer[m_swapChain->GetCurrentBackBufferIndex()].Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET)); D3D12_VIEWPORT viewport = { @@ -806,9 +805,7 @@ void D3D12GSRender::Flip() getCurrentResourceStorage().m_commandList->RSSetScissorRects(1, &box); getCurrentResourceStorage().m_commandList->SetGraphicsRootSignature(m_outputScalingPass.m_rootSignature); getCurrentResourceStorage().m_commandList->SetPipelineState(m_outputScalingPass.m_PSO); - D3D12_CPU_DESCRIPTOR_HANDLE CPUHandle; - CPUHandle = m_outputScalingPass.m_textureDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); - CPUHandle.ptr += m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV) * m_swapChain->GetCurrentBackBufferIndex(); + D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; // FIXME: Not always true srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; @@ -823,29 +820,27 @@ void D3D12GSRender::Flip() D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_3, D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0 ); - m_device->CreateShaderResourceView(resourceToFlip, &srvDesc, CPUHandle); + m_device->CreateShaderResourceView(resourceToFlip, &srvDesc, + CD3DX12_CPU_DESCRIPTOR_HANDLE(m_outputScalingPass.m_textureDescriptorHeap->GetCPUDescriptorHandleForHeapStart()).Offset(m_swapChain->GetCurrentBackBufferIndex(), g_descriptorStrideSRVCBVUAV)); D3D12_SAMPLER_DESC samplerDesc = {}; samplerDesc.Filter = D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT; samplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP; samplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP; samplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - CPUHandle = m_outputScalingPass.m_samplerDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); - CPUHandle.ptr += m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER) * m_swapChain->GetCurrentBackBufferIndex(); - m_device->CreateSampler(&samplerDesc, CPUHandle); + m_device->CreateSampler(&samplerDesc, + CD3DX12_CPU_DESCRIPTOR_HANDLE(m_outputScalingPass.m_samplerDescriptorHeap->GetCPUDescriptorHandleForHeapStart()).Offset(m_swapChain->GetCurrentBackBufferIndex(), g_descriptorStrideSamplers)); - D3D12_GPU_DESCRIPTOR_HANDLE GPUHandle; - GPUHandle = m_outputScalingPass.m_textureDescriptorHeap->GetGPUDescriptorHandleForHeapStart(); - GPUHandle.ptr += m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV) * m_swapChain->GetCurrentBackBufferIndex(); getCurrentResourceStorage().m_commandList->SetDescriptorHeaps(1, &m_outputScalingPass.m_textureDescriptorHeap); - getCurrentResourceStorage().m_commandList->SetGraphicsRootDescriptorTable(0, GPUHandle); - GPUHandle = m_outputScalingPass.m_samplerDescriptorHeap->GetGPUDescriptorHandleForHeapStart(); - GPUHandle.ptr += m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER) * m_swapChain->GetCurrentBackBufferIndex(); + getCurrentResourceStorage().m_commandList->SetGraphicsRootDescriptorTable(0, + CD3DX12_GPU_DESCRIPTOR_HANDLE(m_outputScalingPass.m_textureDescriptorHeap->GetGPUDescriptorHandleForHeapStart()).Offset(m_swapChain->GetCurrentBackBufferIndex(), g_descriptorStrideSRVCBVUAV)); getCurrentResourceStorage().m_commandList->SetDescriptorHeaps(1, &m_outputScalingPass.m_samplerDescriptorHeap); - getCurrentResourceStorage().m_commandList->SetGraphicsRootDescriptorTable(1, GPUHandle); + getCurrentResourceStorage().m_commandList->SetGraphicsRootDescriptorTable(1, + CD3DX12_GPU_DESCRIPTOR_HANDLE(m_outputScalingPass.m_samplerDescriptorHeap->GetGPUDescriptorHandleForHeapStart()).Offset(m_swapChain->GetCurrentBackBufferIndex(), g_descriptorStrideSamplers)); - CPUHandle = m_backbufferAsRendertarget[m_swapChain->GetCurrentBackBufferIndex()]->GetCPUDescriptorHandleForHeapStart(); - getCurrentResourceStorage().m_commandList->OMSetRenderTargets(1, &CPUHandle, true, nullptr); + getCurrentResourceStorage().m_commandList->OMSetRenderTargets(1, + &CD3DX12_CPU_DESCRIPTOR_HANDLE(m_backbufferAsRendertarget[m_swapChain->GetCurrentBackBufferIndex()]->GetCPUDescriptorHandleForHeapStart()), + true, nullptr); D3D12_VERTEX_BUFFER_VIEW vbv = {}; vbv.BufferLocation = m_outputScalingPass.m_vertexBuffer->GetGPUVirtualAddress(); vbv.StrideInBytes = 4 * sizeof(float); @@ -856,9 +851,9 @@ void D3D12GSRender::Flip() getCurrentResourceStorage().m_commandList->DrawInstanced(4, 1, 0, 0); if (!Ini.GSOverlay.GetValue()) - getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &getResourceBarrierTransition(m_backBuffer[m_swapChain->GetCurrentBackBufferIndex()].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT)); + getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_backBuffer[m_swapChain->GetCurrentBackBufferIndex()].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT)); if (isFlipSurfaceInLocalMemory(m_surface_color_target) && m_rtts.m_currentlyBoundRenderTargets[0] != nullptr) - getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &getResourceBarrierTransition(m_rtts.m_currentlyBoundRenderTargets[0], D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_RENDER_TARGET)); + getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_rtts.m_currentlyBoundRenderTargets[0], D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_RENDER_TARGET)); ThrowIfFailed(getCurrentResourceStorage().m_commandList->Close()); m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)getCurrentResourceStorage().m_commandList.GetAddressOf()); @@ -889,7 +884,6 @@ void D3D12GSRender::Flip() // Flush m_texturesRTTs.clear(); - m_vertexCache.clear(); m_vertexConstants.clear(); // Now get ready for next frame @@ -911,6 +905,12 @@ void D3D12GSRender::ResetTimer() { m_timers.m_drawCallCount = 0; m_timers.m_drawCallDuration = 0; + m_timers.m_rttDuration = 0; + m_timers.m_vertexIndexDuration = 0; + m_timers.m_bufferUploadSize = 0; + m_timers.m_programLoadDuration = 0; + m_timers.m_constantsDuration = 0; + m_timers.m_textureDuration = 0; } D3D12GSRender::ResourceStorage& D3D12GSRender::getCurrentResourceStorage() @@ -941,20 +941,15 @@ ID3D12Resource * D3D12GSRender::writeColorBuffer(ID3D12Resource * RTT, ID3D12Gra break; } - D3D12_HEAP_PROPERTIES heapProp = {}; - heapProp.Type = D3D12_HEAP_TYPE_READBACK; - D3D12_RESOURCE_DESC resdesc = getBufferResourceDesc(rowPitch * h); - size_t sizeInByte = rowPitch * h; assert(m_readbackResources.canAlloc(sizeInByte)); size_t heapOffset = m_readbackResources.alloc(sizeInByte); - resdesc = getBufferResourceDesc(sizeInByte); ThrowIfFailed( m_device->CreatePlacedResource( m_readbackResources.m_heap, heapOffset, - &resdesc, + &CD3DX12_RESOURCE_DESC::Buffer(rowPitch * h), D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&Result) @@ -962,21 +957,11 @@ ID3D12Resource * D3D12GSRender::writeColorBuffer(ID3D12Resource * RTT, ID3D12Gra ); getCurrentResourceStorage().m_singleFrameLifetimeResources.push_back(Result); - cmdlist->ResourceBarrier(1, &getResourceBarrierTransition(RTT, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE)); + cmdlist->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(RTT, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE)); - D3D12_TEXTURE_COPY_LOCATION dst = {}, src = {}; - src.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - src.pResource = RTT; - dst.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; - dst.pResource = Result; - dst.PlacedFootprint.Offset = 0; - dst.PlacedFootprint.Footprint.Depth = 1; - dst.PlacedFootprint.Footprint.Format = dxgiFormat; - dst.PlacedFootprint.Footprint.Height = (UINT)h; - dst.PlacedFootprint.Footprint.Width = (UINT)w; - dst.PlacedFootprint.Footprint.RowPitch = (UINT)rowPitch; - cmdlist->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr); - cmdlist->ResourceBarrier(1, &getResourceBarrierTransition(RTT, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET)); + cmdlist->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(Result, { 0, {dxgiFormat, (UINT)h, (UINT)w, 1, (UINT)rowPitch } }), 0, 0, 0, + &CD3DX12_TEXTURE_COPY_LOCATION(RTT, 0), nullptr); + cmdlist->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(RTT, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET)); return Result; } @@ -1003,15 +988,15 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) // Except when a semaphore is written by RSX - ID3D12Fence *fence; + ComPtr fence; ThrowIfFailed( - m_device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence)) + m_device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(fence.GetAddressOf())) ); HANDLE handle = CreateEvent(0, FALSE, FALSE, 0); fence->SetEventOnCompletion(1, handle); ComPtr writeDest, depthConverted; - ID3D12DescriptorHeap *descriptorHeap; + ComPtr descriptorHeap; size_t depthRowPitch = m_surface_clip_w; depthRowPitch = (depthRowPitch + 255) & ~255; @@ -1020,11 +1005,6 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) if (m_set_context_dma_z && Ini.GSDumpDepthBuffer.GetValue()) { - D3D12_HEAP_PROPERTIES heapProp = {}; - heapProp.Type = D3D12_HEAP_TYPE_DEFAULT; - D3D12_RESOURCE_DESC resdesc = getTexture2DResourceDesc(m_surface_clip_w, m_surface_clip_h, DXGI_FORMAT_R8_UNORM, 1); - resdesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; - size_t sizeInByte = m_surface_clip_w * m_surface_clip_h * 2; assert(m_UAVHeap.canAlloc(sizeInByte)); size_t heapOffset = m_UAVHeap.alloc(sizeInByte); @@ -1033,39 +1013,32 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) m_device->CreatePlacedResource( m_UAVHeap.m_heap, heapOffset, - &resdesc, + &CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8_UNORM, m_surface_clip_w, m_surface_clip_h, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS), D3D12_RESOURCE_STATE_UNORDERED_ACCESS, nullptr, IID_PPV_ARGS(depthConverted.GetAddressOf()) ) ); - getCurrentResourceStorage().m_singleFrameLifetimeResources.push_back(depthConverted); sizeInByte = depthRowPitch * m_surface_clip_h; assert(m_readbackResources.canAlloc(sizeInByte)); heapOffset = m_readbackResources.alloc(sizeInByte); - resdesc = getBufferResourceDesc(sizeInByte); ThrowIfFailed( m_device->CreatePlacedResource( m_readbackResources.m_heap, heapOffset, - &resdesc, + &CD3DX12_RESOURCE_DESC::Buffer(sizeInByte), D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(writeDest.GetAddressOf()) ) ); - getCurrentResourceStorage().m_singleFrameLifetimeResources.push_back(writeDest); - D3D12_DESCRIPTOR_HEAP_DESC descriptorHeapDesc = {}; - descriptorHeapDesc.NumDescriptors = 2; - descriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; - descriptorHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + D3D12_DESCRIPTOR_HEAP_DESC descriptorHeapDesc = { D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV , 2, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE }; ThrowIfFailed( - m_device->CreateDescriptorHeap(&descriptorHeapDesc, IID_PPV_ARGS(&descriptorHeap)) + m_device->CreateDescriptorHeap(&descriptorHeapDesc, IID_PPV_ARGS(descriptorHeap.GetAddressOf())) ); - D3D12_CPU_DESCRIPTOR_HANDLE Handle = descriptorHeap->GetCPUDescriptorHandleForHeapStart(); D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; switch (m_surface_depth_format) { @@ -1084,51 +1057,32 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MipLevels = 1; srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; - m_device->CreateShaderResourceView(m_rtts.m_currentlyBoundDepthStencil, &srvDesc, Handle); - Handle.ptr += m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + m_device->CreateShaderResourceView(m_rtts.m_currentlyBoundDepthStencil, &srvDesc, + CD3DX12_CPU_DESCRIPTOR_HANDLE(descriptorHeap->GetCPUDescriptorHandleForHeapStart())); D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {}; uavDesc.Format = DXGI_FORMAT_R8_UNORM; uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D; - m_device->CreateUnorderedAccessView(depthConverted.Get(), nullptr, &uavDesc, Handle); + m_device->CreateUnorderedAccessView(depthConverted.Get(), nullptr, &uavDesc, + CD3DX12_CPU_DESCRIPTOR_HANDLE(descriptorHeap->GetCPUDescriptorHandleForHeapStart()).Offset(1, g_descriptorStrideSRVCBVUAV)); // Convert - getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &getResourceBarrierTransition(m_rtts.m_currentlyBoundDepthStencil, D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_GENERIC_READ)); + getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_rtts.m_currentlyBoundDepthStencil, D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_GENERIC_READ)); getCurrentResourceStorage().m_commandList->SetPipelineState(m_convertPSO); getCurrentResourceStorage().m_commandList->SetComputeRootSignature(m_convertRootSignature); - getCurrentResourceStorage().m_commandList->SetDescriptorHeaps(1, &descriptorHeap); + getCurrentResourceStorage().m_commandList->SetDescriptorHeaps(1, descriptorHeap.GetAddressOf()); getCurrentResourceStorage().m_commandList->SetComputeRootDescriptorTable(0, descriptorHeap->GetGPUDescriptorHandleForHeapStart()); getCurrentResourceStorage().m_commandList->Dispatch(m_surface_clip_w / 8, m_surface_clip_h / 8, 1); - // Flush UAV - D3D12_RESOURCE_BARRIER uavbarrier = {}; - uavbarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; - uavbarrier.UAV.pResource = depthConverted.Get(); - D3D12_RESOURCE_BARRIER barriers[] = { - getResourceBarrierTransition(m_rtts.m_currentlyBoundDepthStencil, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_DEPTH_WRITE), - uavbarrier, + CD3DX12_RESOURCE_BARRIER::Transition(m_rtts.m_currentlyBoundDepthStencil, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_DEPTH_WRITE), + CD3DX12_RESOURCE_BARRIER::UAV(depthConverted.Get()), }; getCurrentResourceStorage().m_commandList->ResourceBarrier(2, barriers); - getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &getResourceBarrierTransition(depthConverted.Get(), D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE)); - } - - if (m_set_context_dma_z && Ini.GSDumpDepthBuffer.GetValue()) - { - // Copy - D3D12_TEXTURE_COPY_LOCATION dst = {}, src = {}; - src.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - src.pResource = depthConverted.Get(); - dst.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; - dst.pResource = writeDest.Get(); - dst.PlacedFootprint.Offset = 0; - dst.PlacedFootprint.Footprint.Depth = 1; - dst.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8_UNORM; - dst.PlacedFootprint.Footprint.Height = m_surface_clip_h; - dst.PlacedFootprint.Footprint.Width = m_surface_clip_w; - dst.PlacedFootprint.Footprint.RowPitch = (UINT)depthRowPitch; - getCurrentResourceStorage().m_commandList->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr); + getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(depthConverted.Get(), D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE)); + getCurrentResourceStorage().m_commandList->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(writeDest.Get(), { 0, { DXGI_FORMAT_R8_UNORM, m_surface_clip_w, m_surface_clip_h, 1, (UINT)depthRowPitch } }), 0, 0, 0, + &CD3DX12_TEXTURE_COPY_LOCATION(depthConverted.Get(), 0), nullptr); invalidateTexture(GetAddress(m_surface_offset_z, m_context_dma_z - 0xfeed0000)); } @@ -1181,118 +1135,107 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) } //Wait for result - m_commandQueueGraphic->Signal(fence, 1); + m_commandQueueGraphic->Signal(fence.Get(), 1); + WaitForSingleObject(handle, INFINITE); + CloseHandle(handle); - auto tmp = [=]() { - WaitForSingleObject(handle, INFINITE); - CloseHandle(handle); - fence->Release(); + if (m_set_context_dma_z && Ini.GSDumpDepthBuffer.GetValue()) + { + u32 address = GetAddress(m_surface_offset_z, m_context_dma_z - 0xfeed0000); + auto ptr = vm::get_ptr(address); + char *ptrAsChar = (char*)ptr; + unsigned char *writeDestPtr; + ThrowIfFailed(writeDest->Map(0, nullptr, (void**)&writeDestPtr)); - if (m_set_context_dma_z && Ini.GSDumpDepthBuffer.GetValue()) + for (unsigned row = 0; row < m_surface_clip_h; row++) { - u32 address = GetAddress(m_surface_offset_z, m_context_dma_z - 0xfeed0000); - auto ptr = vm::get_ptr(address); - char *ptrAsChar = (char*)ptr; - unsigned char *writeDestPtr; - ThrowIfFailed(writeDest->Map(0, nullptr, (void**)&writeDestPtr)); - // TODO : this should be done by the gpu - for (unsigned row = 0; row < m_surface_clip_h; row++) + for (unsigned i = 0; i < m_surface_clip_w; i++) { - for (unsigned i = 0; i < m_surface_clip_w; i++) - { - unsigned char c = writeDestPtr[row * depthRowPitch + i]; - ptrAsChar[4 * (row * m_surface_clip_w + i)] = c; - ptrAsChar[4 * (row * m_surface_clip_w + i) + 1] = c; - ptrAsChar[4 * (row * m_surface_clip_w + i) + 2] = c; - ptrAsChar[4 * (row * m_surface_clip_w + i) + 3] = c; - } - } - descriptorHeap->Release(); - } - - size_t srcPitch, dstPitch; - switch (m_surface_color_format) - { - case CELL_GCM_SURFACE_A8R8G8B8: - srcPitch = align(m_surface_clip_w * 4, 256); - dstPitch = m_surface_clip_w * 4; - break; - case CELL_GCM_SURFACE_F_W16Z16Y16X16: - srcPitch = align(m_surface_clip_w * 8, 256); - dstPitch = m_surface_clip_w * 8; - break; - } - - if (Ini.GSDumpColorBuffers.GetValue()) - { - switch (m_surface_color_target) - { - case CELL_GCM_SURFACE_TARGET_NONE: - break; - - case CELL_GCM_SURFACE_TARGET_0: - { - u32 address = GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000); - void *dstAddress = vm::get_ptr(address); - copyToCellRamAndRelease(dstAddress, rtt0, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); - } - break; - - case CELL_GCM_SURFACE_TARGET_1: - { - u32 address = GetAddress(m_surface_offset_b, m_context_dma_color_b - 0xfeed0000); - void *dstAddress = vm::get_ptr(address); - copyToCellRamAndRelease(dstAddress, rtt1, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); - } - break; - - case CELL_GCM_SURFACE_TARGET_MRT1: - { - u32 address = GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000); - void *dstAddress = vm::get_ptr(address); - copyToCellRamAndRelease(dstAddress, rtt0, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); - address = GetAddress(m_surface_offset_b, m_context_dma_color_b - 0xfeed0000); - dstAddress = vm::get_ptr(address); - copyToCellRamAndRelease(dstAddress, rtt1, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); - } - break; - - case CELL_GCM_SURFACE_TARGET_MRT2: - { - u32 address = GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000); - void *dstAddress = vm::get_ptr(address); - copyToCellRamAndRelease(dstAddress, rtt0, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); - address = GetAddress(m_surface_offset_b, m_context_dma_color_b - 0xfeed0000); - dstAddress = vm::get_ptr(address); - copyToCellRamAndRelease(dstAddress, rtt1, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); - address = GetAddress(m_surface_offset_c, m_context_dma_color_c - 0xfeed0000); - dstAddress = vm::get_ptr(address); - copyToCellRamAndRelease(dstAddress, rtt2, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); - } - break; - - case CELL_GCM_SURFACE_TARGET_MRT3: - { - u32 address = GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000); - void *dstAddress = vm::get_ptr(address); - copyToCellRamAndRelease(dstAddress, rtt0, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); - address = GetAddress(m_surface_offset_b, m_context_dma_color_b - 0xfeed0000); - dstAddress = vm::get_ptr(address); - copyToCellRamAndRelease(dstAddress, rtt1, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); - address = GetAddress(m_surface_offset_c, m_context_dma_color_c - 0xfeed0000); - dstAddress = vm::get_ptr(address); - copyToCellRamAndRelease(dstAddress, rtt2, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); - address = GetAddress(m_surface_offset_d, m_context_dma_color_d - 0xfeed0000); - dstAddress = vm::get_ptr(address); - copyToCellRamAndRelease(dstAddress, rtt3, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); - } - break; + unsigned char c = writeDestPtr[row * depthRowPitch + i]; + ptrAsChar[4 * (row * m_surface_clip_w + i)] = c; + ptrAsChar[4 * (row * m_surface_clip_w + i) + 1] = c; + ptrAsChar[4 * (row * m_surface_clip_w + i) + 2] = c; + ptrAsChar[4 * (row * m_surface_clip_w + i) + 3] = c; } } + } - vm::write32(m_label_addr + offset, value); - }; - tmp(); + size_t srcPitch, dstPitch; + switch (m_surface_color_format) + { + case CELL_GCM_SURFACE_A8R8G8B8: + srcPitch = align(m_surface_clip_w * 4, 256); + dstPitch = m_surface_clip_w * 4; + break; + case CELL_GCM_SURFACE_F_W16Z16Y16X16: + srcPitch = align(m_surface_clip_w * 8, 256); + dstPitch = m_surface_clip_w * 8; + break; + } + + if (Ini.GSDumpColorBuffers.GetValue()) + { + switch (m_surface_color_target) + { + case CELL_GCM_SURFACE_TARGET_NONE: + break; + case CELL_GCM_SURFACE_TARGET_0: + { + u32 address = GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000); + void *dstAddress = vm::get_ptr(address); + copyToCellRamAndRelease(dstAddress, rtt0, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); + } + break; + case CELL_GCM_SURFACE_TARGET_1: + { + u32 address = GetAddress(m_surface_offset_b, m_context_dma_color_b - 0xfeed0000); + void *dstAddress = vm::get_ptr(address); + copyToCellRamAndRelease(dstAddress, rtt1, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); + } + break; + case CELL_GCM_SURFACE_TARGET_MRT1: + { + u32 address = GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000); + void *dstAddress = vm::get_ptr(address); + copyToCellRamAndRelease(dstAddress, rtt0, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); + address = GetAddress(m_surface_offset_b, m_context_dma_color_b - 0xfeed0000); + dstAddress = vm::get_ptr(address); + copyToCellRamAndRelease(dstAddress, rtt1, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); + } + break; + case CELL_GCM_SURFACE_TARGET_MRT2: + { + u32 address = GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000); + void *dstAddress = vm::get_ptr(address); + copyToCellRamAndRelease(dstAddress, rtt0, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); + address = GetAddress(m_surface_offset_b, m_context_dma_color_b - 0xfeed0000); + dstAddress = vm::get_ptr(address); + copyToCellRamAndRelease(dstAddress, rtt1, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); + address = GetAddress(m_surface_offset_c, m_context_dma_color_c - 0xfeed0000); + dstAddress = vm::get_ptr(address); + copyToCellRamAndRelease(dstAddress, rtt2, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); + } + break; + case CELL_GCM_SURFACE_TARGET_MRT3: + { + u32 address = GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000); + void *dstAddress = vm::get_ptr(address); + copyToCellRamAndRelease(dstAddress, rtt0, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); + address = GetAddress(m_surface_offset_b, m_context_dma_color_b - 0xfeed0000); + dstAddress = vm::get_ptr(address); + copyToCellRamAndRelease(dstAddress, rtt1, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); + address = GetAddress(m_surface_offset_c, m_context_dma_color_c - 0xfeed0000); + dstAddress = vm::get_ptr(address); + copyToCellRamAndRelease(dstAddress, rtt2, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); + address = GetAddress(m_surface_offset_d, m_context_dma_color_d - 0xfeed0000); + dstAddress = vm::get_ptr(address); + copyToCellRamAndRelease(dstAddress, rtt3, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); + } + break; + } + } + + vm::write32(m_label_addr + offset, value); } void D3D12GSRender::semaphorePFIFOAcquire(u32 offset, u32 value) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h index 8a46842d30..f03064fa43 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h @@ -13,6 +13,7 @@ #include "D3D12RenderTargetSets.h" #include "D3D12PipelineState.h" #include "D3D12Buffer.h" +#include "d3dx12.h" // Some constants are the same between RSX and GL #include @@ -34,9 +35,6 @@ * draw call use the same buffer, but the first one doesn't use all the attribute ; then the second one will use * the cached version and not have updated attributes. Same for texture, if format/size does change, the caching * system is ignoring it. - * - Fix vertex buffer in The Guided Paradox - * The vertex info in the guided paradox are wrong, leading to missing character parts ingame (like leg or torso). - * It's because some vertex position are incorrect. * - Improve sync between cell and RSX * A lot of optimisation can be gained from using Cell and RSX latency. Cell can't read RSX generated data without * synchronisation. We currently only cover semaphore sync, but there are more (like implicit sync at flip) that @@ -97,7 +95,7 @@ struct InitHeap heapProperties.Type = type; ThrowIfFailed(device->CreateCommittedResource(&heapProperties, flags, - &getBufferResourceDesc(heapSize), + &CD3DX12_RESOURCE_DESC::Buffer(heapSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&result)) @@ -231,10 +229,6 @@ private: std::unordered_map m_texturesCache; // std::vector m_post_draw_objs; - // TODO: Use a tree structure to parse more efficiently - // Key is begin << 32 | end - std::unordered_map m_vertexCache; - PipelineStateObjectCache m_cachePSO; std::pair *m_PSO; @@ -242,6 +236,12 @@ private: { size_t m_drawCallDuration; size_t m_drawCallCount; + size_t m_rttDuration; + size_t m_vertexIndexDuration; + size_t m_bufferUploadSize; + size_t m_programLoadDuration; + size_t m_constantsDuration; + size_t m_textureDuration; } m_timers; void ResetTimer(); @@ -253,7 +253,7 @@ private: ID3D12Resource *m_vertexBuffer; ID3D12DescriptorHeap *m_textureDescriptorHeap; ID3D12DescriptorHeap *m_samplerDescriptorHeap; - void Init(ID3D12Device *device); + void Init(ID3D12Device *device, ID3D12CommandQueue *gfxcommandqueue); void Release(); }; @@ -330,7 +330,7 @@ private: // Constants storage DataHeap m_constantsData; // Vertex storage - DataHeap m_vertexIndexData; + DataHeap m_vertexIndexData; // Texture storage DataHeap m_textureUploadData; DataHeap m_UAVHeap; @@ -347,10 +347,10 @@ private: std::vector m_IASet; - size_t g_descriptorStrideSRVCBVUAV; - size_t g_descriptorStrideDSV; - size_t g_descriptorStrideRTV; - size_t g_descriptorStrideSamplers; + INT g_descriptorStrideSRVCBVUAV; + INT g_descriptorStrideDSV; + INT g_descriptorStrideRTV; + INT g_descriptorStrideSamplers; // Used to fill unused texture slot ID3D12Resource *m_dummyTexture; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Overlay.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Overlay.cpp index d6c08375e1..4f05937e62 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Overlay.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Overlay.cpp @@ -117,7 +117,19 @@ void D3D12GSRender::ReleaseD2DStructures() void D3D12GSRender::renderOverlay() { D2D1_SIZE_F rtSize = m_d2dRenderTargets[m_swapChain->GetCurrentBackBufferIndex()]->GetSize(); - std::wstring duration = L"Draw duration : " + std::to_wstring(m_timers.m_drawCallDuration) + L" ms"; + std::wstring duration = L"Draw duration : " + std::to_wstring(m_timers.m_drawCallDuration) + L" us"; + float vtxIdxPercent = (float)m_timers.m_vertexIndexDuration / (float)m_timers.m_drawCallDuration; + std::wstring vertexIndexDuration = L"Vtx/Idx upload : " + std::to_wstring(m_timers.m_vertexIndexDuration) + L" us (" + std::to_wstring(100.f * vtxIdxPercent) + L" %)"; + std::wstring size = L"Upload size : " + std::to_wstring(m_timers.m_bufferUploadSize) + L" Bytes"; + float texPercent = (float)m_timers.m_textureDuration / (float)m_timers.m_drawCallDuration; + std::wstring texDuration = L"Textures : " + std::to_wstring(m_timers.m_textureDuration) + L" us (" + std::to_wstring(100.f * texPercent) + L" %)"; + float programPercent = (float)m_timers.m_programLoadDuration / (float)m_timers.m_drawCallDuration; + std::wstring programDuration = L"Program : " + std::to_wstring(m_timers.m_programLoadDuration) + L" us (" + std::to_wstring(100.f * programPercent) + L" %)"; + float constantsPercent = (float)m_timers.m_constantsDuration / (float)m_timers.m_drawCallDuration; + std::wstring constantDuration = L"Constants : " + std::to_wstring(m_timers.m_constantsDuration) + L" us (" + std::to_wstring(100.f * constantsPercent) + L" %)"; + float rttPercent = (float)m_timers.m_rttDuration / (float)m_timers.m_drawCallDuration; + std::wstring rttDuration = L"RTT : " + std::to_wstring(m_timers.m_rttDuration) + L" us (" + std::to_wstring(100.f * rttPercent) + L" %)"; + std::wstring count = L"Draw count : " + std::to_wstring(m_timers.m_drawCallCount); // Acquire our wrapped render target resource for the current back buffer. @@ -129,18 +141,60 @@ void D3D12GSRender::renderOverlay() m_d2dDeviceContext->SetTransform(D2D1::Matrix3x2F::Identity()); m_d2dDeviceContext->DrawTextW( duration.c_str(), - duration.size(), + (UINT32)duration.size(), m_textFormat.Get(), &D2D1::RectF(0, 0, rtSize.width, rtSize.height), m_textBrush.Get() ); m_d2dDeviceContext->DrawTextW( count.c_str(), - count.size(), + (UINT32)count.size(), m_textFormat.Get(), &D2D1::RectF(0, 14, rtSize.width, rtSize.height), m_textBrush.Get() ); + m_d2dDeviceContext->DrawTextW( + rttDuration.c_str(), + (UINT32)rttDuration.size(), + m_textFormat.Get(), + &D2D1::RectF(0, 28, rtSize.width, rtSize.height), + m_textBrush.Get() + ); + m_d2dDeviceContext->DrawTextW( + vertexIndexDuration.c_str(), + (UINT32)vertexIndexDuration.size(), + m_textFormat.Get(), + &D2D1::RectF(0, 42, rtSize.width, rtSize.height), + m_textBrush.Get() + ); + m_d2dDeviceContext->DrawTextW( + size.c_str(), + (UINT32)size.size(), + m_textFormat.Get(), + &D2D1::RectF(0, 56, rtSize.width, rtSize.height), + m_textBrush.Get() + ); + m_d2dDeviceContext->DrawTextW( + programDuration.c_str(), + (UINT32)programDuration.size(), + m_textFormat.Get(), + &D2D1::RectF(0, 70, rtSize.width, rtSize.height), + m_textBrush.Get() + ); + m_d2dDeviceContext->DrawTextW( + constantDuration.c_str(), + (UINT32)constantDuration.size(), + m_textFormat.Get(), + &D2D1::RectF(0, 86, rtSize.width, rtSize.height), + m_textBrush.Get() + ); + m_d2dDeviceContext->DrawTextW( + texDuration.c_str(), + (UINT32)texDuration.size(), + m_textFormat.Get(), + &D2D1::RectF(0, 98, rtSize.width, rtSize.height), + m_textBrush.Get() + ); m_d2dDeviceContext->EndDraw(); // Release our wrapped render target resource. Releasing diff --git a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp index bc8132a272..a50d8b6caa 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp @@ -26,11 +26,11 @@ void D3D12GSRender::PrepareRenderTargets(ID3D12GraphicsCommandList *copycmdlist) { if (m_rtts.m_currentlyBoundRenderTargets[i] == nullptr) continue; - copycmdlist->ResourceBarrier(1, &getResourceBarrierTransition(m_rtts.m_currentlyBoundRenderTargets[i], D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_GENERIC_READ)); + copycmdlist->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_rtts.m_currentlyBoundRenderTargets[i], D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_GENERIC_READ)); } // Same for depth buffer if (m_rtts.m_currentlyBoundDepthStencil != nullptr) - copycmdlist->ResourceBarrier(1, &getResourceBarrierTransition(m_rtts.m_currentlyBoundDepthStencil, D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_GENERIC_READ)); + copycmdlist->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_rtts.m_currentlyBoundDepthStencil, D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_GENERIC_READ)); memset(m_rtts.m_currentlyBoundRenderTargetsAddress, 0, 4 * sizeof(u32)); memset(m_rtts.m_currentlyBoundRenderTargets, 0, 4 * sizeof(ID3D12Resource *)); @@ -148,7 +148,7 @@ ID3D12Resource *RenderTargets::bindAddressAsRenderTargets(ID3D12Device *device, if (It != m_renderTargets.end()) { rtt = It->second; - cmdList->ResourceBarrier(1, &getResourceBarrierTransition(rtt, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_RENDER_TARGET)); + cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(rtt, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_RENDER_TARGET)); } else { @@ -170,16 +170,10 @@ ID3D12Resource *RenderTargets::bindAddressAsRenderTargets(ID3D12Device *device, clearColorValue.Color[2] = clearColorB; clearColorValue.Color[3] = clearColorA; - D3D12_HEAP_PROPERTIES heapProp = {}; - heapProp.Type = D3D12_HEAP_TYPE_DEFAULT; - - D3D12_RESOURCE_DESC resourceDesc = getTexture2DResourceDesc(width, height, dxgiFormat, 1); - resourceDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; - device->CreateCommittedResource( - &heapProp, + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, - &resourceDesc, + &CD3DX12_RESOURCE_DESC::Tex2D(dxgiFormat, (UINT)width, (UINT)height, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET), D3D12_RESOURCE_STATE_RENDER_TARGET, &clearColorValue, IID_PPV_ARGS(&rtt) @@ -200,7 +194,7 @@ ID3D12Resource * RenderTargets::bindAddressAsDepthStencil(ID3D12Device * device, if (It != m_depthStencil.end()) { ds = It->second; - cmdList->ResourceBarrier(1, &getResourceBarrierTransition(ds, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_DEPTH_WRITE)); + cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(ds, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_DEPTH_WRITE)); } else { @@ -228,13 +222,10 @@ ID3D12Resource * RenderTargets::bindAddressAsDepthStencil(ID3D12Device * device, assert(0); } - D3D12_RESOURCE_DESC resourceDesc = getTexture2DResourceDesc(width, height, dxgiFormat, 1); - resourceDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; - device->CreateCommittedResource( - &heapProp, + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, - &resourceDesc, + &CD3DX12_RESOURCE_DESC::Tex2D(dxgiFormat, (UINT)width, (UINT)height, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL), D3D12_RESOURCE_STATE_DEPTH_WRITE, &clearDepthValue, IID_PPV_ARGS(&ds) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp index 34026f3fa0..cdccc95bdb 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #if defined(DX12_SUPPORT) #include "D3D12GSRender.h" +#include "d3dx12.h" // For clarity this code deals with texture but belongs to D3D12GSRender class @@ -221,7 +222,6 @@ writeTexelsSwizzled(const char *src, char *dst, size_t widthInBlock, size_t heig log2width = (u32)(logf((float)currentWidth) / logf(2.f)); log2height = (u32)(logf((float)currentHeight) / logf(2.f)); -#pragma omp parallel for for (int row = 0; row < currentHeight; row++) for (int j = 0; j < currentWidth; j++) castedDst[(row * rowPitch / 4) + j] = castedSrc[LinearToSwizzleAddress(j, row, 0, log2width, log2height, 0)]; @@ -297,7 +297,6 @@ write16bTexelsSwizzled(const char *src, char *dst, size_t widthInBlock, size_t h log2width = (u32)(logf((float)currentWidth) / logf(2.f)); log2height = (u32)(logf((float)currentHeight) / logf(2.f)); -#pragma omp parallel for for (int row = 0; row < currentHeight; row++) for (int j = 0; j < currentWidth; j++) castedDst[(row * rowPitch / 2) + j] = castedSrc[LinearToSwizzleAddress(j, row, 0, log2width, log2height, 0)]; @@ -559,7 +558,7 @@ ID3D12Resource *uploadSingleTexture( ThrowIfFailed(device->CreatePlacedResource( textureBuffersHeap.m_heap, heapOffset, - &getBufferResourceDesc(textureSize), + &CD3DX12_RESOURCE_DESC::Buffer(textureSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(Texture.GetAddressOf()) @@ -611,14 +610,11 @@ ID3D12Resource *uploadSingleTexture( } Texture->Unmap(0, nullptr); - D3D12_RESOURCE_DESC texturedesc = getTexture2DResourceDesc(w, h, dxgiFormat, texture.GetMipmap()); + D3D12_RESOURCE_DESC texturedesc = CD3DX12_RESOURCE_DESC::Tex2D(dxgiFormat, (UINT)w, (UINT)h, 1, texture.GetMipmap()); textureSize = device->GetResourceAllocationInfo(0, 1, &texturedesc).SizeInBytes; - D3D12_HEAP_PROPERTIES heapProp = {}; - heapProp.Type = D3D12_HEAP_TYPE_DEFAULT; - ThrowIfFailed(device->CreateCommittedResource( - &heapProp, + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &texturedesc, D3D12_RESOURCE_STATE_COPY_DEST, @@ -629,29 +625,12 @@ ID3D12Resource *uploadSingleTexture( size_t miplevel = 0; for (const MipmapLevelInfo mli : mipInfos) { - D3D12_TEXTURE_COPY_LOCATION dst = {}, src = {}; - dst.pResource = vramTexture; - dst.SubresourceIndex = (UINT)miplevel; - dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - src.PlacedFootprint.Offset = mli.offset; - src.pResource = Texture.Get(); - src.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; - src.PlacedFootprint.Footprint.Depth = 1; - src.PlacedFootprint.Footprint.Width = (UINT)mli.width; - src.PlacedFootprint.Footprint.Height = (UINT)mli.height; - src.PlacedFootprint.Footprint.RowPitch = (UINT)mli.rowPitch; - src.PlacedFootprint.Footprint.Format = dxgiFormat; - - commandList->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr); + commandList->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(vramTexture, (UINT)miplevel), 0, 0, 0, + &CD3DX12_TEXTURE_COPY_LOCATION(Texture.Get(), { mli.offset, { dxgiFormat, (UINT)mli.width, (UINT)mli.height, 1, (UINT)mli.rowPitch } }), nullptr); miplevel++; } - D3D12_RESOURCE_BARRIER barrier = {}; - barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - barrier.Transition.pResource = vramTexture; - barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; - barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_GENERIC_READ; - commandList->ResourceBarrier(1, &barrier); + commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(vramTexture, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_GENERIC_READ)); return vramTexture; } @@ -892,19 +871,17 @@ size_t D3D12GSRender::UploadTextures(ID3D12GraphicsCommandList *cmdlist) break; } - D3D12_CPU_DESCRIPTOR_HANDLE Handle = getCurrentResourceStorage().m_textureDescriptorsHeap->GetCPUDescriptorHandleForHeapStart(); - Handle.ptr += (getCurrentResourceStorage().m_currentTextureIndex + usedTexture) * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - m_device->CreateShaderResourceView(vramTexture, &srvDesc, Handle); + m_device->CreateShaderResourceView(vramTexture, &srvDesc, + CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_textureDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()).Offset((UINT)getCurrentResourceStorage().m_currentTextureIndex + (UINT)usedTexture, g_descriptorStrideSRVCBVUAV)); if (getCurrentResourceStorage().m_currentSamplerIndex + 16 > 2048) { getCurrentResourceStorage().m_samplerDescriptorHeapIndex = 1; getCurrentResourceStorage().m_currentSamplerIndex = 0; } - - Handle = getCurrentResourceStorage().m_samplerDescriptorHeap[getCurrentResourceStorage().m_samplerDescriptorHeapIndex]->GetCPUDescriptorHandleForHeapStart(); - Handle.ptr += (getCurrentResourceStorage().m_currentSamplerIndex + usedTexture) * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); - m_device->CreateSampler(&getSamplerDesc(m_textures[i]), Handle); + m_device->CreateSampler(&getSamplerDesc(m_textures[i]), + CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_samplerDescriptorHeap[getCurrentResourceStorage().m_samplerDescriptorHeapIndex]->GetCPUDescriptorHandleForHeapStart()) + .Offset((UINT)getCurrentResourceStorage().m_currentSamplerIndex + (UINT)usedTexture, g_descriptorStrideSRVCBVUAV)); usedTexture++; } diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Utils.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Utils.cpp index 5c69464a82..de92a9c652 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Utils.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Utils.cpp @@ -5,6 +5,7 @@ #if defined(DX12_SUPPORT) #include "D3D12GSRender.h" #include +#include "d3dx12.h" #define STRINGIFY(x) #x extern PFN_D3D12_SERIALIZE_ROOT_SIGNATURE wrapD3D12SerializeRootSignature; @@ -67,7 +68,7 @@ std::pair compileF32toU8CS() } -void D3D12GSRender::Shader::Init(ID3D12Device *device) +void D3D12GSRender::Shader::Init(ID3D12Device *device, ID3D12CommandQueue *gfxcommandqueue) { const char *fsCode = STRINGIFY( Texture2D InputTexture : register(t0); \n @@ -187,6 +188,19 @@ void D3D12GSRender::Shader::Init(ID3D12Device *device) ThrowIfFailed(device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_PSO))); + D3D12_DESCRIPTOR_HEAP_DESC textureHeapDesc = { D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV , 2, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE }; + ThrowIfFailed( + device->CreateDescriptorHeap(&textureHeapDesc, IID_PPV_ARGS(&m_textureDescriptorHeap)) + ); + D3D12_DESCRIPTOR_HEAP_DESC samplerHeapDesc = { D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER , 2, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE }; + ThrowIfFailed( + device->CreateDescriptorHeap(&samplerHeapDesc, IID_PPV_ARGS(&m_samplerDescriptorHeap)) + ); + + ComPtr fence; + ThrowIfFailed(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(fence.GetAddressOf()))); + HANDLE handle = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS); + fence->SetEventOnCompletion(1, handle); float quadVertex[16] = { -1., -1., 0., 1., @@ -195,35 +209,46 @@ void D3D12GSRender::Shader::Init(ID3D12Device *device) 1., 1., 1., 0., }; - D3D12_HEAP_PROPERTIES heapProp = {}; - heapProp.Type = D3D12_HEAP_TYPE_UPLOAD; + ComPtr cmdlistAllocator; + ThrowIfFailed( + device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(cmdlistAllocator.GetAddressOf())) + ); + ComPtr cmdList; + ThrowIfFailed( + device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, cmdlistAllocator.Get(),nullptr, IID_PPV_ARGS(cmdList.GetAddressOf())) + ); + ComPtr intermediateBuffer; + ThrowIfFailed(device->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC::Buffer(16 * sizeof(float)), + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(intermediateBuffer.GetAddressOf()) + )); + ThrowIfFailed( device->CreateCommittedResource( - &heapProp, + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, - &getBufferResourceDesc(16 * sizeof(float)), - D3D12_RESOURCE_STATE_GENERIC_READ, + &CD3DX12_RESOURCE_DESC::Buffer(16 * sizeof(float)), + D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_vertexBuffer) )); - void *tmp; - m_vertexBuffer->Map(0, nullptr, &tmp); - memcpy(tmp, quadVertex, 16 * sizeof(float)); - m_vertexBuffer->Unmap(0, nullptr); + D3D12_SUBRESOURCE_DATA vertexData = { reinterpret_cast(quadVertex), 16 * sizeof(float), 1 }; - D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {}; - heapDesc.NumDescriptors = 2; - heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; - heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + UpdateSubresources(cmdList.Get(), m_vertexBuffer, intermediateBuffer.Get(), 0, 0, 1, &vertexData); + cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_vertexBuffer, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER)); + ThrowIfFailed(cmdList->Close()); - ThrowIfFailed( - device->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&m_textureDescriptorHeap)) - ); - heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; - ThrowIfFailed( - device->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&m_samplerDescriptorHeap)) - ); + gfxcommandqueue->ExecuteCommandLists(1, CommandListCast(cmdList.GetAddressOf())); + + // Now wait until upload has completed + gfxcommandqueue->Signal(fence.Get(), 1); + WaitForSingleObjectEx(handle, INFINITE, FALSE); + CloseHandle(handle); } void D3D12GSRender::initConvertShader() diff --git a/rpcs3/Emu/RSX/D3D12/d3dx12.h b/rpcs3/Emu/RSX/D3D12/d3dx12.h new file mode 100644 index 0000000000..2e79a23489 --- /dev/null +++ b/rpcs3/Emu/RSX/D3D12/d3dx12.h @@ -0,0 +1,1531 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx12.h +// Content: D3DX12 utility library +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __D3DX12_H__ +#define __D3DX12_H__ + +#include "d3d12.h" + +#if defined( __cplusplus ) + +struct CD3DX12_DEFAULT {}; +extern const DECLSPEC_SELECTANY CD3DX12_DEFAULT D3D12_DEFAULT; + +//------------------------------------------------------------------------------------------------ +inline bool operator==(const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r) +{ + return l.TopLeftX == r.TopLeftX && l.TopLeftY == r.TopLeftY && l.Width == r.Width && + l.Height == r.Height && l.MinDepth == r.MinDepth && l.MaxDepth == r.MaxDepth; +} + +//------------------------------------------------------------------------------------------------ +inline bool operator!=(const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r) +{ + return !(l == r); +} + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RECT : public D3D12_RECT +{ + CD3DX12_RECT() + {} + explicit CD3DX12_RECT(const D3D12_RECT& o) : + D3D12_RECT(o) + {} + explicit CD3DX12_RECT( + LONG Left, + LONG Top, + LONG Right, + LONG Bottom) + { + left = Left; + top = Top; + right = Right; + bottom = Bottom; + } + ~CD3DX12_RECT() {} + operator const D3D12_RECT&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_BOX : public D3D12_BOX +{ + CD3DX12_BOX() + {} + explicit CD3DX12_BOX(const D3D12_BOX& o) : + D3D12_BOX(o) + {} + explicit CD3DX12_BOX( + LONG Left, + LONG Right) + { + left = Left; + top = 0; + front = 0; + right = Right; + bottom = 1; + back = 1; + } + explicit CD3DX12_BOX( + LONG Left, + LONG Top, + LONG Right, + LONG Bottom) + { + left = Left; + top = Top; + front = 0; + right = Right; + bottom = Bottom; + back = 1; + } + explicit CD3DX12_BOX( + LONG Left, + LONG Top, + LONG Front, + LONG Right, + LONG Bottom, + LONG Back) + { + left = Left; + top = Top; + front = Front; + right = Right; + bottom = Bottom; + back = Back; + } + ~CD3DX12_BOX() {} + operator const D3D12_BOX&() const { return *this; } +}; +inline bool operator==(const D3D12_BOX& l, const D3D12_BOX& r) +{ + return l.left == r.left && l.top == r.top && l.front == r.front && + l.right == r.right && l.bottom == r.bottom && l.back == r.back; +} +inline bool operator!=(const D3D12_BOX& l, const D3D12_BOX& r) +{ + return !(l == r); +} + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_DEPTH_STENCIL_DESC : public D3D12_DEPTH_STENCIL_DESC +{ + CD3DX12_DEPTH_STENCIL_DESC() + {} + explicit CD3DX12_DEPTH_STENCIL_DESC(const D3D12_DEPTH_STENCIL_DESC& o) : + D3D12_DEPTH_STENCIL_DESC(o) + {} + explicit CD3DX12_DEPTH_STENCIL_DESC(CD3DX12_DEFAULT) + { + DepthEnable = TRUE; + DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; + DepthFunc = D3D12_COMPARISON_FUNC_LESS; + StencilEnable = FALSE; + StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK; + StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK; + const D3D12_DEPTH_STENCILOP_DESC defaultStencilOp = + { D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS }; + FrontFace = defaultStencilOp; + BackFace = defaultStencilOp; + } + explicit CD3DX12_DEPTH_STENCIL_DESC( + BOOL depthEnable, + D3D12_DEPTH_WRITE_MASK depthWriteMask, + D3D12_COMPARISON_FUNC depthFunc, + BOOL stencilEnable, + UINT8 stencilReadMask, + UINT8 stencilWriteMask, + D3D12_STENCIL_OP frontStencilFailOp, + D3D12_STENCIL_OP frontStencilDepthFailOp, + D3D12_STENCIL_OP frontStencilPassOp, + D3D12_COMPARISON_FUNC frontStencilFunc, + D3D12_STENCIL_OP backStencilFailOp, + D3D12_STENCIL_OP backStencilDepthFailOp, + D3D12_STENCIL_OP backStencilPassOp, + D3D12_COMPARISON_FUNC backStencilFunc) + { + DepthEnable = depthEnable; + DepthWriteMask = depthWriteMask; + DepthFunc = depthFunc; + StencilEnable = stencilEnable; + StencilReadMask = stencilReadMask; + StencilWriteMask = stencilWriteMask; + FrontFace.StencilFailOp = frontStencilFailOp; + FrontFace.StencilDepthFailOp = frontStencilDepthFailOp; + FrontFace.StencilPassOp = frontStencilPassOp; + FrontFace.StencilFunc = frontStencilFunc; + BackFace.StencilFailOp = backStencilFailOp; + BackFace.StencilDepthFailOp = backStencilDepthFailOp; + BackFace.StencilPassOp = backStencilPassOp; + BackFace.StencilFunc = backStencilFunc; + } + ~CD3DX12_DEPTH_STENCIL_DESC() {} + operator const D3D12_DEPTH_STENCIL_DESC&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_BLEND_DESC : public D3D12_BLEND_DESC +{ + CD3DX12_BLEND_DESC() + {} + explicit CD3DX12_BLEND_DESC(const D3D12_BLEND_DESC& o) : + D3D12_BLEND_DESC(o) + {} + explicit CD3DX12_BLEND_DESC(CD3DX12_DEFAULT) + { + AlphaToCoverageEnable = FALSE; + IndependentBlendEnable = FALSE; + const D3D12_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc = + { + FALSE,FALSE, + D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, + D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, + D3D12_LOGIC_OP_NOOP, + D3D12_COLOR_WRITE_ENABLE_ALL, + }; + for (UINT i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + RenderTarget[i] = defaultRenderTargetBlendDesc; + } + ~CD3DX12_BLEND_DESC() {} + operator const D3D12_BLEND_DESC&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RASTERIZER_DESC : public D3D12_RASTERIZER_DESC +{ + CD3DX12_RASTERIZER_DESC() + {} + explicit CD3DX12_RASTERIZER_DESC(const D3D12_RASTERIZER_DESC& o) : + D3D12_RASTERIZER_DESC(o) + {} + explicit CD3DX12_RASTERIZER_DESC(CD3DX12_DEFAULT) + { + FillMode = D3D12_FILL_MODE_SOLID; + CullMode = D3D12_CULL_MODE_BACK; + FrontCounterClockwise = FALSE; + DepthBias = D3D12_DEFAULT_DEPTH_BIAS; + DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; + SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + DepthClipEnable = TRUE; + MultisampleEnable = FALSE; + AntialiasedLineEnable = FALSE; + ForcedSampleCount = 0; + ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; + } + explicit CD3DX12_RASTERIZER_DESC( + D3D12_FILL_MODE fillMode, + D3D12_CULL_MODE cullMode, + BOOL frontCounterClockwise, + INT depthBias, + FLOAT depthBiasClamp, + FLOAT slopeScaledDepthBias, + BOOL depthClipEnable, + BOOL multisampleEnable, + BOOL antialiasedLineEnable, + UINT forcedSampleCount, + D3D12_CONSERVATIVE_RASTERIZATION_MODE conservativeRaster) + { + FillMode = fillMode; + CullMode = cullMode; + FrontCounterClockwise = frontCounterClockwise; + DepthBias = depthBias; + DepthBiasClamp = depthBiasClamp; + SlopeScaledDepthBias = slopeScaledDepthBias; + DepthClipEnable = depthClipEnable; + MultisampleEnable = multisampleEnable; + AntialiasedLineEnable = antialiasedLineEnable; + ForcedSampleCount = forcedSampleCount; + ConservativeRaster = conservativeRaster; + } + ~CD3DX12_RASTERIZER_DESC() {} + operator const D3D12_RASTERIZER_DESC&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_ALLOCATION_INFO : public D3D12_RESOURCE_ALLOCATION_INFO +{ + CD3DX12_RESOURCE_ALLOCATION_INFO() + {} + explicit CD3DX12_RESOURCE_ALLOCATION_INFO(const D3D12_RESOURCE_ALLOCATION_INFO& o) : + D3D12_RESOURCE_ALLOCATION_INFO(o) + {} + CD3DX12_RESOURCE_ALLOCATION_INFO( + UINT64 size, + UINT64 alignment) + { + SizeInBytes = size; + Alignment = alignment; + } + operator const D3D12_RESOURCE_ALLOCATION_INFO&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_HEAP_PROPERTIES : public D3D12_HEAP_PROPERTIES +{ + CD3DX12_HEAP_PROPERTIES() + {} + explicit CD3DX12_HEAP_PROPERTIES(const D3D12_HEAP_PROPERTIES &o) : + D3D12_HEAP_PROPERTIES(o) + {} + CD3DX12_HEAP_PROPERTIES( + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + UINT creationNodeMask = 1, + UINT nodeMask = 1) + { + Type = D3D12_HEAP_TYPE_CUSTOM; + CPUPageProperty = cpuPageProperty; + MemoryPoolPreference = memoryPoolPreference; + CreationNodeMask = creationNodeMask; + VisibleNodeMask = nodeMask; + } + explicit CD3DX12_HEAP_PROPERTIES( + D3D12_HEAP_TYPE type, + UINT creationNodeMask = 1, + UINT nodeMask = 1) + { + Type = type; + CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + CreationNodeMask = creationNodeMask; + VisibleNodeMask = nodeMask; + } + operator const D3D12_HEAP_PROPERTIES&() const { return *this; } + bool IsCPUAccessible() const + { + return Type == D3D12_HEAP_TYPE_UPLOAD || Type == D3D12_HEAP_TYPE_READBACK || (Type == D3D12_HEAP_TYPE_CUSTOM && + (CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE || CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_BACK)); + } +}; +inline bool operator==(const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r) +{ + return l.Type == r.Type && l.CPUPageProperty == r.CPUPageProperty && + l.MemoryPoolPreference == r.MemoryPoolPreference && + l.CreationNodeMask == r.CreationNodeMask && + l.VisibleNodeMask == r.VisibleNodeMask; +} +inline bool operator!=(const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r) +{ + return !(l == r); +} + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_HEAP_DESC : public D3D12_HEAP_DESC +{ + CD3DX12_HEAP_DESC() + {} + explicit CD3DX12_HEAP_DESC(const D3D12_HEAP_DESC &o) : + D3D12_HEAP_DESC(o) + {} + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_HEAP_PROPERTIES properties, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE) + { + SizeInBytes = size; + Properties = properties; + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_HEAP_TYPE type, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE) + { + SizeInBytes = size; + Properties = CD3DX12_HEAP_PROPERTIES(type); + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE) + { + SizeInBytes = size; + Properties = CD3DX12_HEAP_PROPERTIES(cpuPageProperty, memoryPoolPreference); + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_HEAP_PROPERTIES properties, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE) + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = properties; + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_HEAP_TYPE type, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE) + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = CD3DX12_HEAP_PROPERTIES(type); + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE) + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = CD3DX12_HEAP_PROPERTIES(cpuPageProperty, memoryPoolPreference); + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + operator const D3D12_HEAP_DESC&() const { return *this; } + bool IsCPUAccessible() const + { + return static_cast< const CD3DX12_HEAP_PROPERTIES* >(&Properties)->IsCPUAccessible(); + } +}; +inline bool operator==(const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r) +{ + return l.SizeInBytes == r.SizeInBytes && + l.Properties == r.Properties && + l.Alignment == r.Alignment && + l.Flags == r.Flags; +} +inline bool operator!=(const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r) +{ + return !(l == r); +} + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_CLEAR_VALUE : public D3D12_CLEAR_VALUE +{ + CD3DX12_CLEAR_VALUE() + {} + explicit CD3DX12_CLEAR_VALUE(const D3D12_CLEAR_VALUE &o) : + D3D12_CLEAR_VALUE(o) + {} + CD3DX12_CLEAR_VALUE( + DXGI_FORMAT format, + const FLOAT color[4]) + { + Format = format; + memcpy(Color, color, sizeof(Color)); + } + CD3DX12_CLEAR_VALUE( + DXGI_FORMAT format, + FLOAT depth, + UINT8 stencil) + { + Format = format; + /* Use memcpy to preserve NAN values */ + memcpy(&DepthStencil.Depth, &depth, sizeof(depth)); + DepthStencil.Stencil = stencil; + } + operator const D3D12_CLEAR_VALUE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RANGE : public D3D12_RANGE +{ + CD3DX12_RANGE() + {} + explicit CD3DX12_RANGE(const D3D12_RANGE &o) : + D3D12_RANGE(o) + {} + CD3DX12_RANGE( + SIZE_T begin, + SIZE_T end) + { + Begin = begin; + End = end; + } + operator const D3D12_RANGE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILED_RESOURCE_COORDINATE : public D3D12_TILED_RESOURCE_COORDINATE +{ + CD3DX12_TILED_RESOURCE_COORDINATE() + {} + explicit CD3DX12_TILED_RESOURCE_COORDINATE(const D3D12_TILED_RESOURCE_COORDINATE &o) : + D3D12_TILED_RESOURCE_COORDINATE(o) + {} + CD3DX12_TILED_RESOURCE_COORDINATE( + UINT x, + UINT y, + UINT z, + UINT subresource) + { + X = x; + Y = y; + Z = z; + Subresource = subresource; + } + operator const D3D12_TILED_RESOURCE_COORDINATE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILE_REGION_SIZE : public D3D12_TILE_REGION_SIZE +{ + CD3DX12_TILE_REGION_SIZE() + {} + explicit CD3DX12_TILE_REGION_SIZE(const D3D12_TILE_REGION_SIZE &o) : + D3D12_TILE_REGION_SIZE(o) + {} + CD3DX12_TILE_REGION_SIZE( + UINT numTiles, + BOOL useBox, + UINT width, + UINT16 height, + UINT16 depth) + { + NumTiles = numTiles; + UseBox = useBox; + Width = width; + Height = height; + Depth = depth; + } + operator const D3D12_TILE_REGION_SIZE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_SUBRESOURCE_TILING : public D3D12_SUBRESOURCE_TILING +{ + CD3DX12_SUBRESOURCE_TILING() + {} + explicit CD3DX12_SUBRESOURCE_TILING(const D3D12_SUBRESOURCE_TILING &o) : + D3D12_SUBRESOURCE_TILING(o) + {} + CD3DX12_SUBRESOURCE_TILING( + UINT widthInTiles, + UINT16 heightInTiles, + UINT16 depthInTiles, + UINT startTileIndexInOverallResource) + { + WidthInTiles = widthInTiles; + HeightInTiles = heightInTiles; + DepthInTiles = depthInTiles; + StartTileIndexInOverallResource = startTileIndexInOverallResource; + } + operator const D3D12_SUBRESOURCE_TILING&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILE_SHAPE : public D3D12_TILE_SHAPE +{ + CD3DX12_TILE_SHAPE() + {} + explicit CD3DX12_TILE_SHAPE(const D3D12_TILE_SHAPE &o) : + D3D12_TILE_SHAPE(o) + {} + CD3DX12_TILE_SHAPE( + UINT widthInTexels, + UINT heightInTexels, + UINT depthInTexels) + { + WidthInTexels = widthInTexels; + HeightInTexels = heightInTexels; + DepthInTexels = depthInTexels; + } + operator const D3D12_TILE_SHAPE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_BARRIER : public D3D12_RESOURCE_BARRIER +{ + CD3DX12_RESOURCE_BARRIER() + {} + explicit CD3DX12_RESOURCE_BARRIER(const D3D12_RESOURCE_BARRIER &o) : + D3D12_RESOURCE_BARRIER(o) + {} + static inline CD3DX12_RESOURCE_BARRIER Transition( + _In_ ID3D12Resource* pResource, + D3D12_RESOURCE_STATES stateBefore, + D3D12_RESOURCE_STATES stateAfter, + UINT subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, + D3D12_RESOURCE_BARRIER_FLAGS flags = D3D12_RESOURCE_BARRIER_FLAG_NONE) + { + CD3DX12_RESOURCE_BARRIER result; + ZeroMemory(&result, sizeof(result)); + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + result.Flags = flags; + barrier.Transition.pResource = pResource; + barrier.Transition.StateBefore = stateBefore; + barrier.Transition.StateAfter = stateAfter; + barrier.Transition.Subresource = subresource; + return result; + } + static inline CD3DX12_RESOURCE_BARRIER Aliasing( + _In_ ID3D12Resource* pResourceBefore, + _In_ ID3D12Resource* pResourceAfter) + { + CD3DX12_RESOURCE_BARRIER result; + ZeroMemory(&result, sizeof(result)); + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING; + barrier.Aliasing.pResourceBefore = pResourceBefore; + barrier.Aliasing.pResourceAfter = pResourceAfter; + return result; + } + static inline CD3DX12_RESOURCE_BARRIER UAV( + _In_ ID3D12Resource* pResource) + { + CD3DX12_RESOURCE_BARRIER result; + ZeroMemory(&result, sizeof(result)); + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; + barrier.UAV.pResource = pResource; + return result; + } + operator const D3D12_RESOURCE_BARRIER&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_PACKED_MIP_INFO : public D3D12_PACKED_MIP_INFO +{ + CD3DX12_PACKED_MIP_INFO() + {} + explicit CD3DX12_PACKED_MIP_INFO(const D3D12_PACKED_MIP_INFO &o) : + D3D12_PACKED_MIP_INFO(o) + {} + CD3DX12_PACKED_MIP_INFO( + UINT8 numStandardMips, + UINT8 numPackedMips, + UINT numTilesForPackedMips, + UINT startTileIndexInOverallResource) + { + NumStandardMips = numStandardMips; + NumPackedMips = numPackedMips; + NumTilesForPackedMips = numTilesForPackedMips; + StartTileIndexInOverallResource = startTileIndexInOverallResource; + } + operator const D3D12_PACKED_MIP_INFO&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_SUBRESOURCE_FOOTPRINT : public D3D12_SUBRESOURCE_FOOTPRINT +{ + CD3DX12_SUBRESOURCE_FOOTPRINT() + {} + explicit CD3DX12_SUBRESOURCE_FOOTPRINT(const D3D12_SUBRESOURCE_FOOTPRINT &o) : + D3D12_SUBRESOURCE_FOOTPRINT(o) + {} + CD3DX12_SUBRESOURCE_FOOTPRINT( + DXGI_FORMAT format, + UINT width, + UINT height, + UINT depth, + UINT rowPitch) + { + Format = format; + Width = width; + Height = height; + Depth = depth; + RowPitch = rowPitch; + } + explicit CD3DX12_SUBRESOURCE_FOOTPRINT( + const D3D12_RESOURCE_DESC& resDesc, + UINT rowPitch) + { + Format = resDesc.Format; + Width = UINT(resDesc.Width); + Height = resDesc.Height; + Depth = (resDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? resDesc.DepthOrArraySize : 1); + RowPitch = rowPitch; + } + operator const D3D12_SUBRESOURCE_FOOTPRINT&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TEXTURE_COPY_LOCATION : public D3D12_TEXTURE_COPY_LOCATION +{ + CD3DX12_TEXTURE_COPY_LOCATION() + {} + explicit CD3DX12_TEXTURE_COPY_LOCATION(const D3D12_TEXTURE_COPY_LOCATION &o) : + D3D12_TEXTURE_COPY_LOCATION(o) + {} + CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes) { pResource = pRes; } + CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes, D3D12_PLACED_SUBRESOURCE_FOOTPRINT const& Footprint) + { + pResource = pRes; + Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + PlacedFootprint = Footprint; + } + CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes, UINT Sub) + { + pResource = pRes; + Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + SubresourceIndex = Sub; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_DESCRIPTOR_RANGE : public D3D12_DESCRIPTOR_RANGE +{ + CD3DX12_DESCRIPTOR_RANGE() { } + explicit CD3DX12_DESCRIPTOR_RANGE(const D3D12_DESCRIPTOR_RANGE &o) : + D3D12_DESCRIPTOR_RANGE(o) + {} + CD3DX12_DESCRIPTOR_RANGE( + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + Init(rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart); + } + + inline void Init( + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + Init(*this, rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart); + } + + static inline void Init( + _Out_ D3D12_DESCRIPTOR_RANGE &range, + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + range.RangeType = rangeType; + range.NumDescriptors = numDescriptors; + range.BaseShaderRegister = baseShaderRegister; + range.RegisterSpace = registerSpace; + range.OffsetInDescriptorsFromTableStart = offsetInDescriptorsFromTableStart; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_DESCRIPTOR_TABLE : public D3D12_ROOT_DESCRIPTOR_TABLE +{ + CD3DX12_ROOT_DESCRIPTOR_TABLE() {} + explicit CD3DX12_ROOT_DESCRIPTOR_TABLE(const D3D12_ROOT_DESCRIPTOR_TABLE &o) : + D3D12_ROOT_DESCRIPTOR_TABLE(o) + {} + CD3DX12_ROOT_DESCRIPTOR_TABLE( + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) + { + Init(numDescriptorRanges, _pDescriptorRanges); + } + + inline void Init( + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) + { + Init(*this, numDescriptorRanges, _pDescriptorRanges); + } + + static inline void Init( + _Out_ D3D12_ROOT_DESCRIPTOR_TABLE &rootDescriptorTable, + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) + { + rootDescriptorTable.NumDescriptorRanges = numDescriptorRanges; + rootDescriptorTable.pDescriptorRanges = _pDescriptorRanges; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_CONSTANTS : public D3D12_ROOT_CONSTANTS +{ + CD3DX12_ROOT_CONSTANTS() {} + explicit CD3DX12_ROOT_CONSTANTS(const D3D12_ROOT_CONSTANTS &o) : + D3D12_ROOT_CONSTANTS(o) + {} + CD3DX12_ROOT_CONSTANTS( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(num32BitValues, shaderRegister, registerSpace); + } + + inline void Init( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(*this, num32BitValues, shaderRegister, registerSpace); + } + + static inline void Init( + _Out_ D3D12_ROOT_CONSTANTS &rootConstants, + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) + { + rootConstants.Num32BitValues = num32BitValues; + rootConstants.ShaderRegister = shaderRegister; + rootConstants.RegisterSpace = registerSpace; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_DESCRIPTOR : public D3D12_ROOT_DESCRIPTOR +{ + CD3DX12_ROOT_DESCRIPTOR() {} + explicit CD3DX12_ROOT_DESCRIPTOR(const D3D12_ROOT_DESCRIPTOR &o) : + D3D12_ROOT_DESCRIPTOR(o) + {} + CD3DX12_ROOT_DESCRIPTOR( + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(shaderRegister, registerSpace); + } + + inline void Init( + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(*this, shaderRegister, registerSpace); + } + + static inline void Init(_Out_ D3D12_ROOT_DESCRIPTOR &table, UINT shaderRegister, UINT registerSpace = 0) + { + table.ShaderRegister = shaderRegister; + table.RegisterSpace = registerSpace; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_PARAMETER : public D3D12_ROOT_PARAMETER +{ + CD3DX12_ROOT_PARAMETER() {} + explicit CD3DX12_ROOT_PARAMETER(const D3D12_ROOT_PARAMETER &o) : + D3D12_ROOT_PARAMETER(o) + {} + + static inline void InitAsDescriptorTable( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT numDescriptorRanges, + _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR_TABLE::Init(rootParam.DescriptorTable, numDescriptorRanges, pDescriptorRanges); + } + + static inline void InitAsConstants( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_CONSTANTS::Init(rootParam.Constants, num32BitValues, shaderRegister, registerSpace); + } + + static inline void InitAsConstantBufferView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + static inline void InitAsShaderResourceView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + static inline void InitAsUnorderedAccessView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + inline void InitAsDescriptorTable( + UINT numDescriptorRanges, + _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsDescriptorTable(*this, numDescriptorRanges, pDescriptorRanges, visibility); + } + + inline void InitAsConstants( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsConstants(*this, num32BitValues, shaderRegister, registerSpace, visibility); + } + + inline void InitAsConstantBufferView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsConstantBufferView(*this, shaderRegister, registerSpace, visibility); + } + + inline void InitAsShaderResourceView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsShaderResourceView(*this, shaderRegister, registerSpace, visibility); + } + + inline void InitAsUnorderedAccessView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsUnorderedAccessView(*this, shaderRegister, registerSpace, visibility); + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_STATIC_SAMPLER_DESC : public D3D12_STATIC_SAMPLER_DESC +{ + CD3DX12_STATIC_SAMPLER_DESC() {} + explicit CD3DX12_STATIC_SAMPLER_DESC(const D3D12_STATIC_SAMPLER_DESC &o) : + D3D12_STATIC_SAMPLER_DESC(o) + {} + CD3DX12_STATIC_SAMPLER_DESC( + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) + { + Init( + shaderRegister, + filter, + addressU, + addressV, + addressW, + mipLODBias, + maxAnisotropy, + comparisonFunc, + borderColor, + minLOD, + maxLOD, + shaderVisibility, + registerSpace); + } + + static inline void Init( + _Out_ D3D12_STATIC_SAMPLER_DESC &samplerDesc, + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) + { + samplerDesc.ShaderRegister = shaderRegister; + samplerDesc.Filter = filter; + samplerDesc.AddressU = addressU; + samplerDesc.AddressV = addressV; + samplerDesc.AddressW = addressW; + samplerDesc.MipLODBias = mipLODBias; + samplerDesc.MaxAnisotropy = maxAnisotropy; + samplerDesc.ComparisonFunc = comparisonFunc; + samplerDesc.BorderColor = borderColor; + samplerDesc.MinLOD = minLOD; + samplerDesc.MaxLOD = maxLOD; + samplerDesc.ShaderVisibility = shaderVisibility; + samplerDesc.RegisterSpace = registerSpace; + } + inline void Init( + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) + { + Init( + *this, + shaderRegister, + filter, + addressU, + addressV, + addressW, + mipLODBias, + maxAnisotropy, + comparisonFunc, + borderColor, + minLOD, + maxLOD, + shaderVisibility, + registerSpace); + } + +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_SIGNATURE_DESC : public D3D12_ROOT_SIGNATURE_DESC +{ + CD3DX12_ROOT_SIGNATURE_DESC() {} + explicit CD3DX12_ROOT_SIGNATURE_DESC(const D3D12_ROOT_SIGNATURE_DESC &o) : + D3D12_ROOT_SIGNATURE_DESC(o) + {} + CD3DX12_ROOT_SIGNATURE_DESC( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + Init(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + CD3DX12_ROOT_SIGNATURE_DESC(CD3DX12_DEFAULT) + { + Init(0, NULL, 0, NULL, D3D12_ROOT_SIGNATURE_FLAG_NONE); + } + + inline void Init( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + Init(*this, numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + + static inline void Init( + _Out_ D3D12_ROOT_SIGNATURE_DESC &desc, + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + desc.NumParameters = numParameters; + desc.pParameters = _pParameters; + desc.NumStaticSamplers = numStaticSamplers; + desc.pStaticSamplers = _pStaticSamplers; + desc.Flags = flags; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_CPU_DESCRIPTOR_HANDLE : public D3D12_CPU_DESCRIPTOR_HANDLE +{ + CD3DX12_CPU_DESCRIPTOR_HANDLE() {} + explicit CD3DX12_CPU_DESCRIPTOR_HANDLE(const D3D12_CPU_DESCRIPTOR_HANDLE &o) : + D3D12_CPU_DESCRIPTOR_HANDLE(o) + {} + CD3DX12_CPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; } + CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize) + { + InitOffsetted(other, offsetScaledByIncrementSize); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize) + { + ptr += offsetInDescriptors * descriptorIncrementSize; + return *this; + } + CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize) + { + ptr += offsetScaledByIncrementSize; + return *this; + } + bool operator==(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other) + { + return (ptr == other.ptr); + } + bool operator!=(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other) + { + return (ptr != other.ptr); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE &operator=(const D3D12_CPU_DESCRIPTOR_HANDLE &other) + { + ptr = other.ptr; + return *this; + } + + inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + InitOffsetted(*this, base, offsetScaledByIncrementSize); + } + + inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize); + } + + static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + handle.ptr = base.ptr + offsetScaledByIncrementSize; + } + + static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + handle.ptr = base.ptr + offsetInDescriptors * descriptorIncrementSize; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_GPU_DESCRIPTOR_HANDLE : public D3D12_GPU_DESCRIPTOR_HANDLE +{ + CD3DX12_GPU_DESCRIPTOR_HANDLE() {} + explicit CD3DX12_GPU_DESCRIPTOR_HANDLE(const D3D12_GPU_DESCRIPTOR_HANDLE &o) : + D3D12_GPU_DESCRIPTOR_HANDLE(o) + {} + CD3DX12_GPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; } + CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize) + { + InitOffsetted(other, offsetScaledByIncrementSize); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize) + { + ptr += offsetInDescriptors * descriptorIncrementSize; + return *this; + } + CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize) + { + ptr += offsetScaledByIncrementSize; + return *this; + } + inline bool operator==(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other) + { + return (ptr == other.ptr); + } + inline bool operator!=(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other) + { + return (ptr != other.ptr); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE &operator=(const D3D12_GPU_DESCRIPTOR_HANDLE &other) + { + ptr = other.ptr; + return *this; + } + + inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + InitOffsetted(*this, base, offsetScaledByIncrementSize); + } + + inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize); + } + + static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + handle.ptr = base.ptr + offsetScaledByIncrementSize; + } + + static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + handle.ptr = base.ptr + offsetInDescriptors * descriptorIncrementSize; + } +}; + +//------------------------------------------------------------------------------------------------ +inline UINT D3D12CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT PlaneSlice, UINT MipLevels, UINT ArraySize) +{ + return MipSlice + ArraySlice * MipLevels + PlaneSlice * MipLevels * ArraySize; +} + +//------------------------------------------------------------------------------------------------ +template +inline void D3D12DecomposeSubresource(UINT Subresource, UINT MipLevels, UINT ArraySize, _Out_ T& MipSlice, _Out_ U& ArraySlice, _Out_ V& PlaneSlice) +{ + MipSlice = static_cast(Subresource % MipLevels); + ArraySlice = static_cast((Subresource / MipLevels) % ArraySize); + PlaneSlice = static_cast(Subresource / (MipLevels * ArraySize)); +} + +//------------------------------------------------------------------------------------------------ +inline UINT8 D3D12GetFormatPlaneCount( + _In_ ID3D12Device* pDevice, + DXGI_FORMAT Format + ) +{ + D3D12_FEATURE_DATA_FORMAT_INFO formatInfo = { Format }; + if (FAILED(pDevice->CheckFeatureSupport(D3D12_FEATURE_FORMAT_INFO, &formatInfo, sizeof(formatInfo)))) + { + return 0; + } + return formatInfo.PlaneCount; +} + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_DESC : public D3D12_RESOURCE_DESC +{ + CD3DX12_RESOURCE_DESC() + {} + explicit CD3DX12_RESOURCE_DESC(const D3D12_RESOURCE_DESC& o) : + D3D12_RESOURCE_DESC(o) + {} + CD3DX12_RESOURCE_DESC( + D3D12_RESOURCE_DIMENSION dimension, + UINT64 alignment, + UINT64 width, + UINT height, + UINT16 depthOrArraySize, + UINT16 mipLevels, + DXGI_FORMAT format, + UINT sampleCount, + UINT sampleQuality, + D3D12_TEXTURE_LAYOUT layout, + D3D12_RESOURCE_FLAGS flags) + { + Dimension = dimension; + Alignment = alignment; + Width = width; + Height = height; + DepthOrArraySize = depthOrArraySize; + MipLevels = mipLevels; + Format = format; + SampleDesc.Count = sampleCount; + SampleDesc.Quality = sampleQuality; + Layout = layout; + Flags = flags; + } + static inline CD3DX12_RESOURCE_DESC Buffer( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE) + { + return CD3DX12_RESOURCE_DESC(D3D12_RESOURCE_DIMENSION_BUFFER, resAllocInfo.Alignment, resAllocInfo.SizeInBytes, + 1, 1, 1, DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags); + } + static inline CD3DX12_RESOURCE_DESC Buffer( + UINT64 width, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + UINT64 alignment = 0) + { + return CD3DX12_RESOURCE_DESC(D3D12_RESOURCE_DIMENSION_BUFFER, alignment, width, 1, 1, 1, + DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags); + } + static inline CD3DX12_RESOURCE_DESC Tex1D( + DXGI_FORMAT format, + UINT64 width, + UINT16 arraySize = 1, + UINT16 mipLevels = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0) + { + return CD3DX12_RESOURCE_DESC(D3D12_RESOURCE_DIMENSION_TEXTURE1D, alignment, width, 1, arraySize, + mipLevels, format, 1, 0, layout, flags); + } + static inline CD3DX12_RESOURCE_DESC Tex2D( + DXGI_FORMAT format, + UINT64 width, + UINT height, + UINT16 arraySize = 1, + UINT16 mipLevels = 0, + UINT sampleCount = 1, + UINT sampleQuality = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0) + { + return CD3DX12_RESOURCE_DESC(D3D12_RESOURCE_DIMENSION_TEXTURE2D, alignment, width, height, arraySize, + mipLevels, format, sampleCount, sampleQuality, layout, flags); + } + static inline CD3DX12_RESOURCE_DESC Tex3D( + DXGI_FORMAT format, + UINT64 width, + UINT height, + UINT16 depth, + UINT16 mipLevels = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0) + { + return CD3DX12_RESOURCE_DESC(D3D12_RESOURCE_DIMENSION_TEXTURE3D, alignment, width, height, depth, + mipLevels, format, 1, 0, layout, flags); + } + inline UINT16 Depth() const + { + return (Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); + } + inline UINT16 ArraySize() const + { + return (Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); + } + inline UINT8 PlaneCount(_In_ ID3D12Device* pDevice) const + { + return D3D12GetFormatPlaneCount(pDevice, Format); + } + inline UINT Subresources(_In_ ID3D12Device* pDevice) const + { + return MipLevels * ArraySize() * PlaneCount(pDevice); + } + inline UINT CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT PlaneSlice) + { + return D3D12CalcSubresource(MipSlice, ArraySlice, PlaneSlice, MipLevels, ArraySize()); + } + operator const D3D12_RESOURCE_DESC&() const { return *this; } +}; +inline bool operator==(const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r) +{ + return l.Dimension == r.Dimension && + l.Alignment == r.Alignment && + l.Width == r.Width && + l.Height == r.Height && + l.DepthOrArraySize == r.DepthOrArraySize && + l.MipLevels == r.MipLevels && + l.Format == r.Format && + l.SampleDesc.Count == r.SampleDesc.Count && + l.SampleDesc.Quality == r.SampleDesc.Quality && + l.Layout == r.Layout && + l.Flags == r.Flags; +} +inline bool operator!=(const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r) +{ + return !(l == r); +} + +//------------------------------------------------------------------------------------------------ +// Row-by-row memcpy +inline void MemcpySubresource( + _In_ const D3D12_MEMCPY_DEST* pDest, + _In_ const D3D12_SUBRESOURCE_DATA* pSrc, + SIZE_T RowSizeInBytes, + UINT NumRows, + UINT NumSlices) +{ + for (UINT z = 0; z < NumSlices; ++z) + { + BYTE* pDestSlice = reinterpret_cast(pDest->pData) + pDest->SlicePitch * z; + const BYTE* pSrcSlice = reinterpret_cast(pSrc->pData) + pSrc->SlicePitch * z; + for (UINT y = 0; y < NumRows; ++y) + { + memcpy(pDestSlice + pDest->RowPitch * y, + pSrcSlice + pSrc->RowPitch * y, + RowSizeInBytes); + } + } +} + +//------------------------------------------------------------------------------------------------ +// Returns required size of a buffer to be used for data upload +inline UINT64 GetRequiredIntermediateSize( + _In_ ID3D12Resource* pDestinationResource, + _In_range_(0, D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0, D3D12_REQ_SUBRESOURCES - FirstSubresource) UINT NumSubresources) +{ + D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc(); + UINT64 RequiredSize = 0; + + ID3D12Device* pDevice; + pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, 0, nullptr, nullptr, nullptr, &RequiredSize); + pDevice->Release(); + + return RequiredSize; +} + +//------------------------------------------------------------------------------------------------ +// All arrays must be populated (e.g. by calling GetCopyableFootprints) +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + _In_range_(0, D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0, D3D12_REQ_SUBRESOURCES - FirstSubresource) UINT NumSubresources, + UINT64 RequiredSize, + _In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts, + _In_reads_(NumSubresources) const UINT* pNumRows, + _In_reads_(NumSubresources) const UINT64* pRowSizesInBytes, + _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) +{ + // Minor validation + D3D12_RESOURCE_DESC IntermediateDesc = pIntermediate->GetDesc(); + D3D12_RESOURCE_DESC DestinationDesc = pDestinationResource->GetDesc(); + if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER || + IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset || + RequiredSize >(SIZE_T) - 1 || + (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER && + (FirstSubresource != 0 || NumSubresources != 1))) + { + return 0; + } + + BYTE* pData; + HRESULT hr = pIntermediate->Map(0, NULL, reinterpret_cast(&pData)); + if (FAILED(hr)) + { + return 0; + } + + for (UINT i = 0; i < NumSubresources; ++i) + { + if (pRowSizesInBytes[i] >(SIZE_T)-1) return 0; + D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, pLayouts[i].Footprint.RowPitch * pNumRows[i] }; + MemcpySubresource(&DestData, &pSrcData[i], (SIZE_T)pRowSizesInBytes[i], pNumRows[i], pLayouts[i].Footprint.Depth); + } + pIntermediate->Unmap(0, NULL); + + if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + { + CD3DX12_BOX SrcBox(UINT(pLayouts[0].Offset), UINT(pLayouts[0].Offset + pLayouts[0].Footprint.Width)); + pCmdList->CopyBufferRegion( + pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width); + } + else + { + for (UINT i = 0; i < NumSubresources; ++i) + { + CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource); + CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]); + pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr); + } + } + return RequiredSize; +} + +//------------------------------------------------------------------------------------------------ +// Heap-allocating UpdateSubresources implementation +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + UINT64 IntermediateOffset, + _In_range_(0, D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0, D3D12_REQ_SUBRESOURCES - FirstSubresource) UINT NumSubresources, + _In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData) +{ + UINT64 RequiredSize = 0; + UINT64 MemToAlloc = static_cast(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources; + if (MemToAlloc > SIZE_MAX) + { + return 0; + } + void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast(MemToAlloc)); + if (pMem == NULL) + { + return 0; + } + D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts = reinterpret_cast(pMem); + UINT64* pRowSizesInBytes = reinterpret_cast(pLayouts + NumSubresources); + UINT* pNumRows = reinterpret_cast(pRowSizesInBytes + NumSubresources); + + D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc(); + ID3D12Device* pDevice; + pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize); + pDevice->Release(); + + UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData); + HeapFree(GetProcessHeap(), 0, pMem); + return Result; +} + +//------------------------------------------------------------------------------------------------ +// Stack-allocating UpdateSubresources implementation +template +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + UINT64 IntermediateOffset, + _In_range_(0, MaxSubresources) UINT FirstSubresource, + _In_range_(1, MaxSubresources - FirstSubresource) UINT NumSubresources, + _In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData) +{ + UINT64 RequiredSize = 0; + D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts[MaxSubresources]; + UINT NumRows[MaxSubresources]; + UINT64 RowSizesInBytes[MaxSubresources]; + + D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc(); + ID3D12Device* pDevice; + pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize); + pDevice->Release(); + + return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData); +} + +//------------------------------------------------------------------------------------------------ +inline bool D3D12IsLayoutOpaque(D3D12_TEXTURE_LAYOUT Layout) +{ + return Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN || Layout == D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE; +} + +//------------------------------------------------------------------------------------------------ +inline ID3D12CommandList * const * CommandListCast(ID3D12GraphicsCommandList * const * pp) +{ + // This cast is useful for passing strongly typed command list pointers into + // ExecuteCommandLists. + // This cast is valid as long as the const-ness is respected. D3D12 APIs do + // respect the const-ness of their arguments. + return reinterpret_cast(pp); +} + + +#endif // defined( __cplusplus ) + +#endif //__D3DX12_H__ + + diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index f1b32f9671..7b0d7d7616 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -542,6 +542,7 @@ + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 57b993383c..bc79cb2297 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -1879,5 +1879,8 @@ Utilities + + Emu\GPU\RSX\D3D12 + \ No newline at end of file