From a2f6c272210813332aebf7f14d2b02c79e03bffd Mon Sep 17 00:00:00 2001 From: kd-11 Date: Wed, 15 Mar 2017 16:57:41 +0300 Subject: [PATCH] gl: Prep for hw blit --- rpcs3/Emu/RSX/GL/GLGSRender.cpp | 5 ++ rpcs3/Emu/RSX/GL/GLGSRender.h | 3 ++ rpcs3/Emu/RSX/GL/GLTextureCache.h | 78 +++++++++++++++++++++++++++++++ rpcs3/Emu/RSX/rsx_methods.cpp | 9 +++- 4 files changed, 93 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index fae572c5b8..2937065ea3 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -969,3 +969,8 @@ void GLGSRender::synchronize_buffers() flush_draw_buffers = false; } } + +bool GLGSRender::scaled_image_from_memory(rsx::blit_src_info& src, rsx::blit_dst_info& dst, bool interpolate) +{ + return m_gl_texture_cache.upload_scaled_image(src, dst, interpolate); +} diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.h b/rpcs3/Emu/RSX/GL/GLGSRender.h index 5cdc01610e..60d01b2c15 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.h +++ b/rpcs3/Emu/RSX/GL/GLGSRender.h @@ -9,6 +9,7 @@ #include "define_new_memleakdetect.h" #include "GLProgramBuffer.h" #include "GLTextOut.h" +#include "../rsx_cache.h" #pragma comment(lib, "opengl32.lib") @@ -131,6 +132,8 @@ public: void synchronize_buffers(); work_item& post_flush_request(u32 address, gl::texture_cache::cached_rtt_section *section); + bool scaled_image_from_memory(rsx::blit_src_info& src_info, rsx::blit_dst_info& dst_info, bool interpolate) override; + protected: void begin() override; void end() override; diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index e34c661d7e..ad39652e94 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -416,6 +416,78 @@ namespace gl } }; + class blitter + { + fbo fbo_argb8; + fbo fbo_rgb565; + fbo blit_src; + + u32 argb8_surface = 0; + u32 rgb565_surface = 0; + + void init() + { + fbo_argb8.create(); + fbo_rgb565.create(); + blit_src.create(); + + glGenTextures(1, &argb8_surface); + glBindTexture(GL_TEXTURE_2D, argb8_surface); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 4096, 4096); + + glGenTextures(1, &rgb565_surface); + glBindTexture(GL_TEXTURE_2D, rgb565_surface); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB565, 4096, 4096); + + fbo_argb8.color[0] = argb8_surface; + fbo_rgb565.color[0] = rgb565_surface; + + fbo_argb8.check(); + fbo_rgb565.check(); + } + + void destroy() + { + fbo_argb8.remove(); + fbo_rgb565.remove(); + blit_src.remove(); + + glDeleteTextures(1, &argb8_surface); + glDeleteTextures(1, &rgb565_surface); + } + + u32 scale_image(u32 src, areai src_rect, areai dst_rect, position2i clip_offset, size2i clip_dims, bool is_argb8) + { + blit_src.color[0] = src; + blit_src.check(); + + areai src_rect, dst_rect; + u32 src_surface = 0; + u32 dst_tex = 0; + + glGenTextures(1, &dst_tex); + glBindTexture(GL_TEXTURE_2D, dst_tex); + + if (is_argb8) + { + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, clip_dims.width, clip_dims.height); + blit_src.blit(fbo_argb8, src_rect, dst_rect); + src_surface = argb8_surface; + } + else + { + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB565, clip_dims.width, clip_dims.height); + blit_src.blit(fbo_rgb565, src_rect, dst_rect); + src_surface = rgb565_surface; + } + + glCopyImageSubData(src_surface, GL_TEXTURE_2D, 0, clip_offset.x, clip_offset.y, 0, + dst_tex, GL_TEXTURE_2D, 0, 0, 0, 0, clip_dims.width, clip_dims.height, 1); + + return dst_tex; + } + }; + private: std::vector m_texture_cache; std::vector m_rtt_cache; @@ -899,5 +971,11 @@ namespace gl m_temporary_surfaces.clear(); } + + bool upload_scaled_image(rsx::blit_src_info& src, rsx::blit_dst_info& dst, bool interpolate) + { + //TODO + return false; + } }; } \ No newline at end of file diff --git a/rpcs3/Emu/RSX/rsx_methods.cpp b/rpcs3/Emu/RSX/rsx_methods.cpp index 6e289089a9..e62283541e 100644 --- a/rpcs3/Emu/RSX/rsx_methods.cpp +++ b/rpcs3/Emu/RSX/rsx_methods.cpp @@ -564,8 +564,13 @@ namespace rsx dst_info.pixels = pixels_dst; dst_info.swizzled = (method_registers.blit_engine_context_surface() == blit_engine::context_surface::swizzle2d); - if (rsx->scaled_image_from_memory(src_info, dst_info, in_inter == blit_engine::transfer_interpolator::foh)) - return; + if (need_convert) + { + //For now, only use this for actual scaled images, there are use cases that should not go through 3d engine, e.g program ucode transfer + //TODO: Figure out more instances where we can use this without problems + if (rsx->scaled_image_from_memory(src_info, dst_info, in_inter == blit_engine::transfer_interpolator::foh)) + return; + } if (method_registers.blit_engine_context_surface() != blit_engine::context_surface::swizzle2d) {