diff options
| author | 2019-02-06 20:17:59 -0500 | |
|---|---|---|
| committer | 2019-02-06 20:17:59 -0500 | |
| commit | 40ac0585574499bc0dee47c4bef354c8e5676695 (patch) | |
| tree | 096b8e8c32f4affbd791386daa4b1feac2d9bedc /src | |
| parent | Merge pull request #2057 from FearlessTobi/port-4586 (diff) | |
| parent | gl_rasterizer_cache: Fixup test clause (diff) | |
| download | yuzu-40ac0585574499bc0dee47c4bef354c8e5676695.tar.gz yuzu-40ac0585574499bc0dee47c4bef354c8e5676695.tar.xz yuzu-40ac0585574499bc0dee47c4bef354c8e5676695.zip | |
Merge pull request #2071 from ReinUsesLisp/dsa-texture
gl_rasterizer: Use DSA for textures and move swizzling to texture state
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 7 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 242 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 7 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_resource_manager.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_resource_manager.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state.cpp | 32 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state.h | 12 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 63 |
8 files changed, 153 insertions, 216 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 9f7c837d6..53b52753c 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -1019,11 +1019,8 @@ void RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, const Shader& s | |||
| 1019 | if (surface != nullptr) { | 1019 | if (surface != nullptr) { |
| 1020 | unit.texture = | 1020 | unit.texture = |
| 1021 | entry.IsArray() ? surface->TextureLayer().handle : surface->Texture().handle; | 1021 | entry.IsArray() ? surface->TextureLayer().handle : surface->Texture().handle; |
| 1022 | unit.target = entry.IsArray() ? surface->TargetLayer() : surface->Target(); | 1022 | surface->UpdateSwizzle(texture.tic.x_source, texture.tic.y_source, texture.tic.z_source, |
| 1023 | unit.swizzle.r = MaxwellToGL::SwizzleSource(texture.tic.x_source); | 1023 | texture.tic.w_source); |
| 1024 | unit.swizzle.g = MaxwellToGL::SwizzleSource(texture.tic.y_source); | ||
| 1025 | unit.swizzle.b = MaxwellToGL::SwizzleSource(texture.tic.z_source); | ||
| 1026 | unit.swizzle.a = MaxwellToGL::SwizzleSource(texture.tic.w_source); | ||
| 1027 | } else { | 1024 | } else { |
| 1028 | // Can occur when texture addr is null or its memory is unmapped/invalid | 1025 | // Can occur when texture addr is null or its memory is unmapped/invalid |
| 1029 | unit.texture = 0; | 1026 | unit.texture = 0; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 50286432d..a79eee03e 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 | ||
| 47 | static void ApplyTextureDefaults(GLenum target, u32 max_mip_level) { | 46 | static 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, | |||
| 529 | CachedSurface::CachedSurface(const SurfaceParams& params) | 528 | CachedSurface::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 | ||
| @@ -751,63 +736,50 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle, | |||
| 751 | const auto& rect{params.GetRect(mip_map)}; | 736 | const auto& rect{params.GetRect(mip_map)}; |
| 752 | 737 | ||
| 753 | // Load data from memory to the surface | 738 | // Load data from memory to the surface |
| 754 | const GLint x0 = static_cast<GLint>(rect.left); | 739 | const auto x0 = static_cast<GLint>(rect.left); |
| 755 | const GLint y0 = static_cast<GLint>(rect.bottom); | 740 | const auto y0 = static_cast<GLint>(rect.bottom); |
| 756 | std::size_t buffer_offset = | 741 | auto buffer_offset = |
| 757 | static_cast<std::size_t>(static_cast<std::size_t>(y0) * params.MipWidth(mip_map) + | 742 | static_cast<std::size_t>(static_cast<std::size_t>(y0) * params.MipWidth(mip_map) + |
| 758 | static_cast<std::size_t>(x0)) * | 743 | static_cast<std::size_t>(x0)) * |
| 759 | GetBytesPerPixel(params.pixel_format); | 744 | GetBytesPerPixel(params.pixel_format); |
| 760 | 745 | ||
| 761 | const FormatTuple& tuple = GetFormatTuple(params.pixel_format, params.component_type); | 746 | const FormatTuple& tuple = GetFormatTuple(params.pixel_format, params.component_type); |
| 762 | const GLuint target_tex = texture.handle; | ||
| 763 | OpenGLState cur_state = OpenGLState::GetCurState(); | ||
| 764 | |||
| 765 | const auto& old_tex = cur_state.texture_units[0]; | ||
| 766 | SCOPE_EXIT({ | ||
| 767 | cur_state.texture_units[0] = old_tex; | ||
| 768 | cur_state.Apply(); | ||
| 769 | }); | ||
| 770 | cur_state.texture_units[0].texture = target_tex; | ||
| 771 | cur_state.texture_units[0].target = SurfaceTargetToGL(params.target); | ||
| 772 | cur_state.Apply(); | ||
| 773 | 747 | ||
| 774 | // Ensure no bad interactions with GL_UNPACK_ALIGNMENT | 748 | // Ensure no bad interactions with GL_UNPACK_ALIGNMENT |
| 775 | ASSERT(params.MipWidth(mip_map) * GetBytesPerPixel(params.pixel_format) % 4 == 0); | 749 | ASSERT(params.MipWidth(mip_map) * GetBytesPerPixel(params.pixel_format) % 4 == 0); |
| 776 | glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast<GLint>(params.MipWidth(mip_map))); | 750 | glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast<GLint>(params.MipWidth(mip_map))); |
| 777 | 751 | ||
| 778 | GLsizei image_size = static_cast<GLsizei>(params.GetMipmapSizeGL(mip_map, false)); | 752 | const auto image_size = static_cast<GLsizei>(params.GetMipmapSizeGL(mip_map, false)); |
| 779 | glActiveTexture(GL_TEXTURE0); | ||
| 780 | if (tuple.compressed) { | 753 | if (tuple.compressed) { |
| 781 | switch (params.target) { | 754 | switch (params.target) { |
| 782 | case SurfaceTarget::Texture2D: | 755 | case SurfaceTarget::Texture2D: |
| 783 | glCompressedTexImage2D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format, | 756 | glCompressedTextureSubImage2D( |
| 784 | static_cast<GLsizei>(params.MipWidth(mip_map)), | 757 | texture.handle, mip_map, 0, 0, static_cast<GLsizei>(params.MipWidth(mip_map)), |
| 785 | static_cast<GLsizei>(params.MipHeight(mip_map)), 0, image_size, | 758 | static_cast<GLsizei>(params.MipHeight(mip_map)), tuple.internal_format, image_size, |
| 786 | &gl_buffer[mip_map][buffer_offset]); | 759 | &gl_buffer[mip_map][buffer_offset]); |
| 787 | break; | 760 | break; |
| 788 | case SurfaceTarget::Texture3D: | 761 | case SurfaceTarget::Texture3D: |
| 789 | glCompressedTexImage3D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format, | 762 | glCompressedTextureSubImage3D( |
| 790 | static_cast<GLsizei>(params.MipWidth(mip_map)), | 763 | texture.handle, mip_map, 0, 0, 0, static_cast<GLsizei>(params.MipWidth(mip_map)), |
| 791 | static_cast<GLsizei>(params.MipHeight(mip_map)), | 764 | static_cast<GLsizei>(params.MipHeight(mip_map)), |
| 792 | static_cast<GLsizei>(params.MipDepth(mip_map)), 0, image_size, | 765 | static_cast<GLsizei>(params.MipDepth(mip_map)), tuple.internal_format, image_size, |
| 793 | &gl_buffer[mip_map][buffer_offset]); | 766 | &gl_buffer[mip_map][buffer_offset]); |
| 794 | break; | 767 | break; |
| 795 | case SurfaceTarget::Texture2DArray: | 768 | case SurfaceTarget::Texture2DArray: |
| 796 | case SurfaceTarget::TextureCubeArray: | 769 | case SurfaceTarget::TextureCubeArray: |
| 797 | glCompressedTexImage3D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format, | 770 | glCompressedTextureSubImage3D( |
| 798 | static_cast<GLsizei>(params.MipWidth(mip_map)), | 771 | texture.handle, mip_map, 0, 0, 0, static_cast<GLsizei>(params.MipWidth(mip_map)), |
| 799 | static_cast<GLsizei>(params.MipHeight(mip_map)), | 772 | static_cast<GLsizei>(params.MipHeight(mip_map)), static_cast<GLsizei>(params.depth), |
| 800 | static_cast<GLsizei>(params.depth), 0, image_size, | 773 | tuple.internal_format, image_size, &gl_buffer[mip_map][buffer_offset]); |
| 801 | &gl_buffer[mip_map][buffer_offset]); | ||
| 802 | break; | 774 | break; |
| 803 | case SurfaceTarget::TextureCubemap: { | 775 | case SurfaceTarget::TextureCubemap: { |
| 804 | GLsizei layer_size = static_cast<GLsizei>(params.LayerSizeGL(mip_map)); | 776 | const auto layer_size = static_cast<GLsizei>(params.LayerSizeGL(mip_map)); |
| 805 | for (std::size_t face = 0; face < params.depth; ++face) { | 777 | for (std::size_t face = 0; face < params.depth; ++face) { |
| 806 | glCompressedTexImage2D(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face), | 778 | glCompressedTextureSubImage3D( |
| 807 | mip_map, tuple.internal_format, | 779 | texture.handle, mip_map, 0, 0, static_cast<GLint>(face), |
| 808 | static_cast<GLsizei>(params.MipWidth(mip_map)), | 780 | static_cast<GLsizei>(params.MipWidth(mip_map)), |
| 809 | static_cast<GLsizei>(params.MipHeight(mip_map)), 0, | 781 | static_cast<GLsizei>(params.MipHeight(mip_map)), 1, tuple.internal_format, |
| 810 | layer_size, &gl_buffer[mip_map][buffer_offset]); | 782 | layer_size, &gl_buffer[mip_map][buffer_offset]); |
| 811 | buffer_offset += layer_size; | 783 | buffer_offset += layer_size; |
| 812 | } | 784 | } |
| 813 | break; | 785 | break; |
| @@ -816,46 +788,43 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle, | |||
| 816 | LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", | 788 | LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", |
| 817 | static_cast<u32>(params.target)); | 789 | static_cast<u32>(params.target)); |
| 818 | UNREACHABLE(); | 790 | UNREACHABLE(); |
| 819 | glCompressedTexImage2D(GL_TEXTURE_2D, mip_map, tuple.internal_format, | 791 | glCompressedTextureSubImage2D( |
| 820 | static_cast<GLsizei>(params.MipWidth(mip_map)), | 792 | texture.handle, mip_map, 0, 0, static_cast<GLsizei>(params.MipWidth(mip_map)), |
| 821 | static_cast<GLsizei>(params.MipHeight(mip_map)), 0, | 793 | static_cast<GLsizei>(params.MipHeight(mip_map)), tuple.internal_format, |
| 822 | static_cast<GLsizei>(params.size_in_bytes_gl), | 794 | static_cast<GLsizei>(params.size_in_bytes_gl), &gl_buffer[mip_map][buffer_offset]); |
| 823 | &gl_buffer[mip_map][buffer_offset]); | ||
| 824 | } | 795 | } |
| 825 | } else { | 796 | } else { |
| 826 | |||
| 827 | switch (params.target) { | 797 | switch (params.target) { |
| 828 | case SurfaceTarget::Texture1D: | 798 | case SurfaceTarget::Texture1D: |
| 829 | glTexSubImage1D(SurfaceTargetToGL(params.target), mip_map, x0, | 799 | glTextureSubImage1D(texture.handle, mip_map, x0, static_cast<GLsizei>(rect.GetWidth()), |
| 830 | static_cast<GLsizei>(rect.GetWidth()), tuple.format, tuple.type, | 800 | tuple.format, tuple.type, &gl_buffer[mip_map][buffer_offset]); |
| 831 | &gl_buffer[mip_map][buffer_offset]); | ||
| 832 | break; | 801 | break; |
| 833 | case SurfaceTarget::Texture2D: | 802 | case SurfaceTarget::Texture2D: |
| 834 | glTexSubImage2D(SurfaceTargetToGL(params.target), mip_map, x0, y0, | 803 | glTextureSubImage2D(texture.handle, mip_map, x0, y0, |
| 835 | static_cast<GLsizei>(rect.GetWidth()), | 804 | static_cast<GLsizei>(rect.GetWidth()), |
| 836 | static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type, | 805 | static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type, |
| 837 | &gl_buffer[mip_map][buffer_offset]); | 806 | &gl_buffer[mip_map][buffer_offset]); |
| 838 | break; | 807 | break; |
| 839 | case SurfaceTarget::Texture3D: | 808 | case SurfaceTarget::Texture3D: |
| 840 | glTexSubImage3D(SurfaceTargetToGL(params.target), mip_map, x0, y0, 0, | 809 | glTextureSubImage3D(texture.handle, mip_map, x0, y0, 0, |
| 841 | static_cast<GLsizei>(rect.GetWidth()), | 810 | static_cast<GLsizei>(rect.GetWidth()), |
| 842 | static_cast<GLsizei>(rect.GetHeight()), params.MipDepth(mip_map), | 811 | static_cast<GLsizei>(rect.GetHeight()), params.MipDepth(mip_map), |
| 843 | tuple.format, tuple.type, &gl_buffer[mip_map][buffer_offset]); | 812 | tuple.format, tuple.type, &gl_buffer[mip_map][buffer_offset]); |
| 844 | break; | 813 | break; |
| 845 | case SurfaceTarget::Texture2DArray: | 814 | case SurfaceTarget::Texture2DArray: |
| 846 | case SurfaceTarget::TextureCubeArray: | 815 | case SurfaceTarget::TextureCubeArray: |
| 847 | glTexSubImage3D(SurfaceTargetToGL(params.target), mip_map, x0, y0, 0, | 816 | glTextureSubImage3D(texture.handle, mip_map, x0, y0, 0, |
| 848 | static_cast<GLsizei>(rect.GetWidth()), | 817 | static_cast<GLsizei>(rect.GetWidth()), |
| 849 | static_cast<GLsizei>(rect.GetHeight()), params.depth, tuple.format, | 818 | static_cast<GLsizei>(rect.GetHeight()), params.depth, tuple.format, |
| 850 | tuple.type, &gl_buffer[mip_map][buffer_offset]); | 819 | tuple.type, &gl_buffer[mip_map][buffer_offset]); |
| 851 | break; | 820 | break; |
| 852 | case SurfaceTarget::TextureCubemap: { | 821 | case SurfaceTarget::TextureCubemap: { |
| 853 | std::size_t start = buffer_offset; | 822 | std::size_t start = buffer_offset; |
| 854 | for (std::size_t face = 0; face < params.depth; ++face) { | 823 | for (std::size_t face = 0; face < params.depth; ++face) { |
| 855 | glTexSubImage2D(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face), mip_map, | 824 | glTextureSubImage3D(texture.handle, mip_map, x0, y0, static_cast<GLint>(face), |
| 856 | x0, y0, static_cast<GLsizei>(rect.GetWidth()), | 825 | static_cast<GLsizei>(rect.GetWidth()), |
| 857 | static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type, | 826 | static_cast<GLsizei>(rect.GetHeight()), 1, tuple.format, |
| 858 | &gl_buffer[mip_map][buffer_offset]); | 827 | tuple.type, &gl_buffer[mip_map][buffer_offset]); |
| 859 | buffer_offset += params.LayerSizeGL(mip_map); | 828 | buffer_offset += params.LayerSizeGL(mip_map); |
| 860 | } | 829 | } |
| 861 | break; | 830 | break; |
| @@ -864,9 +833,10 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle, | |||
| 864 | LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", | 833 | LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", |
| 865 | static_cast<u32>(params.target)); | 834 | static_cast<u32>(params.target)); |
| 866 | UNREACHABLE(); | 835 | UNREACHABLE(); |
| 867 | glTexSubImage2D(GL_TEXTURE_2D, mip_map, x0, y0, static_cast<GLsizei>(rect.GetWidth()), | 836 | glTextureSubImage2D(texture.handle, mip_map, x0, y0, |
| 868 | static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type, | 837 | static_cast<GLsizei>(rect.GetWidth()), |
| 869 | &gl_buffer[mip_map][buffer_offset]); | 838 | static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type, |
| 839 | &gl_buffer[mip_map][buffer_offset]); | ||
| 870 | } | 840 | } |
| 871 | } | 841 | } |
| 872 | 842 | ||
| @@ -876,29 +846,18 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle, | |||
| 876 | void CachedSurface::EnsureTextureView() { | 846 | void CachedSurface::EnsureTextureView() { |
| 877 | if (texture_view.handle != 0) | 847 | if (texture_view.handle != 0) |
| 878 | return; | 848 | return; |
| 879 | // Compressed texture are not being created with immutable storage | ||
| 880 | UNIMPLEMENTED_IF(gl_is_compressed); | ||
| 881 | 849 | ||
| 882 | const GLenum target{TargetLayer()}; | 850 | const GLenum target{TargetLayer()}; |
| 883 | const GLuint num_layers{target == GL_TEXTURE_CUBE_MAP_ARRAY ? 6u : 1u}; | 851 | const GLuint num_layers{target == GL_TEXTURE_CUBE_MAP_ARRAY ? 6u : 1u}; |
| 884 | constexpr GLuint min_layer = 0; | 852 | constexpr GLuint min_layer = 0; |
| 885 | constexpr GLuint min_level = 0; | 853 | constexpr GLuint min_level = 0; |
| 886 | 854 | ||
| 887 | texture_view.Create(); | 855 | glGenTextures(1, &texture_view.handle); |
| 888 | glTextureView(texture_view.handle, target, texture.handle, gl_internal_format, min_level, | 856 | glTextureView(texture_view.handle, target, texture.handle, gl_internal_format, 0, |
| 889 | params.max_mip_level, min_layer, num_layers); | 857 | params.max_mip_level, 0, 1); |
| 890 | 858 | ApplyTextureDefaults(texture_view.handle, params.max_mip_level); | |
| 891 | OpenGLState cur_state = OpenGLState::GetCurState(); | 859 | glTextureParameteriv(texture_view.handle, GL_TEXTURE_SWIZZLE_RGBA, |
| 892 | const auto& old_tex = cur_state.texture_units[0]; | 860 | reinterpret_cast<const GLint*>(swizzle.data())); |
| 893 | SCOPE_EXIT({ | ||
| 894 | cur_state.texture_units[0] = old_tex; | ||
| 895 | cur_state.Apply(); | ||
| 896 | }); | ||
| 897 | cur_state.texture_units[0].texture = texture_view.handle; | ||
| 898 | cur_state.texture_units[0].target = target; | ||
| 899 | cur_state.Apply(); | ||
| 900 | |||
| 901 | ApplyTextureDefaults(target, params.max_mip_level); | ||
| 902 | } | 861 | } |
| 903 | 862 | ||
| 904 | MICROPROFILE_DEFINE(OpenGL_TextureUL, "OpenGL", "Texture Upload", MP_RGB(128, 192, 64)); | 863 | MICROPROFILE_DEFINE(OpenGL_TextureUL, "OpenGL", "Texture Upload", MP_RGB(128, 192, 64)); |
| @@ -909,6 +868,25 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle | |||
| 909 | UploadGLMipmapTexture(i, read_fb_handle, draw_fb_handle); | 868 | UploadGLMipmapTexture(i, read_fb_handle, draw_fb_handle); |
| 910 | } | 869 | } |
| 911 | 870 | ||
| 871 | void CachedSurface::UpdateSwizzle(Tegra::Texture::SwizzleSource swizzle_x, | ||
| 872 | Tegra::Texture::SwizzleSource swizzle_y, | ||
| 873 | Tegra::Texture::SwizzleSource swizzle_z, | ||
| 874 | Tegra::Texture::SwizzleSource swizzle_w) { | ||
| 875 | const GLenum new_x = MaxwellToGL::SwizzleSource(swizzle_x); | ||
| 876 | const GLenum new_y = MaxwellToGL::SwizzleSource(swizzle_y); | ||
| 877 | const GLenum new_z = MaxwellToGL::SwizzleSource(swizzle_z); | ||
| 878 | const GLenum new_w = MaxwellToGL::SwizzleSource(swizzle_w); | ||
| 879 | if (swizzle[0] == new_x && swizzle[1] == new_y && swizzle[2] == new_z && swizzle[3] == new_w) { | ||
| 880 | return; | ||
| 881 | } | ||
| 882 | swizzle = {new_x, new_y, new_z, new_w}; | ||
| 883 | const auto swizzle_data = reinterpret_cast<const GLint*>(swizzle.data()); | ||
| 884 | glTextureParameteriv(texture.handle, GL_TEXTURE_SWIZZLE_RGBA, swizzle_data); | ||
| 885 | if (texture_view.handle != 0) { | ||
| 886 | glTextureParameteriv(texture_view.handle, GL_TEXTURE_SWIZZLE_RGBA, swizzle_data); | ||
| 887 | } | ||
| 888 | } | ||
| 889 | |||
| 912 | RasterizerCacheOpenGL::RasterizerCacheOpenGL(RasterizerOpenGL& rasterizer) | 890 | RasterizerCacheOpenGL::RasterizerCacheOpenGL(RasterizerOpenGL& rasterizer) |
| 913 | : RasterizerCache{rasterizer} { | 891 | : RasterizerCache{rasterizer} { |
| 914 | read_framebuffer.Create(); | 892 | read_framebuffer.Create(); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 8d7d6722c..490b8252e 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -382,6 +382,11 @@ public: | |||
| 382 | // Upload data in gl_buffer to this surface's texture | 382 | // Upload data in gl_buffer to this surface's texture |
| 383 | void UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle); | 383 | void UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle); |
| 384 | 384 | ||
| 385 | void UpdateSwizzle(Tegra::Texture::SwizzleSource swizzle_x, | ||
| 386 | Tegra::Texture::SwizzleSource swizzle_y, | ||
| 387 | Tegra::Texture::SwizzleSource swizzle_z, | ||
| 388 | Tegra::Texture::SwizzleSource swizzle_w); | ||
| 389 | |||
| 385 | private: | 390 | private: |
| 386 | void UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle, GLuint draw_fb_handle); | 391 | void UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle, GLuint draw_fb_handle); |
| 387 | 392 | ||
| @@ -393,8 +398,8 @@ private: | |||
| 393 | SurfaceParams params{}; | 398 | SurfaceParams params{}; |
| 394 | GLenum gl_target{}; | 399 | GLenum gl_target{}; |
| 395 | GLenum gl_internal_format{}; | 400 | GLenum gl_internal_format{}; |
| 396 | bool gl_is_compressed{}; | ||
| 397 | std::size_t cached_size_in_bytes{}; | 401 | std::size_t cached_size_in_bytes{}; |
| 402 | std::array<GLenum, 4> swizzle{GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA}; | ||
| 398 | }; | 403 | }; |
| 399 | 404 | ||
| 400 | class RasterizerCacheOpenGL final : public RasterizerCache<Surface> { | 405 | class RasterizerCacheOpenGL final : public RasterizerCache<Surface> { |
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 | ||
| 16 | namespace OpenGL { | 16 | namespace OpenGL { |
| 17 | 17 | ||
| 18 | void OGLTexture::Create() { | 18 | void 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 | ||
| 26 | void OGLTexture::Release() { | 26 | void 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/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index b7ba59350..81af803bc 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp | |||
| @@ -462,29 +462,35 @@ void OpenGLState::ApplyPolygonOffset() const { | |||
| 462 | } | 462 | } |
| 463 | 463 | ||
| 464 | void OpenGLState::ApplyTextures() const { | 464 | void OpenGLState::ApplyTextures() const { |
| 465 | bool has_delta{}; | ||
| 466 | std::size_t first{}; | ||
| 467 | std::size_t last{}; | ||
| 468 | std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> textures; | ||
| 469 | |||
| 465 | for (std::size_t i = 0; i < std::size(texture_units); ++i) { | 470 | for (std::size_t i = 0; i < std::size(texture_units); ++i) { |
| 466 | const auto& texture_unit = texture_units[i]; | 471 | const auto& texture_unit = texture_units[i]; |
| 467 | const auto& cur_state_texture_unit = cur_state.texture_units[i]; | 472 | const auto& cur_state_texture_unit = cur_state.texture_units[i]; |
| 473 | textures[i] = texture_unit.texture; | ||
| 468 | 474 | ||
| 469 | if (texture_unit.texture != cur_state_texture_unit.texture) { | 475 | if (textures[i] != cur_state_texture_unit.texture) { |
| 470 | glActiveTexture(TextureUnits::MaxwellTexture(static_cast<int>(i)).Enum()); | 476 | if (!has_delta) { |
| 471 | glBindTexture(texture_unit.target, texture_unit.texture); | 477 | first = i; |
| 472 | } | 478 | has_delta = true; |
| 473 | // Update the texture swizzle | 479 | } |
| 474 | if (texture_unit.swizzle.r != cur_state_texture_unit.swizzle.r || | 480 | last = i; |
| 475 | texture_unit.swizzle.g != cur_state_texture_unit.swizzle.g || | ||
| 476 | texture_unit.swizzle.b != cur_state_texture_unit.swizzle.b || | ||
| 477 | texture_unit.swizzle.a != cur_state_texture_unit.swizzle.a) { | ||
| 478 | std::array<GLint, 4> mask = {texture_unit.swizzle.r, texture_unit.swizzle.g, | ||
| 479 | texture_unit.swizzle.b, texture_unit.swizzle.a}; | ||
| 480 | glTexParameteriv(texture_unit.target, GL_TEXTURE_SWIZZLE_RGBA, mask.data()); | ||
| 481 | } | 481 | } |
| 482 | } | 482 | } |
| 483 | |||
| 484 | if (has_delta) { | ||
| 485 | glBindTextures(static_cast<GLuint>(first), static_cast<GLsizei>(last - first + 1), | ||
| 486 | textures.data()); | ||
| 487 | } | ||
| 483 | } | 488 | } |
| 484 | 489 | ||
| 485 | void OpenGLState::ApplySamplers() const { | 490 | void OpenGLState::ApplySamplers() const { |
| 486 | bool has_delta{}; | 491 | bool has_delta{}; |
| 487 | std::size_t first{}, last{}; | 492 | std::size_t first{}; |
| 493 | std::size_t last{}; | ||
| 488 | std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> samplers; | 494 | std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> samplers; |
| 489 | for (std::size_t i = 0; i < std::size(samplers); ++i) { | 495 | for (std::size_t i = 0; i < std::size(samplers); ++i) { |
| 490 | samplers[i] = texture_units[i].sampler; | 496 | samplers[i] = texture_units[i].sampler; |
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index a5a7c0920..9e1eda5b1 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h | |||
| @@ -126,26 +126,14 @@ public: | |||
| 126 | struct TextureUnit { | 126 | struct TextureUnit { |
| 127 | GLuint texture; // GL_TEXTURE_BINDING_2D | 127 | GLuint texture; // GL_TEXTURE_BINDING_2D |
| 128 | GLuint sampler; // GL_SAMPLER_BINDING | 128 | GLuint sampler; // GL_SAMPLER_BINDING |
| 129 | GLenum target; | ||
| 130 | struct { | ||
| 131 | GLint r; // GL_TEXTURE_SWIZZLE_R | ||
| 132 | GLint g; // GL_TEXTURE_SWIZZLE_G | ||
| 133 | GLint b; // GL_TEXTURE_SWIZZLE_B | ||
| 134 | GLint a; // GL_TEXTURE_SWIZZLE_A | ||
| 135 | } swizzle; | ||
| 136 | 129 | ||
| 137 | void Unbind() { | 130 | void Unbind() { |
| 138 | texture = 0; | 131 | texture = 0; |
| 139 | swizzle.r = GL_RED; | ||
| 140 | swizzle.g = GL_GREEN; | ||
| 141 | swizzle.b = GL_BLUE; | ||
| 142 | swizzle.a = GL_ALPHA; | ||
| 143 | } | 132 | } |
| 144 | 133 | ||
| 145 | void Reset() { | 134 | void Reset() { |
| 146 | Unbind(); | 135 | Unbind(); |
| 147 | sampler = 0; | 136 | sampler = 0; |
| 148 | target = GL_TEXTURE_2D; | ||
| 149 | } | 137 | } |
| 150 | }; | 138 | }; |
| 151 | std::array<TextureUnit, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> texture_units; | 139 | std::array<TextureUnit, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> texture_units; |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index e37b65b38..5b09c38ea 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 | */ |
| 200 | void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a, | 193 | void 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 | ||
| 285 | void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, | 256 | void 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 | ||
| 320 | void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, float y, float w, | 284 | void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, float y, float w, |
| @@ -356,7 +320,6 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, | |||
| 356 | }}; | 320 | }}; |
| 357 | 321 | ||
| 358 | state.texture_units[0].texture = screen_info.display_texture; | 322 | state.texture_units[0].texture = screen_info.display_texture; |
| 359 | state.texture_units[0].swizzle = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA}; | ||
| 360 | // Workaround brigthness problems in SMO by enabling sRGB in the final output | 323 | // Workaround brigthness problems in SMO by enabling sRGB in the final output |
| 361 | // if it has been used in the frame. Needed because of this bug in QT: QTBUG-50987 | 324 | // if it has been used in the frame. Needed because of this bug in QT: QTBUG-50987 |
| 362 | state.framebuffer_srgb.enabled = OpenGLState::GetsRGBUsed(); | 325 | state.framebuffer_srgb.enabled = OpenGLState::GetsRGBUsed(); |