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;