diff options
| author | 2019-04-14 01:44:16 -0300 | |
|---|---|---|
| committer | 2019-06-20 21:36:11 -0300 | |
| commit | fb94871791f78703737125cd2e5a13db8b7d1059 (patch) | |
| tree | 774dc3eab1bea643568582fd96ea4d96c4bd824b | |
| parent | gl_texture_cache: Initial implementation (diff) | |
| download | yuzu-fb94871791f78703737125cd2e5a13db8b7d1059.tar.gz yuzu-fb94871791f78703737125cd2e5a13db8b7d1059.tar.xz yuzu-fb94871791f78703737125cd2e5a13db8b7d1059.zip | |
gl_texture_cache: Add fast copy path
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.cpp | 51 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.h | 9 | ||||
| -rw-r--r-- | src/video_core/texture_cache.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/textures/decoders.cpp | 3 |
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 | ||
| 180 | OGLTexture CreateTexture(const SurfaceParams& params, GLenum internal_format) { | 180 | OGLTexture 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; | |||
| 504 | CachedSurfaceView* TextureCacheOpenGL::TryFastGetSurfaceView( | 505 | CachedSurfaceView* 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 | ||
| 526 | CachedSurfaceView* 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 | |||
| 510 | std::unique_ptr<CachedSurface> TextureCacheOpenGL::CreateSurface(const SurfaceParams& params) { | 555 | std::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 | |||
| 135 | private: | ||
| 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 | } |