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 nv4097_clear_surface(u32 arg, GLGSRender* renderer) { if (rsx::method_registers.surface_color_target() == rsx::surface_target::none) return; if ((arg & 0xf3) == 0) { //do nothing return; } renderer->init_buffers(true); renderer->draw_fbo.bind(); GLbitfield mask = 0; rsx::surface_depth_format surface_depth_format = rsx::method_registers.surface_depth_fmt(); if (arg & 0x1) { u32 max_depth_value = get_max_depth_value(surface_depth_format); u32 clear_depth = rsx::method_registers.z_clear_value(); glDepthMask(GL_TRUE); glClearDepth(double(clear_depth) / max_depth_value); mask |= GLenum(gl::buffers::depth); } if (surface_depth_format == rsx::surface_depth_format::z24s8 && (arg & 0x2)) { u8 clear_stencil = rsx::method_registers.stencil_clear_value(); __glcheck glStencilMask(rsx::method_registers.stencil_mask()); glClearStencil(clear_stencil); mask |= GLenum(gl::buffers::stencil); } if (arg & 0xf0) { u8 clear_a = rsx::method_registers.clear_color_a(); u8 clear_r = rsx::method_registers.clear_color_r(); u8 clear_g = rsx::method_registers.clear_color_g(); u8 clear_b = rsx::method_registers.clear_color_b(); glColorMask(((arg & 0x20) ? 1 : 0), ((arg & 0x40) ? 1 : 0), ((arg & 0x80) ? 1 : 0), ((arg & 0x10) ? 1 : 0)); glClearColor(clear_r / 255.f, clear_g / 255.f, clear_b / 255.f, clear_a / 255.f); mask |= GLenum(gl::buffers::color); } glClear(mask); renderer->write_buffers(); }
void GLGSRender::clear_surface(u32 arg) { if (skip_frame || !framebuffer_status_valid) return; if (rsx::method_registers.surface_color_target() == rsx::surface_target::none) return; if ((arg & 0xf3) == 0) return; GLbitfield mask = 0; rsx::surface_depth_format surface_depth_format = rsx::method_registers.surface_depth_fmt(); if (arg & 0x1) { u32 max_depth_value = get_max_depth_value(surface_depth_format); u32 clear_depth = rsx::method_registers.z_clear_value(surface_depth_format == rsx::surface_depth_format::z24s8); gl_state.depth_mask(GL_TRUE); gl_state.clear_depth(f32(clear_depth) / max_depth_value); mask |= GLenum(gl::buffers::depth); gl::render_target *ds = std::get<1>(m_rtts.m_bound_depth_stencil); if (ds && !ds->cleared()) { ds->set_cleared(); ds->old_contents = nullptr; } } if (surface_depth_format == rsx::surface_depth_format::z24s8 && (arg & 0x2)) { u8 clear_stencil = rsx::method_registers.stencil_clear_value(); gl_state.stencil_mask(rsx::method_registers.stencil_mask()); gl_state.clear_stencil(clear_stencil); mask |= GLenum(gl::buffers::stencil); } if (arg & 0xf0) { u8 clear_a = rsx::method_registers.clear_color_a(); u8 clear_r = rsx::method_registers.clear_color_r(); u8 clear_g = rsx::method_registers.clear_color_g(); u8 clear_b = rsx::method_registers.clear_color_b(); gl_state.color_mask(arg & 0xf0); gl_state.clear_color(clear_r, clear_g, clear_b, clear_a); mask |= GLenum(gl::buffers::color); for (auto &rtt : m_rtts.m_bound_render_targets) { if (std::get<0>(rtt) != 0) { std::get<1>(rtt)->set_cleared(true); std::get<1>(rtt)->old_contents = nullptr; } } } glClear(mask); }