[GPU] Mostly generic, not square-only resolution scaling

This commit is contained in:
Triang3l
2021-12-11 21:55:33 +03:00
parent e2da8597e1
commit 38b4741c8f
254 changed files with 86052 additions and 344263 deletions

View File

@@ -78,9 +78,9 @@ DEFINE_string(
" Choose what is considered the most optimal (currently \"on_copy\").",
"GPU");
DEFINE_int32(
draw_resolution_scale, 1,
"Integer pixel width and height scale used for scaling the rendering "
"resolution opaquely to the game.\n"
draw_resolution_scale_x, 1,
"Integer pixel width scale used for scaling the rendering resolution "
"opaquely to the game.\n"
"1, 2 and 3 may be supported, but support of anything above 1 depends on "
"the device properties, such as whether it supports sparse binding / tiled "
"resources, the number of virtual address bits per resource, and other "
@@ -90,6 +90,12 @@ DEFINE_int32(
"because half-pixel offset (which normally doesn't affect coverage when "
"MSAA isn't used) becomes full-pixel.",
"GPU");
DEFINE_int32(
draw_resolution_scale_y, 1,
"Integer pixel width scale used for scaling the rendering resolution "
"opaquely to the game.\n"
"See draw_resolution_scale_x for more information.",
"GPU");
DEFINE_bool(
draw_resolution_scaled_texture_offsets, true,
"Apply offsets from texture fetch instructions taking resolution scale "
@@ -396,7 +402,7 @@ bool RenderTargetCache::Update(bool is_rasterization_done,
uint32_t pitch_pixels_tile_aligned_scaled =
pitch_tiles_at_32bpp *
(xenos::kEdramTileWidthSamples >> msaa_samples_x_log2) *
GetResolutionScale();
GetResolutionScaleX();
uint32_t max_render_target_width = GetMaxRenderTargetWidth();
if (pitch_pixels_tile_aligned_scaled > max_render_target_width) {
// TODO(Triang3l): If really needed for some game on some device, clamp
@@ -855,14 +861,14 @@ uint32_t RenderTargetCache::GetRenderTargetHeight(
!(xenos::kTexture2DCubeMaxWidthHeight % xenos::kEdramTileHeightSamples),
"Maximum guest render target height is assumed to always be a multiple "
"of an EDRAM tile height");
uint32_t resolution_scale = GetResolutionScale();
uint32_t resolution_scale_y = GetResolutionScaleY();
uint32_t max_height_scaled =
std::min(xenos::kTexture2DCubeMaxWidthHeight * resolution_scale,
std::min(xenos::kTexture2DCubeMaxWidthHeight * resolution_scale_y,
GetMaxRenderTargetHeight());
uint32_t msaa_samples_y_log2 =
uint32_t(msaa_samples >= xenos::MsaaSamples::k2X);
uint32_t tile_height_samples_scaled =
xenos::kEdramTileHeightSamples * resolution_scale;
xenos::kEdramTileHeightSamples * resolution_scale_y;
tile_rows = std::min(tile_rows, (max_height_scaled << msaa_samples_y_log2) /
tile_height_samples_scaled);
assert_not_zero(tile_rows);
@@ -993,7 +999,7 @@ bool RenderTargetCache::PrepareHostRenderTargetsResolveClear(
uint32_t pitch_pixels =
pitch_tiles_at_32bpp *
(xenos::kEdramTileWidthSamples >> msaa_samples_x_log2);
uint32_t pitch_pixels_scaled = pitch_pixels * GetResolutionScale();
uint32_t pitch_pixels_scaled = pitch_pixels * GetResolutionScaleX();
uint32_t max_render_target_width = GetMaxRenderTargetWidth();
if (pitch_pixels_scaled > max_render_target_width) {
// TODO(Triang3l): If really needed for some game on some device, clamp the
@@ -1139,11 +1145,12 @@ RenderTargetCache::RenderTarget*
RenderTargetCache::PrepareFullEdram1280xRenderTargetForSnapshotRestoration(
xenos::ColorRenderTargetFormat color_format) {
assert_true(GetPath() == Path::kHostRenderTargets);
uint32_t resolution_scale = GetResolutionScale();
uint32_t resolution_scale_x = GetResolutionScaleX();
uint32_t resolution_scale_y = GetResolutionScaleY();
constexpr uint32_t kPitchTilesAt32bpp = 16;
constexpr uint32_t kWidth =
kPitchTilesAt32bpp * xenos::kEdramTileWidthSamples;
if (kWidth * resolution_scale > GetMaxRenderTargetWidth()) {
if (kWidth * resolution_scale_x > GetMaxRenderTargetWidth()) {
return nullptr;
}
// Same render target height is used for 32bpp and 64bpp to allow mixing them.
@@ -1159,7 +1166,7 @@ RenderTargetCache::PrepareFullEdram1280xRenderTargetForSnapshotRestoration(
"Using width of the render target for EDRAM snapshot restoration that is "
"expect to fully cover the EDRAM without exceeding the maximum guest "
"render target height.");
if (kHeight * resolution_scale > GetMaxRenderTargetHeight()) {
if (kHeight * resolution_scale_y > GetMaxRenderTargetHeight()) {
return nullptr;
}
RenderTargetKey render_target_key;