rsx/gl: Implement resolution scaling

rsx: Revise wpos calculation to take resolution scale into account
This commit is contained in:
kd-11 2017-09-26 16:24:43 +03:00
parent 47202d5839
commit 12ab03b0b5
14 changed files with 202 additions and 98 deletions

View File

@ -731,9 +731,9 @@ struct area_base
{
return{ x1 * size.width, y1 * size.height, x2 * size.width, y2 * size.height };
}
constexpr area_base operator * (const T& value) const
constexpr area_base operator * (const f32& value) const
{
return{ x1 * value, y1 * value, x2 * value, y2 * value };
return{ (T)(x1 * value), (T)(y1 * value), (T)(x2 * value), (T)(y2 * value) };
}
template<typename NT>

View File

@ -338,6 +338,12 @@ namespace glsl
OS << "{\n";
OS << " return decodeLinearDepth(texture(tex, coord.xy).r);\n";
OS << "}\n\n";
OS << "vec4 get_wpos()\n";
OS << "{\n";
OS << " float abs_scale = abs(wpos_scale);\n";
OS << " return (gl_FragCoord * vec4(abs_scale, wpos_scale, 1., 1.)) + vec4(0., wpos_bias, 0., 0.);\n";
OS << "}\n\n";
}
static void insert_fog_declaration(std::ostream& OS)

View File

@ -167,6 +167,9 @@ public:
f32 fp_value;
};
program_buffer_patch_entry()
{}
program_buffer_patch_entry(f32& key, f32& value)
{
fp_key = key;
@ -178,25 +181,43 @@ public:
hex_key = key;
hex_value = value;
}
bool test_and_set(f32 value, f32* dst) const
{
u32 hex = (u32&)value;
if ((hex & 0x7FFFFFFF) == (hex_key & 0x7FFFFFFF))
{
hex = (hex & ~0x7FFFFFF) | hex_value;
*dst = (f32&)hex;
return true;
}
return false;
}
};
struct
{
std::vector<program_buffer_patch_entry> keys;
std::unordered_map<f32, program_buffer_patch_entry> db;
void add(program_buffer_patch_entry& e)
{
keys.push_back(e);
db[e.fp_key] = e;
}
void add(f32& key, f32& value)
{
db[key] = { key, value };
}
void clear()
{
keys.resize(0);
db.clear();
}
bool is_empty() const
{
return keys.size() == 0;
return db.size() == 0;
}
}
patch_table;
@ -287,49 +308,43 @@ public:
verify(HERE), (dst_buffer.size_bytes() >= ::narrow<int>(I->second.FragmentConstantOffsetCache.size()) * 16);
size_t offset = 0;
if (patch_table.is_empty())
f32* dst = dst_buffer.data();
f32 tmp[4];
for (size_t offset_in_fragment_program : I->second.FragmentConstantOffsetCache)
{
for (size_t offset_in_fragment_program : I->second.FragmentConstantOffsetCache)
void *data = (char*)fragment_program.addr + (u32)offset_in_fragment_program;
const __m128i &vector = _mm_loadu_si128((__m128i*)data);
const __m128i &shuffled_vector = _mm_shuffle_epi8(vector, mask);
if (!patch_table.is_empty())
{
void *data = (char*)fragment_program.addr + (u32)offset_in_fragment_program;
const __m128i &vector = _mm_loadu_si128((__m128i*)data);
const __m128i &shuffled_vector = _mm_shuffle_epi8(vector, mask);
_mm_stream_si128((__m128i*)dst_buffer.subspan(offset, 4).data(), shuffled_vector);
offset += 4;
}
}
else
{
for (size_t offset_in_fragment_program : I->second.FragmentConstantOffsetCache)
{
void *data = (char*)fragment_program.addr + (u32)offset_in_fragment_program;
f32* src = (f32*)data;
f32* dst = dst_buffer.subspan(offset, 4).data();
_mm_storeu_ps(tmp, (__m128&)shuffled_vector);
bool patched;
for (int i = 0; i < 4; ++i)
{
patched = false;
for (auto& e : patch_table.keys)
for (auto& e : patch_table.db)
{
//TODO: Use fp comparison with fabsf without hurting performance
if (e.hex_key == (u32&)src[i])
if (patched = e.second.test_and_set(tmp[i], &dst[i]))
{
dst[i] = e.fp_value;
patched = true;
break;
}
}
if (!patched)
{
dst[i] = src[i];
dst[i] = tmp[i];
}
}
offset += 4;
}
else
{
_mm_stream_si128((__m128i*)dst, shuffled_vector);
}
dst += 4;
}
}

