summaryrefslogtreecommitdiff
path: root/src/video_core/renderer_opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp115
1 files changed, 13 insertions, 102 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index b5a9722f9..876698b37 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -21,7 +21,7 @@
21#include "video_core/renderer_opengl/gl_rasterizer_cache.h" 21#include "video_core/renderer_opengl/gl_rasterizer_cache.h"
22#include "video_core/renderer_opengl/utils.h" 22#include "video_core/renderer_opengl/utils.h"
23#include "video_core/surface.h" 23#include "video_core/surface.h"
24#include "video_core/textures/astc.h" 24#include "video_core/textures/convert.h"
25#include "video_core/textures/decoders.h" 25#include "video_core/textures/decoders.h"
26 26
27namespace OpenGL { 27namespace OpenGL {
@@ -597,103 +597,6 @@ CachedSurface::CachedSurface(const SurfaceParams& params)
597 } 597 }
598} 598}
599 599
600static void ConvertS8Z24ToZ24S8(std::vector<u8>& data, u32 width, u32 height, bool reverse) {
601 union S8Z24 {
602 BitField<0, 24, u32> z24;
603 BitField<24, 8, u32> s8;
604 };
605 static_assert(sizeof(S8Z24) == 4, "S8Z24 is incorrect size");
606
607 union Z24S8 {
608 BitField<0, 8, u32> s8;
609 BitField<8, 24, u32> z24;
610 };
611 static_assert(sizeof(Z24S8) == 4, "Z24S8 is incorrect size");
612
613 S8Z24 s8z24_pixel{};
614 Z24S8 z24s8_pixel{};
615 constexpr auto bpp{GetBytesPerPixel(PixelFormat::S8Z24)};
616 for (std::size_t y = 0; y < height; ++y) {
617 for (std::size_t x = 0; x < width; ++x) {
618 const std::size_t offset{bpp * (y * width + x)};
619 if (reverse) {
620 std::memcpy(&z24s8_pixel, &data[offset], sizeof(Z24S8));
621 s8z24_pixel.s8.Assign(z24s8_pixel.s8);
622 s8z24_pixel.z24.Assign(z24s8_pixel.z24);
623 std::memcpy(&data[offset], &s8z24_pixel, sizeof(S8Z24));
624 } else {
625 std::memcpy(&s8z24_pixel, &data[offset], sizeof(S8Z24));
626 z24s8_pixel.s8.Assign(s8z24_pixel.s8);
627 z24s8_pixel.z24.Assign(s8z24_pixel.z24);
628 std::memcpy(&data[offset], &z24s8_pixel, sizeof(Z24S8));
629 }
630 }
631 }
632}
633
634/**
635 * Helper function to perform software conversion (as needed) when loading a buffer from Switch
636 * memory. This is for Maxwell pixel formats that cannot be represented as-is in OpenGL or with
637 * typical desktop GPUs.
638 */
639static void ConvertFormatAsNeeded_LoadGLBuffer(std::vector<u8>& data, PixelFormat pixel_format,
640 u32 width, u32 height, u32 depth) {
641 switch (pixel_format) {
642 case PixelFormat::ASTC_2D_4X4:
643 case PixelFormat::ASTC_2D_8X8:
644 case PixelFormat::ASTC_2D_8X5:
645 case PixelFormat::ASTC_2D_5X4:
646 case PixelFormat::ASTC_2D_5X5:
647 case PixelFormat::ASTC_2D_4X4_SRGB:
648 case PixelFormat::ASTC_2D_8X8_SRGB:
649 case PixelFormat::ASTC_2D_8X5_SRGB:
650 case PixelFormat::ASTC_2D_5X4_SRGB:
651 case PixelFormat::ASTC_2D_5X5_SRGB:
652 case PixelFormat::ASTC_2D_10X8:
653 case PixelFormat::ASTC_2D_10X8_SRGB: {
654 // Convert ASTC pixel formats to RGBA8, as most desktop GPUs do not support ASTC.
655 u32 block_width{};
656 u32 block_height{};
657 std::tie(block_width, block_height) = GetASTCBlockSize(pixel_format);
658 data =
659 Tegra::Texture::ASTC::Decompress(data, width, height, depth, block_width, block_height);
660 break;
661 }
662 case PixelFormat::S8Z24:
663 // Convert the S8Z24 depth format to Z24S8, as OpenGL does not support S8Z24.
664 ConvertS8Z24ToZ24S8(data, width, height, false);
665 break;
666 }
667}
668
669/**
670 * Helper function to perform software conversion (as needed) when flushing a buffer from OpenGL to
671 * Switch memory. This is for Maxwell pixel formats that cannot be represented as-is in OpenGL or
672 * with typical desktop GPUs.
673 */
674static void ConvertFormatAsNeeded_FlushGLBuffer(std::vector<u8>& data, PixelFormat pixel_format,
675 u32 width, u32 height) {
676 switch (pixel_format) {
677 case PixelFormat::ASTC_2D_4X4:
678 case PixelFormat::ASTC_2D_8X8:
679 case PixelFormat::ASTC_2D_4X4_SRGB:
680 case PixelFormat::ASTC_2D_8X8_SRGB:
681 case PixelFormat::ASTC_2D_5X5:
682 case PixelFormat::ASTC_2D_5X5_SRGB:
683 case PixelFormat::ASTC_2D_10X8:
684 case PixelFormat::ASTC_2D_10X8_SRGB: {
685 LOG_CRITICAL(HW_GPU, "Conversion of format {} after texture flushing is not implemented",
686 static_cast<u32>(pixel_format));
687 UNREACHABLE();
688 break;
689 }
690 case PixelFormat::S8Z24:
691 // Convert the Z24S8 depth format to S8Z24, as OpenGL does not support S8Z24.
692 ConvertS8Z24ToZ24S8(data, width, height, true);
693 break;
694 }
695}
696
697MICROPROFILE_DEFINE(OpenGL_SurfaceLoad, "OpenGL", "Surface Load", MP_RGB(128, 192, 64)); 600MICROPROFILE_DEFINE(OpenGL_SurfaceLoad, "OpenGL", "Surface Load", MP_RGB(128, 192, 64));
698void CachedSurface::LoadGLBuffer() { 601void CachedSurface::LoadGLBuffer() {
699 MICROPROFILE_SCOPE(OpenGL_SurfaceLoad); 602 MICROPROFILE_SCOPE(OpenGL_SurfaceLoad);
@@ -722,8 +625,16 @@ void CachedSurface::LoadGLBuffer() {
722 } 625 }
723 } 626 }
724 for (u32 i = 0; i < params.max_mip_level; i++) { 627 for (u32 i = 0; i < params.max_mip_level; i++) {
725 ConvertFormatAsNeeded_LoadGLBuffer(gl_buffer[i], params.pixel_format, params.MipWidth(i), 628 const u32 width = params.MipWidth(i);
726 params.MipHeight(i), params.MipDepth(i)); 629 const u32 height = params.MipHeight(i);
630 const u32 depth = params.MipDepth(i);
631 if (VideoCore::Surface::IsPixelFormatASTC(params.pixel_format)) {
632 // Reserve size for RGBA8 conversion
633 constexpr std::size_t rgba_bpp = 4;
634 gl_buffer[i].resize(std::max(gl_buffer[i].size(), width * height * depth * rgba_bpp));
635 }
636 Tegra::Texture::ConvertFromGuestToHost(gl_buffer[i].data(), params.pixel_format, width,
637 height, depth, true, true);
727 } 638 }
728} 639}
729 640
@@ -746,8 +657,8 @@ void CachedSurface::FlushGLBuffer() {
746 glGetTextureImage(texture.handle, 0, tuple.format, tuple.type, 657 glGetTextureImage(texture.handle, 0, tuple.format, tuple.type,
747 static_cast<GLsizei>(gl_buffer[0].size()), gl_buffer[0].data()); 658 static_cast<GLsizei>(gl_buffer[0].size()), gl_buffer[0].data());
748 glPixelStorei(GL_PACK_ROW_LENGTH, 0); 659 glPixelStorei(GL_PACK_ROW_LENGTH, 0);
749 ConvertFormatAsNeeded_FlushGLBuffer(gl_buffer[0], params.pixel_format, params.width, 660 Tegra::Texture::ConvertFromHostToGuest(gl_buffer[0].data(), params.pixel_format, params.width,
750 params.height); 661 params.height, params.depth, true, true);
751 const u8* const texture_src_data = Memory::GetPointer(params.addr); 662 const u8* const texture_src_data = Memory::GetPointer(params.addr);
752 ASSERT(texture_src_data); 663 ASSERT(texture_src_data);
753 if (params.is_tiled) { 664 if (params.is_tiled) {