gpu: apply the half-pixel offset in host pixels under resolution scaling to fix resolve-boundary seams
This commit is contained in:
parent
f00a126494
commit
fb392e48f6
1 changed files with 28 additions and 3 deletions
|
|
@ -28,6 +28,13 @@
|
||||||
|
|
||||||
REXCVAR_DEFINE_BOOL(half_pixel_offset, true, "GPU", "Enable half pixel offset");
|
REXCVAR_DEFINE_BOOL(half_pixel_offset, true, "GPU", "Enable half pixel offset");
|
||||||
|
|
||||||
|
REXCVAR_DEFINE_BOOL(draw_resolution_scaled_half_pixel_offset, true, "GPU",
|
||||||
|
"With resolution scaling, apply the Direct3D 9 half-pixel offset as half a "
|
||||||
|
"host pixel instead of half a guest pixel. Keeps the first host row and "
|
||||||
|
"column of every render target region covered, so scaled resolves need no "
|
||||||
|
"edge fill and resolve boundaries inside the frame (predicated tiling "
|
||||||
|
"splits) show no seam.");
|
||||||
|
|
||||||
REXCVAR_DEFINE_BOOL(resolve_resolution_scale_fill_half_pixel_offset, true, "GPU",
|
REXCVAR_DEFINE_BOOL(resolve_resolution_scale_fill_half_pixel_offset, true, "GPU",
|
||||||
"Fill half pixel offset during resolution scale resolve");
|
"Fill half pixel offset during resolution scale resolve");
|
||||||
|
|
||||||
|
|
@ -323,9 +330,24 @@ void GetHostViewportInfo(const RegisterFile& regs, uint32_t draw_resolution_scal
|
||||||
offset_add_xy[1] += float(pa_sc_window_offset.window_y_offset);
|
offset_add_xy[1] += float(pa_sc_window_offset.window_y_offset);
|
||||||
}
|
}
|
||||||
if (REXCVAR_GET(half_pixel_offset) && pa_su_vtx_cntl.pix_center == xenos::PixelCenter::kD3DZero) {
|
if (REXCVAR_GET(half_pixel_offset) && pa_su_vtx_cntl.pix_center == xenos::PixelCenter::kD3DZero) {
|
||||||
|
if (REXCVAR_GET(draw_resolution_scaled_half_pixel_offset) &&
|
||||||
|
(draw_resolution_scale_x > 1 || draw_resolution_scale_y > 1)) {
|
||||||
|
// Half a HOST pixel, expressed in guest units. A half-guest-pixel offset
|
||||||
|
// becomes one or more whole host pixels under resolution scaling,
|
||||||
|
// pushing all coverage off the first host row/column of every render
|
||||||
|
// target region; resolves then have to fill the uncovered edge by
|
||||||
|
// duplicating the adjacent row/column, which shows as a seam wherever a
|
||||||
|
// resolve boundary crosses the frame interior (predicated tiling
|
||||||
|
// splits the scene into multiple EDRAM tiles). Half a host pixel keeps
|
||||||
|
// the Direct3D 9 rasterization convention with every host pixel still
|
||||||
|
// covered, so no fill is needed.
|
||||||
|
offset_add_xy[0] += 0.5f / float(draw_resolution_scale_x);
|
||||||
|
offset_add_xy[1] += 0.5f / float(draw_resolution_scale_y);
|
||||||
|
} else {
|
||||||
offset_add_xy[0] += 0.5f;
|
offset_add_xy[0] += 0.5f;
|
||||||
offset_add_xy[1] += 0.5f;
|
offset_add_xy[1] += 0.5f;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The maximum value is at least the maximum host render target size anyway -
|
// The maximum value is at least the maximum host render target size anyway -
|
||||||
// and a guest pixel is always treated as a whole with resolution scaling.
|
// and a guest pixel is always treated as a whole with resolution scaling.
|
||||||
|
|
@ -1026,11 +1048,14 @@ bool GetResolveInfo(const RegisterFile& regs, const memory::Memory& memory,
|
||||||
uint32_t edram_base_offset_tiles =
|
uint32_t edram_base_offset_tiles =
|
||||||
base_offset_y_tiles * surface_pitch_tiles + base_offset_x_tiles;
|
base_offset_y_tiles * surface_pitch_tiles + base_offset_x_tiles;
|
||||||
|
|
||||||
// Write the color/depth EDRAM info.
|
// Write the color/depth EDRAM info. With the host-pixel offset mode there
|
||||||
|
// is no coverage gap along resolve region edges, and filling would instead
|
||||||
|
// overwrite valid pixels with their neighbors.
|
||||||
bool fill_half_pixel_offset =
|
bool fill_half_pixel_offset =
|
||||||
(draw_resolution_scale_x > 1 || draw_resolution_scale_y > 1) &&
|
(draw_resolution_scale_x > 1 || draw_resolution_scale_y > 1) &&
|
||||||
REXCVAR_GET(resolve_resolution_scale_fill_half_pixel_offset) &&
|
REXCVAR_GET(resolve_resolution_scale_fill_half_pixel_offset) &&
|
||||||
REXCVAR_GET(half_pixel_offset) &&
|
REXCVAR_GET(half_pixel_offset) &&
|
||||||
|
!REXCVAR_GET(draw_resolution_scaled_half_pixel_offset) &&
|
||||||
regs.Get<reg::PA_SU_VTX_CNTL>().pix_center == xenos::PixelCenter::kD3DZero;
|
regs.Get<reg::PA_SU_VTX_CNTL>().pix_center == xenos::PixelCenter::kD3DZero;
|
||||||
int32_t exp_bias = is_depth ? 0 : rb_copy_dest_info.copy_dest_exp_bias;
|
int32_t exp_bias = is_depth ? 0 : rb_copy_dest_info.copy_dest_exp_bias;
|
||||||
ResolveEdramInfo depth_edram_info;
|
ResolveEdramInfo depth_edram_info;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue