GPUTexture: Add GPU_texture_create_single_layer_view

This allows the creation of texture arrays from 1D/2D/Cube texture.
This is useful when the shader expect a texture array but the original
texture isn't.
This commit is contained in:
Clément Foucault
2022-10-02 15:18:35 +02:00
parent 208b3a0472
commit 5a982b0695
3 changed files with 31 additions and 4 deletions

View File

@@ -257,6 +257,13 @@ GPUTexture *GPU_texture_create_view(const char *name,
int layer_len,
bool cube_as_array);
/**
* Create an alias of the source texture as a texture array with only one layer.
* Works for 1D, 2D and cube-map source texture.
* If \a src is freed, the texture view will continue to be valid.
*/
GPUTexture *GPU_texture_create_single_layer_array_view(const char *name, const GPUTexture *src);
void GPU_texture_update_mipmap(GPUTexture *tex,
int miplvl,
eGPUDataFormat gpu_data_format,

View File

@@ -132,6 +132,7 @@ bool Texture::init_buffer(GPUVertBuf *vbo, eGPUTextureFormat format)
bool Texture::init_view(const GPUTexture *src_,
eGPUTextureFormat format,
eGPUTextureType type,
int mip_start,
int mip_len,
int layer_start,
@@ -144,7 +145,7 @@ bool Texture::init_view(const GPUTexture *src_,
d_ = src->d_;
layer_start = min_ii(layer_start, src->layer_count() - 1);
layer_len = min_ii(layer_len, (src->layer_count() - layer_start));
switch (src->type_) {
switch (type) {
case GPU_TEXTURE_1D_ARRAY:
h_ = layer_len;
break;
@@ -163,8 +164,7 @@ bool Texture::init_view(const GPUTexture *src_,
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_;
type_ = type;
if (cube_as_array) {
BLI_assert(type_ & GPU_TEXTURE_CUBE);
type_ = (type_ & ~GPU_TEXTURE_CUBE) | GPU_TEXTURE_2D_ARRAY;
@@ -404,7 +404,26 @@ GPUTexture *GPU_texture_create_view(const char *name,
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, cube_as_array);
view->init_view(src,
format,
unwrap(src)->type_get(),
mip_start,
mip_len,
layer_start,
layer_len,
cube_as_array);
return wrap(view);
}
GPUTexture *GPU_texture_create_single_layer_view(const char *name, const GPUTexture *src)
{
eGPUTextureFormat format = unwrap(src)->format_get();
eGPUTextureType type = unwrap(src)->type_get();
BLI_assert(ELEM(type, GPU_TEXTURE_1D, GPU_TEXTURE_2D, GPU_TEXTURE_CUBE));
type |= GPU_TEXTURE_ARRAY;
Texture *view = GPUBackend::get()->texture_alloc(name);
view->init_view(src, format, type, 0, 9999, 0, 1, false);
return wrap(view);
}

View File

@@ -108,6 +108,7 @@ class Texture {
bool init_buffer(GPUVertBuf *vbo, eGPUTextureFormat format);
bool init_view(const GPUTexture *src,
eGPUTextureFormat format,
eGPUTextureType type,
int mip_start,
int mip_len,
int layer_start,