From 4631b2b16ccb9ea6a1f486ed74afd92a7e4f68c5 Mon Sep 17 00:00:00 2001 From: Triang3l Date: Mon, 11 May 2020 20:37:02 +0300 Subject: [PATCH] [D3D12] Apply half pixel offset through viewport, remove some 2560 references --- src/xenia/gpu/command_processor.cc | 4 +- .../gpu/d3d12/d3d12_command_processor.cc | 46 +++++++------------ 2 files changed, 18 insertions(+), 32 deletions(-) diff --git a/src/xenia/gpu/command_processor.cc b/src/xenia/gpu/command_processor.cc index e5700e1de..d2be4ded5 100644 --- a/src/xenia/gpu/command_processor.cc +++ b/src/xenia/gpu/command_processor.cc @@ -1124,9 +1124,9 @@ bool CommandProcessor::ExecutePacketType3_EVENT_WRITE_EXT(RingBuffer* reader, // https://www.google.com/patents/US20060055701 uint16_t extents[] = { 0 >> 3, // min x - 2560 >> 3, // max x + 8192 >> 3, // max x 0 >> 3, // min y - 2560 >> 3, // max y + 8192 >> 3, // max y 0, // min z 1, // max z }; diff --git a/src/xenia/gpu/d3d12/d3d12_command_processor.cc b/src/xenia/gpu/d3d12/d3d12_command_processor.cc index 29bb913a5..be889cea0 100644 --- a/src/xenia/gpu/d3d12/d3d12_command_processor.cc +++ b/src/xenia/gpu/d3d12/d3d12_command_processor.cc @@ -2182,11 +2182,11 @@ void D3D12CommandProcessor::UpdateFixedFunctionState(bool primitive_two_faced) { float viewport_scale_x = pa_cl_vte_cntl.vport_x_scale_ena ? std::abs(regs[XE_GPU_REG_PA_CL_VPORT_XSCALE].f32) - : 1280.0f; + : 4096.0f; float viewport_scale_y = pa_cl_vte_cntl.vport_y_scale_ena ? std::abs(regs[XE_GPU_REG_PA_CL_VPORT_YSCALE].f32) - : 1280.0f; + : 4096.0f; float viewport_scale_z = pa_cl_vte_cntl.vport_z_scale_ena ? regs[XE_GPU_REG_PA_CL_VPORT_ZSCALE].f32 : 1.0f; @@ -2203,6 +2203,11 @@ void D3D12CommandProcessor::UpdateFixedFunctionState(bool primitive_two_faced) { viewport_offset_x += float(pa_sc_window_offset.window_x_offset); viewport_offset_y += float(pa_sc_window_offset.window_y_offset); } + if (cvars::d3d12_half_pixel_offset && + !regs.Get().pix_center) { + viewport_offset_x += 0.5f; + viewport_offset_y += 0.5f; + } D3D12_VIEWPORT viewport; viewport.TopLeftX = (viewport_offset_x - viewport_scale_x) * float(pixel_size_x); @@ -2318,7 +2323,6 @@ void D3D12CommandProcessor::UpdateSystemConstantValues( auto pa_su_point_minmax = regs.Get(); auto pa_su_point_size = regs.Get(); auto pa_su_sc_mode_cntl = regs.Get(); - auto pa_su_vtx_cntl = regs.Get(); float rb_alpha_ref = regs[XE_GPU_REG_RB_ALPHA_REF].f32; auto rb_colorcontrol = regs.Get(); auto rb_depth_info = regs.Get(); @@ -2526,10 +2530,10 @@ void D3D12CommandProcessor::UpdateSystemConstantValues( // Conversion to Direct3D 12 normalized device coordinates. // See viewport configuration in UpdateFixedFunctionState for explanations. // X and Y scale/offset is to convert unnormalized coordinates generated by - // shaders (for rectangle list drawing, for instance) to the 2560x2560 - // viewport that is used to emulate unnormalized coordinates. - // Z scale/offset is to convert from OpenGL NDC to Direct3D NDC if needed. - // Also apply half-pixel offset to reproduce Direct3D 9 rasterization rules. + // shaders (for rectangle list drawing, for instance) to the 8192x8192 + // viewport (the maximum render target size) that is used to emulate + // unnormalized coordinates. Z scale/offset is to convert from OpenGL NDC to + // Direct3D NDC if needed. float viewport_scale_x = regs[XE_GPU_REG_PA_CL_VPORT_XSCALE].f32; float viewport_scale_y = regs[XE_GPU_REG_PA_CL_VPORT_YSCALE].f32; // Kill all primitives if multipass or both faces are culled, but still need @@ -2559,32 +2563,14 @@ void D3D12CommandProcessor::UpdateSystemConstantValues( !pa_cl_clip_cntl.dx_clip_space_def && pa_cl_vte_cntl.vport_z_scale_ena; float ndc_scale_x = pa_cl_vte_cntl.vport_x_scale_ena ? (viewport_scale_x >= 0.0f ? 1.0f : -1.0f) - : (1.0f / 1280.0f); + : (1.0f / 4096.0f); float ndc_scale_y = pa_cl_vte_cntl.vport_y_scale_ena ? (viewport_scale_y >= 0.0f ? -1.0f : 1.0f) - : (-1.0f / 1280.0f); + : (-1.0f / 4096.0f); float ndc_scale_z = gl_clip_space_def ? 0.5f : 1.0f; float ndc_offset_x = pa_cl_vte_cntl.vport_x_offset_ena ? 0.0f : -1.0f; float ndc_offset_y = pa_cl_vte_cntl.vport_y_offset_ena ? 0.0f : 1.0f; float ndc_offset_z = gl_clip_space_def ? 0.5f : 0.0f; - if (cvars::d3d12_half_pixel_offset && !pa_su_vtx_cntl.pix_center) { - // Signs are hopefully correct here, tested in GTA IV on both clearing - // (without a viewport) and drawing things near the edges of the screen. - if (pa_cl_vte_cntl.vport_x_scale_ena) { - if (viewport_scale_x != 0.0f) { - ndc_offset_x += 0.5f / viewport_scale_x; - } - } else { - ndc_offset_x += 1.0f / 2560.0f; - } - if (pa_cl_vte_cntl.vport_y_scale_ena) { - if (viewport_scale_y != 0.0f) { - ndc_offset_y += 0.5f / viewport_scale_y; - } - } else { - ndc_offset_y -= 1.0f / 2560.0f; - } - } dirty |= system_constants_.ndc_scale[0] != ndc_scale_x; dirty |= system_constants_.ndc_scale[1] != ndc_scale_y; dirty |= system_constants_.ndc_scale[2] != ndc_scale_z; @@ -2617,13 +2603,13 @@ void D3D12CommandProcessor::UpdateSystemConstantValues( point_screen_to_ndc_x = (viewport_scale_x != 0.0f) ? (0.5f / viewport_scale_x) : 0.0f; } else { - point_screen_to_ndc_x = 1.0f / 2560.0f; + point_screen_to_ndc_x = 1.0f / 8192.0f; } if (pa_cl_vte_cntl.vport_y_scale_ena) { point_screen_to_ndc_y = (viewport_scale_y != 0.0f) ? (-0.5f / viewport_scale_y) : 0.0f; } else { - point_screen_to_ndc_y = -1.0f / 2560.0f; + point_screen_to_ndc_y = -1.0f / 8192.0f; } dirty |= system_constants_.point_screen_to_ndc[0] != point_screen_to_ndc_x; dirty |= system_constants_.point_screen_to_ndc[1] != point_screen_to_ndc_y; @@ -2654,7 +2640,7 @@ void D3D12CommandProcessor::UpdateSystemConstantValues( // EDRAM pitch for ROV writing. if (edram_rov_used_) { uint32_t edram_pitch_tiles = - ((std::min(rb_surface_info.surface_pitch, 2560u) * + ((rb_surface_info.surface_pitch * (rb_surface_info.msaa_samples >= MsaaSamples::k4X ? 2 : 1)) + 79) / 80;