diff options
| author | 2018-12-29 17:51:32 -0300 | |
|---|---|---|
| committer | 2018-12-29 23:49:12 -0300 | |
| commit | 97fb6179b943f9f87bd7cbf185da1153aaae9309 (patch) | |
| tree | 7dd42951c7e5cd4c2cef0ac1356c50a0b52abe5a /src/video_core | |
| parent | Merge pull request #1886 from FearlessTobi/port-4164 (diff) | |
| download | yuzu-97fb6179b943f9f87bd7cbf185da1153aaae9309.tar.gz yuzu-97fb6179b943f9f87bd7cbf185da1153aaae9309.tar.xz yuzu-97fb6179b943f9f87bd7cbf185da1153aaae9309.zip | |
gl_rasterizer_cache: Texture view if shader samples array but OGL is not
When a shader samples a texture array but that texture in OpenGL is
created without layers, use a texture view to increase the texture
hierarchy. For example, instead of binding a GL_TEXTURE_2D bind a
GL_TEXTURE_2D_ARRAY view.
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 7 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 49 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 32 |
3 files changed, 74 insertions, 14 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 2b29fc45f..089daf96f 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -1014,8 +1014,11 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader, | |||
| 1014 | texture_samplers[current_bindpoint].SyncWithConfig(texture.tsc); | 1014 | texture_samplers[current_bindpoint].SyncWithConfig(texture.tsc); |
| 1015 | Surface surface = res_cache.GetTextureSurface(texture, entry); | 1015 | Surface surface = res_cache.GetTextureSurface(texture, entry); |
| 1016 | if (surface != nullptr) { | 1016 | if (surface != nullptr) { |
| 1017 | state.texture_units[current_bindpoint].texture = surface->Texture().handle; | 1017 | const GLuint handle = |
| 1018 | state.texture_units[current_bindpoint].target = surface->Target(); | 1018 | entry.IsArray() ? surface->TextureLayer().handle : surface->Texture().handle; |
| 1019 | const GLenum target = entry.IsArray() ? surface->TargetLayer() : surface->Target(); | ||
| 1020 | state.texture_units[current_bindpoint].texture = handle; | ||
| 1021 | state.texture_units[current_bindpoint].target = target; | ||
| 1019 | state.texture_units[current_bindpoint].swizzle.r = | 1022 | state.texture_units[current_bindpoint].swizzle.r = |
| 1020 | MaxwellToGL::SwizzleSource(texture.tic.x_source); | 1023 | MaxwellToGL::SwizzleSource(texture.tic.x_source); |
| 1021 | state.texture_units[current_bindpoint].swizzle.g = | 1024 | state.texture_units[current_bindpoint].swizzle.g = |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 7ea07631a..352c391a9 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |||
| @@ -44,6 +44,17 @@ struct FormatTuple { | |||
| 44 | bool compressed; | 44 | bool compressed; |
| 45 | }; | 45 | }; |
| 46 | 46 | ||
| 47 | static void ApplyTextureDefaults(GLenum target, u32 max_mip_level) { | ||
| 48 | glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
| 49 | glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||
| 50 | glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
| 51 | glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
| 52 | glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, max_mip_level - 1); | ||
| 53 | if (max_mip_level == 1) { | ||
| 54 | glTexParameterf(target, GL_TEXTURE_LOD_BIAS, 1000.0); | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 47 | void SurfaceParams::InitCacheParameters(Tegra::GPUVAddr gpu_addr_) { | 58 | void SurfaceParams::InitCacheParameters(Tegra::GPUVAddr gpu_addr_) { |
| 48 | auto& memory_manager{Core::System::GetInstance().GPU().MemoryManager()}; | 59 | auto& memory_manager{Core::System::GetInstance().GPU().MemoryManager()}; |
| 49 | const auto cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr_)}; | 60 | const auto cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr_)}; |
| @@ -532,6 +543,9 @@ CachedSurface::CachedSurface(const SurfaceParams& params) | |||
| 532 | glActiveTexture(GL_TEXTURE0); | 543 | glActiveTexture(GL_TEXTURE0); |
| 533 | 544 | ||
| 534 | const auto& format_tuple = GetFormatTuple(params.pixel_format, params.component_type); | 545 | const auto& format_tuple = GetFormatTuple(params.pixel_format, params.component_type); |
| 546 | gl_internal_format = format_tuple.internal_format; | ||
| 547 | gl_is_compressed = format_tuple.compressed; | ||
| 548 | |||
| 535 | if (!format_tuple.compressed) { | 549 | if (!format_tuple.compressed) { |
| 536 | // Only pre-create the texture for non-compressed textures. | 550 | // Only pre-create the texture for non-compressed textures. |
| 537 | switch (params.target) { | 551 | switch (params.target) { |
| @@ -560,15 +574,7 @@ CachedSurface::CachedSurface(const SurfaceParams& params) | |||
| 560 | } | 574 | } |
| 561 | } | 575 | } |
| 562 | 576 | ||
| 563 | glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 577 | ApplyTextureDefaults(SurfaceTargetToGL(params.target), params.max_mip_level); |
| 564 | glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||
| 565 | glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
| 566 | glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
| 567 | glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_MAX_LEVEL, | ||
| 568 | params.max_mip_level - 1); | ||
| 569 | if (params.max_mip_level == 1) { | ||
| 570 | glTexParameterf(SurfaceTargetToGL(params.target), GL_TEXTURE_LOD_BIAS, 1000.0); | ||
| 571 | } | ||
| 572 | 578 | ||
| 573 | LabelGLObject(GL_TEXTURE, texture.handle, params.addr, | 579 | LabelGLObject(GL_TEXTURE, texture.handle, params.addr, |
| 574 | SurfaceParams::SurfaceTargetName(params.target)); | 580 | SurfaceParams::SurfaceTargetName(params.target)); |
| @@ -886,6 +892,31 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle, | |||
| 886 | glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); | 892 | glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
| 887 | } | 893 | } |
| 888 | 894 | ||
| 895 | void CachedSurface::EnsureTextureView() { | ||
| 896 | if (texture_view.handle != 0) | ||
| 897 | return; | ||
| 898 | // Compressed texture are not being created with immutable storage | ||
| 899 | UNIMPLEMENTED_IF(gl_is_compressed); | ||
| 900 | |||
| 901 | const GLenum target{TargetLayer()}; | ||
| 902 | |||
| 903 | texture_view.Create(); | ||
| 904 | glTextureView(texture_view.handle, target, texture.handle, gl_internal_format, 0, | ||
| 905 | params.max_mip_level, 0, 1); | ||
| 906 | |||
| 907 | OpenGLState cur_state = OpenGLState::GetCurState(); | ||
| 908 | const auto& old_tex = cur_state.texture_units[0]; | ||
| 909 | SCOPE_EXIT({ | ||
| 910 | cur_state.texture_units[0] = old_tex; | ||
| 911 | cur_state.Apply(); | ||
| 912 | }); | ||
| 913 | cur_state.texture_units[0].texture = texture_view.handle; | ||
| 914 | cur_state.texture_units[0].target = target; | ||
| 915 | cur_state.Apply(); | ||
| 916 | |||
| 917 | ApplyTextureDefaults(target, params.max_mip_level); | ||
| 918 | } | ||
| 919 | |||
| 889 | MICROPROFILE_DEFINE(OpenGL_TextureUL, "OpenGL", "Texture Upload", MP_RGB(128, 192, 64)); | 920 | MICROPROFILE_DEFINE(OpenGL_TextureUL, "OpenGL", "Texture Upload", MP_RGB(128, 192, 64)); |
| 890 | void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle) { | 921 | void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle) { |
| 891 | if (params.type == SurfaceType::Fill) | 922 | if (params.type == SurfaceType::Fill) |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index c710aa245..7223700c4 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -293,10 +293,31 @@ public: | |||
| 293 | return texture; | 293 | return texture; |
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | const OGLTexture& TextureLayer() { | ||
| 297 | if (params.is_layered) { | ||
| 298 | return Texture(); | ||
| 299 | } | ||
| 300 | EnsureTextureView(); | ||
| 301 | return texture_view; | ||
| 302 | } | ||
| 303 | |||
| 296 | GLenum Target() const { | 304 | GLenum Target() const { |
| 297 | return gl_target; | 305 | return gl_target; |
| 298 | } | 306 | } |
| 299 | 307 | ||
| 308 | GLenum TargetLayer() const { | ||
| 309 | using VideoCore::Surface::SurfaceTarget; | ||
| 310 | switch (params.target) { | ||
| 311 | case SurfaceTarget::Texture1D: | ||
| 312 | return GL_TEXTURE_1D_ARRAY; | ||
| 313 | case SurfaceTarget::Texture2D: | ||
| 314 | return GL_TEXTURE_2D_ARRAY; | ||
| 315 | case SurfaceTarget::TextureCubemap: | ||
| 316 | return GL_TEXTURE_CUBE_MAP_ARRAY; | ||
| 317 | } | ||
| 318 | return Target(); | ||
| 319 | } | ||
| 320 | |||
| 300 | const SurfaceParams& GetSurfaceParams() const { | 321 | const SurfaceParams& GetSurfaceParams() const { |
| 301 | return params; | 322 | return params; |
| 302 | } | 323 | } |
| @@ -311,11 +332,16 @@ public: | |||
| 311 | private: | 332 | private: |
| 312 | void UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle, GLuint draw_fb_handle); | 333 | void UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle, GLuint draw_fb_handle); |
| 313 | 334 | ||
| 335 | void EnsureTextureView(); | ||
| 336 | |||
| 314 | OGLTexture texture; | 337 | OGLTexture texture; |
| 338 | OGLTexture texture_view; | ||
| 315 | std::vector<std::vector<u8>> gl_buffer; | 339 | std::vector<std::vector<u8>> gl_buffer; |
| 316 | SurfaceParams params; | 340 | SurfaceParams params{}; |
| 317 | GLenum gl_target; | 341 | GLenum gl_target{}; |
| 318 | std::size_t cached_size_in_bytes; | 342 | GLenum gl_internal_format{}; |
| 343 | bool gl_is_compressed{}; | ||
| 344 | std::size_t cached_size_in_bytes{}; | ||
| 319 | }; | 345 | }; |
| 320 | 346 | ||
| 321 | class RasterizerCacheOpenGL final : public RasterizerCache<Surface> { | 347 | class RasterizerCacheOpenGL final : public RasterizerCache<Surface> { |