View File

@ -856,13 +856,14 @@ namespace rsx
return rsc.surface->get_view();
}
else
return create_temporary_subresource_view(cmd, rsc.surface, format, rsc.x, rsc.y, rsc.w, rsc.h);
else return create_temporary_subresource_view(cmd, rsc.surface, format, rsx::apply_resolution_scale(rsc.x, false), rsx::apply_resolution_scale(rsc.y, false),
rsx::apply_resolution_scale(rsc.w, true), rsx::apply_resolution_scale(rsc.h, true));
}
else
{
LOG_WARNING(RSX, "Attempting to sample a currently bound render target @ 0x%x", texaddr);
return create_temporary_subresource_view(cmd, rsc.surface, format, rsc.x, rsc.y, rsc.w, rsc.h);
return create_temporary_subresource_view(cmd, rsc.surface, format, rsx::apply_resolution_scale(rsc.x, false), rsx::apply_resolution_scale(rsc.y, false),
rsx::apply_resolution_scale(rsc.w, true), rsx::apply_resolution_scale(rsc.h, true));
}
}
}
@ -1198,6 +1199,13 @@ namespace rsx
default_remap_vector)->get_raw_texture();
}
const f32 scale = rsx::get_resolution_scale();
if (src_is_render_target)
src_area = src_area * scale;
if (dst_is_render_target)
dst_area = dst_area * scale;
blitter.scale_image(vram_texture, dest_texture, src_area, dst_area, interpolate, is_depth_blit);
return true;
}

View File

@ -46,8 +46,8 @@ void D3D12FragmentDecompiler::insertHeader(std::stringstream & OS)
OS << " float alpha_ref;\n";
OS << " uint alpha_func;\n";
OS << " uint fog_mode;\n";
OS << " uint window_origin;\n";
OS << " uint window_height;\n";
OS << " float wpos_scale;\n";
OS << " float wpos_bias;\n";
OS << " float4 texture_parameters[16];\n";
OS << "};\n";
}
@ -224,8 +224,10 @@ void D3D12FragmentDecompiler::insertMainStart(std::stringstream & OS)
}
}
//NOTE: Framebuffer scaling not actually supported. wpos_scale is used to reconstruct the true window height
OS << " float4 wpos = In.Position;\n";
OS << " if (window_origin != 0) wpos.y = window_height - wpos.y;\n";
OS << " float4 res_scale = abs(1.f / wpos_scale);\n";
OS << " if (wpos_scale < 0) wpos.y = (wpos_bias * res_scale) - wpos.y;\n";
OS << " float4 ssa = is_front_face ? float4(1., 1., 1., 1.) : float4(-1., -1., -1., -1.);\n";
// Declare output

View File

