D3D12GSRender::~D3D12GSRender() { wait_for_command_queue(m_device.Get(), m_command_queue.Get()); m_texture_cache.unprotect_all(); m_dummy_texture->Release(); m_convert_pso->Release(); m_convert_root_signature->Release(); m_per_frame_storage[0].release(); m_per_frame_storage[1].release(); m_output_scaling_pass.release(); release_d2d_structures(); }
D3D12GSRender::~D3D12GSRender() { if (!m_device) { //Initialization must have failed return; } wait_for_command_queue(m_device.Get(), m_command_queue.Get()); m_texture_cache.unprotect_all(); m_dummy_texture->Release(); m_per_frame_storage[0].release(); m_per_frame_storage[1].release(); m_output_scaling_pass.release(); release_d2d_structures(); }
D3D12GSRender::~D3D12GSRender() { wait_for_command_queue(m_device.Get(), m_commandQueueGraphic.Get()); m_textureCache.unprotect_all(); gfxHandler = [this](u32) { return false; }; m_constantsData.release(); m_vertexIndexData.release(); m_textureUploadData.release(); m_UAVHeap.m_heap->Release(); m_readbackResources.m_heap->Release(); m_texturesRTTs.clear(); m_dummyTexture->Release(); m_convertPSO->Release(); m_convertRootSignature->Release(); m_perFrameStorage[0].release(); m_perFrameStorage[1].release(); m_outputScalingPass.Release(); release_d2d_structures(); }
void D3D12GSRender::copy_render_target_to_dma_location() { // Add all buffer write // Cell can't make any assumption about readyness of color/depth buffer // Except when a semaphore is written by RSX int clip_w = rsx::method_registers.surface_clip_width(); int clip_h = rsx::method_registers.surface_clip_height(); size_t depth_row_pitch = align(clip_w * 4, 256); size_t depth_buffer_offset_in_heap = 0; u32 address_color[] = { rsx::get_address(rsx::method_registers.surface_a_offset(), rsx::method_registers.surface_a_dma()), rsx::get_address(rsx::method_registers.surface_b_offset(), rsx::method_registers.surface_b_dma()), rsx::get_address(rsx::method_registers.surface_c_offset(), rsx::method_registers.surface_c_dma()), rsx::get_address(rsx::method_registers.surface_d_offset(), rsx::method_registers.surface_d_dma()), }; u32 address_z = rsx::get_address(rsx::method_registers.surface_z_offset(), rsx::method_registers.surface_z_dma()); bool need_transfer = false; if (rsx::method_registers.surface_z_dma() && g_cfg_rsx_write_depth_buffer) { get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(std::get<1>(m_rtts.m_bound_depth_stencil), D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE)); get_current_resource_storage().command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(m_readback_resources.get_heap(), { depth_buffer_offset_in_heap,{ DXGI_FORMAT_R32_TYPELESS, (UINT)clip_w, (UINT)clip_h, 1, (UINT)depth_row_pitch } }), 0, 0, 0, &CD3DX12_TEXTURE_COPY_LOCATION(std::get<1>(m_rtts.m_bound_depth_stencil), 0), nullptr); get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(std::get<1>(m_rtts.m_bound_depth_stencil), D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE)); invalidate_address(address_z); need_transfer = true; } size_t color_buffer_offset_in_heap[4]; if (g_cfg_rsx_write_color_buffers) { for (u8 i : get_rtt_indexes(rsx::method_registers.surface_color_target())) { if (!address_color[i]) continue; color_buffer_offset_in_heap[i] = download_to_readback_buffer(m_device.Get(), get_current_resource_storage().command_list.Get(), m_readback_resources, std::get<1>(m_rtts.m_bound_render_targets[i]), rsx::method_registers.surface_color()); invalidate_address(address_color[i]); need_transfer = true; } } if (need_transfer) { CHECK_HRESULT(get_current_resource_storage().command_list->Close()); m_command_queue->ExecuteCommandLists(1, (ID3D12CommandList**)get_current_resource_storage().command_list.GetAddressOf()); get_current_resource_storage().set_new_command_list(); } //Wait for result wait_for_command_queue(m_device.Get(), m_command_queue.Get()); if (address_z && g_cfg_rsx_write_depth_buffer) { auto ptr = vm::base(address_z); char *depth_buffer = (char*)ptr; u8 *mapped_buffer = m_readback_resources.map<u8>(depth_buffer_offset_in_heap); for (unsigned row = 0; row < (unsigned)clip_h; row++) { for (unsigned i = 0; i < (unsigned)clip_w; i++) { 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; } } m_readback_resources.unmap(); } if (g_cfg_rsx_write_color_buffers) { size_t srcPitch = get_aligned_pitch(rsx::method_registers.surface_color(), clip_w); size_t dstPitch = get_packed_pitch(rsx::method_registers.surface_color(), clip_w); void *dest_buffer[] = { vm::base(address_color[0]), vm::base(address_color[1]), vm::base(address_color[2]), vm::base(address_color[3]), }; for (u8 i : get_rtt_indexes(rsx::method_registers.surface_color_target())) { if (!address_color[i]) continue; copy_readback_buffer_to_dest(dest_buffer[i], m_readback_resources, color_buffer_offset_in_heap[i], srcPitch, dstPitch, clip_h); } } }