rsx/gl/scaling: Fixes
This commit is contained in:
@@ -692,6 +692,15 @@ bool GLGSRender::load_program()
|
|||||||
else
|
else
|
||||||
surface = m_rtts.get_texture_from_depth_stencil_if_applicable(texaddr);
|
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());
|
return std::make_tuple(true, surface->get_native_pitch());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -298,11 +298,12 @@ struct surface_subresource
|
|||||||
|
|
||||||
bool is_bound = false;
|
bool is_bound = false;
|
||||||
bool is_depth_surface = false;
|
bool is_depth_surface = false;
|
||||||
|
bool is_clipped = false;
|
||||||
|
|
||||||
surface_subresource() {}
|
surface_subresource() {}
|
||||||
|
|
||||||
surface_subresource(gl::render_target *src, u16 X, u16 Y, u16 W, u16 H, bool _Bound, bool _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)
|
: 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:
|
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;
|
gl::render_target *surface = nullptr;
|
||||||
bool is_subslice = false;
|
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 };
|
return{ surface, x_offset, y_offset, requested_width, requested_height, is_bound(this_address, false), false };
|
||||||
else
|
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_width = dims.first - x_offset;
|
||||||
u16 remaining_height = dims.second - y_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)
|
if (dims.first >= requested_width && dims.second >= requested_height)
|
||||||
{
|
{
|
||||||
LOG_WARNING(RSX, "Overlapping surface exceeds bounds; returning full surface region");
|
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 };
|
return{ surface, x_offset, y_offset, requested_width, requested_height, is_bound(this_address, true), true };
|
||||||
else
|
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_width = dims.first - x_offset;
|
||||||
u16 remaining_height = dims.second - y_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)
|
if (dims.first >= requested_width && dims.second >= requested_height)
|
||||||
{
|
{
|
||||||
LOG_WARNING(RSX, "Overlapping depth surface exceeds bounds; returning full surface region");
|
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 };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -754,7 +754,11 @@ namespace gl
|
|||||||
* a bound render target. We can bypass the expensive download in this case
|
* 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)
|
if (rsc.surface)
|
||||||
{
|
{
|
||||||
//Check that this region is not cpu-dirty before doing a copy
|
//Check that this region is not cpu-dirty before doing a copy
|
||||||
@@ -782,8 +786,6 @@ namespace gl
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const u32 format = tex.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
|
|
||||||
|
|
||||||
GLenum src_format = (GLenum)rsc.surface->get_internal_format();
|
GLenum src_format = (GLenum)rsc.surface->get_internal_format();
|
||||||
GLenum dst_format = std::get<0>(get_format_type(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));
|
const u32 dst_address = (u32)((u64)dst.pixels - (u64)vm::base(0));
|
||||||
|
|
||||||
//Check if src/dst are parts of render targets
|
//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;
|
src_is_render_target = src_subres.surface != nullptr;
|
||||||
|
|
||||||
float scale_x = (f32)dst.width / src.width;
|
float scale_x = (f32)dst.width / src.width;
|
||||||
@@ -1147,7 +1149,7 @@ namespace gl
|
|||||||
source_texture = src_subres.surface->id();
|
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;
|
dst_is_render_target = dst_subres.surface != nullptr;
|
||||||
|
|
||||||
if (!dst_is_render_target)
|
if (!dst_is_render_target)
|
||||||
|
|||||||
Reference in New Issue
Block a user