diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index cfc470e9e1..588be48702 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -19,25 +19,46 @@ PFN_D3D12_GET_DEBUG_INTERFACE wrapD3D12GetDebugInterface; PFN_D3D12_SERIALIZE_ROOT_SIGNATURE wrapD3D12SerializeRootSignature; PFN_D3D11ON12_CREATE_DEVICE wrapD3D11On12CreateDevice; -static HMODULE D3D12Module; -static HMODULE D3D11Module; +namespace +{ +HMODULE D3D12Module; +HMODULE D3D11Module; -static void loadD3D12FunctionPointers() +void loadD3D12FunctionPointers() { D3D12Module = LoadLibrary(L"d3d12.dll"); + if (!D3D12Module) + unreachable("Failed to load d3d12.dll"); wrapD3D12CreateDevice = (PFN_D3D12_CREATE_DEVICE)GetProcAddress(D3D12Module, "D3D12CreateDevice"); wrapD3D12GetDebugInterface = (PFN_D3D12_GET_DEBUG_INTERFACE)GetProcAddress(D3D12Module, "D3D12GetDebugInterface"); wrapD3D12SerializeRootSignature = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)GetProcAddress(D3D12Module, "D3D12SerializeRootSignature"); D3D11Module = LoadLibrary(L"d3d11.dll"); + if (!D3D11Module) + unreachable("Failed to load d3d11.dll"); wrapD3D11On12CreateDevice = (PFN_D3D11ON12_CREATE_DEVICE)GetProcAddress(D3D11Module, "D3D11On12CreateDevice"); } -static void unloadD3D12FunctionPointers() +void unloadD3D12FunctionPointers() { FreeLibrary(D3D12Module); FreeLibrary(D3D11Module); } +/** + * Wait until command queue has completed all task. + */ +void wait_for_command_queue(ID3D12Device *device, ID3D12CommandQueue *command_queue) +{ + 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); + command_queue->Signal(fence.Get(), 1); + WaitForSingleObjectEx(handle, INFINITE, FALSE); + CloseHandle(handle); +} +} + void D3D12GSRender::ResourceStorage::Reset() { m_descriptorsHeapIndex = 0; @@ -66,12 +87,12 @@ 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 = { D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 10000, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE }; - ThrowIfFailed(device->CreateDescriptorHeap(&descriptorHeapDesc, IID_PPV_ARGS(&m_descriptorsHeap))); + D3D12_DESCRIPTOR_HEAP_DESC descriptor_heap_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 10000, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE }; + ThrowIfFailed(device->CreateDescriptorHeap(&descriptor_heap_desc, IID_PPV_ARGS(&m_descriptorsHeap))); - 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]))); + D3D12_DESCRIPTOR_HEAP_DESC sampler_heap_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER , 2048, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE }; + ThrowIfFailed(device->CreateDescriptorHeap(&sampler_heap_desc, IID_PPV_ARGS(&m_samplerDescriptorHeap[0]))); + ThrowIfFailed(device->CreateDescriptorHeap(&sampler_heap_desc, IID_PPV_ARGS(&m_samplerDescriptorHeap[1]))); m_frameFinishedHandle = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS); m_fenceValue = 0; @@ -149,18 +170,16 @@ D3D12GSRender::D3D12GSRender() debugInterface->EnableDebugLayer(); } - Microsoft::WRL::ComPtr dxgiFactory; - ThrowIfFailed(CreateDXGIFactory(IID_PPV_ARGS(&dxgiFactory))); + Microsoft::WRL::ComPtr dxgi_factory; + ThrowIfFailed(CreateDXGIFactory(IID_PPV_ARGS(&dxgi_factory))); // Create adapter ComPtr adaptater = nullptr; - ThrowIfFailed(dxgiFactory->EnumAdapters(rpcs3::state.config.rsx.d3d12.adaptater.value(), adaptater.GetAddressOf())); + ThrowIfFailed(dxgi_factory->EnumAdapters(rpcs3::state.config.rsx.d3d12.adaptater.value(), adaptater.GetAddressOf())); ThrowIfFailed(wrapD3D12CreateDevice(adaptater.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device))); // Queues - D3D12_COMMAND_QUEUE_DESC copyQueueDesc = {}, graphicQueueDesc = {}; - copyQueueDesc.Type = D3D12_COMMAND_LIST_TYPE_COPY; - graphicQueueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; - ThrowIfFailed(m_device->CreateCommandQueue(&graphicQueueDesc, IID_PPV_ARGS(m_commandQueueGraphic.GetAddressOf()))); + D3D12_COMMAND_QUEUE_DESC graphic_queue_desc = { D3D12_COMMAND_LIST_TYPE_DIRECT }; + ThrowIfFailed(m_device->CreateCommandQueue(&graphic_queue_desc, IID_PPV_ARGS(m_commandQueueGraphic.GetAddressOf()))); g_descriptorStrideSRVCBVUAV = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); g_descriptorStrideDSV = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV); @@ -168,31 +187,31 @@ D3D12GSRender::D3D12GSRender() g_descriptorStrideSamplers = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); // Create swap chain and put them in a descriptor heap as rendertarget - DXGI_SWAP_CHAIN_DESC swapChain = {}; - swapChain.BufferCount = 2; - swapChain.Windowed = true; - swapChain.OutputWindow = (HWND)m_frame->handle(); - swapChain.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - swapChain.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapChain.SampleDesc.Count = 1; - swapChain.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; - swapChain.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + DXGI_SWAP_CHAIN_DESC swap_chain = {}; + swap_chain.BufferCount = 2; + swap_chain.Windowed = true; + swap_chain.OutputWindow = (HWND)m_frame->handle(); + swap_chain.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + swap_chain.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swap_chain.SampleDesc.Count = 1; + swap_chain.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + swap_chain.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; - ThrowIfFailed(dxgiFactory->CreateSwapChain(m_commandQueueGraphic.Get(), &swapChain, (IDXGISwapChain**)m_swapChain.GetAddressOf())); + ThrowIfFailed(dxgi_factory->CreateSwapChain(m_commandQueueGraphic.Get(), &swap_chain, (IDXGISwapChain**)m_swapChain.GetAddressOf())); 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 = { D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1}; - D3D12_RENDER_TARGET_VIEW_DESC rttDesc = {}; - rttDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; - rttDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - m_device->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&m_backbufferAsRendertarget[0])); - m_device->CreateRenderTargetView(m_backBuffer[0].Get(), &rttDesc, m_backbufferAsRendertarget[0]->GetCPUDescriptorHandleForHeapStart()); - m_device->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&m_backbufferAsRendertarget[1])); - m_device->CreateRenderTargetView(m_backBuffer[1].Get(), &rttDesc, m_backbufferAsRendertarget[1]->GetCPUDescriptorHandleForHeapStart()); + D3D12_DESCRIPTOR_HEAP_DESC render_target_descriptor_heap_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1}; + D3D12_RENDER_TARGET_VIEW_DESC renter_target_view_desc = {}; + renter_target_view_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + renter_target_view_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + m_device->CreateDescriptorHeap(&render_target_descriptor_heap_desc, IID_PPV_ARGS(&m_backbufferAsRendertarget[0])); + m_device->CreateRenderTargetView(m_backBuffer[0].Get(), &renter_target_view_desc, m_backbufferAsRendertarget[0]->GetCPUDescriptorHandleForHeapStart()); + m_device->CreateDescriptorHeap(&render_target_descriptor_heap_desc, IID_PPV_ARGS(&m_backbufferAsRendertarget[1])); + m_device->CreateRenderTargetView(m_backBuffer[1].Get(), &renter_target_view_desc, m_backbufferAsRendertarget[1]->GetCPUDescriptorHandleForHeapStart()); // Common root signatures - for (unsigned textureCount = 0; textureCount < 17; textureCount++) + for (unsigned texture_count = 0; texture_count < 17; texture_count++) { CD3DX12_DESCRIPTOR_RANGE descriptorRange[] = { @@ -201,24 +220,24 @@ D3D12GSRender::D3D12GSRender() // Constants CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 2, 1), // Textures - CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, textureCount, 0), + CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, texture_count, 0), // Samplers - CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, textureCount, 0), + CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, texture_count, 0), }; CD3DX12_ROOT_PARAMETER RP[2]; - RP[0].InitAsDescriptorTable((textureCount > 0) ? 3 : 2, &descriptorRange[0]); + RP[0].InitAsDescriptorTable((texture_count > 0) ? 3 : 2, &descriptorRange[0]); RP[1].InitAsDescriptorTable(1, &descriptorRange[3]); Microsoft::WRL::ComPtr rootSignatureBlob; Microsoft::WRL::ComPtr errorBlob; ThrowIfFailed(wrapD3D12SerializeRootSignature( - &CD3DX12_ROOT_SIGNATURE_DESC((textureCount > 0) ? 2 : 1, RP, 0, 0, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), + &CD3DX12_ROOT_SIGNATURE_DESC((texture_count > 0) ? 2 : 1, RP, 0, 0, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), D3D_ROOT_SIGNATURE_VERSION_1, &rootSignatureBlob, &errorBlob)); m_device->CreateRootSignature(0, rootSignatureBlob->GetBufferPointer(), rootSignatureBlob->GetBufferSize(), - IID_PPV_ARGS(m_rootSignatures[textureCount].GetAddressOf())); + IID_PPV_ARGS(m_rootSignatures[texture_count].GetAddressOf())); } m_perFrameStorage[0].Init(m_device.Get()); @@ -254,15 +273,7 @@ D3D12GSRender::D3D12GSRender() D3D12GSRender::~D3D12GSRender() { - // 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); + wait_for_command_queue(m_device.Get(), m_commandQueueGraphic.Get()); { m_textureCache.unprotedAll(); @@ -309,15 +320,66 @@ bool D3D12GSRender::domethod(u32 cmd, u32 arg) } } +namespace +{ + UINT get_num_rtt(u8 color_target) noexcept + { + switch (color_target) + { + case CELL_GCM_SURFACE_TARGET_NONE: return 0; + case CELL_GCM_SURFACE_TARGET_0: + case CELL_GCM_SURFACE_TARGET_1: return 1; + case CELL_GCM_SURFACE_TARGET_MRT1: return 2; + case CELL_GCM_SURFACE_TARGET_MRT2: return 3; + case CELL_GCM_SURFACE_TARGET_MRT3: return 4; + } + unreachable("Wrong color target"); + } + + std::vector get_rtt_indexes(u8 color_target) noexcept + { + switch (color_target) + { + case CELL_GCM_SURFACE_TARGET_NONE: return{}; + case CELL_GCM_SURFACE_TARGET_0: return{ 0 }; + case CELL_GCM_SURFACE_TARGET_1: return{ 1 }; + case CELL_GCM_SURFACE_TARGET_MRT1: return{ 0, 1 }; + case CELL_GCM_SURFACE_TARGET_MRT2: return{ 0, 1, 2 }; + case CELL_GCM_SURFACE_TARGET_MRT3: return{ 0, 1, 2, 3 }; + } + unreachable("Wrong color target"); + } + + std::array get_clear_color(u32 clear_color) noexcept + { + u8 clear_a = clear_color >> 24; + u8 clear_r = clear_color >> 16; + u8 clear_g = clear_color >> 8; + u8 clear_b = clear_color; + return + { + clear_r / 255.0f, + clear_g / 255.0f, + clear_b / 255.0f, + clear_a / 255.0f + }; + } + + u8 get_clear_stencil(u32 register_value) noexcept + { + return register_value & 0xff; + } +} + void D3D12GSRender::clear_surface(u32 arg) { - std::chrono::time_point startDuration = std::chrono::system_clock::now(); + std::chrono::time_point start_duration = std::chrono::system_clock::now(); - std::chrono::time_point rttDurationStart = std::chrono::system_clock::now(); + std::chrono::time_point rtt_duration_start = 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 rtt_duration_end = std::chrono::system_clock::now(); + m_timers.m_rttDuration += std::chrono::duration_cast(rtt_duration_end - rtt_duration_start).count(); /* if (m_set_color_mask) { @@ -340,57 +402,18 @@ void D3D12GSRender::clear_surface(u32 arg) } if (arg & 0x2) - { - u8 clear_stencil = rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] & 0xff; - getCurrentResourceStorage().m_commandList->ClearDepthStencilView(m_rtts.m_depthStencilDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), D3D12_CLEAR_FLAG_STENCIL, 0.f, clear_stencil, 0, nullptr); - } + getCurrentResourceStorage().m_commandList->ClearDepthStencilView(m_rtts.m_depthStencilDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), D3D12_CLEAR_FLAG_STENCIL, 0.f, + get_clear_stencil(rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE]), 0, nullptr); if (arg & 0xF0) { - u32 clear_color = rsx::method_registers[NV4097_SET_COLOR_CLEAR_VALUE]; - u8 clear_a = clear_color >> 24; - u8 clear_r = clear_color >> 16; - u8 clear_g = clear_color >> 8; - u8 clear_b = clear_color; - float clearColor[] = - { - clear_r / 255.0f, - clear_g / 255.0f, - clear_b / 255.0f, - clear_a / 255.0f - }; - - size_t g_RTTIncrement = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); - switch (u32 color_target = rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]) - { - case CELL_GCM_SURFACE_TARGET_NONE: break; - - case CELL_GCM_SURFACE_TARGET_0: - case CELL_GCM_SURFACE_TARGET_1: - 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(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(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(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", color_target); - } + for (u8 i : get_rtt_indexes(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) + getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()).Offset(i, g_descriptorStrideRTV), + get_clear_color(rsx::method_registers[NV4097_SET_COLOR_CLEAR_VALUE]).data(), 0, nullptr); } - std::chrono::time_point endDuration = std::chrono::system_clock::now(); - m_timers.m_drawCallDuration += std::chrono::duration_cast(endDuration - startDuration).count(); + std::chrono::time_point end_duration = std::chrono::system_clock::now(); + m_timers.m_drawCallDuration += std::chrono::duration_cast(end_duration - start_duration).count(); m_timers.m_drawCallCount++; if (rpcs3::config.rsx.d3d12.debug_output.value()) @@ -401,55 +424,38 @@ void D3D12GSRender::clear_surface(u32 arg) } } -namespace -{ -UINT get_num_rtt(u8 color_target) noexcept -{ - switch (color_target) - { - case CELL_GCM_SURFACE_TARGET_NONE: return 0; - case CELL_GCM_SURFACE_TARGET_0: - case CELL_GCM_SURFACE_TARGET_1: return 1; - case CELL_GCM_SURFACE_TARGET_MRT1: return 2; - case CELL_GCM_SURFACE_TARGET_MRT2: return 3; - case CELL_GCM_SURFACE_TARGET_MRT3: return 4; - } - unreachable("Wrong color target"); -} -} - void D3D12GSRender::end() { - std::chrono::time_point startDuration = std::chrono::system_clock::now(); + std::chrono::time_point start_duration = std::chrono::system_clock::now(); - std::chrono::time_point rttDurationStart = std::chrono::system_clock::now(); + std::chrono::time_point rtt_duration_start = 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 rtt_duration_end = std::chrono::system_clock::now(); + m_timers.m_rttDuration += std::chrono::duration_cast(rtt_duration_end - rtt_duration_start).count(); - std::chrono::time_point vertexIndexDurationStart = std::chrono::system_clock::now(); + std::chrono::time_point vertex_index_duration_start = std::chrono::system_clock::now(); if (!vertex_index_array.empty() || vertex_draw_count) upload_vertex_index_data(getCurrentResourceStorage().m_commandList.Get()); - 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 vertex_index_duration_end = std::chrono::system_clock::now(); + m_timers.m_vertexIndexDuration += std::chrono::duration_cast(vertex_index_duration_end - vertex_index_duration_start).count(); - std::chrono::time_point programLoadStart = std::chrono::system_clock::now(); + std::chrono::time_point program_load_start = 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(); + std::chrono::time_point program_load_end = std::chrono::system_clock::now(); + m_timers.m_programLoadDuration += std::chrono::duration_cast(program_load_end - program_load_start).count(); getCurrentResourceStorage().m_commandList->SetGraphicsRootSignature(m_rootSignatures[std::get<2>(*m_PSO)].Get()); getCurrentResourceStorage().m_commandList->OMSetStencilRef(rsx::method_registers[NV4097_SET_STENCIL_FUNC_REF]); - std::chrono::time_point constantsDurationStart = std::chrono::system_clock::now(); + std::chrono::time_point constants_duration_start = std::chrono::system_clock::now(); size_t currentDescriptorIndex = getCurrentResourceStorage().m_descriptorsHeapIndex; // Constants @@ -457,41 +463,41 @@ void D3D12GSRender::end() FillVertexShaderConstantsBuffer(currentDescriptorIndex + 1); FillPixelShaderConstantsBuffer(currentDescriptorIndex + 2); - std::chrono::time_point constantsDurationEnd = std::chrono::system_clock::now(); - m_timers.m_constantsDuration += std::chrono::duration_cast(constantsDurationEnd - constantsDurationStart).count(); + std::chrono::time_point constants_duration_end = std::chrono::system_clock::now(); + m_timers.m_constantsDuration += std::chrono::duration_cast(constants_duration_end - constants_duration_start).count(); getCurrentResourceStorage().m_commandList->SetPipelineState(std::get<0>(*m_PSO)); - std::chrono::time_point textureDurationStart = std::chrono::system_clock::now(); + std::chrono::time_point texture_duration_start = std::chrono::system_clock::now(); if (std::get<2>(*m_PSO) > 0) { - size_t usedTexture = UploadTextures(getCurrentResourceStorage().m_commandList.Get(), currentDescriptorIndex + 3); + size_t used_texture = UploadTextures(getCurrentResourceStorage().m_commandList.Get(), currentDescriptorIndex + 3); // Fill empty slots - for (; usedTexture < std::get<2>(*m_PSO); usedTexture++) + for (; used_texture < std::get<2>(*m_PSO); used_texture++) { - D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; - srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; - srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - srvDesc.Texture2D.MipLevels = 1; - srvDesc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING( + D3D12_SHADER_RESOURCE_VIEW_DESC shader_resource_view_desc = {}; + shader_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + shader_resource_view_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + shader_resource_view_desc.Texture2D.MipLevels = 1; + shader_resource_view_desc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING( D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0, 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, + m_device->CreateShaderResourceView(m_dummyTexture, &shader_resource_view_desc, CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_descriptorsHeap->GetCPUDescriptorHandleForHeapStart()) - .Offset((INT)currentDescriptorIndex + 3 + (INT)usedTexture, g_descriptorStrideSRVCBVUAV) + .Offset((INT)currentDescriptorIndex + 3 + (INT)used_texture, g_descriptorStrideSRVCBVUAV) ); - D3D12_SAMPLER_DESC samplerDesc = {}; - samplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; - samplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - samplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - samplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - m_device->CreateSampler(&samplerDesc, + D3D12_SAMPLER_DESC sampler_desc = {}; + sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; + sampler_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + sampler_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + m_device->CreateSampler(&sampler_desc, CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_samplerDescriptorHeap[getCurrentResourceStorage().m_samplerDescriptorHeapIndex]->GetCPUDescriptorHandleForHeapStart()) - .Offset((INT)getCurrentResourceStorage().m_currentSamplerIndex + (INT)usedTexture, g_descriptorStrideSamplers) + .Offset((INT)getCurrentResourceStorage().m_currentSamplerIndex + (INT)used_texture, g_descriptorStrideSamplers) ); } @@ -511,8 +517,8 @@ void D3D12GSRender::end() .Offset((INT)getCurrentResourceStorage().m_currentSamplerIndex, g_descriptorStrideSamplers) ); - getCurrentResourceStorage().m_currentSamplerIndex += usedTexture; - getCurrentResourceStorage().m_descriptorsHeapIndex += usedTexture + 3; + getCurrentResourceStorage().m_currentSamplerIndex += used_texture; + getCurrentResourceStorage().m_descriptorsHeapIndex += used_texture + 3; } else { @@ -524,11 +530,11 @@ void D3D12GSRender::end() getCurrentResourceStorage().m_descriptorsHeapIndex += 3; } - std::chrono::time_point textureDurationEnd = std::chrono::system_clock::now(); - m_timers.m_textureDuration += std::chrono::duration_cast(textureDurationEnd - textureDurationStart).count(); + std::chrono::time_point texture_duration_end = std::chrono::system_clock::now(); + m_timers.m_textureDuration += std::chrono::duration_cast(texture_duration_end - texture_duration_start).count(); - size_t numRTT = get_num_rtt(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]); - getCurrentResourceStorage().m_commandList->OMSetRenderTargets((UINT)numRTT, &m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart(), true, + size_t num_rtt = get_num_rtt(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]); + getCurrentResourceStorage().m_commandList->OMSetRenderTargets((UINT)num_rtt, &m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart(), true, &CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_depthStencilDescriptorHeap->GetCPUDescriptorHandleForHeapStart())); int clip_w = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16; @@ -562,8 +568,8 @@ void D3D12GSRender::end() getCurrentResourceStorage().m_commandList->DrawInstanced((UINT)m_renderingInfo.m_count, 1, 0, 0); vertex_index_array.clear(); - std::chrono::time_point endDuration = std::chrono::system_clock::now(); - m_timers.m_drawCallDuration += std::chrono::duration_cast(endDuration - startDuration).count(); + std::chrono::time_point end_duration = std::chrono::system_clock::now(); + m_timers.m_drawCallDuration += std::chrono::duration_cast(end_duration - start_duration).count(); m_timers.m_drawCallCount++; if (rpcs3::config.rsx.d3d12.debug_output.value()) @@ -577,10 +583,11 @@ void D3D12GSRender::end() thread::end(); } -static bool -isFlipSurfaceInLocalMemory(u32 surfaceColorTarget) +namespace { - switch (surfaceColorTarget) +bool is_flip_surface_in_global_memory(u32 color_target) +{ + switch (color_target) { case CELL_GCM_SURFACE_TARGET_0: case CELL_GCM_SURFACE_TARGET_1: @@ -589,44 +596,45 @@ isFlipSurfaceInLocalMemory(u32 surfaceColorTarget) case CELL_GCM_SURFACE_TARGET_MRT3: return true; case CELL_GCM_SURFACE_TARGET_NONE: - default: return false; } + unreachable("Wrong color target"); +} } void D3D12GSRender::flip(int buffer) { - ID3D12Resource *resourceToFlip; + ID3D12Resource *resource_to_flip; float viewport_w, viewport_h; - if (!isFlipSurfaceInLocalMemory(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) + if (!is_flip_surface_in_global_memory(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) { ResourceStorage &storage = getCurrentResourceStorage(); assert(storage.m_RAMFramebuffer == nullptr); - size_t w = 0, h = 0, rowPitch = 0; + size_t w = 0, h = 0, row_pitch = 0; size_t offset = 0; if (false) { - CellGcmDisplayInfo* buffers;// = vm::ps3::_ptr(m_gcm_buffers_addr); + CellGcmDisplayInfo* buffers = nullptr;// = vm::ps3::_ptr(m_gcm_buffers_addr); u32 addr = rsx::get_address(gcm_buffers[gcm_current_buffer].offset, CELL_GCM_LOCATION_LOCAL); w = gcm_buffers[gcm_current_buffer].width; h = gcm_buffers[gcm_current_buffer].height; u8 *src_buffer = vm::ps3::_ptr(addr); - rowPitch = align(w * 4, 256); - size_t textureSize = rowPitch * h; // * 4 for mipmap levels - assert(m_textureUploadData.canAlloc(textureSize)); - size_t heapOffset = m_textureUploadData.alloc(textureSize); + row_pitch = align(w * 4, 256); + size_t texture_size = row_pitch * h; // * 4 for mipmap levels + assert(m_textureUploadData.canAlloc(texture_size)); + size_t heap_offset = m_textureUploadData.alloc(texture_size); void *buffer; - ThrowIfFailed(m_textureUploadData.m_heap->Map(0, &CD3DX12_RANGE(heapOffset, heapOffset + textureSize), &buffer)); - void *dstBuffer = (char*)buffer + heapOffset; + ThrowIfFailed(m_textureUploadData.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + texture_size), &buffer)); + void *mapped_buffer = (char*)buffer + heap_offset; for (unsigned row = 0; row < h; row++) - memcpy((char*)dstBuffer + row * rowPitch, (char*)src_buffer + row * w * 4, w * 4); - m_textureUploadData.m_heap->Unmap(0, &CD3DX12_RANGE(heapOffset, heapOffset + textureSize)); - offset = heapOffset; + memcpy((char*)mapped_buffer + row * row_pitch, (char*)src_buffer + row * w * 4, w * 4); + m_textureUploadData.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + texture_size)); + offset = heap_offset; } ThrowIfFailed( @@ -640,17 +648,17 @@ void D3D12GSRender::flip(int buffer) ) ); getCurrentResourceStorage().m_commandList->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(storage.m_RAMFramebuffer.Get(), 0), 0, 0, 0, - &CD3DX12_TEXTURE_COPY_LOCATION(m_textureUploadData.m_heap, { offset, { DXGI_FORMAT_R8G8B8A8_UNORM, (UINT)w, (UINT)h, 1, (UINT)rowPitch} }), nullptr); + &CD3DX12_TEXTURE_COPY_LOCATION(m_textureUploadData.m_heap, { offset, { DXGI_FORMAT_R8G8B8A8_UNORM, (UINT)w, (UINT)h, 1, (UINT)row_pitch } }), nullptr); 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(); + resource_to_flip = 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, &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]; + resource_to_flip = m_rtts.m_currentlyBoundRenderTargets[0]; } getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_backBuffer[m_swapChain->GetCurrentBackBufferIndex()].Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET)); @@ -677,29 +685,29 @@ void D3D12GSRender::flip(int buffer) getCurrentResourceStorage().m_commandList->SetGraphicsRootSignature(m_outputScalingPass.m_rootSignature); getCurrentResourceStorage().m_commandList->SetPipelineState(m_outputScalingPass.m_PSO); - D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; + D3D12_SHADER_RESOURCE_VIEW_DESC shader_resource_view_desc = {}; // FIXME: Not always true - srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; - srvDesc.Texture2D.MipLevels = 1; - if (isFlipSurfaceInLocalMemory(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) - srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + shader_resource_view_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + shader_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + shader_resource_view_desc.Texture2D.MipLevels = 1; + if (is_flip_surface_in_global_memory(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) + shader_resource_view_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; else - srvDesc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING( + shader_resource_view_desc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING( D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1, D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2, D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_3, D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0 ); - m_device->CreateShaderResourceView(resourceToFlip, &srvDesc, + m_device->CreateShaderResourceView(resource_to_flip, &shader_resource_view_desc, 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; - m_device->CreateSampler(&samplerDesc, + D3D12_SAMPLER_DESC sampler_desc = {}; + sampler_desc.Filter = D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT; + sampler_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + sampler_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + m_device->CreateSampler(&sampler_desc, CD3DX12_CPU_DESCRIPTOR_HANDLE(m_outputScalingPass.m_samplerDescriptorHeap->GetCPUDescriptorHandleForHeapStart()).Offset(m_swapChain->GetCurrentBackBufferIndex(), g_descriptorStrideSamplers)); getCurrentResourceStorage().m_commandList->SetDescriptorHeaps(1, &m_outputScalingPass.m_textureDescriptorHeap); @@ -712,18 +720,18 @@ void D3D12GSRender::flip(int buffer) 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); - vbv.SizeInBytes = 16 * sizeof(float); - getCurrentResourceStorage().m_commandList->IASetVertexBuffers(0, 1, &vbv); + D3D12_VERTEX_BUFFER_VIEW vertex_buffer_view = {}; + vertex_buffer_view.BufferLocation = m_outputScalingPass.m_vertexBuffer->GetGPUVirtualAddress(); + vertex_buffer_view.StrideInBytes = 4 * sizeof(float); + vertex_buffer_view.SizeInBytes = 16 * sizeof(float); + getCurrentResourceStorage().m_commandList->IASetVertexBuffers(0, 1, &vertex_buffer_view); getCurrentResourceStorage().m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); if (m_rtts.m_currentlyBoundRenderTargets[0] != nullptr) getCurrentResourceStorage().m_commandList->DrawInstanced(4, 1, 0, 0); if (!rpcs3::config.rsx.d3d12.overlay.value()) 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(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]) && m_rtts.m_currentlyBoundRenderTargets[0] != nullptr) + if (is_flip_surface_in_global_memory(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]) && m_rtts.m_currentlyBoundRenderTargets[0] != nullptr) 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()); @@ -733,7 +741,7 @@ void D3D12GSRender::flip(int buffer) ResetTimer(); - std::chrono::time_point flipStart = std::chrono::system_clock::now(); + std::chrono::time_point flip_start = std::chrono::system_clock::now(); ThrowIfFailed(m_swapChain->Present(rpcs3::state.config.rsx.vsync.value() ? 1 : 0, 0)); // Add an event signaling queue completion @@ -760,23 +768,23 @@ void D3D12GSRender::flip(int buffer) m_texturesRTTs.clear(); // Now get ready for next frame - ResourceStorage &newStorage = getCurrentResourceStorage(); + ResourceStorage &new_storage = getCurrentResourceStorage(); - newStorage.WaitAndClean(); - if (newStorage.m_inUse) + new_storage.WaitAndClean(); + if (new_storage.m_inUse) { - m_constantsData.m_getPos = newStorage.m_getPosConstantsHeap; - m_vertexIndexData.m_getPos = newStorage.m_getPosVertexIndexHeap; - m_textureUploadData.m_getPos = newStorage.m_getPosTextureUploadHeap; - m_readbackResources.m_getPos = newStorage.m_getPosReadbackHeap; - m_UAVHeap.m_getPos = newStorage.m_getPosUAVHeap; + m_constantsData.m_getPos = new_storage.m_getPosConstantsHeap; + m_vertexIndexData.m_getPos = new_storage.m_getPosVertexIndexHeap; + m_textureUploadData.m_getPos = new_storage.m_getPosTextureUploadHeap; + m_readbackResources.m_getPos = new_storage.m_getPosReadbackHeap; + m_UAVHeap.m_getPos = new_storage.m_getPosUAVHeap; } m_frame->flip(nullptr); - std::chrono::time_point flipEnd = std::chrono::system_clock::now(); - m_timers.m_flipDuration += std::chrono::duration_cast(flipEnd - flipStart).count(); + std::chrono::time_point flip_end = std::chrono::system_clock::now(); + m_timers.m_flipDuration += std::chrono::duration_cast(flip_end - flip_start).count(); } void D3D12GSRender::ResetTimer() @@ -802,57 +810,71 @@ D3D12GSRender::ResourceStorage& D3D12GSRender::getNonCurrentResourceStorage() return m_perFrameStorage[1 - m_swapChain->GetCurrentBackBufferIndex()]; } -ID3D12Resource * D3D12GSRender::writeColorBuffer(ID3D12Resource * RTT, ID3D12GraphicsCommandList * cmdlist) +namespace +{ +/** + * Create a write back buffer resource and populate command_list with copy command to fill it + * with color_surface data. + */ + ComPtr create_readback_buffer_and_download( + ID3D12Device *device, + ID3D12GraphicsCommandList * command_list, + DataHeap &readback_heap, + ID3D12Resource * color_surface, + int color_surface_format + ) { int clip_w = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16; int clip_h = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16; - ID3D12Resource *Result; - size_t w = clip_w, h = clip_h; - DXGI_FORMAT dxgiFormat = get_color_surface_format(m_surface.color_format); - size_t rowPitch; - switch (m_surface.color_format) + + DXGI_FORMAT dxgi_format = get_color_surface_format(color_surface_format); + size_t row_pitch; + switch (color_surface_format) { case CELL_GCM_SURFACE_A8R8G8B8: - rowPitch = align(w * 4, 256); + row_pitch = align(clip_w * 4, 256); break; case CELL_GCM_SURFACE_F_W16Z16Y16X16: - rowPitch = align(w * 8, 256); + row_pitch = align(clip_w * 8, 256); break; } - size_t sizeInByte = rowPitch * h; - assert(m_readbackResources.canAlloc(sizeInByte)); - size_t heapOffset = m_readbackResources.alloc(sizeInByte); - + size_t buffer_size = row_pitch * clip_h; + assert(readback_heap.canAlloc(buffer_size)); + size_t heapOffset = readback_heap.alloc(buffer_size); + ComPtr Result; ThrowIfFailed( - m_device->CreatePlacedResource( - m_readbackResources.m_heap, + device->CreatePlacedResource( + readback_heap.m_heap, heapOffset, - &CD3DX12_RESOURCE_DESC::Buffer(rowPitch * h), + &CD3DX12_RESOURCE_DESC::Buffer(row_pitch * clip_h), D3D12_RESOURCE_STATE_COPY_DEST, nullptr, - IID_PPV_ARGS(&Result) + IID_PPV_ARGS(Result.GetAddressOf()) ) ); - getCurrentResourceStorage().m_singleFrameLifetimeResources.push_back(Result); - cmdlist->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(RTT, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE)); + command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(color_surface, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE)); - 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)); + command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(Result.Get(), { 0, { dxgi_format, (UINT)clip_w, (UINT)clip_h, 1, (UINT)row_pitch } }), 0, 0, 0, + &CD3DX12_TEXTURE_COPY_LOCATION(color_surface, 0), nullptr); + command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(color_surface, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET)); return Result; } -static -void copyToCellRamAndRelease(void *dstAddress, ID3D12Resource *res, size_t dstPitch, size_t srcPitch, size_t width, size_t height) +void copy_readback_buffer_to_dest(void *dest, ID3D12Resource *res, size_t dst_pitch, size_t src_pitch, size_t height) { - void *srcBuffer; - ThrowIfFailed(res->Map(0, nullptr, &srcBuffer)); + void *mapped_buffer; + ThrowIfFailed(res->Map(0, nullptr, &mapped_buffer)); for (unsigned row = 0; row < height; row++) - memcpy((char*)dstAddress + row * dstPitch, (char*)srcBuffer + row * srcPitch, srcPitch); + { + u32 *casted_dest = (u32*)((char*)dest + row * dst_pitch); + u32 *casted_src = (u32*)((char*)mapped_buffer + row * src_pitch); + for (unsigned col = 0; col < src_pitch / 4; col++) + *casted_dest++ = _byteswap_ulong(*casted_src++); + } res->Unmap(0, nullptr); - res->Release(); +} } void D3D12GSRender::semaphore_PGRAPH_texture_read_release() @@ -868,139 +890,107 @@ void D3D12GSRender::semaphore_PGRAPH_backend_release() int clip_w = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16; int clip_h = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16; - ComPtr fence; - ThrowIfFailed( - 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 depth_buffer_write_dest, depth_format_conversion_buffer; + ComPtr descriptor_heap; + size_t depth_row_pitch = align(clip_w, 256); - ComPtr writeDest, depthConverted; - ComPtr descriptorHeap; - size_t depthRowPitch = clip_w; - depthRowPitch = (depthRowPitch + 255) & ~255; - - u32 m_context_dma_color_a = rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_A]; - u32 m_context_dma_color_b = rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_B]; - u32 m_context_dma_color_c = rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_C]; - u32 m_context_dma_color_d = rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_D]; + u32 context_dma_color[] = + { + rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_A], + rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_B], + rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_C], + rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_D], + }; u32 m_context_dma_z = rsx::method_registers[NV4097_SET_CONTEXT_DMA_ZETA]; - bool needTransfer = (m_context_dma_z && rpcs3::state.config.rsx.opengl.write_depth_buffer) || - ((m_context_dma_color_a || m_context_dma_color_b || m_context_dma_color_c || m_context_dma_color_d) && rpcs3::state.config.rsx.opengl.write_color_buffers); + bool need_transfer = false; if (m_context_dma_z && rpcs3::state.config.rsx.opengl.write_depth_buffer) { - size_t sizeInByte = clip_w * clip_h * 2; - assert(m_UAVHeap.canAlloc(sizeInByte)); - size_t heapOffset = m_UAVHeap.alloc(sizeInByte); + size_t uav_size = clip_w * clip_h * 2; + assert(m_UAVHeap.canAlloc(uav_size)); + size_t heap_offset = m_UAVHeap.alloc(uav_size); ThrowIfFailed( m_device->CreatePlacedResource( m_UAVHeap.m_heap, - heapOffset, + heap_offset, &CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8_UNORM, clip_w, clip_h, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS), D3D12_RESOURCE_STATE_UNORDERED_ACCESS, nullptr, - IID_PPV_ARGS(depthConverted.GetAddressOf()) + IID_PPV_ARGS(depth_format_conversion_buffer.GetAddressOf()) ) ); - sizeInByte = depthRowPitch * clip_h; - assert(m_readbackResources.canAlloc(sizeInByte)); - heapOffset = m_readbackResources.alloc(sizeInByte); + size_t buffer_size = depth_row_pitch * clip_h; + assert(m_readbackResources.canAlloc(buffer_size)); + heap_offset = m_readbackResources.alloc(buffer_size); ThrowIfFailed( m_device->CreatePlacedResource( m_readbackResources.m_heap, - heapOffset, - &CD3DX12_RESOURCE_DESC::Buffer(sizeInByte), + heap_offset, + &CD3DX12_RESOURCE_DESC::Buffer(buffer_size), D3D12_RESOURCE_STATE_COPY_DEST, nullptr, - IID_PPV_ARGS(writeDest.GetAddressOf()) + IID_PPV_ARGS(depth_buffer_write_dest.GetAddressOf()) ) ); - D3D12_DESCRIPTOR_HEAP_DESC descriptorHeapDesc = { D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV , 2, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE }; + D3D12_DESCRIPTOR_HEAP_DESC descriptor_heap_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV , 2, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE }; ThrowIfFailed( - m_device->CreateDescriptorHeap(&descriptorHeapDesc, IID_PPV_ARGS(descriptorHeap.GetAddressOf())) + m_device->CreateDescriptorHeap(&descriptor_heap_desc, IID_PPV_ARGS(descriptor_heap.GetAddressOf())) ); - D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; + D3D12_SHADER_RESOURCE_VIEW_DESC shader_resource_view_desc = {}; m_surface.depth_format = get_depth_typeless_surface_format(m_surface.depth_format); - 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, - 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, - CD3DX12_CPU_DESCRIPTOR_HANDLE(descriptorHeap->GetCPUDescriptorHandleForHeapStart()).Offset(1, g_descriptorStrideSRVCBVUAV)); + shader_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + shader_resource_view_desc.Texture2D.MipLevels = 1; + shader_resource_view_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + m_device->CreateShaderResourceView(m_rtts.m_currentlyBoundDepthStencil, &shader_resource_view_desc, + CD3DX12_CPU_DESCRIPTOR_HANDLE(descriptor_heap->GetCPUDescriptorHandleForHeapStart())); + D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc = {}; + uav_desc.Format = DXGI_FORMAT_R8_UNORM; + uav_desc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D; + m_device->CreateUnorderedAccessView(depth_format_conversion_buffer.Get(), nullptr, &uav_desc, + CD3DX12_CPU_DESCRIPTOR_HANDLE(descriptor_heap->GetCPUDescriptorHandleForHeapStart()).Offset(1, g_descriptorStrideSRVCBVUAV)); // Convert 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.GetAddressOf()); - getCurrentResourceStorage().m_commandList->SetComputeRootDescriptorTable(0, descriptorHeap->GetGPUDescriptorHandleForHeapStart()); + getCurrentResourceStorage().m_commandList->SetDescriptorHeaps(1, descriptor_heap.GetAddressOf()); + getCurrentResourceStorage().m_commandList->SetComputeRootDescriptorTable(0, descriptor_heap->GetGPUDescriptorHandleForHeapStart()); getCurrentResourceStorage().m_commandList->Dispatch(clip_w / 8, clip_h / 8, 1); D3D12_RESOURCE_BARRIER barriers[] = { CD3DX12_RESOURCE_BARRIER::Transition(m_rtts.m_currentlyBoundDepthStencil, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_DEPTH_WRITE), - CD3DX12_RESOURCE_BARRIER::UAV(depthConverted.Get()), + CD3DX12_RESOURCE_BARRIER::UAV(depth_format_conversion_buffer.Get()), }; getCurrentResourceStorage().m_commandList->ResourceBarrier(2, barriers); - 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, (UINT)clip_w, (UINT)clip_h, 1, (UINT)depthRowPitch } }), 0, 0, 0, - &CD3DX12_TEXTURE_COPY_LOCATION(depthConverted.Get(), 0), nullptr); + getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(depth_format_conversion_buffer.Get(), D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE)); + getCurrentResourceStorage().m_commandList->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(depth_buffer_write_dest.Get(), { 0, { DXGI_FORMAT_R8_UNORM, (UINT)clip_w, (UINT)clip_h, 1, (UINT)depth_row_pitch } }), 0, 0, 0, + &CD3DX12_TEXTURE_COPY_LOCATION(depth_buffer_write_dest.Get(), 0), nullptr); invalidateAddress(rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET], m_context_dma_z - 0xfeed0000)); + + need_transfer = true; } - ID3D12Resource *rtt0 = nullptr, *rtt1 = nullptr, *rtt2 = nullptr, *rtt3 = nullptr; + ComPtr readback_buffers[4]; if (rpcs3::state.config.rsx.opengl.write_color_buffers) { - switch (rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]) + for (u8 i : get_rtt_indexes(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) { - case CELL_GCM_SURFACE_TARGET_NONE: - break; - - case CELL_GCM_SURFACE_TARGET_0: - if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[0], getCurrentResourceStorage().m_commandList.Get()); - break; - - case CELL_GCM_SURFACE_TARGET_1: - if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[0], getCurrentResourceStorage().m_commandList.Get()); - break; - - case CELL_GCM_SURFACE_TARGET_MRT1: - if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[0], getCurrentResourceStorage().m_commandList.Get()); - if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[1], getCurrentResourceStorage().m_commandList.Get()); - break; - - case CELL_GCM_SURFACE_TARGET_MRT2: - if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[0], getCurrentResourceStorage().m_commandList.Get()); - if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[1], getCurrentResourceStorage().m_commandList.Get()); - if (m_context_dma_color_c) rtt2 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[2], getCurrentResourceStorage().m_commandList.Get()); - break; - - case CELL_GCM_SURFACE_TARGET_MRT3: - if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[0], getCurrentResourceStorage().m_commandList.Get()); - if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[1], getCurrentResourceStorage().m_commandList.Get()); - if (m_context_dma_color_c) rtt2 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[2], getCurrentResourceStorage().m_commandList.Get()); - if (m_context_dma_color_d) rtt3 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[3], getCurrentResourceStorage().m_commandList.Get()); - break; + if (!context_dma_color[i]) + continue; + readback_buffers[i] = create_readback_buffer_and_download(m_device.Get(), getCurrentResourceStorage().m_commandList.Get(), m_readbackResources, m_rtts.m_currentlyBoundRenderTargets[0], m_surface.color_format); + invalidateAddress(rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET], context_dma_color[i] - 0xfeed0000)); + need_transfer = true; } - - if (m_context_dma_color_a) invalidateAddress(rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET], m_context_dma_color_a - 0xfeed0000)); - if (m_context_dma_color_b) invalidateAddress(rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_BOFFSET], m_context_dma_color_b - 0xfeed0000)); - if (m_context_dma_color_c) invalidateAddress(rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_COFFSET], m_context_dma_color_c - 0xfeed0000)); - if (m_context_dma_color_d) invalidateAddress(rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_DOFFSET], m_context_dma_color_d - 0xfeed0000)); } - if (needTransfer) + if (need_transfer) { ThrowIfFailed(getCurrentResourceStorage().m_commandList->Close()); m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)getCurrentResourceStorage().m_commandList.GetAddressOf()); @@ -1008,27 +998,25 @@ void D3D12GSRender::semaphore_PGRAPH_backend_release() } //Wait for result - m_commandQueueGraphic->Signal(fence.Get(), 1); - WaitForSingleObject(handle, INFINITE); - CloseHandle(handle); + wait_for_command_queue(m_device.Get(), m_commandQueueGraphic.Get()); if (m_context_dma_z && rpcs3::state.config.rsx.opengl.write_depth_buffer) { u32 address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET], m_context_dma_z - 0xfeed0000); auto ptr = vm::base(address); - char *ptrAsChar = (char*)ptr; - unsigned char *writeDestPtr; - ThrowIfFailed(writeDest->Map(0, nullptr, (void**)&writeDestPtr)); + char *depth_buffer = (char*)ptr; + unsigned char *mapped_buffer; + ThrowIfFailed(depth_buffer_write_dest->Map(0, nullptr, (void**)&mapped_buffer)); for (unsigned row = 0; row < (unsigned)clip_h; row++) { for (unsigned i = 0; i < (unsigned)clip_w; i++) { - unsigned char c = writeDestPtr[row * depthRowPitch + i]; - ptrAsChar[4 * (row * clip_w + i)] = c; - ptrAsChar[4 * (row * clip_w + i) + 1] = c; - ptrAsChar[4 * (row * clip_w + i) + 2] = c; - ptrAsChar[4 * (row * clip_w + i) + 3] = c; + unsigned char c = mapped_buffer[row * depth_row_pitch + i]; + depth_buffer[4 * (row * clip_w + i)] = c; + depth_buffer[4 * (row * clip_w + i) + 1] = c; + depth_buffer[4 * (row * clip_w + i) + 2] = c; + depth_buffer[4 * (row * clip_w + i) + 3] = c; } } } @@ -1048,52 +1036,19 @@ void D3D12GSRender::semaphore_PGRAPH_backend_release() if (rpcs3::state.config.rsx.opengl.write_color_buffers) { - switch (rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]) + void *dest_buffer[] = { - case CELL_GCM_SURFACE_TARGET_NONE: - break; - case CELL_GCM_SURFACE_TARGET_0: + vm::base(rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET], context_dma_color[0] - 0xfeed0000)), + vm::base(rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET], context_dma_color[1] - 0xfeed0000)), + vm::base(rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET], context_dma_color[2] - 0xfeed0000)), + vm::base(rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET], context_dma_color[3] - 0xfeed0000)) + }; + + for (u8 i : get_rtt_indexes(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) { - u32 address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET], m_context_dma_color_a - 0xfeed0000); - copyToCellRamAndRelease(vm::base(address), rtt0, srcPitch, dstPitch, clip_w, clip_h); - } - break; - case CELL_GCM_SURFACE_TARGET_1: - { - u32 address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_BOFFSET], m_context_dma_color_b - 0xfeed0000); - copyToCellRamAndRelease(vm::base(address), rtt1, srcPitch, dstPitch, clip_w, clip_h); - } - break; - case CELL_GCM_SURFACE_TARGET_MRT1: - { - u32 address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET], m_context_dma_color_a - 0xfeed0000); - copyToCellRamAndRelease(vm::base(address), rtt0, srcPitch, dstPitch, clip_w, clip_h); - address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_BOFFSET], m_context_dma_color_b - 0xfeed0000); - copyToCellRamAndRelease(vm::base(address), rtt1, srcPitch, dstPitch, clip_w, clip_h); - } - break; - case CELL_GCM_SURFACE_TARGET_MRT2: - { - u32 address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET], m_context_dma_color_a - 0xfeed0000); - copyToCellRamAndRelease(vm::base(address), rtt0, srcPitch, dstPitch, clip_w, clip_h); - address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_BOFFSET], m_context_dma_color_b - 0xfeed0000); - copyToCellRamAndRelease(vm::base(address), rtt1, srcPitch, dstPitch, clip_w, clip_h); - address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_COFFSET], m_context_dma_color_c - 0xfeed0000); - copyToCellRamAndRelease(vm::base(address), rtt2, srcPitch, dstPitch, clip_w, clip_h); - } - break; - case CELL_GCM_SURFACE_TARGET_MRT3: - { - u32 address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET], m_context_dma_color_a - 0xfeed0000); - copyToCellRamAndRelease(vm::base(address), rtt0, srcPitch, dstPitch, clip_w, clip_h); - address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_BOFFSET], m_context_dma_color_b - 0xfeed0000); - copyToCellRamAndRelease(vm::base(address), rtt1, srcPitch, dstPitch, clip_w, clip_h); - address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_COFFSET], m_context_dma_color_c - 0xfeed0000); - copyToCellRamAndRelease(vm::base(address), rtt2, srcPitch, dstPitch, clip_w, clip_h); - address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_DOFFSET], m_context_dma_color_d - 0xfeed0000); - copyToCellRamAndRelease(vm::base(address), rtt3, srcPitch, dstPitch, clip_w, clip_h); - } - break; + if (!context_dma_color[i]) + continue; + copy_readback_buffer_to_dest(dest_buffer[i], readback_buffers[i].Get(), srcPitch, dstPitch, clip_h); } } } diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h index 0873f6aee1..e697f10476 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h @@ -452,7 +452,6 @@ public: private: void InitD2DStructures(); void ReleaseD2DStructures(); - ID3D12Resource *writeColorBuffer(ID3D12Resource *RTT, ID3D12GraphicsCommandList *cmdlist); bool LoadProgram();