rsx: Res scaling improvements

- gl: Reintroduce the wcb hw downscaling
- rsx: Clamp scalable render target size with a config var
This commit is contained in:
kd-11 2017-10-03 14:38:00 +03:00
parent 3fe37ede97
commit fc0f98b5db
4 changed files with 47 additions and 11 deletions

View File

@ -179,8 +179,10 @@ namespace gl
glGenBuffers(1, &pbo_id); glGenBuffers(1, &pbo_id);
const u32 real_buffer_size = (u32)(rsx::get_resolution_scale() * rsx::get_resolution_scale() * cpu_address_range); const f32 resolution_scale = rsx::get_resolution_scale();
const u32 real_buffer_size = (resolution_scale < 1.f)? cpu_address_range: (u32)(resolution_scale * resolution_scale * cpu_address_range);
const u32 buffer_size = align(real_buffer_size, 4096); const u32 buffer_size = align(real_buffer_size, 4096);
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_id); glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_id);
glBufferStorage(GL_PIXEL_PACK_BUFFER, buffer_size, nullptr, GL_MAP_READ_BIT); glBufferStorage(GL_PIXEL_PACK_BUFFER, buffer_size, nullptr, GL_MAP_READ_BIT);
@ -202,7 +204,6 @@ namespace gl
is_depth = false; is_depth = false;
vram_texture = 0; vram_texture = 0;
scaled_texture = 0;
} }
void create(const u16 w, const u16 h, const u16 depth, const u16 mipmaps, void*, void create(const u16 w, const u16 h, const u16 depth, const u16 mipmaps, void*,
@ -275,7 +276,7 @@ namespace gl
} }
u32 target_texture = vram_texture; u32 target_texture = vram_texture;
if (0)//real_pitch != rsx_pitch || rsx::get_resolution_scale_percent() != 100) if (real_pitch != rsx_pitch || rsx::get_resolution_scale_percent() != 100)
{ {
//Disabled - doesnt work properly yet //Disabled - doesnt work properly yet
const u32 real_width = (rsx_pitch * width) / real_pitch; const u32 real_width = (rsx_pitch * width) / real_pitch;
@ -302,7 +303,6 @@ namespace gl
if ((u32)sw != real_width || (u32)sh != real_height || (GLenum)fmt != ifmt) if ((u32)sw != real_width || (u32)sh != real_height || (GLenum)fmt != ifmt)
{ {
LOG_ERROR(RSX, "Incompatible scaling texture found. Deleting...");
glDeleteTextures(1, &scaled_texture); glDeleteTextures(1, &scaled_texture);
scaled_texture = 0; scaled_texture = 0;
} }
@ -329,11 +329,37 @@ namespace gl
glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1);
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_id); glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_id);
glGetError();
if (get_driver_caps().EXT_dsa_supported) if (get_driver_caps().EXT_dsa_supported)
glGetTextureImageEXT(target_texture, GL_TEXTURE_2D, 0, (GLenum)format, (GLenum)type, nullptr); glGetTextureImageEXT(target_texture, GL_TEXTURE_2D, 0, (GLenum)format, (GLenum)type, nullptr);
else else
glGetTextureImage(target_texture, 0, (GLenum)format, (GLenum)type, pbo_size, nullptr); glGetTextureImage(target_texture, 0, (GLenum)format, (GLenum)type, pbo_size, nullptr);
if (GLenum err = glGetError())
{
bool recovered = false;
if (target_texture == scaled_texture)
{
if (get_driver_caps().EXT_dsa_supported)
glGetTextureImageEXT(vram_texture, GL_TEXTURE_2D, 0, (GLenum)format, (GLenum)type, nullptr);
else
glGetTextureImage(vram_texture, 0, (GLenum)format, (GLenum)type, pbo_size, nullptr);
if (!glGetError())
{
recovered = true;
const u32 min_dimension = cpu_address_range / rsx_pitch;
LOG_WARNING(RSX, "Failed to read back a scaled image, but the original texture can be read back. Consider setting min scalable dimension below or equal to %d", min_dimension);
}
}
if (!recovered && rsx::get_resolution_scale_percent() != 100)
{
LOG_ERROR(RSX, "Texture readback failed. Disable resolution scaling to get the 'Write Color Buffers' option to work properly");
}
}
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
m_fence.reset(); m_fence.reset();

