diff options
| author | 2020-05-24 17:57:54 -0300 | |
|---|---|---|
| committer | 2020-05-26 17:44:50 -0300 | |
| commit | 8bba84a4014e1bf204089ff7dbcaa73917f84738 (patch) | |
| tree | 2775c6a219a18ff4ceed45e4954f6707d7fafd8b /src/video_core/renderer_opengl | |
| parent | Merge pull request #3978 from ReinUsesLisp/write-rz (diff) | |
| download | yuzu-8bba84a4014e1bf204089ff7dbcaa73917f84738.tar.gz yuzu-8bba84a4014e1bf204089ff7dbcaa73917f84738.tar.xz yuzu-8bba84a4014e1bf204089ff7dbcaa73917f84738.zip | |
texture_cache: Implement depth stencil texture swizzles
Stop ignoring image swizzles on depth and stencil images.
This doesn't fix a known issue on Xenoblade Chronicles 2 where an OpenGL
texture changes swizzles twice before being used. A proper fix would be
having a small texture view cache for this like we do on Vulkan.
Diffstat (limited to 'src/video_core/renderer_opengl')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.cpp | 39 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.h | 10 |
2 files changed, 29 insertions, 20 deletions
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 94fbd2a22..7e0ffe3cd 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp | |||
| @@ -238,6 +238,12 @@ OGLTexture CreateTexture(const SurfaceParams& params, GLenum target, GLenum inte | |||
| 238 | return texture; | 238 | return texture; |
| 239 | } | 239 | } |
| 240 | 240 | ||
| 241 | constexpr u32 EncodeSwizzle(SwizzleSource x_source, SwizzleSource y_source, SwizzleSource z_source, | ||
| 242 | SwizzleSource w_source) { | ||
| 243 | return (static_cast<u32>(x_source) << 24) | (static_cast<u32>(y_source) << 16) | | ||
| 244 | (static_cast<u32>(z_source) << 8) | static_cast<u32>(w_source); | ||
| 245 | } | ||
| 246 | |||
| 241 | } // Anonymous namespace | 247 | } // Anonymous namespace |
| 242 | 248 | ||
| 243 | CachedSurface::CachedSurface(const GPUVAddr gpu_addr, const SurfaceParams& params, | 249 | CachedSurface::CachedSurface(const GPUVAddr gpu_addr, const SurfaceParams& params, |
| @@ -404,7 +410,8 @@ CachedSurfaceView::CachedSurfaceView(CachedSurface& surface, const ViewParams& p | |||
| 404 | if (!is_proxy) { | 410 | if (!is_proxy) { |
| 405 | texture_view = CreateTextureView(); | 411 | texture_view = CreateTextureView(); |
| 406 | } | 412 | } |
| 407 | swizzle = EncodeSwizzle(SwizzleSource::R, SwizzleSource::G, SwizzleSource::B, SwizzleSource::A); | 413 | current_swizzle = |
| 414 | EncodeSwizzle(SwizzleSource::R, SwizzleSource::G, SwizzleSource::B, SwizzleSource::A); | ||
| 408 | } | 415 | } |
| 409 | 416 | ||
| 410 | CachedSurfaceView::~CachedSurfaceView() = default; | 417 | CachedSurfaceView::~CachedSurfaceView() = default; |
| @@ -449,25 +456,35 @@ void CachedSurfaceView::Attach(GLenum attachment, GLenum target) const { | |||
| 449 | 456 | ||
| 450 | void CachedSurfaceView::ApplySwizzle(SwizzleSource x_source, SwizzleSource y_source, | 457 | void CachedSurfaceView::ApplySwizzle(SwizzleSource x_source, SwizzleSource y_source, |
| 451 | SwizzleSource z_source, SwizzleSource w_source) { | 458 | SwizzleSource z_source, SwizzleSource w_source) { |
| 452 | u32 new_swizzle = EncodeSwizzle(x_source, y_source, z_source, w_source); | 459 | const u32 new_swizzle = EncodeSwizzle(x_source, y_source, z_source, w_source); |
| 453 | if (new_swizzle == swizzle) | 460 | if (current_swizzle == new_swizzle) { |
| 454 | return; | 461 | return; |
| 455 | swizzle = new_swizzle; | 462 | } |
| 456 | const std::array gl_swizzle = {GetSwizzleSource(x_source), GetSwizzleSource(y_source), | 463 | current_swizzle = new_swizzle; |
| 457 | GetSwizzleSource(z_source), GetSwizzleSource(w_source)}; | 464 | |
| 465 | std::array swizzle{x_source, y_source, z_source, w_source}; | ||
| 466 | |||
| 458 | const GLuint handle = GetTexture(); | 467 | const GLuint handle = GetTexture(); |
| 459 | const PixelFormat format = surface.GetSurfaceParams().pixel_format; | 468 | switch (const PixelFormat format = surface.GetSurfaceParams().pixel_format) { |
| 460 | switch (format) { | 469 | case PixelFormat::S8Z24: |
| 461 | case PixelFormat::Z24S8: | 470 | case PixelFormat::Z24S8: |
| 462 | case PixelFormat::Z32FS8: | 471 | case PixelFormat::Z32FS8: |
| 463 | case PixelFormat::S8Z24: | 472 | UNIMPLEMENTED_IF(x_source != SwizzleSource::R && x_source != SwizzleSource::G); |
| 464 | glTextureParameteri(handle, GL_DEPTH_STENCIL_TEXTURE_MODE, | 473 | glTextureParameteri(handle, GL_DEPTH_STENCIL_TEXTURE_MODE, |
| 465 | GetComponent(format, x_source == SwizzleSource::R)); | 474 | GetComponent(format, x_source == SwizzleSource::R)); |
| 466 | break; | 475 | |
| 467 | default: | 476 | // Make sure we sample the first component |
| 477 | std::transform(swizzle.begin(), swizzle.end(), swizzle.begin(), [](SwizzleSource value) { | ||
| 478 | return value == SwizzleSource::G ? SwizzleSource::R : value; | ||
| 479 | }); | ||
| 480 | [[fallthrough]]; | ||
| 481 | default: { | ||
| 482 | const std::array gl_swizzle = {GetSwizzleSource(swizzle[0]), GetSwizzleSource(swizzle[1]), | ||
| 483 | GetSwizzleSource(swizzle[2]), GetSwizzleSource(swizzle[3])}; | ||
| 468 | glTextureParameteriv(handle, GL_TEXTURE_SWIZZLE_RGBA, gl_swizzle.data()); | 484 | glTextureParameteriv(handle, GL_TEXTURE_SWIZZLE_RGBA, gl_swizzle.data()); |
| 469 | break; | 485 | break; |
| 470 | } | 486 | } |
| 487 | } | ||
| 471 | } | 488 | } |
| 472 | 489 | ||
| 473 | OGLTextureView CachedSurfaceView::CreateTextureView() const { | 490 | OGLTextureView 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 02d9981a1..0d88d738f 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h | |||
| @@ -110,14 +110,6 @@ public: | |||
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | private: | 112 | private: |
| 113 | u32 EncodeSwizzle(Tegra::Texture::SwizzleSource x_source, | ||
| 114 | Tegra::Texture::SwizzleSource y_source, | ||
| 115 | Tegra::Texture::SwizzleSource z_source, | ||
| 116 | Tegra::Texture::SwizzleSource w_source) const { | ||
| 117 | return (static_cast<u32>(x_source) << 24) | (static_cast<u32>(y_source) << 16) | | ||
| 118 | (static_cast<u32>(z_source) << 8) | static_cast<u32>(w_source); | ||
| 119 | } | ||
| 120 | |||
| 121 | OGLTextureView CreateTextureView() const; | 113 | OGLTextureView CreateTextureView() const; |
| 122 | 114 | ||
| 123 | CachedSurface& surface; | 115 | CachedSurface& surface; |
| @@ -125,7 +117,7 @@ private: | |||
| 125 | GLenum format{}; | 117 | GLenum format{}; |
| 126 | 118 | ||
| 127 | OGLTextureView texture_view; | 119 | OGLTextureView texture_view; |
| 128 | u32 swizzle{}; | 120 | u32 current_swizzle{}; |
| 129 | bool is_proxy{}; | 121 | bool is_proxy{}; |
| 130 | }; | 122 | }; |
| 131 | 123 | ||