summaryrefslogtreecommitdiff
path: root/src/video_core
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-01-06 18:49:23 -0300
committerGravatar ReinUsesLisp2019-01-30 19:10:11 -0300
commit4b676e7786f03a86fd1ecae50eae61098fd3766d (patch)
tree34ac3f96aea40f31bf00b3668a83f148e37ead45 /src/video_core
parentMerge pull request #1485 from FernandoS27/render-info (diff)
downloadyuzu-4b676e7786f03a86fd1ecae50eae61098fd3766d.tar.gz
yuzu-4b676e7786f03a86fd1ecae50eae61098fd3766d.tar.xz
yuzu-4b676e7786f03a86fd1ecae50eae61098fd3766d.zip
gl_rasterizer: Use DSA for textures
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp221
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h1
-rw-r--r--src/video_core/renderer_opengl/gl_resource_manager.cpp4
-rw-r--r--src/video_core/renderer_opengl/gl_resource_manager.h2
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp62
5 files changed, 105 insertions, 185 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 2b9c4628f..a3c782972 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -18,7 +18,6 @@
18#include "video_core/morton.h" 18#include "video_core/morton.h"
19#include "video_core/renderer_opengl/gl_rasterizer.h" 19#include "video_core/renderer_opengl/gl_rasterizer.h"
20#include "video_core/renderer_opengl/gl_rasterizer_cache.h" 20#include "video_core/renderer_opengl/gl_rasterizer_cache.h"
21#include "video_core/renderer_opengl/gl_state.h"
22#include "video_core/renderer_opengl/utils.h" 21#include "video_core/renderer_opengl/utils.h"
23#include "video_core/surface.h" 22#include "video_core/surface.h"
24#include "video_core/textures/astc.h" 23#include "video_core/textures/astc.h"
@@ -44,14 +43,14 @@ struct FormatTuple {
44 bool compressed; 43 bool compressed;
45}; 44};
46 45
47static void ApplyTextureDefaults(GLenum target, u32 max_mip_level) { 46static void ApplyTextureDefaults(GLuint texture, u32 max_mip_level) {
48 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 47 glTextureParameteri(texture, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
49 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 48 glTextureParameteri(texture, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
50 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 49 glTextureParameteri(texture, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
51 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 50 glTextureParameteri(texture, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
52 glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, max_mip_level - 1); 51 glTextureParameteri(texture, GL_TEXTURE_MAX_LEVEL, max_mip_level - 1);
53 if (max_mip_level == 1) { 52 if (max_mip_level == 1) {
54 glTexParameterf(target, GL_TEXTURE_LOD_BIAS, 1000.0); 53 glTextureParameterf(texture, GL_TEXTURE_LOD_BIAS, 1000.0);
55 } 54 }
56} 55}
57 56
@@ -529,55 +528,41 @@ static void CopySurface(const Surface& src_surface, const Surface& dst_surface,
529CachedSurface::CachedSurface(const SurfaceParams& params) 528CachedSurface::CachedSurface(const SurfaceParams& params)
530 : params(params), gl_target(SurfaceTargetToGL(params.target)), 529 : params(params), gl_target(SurfaceTargetToGL(params.target)),
531 cached_size_in_bytes(params.size_in_bytes) { 530 cached_size_in_bytes(params.size_in_bytes) {
532 texture.Create(); 531 texture.Create(gl_target);
533 const auto& rect{params.GetRect()}; 532
534 533 // TODO(Rodrigo): Using params.GetRect() returns a different size than using its Mip*(0)
535 // Keep track of previous texture bindings 534 // alternatives. This signals a bug on those functions.
536 OpenGLState cur_state = OpenGLState::GetCurState(); 535 const auto width = static_cast<GLsizei>(params.MipWidth(0));
537 const auto& old_tex = cur_state.texture_units[0]; 536 const auto height = static_cast<GLsizei>(params.MipHeight(0));
538 SCOPE_EXIT({
539 cur_state.texture_units[0] = old_tex;
540 cur_state.Apply();
541 });
542
543 cur_state.texture_units[0].texture = texture.handle;
544 cur_state.texture_units[0].target = SurfaceTargetToGL(params.target);
545 cur_state.Apply();
546 glActiveTexture(GL_TEXTURE0);
547 537
548 const auto& format_tuple = GetFormatTuple(params.pixel_format, params.component_type); 538 const auto& format_tuple = GetFormatTuple(params.pixel_format, params.component_type);
549 gl_internal_format = format_tuple.internal_format; 539 gl_internal_format = format_tuple.internal_format;
550 gl_is_compressed = format_tuple.compressed;
551 540
552 if (!format_tuple.compressed) { 541 switch (params.target) {
553 // Only pre-create the texture for non-compressed textures. 542 case SurfaceTarget::Texture1D:
554 switch (params.target) { 543 glTextureStorage1D(texture.handle, params.max_mip_level, format_tuple.internal_format,
555 case SurfaceTarget::Texture1D: 544 width);
556 glTexStorage1D(SurfaceTargetToGL(params.target), params.max_mip_level, 545 break;
557 format_tuple.internal_format, rect.GetWidth()); 546 case SurfaceTarget::Texture2D:
558 break; 547 case SurfaceTarget::TextureCubemap:
559 case SurfaceTarget::Texture2D: 548 glTextureStorage2D(texture.handle, params.max_mip_level, format_tuple.internal_format,
560 case SurfaceTarget::TextureCubemap: 549 width, height);
561 glTexStorage2D(SurfaceTargetToGL(params.target), params.max_mip_level, 550 break;
562 format_tuple.internal_format, rect.GetWidth(), rect.GetHeight()); 551 case SurfaceTarget::Texture3D:
563 break; 552 case SurfaceTarget::Texture2DArray:
564 case SurfaceTarget::Texture3D: 553 case SurfaceTarget::TextureCubeArray:
565 case SurfaceTarget::Texture2DArray: 554 glTextureStorage3D(texture.handle, params.max_mip_level, format_tuple.internal_format,
566 case SurfaceTarget::TextureCubeArray: 555 width, height, params.depth);
567 glTexStorage3D(SurfaceTargetToGL(params.target), params.max_mip_level, 556 break;
568 format_tuple.internal_format, rect.GetWidth(), rect.GetHeight(), 557 default:
569 params.depth); 558 LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}",
570 break; 559 static_cast<u32>(params.target));
571 default: 560 UNREACHABLE();
572 LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", 561 glTextureStorage2D(texture.handle, params.max_mip_level, format_tuple.internal_format,
573 static_cast<u32>(params.target)); 562 width, height);
574 UNREACHABLE();
575 glTexStorage2D(GL_TEXTURE_2D, params.max_mip_level, format_tuple.internal_format,
576 rect.GetWidth(), rect.GetHeight());
577 }
578 } 563 }
579 564
580 ApplyTextureDefaults(SurfaceTargetToGL(params.target), params.max_mip_level); 565 ApplyTextureDefaults(texture.handle, params.max_mip_level);
581 566
582 OpenGL::LabelGLObject(GL_TEXTURE, texture.handle, params.addr, params.IdentityString()); 567 OpenGL::LabelGLObject(GL_TEXTURE, texture.handle, params.addr, params.IdentityString());
583 568
@@ -752,63 +737,50 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle,
752 const auto& rect{params.GetRect(mip_map)}; 737 const auto& rect{params.GetRect(mip_map)};
753 738
754 // Load data from memory to the surface 739 // Load data from memory to the surface
755 const GLint x0 = static_cast<GLint>(rect.left); 740 const auto x0 = static_cast<GLint>(rect.left);
756 const GLint y0 = static_cast<GLint>(rect.bottom); 741 const auto y0 = static_cast<GLint>(rect.bottom);
757 std::size_t buffer_offset = 742 auto buffer_offset =
758 static_cast<std::size_t>(static_cast<std::size_t>(y0) * params.MipWidth(mip_map) + 743 static_cast<std::size_t>(static_cast<std::size_t>(y0) * params.MipWidth(mip_map) +
759 static_cast<std::size_t>(x0)) * 744 static_cast<std::size_t>(x0)) *
760 GetBytesPerPixel(params.pixel_format); 745 GetBytesPerPixel(params.pixel_format);
761 746
762 const FormatTuple& tuple = GetFormatTuple(params.pixel_format, params.component_type); 747 const FormatTuple& tuple = GetFormatTuple(params.pixel_format, params.component_type);
763 const GLuint target_tex = texture.handle;
764 OpenGLState cur_state = OpenGLState::GetCurState();
765
766 const auto& old_tex = cur_state.texture_units[0];
767 SCOPE_EXIT({
768 cur_state.texture_units[0] = old_tex;
769 cur_state.Apply();
770 });
771 cur_state.texture_units[0].texture = target_tex;
772 cur_state.texture_units[0].target = SurfaceTargetToGL(params.target);
773 cur_state.Apply();
774 748
775 // Ensure no bad interactions with GL_UNPACK_ALIGNMENT 749 // Ensure no bad interactions with GL_UNPACK_ALIGNMENT
776 ASSERT(params.MipWidth(mip_map) * GetBytesPerPixel(params.pixel_format) % 4 == 0); 750 ASSERT(params.MipWidth(mip_map) * GetBytesPerPixel(params.pixel_format) % 4 == 0);
777 glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast<GLint>(params.MipWidth(mip_map))); 751 glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast<GLint>(params.MipWidth(mip_map)));
778 752
779 GLsizei image_size = static_cast<GLsizei>(params.GetMipmapSizeGL(mip_map, false)); 753 const auto image_size = static_cast<GLsizei>(params.GetMipmapSizeGL(mip_map, false));
780 glActiveTexture(GL_TEXTURE0);
781 if (tuple.compressed) { 754 if (tuple.compressed) {
782 switch (params.target) { 755 switch (params.target) {
783 case SurfaceTarget::Texture2D: 756 case SurfaceTarget::Texture2D:
784 glCompressedTexImage2D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format, 757 glCompressedTextureSubImage2D(
785 static_cast<GLsizei>(params.MipWidth(mip_map)), 758 texture.handle, mip_map, 0, 0, static_cast<GLsizei>(params.MipWidth(mip_map)),
786 static_cast<GLsizei>(params.MipHeight(mip_map)), 0, image_size, 759 static_cast<GLsizei>(params.MipHeight(mip_map)), tuple.internal_format, image_size,
787 &gl_buffer[mip_map][buffer_offset]); 760 &gl_buffer[mip_map][buffer_offset]);
788 break; 761 break;
789 case SurfaceTarget::Texture3D: 762 case SurfaceTarget::Texture3D:
790 glCompressedTexImage3D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format, 763 glCompressedTextureSubImage3D(
791 static_cast<GLsizei>(params.MipWidth(mip_map)), 764 texture.handle, mip_map, 0, 0, 0, static_cast<GLsizei>(params.MipWidth(mip_map)),
792 static_cast<GLsizei>(params.MipHeight(mip_map)), 765 static_cast<GLsizei>(params.MipHeight(mip_map)),
793 static_cast<GLsizei>(params.MipDepth(mip_map)), 0, image_size, 766 static_cast<GLsizei>(params.MipDepth(mip_map)), tuple.internal_format, image_size,
794 &gl_buffer[mip_map][buffer_offset]); 767 &gl_buffer[mip_map][buffer_offset]);
795 break; 768 break;
796 case SurfaceTarget::Texture2DArray: 769 case SurfaceTarget::Texture2DArray:
797 case SurfaceTarget::TextureCubeArray: 770 case SurfaceTarget::TextureCubeArray:
798 glCompressedTexImage3D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format, 771 glCompressedTextureSubImage3D(
799 static_cast<GLsizei>(params.MipWidth(mip_map)), 772 texture.handle, mip_map, 0, 0, 0, static_cast<GLsizei>(params.MipWidth(mip_map)),
800 static_cast<GLsizei>(params.MipHeight(mip_map)), 773 static_cast<GLsizei>(params.MipHeight(mip_map)), static_cast<GLsizei>(params.depth),
801 static_cast<GLsizei>(params.depth), 0, image_size, 774 tuple.internal_format, image_size, &gl_buffer[mip_map][buffer_offset]);
802 &gl_buffer[mip_map][buffer_offset]);
803 break; 775 break;
804 case SurfaceTarget::TextureCubemap: { 776 case SurfaceTarget::TextureCubemap: {
805 GLsizei layer_size = static_cast<GLsizei>(params.LayerSizeGL(mip_map)); 777 const auto layer_size = static_cast<GLsizei>(params.LayerSizeGL(mip_map));
806 for (std::size_t face = 0; face < params.depth; ++face) { 778 for (std::size_t face = 0; face < params.depth; ++face) {
807 glCompressedTexImage2D(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face), 779 glCompressedTextureSubImage3D(
808 mip_map, tuple.internal_format, 780 texture.handle, mip_map, 0, 0, static_cast<GLint>(face),
809 static_cast<GLsizei>(params.MipWidth(mip_map)), 781 static_cast<GLsizei>(params.MipWidth(mip_map)),
810 static_cast<GLsizei>(params.MipHeight(mip_map)), 0, 782 static_cast<GLsizei>(params.MipHeight(mip_map)), 1, tuple.internal_format,
811 layer_size, &gl_buffer[mip_map][buffer_offset]); 783 layer_size, &gl_buffer[mip_map][buffer_offset]);
812 buffer_offset += layer_size; 784 buffer_offset += layer_size;
813 } 785 }
814 break; 786 break;
@@ -817,46 +789,43 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle,
817 LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", 789 LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}",
818 static_cast<u32>(params.target)); 790 static_cast<u32>(params.target));
819 UNREACHABLE(); 791 UNREACHABLE();
820 glCompressedTexImage2D(GL_TEXTURE_2D, mip_map, tuple.internal_format, 792 glCompressedTextureSubImage2D(
821 static_cast<GLsizei>(params.MipWidth(mip_map)), 793 texture.handle, mip_map, 0, 0, static_cast<GLsizei>(params.MipWidth(mip_map)),
822 static_cast<GLsizei>(params.MipHeight(mip_map)), 0, 794 static_cast<GLsizei>(params.MipHeight(mip_map)), tuple.internal_format,
823 static_cast<GLsizei>(params.size_in_bytes_gl), 795 static_cast<GLsizei>(params.size_in_bytes_gl), &gl_buffer[mip_map][buffer_offset]);
824 &gl_buffer[mip_map][buffer_offset]);
825 } 796 }
826 } else { 797 } else {
827
828 switch (params.target) { 798 switch (params.target) {
829 case SurfaceTarget::Texture1D: 799 case SurfaceTarget::Texture1D:
830 glTexSubImage1D(SurfaceTargetToGL(params.target), mip_map, x0, 800 glTextureSubImage1D(texture.handle, mip_map, x0, static_cast<GLsizei>(rect.GetWidth()),
831 static_cast<GLsizei>(rect.GetWidth()), tuple.format, tuple.type, 801 tuple.format, tuple.type, &gl_buffer[mip_map][buffer_offset]);
832 &gl_buffer[mip_map][buffer_offset]);
833 break; 802 break;
834 case SurfaceTarget::Texture2D: 803 case SurfaceTarget::Texture2D:
835 glTexSubImage2D(SurfaceTargetToGL(params.target), mip_map, x0, y0, 804 glTextureSubImage2D(texture.handle, mip_map, x0, y0,
836 static_cast<GLsizei>(rect.GetWidth()), 805 static_cast<GLsizei>(rect.GetWidth()),
837 static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type, 806 static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type,
838 &gl_buffer[mip_map][buffer_offset]); 807 &gl_buffer[mip_map][buffer_offset]);
839 break; 808 break;
840 case SurfaceTarget::Texture3D: 809 case SurfaceTarget::Texture3D:
841 glTexSubImage3D(SurfaceTargetToGL(params.target), mip_map, x0, y0, 0, 810 glTextureSubImage3D(texture.handle, mip_map, x0, y0, 0,
842 static_cast<GLsizei>(rect.GetWidth()), 811 static_cast<GLsizei>(rect.GetWidth()),
843 static_cast<GLsizei>(rect.GetHeight()), params.MipDepth(mip_map), 812 static_cast<GLsizei>(rect.GetHeight()), params.MipDepth(mip_map),
844 tuple.format, tuple.type, &gl_buffer[mip_map][buffer_offset]); 813 tuple.format, tuple.type, &gl_buffer[mip_map][buffer_offset]);
845 break; 814 break;
846 case SurfaceTarget::Texture2DArray: 815 case SurfaceTarget::Texture2DArray:
847 case SurfaceTarget::TextureCubeArray: 816 case SurfaceTarget::TextureCubeArray:
848 glTexSubImage3D(SurfaceTargetToGL(params.target), mip_map, x0, y0, 0, 817 glTextureSubImage3D(texture.handle, mip_map, x0, y0, 0,
849 static_cast<GLsizei>(rect.GetWidth()), 818 static_cast<GLsizei>(rect.GetWidth()),
850 static_cast<GLsizei>(rect.GetHeight()), params.depth, tuple.format, 819 static_cast<GLsizei>(rect.GetHeight()), params.depth, tuple.format,
851 tuple.type, &gl_buffer[mip_map][buffer_offset]); 820 tuple.type, &gl_buffer[mip_map][buffer_offset]);
852 break; 821 break;
853 case SurfaceTarget::TextureCubemap: { 822 case SurfaceTarget::TextureCubemap: {
854 std::size_t start = buffer_offset; 823 std::size_t start = buffer_offset;
855 for (std::size_t face = 0; face < params.depth; ++face) { 824 for (std::size_t face = 0; face < params.depth; ++face) {
856 glTexSubImage2D(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face), mip_map, 825 glTextureSubImage3D(texture.handle, mip_map, x0, y0, static_cast<GLint>(face),
857 x0, y0, static_cast<GLsizei>(rect.GetWidth()), 826 static_cast<GLsizei>(rect.GetWidth()),
858 static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type, 827 static_cast<GLsizei>(rect.GetHeight()), 1, tuple.format,
859 &gl_buffer[mip_map][buffer_offset]); 828 tuple.type, &gl_buffer[mip_map][buffer_offset]);
860 buffer_offset += params.LayerSizeGL(mip_map); 829 buffer_offset += params.LayerSizeGL(mip_map);
861 } 830 }
862 break; 831 break;
@@ -865,9 +834,10 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle,
865 LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", 834 LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}",
866 static_cast<u32>(params.target)); 835 static_cast<u32>(params.target));
867 UNREACHABLE(); 836 UNREACHABLE();
868 glTexSubImage2D(GL_TEXTURE_2D, mip_map, x0, y0, static_cast<GLsizei>(rect.GetWidth()), 837 glTextureSubImage2D(texture.handle, mip_map, x0, y0,
869 static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type, 838 static_cast<GLsizei>(rect.GetWidth()),
870 &gl_buffer[mip_map][buffer_offset]); 839 static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type,
840 &gl_buffer[mip_map][buffer_offset]);
871 } 841 }
872 } 842 }
873 843
@@ -877,29 +847,16 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle,
877void CachedSurface::EnsureTextureView() { 847void CachedSurface::EnsureTextureView() {
878 if (texture_view.handle != 0) 848 if (texture_view.handle != 0)
879 return; 849 return;
880 // Compressed texture are not being created with immutable storage
881 UNIMPLEMENTED_IF(gl_is_compressed);
882 850
883 const GLenum target{TargetLayer()}; 851 const GLenum target{TargetLayer()};
884 const GLuint num_layers{target == GL_TEXTURE_CUBE_MAP_ARRAY ? 6u : 1u}; 852 const GLuint num_layers{target == GL_TEXTURE_CUBE_MAP_ARRAY ? 6u : 1u};
885 constexpr GLuint min_layer = 0; 853 constexpr GLuint min_layer = 0;
886 constexpr GLuint min_level = 0; 854 constexpr GLuint min_level = 0;
887 855
888 texture_view.Create(); 856 glGenTextures(1, &texture_view.handle);
889 glTextureView(texture_view.handle, target, texture.handle, gl_internal_format, min_level, 857 glTextureView(texture_view.handle, target, texture.handle, gl_internal_format, 0,
890 params.max_mip_level, min_layer, num_layers); 858 params.max_mip_level, 0, 1);
891 859 ApplyTextureDefaults(texture_view.handle, params.max_mip_level);
892 OpenGLState cur_state = OpenGLState::GetCurState();
893 const auto& old_tex = cur_state.texture_units[0];
894 SCOPE_EXIT({
895 cur_state.texture_units[0] = old_tex;
896 cur_state.Apply();
897 });
898 cur_state.texture_units[0].texture = texture_view.handle;
899 cur_state.texture_units[0].target = target;
900 cur_state.Apply();
901
902 ApplyTextureDefaults(target, params.max_mip_level);
903} 860}
904 861
905MICROPROFILE_DEFINE(OpenGL_TextureUL, "OpenGL", "Texture Upload", MP_RGB(128, 192, 64)); 862MICROPROFILE_DEFINE(OpenGL_TextureUL, "OpenGL", "Texture Upload", MP_RGB(128, 192, 64));
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index 8d7d6722c..9ee6f3f65 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -393,7 +393,6 @@ private:
393 SurfaceParams params{}; 393 SurfaceParams params{};
394 GLenum gl_target{}; 394 GLenum gl_target{};
395 GLenum gl_internal_format{}; 395 GLenum gl_internal_format{};
396 bool gl_is_compressed{};
397 std::size_t cached_size_in_bytes{}; 396 std::size_t cached_size_in_bytes{};
398}; 397};
399 398
diff --git a/src/video_core/renderer_opengl/gl_resource_manager.cpp b/src/video_core/renderer_opengl/gl_resource_manager.cpp
index 1da744158..4170cbd3c 100644
--- a/src/video_core/renderer_opengl/gl_resource_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_resource_manager.cpp
@@ -15,12 +15,12 @@ MICROPROFILE_DEFINE(OpenGL_ResourceDeletion, "OpenGL", "Resource Deletion", MP_R
15 15
16namespace OpenGL { 16namespace OpenGL {
17 17
18void OGLTexture::Create() { 18void OGLTexture::Create(GLenum target) {
19 if (handle != 0) 19 if (handle != 0)
20 return; 20 return;
21 21
22 MICROPROFILE_SCOPE(OpenGL_ResourceCreation); 22 MICROPROFILE_SCOPE(OpenGL_ResourceCreation);
23 glGenTextures(1, &handle); 23 glCreateTextures(target, 1, &handle);
24} 24}
25 25
26void OGLTexture::Release() { 26void OGLTexture::Release() {
diff --git a/src/video_core/renderer_opengl/gl_resource_manager.h b/src/video_core/renderer_opengl/gl_resource_manager.h
index e33f1e973..df76cbc4b 100644
--- a/src/video_core/renderer_opengl/gl_resource_manager.h
+++ b/src/video_core/renderer_opengl/gl_resource_manager.h
@@ -28,7 +28,7 @@ public:
28 } 28 }
29 29
30 /// Creates a new internal OpenGL resource and stores the handle 30 /// Creates a new internal OpenGL resource and stores the handle
31 void Create(); 31 void Create(GLenum target);
32 32
33 /// Deletes the internal OpenGL resource 33 /// Deletes the internal OpenGL resource
34 void Release(); 34 void Release();
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index e37b65b38..761dd6be3 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -171,10 +171,6 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf
171 Memory::GetPointer(framebuffer_addr), 171 Memory::GetPointer(framebuffer_addr),
172 gl_framebuffer_data.data(), true); 172 gl_framebuffer_data.data(), true);
173 173
174 state.texture_units[0].texture = screen_info.texture.resource.handle;
175 state.Apply();
176
177 glActiveTexture(GL_TEXTURE0);
178 glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast<GLint>(framebuffer.stride)); 174 glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast<GLint>(framebuffer.stride));
179 175
180 // Update existing texture 176 // Update existing texture
@@ -182,14 +178,11 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf
182 // they differ from the LCD resolution. 178 // they differ from the LCD resolution.
183 // TODO: Applications could theoretically crash yuzu here by specifying too large 179 // TODO: Applications could theoretically crash yuzu here by specifying too large
184 // framebuffer sizes. We should make sure that this cannot happen. 180 // framebuffer sizes. We should make sure that this cannot happen.
185 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, framebuffer.width, framebuffer.height, 181 glTextureSubImage2D(screen_info.texture.resource.handle, 0, 0, 0, framebuffer.width,
186 screen_info.texture.gl_format, screen_info.texture.gl_type, 182 framebuffer.height, screen_info.texture.gl_format,
187 gl_framebuffer_data.data()); 183 screen_info.texture.gl_type, gl_framebuffer_data.data());
188 184
189 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 185 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
190
191 state.texture_units[0].texture = 0;
192 state.Apply();
193 } 186 }
194} 187}
195 188
@@ -199,17 +192,8 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf
199 */ 192 */
200void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a, 193void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a,
201 const TextureInfo& texture) { 194 const TextureInfo& texture) {
202 state.texture_units[0].texture = texture.resource.handle; 195 const u8 framebuffer_data[4] = {color_a, color_b, color_g, color_r};
203 state.Apply(); 196 glClearTexImage(texture.resource.handle, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer_data);
204
205 glActiveTexture(GL_TEXTURE0);
206 u8 framebuffer_data[4] = {color_a, color_b, color_g, color_r};
207
208 // Update existing texture
209 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer_data);
210
211 state.texture_units[0].texture = 0;
212 state.Apply();
213} 197}
214 198
215/** 199/**
@@ -249,26 +233,13 @@ void RendererOpenGL::InitOpenGLObjects() {
249 sizeof(ScreenRectVertex)); 233 sizeof(ScreenRectVertex));
250 234
251 // Allocate textures for the screen 235 // Allocate textures for the screen
252 screen_info.texture.resource.Create(); 236 screen_info.texture.resource.Create(GL_TEXTURE_2D);
253 237
254 // Allocation of storage is deferred until the first frame, when we 238 const GLuint texture = screen_info.texture.resource.handle;
255 // know the framebuffer size. 239 glTextureStorage2D(texture, 1, GL_RGBA8, 1, 1);
256
257 state.texture_units[0].texture = screen_info.texture.resource.handle;
258 state.Apply();
259
260 glActiveTexture(GL_TEXTURE0);
261 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
262 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
263 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
264 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
265 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
266 240
267 screen_info.display_texture = screen_info.texture.resource.handle; 241 screen_info.display_texture = screen_info.texture.resource.handle;
268 242
269 state.texture_units[0].texture = 0;
270 state.Apply();
271
272 // Clear screen to black 243 // Clear screen to black
273 LoadColorToActiveGLTexture(0, 0, 0, 0, screen_info.texture); 244 LoadColorToActiveGLTexture(0, 0, 0, 0, screen_info.texture);
274} 245}
@@ -284,20 +255,19 @@ void RendererOpenGL::CreateRasterizer() {
284 255
285void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, 256void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
286 const Tegra::FramebufferConfig& framebuffer) { 257 const Tegra::FramebufferConfig& framebuffer) {
287
288 texture.width = framebuffer.width; 258 texture.width = framebuffer.width;
289 texture.height = framebuffer.height; 259 texture.height = framebuffer.height;
290 260
291 GLint internal_format; 261 GLint internal_format;
292 switch (framebuffer.pixel_format) { 262 switch (framebuffer.pixel_format) {
293 case Tegra::FramebufferConfig::PixelFormat::ABGR8: 263 case Tegra::FramebufferConfig::PixelFormat::ABGR8:
294 internal_format = GL_RGBA; 264 internal_format = GL_RGBA8;
295 texture.gl_format = GL_RGBA; 265 texture.gl_format = GL_RGBA;
296 texture.gl_type = GL_UNSIGNED_INT_8_8_8_8_REV; 266 texture.gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
297 gl_framebuffer_data.resize(texture.width * texture.height * 4); 267 gl_framebuffer_data.resize(texture.width * texture.height * 4);
298 break; 268 break;
299 default: 269 default:
300 internal_format = GL_RGBA; 270 internal_format = GL_RGBA8;
301 texture.gl_format = GL_RGBA; 271 texture.gl_format = GL_RGBA;
302 texture.gl_type = GL_UNSIGNED_INT_8_8_8_8_REV; 272 texture.gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
303 gl_framebuffer_data.resize(texture.width * texture.height * 4); 273 gl_framebuffer_data.resize(texture.width * texture.height * 4);
@@ -306,15 +276,9 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
306 UNREACHABLE(); 276 UNREACHABLE();
307 } 277 }
308 278
309 state.texture_units[0].texture = texture.resource.handle; 279 texture.resource.Release();
310 state.Apply(); 280 texture.resource.Create(GL_TEXTURE_2D);
311 281 glTextureStorage2D(texture.resource.handle, 1, internal_format, texture.width, texture.height);
312 glActiveTexture(GL_TEXTURE0);
313 glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0,
314 texture.gl_format, texture.gl_type, nullptr);
315
316 state.texture_units[0].texture = 0;
317 state.Apply();
318} 282}
319 283
320void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, float y, float w, 284void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, float y, float w,