View File

@ -809,7 +809,7 @@ namespace rsx
const auto window_origin = rsx::method_registers.shader_window_origin(); const auto window_origin = rsx::method_registers.shader_window_origin();
const u32 window_height = rsx::method_registers.shader_window_height(); const u32 window_height = rsx::method_registers.shader_window_height();
const f32 resolution_scale = rsx::get_resolution_scale(); const f32 resolution_scale = (window_height <= g_cfg.video.min_scalable_dimension)? 1.f : rsx::get_resolution_scale();
const f32 wpos_scale = (window_origin == rsx::window_origin::top) ? (1.f / resolution_scale) : (-1.f / resolution_scale); const f32 wpos_scale = (window_origin == rsx::window_origin::top) ? (1.f / resolution_scale) : (-1.f / resolution_scale);
const f32 wpos_bias = (window_origin == rsx::window_origin::top) ? 0.f : window_height; const f32 wpos_bias = (window_origin == rsx::window_origin::top) ? 0.f : window_height;

View File

@ -209,19 +209,21 @@ namespace rsx
return std::make_tuple(x, y, width, height); return std::make_tuple(x, y, width, height);
} }
static inline f32 get_resolution_scale() static inline const f32 get_resolution_scale()
{ {
return g_cfg.video.strict_rendering_mode? 1.f : ((f32)g_cfg.video.resolution_scale_percent / 100.f); return g_cfg.video.strict_rendering_mode? 1.f : ((f32)g_cfg.video.resolution_scale_percent / 100.f);
} }
static inline int get_resolution_scale_percent() static inline const int get_resolution_scale_percent()
{ {
return g_cfg.video.strict_rendering_mode ? 100 : g_cfg.video.resolution_scale_percent; return g_cfg.video.strict_rendering_mode ? 100 : g_cfg.video.resolution_scale_percent;
} }
static inline const u16 apply_resolution_scale(u16 value, bool clamp) static inline const u16 apply_resolution_scale(u16 value, bool clamp)
{ {
if (clamp) if (value <= g_cfg.video.min_scalable_dimension)
return value;
else if (clamp)
return (u16)std::max((get_resolution_scale_percent() * value) / 100, 1); return (u16)std::max((get_resolution_scale_percent() * value) / 100, 1);
else else
return (get_resolution_scale_percent() * value) / 100; return (get_resolution_scale_percent() * value) / 100;
@ -229,9 +231,16 @@ namespace rsx
static inline const u16 apply_inverse_resolution_scale(u16 value, bool clamp) static inline const u16 apply_inverse_resolution_scale(u16 value, bool clamp)
{ {
u16 result = value;
if (clamp) if (clamp)
return (u16)std::max((value * 100) / get_resolution_scale_percent(), 1); result = (u16)std::max((value * 100) / get_resolution_scale_percent(), 1);
else else
return (value * 100) / get_resolution_scale_percent(); result = (value * 100) / get_resolution_scale_percent();
if (result <= g_cfg.video.min_scalable_dimension)
return value;
return result;
} }
} }

View File

@ -333,6 +333,7 @@ struct cfg_root : cfg::node
cfg::_int<1, 8> consequtive_frames_to_skip{this, "Consecutive Frames To Skip", 1}; cfg::_int<1, 8> consequtive_frames_to_skip{this, "Consecutive Frames To Skip", 1};
cfg::_int<50, 800> resolution_scale_percent{this, "Resolution Scale", 100}; cfg::_int<50, 800> resolution_scale_percent{this, "Resolution Scale", 100};
cfg::_int<0, 16> anisotropic_level_override{this, "Anisotropic Filter Override", 0}; cfg::_int<0, 16> anisotropic_level_override{this, "Anisotropic Filter Override", 0};
cfg::_int<1, 1024> min_scalable_dimension{this, "Minimum Scalable Dimension", 128};
struct node_d3d12 : cfg::node struct node_d3d12 : cfg::node
{ {