1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 02:32:36 +01:00

rsx: Roll back some optimizations

- Just use RGB565 for all blit targets. Avoids really dumb transforms done by GPU hw.
- When X16 is used, all the channels get written to R channel alone. CmdBlit does perform format conversion!
- gl: Force image copy when blit is requested with compatible targets. Avoids format conversion issues.
This commit is contained in:
kd-11 2021-11-17 23:02:08 +03:00 committed by kd-11
parent a21c6c4628
commit 94a3b1cfe8
4 changed files with 100 additions and 79 deletions

View File

@ -2240,7 +2240,6 @@ namespace rsx
const bool is_copy_op = (fcmp(scale_x, 1.f) && fcmp(scale_y, 1.f));
const bool is_format_convert = (dst_is_argb8 != src_is_argb8);
const bool is_interpolating_op = (!is_copy_op && interpolate);
bool skip_if_collision_exists = false;
// Offset in x and y for src is 0 (it is already accounted for when getting pixels_src)
@ -2417,14 +2416,14 @@ namespace rsx
if (!typeless) [[likely]]
{
// Use format as-is
typeless_info.src_gcm_format = helpers::get_sized_blit_format(src_is_argb8, src_subres.is_depth, false, is_interpolating_op);
typeless_info.src_gcm_format = helpers::get_sized_blit_format(src_is_argb8, src_subres.is_depth, false);
}
else
{
// Enable type scaling in src
typeless_info.src_is_typeless = true;
typeless_info.src_scaling_hint = static_cast<f32>(bpp) / src_bpp;
typeless_info.src_gcm_format = helpers::get_sized_blit_format(src_is_argb8, false, is_format_convert, is_interpolating_op);
typeless_info.src_gcm_format = helpers::get_sized_blit_format(src_is_argb8, false, is_format_convert);
}
if (surf->get_surface_width(rsx::surface_metrics::pixels) != surf->width() ||
@ -2492,14 +2491,14 @@ namespace rsx
if (!typeless) [[likely]]
{
typeless_info.dst_gcm_format = helpers::get_sized_blit_format(dst_is_argb8, dst_subres.is_depth, false, is_interpolating_op);
typeless_info.dst_gcm_format = helpers::get_sized_blit_format(dst_is_argb8, dst_subres.is_depth, false);
}
else
{
// Enable type scaling in dst
typeless_info.dst_is_typeless = true;
typeless_info.dst_scaling_hint = static_cast<f32>(bpp) / dst_bpp;
typeless_info.dst_gcm_format = helpers::get_sized_blit_format(dst_is_argb8, false, is_format_convert, is_interpolating_op);
typeless_info.dst_gcm_format = helpers::get_sized_blit_format(dst_is_argb8, false, is_format_convert);
}
}
@ -2624,7 +2623,6 @@ namespace rsx
case CELL_GCM_TEXTURE_A8R8G8B8:
if (!dst_is_argb8) continue;
break;
case CELL_GCM_TEXTURE_X16:
case CELL_GCM_TEXTURE_R5G6B5:
if (dst_is_argb8) continue;
break;
@ -2705,20 +2703,28 @@ namespace rsx
// Force format matching; only accept 16-bit data for 16-bit transfers, 32-bit for 32-bit transfers
switch (surface->get_gcm_format())
{
case CELL_GCM_TEXTURE_A8R8G8B8:
case CELL_GCM_TEXTURE_D8R8G8B8:
case CELL_GCM_TEXTURE_DEPTH24_D8:
case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT:
case CELL_GCM_TEXTURE_X32_FLOAT:
case CELL_GCM_TEXTURE_Y16_X16:
case CELL_GCM_TEXTURE_Y16_X16_FLOAT:
{
if (!src_is_argb8) continue;
break;
// Should be copy compatible but not scaling compatible
if (src_is_argb8 && (is_copy_op || dst_is_render_target)) break;
continue;
}
case CELL_GCM_TEXTURE_DEPTH24_D8:
case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT:
{
// Should be copy compatible but not scaling compatible
if (src_is_argb8 && (is_copy_op || !dst_is_render_target)) break;
continue;
}
case CELL_GCM_TEXTURE_A8R8G8B8:
case CELL_GCM_TEXTURE_D8R8G8B8:
{
// Perfect match
if (src_is_argb8) break;
continue;
}
case CELL_GCM_TEXTURE_R5G6B5:
case CELL_GCM_TEXTURE_DEPTH16:
case CELL_GCM_TEXTURE_DEPTH16_FLOAT:
case CELL_GCM_TEXTURE_X16:
case CELL_GCM_TEXTURE_G8B8:
case CELL_GCM_TEXTURE_A1R5G5B5:
@ -2726,8 +2732,22 @@ namespace rsx
case CELL_GCM_TEXTURE_D1R5G5B5:
case CELL_GCM_TEXTURE_R5G5B5A1:
{
if (src_is_argb8) continue;
break;
// Copy compatible
if (!src_is_argb8 && (is_copy_op || dst_is_render_target)) break;
continue;
}
case CELL_GCM_TEXTURE_DEPTH16:
case CELL_GCM_TEXTURE_DEPTH16_FLOAT:
{
// Copy compatible
if (!src_is_argb8 && (is_copy_op || !dst_is_render_target)) break;
continue;
}
case CELL_GCM_TEXTURE_R5G6B5:
{
// Perfect match
if (!src_is_argb8) break;
continue;
}
default:
{
@ -2800,7 +2820,7 @@ namespace rsx
subres.data = { vm::_ptr<const std::byte>(image_base), static_cast<std::span<const std::byte>::size_type>(src.pitch * image_height) };
subresource_layout.push_back(subres);
const u32 gcm_format = helpers::get_sized_blit_format(src_is_argb8, dst_is_depth_surface, is_format_convert, is_interpolating_op);
const u32 gcm_format = helpers::get_sized_blit_format(src_is_argb8, dst_is_depth_surface, is_format_convert);
const auto rsx_range = address_range::start_length(image_base, src.pitch * image_height);
lock.upgrade();
@ -2829,7 +2849,7 @@ namespace rsx
}
//const auto src_is_depth_format = helpers::is_gcm_depth_format(typeless_info.src_gcm_format);
const auto preferred_dst_format = helpers::get_sized_blit_format(dst_is_argb8, false, is_format_convert, is_interpolating_op);
const auto preferred_dst_format = helpers::get_sized_blit_format(dst_is_argb8, false, is_format_convert);
if (cached_dest && !use_null_region)
{
@ -3036,7 +3056,7 @@ namespace rsx
if (!typeless_info.src_is_typeless)
{
typeless_info.src_is_typeless = true;
typeless_info.src_gcm_format = helpers::get_sized_blit_format(src_is_argb8, false, false, is_interpolating_op);
typeless_info.src_gcm_format = helpers::get_sized_blit_format(src_is_argb8, false, false);
}
}
else
@ -3045,7 +3065,7 @@ namespace rsx
if (!typeless_info.dst_is_typeless)
{
typeless_info.dst_is_typeless = true;
typeless_info.dst_gcm_format = helpers::get_sized_blit_format(dst_is_argb8, false, false, is_interpolating_op);
typeless_info.dst_gcm_format = helpers::get_sized_blit_format(dst_is_argb8, false, false);
}
}
}

