rsx/gl/scaling: Fixes

This commit is contained in:
kd-11 2017-03-17 17:31:54 +03:00
parent 5928b78c45
commit ffd9ab12c6
3 changed files with 26 additions and 14 deletions

View file

@ -692,6 +692,15 @@ bool GLGSRender::load_program()
else
surface = m_rtts.get_texture_from_depth_stencil_if_applicable(texaddr);
if (!surface)
{
auto rsc = m_rtts.get_surface_subresource_if_applicable(texaddr, 0, 0, tex.pitch());
if (!rsc.surface || rsc.is_depth_surface != is_depth)
return std::make_tuple(false, 0);
surface = rsc.surface;
}
return std::make_tuple(true, surface->get_native_pitch());
};

View file

@ -298,11 +298,12 @@ struct surface_subresource
bool is_bound = false;
bool is_depth_surface = false;
bool is_clipped = false;
surface_subresource() {}
surface_subresource(gl::render_target *src, u16 X, u16 Y, u16 W, u16 H, bool _Bound, bool _Depth)
: surface(src), x(X), y(Y), w(W), h(H), is_bound(_Bound), is_depth_surface(_Depth)
surface_subresource(gl::render_target *src, u16 X, u16 Y, u16 W, u16 H, bool _Bound, bool _Depth, bool _Clipped = false)
: surface(src), x(X), y(Y), w(W), h(H), is_bound(_Bound), is_depth_surface(_Depth), is_clipped(_Clipped)
{}
};
@ -361,7 +362,7 @@ private:
}
public:
surface_subresource get_surface_subresource_if_applicable(u32 texaddr, u16 requested_width, u16 requested_height, u16 requested_pitch, bool scale_to_fit =false)
surface_subresource get_surface_subresource_if_applicable(u32 texaddr, u16 requested_width, u16 requested_height, u16 requested_pitch, bool scale_to_fit =false, bool crop=false)
{
gl::render_target *surface = nullptr;
bool is_subslice = false;
@ -390,18 +391,18 @@ public:
return{ surface, x_offset, y_offset, requested_width, requested_height, is_bound(this_address, false), false };
else
{
if (scale_to_fit) //Forcefully fit the requested region by clipping and scaling
if (crop) //Forcefully fit the requested region by clipping and scaling
{
u16 remaining_width = dims.first - x_offset;
u16 remaining_height = dims.second - y_offset;
return{ surface, x_offset, y_offset, remaining_width, remaining_height, is_bound(this_address, false), false };
return{ surface, x_offset, y_offset, remaining_width, remaining_height, is_bound(this_address, false), false, true };
}
if (dims.first >= requested_width && dims.second >= requested_height)
{
LOG_WARNING(RSX, "Overlapping surface exceeds bounds; returning full surface region");
return{ surface, 0, 0, requested_width, requested_height, is_bound(this_address, false), false };
return{ surface, 0, 0, requested_width, requested_height, is_bound(this_address, false), false, true };
}
}
}
@ -430,18 +431,18 @@ public:
return{ surface, x_offset, y_offset, requested_width, requested_height, is_bound(this_address, true), true };
else
{
if (scale_to_fit) //Forcefully fit the requested region by clipping and scaling
if (crop) //Forcefully fit the requested region by clipping and scaling
{
u16 remaining_width = dims.first - x_offset;
u16 remaining_height = dims.second - y_offset;
return{ surface, x_offset, y_offset, remaining_width, remaining_height, is_bound(this_address, false), false };
return{ surface, x_offset, y_offset, remaining_width, remaining_height, is_bound(this_address, true), true, true };
}
if (dims.first >= requested_width && dims.second >= requested_height)
{
LOG_WARNING(RSX, "Overlapping depth surface exceeds bounds; returning full surface region");
return{ surface, 0, 0, requested_width, requested_height, is_bound(this_address, true), true };
return{ surface, 0, 0, requested_width, requested_height, is_bound(this_address, true), true, true };
}
}
}

View file

@ -754,7 +754,11 @@ namespace gl
* a bound render target. We can bypass the expensive download in this case
*/
surface_subresource rsc = m_rtts.get_surface_subresource_if_applicable(texaddr, tex.width(), tex.height(), tex.pitch(), true);
const u32 format = tex.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
const f32 internal_scale = (f32)tex.pitch() / (tex.width() * get_format_block_size_in_bytes(format));
const u32 internal_width = tex.width() * internal_scale;
const surface_subresource rsc = m_rtts.get_surface_subresource_if_applicable(texaddr, internal_width, tex.height(), tex.pitch(), true);
if (rsc.surface)
{
//Check that this region is not cpu-dirty before doing a copy
@ -782,8 +786,6 @@ namespace gl
}
else
{
const u32 format = tex.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
GLenum src_format = (GLenum)rsc.surface->get_internal_format();
GLenum dst_format = std::get<0>(get_format_type(format));
@ -1075,7 +1077,7 @@ namespace gl
const u32 dst_address = (u32)((u64)dst.pixels - (u64)vm::base(0));
//Check if src/dst are parts of render targets
surface_subresource src_subres = m_rtts.get_surface_subresource_if_applicable(src_address, src.width, src.slice_h, src.pitch, true);
surface_subresource src_subres = m_rtts.get_surface_subresource_if_applicable(src_address, src.width, src.slice_h, src.pitch, true, true);
src_is_render_target = src_subres.surface != nullptr;
float scale_x = (f32)dst.width / src.width;
@ -1147,7 +1149,7 @@ namespace gl
source_texture = src_subres.surface->id();
}
surface_subresource dst_subres = m_rtts.get_surface_subresource_if_applicable(dst_address, dst.width, dst.clip_height, dst.pitch, true);
surface_subresource dst_subres = m_rtts.get_surface_subresource_if_applicable(dst_address, dst.width, dst.clip_height, dst.pitch, true, true);
dst_is_render_target = dst_subres.surface != nullptr;
if (!dst_is_render_target)