Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2022-02-25 00:45:00 +0300
committerClément Foucault <foucault.clem@gmail.com>2022-02-25 00:51:19 +0300
commit7d7dd66ba78fc97795edeb7c1a0221e4bb676c85 (patch)
tree06622b61fe95999935aefda6bd7b9fbe745dbbfc /source
parente59f754c169d855110296a365d93c33e82333385 (diff)
GPUTexture: Add support for texture view
This is an OpenGL 4.3 feature that enables creating a texture using a range of the same data as another texture.
Diffstat (limited to 'source')
-rw-r--r--source/blender/gpu/GPU_texture.h13
-rw-r--r--source/blender/gpu/intern/gpu_texture.cc51
-rw-r--r--source/blender/gpu/intern/gpu_texture_private.hh7
-rw-r--r--source/blender/gpu/opengl/gl_texture.cc22
-rw-r--r--source/blender/gpu/opengl/gl_texture.hh2
5 files changed, 95 insertions, 0 deletions
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index d689fbe14b5..734d407d011 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -226,6 +226,19 @@ GPUTexture *GPU_texture_create_compressed_2d(
* Create an error texture that will bind an invalid texture (pink) at draw time.
*/
GPUTexture *GPU_texture_create_error(int dimension, bool array);
+/**
+ * Create an alias of the source texture data.
+ * If \a src is freed, the texture view will continue to be valid.
+ * If \a mip_start or \a mip_len is bigger than available mips they will be clamped.
+ * TODO(@fclem): Target conversion is not implemented yet.
+ */
+GPUTexture *GPU_texture_create_view(const char *name,
+ const GPUTexture *src,
+ eGPUTextureFormat format,
+ int mip_start,
+ int mip_len,
+ int layer_start,
+ int layer_len);
void GPU_texture_update_mipmap(GPUTexture *tex,
int miplvl,
diff --git a/source/blender/gpu/intern/gpu_texture.cc b/source/blender/gpu/intern/gpu_texture.cc
index 507ad47e36a..9e6a6f75391 100644
--- a/source/blender/gpu/intern/gpu_texture.cc
+++ b/source/blender/gpu/intern/gpu_texture.cc
@@ -131,6 +131,42 @@ bool Texture::init_buffer(GPUVertBuf *vbo, eGPUTextureFormat format)
return this->init_internal(vbo);
}
+bool Texture::init_view(const GPUTexture *src_,
+ eGPUTextureFormat format,
+ int mip_start,
+ int mip_len,
+ int layer_start,
+ int layer_len)
+{
+ const Texture *src = unwrap(src_);
+ w_ = src->w_;
+ h_ = src->h_;
+ d_ = src->d_;
+ switch (type_) {
+ case GPU_TEXTURE_1D_ARRAY:
+ h_ = layer_len;
+ break;
+ case GPU_TEXTURE_CUBE_ARRAY:
+ BLI_assert(layer_len % 6 == 0);
+ ATTR_FALLTHROUGH;
+ case GPU_TEXTURE_2D_ARRAY:
+ d_ = layer_len;
+ break;
+ default:
+ BLI_assert(layer_len == 1 && layer_start == 0);
+ break;
+ }
+ mip_start = min_ii(mip_start, src->mipmaps_ - 1);
+ mip_len = min_ii(mip_len, (src->mipmaps_ - mip_start));
+ mipmaps_ = mip_len;
+ format_ = format;
+ format_flag_ = to_format_flag(format);
+ /* For now always copy the target. Target aliasing could be exposed later. */
+ type_ = src->type_;
+ sampler_state = src->sampler_state;
+ return this->init_internal(src_, mip_start, layer_start);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -343,6 +379,21 @@ GPUTexture *GPU_texture_create_error(int dimension, bool is_array)
return gpu_texture_create("invalid_tex", w, h, d, type, 1, GPU_RGBA8, GPU_DATA_FLOAT, pixel);
}
+GPUTexture *GPU_texture_create_view(const char *name,
+ const GPUTexture *src,
+ eGPUTextureFormat format,
+ int mip_start,
+ int mip_len,
+ int layer_start,
+ int layer_len)
+{
+ BLI_assert(mip_len > 0);
+ BLI_assert(layer_len > 0);
+ Texture *view = GPUBackend::get()->texture_alloc(name);
+ view->init_view(src, format, mip_start, mip_len, layer_start, layer_len);
+ return wrap(view);
+}
+
/* ------ Update ------ */
void GPU_texture_update_mipmap(GPUTexture *tex_,
diff --git a/source/blender/gpu/intern/gpu_texture_private.hh b/source/blender/gpu/intern/gpu_texture_private.hh
index b019235e463..ec11fab421c 100644
--- a/source/blender/gpu/intern/gpu_texture_private.hh
+++ b/source/blender/gpu/intern/gpu_texture_private.hh
@@ -106,6 +106,12 @@ class Texture {
bool init_3D(int w, int h, int d, int mips, eGPUTextureFormat format);
bool init_cubemap(int w, int layers, int mips, eGPUTextureFormat format);
bool init_buffer(GPUVertBuf *vbo, eGPUTextureFormat format);
+ bool init_view(const GPUTexture *src,
+ eGPUTextureFormat format,
+ int mip_start,
+ int mip_len,
+ int layer_start,
+ int layer_len);
virtual void generate_mipmap() = 0;
virtual void copy_to(Texture *tex) = 0;
@@ -234,6 +240,7 @@ class Texture {
protected:
virtual bool init_internal() = 0;
virtual bool init_internal(GPUVertBuf *vbo) = 0;
+ virtual bool init_internal(const GPUTexture *src, int mip_offset, int layer_offset) = 0;
};
/* Syntactic sugar. */
diff --git a/source/blender/gpu/opengl/gl_texture.cc b/source/blender/gpu/opengl/gl_texture.cc
index 37bf2f6b8b3..0a5c7f8e79e 100644
--- a/source/blender/gpu/opengl/gl_texture.cc
+++ b/source/blender/gpu/opengl/gl_texture.cc
@@ -175,6 +175,28 @@ bool GLTexture::init_internal(GPUVertBuf *vbo)
return true;
}
+bool GLTexture::init_internal(const GPUTexture *src, int mip_offset, int layer_offset)
+{
+ BLI_assert(GLContext::texture_storage_support);
+
+ const GLTexture *gl_src = static_cast<const GLTexture *>(unwrap(src));
+ GLenum internal_format = to_gl_internal_format(format_);
+ target_ = to_gl_target(type_);
+
+ glTextureView(tex_id_,
+ target_,
+ gl_src->tex_id_,
+ internal_format,
+ mip_offset,
+ mipmaps_,
+ layer_offset,
+ this->layer_count());
+
+ debug::object_label(GL_TEXTURE, tex_id_, name_);
+
+ return true;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/gpu/opengl/gl_texture.hh b/source/blender/gpu/opengl/gl_texture.hh
index 9e128da90e8..d4d024f5e3e 100644
--- a/source/blender/gpu/opengl/gl_texture.hh
+++ b/source/blender/gpu/opengl/gl_texture.hh
@@ -74,6 +74,8 @@ class GLTexture : public Texture {
bool init_internal() override;
/** Return true on success. */
bool init_internal(GPUVertBuf *vbo) override;
+ /** Return true on success. */
+ bool init_internal(const GPUTexture *src, int mip_offset, int layer_offset) override;
private:
bool proxy_check(int mip);