summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-05-26 02:17:17 -0300
committerGravatar ReinUsesLisp2020-05-26 17:50:08 -0300
commitb17fe82973009cc204a298bf8c345ea6eec37a17 (patch)
tree543ae26fad2f4198f7682b44086b8dc6338f8ea0 /src
parenttexture_cache: Implement depth stencil texture swizzles (diff)
downloadyuzu-b17fe82973009cc204a298bf8c345ea6eec37a17.tar.gz
yuzu-b17fe82973009cc204a298bf8c345ea6eec37a17.tar.xz
yuzu-b17fe82973009cc204a298bf8c345ea6eec37a17.zip
gl_texture_cache: Implement small texture view cache for swizzles
This fixes cases where the texture swizzle was applied twice on the same draw to a texture bound to two different slots.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp21
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp42
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.h18
3 files changed, 44 insertions, 37 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 8116a5daa..716d43e65 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -977,16 +977,12 @@ void RasterizerOpenGL::SetupTexture(u32 binding, const Tegra::Texture::FullTextu
977 glBindTextureUnit(binding, 0); 977 glBindTextureUnit(binding, 0);
978 return; 978 return;
979 } 979 }
980 glBindTextureUnit(binding, view->GetTexture()); 980 const GLuint handle = view->GetTexture(texture.tic.x_source, texture.tic.y_source,
981 981 texture.tic.z_source, texture.tic.w_source);
982 if (view->GetSurfaceParams().IsBuffer()) { 982 glBindTextureUnit(binding, handle);
983 return; 983 if (!view->GetSurfaceParams().IsBuffer()) {
984 glBindSampler(binding, sampler_cache.GetSampler(texture.tsc));
984 } 985 }
985 // Apply swizzle to textures that are not buffers.
986 view->ApplySwizzle(texture.tic.x_source, texture.tic.y_source, texture.tic.z_source,
987 texture.tic.w_source);
988
989 glBindSampler(binding, sampler_cache.GetSampler(texture.tsc));
990} 986}
991 987
992void RasterizerOpenGL::SetupDrawImages(std::size_t stage_index, const Shader& shader) { 988void RasterizerOpenGL::SetupDrawImages(std::size_t stage_index, const Shader& shader) {
@@ -1015,14 +1011,11 @@ void RasterizerOpenGL::SetupImage(u32 binding, const Tegra::Texture::TICEntry& t
1015 glBindImageTexture(binding, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R8); 1011 glBindImageTexture(binding, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R8);
1016 return; 1012 return;
1017 } 1013 }
1018 if (!tic.IsBuffer()) {
1019 view->ApplySwizzle(tic.x_source, tic.y_source, tic.z_source, tic.w_source);
1020 }
1021 if (entry.is_written) { 1014 if (entry.is_written) {
1022 view->MarkAsModified(texture_cache.Tick()); 1015 view->MarkAsModified(texture_cache.Tick());
1023 } 1016 }
1024 glBindImageTexture(binding, view->GetTexture(), 0, GL_TRUE, 0, GL_READ_WRITE, 1017 const GLuint handle = view->GetTexture(tic.x_source, tic.y_source, tic.z_source, tic.w_source);
1025 view->GetFormat()); 1018 glBindImageTexture(binding, handle, 0, GL_TRUE, 0, GL_READ_WRITE, view->GetFormat());
1026} 1019}
1027 1020
1028void RasterizerOpenGL::SyncViewport() { 1021void RasterizerOpenGL::SyncViewport() {
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index 7e0ffe3cd..4faa8b90c 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -35,7 +35,7 @@ MICROPROFILE_DEFINE(OpenGL_Texture_Buffer_Copy, "OpenGL", "Texture Buffer Copy",
35namespace { 35namespace {
36 36
37struct FormatTuple { 37struct FormatTuple {
38 GLint internal_format; 38 GLenum internal_format;
39 GLenum format = GL_NONE; 39 GLenum format = GL_NONE;
40 GLenum type = GL_NONE; 40 GLenum type = GL_NONE;
41}; 41};
@@ -387,7 +387,7 @@ void CachedSurface::DecorateSurfaceName() {
387} 387}
388 388
389void CachedSurfaceView::DecorateViewName(GPUVAddr gpu_addr, std::string prefix) { 389void CachedSurfaceView::DecorateViewName(GPUVAddr gpu_addr, std::string prefix) {
390 LabelGLObject(GL_TEXTURE, texture_view.handle, gpu_addr, prefix); 390 LabelGLObject(GL_TEXTURE, main_view.handle, gpu_addr, prefix);
391} 391}
392 392
393View CachedSurface::CreateView(const ViewParams& view_key) { 393View CachedSurface::CreateView(const ViewParams& view_key) {
@@ -403,15 +403,13 @@ View CachedSurface::CreateViewInner(const ViewParams& view_key, const bool is_pr
403} 403}
404 404
405CachedSurfaceView::CachedSurfaceView(CachedSurface& surface, const ViewParams& params, 405CachedSurfaceView::CachedSurfaceView(CachedSurface& surface, const ViewParams& params,
406 const bool is_proxy) 406 bool is_proxy)
407 : VideoCommon::ViewBase(params), surface{surface}, is_proxy{is_proxy} { 407 : VideoCommon::ViewBase(params), surface{surface},
408 target = GetTextureTarget(params.target); 408 format{GetFormatTuple(surface.GetSurfaceParams().pixel_format).internal_format},
409 format = GetFormatTuple(surface.GetSurfaceParams().pixel_format).internal_format; 409 target{GetTextureTarget(params.target)}, is_proxy{is_proxy} {
410 if (!is_proxy) { 410 if (!is_proxy) {
411 texture_view = CreateTextureView(); 411 main_view = CreateTextureView();
412 } 412 }
413 current_swizzle =
414 EncodeSwizzle(SwizzleSource::R, SwizzleSource::G, SwizzleSource::B, SwizzleSource::A);
415} 413}
416 414
417CachedSurfaceView::~CachedSurfaceView() = default; 415CachedSurfaceView::~CachedSurfaceView() = default;
@@ -454,23 +452,34 @@ void CachedSurfaceView::Attach(GLenum attachment, GLenum target) const {
454 } 452 }
455} 453}
456 454
457void CachedSurfaceView::ApplySwizzle(SwizzleSource x_source, SwizzleSource y_source, 455GLuint CachedSurfaceView::GetTexture(SwizzleSource x_source, SwizzleSource y_source,
458 SwizzleSource z_source, SwizzleSource w_source) { 456 SwizzleSource z_source, SwizzleSource w_source) {
457 if (GetSurfaceParams().IsBuffer()) {
458 return GetTexture();
459 }
459 const u32 new_swizzle = EncodeSwizzle(x_source, y_source, z_source, w_source); 460 const u32 new_swizzle = EncodeSwizzle(x_source, y_source, z_source, w_source);
460 if (current_swizzle == new_swizzle) { 461 if (current_swizzle == new_swizzle) {
461 return; 462 return current_view;
462 } 463 }
463 current_swizzle = new_swizzle; 464 current_swizzle = new_swizzle;
464 465
466 const auto [entry, is_cache_miss] = view_cache.try_emplace(new_swizzle);
467 OGLTextureView& view = entry->second;
468 if (!is_cache_miss) {
469 current_view = view.handle;
470 return view.handle;
471 }
472 view = CreateTextureView();
473 current_view = view.handle;
474
465 std::array swizzle{x_source, y_source, z_source, w_source}; 475 std::array swizzle{x_source, y_source, z_source, w_source};
466 476
467 const GLuint handle = GetTexture(); 477 switch (const PixelFormat format = GetSurfaceParams().pixel_format) {
468 switch (const PixelFormat format = surface.GetSurfaceParams().pixel_format) {
469 case PixelFormat::S8Z24:
470 case PixelFormat::Z24S8: 478 case PixelFormat::Z24S8:
471 case PixelFormat::Z32FS8: 479 case PixelFormat::Z32FS8:
480 case PixelFormat::S8Z24:
472 UNIMPLEMENTED_IF(x_source != SwizzleSource::R && x_source != SwizzleSource::G); 481 UNIMPLEMENTED_IF(x_source != SwizzleSource::R && x_source != SwizzleSource::G);
473 glTextureParameteri(handle, GL_DEPTH_STENCIL_TEXTURE_MODE, 482 glTextureParameteri(view.handle, GL_DEPTH_STENCIL_TEXTURE_MODE,
474 GetComponent(format, x_source == SwizzleSource::R)); 483 GetComponent(format, x_source == SwizzleSource::R));
475 484
476 // Make sure we sample the first component 485 // Make sure we sample the first component
@@ -481,10 +490,11 @@ void CachedSurfaceView::ApplySwizzle(SwizzleSource x_source, SwizzleSource y_sou
481 default: { 490 default: {
482 const std::array gl_swizzle = {GetSwizzleSource(swizzle[0]), GetSwizzleSource(swizzle[1]), 491 const std::array gl_swizzle = {GetSwizzleSource(swizzle[0]), GetSwizzleSource(swizzle[1]),
483 GetSwizzleSource(swizzle[2]), GetSwizzleSource(swizzle[3])}; 492 GetSwizzleSource(swizzle[2]), GetSwizzleSource(swizzle[3])};
484 glTextureParameteriv(handle, GL_TEXTURE_SWIZZLE_RGBA, gl_swizzle.data()); 493 glTextureParameteriv(view.handle, GL_TEXTURE_SWIZZLE_RGBA, gl_swizzle.data());
485 break; 494 break;
486 } 495 }
487 } 496 }
497 return view.handle;
488} 498}
489 499
490OGLTextureView CachedSurfaceView::CreateTextureView() const { 500OGLTextureView CachedSurfaceView::CreateTextureView() const {
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h
index 0d88d738f..8a2ac8603 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.h
+++ b/src/video_core/renderer_opengl/gl_texture_cache.h
@@ -83,7 +83,7 @@ public:
83 /// Attaches this texture view to the current bound GL_DRAW_FRAMEBUFFER 83 /// Attaches this texture view to the current bound GL_DRAW_FRAMEBUFFER
84 void Attach(GLenum attachment, GLenum target) const; 84 void Attach(GLenum attachment, GLenum target) const;
85 85
86 void ApplySwizzle(Tegra::Texture::SwizzleSource x_source, 86 GLuint GetTexture(Tegra::Texture::SwizzleSource x_source,
87 Tegra::Texture::SwizzleSource y_source, 87 Tegra::Texture::SwizzleSource y_source,
88 Tegra::Texture::SwizzleSource z_source, 88 Tegra::Texture::SwizzleSource z_source,
89 Tegra::Texture::SwizzleSource w_source); 89 Tegra::Texture::SwizzleSource w_source);
@@ -98,7 +98,7 @@ public:
98 if (is_proxy) { 98 if (is_proxy) {
99 return surface.GetTexture(); 99 return surface.GetTexture();
100 } 100 }
101 return texture_view.handle; 101 return main_view.handle;
102 } 102 }
103 103
104 GLenum GetFormat() const { 104 GLenum GetFormat() const {
@@ -113,12 +113,16 @@ private:
113 OGLTextureView CreateTextureView() const; 113 OGLTextureView CreateTextureView() const;
114 114
115 CachedSurface& surface; 115 CachedSurface& surface;
116 GLenum target{}; 116 const GLenum format;
117 GLenum format{}; 117 const GLenum target;
118 const bool is_proxy;
119
120 std::unordered_map<u32, OGLTextureView> view_cache;
121 OGLTextureView main_view;
118 122
119 OGLTextureView texture_view; 123 // Use an invalid default so it always fails the comparison test
120 u32 current_swizzle{}; 124 u32 current_swizzle = 0xffffffff;
121 bool is_proxy{}; 125 GLuint current_view = 0;
122}; 126};
123 127
124class TextureCacheOpenGL final : public TextureCacheBase { 128class TextureCacheOpenGL final : public TextureCacheBase {