summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-04-14 01:44:16 -0300
committerGravatar ReinUsesLisp2019-06-20 21:36:11 -0300
commitfb94871791f78703737125cd2e5a13db8b7d1059 (patch)
tree774dc3eab1bea643568582fd96ea4d96c4bd824b /src
parentgl_texture_cache: Initial implementation (diff)
downloadyuzu-fb94871791f78703737125cd2e5a13db8b7d1059.tar.gz
yuzu-fb94871791f78703737125cd2e5a13db8b7d1059.tar.xz
yuzu-fb94871791f78703737125cd2e5a13db8b7d1059.zip
gl_texture_cache: Add fast copy path
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp51
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.h9
-rw-r--r--src/video_core/texture_cache.cpp4
-rw-r--r--src/video_core/textures/decoders.cpp3
4 files changed, 60 insertions, 7 deletions
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index 3a456995e..00f9ab92f 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -177,9 +177,9 @@ void ApplyTextureDefaults(const SurfaceParams& params, GLuint texture) {
177 } 177 }
178} 178}
179 179
180OGLTexture CreateTexture(const SurfaceParams& params, GLenum internal_format) { 180OGLTexture CreateTexture(const SurfaceParams& params, GLenum target, GLenum internal_format) {
181 OGLTexture texture; 181 OGLTexture texture;
182 texture.Create(GetTextureTarget(params)); 182 texture.Create(target);
183 183
184 switch (params.GetTarget()) { 184 switch (params.GetTarget()) {
185 case SurfaceTarget::Texture1D: 185 case SurfaceTarget::Texture1D:
@@ -241,7 +241,8 @@ CachedSurface::CachedSurface(const SurfaceParams& params)
241 format = tuple.format; 241 format = tuple.format;
242 type = tuple.type; 242 type = tuple.type;
243 is_compressed = tuple.compressed; 243 is_compressed = tuple.compressed;
244 texture = CreateTexture(params, internal_format); 244 target = GetTextureTarget(params);
245 texture = CreateTexture(params, target, internal_format);
245 staging_buffer.resize(params.GetHostSizeInBytes()); 246 staging_buffer.resize(params.GetHostSizeInBytes());
246} 247}
247 248
@@ -504,9 +505,53 @@ TextureCacheOpenGL::~TextureCacheOpenGL() = default;
504CachedSurfaceView* TextureCacheOpenGL::TryFastGetSurfaceView( 505CachedSurfaceView* TextureCacheOpenGL::TryFastGetSurfaceView(
505 VAddr cpu_addr, u8* host_ptr, const SurfaceParams& params, bool preserve_contents, 506 VAddr cpu_addr, u8* host_ptr, const SurfaceParams& params, bool preserve_contents,
506 const std::vector<CachedSurface*>& overlaps) { 507 const std::vector<CachedSurface*>& overlaps) {
508 if (overlaps.size() > 1) {
509 return nullptr;
510 }
511
512 const auto& old_surface{overlaps[0]};
513 const auto& old_params{old_surface->GetSurfaceParams()};
514 const auto& new_params{params};
515
516 if (old_params.GetTarget() == new_params.GetTarget() &&
517 old_params.GetDepth() == new_params.GetDepth() && old_params.GetDepth() == 1 &&
518 old_params.GetNumLevels() == new_params.GetNumLevels() &&
519 old_params.GetPixelFormat() == new_params.GetPixelFormat()) {
520 return SurfaceCopy(cpu_addr, host_ptr, new_params, old_surface, old_params);
521 }
522
507 return nullptr; 523 return nullptr;
508} 524}
509 525
526CachedSurfaceView* TextureCacheOpenGL::SurfaceCopy(VAddr cpu_addr, u8* host_ptr,
527 const SurfaceParams& new_params,
528 CachedSurface* old_surface,
529 const SurfaceParams& old_params) {
530 CachedSurface* const new_surface{GetUncachedSurface(new_params)};
531 Register(new_surface, cpu_addr, host_ptr);
532
533 const u32 min_width{
534 std::max(old_params.GetDefaultBlockWidth(), new_params.GetDefaultBlockWidth())};
535 const u32 min_height{
536 std::max(old_params.GetDefaultBlockHeight(), new_params.GetDefaultBlockHeight())};
537 for (u32 level = 0; level < old_params.GetNumLevels(); ++level) {
538 const u32 width{std::min(old_params.GetMipWidth(level), new_params.GetMipWidth(level))};
539 const u32 height{std::min(old_params.GetMipHeight(level), new_params.GetMipHeight(level))};
540 if (width < min_width || height < min_height) {
541 // Avoid copies that are too small to be handled in OpenGL
542 break;
543 }
544 glCopyImageSubData(old_surface->GetTexture(), old_surface->GetTarget(), level, 0, 0, 0,
545 new_surface->GetTexture(), new_surface->GetTarget(), level, 0, 0, 0,
546 width, height, 1);
547 }
548
549 new_surface->MarkAsModified(true);
550
551 // TODO(Rodrigo): Add an entry to directly get the superview
552 return new_surface->GetView(cpu_addr, new_params);
553}
554
510std::unique_ptr<CachedSurface> TextureCacheOpenGL::CreateSurface(const SurfaceParams& params) { 555std::unique_ptr<CachedSurface> TextureCacheOpenGL::CreateSurface(const SurfaceParams& params) {
511 return std::make_unique<CachedSurface>(params); 556 return std::make_unique<CachedSurface>(params);
512} 557}
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h
index f0a524882..b18b32d99 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.h
+++ b/src/video_core/renderer_opengl/gl_texture_cache.h
@@ -38,6 +38,10 @@ public:
38 38
39 void LoadBuffer(); 39 void LoadBuffer();
40 40
41 GLenum GetTarget() const {
42 return target;
43 }
44
41 GLuint GetTexture() const { 45 GLuint GetTexture() const {
42 return texture.handle; 46 return texture.handle;
43 } 47 }
@@ -56,6 +60,7 @@ private:
56 GLenum format{}; 60 GLenum format{};
57 GLenum type{}; 61 GLenum type{};
58 bool is_compressed{}; 62 bool is_compressed{};
63 GLenum target{};
59 64
60 OGLTexture texture; 65 OGLTexture texture;
61 66
@@ -126,6 +131,10 @@ protected:
126 const std::vector<CachedSurface*>& overlaps); 131 const std::vector<CachedSurface*>& overlaps);
127 132
128 std::unique_ptr<CachedSurface> CreateSurface(const SurfaceParams& params); 133 std::unique_ptr<CachedSurface> CreateSurface(const SurfaceParams& params);
134
135private:
136 CachedSurfaceView* SurfaceCopy(VAddr cpu_addr, u8* host_ptr, const SurfaceParams& new_params,
137 CachedSurface* old_surface, const SurfaceParams& old_params);
129}; 138};
130 139
131} // namespace OpenGL 140} // namespace OpenGL
diff --git a/src/video_core/texture_cache.cpp b/src/video_core/texture_cache.cpp
index c42365a82..1cfb9962f 100644
--- a/src/video_core/texture_cache.cpp
+++ b/src/video_core/texture_cache.cpp
@@ -160,7 +160,7 @@ u32 SurfaceParams::GetMipBlockHeight(u32 level) const {
160 // Auto block resizing algorithm from: 160 // Auto block resizing algorithm from:
161 // https://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/drivers/nouveau/nv50/nv50_miptree.c 161 // https://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
162 if (level == 0) { 162 if (level == 0) {
163 return block_height; 163 return this->block_height;
164 } 164 }
165 const u32 height{GetMipHeight(level)}; 165 const u32 height{GetMipHeight(level)};
166 const u32 default_block_height{GetDefaultBlockHeight()}; 166 const u32 default_block_height{GetDefaultBlockHeight()};
@@ -316,7 +316,7 @@ std::size_t SurfaceParams::GetInnerMemorySize(bool as_host_size, bool layer_only
316 size += GetInnerMipmapMemorySize(level, as_host_size, layer_only, uncompressed); 316 size += GetInnerMipmapMemorySize(level, as_host_size, layer_only, uncompressed);
317 } 317 }
318 if (is_tiled && !as_host_size) { 318 if (is_tiled && !as_host_size) {
319 size = Common::AlignUp(size, Tegra::Texture::GetGOBSize() * block_height * block_depth); 319 //size = Common::AlignUp(size, Tegra::Texture::GetGOBSize() * block_height * block_depth);
320 } 320 }
321 return size; 321 return size;
322} 322}
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp
index 664ed4b56..217805386 100644
--- a/src/video_core/textures/decoders.cpp
+++ b/src/video_core/textures/decoders.cpp
@@ -359,8 +359,7 @@ std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height
359 const u32 aligned_width = Common::AlignUp(width * bytes_per_pixel, gob_size_x); 359 const u32 aligned_width = Common::AlignUp(width * bytes_per_pixel, gob_size_x);
360 const u32 aligned_height = Common::AlignUp(height, gob_size_y * block_height); 360 const u32 aligned_height = Common::AlignUp(height, gob_size_y * block_height);
361 const u32 aligned_depth = Common::AlignUp(depth, gob_size_z * block_depth); 361 const u32 aligned_depth = Common::AlignUp(depth, gob_size_z * block_depth);
362 const u32 size = aligned_width * aligned_height * aligned_depth; 362 return aligned_width * aligned_height * aligned_depth;
363 return size;
364 } else { 363 } else {
365 return width * height * depth * bytes_per_pixel; 364 return width * height * depth * bytes_per_pixel;
366 } 365 }