From ac78b74c45569ab5460d5458b75a1c817dbaa9bb Mon Sep 17 00:00:00 2001 From: GPUCode <47210458+GPUCode@users.noreply.github.com> Date: Tue, 8 Aug 2023 01:10:28 +0300 Subject: [PATCH] gl_texture_runtime: Implement ARB_clear_texture (#6850) --- .../renderer_opengl/gl_texture_runtime.cpp | 39 +++++++++++++++++-- .../renderer_opengl/gl_texture_runtime.h | 5 ++- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_texture_runtime.cpp b/src/video_core/renderer_opengl/gl_texture_runtime.cpp index e7ca8179f..3fdb625f1 100644 --- a/src/video_core/renderer_opengl/gl_texture_runtime.cpp +++ b/src/video_core/renderer_opengl/gl_texture_runtime.cpp @@ -187,7 +187,41 @@ bool TextureRuntime::Reinterpret(Surface& source, Surface& dest, return true; } -bool TextureRuntime::ClearTexture(Surface& surface, const VideoCore::TextureClear& clear) { +bool TextureRuntime::ClearTextureWithoutFbo(Surface& surface, + const VideoCore::TextureClear& clear) { + if (!driver.HasArbClearTexture()) { + return false; + } + GLenum format{}; + GLenum type{}; + switch (surface.type) { + case SurfaceType::Color: + case SurfaceType::Texture: + format = GL_RGBA; + type = GL_FLOAT; + break; + case SurfaceType::Depth: + format = GL_DEPTH_COMPONENT; + type = GL_FLOAT; + break; + case SurfaceType::DepthStencil: + format = GL_DEPTH_STENCIL; + type = GL_FLOAT_32_UNSIGNED_INT_24_8_REV; + break; + default: + UNREACHABLE_MSG("Unknown surface type {}", surface.type); + } + glClearTexSubImage(surface.Handle(), clear.texture_level, clear.texture_rect.left, + clear.texture_rect.bottom, 0, clear.texture_rect.GetWidth(), + clear.texture_rect.GetHeight(), 1, format, type, &clear.value); + return true; +} + +void TextureRuntime::ClearTexture(Surface& surface, const VideoCore::TextureClear& clear) { + if (ClearTextureWithoutFbo(surface, clear)) { + return; + } + OpenGLState state = OpenGLState::GetCurState(); state.scissor.enabled = true; state.scissor.x = clear.texture_rect.left; @@ -222,10 +256,7 @@ bool TextureRuntime::ClearTexture(Surface& surface, const VideoCore::TextureClea break; default: UNREACHABLE_MSG("Unknown surface type {}", surface.type); - return false; } - - return true; } bool TextureRuntime::CopyTextures(Surface& source, Surface& dest, diff --git a/src/video_core/renderer_opengl/gl_texture_runtime.h b/src/video_core/renderer_opengl/gl_texture_runtime.h index 02914624b..b9a971c2d 100644 --- a/src/video_core/renderer_opengl/gl_texture_runtime.h +++ b/src/video_core/renderer_opengl/gl_texture_runtime.h @@ -59,7 +59,7 @@ public: bool Reinterpret(Surface& source, Surface& dest, const VideoCore::TextureBlit& blit); /// Fills the rectangle of the texture with the clear value provided - bool ClearTexture(Surface& surface, const VideoCore::TextureClear& clear); + void ClearTexture(Surface& surface, const VideoCore::TextureClear& clear); /// Copies a rectangle of source to another rectange of dest bool CopyTextures(Surface& source, Surface& dest, const VideoCore::TextureCopy& copy); @@ -76,6 +76,9 @@ private: return driver; } + /// Fills the rectangle of the surface with the value provided, without an fbo. + bool ClearTextureWithoutFbo(Surface& surface, const VideoCore::TextureClear& clear); + private: const Driver& driver; BlitHelper blit_helper;