@ -154,8 +154,8 @@ void GLFragmentDecompilerThread::insertConstants(std::stringstream & OS)
OS << " float alpha_ref;\n";
OS << " uint alpha_func;\n";
OS << " uint fog_mode;\n";
OS << " uint window_origin;\n";
OS << " uint window_height;\n";
OS << " float wpos_scale;\n";
OS << " float wpos_bias;\n";
OS << " vec4 texture_parameters[16];\n"; //sampling: x,y scaling and (unused) offsets data
OS << "};\n";
}
@ -251,8 +251,7 @@ void GLFragmentDecompilerThread::insertMainStart(std::stringstream & OS)
}
OS << " vec4 ssa = gl_FrontFacing ? vec4(1.) : vec4(-1.);\n";
OS << " vec4 wpos = gl_FragCoord;\n";
OS << " if (window_origin != 0) wpos.y = window_height - wpos.y;\n";
OS << " vec4 wpos = get_wpos();\n";
for (const ParamType& PT : m_parr.params[PF_PARAM_UNIFORM])
{

View File

@ -589,14 +589,14 @@ void GLGSRender::end()
void GLGSRender::set_viewport()
{
//NOTE: scale offset matrix already contains the viewport transformation
const auto clip_width = rsx::method_registers.surface_clip_width();
const auto clip_height = rsx::method_registers.surface_clip_height();
const auto clip_width = rsx::apply_resolution_scale(rsx::method_registers.surface_clip_width(), true);
const auto clip_height = rsx::apply_resolution_scale(rsx::method_registers.surface_clip_height(), true);
glViewport(0, 0, clip_width, clip_height);
u16 scissor_x = rsx::method_registers.scissor_origin_x();
u16 scissor_w = rsx::method_registers.scissor_width();
u16 scissor_y = rsx::method_registers.scissor_origin_y();
u16 scissor_h = rsx::method_registers.scissor_height();
u16 scissor_x = rsx::apply_resolution_scale(rsx::method_registers.scissor_origin_x(), false);
u16 scissor_w = rsx::apply_resolution_scale(rsx::method_registers.scissor_width(), true);
u16 scissor_y = rsx::apply_resolution_scale(rsx::method_registers.scissor_origin_y(), false);
u16 scissor_h = rsx::apply_resolution_scale(rsx::method_registers.scissor_height(), true);
//Do not bother drawing anything if output is zero sized
//TODO: Clip scissor region

View File

@ -3,6 +3,7 @@
#include "GLHelpers.h"
#include "stdafx.h"
#include "../RSXThread.h"
#include "../rsx_utils.h"
struct color_swizzle
{
@ -52,12 +53,14 @@ namespace gl
{
bool is_cleared = false;
u32 rsx_pitch = 0;
u16 native_pitch = 0;
u32 rsx_pitch = 0;
u16 native_pitch = 0;
u16 surface_height = 0;
u16 surface_width = 0;
u16 surface_pixel_size = 0;
u16 internal_width = 0;
u16 internal_height = 0;
u16 surface_height = 0;
u16 surface_width = 0;
u16 surface_pixel_size = 0;
texture::internal_format compatible_internal_format = texture::internal_format::rgba8;
@ -130,8 +133,16 @@ namespace gl
void update_surface()
{
surface_width = width();
surface_height = height();
internal_width = width();
internal_height = height();
surface_width = rsx::apply_inverse_resolution_scale(internal_width, true);
surface_height = rsx::apply_inverse_resolution_scale(internal_height, true);
}
bool matches_dimensions(u16 _width, u16 _height) const
{
//Use foward scaling to account for rounding and clamping errors
return (rsx::apply_resolution_scale(_width, true) == internal_width) && (rsx::apply_resolution_scale(_height, true) == internal_height);
}
};
}
@ -162,7 +173,7 @@ struct gl_render_target_traits
result->set_compatible_format(internal_fmt);
__glcheck result->config()
.size({ (int)width, (int)height })
.size({ (int)rsx::apply_resolution_scale((u16)width, true), (int)rsx::apply_resolution_scale((u16)height, true) })
.type(format.type)
.format(format.format)
.internal_format(internal_fmt)
@ -195,8 +206,10 @@ struct gl_render_target_traits
auto format = rsx::internals::surface_depth_format_to_gl(surface_depth_format);
result->recreate(gl::texture::target::texture2D);
const auto scale = rsx::get_resolution_scale();
__glcheck result->config()
.size({ (int)width, (int)height })
.size({ (int)rsx::apply_resolution_scale((u16)width, true), (int)rsx::apply_resolution_scale((u16)height, true) })
.type(format.type)
.format(format.format)
.internal_format(format.internal_format)
@ -247,7 +260,7 @@ struct gl_render_target_traits
return false;
auto internal_fmt = rsx::internals::sized_internal_format(format);
return rtt->get_compatible_internal_format() == internal_fmt && rtt->width() == width && rtt->height() == height;
return rtt->get_compatible_internal_format() == internal_fmt && rtt->matches_dimensions((u16)width, (u16)height);
}
static
@ -257,7 +270,7 @@ struct gl_render_target_traits
return false;
// TODO: check format
return rtt->width() == width && rtt->height() == height;
return rtt->matches_dimensions((u16)width, (u16)height);
}
// Note : pbo breaks fbo here so use classic texture copy

View File

@ -230,7 +230,7 @@ struct RSXFragmentProgram
bool front_color_specular_output : 1;
u32 texture_dimensions;
float texture_pitch_scale[16];
std::array<float, 2> texture_scale[16];
u8 textures_alpha_kill[16];
u8 textures_zfunc[16];

View File

