diff options
| author | 2021-11-18 11:30:47 -0800 | |
|---|---|---|
| committer | 2021-11-18 11:30:47 -0800 | |
| commit | 0bc46fedd617f6a42c53716680ed99d8f42bf99a (patch) | |
| tree | aec333a588d638492cca77d7814cdc5379d2b6c0 /src/video_core/renderer_opengl | |
| parent | Merge pull request #7353 from v1993/no-more-epilepsy (diff) | |
| parent | gl_texture_cache: Round format conversion PBO to next power of 2 (diff) | |
| download | yuzu-0bc46fedd617f6a42c53716680ed99d8f42bf99a.tar.gz yuzu-0bc46fedd617f6a42c53716680ed99d8f42bf99a.tar.xz yuzu-0bc46fedd617f6a42c53716680ed99d8f42bf99a.zip | |
Merge pull request #7349 from ameerj/ogl-convert-image
gl_texture_cache: Implement pixel format conversions for copies
Diffstat (limited to 'src/video_core/renderer_opengl')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.cpp | 52 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.h | 19 |
2 files changed, 43 insertions, 28 deletions
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 2f7d98d8b..6956535e5 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp | |||
| @@ -396,6 +396,10 @@ OGLTexture MakeImage(const VideoCommon::ImageInfo& info, GLenum gl_internal_form | |||
| 396 | UNREACHABLE_MSG("Invalid image format={}", format); | 396 | UNREACHABLE_MSG("Invalid image format={}", format); |
| 397 | return GL_R32UI; | 397 | return GL_R32UI; |
| 398 | } | 398 | } |
| 399 | |||
| 400 | [[nodiscard]] u32 NextPow2(u32 value) { | ||
| 401 | return 1U << (32U - std::countl_zero(value - 1U)); | ||
| 402 | } | ||
| 399 | } // Anonymous namespace | 403 | } // Anonymous namespace |
| 400 | 404 | ||
| 401 | ImageBufferMap::~ImageBufferMap() { | 405 | ImageBufferMap::~ImageBufferMap() { |
| @@ -522,6 +526,12 @@ void TextureCacheRuntime::CopyImage(Image& dst_image, Image& src_image, | |||
| 522 | } | 526 | } |
| 523 | } | 527 | } |
| 524 | 528 | ||
| 529 | void TextureCacheRuntime::ConvertImage(Image& dst, Image& src, | ||
| 530 | std::span<const VideoCommon::ImageCopy> copies) { | ||
| 531 | LOG_DEBUG(Render_OpenGL, "Converting {} to {}", src.info.format, dst.info.format); | ||
| 532 | format_conversion_pass.ConvertImage(dst, src, copies); | ||
| 533 | } | ||
| 534 | |||
| 525 | bool TextureCacheRuntime::CanImageBeCopied(const Image& dst, const Image& src) { | 535 | bool TextureCacheRuntime::CanImageBeCopied(const Image& dst, const Image& src) { |
| 526 | if (dst.info.type == ImageType::e3D && dst.info.format == PixelFormat::BC4_UNORM) { | 536 | if (dst.info.type == ImageType::e3D && dst.info.format == PixelFormat::BC4_UNORM) { |
| 527 | return false; | 537 | return false; |
| @@ -538,7 +548,7 @@ void TextureCacheRuntime::EmulateCopyImage(Image& dst, Image& src, | |||
| 538 | ASSERT(src.info.type == ImageType::e3D); | 548 | ASSERT(src.info.type == ImageType::e3D); |
| 539 | util_shaders.CopyBC4(dst, src, copies); | 549 | util_shaders.CopyBC4(dst, src, copies); |
| 540 | } else if (IsPixelFormatBGR(dst.info.format) || IsPixelFormatBGR(src.info.format)) { | 550 | } else if (IsPixelFormatBGR(dst.info.format) || IsPixelFormatBGR(src.info.format)) { |
| 541 | bgr_copy_pass.CopyBGR(dst, src, copies); | 551 | format_conversion_pass.ConvertImage(dst, src, copies); |
| 542 | } else { | 552 | } else { |
| 543 | UNREACHABLE(); | 553 | UNREACHABLE(); |
| 544 | } | 554 | } |
| @@ -1286,35 +1296,37 @@ Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM | |||
| 1286 | 1296 | ||
| 1287 | Framebuffer::~Framebuffer() = default; | 1297 | Framebuffer::~Framebuffer() = default; |
| 1288 | 1298 | ||
| 1289 | void BGRCopyPass::CopyBGR(Image& dst_image, Image& src_image, | 1299 | void FormatConversionPass::ConvertImage(Image& dst_image, Image& src_image, |
| 1290 | std::span<const VideoCommon::ImageCopy> copies) { | 1300 | std::span<const VideoCommon::ImageCopy> copies) { |
| 1291 | static constexpr VideoCommon::Offset3D zero_offset{0, 0, 0}; | 1301 | const GLenum dst_target = ImageTarget(dst_image.info); |
| 1302 | const GLenum src_target = ImageTarget(src_image.info); | ||
| 1292 | const u32 img_bpp = BytesPerBlock(src_image.info.format); | 1303 | const u32 img_bpp = BytesPerBlock(src_image.info.format); |
| 1293 | for (const ImageCopy& copy : copies) { | 1304 | for (const ImageCopy& copy : copies) { |
| 1294 | ASSERT(copy.src_offset == zero_offset); | 1305 | const auto src_origin = MakeCopyOrigin(copy.src_offset, copy.src_subresource, src_target); |
| 1295 | ASSERT(copy.dst_offset == zero_offset); | 1306 | const auto dst_origin = MakeCopyOrigin(copy.dst_offset, copy.dst_subresource, dst_target); |
| 1296 | const u32 num_src_layers = static_cast<u32>(copy.src_subresource.num_layers); | 1307 | const auto region = MakeCopyRegion(copy.extent, copy.dst_subresource, dst_target); |
| 1297 | const u32 copy_size = copy.extent.width * copy.extent.height * num_src_layers * img_bpp; | 1308 | const u32 copy_size = region.width * region.height * region.depth * img_bpp; |
| 1298 | if (bgr_pbo_size < copy_size) { | 1309 | if (pbo_size < copy_size) { |
| 1299 | bgr_pbo.Create(); | 1310 | intermediate_pbo.Create(); |
| 1300 | bgr_pbo_size = copy_size; | 1311 | pbo_size = NextPow2(copy_size); |
| 1301 | glNamedBufferData(bgr_pbo.handle, bgr_pbo_size, nullptr, GL_STREAM_COPY); | 1312 | glNamedBufferData(intermediate_pbo.handle, pbo_size, nullptr, GL_STREAM_COPY); |
| 1302 | } | 1313 | } |
| 1303 | // Copy from source to PBO | 1314 | // Copy from source to PBO |
| 1304 | glPixelStorei(GL_PACK_ALIGNMENT, 1); | 1315 | glPixelStorei(GL_PACK_ALIGNMENT, 1); |
| 1305 | glPixelStorei(GL_PACK_ROW_LENGTH, copy.extent.width); | 1316 | glPixelStorei(GL_PACK_ROW_LENGTH, copy.extent.width); |
| 1306 | glBindBuffer(GL_PIXEL_PACK_BUFFER, bgr_pbo.handle); | 1317 | glBindBuffer(GL_PIXEL_PACK_BUFFER, intermediate_pbo.handle); |
| 1307 | glGetTextureSubImage(src_image.Handle(), 0, 0, 0, 0, copy.extent.width, copy.extent.height, | 1318 | glGetTextureSubImage(src_image.Handle(), src_origin.level, src_origin.x, src_origin.y, |
| 1308 | num_src_layers, src_image.GlFormat(), src_image.GlType(), | 1319 | src_origin.z, region.width, region.height, region.depth, |
| 1309 | static_cast<GLsizei>(bgr_pbo_size), nullptr); | 1320 | src_image.GlFormat(), src_image.GlType(), |
| 1321 | static_cast<GLsizei>(pbo_size), nullptr); | ||
| 1310 | 1322 | ||
| 1311 | // Copy from PBO to destination in desired GL format | 1323 | // Copy from PBO to destination in desired GL format |
| 1312 | glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | 1324 | glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
| 1313 | glPixelStorei(GL_UNPACK_ROW_LENGTH, copy.extent.width); | 1325 | glPixelStorei(GL_UNPACK_ROW_LENGTH, copy.extent.width); |
| 1314 | glBindBuffer(GL_PIXEL_UNPACK_BUFFER, bgr_pbo.handle); | 1326 | glBindBuffer(GL_PIXEL_UNPACK_BUFFER, intermediate_pbo.handle); |
| 1315 | glTextureSubImage3D(dst_image.Handle(), 0, 0, 0, 0, copy.extent.width, copy.extent.height, | 1327 | glTextureSubImage3D(dst_image.Handle(), dst_origin.level, dst_origin.x, dst_origin.y, |
| 1316 | copy.dst_subresource.num_layers, dst_image.GlFormat(), | 1328 | dst_origin.z, region.width, region.height, region.depth, |
| 1317 | dst_image.GlType(), nullptr); | 1329 | dst_image.GlFormat(), dst_image.GlType(), nullptr); |
| 1318 | } | 1330 | } |
| 1319 | } | 1331 | } |
| 1320 | 1332 | ||
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index 1bb762568..578f8d523 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h | |||
| @@ -52,17 +52,17 @@ struct FormatProperties { | |||
| 52 | bool is_compressed; | 52 | bool is_compressed; |
| 53 | }; | 53 | }; |
| 54 | 54 | ||
| 55 | class BGRCopyPass { | 55 | class FormatConversionPass { |
| 56 | public: | 56 | public: |
| 57 | BGRCopyPass() = default; | 57 | FormatConversionPass() = default; |
| 58 | ~BGRCopyPass() = default; | 58 | ~FormatConversionPass() = default; |
| 59 | 59 | ||
| 60 | void CopyBGR(Image& dst_image, Image& src_image, | 60 | void ConvertImage(Image& dst_image, Image& src_image, |
| 61 | std::span<const VideoCommon::ImageCopy> copies); | 61 | std::span<const VideoCommon::ImageCopy> copies); |
| 62 | 62 | ||
| 63 | private: | 63 | private: |
| 64 | OGLBuffer bgr_pbo; | 64 | OGLBuffer intermediate_pbo; |
| 65 | size_t bgr_pbo_size{}; | 65 | size_t pbo_size{}; |
| 66 | }; | 66 | }; |
| 67 | 67 | ||
| 68 | class TextureCacheRuntime { | 68 | class TextureCacheRuntime { |
| @@ -86,6 +86,8 @@ public: | |||
| 86 | 86 | ||
| 87 | void CopyImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies); | 87 | void CopyImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies); |
| 88 | 88 | ||
| 89 | void ConvertImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies); | ||
| 90 | |||
| 89 | void ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view, bool rescaled) { | 91 | void ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view, bool rescaled) { |
| 90 | UNIMPLEMENTED(); | 92 | UNIMPLEMENTED(); |
| 91 | } | 93 | } |
| @@ -144,7 +146,7 @@ private: | |||
| 144 | const Device& device; | 146 | const Device& device; |
| 145 | StateTracker& state_tracker; | 147 | StateTracker& state_tracker; |
| 146 | UtilShaders util_shaders; | 148 | UtilShaders util_shaders; |
| 147 | BGRCopyPass bgr_copy_pass; | 149 | FormatConversionPass format_conversion_pass; |
| 148 | 150 | ||
| 149 | std::array<std::unordered_map<GLenum, FormatProperties>, 3> format_properties; | 151 | std::array<std::unordered_map<GLenum, FormatProperties>, 3> format_properties; |
| 150 | bool has_broken_texture_view_formats = false; | 152 | bool has_broken_texture_view_formats = false; |
| @@ -336,6 +338,7 @@ struct TextureCacheParams { | |||
| 336 | static constexpr bool FRAMEBUFFER_BLITS = true; | 338 | static constexpr bool FRAMEBUFFER_BLITS = true; |
| 337 | static constexpr bool HAS_EMULATED_COPIES = true; | 339 | static constexpr bool HAS_EMULATED_COPIES = true; |
| 338 | static constexpr bool HAS_DEVICE_MEMORY_INFO = true; | 340 | static constexpr bool HAS_DEVICE_MEMORY_INFO = true; |
| 341 | static constexpr bool HAS_PIXEL_FORMAT_CONVERSIONS = true; | ||
| 339 | 342 | ||
| 340 | using Runtime = OpenGL::TextureCacheRuntime; | 343 | using Runtime = OpenGL::TextureCacheRuntime; |
| 341 | using Image = OpenGL::Image; | 344 | using Image = OpenGL::Image; |