summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2019-04-14 06:44:16 +0200
committerReinUsesLisp <reinuseslisp@airmail.cc>2019-06-21 02:36:11 +0200
commitfb94871791f78703737125cd2e5a13db8b7d1059 (patch)
tree774dc3eab1bea643568582fd96ea4d96c4bd824b /src/video_core/renderer_opengl
parentgl_texture_cache: Initial implementation (diff)
downloadyuzu-fb94871791f78703737125cd2e5a13db8b7d1059.tar
yuzu-fb94871791f78703737125cd2e5a13db8b7d1059.tar.gz
yuzu-fb94871791f78703737125cd2e5a13db8b7d1059.tar.bz2
yuzu-fb94871791f78703737125cd2e5a13db8b7d1059.tar.lz
yuzu-fb94871791f78703737125cd2e5a13db8b7d1059.tar.xz
yuzu-fb94871791f78703737125cd2e5a13db8b7d1059.tar.zst
yuzu-fb94871791f78703737125cd2e5a13db8b7d1059.zip
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp51
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.h9
2 files changed, 57 insertions, 3 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) {
}
}
-OGLTexture CreateTexture(const SurfaceParams& params, GLenum internal_format) {
+OGLTexture CreateTexture(const SurfaceParams& params, GLenum target, GLenum internal_format) {
OGLTexture texture;
- texture.Create(GetTextureTarget(params));
+ texture.Create(target);
switch (params.GetTarget()) {
case SurfaceTarget::Texture1D:
@@ -241,7 +241,8 @@ CachedSurface::CachedSurface(const SurfaceParams& params)
format = tuple.format;
type = tuple.type;
is_compressed = tuple.compressed;
- texture = CreateTexture(params, internal_format);
+ target = GetTextureTarget(params);
+ texture = CreateTexture(params, target, internal_format);
staging_buffer.resize(params.GetHostSizeInBytes());
}
@@ -504,9 +505,53 @@ TextureCacheOpenGL::~TextureCacheOpenGL() = default;
CachedSurfaceView* TextureCacheOpenGL::TryFastGetSurfaceView(
VAddr cpu_addr, u8* host_ptr, const SurfaceParams& params, bool preserve_contents,
const std::vector<CachedSurface*>& overlaps) {
+ if (overlaps.size() > 1) {
+ return nullptr;
+ }
+
+ const auto& old_surface{overlaps[0]};
+ const auto& old_params{old_surface->GetSurfaceParams()};
+ const auto& new_params{params};
+
+ if (old_params.GetTarget() == new_params.GetTarget() &&
+ old_params.GetDepth() == new_params.GetDepth() && old_params.GetDepth() == 1 &&
+ old_params.GetNumLevels() == new_params.GetNumLevels() &&
+ old_params.GetPixelFormat() == new_params.GetPixelFormat()) {
+ return SurfaceCopy(cpu_addr, host_ptr, new_params, old_surface, old_params);
+ }
+
return nullptr;
}
+CachedSurfaceView* TextureCacheOpenGL::SurfaceCopy(VAddr cpu_addr, u8* host_ptr,
+ const SurfaceParams& new_params,
+ CachedSurface* old_surface,
+ const SurfaceParams& old_params) {
+ CachedSurface* const new_surface{GetUncachedSurface(new_params)};
+ Register(new_surface, cpu_addr, host_ptr);
+
+ const u32 min_width{
+ std::max(old_params.GetDefaultBlockWidth(), new_params.GetDefaultBlockWidth())};
+ const u32 min_height{
+ std::max(old_params.GetDefaultBlockHeight(), new_params.GetDefaultBlockHeight())};
+ for (u32 level = 0; level < old_params.GetNumLevels(); ++level) {
+ const u32 width{std::min(old_params.GetMipWidth(level), new_params.GetMipWidth(level))};
+ const u32 height{std::min(old_params.GetMipHeight(level), new_params.GetMipHeight(level))};
+ if (width < min_width || height < min_height) {
+ // Avoid copies that are too small to be handled in OpenGL
+ break;
+ }
+ glCopyImageSubData(old_surface->GetTexture(), old_surface->GetTarget(), level, 0, 0, 0,
+ new_surface->GetTexture(), new_surface->GetTarget(), level, 0, 0, 0,
+ width, height, 1);
+ }
+
+ new_surface->MarkAsModified(true);
+
+ // TODO(Rodrigo): Add an entry to directly get the superview
+ return new_surface->GetView(cpu_addr, new_params);
+}
+
std::unique_ptr<CachedSurface> TextureCacheOpenGL::CreateSurface(const SurfaceParams& params) {
return std::make_unique<CachedSurface>(params);
}
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:
void LoadBuffer();
+ GLenum GetTarget() const {
+ return target;
+ }
+
GLuint GetTexture() const {
return texture.handle;
}
@@ -56,6 +60,7 @@ private:
GLenum format{};
GLenum type{};
bool is_compressed{};
+ GLenum target{};
OGLTexture texture;
@@ -126,6 +131,10 @@ protected:
const std::vector<CachedSurface*>& overlaps);
std::unique_ptr<CachedSurface> CreateSurface(const SurfaceParams& params);
+
+private:
+ CachedSurfaceView* SurfaceCopy(VAddr cpu_addr, u8* host_ptr, const SurfaceParams& new_params,
+ CachedSurface* old_surface, const SurfaceParams& old_params);
};
} // namespace OpenGL