@ -8,11 +8,13 @@
#include "Common/BufferUtils.h"
#include "rsx_methods.h"
#include "rsx_utils.h"
#include "Utilities/GSL.h"
#include "Utilities/StrUtil.h"
#include <thread>
#include <fenv.h>
class GSRender;
@ -391,6 +393,9 @@ namespace rsx
// Raise priority above other threads
thread_ctrl::set_native_priority(1);
// Round to nearest to deal with forward/reverse scaling
fesetround(FE_TONEAREST);
// Deferred calls are used to batch draws together
u32 deferred_primitive_type = 0;
u32 deferred_call_size = 0;
@ -790,24 +795,33 @@ namespace rsx
void thread::fill_fragment_state_buffer(void *buffer, const RSXFragmentProgram &fragment_program)
{
const u32 is_alpha_tested = rsx::method_registers.alpha_test_enabled();
const float alpha_ref = rsx::method_registers.alpha_ref() / 255.f;
const f32 alpha_ref = rsx::method_registers.alpha_ref() / 255.f;
const f32 fog0 = rsx::method_registers.fog_params_0();
const f32 fog1 = rsx::method_registers.fog_params_1();
const u32 alpha_func = static_cast<u32>(rsx::method_registers.alpha_func());
const u32 fog_mode = static_cast<u32>(rsx::method_registers.fog_equation());
const u32 window_origin = static_cast<u32>(rsx::method_registers.shader_window_origin());
// Generate wpos coeffecients
// wpos equation is now as follows:
// wpos.y = (frag_coord / resolution_scale) * ((window_origin!=top)?-1.: 1.) + ((window_origin!=top)? window_height : 0)
// wpos.x = (frag_coord / resolution_scale)
// wpos.zw = frag_coord.zw
const auto window_origin = rsx::method_registers.shader_window_origin();
const u32 window_height = rsx::method_registers.shader_window_height();
const float one = 1.f;
const f32 resolution_scale = 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_bias = (window_origin == rsx::window_origin::top) ? 0.f : window_height;
u32 *dst = static_cast<u32*>(buffer);
stream_vector(dst, (u32&)fog0, (u32&)fog1, is_alpha_tested, (u32&)alpha_ref);
stream_vector(dst + 4, alpha_func, fog_mode, window_origin, window_height);
stream_vector(dst + 4, alpha_func, fog_mode, (u32&)wpos_scale, (u32&)wpos_bias);
size_t offset = 8;
for (int index = 0; index < 16; ++index)
{
stream_vector(&dst[offset], (u32&)fragment_program.texture_pitch_scale[index], (u32&)one, 0U, 0U);
stream_vector(&dst[offset], (u32&)fragment_program.texture_scale[index][0], (u32&)fragment_program.texture_scale[index][1], 0U, 0U);
offset += 4;
}
}
@ -1305,10 +1319,13 @@ namespace rsx
result.shadow_textures = 0;
std::array<texture_dimension_extended, 16> texture_dimensions;
const auto resolution_scale = rsx::get_resolution_scale();
for (u32 i = 0; i < rsx::limits::fragment_textures_count; ++i)
{
auto &tex = rsx::method_registers.fragment_textures[i];
result.texture_pitch_scale[i] = 1.f;
result.texture_scale[i][0] = 1.f;
result.texture_scale[i][1] = 1.f;
result.textures_alpha_kill[i] = 0;
result.textures_zfunc[i] = 0;
@ -1345,14 +1362,23 @@ namespace rsx
if (surface_exists && surface_pitch)
{
if (raw_format & CELL_GCM_TEXTURE_UN)
result.texture_pitch_scale[i] = (float)surface_pitch / tex.pitch();
{
result.texture_scale[i][0] = (resolution_scale * (float)surface_pitch) / tex.pitch();
result.texture_scale[i][1] = resolution_scale;
}
}
else
{
std::tie(surface_exists, surface_pitch) = get_surface_info(texaddr, tex, true);
if (surface_exists)
{
u32 format = raw_format & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
if (raw_format & CELL_GCM_TEXTURE_UN)
{
result.texture_scale[i][0] = (resolution_scale * (float)surface_pitch) / tex.pitch();
result.texture_scale[i][1] = resolution_scale;
}
const u32 format = raw_format & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
switch (format)
{
case CELL_GCM_TEXTURE_A8R8G8B8:

View File

@ -166,8 +166,8 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS)
OS << " float alpha_ref;\n";
OS << " uint alpha_func;\n";
OS << " uint fog_mode;\n";
OS << " uint window_origin;\n";
OS << " uint window_height;\n";
OS << " float wpos_scale;\n";
OS << " float wpos_bias;\n";
OS << " vec4 texture_parameters[16];\n";
OS << "};\n";
@ -253,8 +253,7 @@ void VKFragmentDecompilerThread::insertMainStart(std::stringstream & OS)
}
OS << " vec4 ssa = gl_FrontFacing ? vec4(1.) : vec4(-1.);\n";
OS << " vec4 wpos = gl_FragCoord;\n";
OS << " if (window_origin != 0) wpos.y = window_height - wpos.y;\n";
OS << " vec4 wpos = get_wpos();\n";
bool two_sided_enabled = m_prog.front_back_color_enabled && (m_prog.back_color_diffuse_output || m_prog.back_color_specular_output);

View File

@ -1266,17 +1266,19 @@ void VKGSRender::end()
void VKGSRender::set_viewport()
{
u16 scissor_x = rsx::method_registers.scissor_origin_x();
u16 scissor_w = rsx::method_registers.scissor_width();
u16 scissor_y = rsx::method_registers.scissor_origin_y();
u16 scissor_h = rsx::method_registers.scissor_height();
const auto clip_width = rsx::apply_resolution_scale(rsx::method_registers.surface_clip_width(), true);
const auto clip_height = rsx::apply_resolution_scale(rsx::method_registers.surface_clip_height(), true);
u16 scissor_x = rsx::apply_resolution_scale(rsx::method_registers.scissor_origin_x(), false);
u16 scissor_w = rsx::apply_resolution_scale(rsx::method_registers.scissor_width(), true);
u16 scissor_y = rsx::apply_resolution_scale(rsx::method_registers.scissor_origin_y(), false);
u16 scissor_h = rsx::apply_resolution_scale(rsx::method_registers.scissor_height(), true);
//NOTE: The scale_offset matrix already has viewport matrix factored in
VkViewport viewport = {};
viewport.x = 0;
viewport.y = 0;
viewport.width = rsx::method_registers.surface_clip_width();
viewport.height = rsx::method_registers.surface_clip_height();
viewport.width = clip_width;
viewport.height = clip_height;
viewport.minDepth = 0.f;
viewport.maxDepth = 1.f;
@ -1341,13 +1343,14 @@ void VKGSRender::clear_surface(u32 mask)
std::vector<VkClearAttachment> clear_descriptors;
VkClearValue depth_stencil_clear_values, color_clear_values;
u16 scissor_x = rsx::method_registers.scissor_origin_x();
u16 scissor_w = rsx::method_registers.scissor_width();
u16 scissor_y = rsx::method_registers.scissor_origin_y();
u16 scissor_h = rsx::method_registers.scissor_height();
const auto scale = rsx::get_resolution_scale();
u16 scissor_x = rsx::apply_resolution_scale(rsx::method_registers.scissor_origin_x(), false);
u16 scissor_w = rsx::apply_resolution_scale(rsx::method_registers.scissor_width(), true);
u16 scissor_y = rsx::apply_resolution_scale(rsx::method_registers.scissor_origin_y(), false);
u16 scissor_h = rsx::apply_resolution_scale(rsx::method_registers.scissor_height(), true);
const u32 fb_width = m_draw_fbo->width();
const u32 fb_height = m_draw_fbo->height();
const u16 fb_width = m_draw_fbo->width();
const u16 fb_height = m_draw_fbo->height();
//clip region
std::tie(scissor_x, scissor_y, scissor_w, scissor_h) = rsx::clip_region<u16>(fb_width, fb_height, scissor_x, scissor_y, scissor_w, scissor_h, true);
@ -2086,14 +2089,14 @@ void VKGSRender::prepare_rtts()
const u32 surface_pitchs[] = { rsx::method_registers.surface_a_pitch(), rsx::method_registers.surface_b_pitch(),
rsx::method_registers.surface_c_pitch(), rsx::method_registers.surface_d_pitch() };
const auto fbo_width = rsx::apply_resolution_scale(clip_width, true);
const auto fbo_height = rsx::apply_resolution_scale(clip_height, true);
if (m_draw_fbo)
{
const u32 fb_width = m_draw_fbo->width();
const u32 fb_height = m_draw_fbo->height();
bool really_changed = false;
if (fb_width == clip_width && fb_height == clip_height)
if (m_draw_fbo->width() == fbo_width && m_draw_fbo->height() == clip_height)
{
for (u8 i = 0; i < rsx::limits::color_buffers_count; ++i)
{
@ -2215,7 +2218,7 @@ void VKGSRender::prepare_rtts()
for (auto &fbo : m_framebuffers_to_clean)
{
if (fbo->matches(bound_images, clip_width, clip_height))
if (fbo->matches(bound_images, fbo_width, fbo_height))
{
m_draw_fbo.swap(fbo);
m_draw_fbo->reset_refs();
@ -2263,7 +2266,7 @@ void VKGSRender::prepare_rtts()
if (m_draw_fbo)
m_framebuffers_to_clean.push_back(std::move(m_draw_fbo));
m_draw_fbo.reset(new vk::framebuffer_holder(*m_device, current_render_pass, clip_width, clip_height, std::move(fbo_images)));
m_draw_fbo.reset(new vk::framebuffer_holder(*m_device, current_render_pass, fbo_width, fbo_height, std::move(fbo_images)));
}
}

View File

@ -6,6 +6,7 @@
#include "../Common/surface_store.h"
#include "../Common/TextureUtils.h"
#include "VKFormats.h"
#include "../rsx_utils.h"
struct ref_counted
{
@ -59,12 +60,12 @@ namespace vk
u16 get_surface_width() const override
{
return width();
return rsx::apply_inverse_resolution_scale(width(), true);
}
u16 get_surface_height() const override
{
return height();
return rsx::apply_inverse_resolution_scale(height(), true);
}
u16 get_rsx_pitch() const override
@ -76,6 +77,12 @@ namespace vk
{
return native_pitch;
}
bool matches_dimensions(u16 _width, u16 _height) const
{
//Use foward scaling to account for rounding and clamping errors
return (rsx::apply_resolution_scale(_width, true) == width()) && (rsx::apply_resolution_scale(_height, true) == height());
}
};
struct framebuffer_holder: public vk::framebuffer, public ref_counted
@ -114,7 +121,7 @@ namespace rsx
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
VK_IMAGE_TYPE_2D,
requested_format,
static_cast<uint32_t>(width), static_cast<uint32_t>(height), 1, 1, 1,
static_cast<uint32_t>(rsx::apply_resolution_scale((u16)width, true)), static_cast<uint32_t>(rsx::apply_resolution_scale((u16)height, true)), 1, 1, 1,
VK_SAMPLE_COUNT_1_BIT,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_TILING_OPTIMAL,
@ -158,12 +165,14 @@ namespace rsx
if (requested_format != VK_FORMAT_D16_UNORM)
range.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
const auto scale = rsx::get_resolution_scale();
std::unique_ptr<vk::render_target> ds;
ds.reset(new vk::render_target(device, mem_mapping.device_local,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
VK_IMAGE_TYPE_2D,
requested_format,
static_cast<uint32_t>(width), static_cast<uint32_t>(height), 1, 1, 1,
static_cast<uint32_t>(rsx::apply_resolution_scale((u16)width, true)), static_cast<uint32_t>(rsx::apply_resolution_scale((u16)height, true)), 1, 1, 1,
VK_SAMPLE_COUNT_1_BIT,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_TILING_OPTIMAL,
@ -202,8 +211,8 @@ namespace rsx
{
info->rsx_pitch = surface->rsx_pitch;
info->native_pitch = surface->native_pitch;
info->surface_width = surface->info.extent.width;
info->surface_height = surface->info.extent.height;
info->surface_width = surface->get_surface_width();
info->surface_height = surface->get_surface_height();
info->bpp = static_cast<u8>(info->native_pitch / info->surface_width);
}
@ -260,8 +269,7 @@ namespace rsx
VkFormat fmt = vk::get_compatible_surface_format(format).first;
if (rtt->info.format == fmt &&
rtt->info.extent.width == width &&
rtt->info.extent.height == height)
rtt->matches_dimensions((u16)width, (u16)height))
return true;
return false;
@ -272,8 +280,7 @@ namespace rsx
if (check_refs && ds->deref_count == 0) //Surface may still have read refs from data 'copy'
return false;
if (ds->info.extent.width == width &&
ds->info.extent.height == height)
if (ds->matches_dimensions((u16)width, (u16)height))
{
//Check format
switch (ds->info.format)

View File

@ -207,4 +207,30 @@ namespace rsx
return std::make_tuple(x, y, width, height);
}
static inline f32 get_resolution_scale()
{
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()
{
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)
{
if (clamp)
return (u16)std::max((get_resolution_scale_percent() * value) / 100, 1);
else
return (get_resolution_scale_percent() * value) / 100;
}
static inline const u16 apply_inverse_resolution_scale(u16 value, bool clamp)
{
if (clamp)
return (u16)std::max((value * 100) / get_resolution_scale_percent(), 1);
else
return (value * 100) / get_resolution_scale_percent();
}
}