diff options
author | bunnei <bunneidev@gmail.com> | 2018-09-14 18:07:22 +0200 |
---|---|---|
committer | bunnei <bunneidev@gmail.com> | 2018-09-30 20:31:57 +0200 |
commit | a9aa1db5522798c06d3c5708f649758b045e9cde (patch) | |
tree | 1891b2f0dcf7e2f08a7285a676c809368a3437e3 /src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |
parent | gl_rasterizer_cache: Track texture target and depth in the cache. (diff) | |
download | yuzu-a9aa1db5522798c06d3c5708f649758b045e9cde.tar yuzu-a9aa1db5522798c06d3c5708f649758b045e9cde.tar.gz yuzu-a9aa1db5522798c06d3c5708f649758b045e9cde.tar.bz2 yuzu-a9aa1db5522798c06d3c5708f649758b045e9cde.tar.lz yuzu-a9aa1db5522798c06d3c5708f649758b045e9cde.tar.xz yuzu-a9aa1db5522798c06d3c5708f649758b045e9cde.tar.zst yuzu-a9aa1db5522798c06d3c5708f649758b045e9cde.zip |
Diffstat (limited to '')
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 111 |
1 files changed, 88 insertions, 23 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 00351d743..57af6cdd1 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -414,9 +414,12 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, std::size_t, VAddr), // clang-format on }; -static bool BlitTextures(GLuint src_tex, const MathUtil::Rectangle<u32>& src_rect, GLuint dst_tex, - const MathUtil::Rectangle<u32>& dst_rect, SurfaceType type, - GLuint read_fb_handle, GLuint draw_fb_handle) { +static bool BlitSurface(const Surface& src_surface, const Surface& dst_surface, + GLuint read_fb_handle, GLuint draw_fb_handle, std::size_t face = 0) { + + const auto& src_params{src_surface->GetSurfaceParams()}; + const auto& dst_params{dst_surface->GetSurfaceParams()}; + OpenGLState prev_state{OpenGLState::GetCurState()}; SCOPE_EXIT({ prev_state.Apply(); }); @@ -427,42 +430,106 @@ static bool BlitTextures(GLuint src_tex, const MathUtil::Rectangle<u32>& src_rec u32 buffers{}; - if (type == SurfaceType::ColorTexture) { - glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, src_tex, - 0); - glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, - 0); + if (src_params.type == SurfaceType::ColorTexture) { + switch (src_params.target) { + case SurfaceParams::SurfaceTarget::Texture2D: + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + src_surface->Texture().handle, 0); + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, + 0, 0); + break; + case SurfaceParams::SurfaceTarget::TextureCubemap: + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face), + src_surface->Texture().handle, 0); + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, + static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face), 0, + 0); + break; + case SurfaceParams::SurfaceTarget::Texture2DArray: + glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + src_surface->Texture().handle, 0, 0); + glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, 0, 0, 0); + break; + case SurfaceParams::SurfaceTarget::Texture3D: + glFramebufferTexture3D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + SurfaceTargetToGL(src_params.target), + src_surface->Texture().handle, 0, 0); + glFramebufferTexture3D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, + SurfaceTargetToGL(src_params.target), 0, 0, 0); + break; + default: + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + src_surface->Texture().handle, 0); + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, + 0, 0); + break; + } - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_tex, - 0); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, - 0); + switch (dst_params.target) { + case SurfaceParams::SurfaceTarget::Texture2D: + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + dst_surface->Texture().handle, 0); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, + 0, 0); + break; + case SurfaceParams::SurfaceTarget::TextureCubemap: + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face), + dst_surface->Texture().handle, 0); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, + static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face), 0, + 0); + break; + case SurfaceParams::SurfaceTarget::Texture2DArray: + glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + dst_surface->Texture().handle, 0, 0); + glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, 0, 0, 0); + break; + + case SurfaceParams::SurfaceTarget::Texture3D: + glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + SurfaceTargetToGL(dst_params.target), + dst_surface->Texture().handle, 0, 0); + glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, + SurfaceTargetToGL(dst_params.target), 0, 0, 0); + break; + default: + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + dst_surface->Texture().handle, 0); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, + 0, 0); + break; + } buffers = GL_COLOR_BUFFER_BIT; - } else if (type == SurfaceType::Depth) { + } else if (src_params.type == SurfaceType::Depth) { glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); - glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, src_tex, 0); + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, + src_surface->Texture().handle, 0); glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, dst_tex, 0); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, + dst_surface->Texture().handle, 0); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); buffers = GL_DEPTH_BUFFER_BIT; - } else if (type == SurfaceType::DepthStencil) { + } else if (src_params.type == SurfaceType::DepthStencil) { glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, - src_tex, 0); + src_surface->Texture().handle, 0); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, - dst_tex, 0); + dst_surface->Texture().handle, 0); buffers = GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; } - glBlitFramebuffer(src_rect.left, src_rect.bottom, src_rect.right, src_rect.top, dst_rect.left, - dst_rect.bottom, dst_rect.right, dst_rect.top, buffers, + const auto& rect{src_params.GetRect()}; + glBlitFramebuffer(rect.left, rect.bottom, rect.right, rect.top, rect.left, rect.bottom, + rect.right, rect.top, buffers, buffers == GL_COLOR_BUFFER_BIT ? GL_LINEAR : GL_NEAREST); return true; @@ -841,9 +908,7 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface, // using PBOs. The is also likely less accurate, as textures will be converted rather than // reinterpreted. - BlitTextures(surface->Texture().handle, params.GetRect(), new_surface->Texture().handle, - params.GetRect(), params.type, read_framebuffer.handle, - draw_framebuffer.handle); + BlitSurface(old_surface, new_surface, read_framebuffer.handle, draw_framebuffer.handle); } else { // When use_accurate_framebuffers setting is enabled, perform a more accurate surface copy, // where pixels are reinterpreted as a new format (without conversion). This code path uses |