diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 022561d43..bd4330327 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -60,6 +60,9 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) { case SurfaceTarget::Texture2D: params.depth = 1; break; + case SurfaceTarget::TextureCubemap: + params.depth = config.tic.Depth() * 6; + break; case SurfaceTarget::Texture3D: params.depth = config.tic.Depth(); break; @@ -562,6 +565,7 @@ CachedSurface::CachedSurface(const SurfaceParams& params) rect.GetWidth()); break; case SurfaceParams::SurfaceTarget::Texture2D: + case SurfaceParams::SurfaceTarget::TextureCubemap: glTexStorage2D(SurfaceTargetToGL(params.target), 1, format_tuple.internal_format, rect.GetWidth(), rect.GetHeight()); break; @@ -680,6 +684,7 @@ void CachedSurface::LoadGLBuffer() { // Pass impl. to the fallback code below break; case SurfaceParams::SurfaceTarget::Texture2DArray: + case SurfaceParams::SurfaceTarget::TextureCubemap: for (std::size_t index = 0; index < params.depth; ++index) { const std::size_t offset{index * copy_size}; morton_to_gl_fns[static_cast(params.pixel_format)]( @@ -724,7 +729,7 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle // Load data from memory to the surface const GLint x0 = static_cast(rect.left); const GLint y0 = static_cast(rect.bottom); - const std::size_t buffer_offset = + std::size_t buffer_offset = static_cast(static_cast(y0) * params.width + static_cast(x0)) * GetGLBytesPerPixel(params.pixel_format); @@ -763,6 +768,16 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle static_cast(params.depth), 0, static_cast(params.size_in_bytes_total), &gl_buffer[buffer_offset]); break; + case SurfaceParams::SurfaceTarget::TextureCubemap: + for (std::size_t face = 0; face < params.depth; ++face) { + glCompressedTexImage2D(static_cast(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face), + 0, tuple.internal_format, static_cast(params.width), + static_cast(params.height), 0, + static_cast(params.size_in_bytes_2d), + &gl_buffer[buffer_offset]); + buffer_offset += params.size_in_bytes_2d; + } + break; default: LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", static_cast(params.target)); @@ -793,6 +808,15 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle static_cast(rect.GetHeight()), params.depth, tuple.format, tuple.type, &gl_buffer[buffer_offset]); break; + case SurfaceParams::SurfaceTarget::TextureCubemap: + for (std::size_t face = 0; face < params.depth; ++face) { + glTexSubImage2D(static_cast(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face), 0, x0, + y0, static_cast(rect.GetWidth()), + static_cast(rect.GetHeight()), tuple.format, tuple.type, + &gl_buffer[buffer_offset]); + buffer_offset += params.size_in_bytes_2d; + } + break; default: LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", static_cast(params.target)); @@ -989,6 +1013,15 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface, static_cast(new_params.depth), dest_format.format, dest_format.type, nullptr); break; + case SurfaceParams::SurfaceTarget::TextureCubemap: + for (std::size_t face = 0; face < new_params.depth; ++face) { + glTextureSubImage3D( + new_surface->Texture().handle, 0, 0, 0, static_cast(face), + static_cast(dest_rect.GetWidth()), + static_cast(dest_rect.GetHeight()), static_cast(1), + dest_format.format, dest_format.type, nullptr); + } + break; default: LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", static_cast(new_params.target)); diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 2aed83bbc..e2fd0009e 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -127,6 +127,8 @@ struct SurfaceParams { case Tegra::Texture::TextureType::Texture2D: case Tegra::Texture::TextureType::Texture2DNoMipmap: return SurfaceTarget::Texture2D; + case Tegra::Texture::TextureType::TextureCubemap: + return SurfaceTarget::TextureCubemap; case Tegra::Texture::TextureType::Texture1DArray: return SurfaceTarget::Texture1DArray; case Tegra::Texture::TextureType::Texture2DArray: