From 07f7ce1da2e86e862b1254a5f543af5ae76d1b43 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 28 Apr 2019 18:03:41 -0300 Subject: [PATCH] gl_rasterizer_cache: Use texture buffers to emulate texture buffers --- .../renderer_opengl/gl_rasterizer_cache.cpp | 37 ++++++++++++++----- .../renderer_opengl/gl_rasterizer_cache.h | 3 ++ .../renderer_opengl/renderer_opengl.cpp | 1 - src/video_core/surface.cpp | 4 +- src/video_core/surface.h | 1 + 5 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 543b36271..e27da1fa7 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -149,6 +149,7 @@ std::size_t SurfaceParams::InnerMemorySize(bool force_gl, bool layer_only, switch (params.target) { case SurfaceTarget::Texture1D: + case SurfaceTarget::TextureBuffer: case SurfaceTarget::Texture2D: params.depth = 1; break; @@ -389,6 +390,8 @@ static GLenum SurfaceTargetToGL(SurfaceTarget target) { switch (target) { case SurfaceTarget::Texture1D: return GL_TEXTURE_1D; + case SurfaceTarget::TextureBuffer: + return GL_TEXTURE_BUFFER; case SurfaceTarget::Texture2D: return GL_TEXTURE_2D; case SurfaceTarget::Texture3D: @@ -600,29 +603,35 @@ CachedSurface::CachedSurface(const SurfaceParams& params) switch (params.target) { case SurfaceTarget::Texture1D: - glTextureStorage1D(texture.handle, params.max_mip_level, format_tuple.internal_format, - width); + glTextureStorage1D(texture.handle, params.max_mip_level, gl_internal_format, width); + break; + case SurfaceTarget::TextureBuffer: + texture_buffer.Create(); + glNamedBufferStorage(texture_buffer.handle, + params.width * GetBytesPerPixel(params.pixel_format), nullptr, + GL_DYNAMIC_STORAGE_BIT); + glTextureBuffer(texture.handle, gl_internal_format, texture_buffer.handle); break; case SurfaceTarget::Texture2D: case SurfaceTarget::TextureCubemap: - glTextureStorage2D(texture.handle, params.max_mip_level, format_tuple.internal_format, - width, height); + glTextureStorage2D(texture.handle, params.max_mip_level, gl_internal_format, width, height); break; case SurfaceTarget::Texture3D: case SurfaceTarget::Texture2DArray: case SurfaceTarget::TextureCubeArray: - glTextureStorage3D(texture.handle, params.max_mip_level, format_tuple.internal_format, - width, height, params.depth); + glTextureStorage3D(texture.handle, params.max_mip_level, gl_internal_format, width, height, + params.depth); break; default: LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", static_cast(params.target)); UNREACHABLE(); - glTextureStorage2D(texture.handle, params.max_mip_level, format_tuple.internal_format, - width, height); + glTextureStorage2D(texture.handle, params.max_mip_level, gl_internal_format, width, height); } - ApplyTextureDefaults(texture.handle, params.max_mip_level); + if (params.target != SurfaceTarget::TextureBuffer) { + ApplyTextureDefaults(texture.handle, params.max_mip_level); + } OpenGL::LabelGLObject(GL_TEXTURE, texture.handle, params.gpu_addr, params.IdentityString()); } @@ -785,6 +794,13 @@ void CachedSurface::UploadGLMipmapTexture(RasterizerTemporaryMemory& res_cache_t glTextureSubImage1D(texture.handle, mip_map, x0, static_cast(rect.GetWidth()), tuple.format, tuple.type, &gl_buffer[mip_map][buffer_offset]); break; + case SurfaceTarget::TextureBuffer: + ASSERT(mip_map == 0); + glNamedBufferSubData(texture_buffer.handle, x0, + static_cast(rect.GetWidth()) * + GetBytesPerPixel(params.pixel_format), + &gl_buffer[mip_map][buffer_offset]); + break; case SurfaceTarget::Texture2D: glTextureSubImage2D(texture.handle, mip_map, x0, y0, static_cast(rect.GetWidth()), @@ -860,6 +876,9 @@ void CachedSurface::UpdateSwizzle(Tegra::Texture::SwizzleSource swizzle_x, Tegra::Texture::SwizzleSource swizzle_y, Tegra::Texture::SwizzleSource swizzle_z, Tegra::Texture::SwizzleSource swizzle_w) { + if (params.target == SurfaceTarget::TextureBuffer) { + return; + } const GLenum new_x = MaxwellToGL::SwizzleSource(swizzle_x); const GLenum new_y = MaxwellToGL::SwizzleSource(swizzle_y); const GLenum new_z = MaxwellToGL::SwizzleSource(swizzle_z); diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 6263ef3e7..bbab79575 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -250,6 +250,8 @@ struct SurfaceParams { switch (target) { case SurfaceTarget::Texture1D: return "1D"; + case SurfaceTarget::TextureBuffer: + return "Buffer"; case SurfaceTarget::Texture2D: return "2D"; case SurfaceTarget::Texture3D: @@ -439,6 +441,7 @@ private: OGLTexture texture; OGLTexture discrepant_view; + OGLBuffer texture_buffer; SurfaceParams params{}; GLenum gl_target{}; GLenum gl_internal_format{}; diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index aafd6f31b..b142521ec 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -471,7 +471,6 @@ static void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum } } -/// Initialize the renderer bool RendererOpenGL::Init() { Core::Frontend::ScopeAcquireWindowContext acquire_context{render_window}; diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp index 56c43af17..52a79e4a7 100644 --- a/src/video_core/surface.cpp +++ b/src/video_core/surface.cpp @@ -13,7 +13,7 @@ SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_t case Tegra::Texture::TextureType::Texture1D: return SurfaceTarget::Texture1D; case Tegra::Texture::TextureType::Texture1DBuffer: - return SurfaceTarget::Texture1D; // Fixme + return SurfaceTarget::TextureBuffer; case Tegra::Texture::TextureType::Texture2D: case Tegra::Texture::TextureType::Texture2DNoMipmap: return SurfaceTarget::Texture2D; @@ -37,6 +37,7 @@ SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_t bool SurfaceTargetIsLayered(SurfaceTarget target) { switch (target) { case SurfaceTarget::Texture1D: + case SurfaceTarget::TextureBuffer: case SurfaceTarget::Texture2D: case SurfaceTarget::Texture3D: return false; @@ -55,6 +56,7 @@ bool SurfaceTargetIsLayered(SurfaceTarget target) { bool SurfaceTargetIsArray(SurfaceTarget target) { switch (target) { case SurfaceTarget::Texture1D: + case SurfaceTarget::TextureBuffer: case SurfaceTarget::Texture2D: case SurfaceTarget::Texture3D: case SurfaceTarget::TextureCubemap: diff --git a/src/video_core/surface.h b/src/video_core/surface.h index 5d49214e5..959504cd3 100644 --- a/src/video_core/surface.h +++ b/src/video_core/surface.h @@ -114,6 +114,7 @@ enum class SurfaceType { enum class SurfaceTarget { Texture1D, + TextureBuffer, Texture2D, Texture3D, Texture1DArray,