View File

@ -133,19 +133,15 @@ namespace rsx
return gcm_format;
}
static inline u32 get_sized_blit_format(bool is_32_bit, bool depth_format, bool is_format_convert, bool is_interpolating_op)
static inline u32 get_sized_blit_format(bool is_32_bit, bool depth_format, bool is_format_convert)
{
if (is_format_convert || is_interpolating_op)
{
return (is_32_bit) ? CELL_GCM_TEXTURE_A8R8G8B8 : CELL_GCM_TEXTURE_R5G6B5;
}
else if (is_32_bit)
if (is_32_bit)
{
return (!depth_format) ? CELL_GCM_TEXTURE_A8R8G8B8 : CELL_GCM_TEXTURE_DEPTH24_D8;
}
else
{
return (!depth_format) ? CELL_GCM_TEXTURE_X16 : CELL_GCM_TEXTURE_DEPTH16;
return (!depth_format) ? CELL_GCM_TEXTURE_R5G6B5 : CELL_GCM_TEXTURE_DEPTH16;
}
}

View File

@ -554,63 +554,73 @@ namespace gl
ensure(real_src->aspect() == real_dst->aspect());
const bool is_depth_copy = (real_src->aspect() != image_aspect::color);
const filter interp = (linear_interpolation && !is_depth_copy) ? filter::linear : filter::nearest;
GLenum attachment;
gl::buffers target;
if (is_depth_copy)
if (src_rect.width() == dst_rect.width() && src_rect.height() == dst_rect.height() &&
!src_rect.is_flipped() && !dst_rect.is_flipped())
{
if (real_dst->aspect() & gl::image_aspect::stencil)
{
attachment = GL_DEPTH_STENCIL_ATTACHMENT;
target = gl::buffers::depth_stencil;
}
else
{
attachment = GL_DEPTH_ATTACHMENT;
target = gl::buffers::depth;
}
glCopyImageSubData(real_src->id(), static_cast<GLenum>(real_src->get_target()), 0, src_rect.x1, src_rect.y1, 0,
real_dst->id(), static_cast<GLenum>(real_dst->get_target()), 0, dst_rect.x1, dst_rect.y1, 0,
src_rect.width(), src_rect.height(), 1);
}
else
{
attachment = GL_COLOR_ATTACHMENT0;
target = gl::buffers::color;
const bool is_depth_copy = (real_src->aspect() != image_aspect::color);
const filter interp = (linear_interpolation && !is_depth_copy) ? filter::linear : filter::nearest;
GLenum attachment;
gl::buffers target;
if (is_depth_copy)
{
if (real_dst->aspect() & gl::image_aspect::stencil)
{
attachment = GL_DEPTH_STENCIL_ATTACHMENT;
target = gl::buffers::depth_stencil;
}
else
{
attachment = GL_DEPTH_ATTACHMENT;
target = gl::buffers::depth;
}
}
else
{
attachment = GL_COLOR_ATTACHMENT0;
target = gl::buffers::color;
}
cmd.drv->enable(GL_FALSE, GL_SCISSOR_TEST);
save_binding_state saved;
glBindFramebuffer(GL_READ_FRAMEBUFFER, blit_src.id());
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, attachment, GL_TEXTURE_2D, real_src->id(), 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, blit_dst.id());
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, real_dst->id(), 0);
if (xfer_info.flip_horizontal)
{
src_rect.flip_horizontal();
}
if (xfer_info.flip_vertical)
{
src_rect.flip_vertical();
}
glBlitFramebuffer(src_rect.x1, src_rect.y1, src_rect.x2, src_rect.y2,
dst_rect.x1, dst_rect.y1, dst_rect.x2, dst_rect.y2,
static_cast<GLbitfield>(target), static_cast<GLenum>(interp));
// Release the attachments explicitly (not doing so causes glitches, e.g Journey Menu)
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, attachment, GL_TEXTURE_2D, GL_NONE, 0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, GL_NONE, 0);
}
cmd.drv->enable(GL_FALSE, GL_SCISSOR_TEST);
save_binding_state saved;
glBindFramebuffer(GL_READ_FRAMEBUFFER, blit_src.id());
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, attachment, GL_TEXTURE_2D, real_src->id(), 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, blit_dst.id());
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, real_dst->id(), 0);
if (xfer_info.flip_horizontal)
{
src_rect.flip_horizontal();
}
if (xfer_info.flip_vertical)
{
src_rect.flip_vertical();
}
glBlitFramebuffer(src_rect.x1, src_rect.y1, src_rect.x2, src_rect.y2,
dst_rect.x1, dst_rect.y1, dst_rect.x2, dst_rect.y2,
static_cast<GLbitfield>(target), static_cast<GLenum>(interp));
if (xfer_info.dst_is_typeless)
{
// Transfer contents from typeless dst back to original dst
copy_typeless(dst, typeless_dst.get());
}
// Release the attachments explicitly (not doing so causes glitches, e.g Journey Menu)
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, attachment, GL_TEXTURE_2D, GL_NONE, 0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, GL_NONE, 0);
}
void blitter::fast_clear_image(gl::command_context& cmd, const texture* dst, const color4f& color)

View File

@ -727,11 +727,6 @@ namespace gl
cached.set_format(gl::texture::format::depth, gl::texture::type::ushort, true);
break;
}
case CELL_GCM_TEXTURE_X16:
{
cached.set_format(gl::texture::format::r, gl::texture::type::ushort, true);
break;
}
default:
fmt::throw_exception("Unexpected gcm format 0x%X", gcm_format);
}