From 678c18aa5cca65042d3b91b655fd713f37304592 Mon Sep 17 00:00:00 2001
From: FernandoS27 <fsahmkow27@gmail.com>
Date: Thu, 18 Oct 2018 20:04:43 -0400
Subject: [PATCH] Implement Cube Arrays

---
 .../renderer_opengl/gl_rasterizer_cache.cpp        | 14 ++++++++++++++
 .../renderer_opengl/gl_rasterizer_cache.h          |  2 ++
 src/video_core/surface.cpp                         |  3 +++
 src/video_core/surface.h                           |  1 +
 4 files changed, 20 insertions(+)

diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index f194a76872..752c4ee84f 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -128,6 +128,13 @@ std::size_t SurfaceParams::InnerMemorySize(bool force_gl, bool layer_only,
             params.target = SurfaceTarget::Texture2D;
         }
         break;
+    case SurfaceTarget::TextureCubeArray:
+        params.depth = config.tic.Depth() * 6;
+        if (!entry.IsArray()) {
+            ASSERT(params.depth == 6);
+            params.target = SurfaceTarget::TextureCubemap;
+        }
+        break;
     default:
         LOG_CRITICAL(HW_GPU, "Unknown depth for target={}", static_cast<u32>(params.target));
         UNREACHABLE();
@@ -334,6 +341,8 @@ static GLenum SurfaceTargetToGL(SurfaceTarget target) {
         return GL_TEXTURE_2D_ARRAY;
     case SurfaceTarget::TextureCubemap:
         return GL_TEXTURE_CUBE_MAP;
+    case SurfaceTarget::TextureCubeArray:
+        return GL_TEXTURE_CUBE_MAP_ARRAY_ARB;
     }
     LOG_CRITICAL(Render_OpenGL, "Unimplemented texture target={}", static_cast<u32>(target));
     UNREACHABLE();
@@ -754,6 +763,7 @@ static void CopySurface(const Surface& src_surface, const Surface& dst_surface,
             break;
         case SurfaceTarget::Texture3D:
         case SurfaceTarget::Texture2DArray:
+        case SurfaceTarget::TextureCubeArray:
             glTextureSubImage3D(dst_surface->Texture().handle, 0, 0, 0, 0, width, height,
                                 static_cast<GLsizei>(dst_params.depth), dest_format.format,
                                 dest_format.type, nullptr);
@@ -806,6 +816,7 @@ CachedSurface::CachedSurface(const SurfaceParams& params)
             break;
         case SurfaceTarget::Texture3D:
         case SurfaceTarget::Texture2DArray:
+        case SurfaceTarget::TextureCubeArray:
             glTexStorage3D(SurfaceTargetToGL(params.target), params.max_mip_level,
                            format_tuple.internal_format, rect.GetWidth(), rect.GetHeight(),
                            params.depth);
@@ -1055,6 +1066,7 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle,
                                    &gl_buffer[mip_map][buffer_offset]);
             break;
         case SurfaceTarget::Texture2DArray:
+        case SurfaceTarget::TextureCubeArray:
             glCompressedTexImage3D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format,
                                    static_cast<GLsizei>(params.MipWidth(mip_map)),
                                    static_cast<GLsizei>(params.MipHeight(mip_map)),
@@ -1104,6 +1116,7 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle,
                             tuple.format, tuple.type, &gl_buffer[mip_map][buffer_offset]);
             break;
         case SurfaceTarget::Texture2DArray:
+        case SurfaceTarget::TextureCubeArray:
             glTexSubImage3D(SurfaceTargetToGL(params.target), mip_map, x0, y0, 0,
                             static_cast<GLsizei>(rect.GetWidth()),
                             static_cast<GLsizei>(rect.GetHeight()), params.depth, tuple.format,
@@ -1306,6 +1319,7 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface,
         break;
     case SurfaceTarget::TextureCubemap:
     case SurfaceTarget::Texture3D:
+    case SurfaceTarget::TextureCubeArray:
         AccurateCopySurface(old_surface, new_surface);
         break;
     default:
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index f255f4419c..5a5f2cec0f 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -49,6 +49,8 @@ struct SurfaceParams {
             return "Texture2DArray";
         case SurfaceTarget::TextureCubemap:
             return "TextureCubemap";
+        case SurfaceTarget::TextureCubeArray:
+            return "TextureCubeArray";
         default:
             LOG_CRITICAL(HW_GPU, "Unimplemented surface_target={}", static_cast<u32>(target));
             UNREACHABLE();
diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp
index d9a97e30b9..e6941b95f6 100644
--- a/src/video_core/surface.cpp
+++ b/src/video_core/surface.cpp
@@ -19,6 +19,8 @@ SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_t
         return SurfaceTarget::Texture3D;
     case Tegra::Texture::TextureType::TextureCubemap:
         return SurfaceTarget::TextureCubemap;
+    case Tegra::Texture::TextureType::TextureCubeArray:
+        return SurfaceTarget::TextureCubeArray;
     case Tegra::Texture::TextureType::Texture1DArray:
         return SurfaceTarget::Texture1DArray;
     case Tegra::Texture::TextureType::Texture2DArray:
@@ -39,6 +41,7 @@ bool SurfaceTargetIsLayered(SurfaceTarget target) {
     case SurfaceTarget::Texture1DArray:
     case SurfaceTarget::Texture2DArray:
     case SurfaceTarget::TextureCubemap:
+    case SurfaceTarget::TextureCubeArray:
         return true;
     default:
         LOG_CRITICAL(HW_GPU, "Unimplemented surface_target={}", static_cast<u32>(target));
diff --git a/src/video_core/surface.h b/src/video_core/surface.h
index 3232e437f3..25300a193c 100644
--- a/src/video_core/surface.h
+++ b/src/video_core/surface.h
@@ -118,6 +118,7 @@ enum class SurfaceTarget {
     Texture1DArray,
     Texture2DArray,
     TextureCubemap,
+    TextureCubeArray,
 };
 
 /**
-- 
GitLab