void D3D12GSRender::clear_surface(u32 arg) { // Ignore clear if surface target is set to CELL_GCM_SURFACE_TARGET_NONE if (rsx::method_registers.surface_color_target() == rsx::surface_target::none) return; std::chrono::time_point<std::chrono::system_clock> start_duration = std::chrono::system_clock::now(); std::chrono::time_point<std::chrono::system_clock> rtt_duration_start = std::chrono::system_clock::now(); prepare_render_targets(get_current_resource_storage().command_list.Get()); std::chrono::time_point<std::chrono::system_clock> rtt_duration_end = std::chrono::system_clock::now(); m_timers.prepare_rtt_duration += std::chrono::duration_cast<std::chrono::microseconds>(rtt_duration_end - rtt_duration_start).count(); if (arg & 0x1 || arg & 0x2) { get_current_resource_storage().depth_stencil_descriptor_heap_index++; if (arg & 0x1) { u32 clear_depth = rsx::method_registers.z_clear_value(); u32 max_depth_value = get_max_depth_value(rsx::method_registers.surface_depth_fmt()); get_current_resource_storage().command_list->ClearDepthStencilView(m_rtts.current_ds_handle, D3D12_CLEAR_FLAG_DEPTH, clear_depth / (float)max_depth_value, 0, 1, &get_scissor(rsx::method_registers.scissor_origin_x(), rsx::method_registers.scissor_origin_y(), rsx::method_registers.scissor_width(), rsx::method_registers.scissor_height())); } if (arg & 0x2) get_current_resource_storage().command_list->ClearDepthStencilView(m_rtts.current_ds_handle, D3D12_CLEAR_FLAG_STENCIL, 0.f, get_clear_stencil(rsx::method_registers.stencil_clear_value()), 1, &get_scissor(rsx::method_registers.scissor_origin_x(), rsx::method_registers.scissor_origin_y(), rsx::method_registers.scissor_width(), rsx::method_registers.scissor_height())); } if (arg & 0xF0) { CD3DX12_CPU_DESCRIPTOR_HANDLE handle = CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.current_rtts_handle); size_t rtt_index = get_num_rtt(rsx::method_registers.surface_color_target()); get_current_resource_storage().render_targets_descriptors_heap_index += rtt_index; std::array<float, 4> clear_color = { rsx::method_registers.clear_color_r() / 255.f, rsx::method_registers.clear_color_g() / 255.f, rsx::method_registers.clear_color_b() / 255.f, rsx::method_registers.clear_color_a() / 255.f, }; for (unsigned i = 0; i < rtt_index; i++) get_current_resource_storage().command_list->ClearRenderTargetView(handle.Offset(i, m_descriptor_stride_rtv), clear_color.data(), 1, &get_scissor(rsx::method_registers.scissor_origin_x(), rsx::method_registers.scissor_origin_y(), rsx::method_registers.scissor_width(), rsx::method_registers.scissor_height())); } std::chrono::time_point<std::chrono::system_clock> end_duration = std::chrono::system_clock::now(); m_timers.draw_calls_duration += std::chrono::duration_cast<std::chrono::microseconds>(end_duration - start_duration).count(); m_timers.draw_calls_count++; if (g_cfg_rsx_debug_output) { 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(); } }
void D3D12GSRender::end() { std::chrono::time_point<std::chrono::system_clock> start_duration = std::chrono::system_clock::now(); std::chrono::time_point<std::chrono::system_clock> rtt_duration_start = std::chrono::system_clock::now(); prepare_render_targets(get_current_resource_storage().command_list.Get()); std::chrono::time_point<std::chrono::system_clock> rtt_duration_end = std::chrono::system_clock::now(); m_timers.prepare_rtt_duration += std::chrono::duration_cast<std::chrono::microseconds>(rtt_duration_end - rtt_duration_start).count(); std::chrono::time_point<std::chrono::system_clock> vertex_index_duration_start = std::chrono::system_clock::now(); size_t currentDescriptorIndex = get_current_resource_storage().descriptors_heap_index; size_t vertex_count; bool indexed_draw; std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC> vertex_buffer_views; std::tie(indexed_draw, vertex_count, vertex_buffer_views) = upload_and_set_vertex_index_data(get_current_resource_storage().command_list.Get()); size_t vertex_buffer_count = vertex_buffer_views.size(); std::chrono::time_point<std::chrono::system_clock> vertex_index_duration_end = std::chrono::system_clock::now(); m_timers.vertex_index_duration += std::chrono::duration_cast<std::chrono::microseconds>(vertex_index_duration_end - vertex_index_duration_start).count(); std::chrono::time_point<std::chrono::system_clock> program_load_start = std::chrono::system_clock::now(); load_program(); std::chrono::time_point<std::chrono::system_clock> program_load_end = std::chrono::system_clock::now(); m_timers.program_load_duration += std::chrono::duration_cast<std::chrono::microseconds>(program_load_end - program_load_start).count(); get_current_resource_storage().command_list->SetGraphicsRootSignature(m_root_signatures[std::get<2>(m_current_pso)][vertex_buffer_count].Get()); get_current_resource_storage().command_list->OMSetStencilRef(rsx::method_registers[NV4097_SET_STENCIL_FUNC_REF]); std::chrono::time_point<std::chrono::system_clock> constants_duration_start = std::chrono::system_clock::now(); INT offset = 0; for (const auto view : vertex_buffer_views) { m_device->CreateShaderResourceView(m_vertex_buffer_data.Get(), &view, CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetCPUDescriptorHandleForHeapStart()) .Offset((INT)currentDescriptorIndex + offset++, m_descriptor_stride_srv_cbv_uav)); } // Constants upload_and_bind_scale_offset_matrix(currentDescriptorIndex + vertex_buffer_count); upload_and_bind_vertex_shader_constants(currentDescriptorIndex + 1 + vertex_buffer_count); upload_and_bind_fragment_shader_constants(currentDescriptorIndex + 2 + vertex_buffer_count); std::chrono::time_point<std::chrono::system_clock> constants_duration_end = std::chrono::system_clock::now(); m_timers.constants_duration += std::chrono::duration_cast<std::chrono::microseconds>(constants_duration_end - constants_duration_start).count(); get_current_resource_storage().command_list->SetPipelineState(std::get<0>(m_current_pso).Get()); std::chrono::time_point<std::chrono::system_clock> texture_duration_start = std::chrono::system_clock::now(); size_t texture_count = std::get<2>(m_current_pso); if (texture_count > 0) { upload_and_bind_textures(get_current_resource_storage().command_list.Get(), texture_count); for (unsigned i = 0; i < texture_count; i++) { ID3D12Resource *tex_resource; D3D12_SHADER_RESOURCE_VIEW_DESC srv; std::tie(tex_resource, srv) = m_current_shader_resources[i]; m_device->CreateShaderResourceView(tex_resource, &srv, CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetCPUDescriptorHandleForHeapStart()) .Offset((INT)currentDescriptorIndex + 3 + (INT)vertex_buffer_count + (INT)i, m_descriptor_stride_srv_cbv_uav) ); m_device->CreateSampler(&m_current_samplers[i], CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().sampler_descriptor_heap[get_current_resource_storage().sampler_descriptors_heap_index]->GetCPUDescriptorHandleForHeapStart()) .Offset((UINT)get_current_resource_storage().current_sampler_index + (UINT)i, m_descriptor_stride_samplers)); } get_current_resource_storage().command_list->SetGraphicsRootDescriptorTable(0, CD3DX12_GPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetGPUDescriptorHandleForHeapStart()) .Offset((INT)currentDescriptorIndex, m_descriptor_stride_srv_cbv_uav) ); get_current_resource_storage().command_list->SetGraphicsRootDescriptorTable(1, CD3DX12_GPU_DESCRIPTOR_HANDLE(get_current_resource_storage().sampler_descriptor_heap[get_current_resource_storage().sampler_descriptors_heap_index]->GetGPUDescriptorHandleForHeapStart()) .Offset((INT)get_current_resource_storage().current_sampler_index, m_descriptor_stride_samplers) ); get_current_resource_storage().current_sampler_index += std::get<2>(m_current_pso); get_current_resource_storage().descriptors_heap_index += std::get<2>(m_current_pso) + 3 + vertex_buffer_count; } else { get_current_resource_storage().command_list->SetGraphicsRootDescriptorTable(0, CD3DX12_GPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetGPUDescriptorHandleForHeapStart()) .Offset((INT)currentDescriptorIndex, m_descriptor_stride_srv_cbv_uav) ); get_current_resource_storage().descriptors_heap_index += 3 + vertex_buffer_count; } std::chrono::time_point<std::chrono::system_clock> texture_duration_end = std::chrono::system_clock::now(); m_timers.texture_duration += std::chrono::duration_cast<std::chrono::microseconds>(texture_duration_end - texture_duration_start).count(); set_rtt_and_ds(get_current_resource_storage().command_list.Get()); int clip_w = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16; int clip_h = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16; D3D12_VIEWPORT viewport = { 0.f, 0.f, (float)clip_w, (float)clip_h, (f32&)rsx::method_registers[NV4097_SET_CLIP_MIN], (f32&)rsx::method_registers[NV4097_SET_CLIP_MAX] }; get_current_resource_storage().command_list->RSSetViewports(1, &viewport); get_current_resource_storage().command_list->RSSetScissorRects(1, &get_scissor(rsx::method_registers[NV4097_SET_SCISSOR_HORIZONTAL], rsx::method_registers[NV4097_SET_SCISSOR_VERTICAL])); get_current_resource_storage().command_list->IASetPrimitiveTopology(get_primitive_topology(draw_mode)); if (indexed_draw) get_current_resource_storage().command_list->DrawIndexedInstanced((UINT)vertex_count, 1, 0, 0, 0); else get_current_resource_storage().command_list->DrawInstanced((UINT)vertex_count, 1, 0, 0); std::chrono::time_point<std::chrono::system_clock> end_duration = std::chrono::system_clock::now(); m_timers.draw_calls_duration += std::chrono::duration_cast<std::chrono::microseconds>(end_duration - start_duration).count(); m_timers.draw_calls_count++; if (rpcs3::config.rsx.d3d12.debug_output.value()) { 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(); } thread::end(); }
void D3D12GSRender::end() { std::chrono::time_point<steady_clock> start_duration = steady_clock::now(); std::chrono::time_point<steady_clock> rtt_duration_start = steady_clock::now(); prepare_render_targets(get_current_resource_storage().command_list.Get()); std::chrono::time_point<steady_clock> rtt_duration_end = steady_clock::now(); m_timers.prepare_rtt_duration += std::chrono::duration_cast<std::chrono::microseconds>(rtt_duration_end - rtt_duration_start).count(); std::chrono::time_point<steady_clock> vertex_index_duration_start = steady_clock::now(); size_t currentDescriptorIndex = get_current_resource_storage().descriptors_heap_index; size_t vertex_count; bool indexed_draw; std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC> vertex_buffer_views; std::tie(indexed_draw, vertex_count, vertex_buffer_views) = upload_and_set_vertex_index_data(get_current_resource_storage().command_list.Get()); UINT vertex_buffer_count = static_cast<UINT>(vertex_buffer_views.size()); std::chrono::time_point<steady_clock> vertex_index_duration_end = steady_clock::now(); m_timers.vertex_index_duration += std::chrono::duration_cast<std::chrono::microseconds>(vertex_index_duration_end - vertex_index_duration_start).count(); std::chrono::time_point<steady_clock> program_load_start = steady_clock::now(); load_program(); std::chrono::time_point<steady_clock> program_load_end = steady_clock::now(); m_timers.program_load_duration += std::chrono::duration_cast<std::chrono::microseconds>(program_load_end - program_load_start).count(); get_current_resource_storage().command_list->SetGraphicsRootSignature(m_shared_root_signature.Get()); get_current_resource_storage().command_list->OMSetStencilRef(rsx::method_registers.stencil_func_ref()); std::chrono::time_point<steady_clock> constants_duration_start = steady_clock::now(); INT offset = 0; for (const auto view : vertex_buffer_views) { m_device->CreateShaderResourceView(m_vertex_buffer_data.Get(), &view, CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetCPUDescriptorHandleForHeapStart()) .Offset((INT)currentDescriptorIndex + offset++, m_descriptor_stride_srv_cbv_uav)); } // Bind vertex buffer get_current_resource_storage().command_list->SetGraphicsRootDescriptorTable(VERTEX_BUFFERS_SLOT, CD3DX12_GPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetGPUDescriptorHandleForHeapStart()) .Offset((INT)currentDescriptorIndex, m_descriptor_stride_srv_cbv_uav) ); // Constants const D3D12_CONSTANT_BUFFER_VIEW_DESC &fragment_constant_view = upload_fragment_shader_constants(); get_current_resource_storage().command_list->SetGraphicsRootConstantBufferView(FRAGMENT_CONSTANT_BUFFERS_SLOT, fragment_constant_view.BufferLocation); upload_and_bind_scale_offset_matrix(currentDescriptorIndex + vertex_buffer_count); get_current_resource_storage().command_list->SetGraphicsRootDescriptorTable(SCALE_OFFSET_SLOT, CD3DX12_GPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetGPUDescriptorHandleForHeapStart()) .Offset((INT)currentDescriptorIndex + vertex_buffer_count, m_descriptor_stride_srv_cbv_uav) ); if (m_transform_constants_dirty && !g_cfg.video.debug_output) { m_current_transform_constants_buffer_descriptor_id = (u32)currentDescriptorIndex + 1 + vertex_buffer_count; upload_and_bind_vertex_shader_constants(currentDescriptorIndex + 1 + vertex_buffer_count); m_transform_constants_dirty = false; get_current_resource_storage().command_list->SetGraphicsRootDescriptorTable(VERTEX_CONSTANT_BUFFERS_SLOT, CD3DX12_GPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetGPUDescriptorHandleForHeapStart()) .Offset(m_current_transform_constants_buffer_descriptor_id, m_descriptor_stride_srv_cbv_uav) ); } std::chrono::time_point<steady_clock> constants_duration_end = steady_clock::now(); m_timers.constants_duration += std::chrono::duration_cast<std::chrono::microseconds>(constants_duration_end - constants_duration_start).count(); get_current_resource_storage().command_list->SetPipelineState(std::get<0>(m_current_pso).Get()); std::chrono::time_point<steady_clock> texture_duration_start = steady_clock::now(); get_current_resource_storage().descriptors_heap_index += 2 + vertex_buffer_count; size_t texture_count = std::get<2>(m_current_pso); if (texture_count > 0) { if (get_current_resource_storage().current_sampler_index + 16 > 2048) { get_current_resource_storage().sampler_descriptors_heap_index = 1; get_current_resource_storage().current_sampler_index = 0; ID3D12DescriptorHeap *descriptors[] = { get_current_resource_storage().descriptors_heap.Get(), get_current_resource_storage().sampler_descriptor_heap[get_current_resource_storage().sampler_descriptors_heap_index].Get(), }; get_current_resource_storage().command_list->SetDescriptorHeaps(2, descriptors); } upload_textures(get_current_resource_storage().command_list.Get(), texture_count); m_device->CopyDescriptorsSimple(16, CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetCPUDescriptorHandleForHeapStart()) .Offset((UINT)get_current_resource_storage().descriptors_heap_index, m_descriptor_stride_srv_cbv_uav), CD3DX12_CPU_DESCRIPTOR_HANDLE(m_current_texture_descriptors->GetCPUDescriptorHandleForHeapStart()), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV ); m_device->CopyDescriptorsSimple(16, CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().sampler_descriptor_heap[get_current_resource_storage().sampler_descriptors_heap_index]->GetCPUDescriptorHandleForHeapStart()) .Offset((UINT)get_current_resource_storage().current_sampler_index, m_descriptor_stride_samplers), CD3DX12_CPU_DESCRIPTOR_HANDLE(m_current_sampler_descriptors->GetCPUDescriptorHandleForHeapStart()), D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER ); get_current_resource_storage().command_list->SetGraphicsRootDescriptorTable(TEXTURES_SLOT, CD3DX12_GPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetGPUDescriptorHandleForHeapStart()) .Offset((INT)get_current_resource_storage().descriptors_heap_index, m_descriptor_stride_srv_cbv_uav) ); get_current_resource_storage().command_list->SetGraphicsRootDescriptorTable(SAMPLERS_SLOT, CD3DX12_GPU_DESCRIPTOR_HANDLE(get_current_resource_storage().sampler_descriptor_heap[get_current_resource_storage().sampler_descriptors_heap_index]->GetGPUDescriptorHandleForHeapStart()) .Offset((INT)get_current_resource_storage().current_sampler_index, m_descriptor_stride_samplers) ); get_current_resource_storage().current_sampler_index += texture_count; get_current_resource_storage().descriptors_heap_index += texture_count; } std::chrono::time_point<steady_clock> texture_duration_end = steady_clock::now(); m_timers.texture_duration += std::chrono::duration_cast<std::chrono::microseconds>(texture_duration_end - texture_duration_start).count(); set_rtt_and_ds(get_current_resource_storage().command_list.Get()); int clip_w = rsx::method_registers.surface_clip_width(); int clip_h = rsx::method_registers.surface_clip_height(); D3D12_VIEWPORT viewport = { 0.f, 0.f, (float)clip_w, (float)clip_h, rsx::method_registers.clip_min(), rsx::method_registers.clip_max(), }; get_current_resource_storage().command_list->RSSetViewports(1, &viewport); get_current_resource_storage().command_list->RSSetScissorRects(1, &get_scissor(rsx::method_registers.scissor_origin_x(), rsx::method_registers.scissor_origin_y(), rsx::method_registers.scissor_width(), rsx::method_registers.scissor_height())); get_current_resource_storage().command_list->IASetPrimitiveTopology(get_primitive_topology(rsx::method_registers.current_draw_clause.primitive)); if (indexed_draw) get_current_resource_storage().command_list->DrawIndexedInstanced((UINT)vertex_count, 1, 0, 0, 0); else get_current_resource_storage().command_list->DrawInstanced((UINT)vertex_count, 1, 0, 0); std::chrono::time_point<steady_clock> end_duration = steady_clock::now(); m_timers.draw_calls_duration += std::chrono::duration_cast<std::chrono::microseconds>(end_duration - start_duration).count(); m_timers.draw_calls_count++; if (g_cfg.video.debug_output) { 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(); } thread::end(); }