summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp35
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.h14
-rw-r--r--src/video_core/renderer_opengl/util_shaders.cpp35
-rw-r--r--src/video_core/renderer_opengl/util_shaders.h6
4 files changed, 48 insertions, 42 deletions
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index 3ec78d866..54dae2c41 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -473,7 +473,7 @@ void TextureCacheRuntime::EmulateCopyImage(Image& dst, Image& src,
473 ASSERT(src.info.type == ImageType::e3D); 473 ASSERT(src.info.type == ImageType::e3D);
474 util_shaders.CopyBC4(dst, src, copies); 474 util_shaders.CopyBC4(dst, src, copies);
475 } else if (IsPixelFormatBGR(dst.info.format) || IsPixelFormatBGR(src.info.format)) { 475 } else if (IsPixelFormatBGR(dst.info.format) || IsPixelFormatBGR(src.info.format)) {
476 util_shaders.CopyBGR(dst, src, copies); 476 bgr_copy_pass.CopyBGR(dst, src, copies);
477 } else { 477 } else {
478 UNREACHABLE(); 478 UNREACHABLE();
479 } 479 }
@@ -1112,4 +1112,37 @@ Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM
1112 framebuffer.handle = handle; 1112 framebuffer.handle = handle;
1113} 1113}
1114 1114
1115void BGRCopyPass::CopyBGR(Image& dst_image, Image& src_image,
1116 std::span<const VideoCommon::ImageCopy> copies) {
1117 static constexpr VideoCommon::Offset3D zero_offset{0, 0, 0};
1118 const u32 requested_pbo_size =
1119 std::max(src_image.unswizzled_size_bytes, dst_image.unswizzled_size_bytes);
1120
1121 if (bgr_pbo_size < requested_pbo_size) {
1122 bgr_pbo.Create();
1123 bgr_pbo_size = requested_pbo_size;
1124 glNamedBufferData(bgr_pbo.handle, bgr_pbo_size, nullptr, GL_STREAM_COPY);
1125 }
1126 for (const ImageCopy& copy : copies) {
1127 ASSERT(copy.src_offset == zero_offset);
1128 ASSERT(copy.dst_offset == zero_offset);
1129
1130 // Copy from source to PBO
1131 glPixelStorei(GL_PACK_ALIGNMENT, 1);
1132 glPixelStorei(GL_PACK_ROW_LENGTH, copy.extent.width);
1133 glBindBuffer(GL_PIXEL_PACK_BUFFER, bgr_pbo.handle);
1134 glGetTextureSubImage(src_image.Handle(), 0, 0, 0, 0, copy.extent.width, copy.extent.height,
1135 copy.src_subresource.num_layers, src_image.GlFormat(),
1136 src_image.GlType(), static_cast<GLsizei>(bgr_pbo_size), nullptr);
1137
1138 // Copy from PBO to destination in desired GL format
1139 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1140 glPixelStorei(GL_UNPACK_ROW_LENGTH, copy.extent.width);
1141 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, bgr_pbo.handle);
1142 glTextureSubImage3D(dst_image.Handle(), 0, 0, 0, 0, copy.extent.width, copy.extent.height,
1143 copy.dst_subresource.num_layers, dst_image.GlFormat(),
1144 dst_image.GlType(), nullptr);
1145 }
1146}
1147
1115} // namespace OpenGL 1148} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h
index 990a8ddcb..c498a8a8f 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.h
+++ b/src/video_core/renderer_opengl/gl_texture_cache.h
@@ -47,6 +47,19 @@ struct FormatProperties {
47 bool is_compressed; 47 bool is_compressed;
48}; 48};
49 49
50class BGRCopyPass {
51public:
52 BGRCopyPass() = default;
53 ~BGRCopyPass() = default;
54
55 void CopyBGR(Image& dst_image, Image& src_image,
56 std::span<const VideoCommon::ImageCopy> copies);
57
58private:
59 OGLBuffer bgr_pbo;
60 size_t bgr_pbo_size{};
61};
62
50class TextureCacheRuntime { 63class TextureCacheRuntime {
51 friend Framebuffer; 64 friend Framebuffer;
52 friend Image; 65 friend Image;
@@ -118,6 +131,7 @@ private:
118 const Device& device; 131 const Device& device;
119 StateTracker& state_tracker; 132 StateTracker& state_tracker;
120 UtilShaders util_shaders; 133 UtilShaders util_shaders;
134 BGRCopyPass bgr_copy_pass;
121 135
122 std::array<std::unordered_map<GLenum, FormatProperties>, 3> format_properties; 136 std::array<std::unordered_map<GLenum, FormatProperties>, 3> format_properties;
123 bool has_broken_texture_view_formats = false; 137 bool has_broken_texture_view_formats = false;
diff --git a/src/video_core/renderer_opengl/util_shaders.cpp b/src/video_core/renderer_opengl/util_shaders.cpp
index 2cb6e19b3..b4083cc36 100644
--- a/src/video_core/renderer_opengl/util_shaders.cpp
+++ b/src/video_core/renderer_opengl/util_shaders.cpp
@@ -44,11 +44,6 @@ namespace {
44OGLProgram MakeProgram(std::string_view source) { 44OGLProgram MakeProgram(std::string_view source) {
45 return CreateProgram(source, GL_COMPUTE_SHADER); 45 return CreateProgram(source, GL_COMPUTE_SHADER);
46} 46}
47
48size_t NumPixelsInCopy(const VideoCommon::ImageCopy& copy) {
49 return static_cast<size_t>(copy.extent.width * copy.extent.height *
50 copy.src_subresource.num_layers);
51}
52} // Anonymous namespace 47} // Anonymous namespace
53 48
54UtilShaders::UtilShaders(ProgramManager& program_manager_) 49UtilShaders::UtilShaders(ProgramManager& program_manager_)
@@ -255,36 +250,6 @@ void UtilShaders::CopyBC4(Image& dst_image, Image& src_image, std::span<const Im
255 program_manager.RestoreGuestCompute(); 250 program_manager.RestoreGuestCompute();
256} 251}
257 252
258void UtilShaders::CopyBGR(Image& dst_image, Image& src_image,
259 std::span<const VideoCommon::ImageCopy> copies) {
260 static constexpr VideoCommon::Offset3D zero_offset{0, 0, 0};
261 for (const ImageCopy& copy : copies) {
262 ASSERT(copy.src_offset == zero_offset);
263 ASSERT(copy.dst_offset == zero_offset);
264
265 if (bgr_pbo_size < dst_image.unswizzled_size_bytes) {
266 bgr_pbo.Create();
267 bgr_pbo_size = dst_image.unswizzled_size_bytes;
268 glNamedBufferData(bgr_pbo.handle, bgr_pbo_size, nullptr, GL_STREAM_COPY);
269 }
270 // Copy from source to PBO
271 glPixelStorei(GL_PACK_ALIGNMENT, 1);
272 glPixelStorei(GL_PACK_ROW_LENGTH, copy.extent.width);
273 glBindBuffer(GL_PIXEL_PACK_BUFFER, bgr_pbo.handle);
274 glGetTextureSubImage(src_image.Handle(), 0, 0, 0, 0, copy.extent.width, copy.extent.height,
275 copy.src_subresource.num_layers, src_image.GlFormat(),
276 src_image.GlType(), static_cast<GLsizei>(bgr_pbo_size), nullptr);
277
278 // Copy from PBO to destination in reverse order
279 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
280 glPixelStorei(GL_UNPACK_ROW_LENGTH, copy.extent.width);
281 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, bgr_pbo.handle);
282 glTextureSubImage3D(dst_image.Handle(), 0, 0, 0, 0, copy.extent.width, copy.extent.height,
283 copy.dst_subresource.num_layers, dst_image.GlFormat(),
284 dst_image.GlType(), nullptr);
285 }
286}
287
288GLenum StoreFormat(u32 bytes_per_block) { 253GLenum StoreFormat(u32 bytes_per_block) {
289 switch (bytes_per_block) { 254 switch (bytes_per_block) {
290 case 1: 255 case 1:
diff --git a/src/video_core/renderer_opengl/util_shaders.h b/src/video_core/renderer_opengl/util_shaders.h
index b474480cb..aaa5fba3a 100644
--- a/src/video_core/renderer_opengl/util_shaders.h
+++ b/src/video_core/renderer_opengl/util_shaders.h
@@ -39,9 +39,6 @@ public:
39 void CopyBC4(Image& dst_image, Image& src_image, 39 void CopyBC4(Image& dst_image, Image& src_image,
40 std::span<const VideoCommon::ImageCopy> copies); 40 std::span<const VideoCommon::ImageCopy> copies);
41 41
42 void CopyBGR(Image& dst_image, Image& src_image,
43 std::span<const VideoCommon::ImageCopy> copies);
44
45private: 42private:
46 ProgramManager& program_manager; 43 ProgramManager& program_manager;
47 44
@@ -53,9 +50,6 @@ private:
53 OGLProgram pitch_unswizzle_program; 50 OGLProgram pitch_unswizzle_program;
54 OGLProgram copy_bgra_program; 51 OGLProgram copy_bgra_program;
55 OGLProgram copy_bc4_program; 52 OGLProgram copy_bc4_program;
56
57 OGLBuffer bgr_pbo;
58 size_t bgr_pbo_size{};
59}; 53};
60 54
61GLenum StoreFormat(u32 bytes_per_block); 55GLenum StoreFormat(u32 bytes_per_block);