[D3D12] Apply half pixel offset through viewport, remove some 2560 references
This commit is contained in:
parent
6d0e4787fb
commit
4631b2b16c
|
@ -1124,9 +1124,9 @@ bool CommandProcessor::ExecutePacketType3_EVENT_WRITE_EXT(RingBuffer* reader,
|
||||||
// https://www.google.com/patents/US20060055701
|
// https://www.google.com/patents/US20060055701
|
||||||
uint16_t extents[] = {
|
uint16_t extents[] = {
|
||||||
0 >> 3, // min x
|
0 >> 3, // min x
|
||||||
2560 >> 3, // max x
|
8192 >> 3, // max x
|
||||||
0 >> 3, // min y
|
0 >> 3, // min y
|
||||||
2560 >> 3, // max y
|
8192 >> 3, // max y
|
||||||
0, // min z
|
0, // min z
|
||||||
1, // max z
|
1, // max z
|
||||||
};
|
};
|
||||||
|
|
|
@ -2182,11 +2182,11 @@ void D3D12CommandProcessor::UpdateFixedFunctionState(bool primitive_two_faced) {
|
||||||
float viewport_scale_x =
|
float viewport_scale_x =
|
||||||
pa_cl_vte_cntl.vport_x_scale_ena
|
pa_cl_vte_cntl.vport_x_scale_ena
|
||||||
? std::abs(regs[XE_GPU_REG_PA_CL_VPORT_XSCALE].f32)
|
? std::abs(regs[XE_GPU_REG_PA_CL_VPORT_XSCALE].f32)
|
||||||
: 1280.0f;
|
: 4096.0f;
|
||||||
float viewport_scale_y =
|
float viewport_scale_y =
|
||||||
pa_cl_vte_cntl.vport_y_scale_ena
|
pa_cl_vte_cntl.vport_y_scale_ena
|
||||||
? std::abs(regs[XE_GPU_REG_PA_CL_VPORT_YSCALE].f32)
|
? 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
|
float viewport_scale_z = pa_cl_vte_cntl.vport_z_scale_ena
|
||||||
? regs[XE_GPU_REG_PA_CL_VPORT_ZSCALE].f32
|
? regs[XE_GPU_REG_PA_CL_VPORT_ZSCALE].f32
|
||||||
: 1.0f;
|
: 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_x += float(pa_sc_window_offset.window_x_offset);
|
||||||
viewport_offset_y += float(pa_sc_window_offset.window_y_offset);
|
viewport_offset_y += float(pa_sc_window_offset.window_y_offset);
|
||||||
}
|
}
|
||||||
|
if (cvars::d3d12_half_pixel_offset &&
|
||||||
|
!regs.Get<reg::PA_SU_VTX_CNTL>().pix_center) {
|
||||||
|
viewport_offset_x += 0.5f;
|
||||||
|
viewport_offset_y += 0.5f;
|
||||||
|
}
|
||||||
D3D12_VIEWPORT viewport;
|
D3D12_VIEWPORT viewport;
|
||||||
viewport.TopLeftX =
|
viewport.TopLeftX =
|
||||||
(viewport_offset_x - viewport_scale_x) * float(pixel_size_x);
|
(viewport_offset_x - viewport_scale_x) * float(pixel_size_x);
|
||||||
|
@ -2318,7 +2323,6 @@ void D3D12CommandProcessor::UpdateSystemConstantValues(
|
||||||
auto pa_su_point_minmax = regs.Get<reg::PA_SU_POINT_MINMAX>();
|
auto pa_su_point_minmax = regs.Get<reg::PA_SU_POINT_MINMAX>();
|
||||||
auto pa_su_point_size = regs.Get<reg::PA_SU_POINT_SIZE>();
|
auto pa_su_point_size = regs.Get<reg::PA_SU_POINT_SIZE>();
|
||||||
auto pa_su_sc_mode_cntl = regs.Get<reg::PA_SU_SC_MODE_CNTL>();
|
auto pa_su_sc_mode_cntl = regs.Get<reg::PA_SU_SC_MODE_CNTL>();
|
||||||
auto pa_su_vtx_cntl = regs.Get<reg::PA_SU_VTX_CNTL>();
|
|
||||||
float rb_alpha_ref = regs[XE_GPU_REG_RB_ALPHA_REF].f32;
|
float rb_alpha_ref = regs[XE_GPU_REG_RB_ALPHA_REF].f32;
|
||||||
auto rb_colorcontrol = regs.Get<reg::RB_COLORCONTROL>();
|
auto rb_colorcontrol = regs.Get<reg::RB_COLORCONTROL>();
|
||||||
auto rb_depth_info = regs.Get<reg::RB_DEPTH_INFO>();
|
auto rb_depth_info = regs.Get<reg::RB_DEPTH_INFO>();
|
||||||
|
@ -2526,10 +2530,10 @@ void D3D12CommandProcessor::UpdateSystemConstantValues(
|
||||||
// Conversion to Direct3D 12 normalized device coordinates.
|
// Conversion to Direct3D 12 normalized device coordinates.
|
||||||
// See viewport configuration in UpdateFixedFunctionState for explanations.
|
// See viewport configuration in UpdateFixedFunctionState for explanations.
|
||||||
// X and Y scale/offset is to convert unnormalized coordinates generated by
|
// X and Y scale/offset is to convert unnormalized coordinates generated by
|
||||||
// shaders (for rectangle list drawing, for instance) to the 2560x2560
|
// shaders (for rectangle list drawing, for instance) to the 8192x8192
|
||||||
// viewport that is used to emulate unnormalized coordinates.
|
// viewport (the maximum render target size) that is used to emulate
|
||||||
// Z scale/offset is to convert from OpenGL NDC to Direct3D NDC if needed.
|
// unnormalized coordinates. Z scale/offset is to convert from OpenGL NDC to
|
||||||
// Also apply half-pixel offset to reproduce Direct3D 9 rasterization rules.
|
// Direct3D NDC if needed.
|
||||||
float viewport_scale_x = regs[XE_GPU_REG_PA_CL_VPORT_XSCALE].f32;
|
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;
|
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
|
// 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;
|
!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
|
float ndc_scale_x = pa_cl_vte_cntl.vport_x_scale_ena
|
||||||
? (viewport_scale_x >= 0.0f ? 1.0f : -1.0f)
|
? (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
|
float ndc_scale_y = pa_cl_vte_cntl.vport_y_scale_ena
|
||||||
? (viewport_scale_y >= 0.0f ? -1.0f : 1.0f)
|
? (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_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_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_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;
|
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[0] != ndc_scale_x;
|
||||||
dirty |= system_constants_.ndc_scale[1] != ndc_scale_y;
|
dirty |= system_constants_.ndc_scale[1] != ndc_scale_y;
|
||||||
dirty |= system_constants_.ndc_scale[2] != ndc_scale_z;
|
dirty |= system_constants_.ndc_scale[2] != ndc_scale_z;
|
||||||
|
@ -2617,13 +2603,13 @@ void D3D12CommandProcessor::UpdateSystemConstantValues(
|
||||||
point_screen_to_ndc_x =
|
point_screen_to_ndc_x =
|
||||||
(viewport_scale_x != 0.0f) ? (0.5f / viewport_scale_x) : 0.0f;
|
(viewport_scale_x != 0.0f) ? (0.5f / viewport_scale_x) : 0.0f;
|
||||||
} else {
|
} 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) {
|
if (pa_cl_vte_cntl.vport_y_scale_ena) {
|
||||||
point_screen_to_ndc_y =
|
point_screen_to_ndc_y =
|
||||||
(viewport_scale_y != 0.0f) ? (-0.5f / viewport_scale_y) : 0.0f;
|
(viewport_scale_y != 0.0f) ? (-0.5f / viewport_scale_y) : 0.0f;
|
||||||
} else {
|
} 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[0] != point_screen_to_ndc_x;
|
||||||
dirty |= system_constants_.point_screen_to_ndc[1] != point_screen_to_ndc_y;
|
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.
|
// EDRAM pitch for ROV writing.
|
||||||
if (edram_rov_used_) {
|
if (edram_rov_used_) {
|
||||||
uint32_t edram_pitch_tiles =
|
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)) +
|
(rb_surface_info.msaa_samples >= MsaaSamples::k4X ? 2 : 1)) +
|
||||||
79) /
|
79) /
|
||||||
80;
|
80;
|
||||||
|
|
Loading…
Reference in New Issue