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
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/gpu')
-rw-r--r--source/blender/gpu/CMakeLists.txt26
-rw-r--r--source/blender/gpu/GPU_batch.h1
-rw-r--r--source/blender/gpu/GPU_texture.h13
-rw-r--r--source/blender/gpu/intern/gpu_batch.cc10
-rw-r--r--source/blender/gpu/intern/gpu_node_graph.c2
-rw-r--r--source/blender/gpu/intern/gpu_shader_create_info.hh8
-rw-r--r--source/blender/gpu/intern/gpu_shader_dependency.cc6
-rw-r--r--source/blender/gpu/intern/gpu_shader_dependency_private.h2
-rw-r--r--source/blender/gpu/intern/gpu_texture.cc80
-rw-r--r--source/blender/gpu/intern/gpu_texture_private.hh15
-rw-r--r--source/blender/gpu/intern/gpu_viewport.c4
-rw-r--r--source/blender/gpu/opengl/gl_backend.cc3
-rw-r--r--source/blender/gpu/opengl/gl_context.hh1
-rw-r--r--source/blender/gpu/opengl/gl_immediate.cc2
-rw-r--r--source/blender/gpu/opengl/gl_texture.cc150
-rw-r--r--source/blender/gpu/opengl/gl_texture.hh4
-rw-r--r--source/blender/gpu/opengl/gl_vertex_array.cc2
-rw-r--r--source/blender/gpu/shaders/infos/gpu_shader_2D_image_overlays_merge_info.hh1
18 files changed, 235 insertions, 95 deletions
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index e883a12a5b2..3ad43ef05af 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -147,6 +147,7 @@ set(SRC
intern/gpu_select_private.h
intern/gpu_shader_create_info.hh
intern/gpu_shader_create_info_private.hh
+ intern/gpu_shader_dependency_private.h
intern/gpu_shader_interface.hh
intern/gpu_shader_private.hh
intern/gpu_state_private.hh
@@ -384,7 +385,7 @@ file(GENERATE OUTPUT ${glsl_source_list_file} CONTENT "${GLSL_SOURCE_CONTENT}")
list(APPEND SRC ${glsl_source_list_file})
list(APPEND INC ${CMAKE_CURRENT_BINARY_DIR})
-set(SHADER_CREATE_INFOS
+set(SRC_SHADER_CREATE_INFOS
../draw/engines/workbench/shaders/infos/workbench_composite_info.hh
../draw/engines/workbench/shaders/infos/workbench_effect_antialiasing_info.hh
../draw/engines/workbench/shaders/infos/workbench_effect_cavity_info.hh
@@ -435,7 +436,7 @@ set(SHADER_CREATE_INFOS
)
set(SHADER_CREATE_INFOS_CONTENT "")
-foreach(DESCRIPTOR_FILE ${SHADER_CREATE_INFOS})
+foreach(DESCRIPTOR_FILE ${SRC_SHADER_CREATE_INFOS})
string(APPEND SHADER_CREATE_INFOS_CONTENT "#include \"${DESCRIPTOR_FILE}\"\n")
endforeach()
@@ -452,12 +453,21 @@ if(WITH_IMAGE_DDS)
add_definitions(-DWITH_DDS)
endif()
+if(WITH_OPENCOLORIO)
+ add_definitions(-DWITH_OCIO)
+endif()
+
blender_add_lib(bf_gpu "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
target_link_libraries(bf_gpu PUBLIC
bf_draw_shaders
bf_gpu_shaders
)
+if(WITH_OPENCOLORIO)
+ target_link_libraries(bf_gpu PUBLIC bf_ocio_shaders)
+endif()
+
+
if(CXX_WARN_NO_SUGGEST_OVERRIDE)
target_compile_options(bf_gpu PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-Wsuggest-override>)
endif()
@@ -477,18 +487,22 @@ if(WITH_GPU_SHADER_BUILDER)
)
target_include_directories(shader_builder PRIVATE ${INC} ${CMAKE_CURRENT_BINARY_DIR})
- set(BAKED_CREATE_INFOS_FILE ${CMAKE_CURRENT_BINARY_DIR}/shader_baked.hh)
+ set(SRC_BAKED_CREATE_INFOS_FILE ${CMAKE_CURRENT_BINARY_DIR}/shader_baked.hh)
add_custom_command(
OUTPUT
- ${BAKED_CREATE_INFOS_FILE}
+ ${SRC_BAKED_CREATE_INFOS_FILE}
COMMAND
- "$<TARGET_FILE:shader_builder>" ${BAKED_CREATE_INFOS_FILE}
+ "$<TARGET_FILE:shader_builder>" ${SRC_BAKED_CREATE_INFOS_FILE}
DEPENDS shader_builder
)
set(GPU_SHADER_INFO_SRC
intern/gpu_shader_info_baked.cc
- ${BAKED_CREATE_INFOS_FILE}
+ ${SRC_BAKED_CREATE_INFOS_FILE}
+
+ # For project files to be aware of these headers.
+ ${SRC_SHADER_CREATE_INFOS}
+ shaders/infos/gpu_interface_info.hh
)
blender_add_lib(bf_gpu_shader_infos "${GPU_SHADER_INFO_SRC}" "" "" "")
diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h
index 803a5825c94..7fad8dd23be 100644
--- a/source/blender/gpu/GPU_batch.h
+++ b/source/blender/gpu/GPU_batch.h
@@ -119,6 +119,7 @@ int GPU_batch_instbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo);
* Returns the index of verts in the batch.
*/
int GPU_batch_vertbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo);
+bool GPU_batch_vertbuf_has(GPUBatch *, GPUVertBuf *);
#define GPU_batch_vertbuf_add(batch, verts) GPU_batch_vertbuf_add_ex(batch, verts, false)
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_batch.cc b/source/blender/gpu/intern/gpu_batch.cc
index 44e95b1f5f5..32b117dac12 100644
--- a/source/blender/gpu/intern/gpu_batch.cc
+++ b/source/blender/gpu/intern/gpu_batch.cc
@@ -191,6 +191,16 @@ int GPU_batch_vertbuf_add_ex(GPUBatch *batch, GPUVertBuf *verts, bool own_vbo)
return -1;
}
+bool GPU_batch_vertbuf_has(GPUBatch *batch, GPUVertBuf *verts)
+{
+ for (uint v = 0; v < GPU_BATCH_VBO_MAX_LEN; v++) {
+ if (batch->verts[v] == verts) {
+ return true;
+ }
+ }
+ return false;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c
index da4e49f0257..57e415a8183 100644
--- a/source/blender/gpu/intern/gpu_node_graph.c
+++ b/source/blender/gpu/intern/gpu_node_graph.c
@@ -165,7 +165,7 @@ static const char *gpu_uniform_set_function_from_type(eNodeSocketDatatype type)
/**
* Link stack uniform buffer.
- * This is called for the input/output sockets that are note connected.
+ * This is called for the input/output sockets that are not connected.
*/
static GPUNodeLink *gpu_uniformbuffer_link(GPUMaterial *mat,
bNode *node,
diff --git a/source/blender/gpu/intern/gpu_shader_create_info.hh b/source/blender/gpu/intern/gpu_shader_create_info.hh
index bd0187e2dc5..bf74d44d9a7 100644
--- a/source/blender/gpu/intern/gpu_shader_create_info.hh
+++ b/source/blender/gpu/intern/gpu_shader_create_info.hh
@@ -255,7 +255,7 @@ struct StageInterfaceInfo {
};
/**
- * @brief Describe inputs & outputs, stage interfaces, resources and sources of a shader.
+ * \brief Describe inputs & outputs, stage interfaces, resources and sources of a shader.
* If all data is correctly provided, this is all that is needed to create and compile
* a GPUShader.
*
@@ -497,9 +497,9 @@ struct ShaderCreateInfo {
/**
* IMPORTANT: invocations count is only used if GL_ARB_gpu_shader5 is supported. On
- * implementations that do not supports it, the max_vertices will be be multiplied by
- * invocations. Your shader needs to account for this fact. Use `#ifdef GPU_ARB_gpu_shader5`
- * and make a code path that does not rely on gl_InvocationID.
+ * implementations that do not supports it, the max_vertices will be multiplied by invocations.
+ * Your shader needs to account for this fact. Use `#ifdef GPU_ARB_gpu_shader5` and make a code
+ * path that does not rely on #gl_InvocationID.
*/
Self &geometry_layout(PrimitiveIn prim_in,
PrimitiveOut prim_out,
diff --git a/source/blender/gpu/intern/gpu_shader_dependency.cc b/source/blender/gpu/intern/gpu_shader_dependency.cc
index 8a842ef4d7c..5b7df035acd 100644
--- a/source/blender/gpu/intern/gpu_shader_dependency.cc
+++ b/source/blender/gpu/intern/gpu_shader_dependency.cc
@@ -21,6 +21,9 @@ extern "C" {
#define SHADER_SOURCE(datatoc, filename, filepath) extern char datatoc[];
#include "glsl_draw_source_list.h"
#include "glsl_gpu_source_list.h"
+#ifdef WITH_OCIO
+# include "glsl_ocio_source_list.h"
+#endif
#undef SHADER_SOURCE
}
@@ -348,6 +351,9 @@ void gpu_shader_dependency_init()
g_sources->add_new(filename, new GPUSource(filepath, filename, datatoc));
#include "glsl_draw_source_list.h"
#include "glsl_gpu_source_list.h"
+#ifdef WITH_OCIO
+# include "glsl_ocio_source_list.h"
+#endif
#undef SHADER_SOURCE
int errors = 0;
diff --git a/source/blender/gpu/intern/gpu_shader_dependency_private.h b/source/blender/gpu/intern/gpu_shader_dependency_private.h
index 29ee70962d1..7b9ecef5835 100644
--- a/source/blender/gpu/intern/gpu_shader_dependency_private.h
+++ b/source/blender/gpu/intern/gpu_shader_dependency_private.h
@@ -38,7 +38,7 @@ StringRefNull gpu_shader_dependency_get_source(const StringRefNull source_name);
/**
* \brief Find the name of the file from which the given string was generated.
- * \return Return filename or empty string.
+ * \return filename or empty string.
* \note source_string needs to be identical to the one given by gpu_shader_dependency_get_source()
*/
StringRefNull gpu_shader_dependency_get_filename_from_source_string(
diff --git a/source/blender/gpu/intern/gpu_texture.cc b/source/blender/gpu/intern/gpu_texture.cc
index da5f08f003e..9e6a6f75391 100644
--- a/source/blender/gpu/intern/gpu_texture.cc
+++ b/source/blender/gpu/intern/gpu_texture.cc
@@ -52,11 +52,13 @@ Texture::~Texture()
#endif
}
-bool Texture::init_1D(int w, int layers, eGPUTextureFormat format)
+bool Texture::init_1D(int w, int layers, int mips, eGPUTextureFormat format)
{
w_ = w;
h_ = layers;
d_ = 0;
+ int mips_max = 1 + floorf(log2f(w));
+ mipmaps_ = min_ii(mips, mips_max);
format_ = format;
format_flag_ = to_format_flag(format);
type_ = (layers > 0) ? GPU_TEXTURE_1D_ARRAY : GPU_TEXTURE_1D;
@@ -66,11 +68,13 @@ bool Texture::init_1D(int w, int layers, eGPUTextureFormat format)
return this->init_internal();
}
-bool Texture::init_2D(int w, int h, int layers, eGPUTextureFormat format)
+bool Texture::init_2D(int w, int h, int layers, int mips, eGPUTextureFormat format)
{
w_ = w;
h_ = h;
d_ = layers;
+ int mips_max = 1 + floorf(log2f(max_ii(w, h)));
+ mipmaps_ = min_ii(mips, mips_max);
format_ = format;
format_flag_ = to_format_flag(format);
type_ = (layers > 0) ? GPU_TEXTURE_2D_ARRAY : GPU_TEXTURE_2D;
@@ -80,11 +84,13 @@ bool Texture::init_2D(int w, int h, int layers, eGPUTextureFormat format)
return this->init_internal();
}
-bool Texture::init_3D(int w, int h, int d, eGPUTextureFormat format)
+bool Texture::init_3D(int w, int h, int d, int mips, eGPUTextureFormat format)
{
w_ = w;
h_ = h;
d_ = d;
+ int mips_max = 1 + floorf(log2f(max_iii(w, h, d)));
+ mipmaps_ = min_ii(mips, mips_max);
format_ = format;
format_flag_ = to_format_flag(format);
type_ = GPU_TEXTURE_3D;
@@ -94,11 +100,13 @@ bool Texture::init_3D(int w, int h, int d, eGPUTextureFormat format)
return this->init_internal();
}
-bool Texture::init_cubemap(int w, int layers, eGPUTextureFormat format)
+bool Texture::init_cubemap(int w, int layers, int mips, eGPUTextureFormat format)
{
w_ = w;
h_ = w;
d_ = max_ii(1, layers) * 6;
+ int mips_max = 1 + floorf(log2f(w));
+ mipmaps_ = min_ii(mips, mips_max);
format_ = format;
format_flag_ = to_format_flag(format);
type_ = (layers > 0) ? GPU_TEXTURE_CUBE_ARRAY : GPU_TEXTURE_CUBE;
@@ -123,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);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -187,28 +231,29 @@ static inline GPUTexture *gpu_texture_create(const char *name,
const int h,
const int d,
const eGPUTextureType type,
- int UNUSED(mips),
+ int mips,
eGPUTextureFormat tex_format,
eGPUDataFormat data_format,
const void *pixels)
{
+ BLI_assert(mips > 0);
Texture *tex = GPUBackend::get()->texture_alloc(name);
bool success = false;
switch (type) {
case GPU_TEXTURE_1D:
case GPU_TEXTURE_1D_ARRAY:
- success = tex->init_1D(w, h, tex_format);
+ success = tex->init_1D(w, h, mips, tex_format);
break;
case GPU_TEXTURE_2D:
case GPU_TEXTURE_2D_ARRAY:
- success = tex->init_2D(w, h, d, tex_format);
+ success = tex->init_2D(w, h, d, mips, tex_format);
break;
case GPU_TEXTURE_3D:
- success = tex->init_3D(w, h, d, tex_format);
+ success = tex->init_3D(w, h, d, mips, tex_format);
break;
case GPU_TEXTURE_CUBE:
case GPU_TEXTURE_CUBE_ARRAY:
- success = tex->init_cubemap(w, d, tex_format);
+ success = tex->init_cubemap(w, d, mips, tex_format);
break;
default:
break;
@@ -286,7 +331,7 @@ GPUTexture *GPU_texture_create_compressed_2d(
const char *name, int w, int h, int miplen, eGPUTextureFormat tex_format, const void *data)
{
Texture *tex = GPUBackend::get()->texture_alloc(name);
- bool success = tex->init_2D(w, h, 0, tex_format);
+ bool success = tex->init_2D(w, h, 0, miplen, tex_format);
if (!success) {
delete tex;
@@ -334,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 2c57c467bcf..ec11fab421c 100644
--- a/source/blender/gpu/intern/gpu_texture_private.hh
+++ b/source/blender/gpu/intern/gpu_texture_private.hh
@@ -101,11 +101,17 @@ class Texture {
virtual ~Texture();
/* Return true on success. */
- bool init_1D(int w, int layers, eGPUTextureFormat format);
- bool init_2D(int w, int h, int layers, eGPUTextureFormat format);
- bool init_3D(int w, int h, int d, eGPUTextureFormat format);
- bool init_cubemap(int w, int layers, eGPUTextureFormat format);
+ bool init_1D(int w, int layers, int mips, eGPUTextureFormat format);
+ bool init_2D(int w, int h, int layers, int mips, eGPUTextureFormat format);
+ 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/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
index fd4a87bc544..b5a572bccbe 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -277,8 +277,6 @@ void GPU_viewport_stereo_composite(GPUViewport *viewport, Stereo3dFormat *stereo
GPU_matrix_identity_set();
GPU_matrix_identity_projection_set();
immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_OVERLAYS_STEREO_MERGE);
- immUniform1i("overlayTexture", 0);
- immUniform1i("imageTexture", 1);
int settings = stereo_format->display_mode;
if (settings == S3D_DISPLAY_ANAGLYPH) {
switch (stereo_format->anaglyph_type) {
@@ -432,8 +430,6 @@ static void gpu_viewport_draw_colormanaged(GPUViewport *viewport,
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE);
GPU_batch_uniform_1i(batch, "overlay", do_overlay_merge);
GPU_batch_uniform_1i(batch, "display_transform", display_colorspace);
- GPU_batch_uniform_1i(batch, "image_texture", 0);
- GPU_batch_uniform_1i(batch, "overlays_texture", 1);
}
GPU_texture_bind(color, 0);
diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc
index 7a1674a5f01..302d8249914 100644
--- a/source/blender/gpu/opengl/gl_backend.cc
+++ b/source/blender/gpu/opengl/gl_backend.cc
@@ -240,6 +240,7 @@ static void detect_workarounds()
GLContext::texture_cube_map_array_support = false;
GLContext::texture_filter_anisotropic_support = false;
GLContext::texture_gather_support = false;
+ GLContext::texture_storage_support = false;
GLContext::vertex_attrib_binding_support = false;
return;
}
@@ -439,6 +440,7 @@ bool GLContext::shader_draw_parameters_support = false;
bool GLContext::texture_cube_map_array_support = false;
bool GLContext::texture_filter_anisotropic_support = false;
bool GLContext::texture_gather_support = false;
+bool GLContext::texture_storage_support = false;
bool GLContext::vertex_attrib_binding_support = false;
/** Workarounds. */
@@ -501,6 +503,7 @@ void GLBackend::capabilities_init()
GLContext::texture_cube_map_array_support = GLEW_ARB_texture_cube_map_array;
GLContext::texture_filter_anisotropic_support = GLEW_EXT_texture_filter_anisotropic;
GLContext::texture_gather_support = GLEW_ARB_texture_gather;
+ GLContext::texture_storage_support = GLEW_VERSION_4_3;
GLContext::vertex_attrib_binding_support = GLEW_ARB_vertex_attrib_binding;
detect_workarounds();
diff --git a/source/blender/gpu/opengl/gl_context.hh b/source/blender/gpu/opengl/gl_context.hh
index fe2ad0a4747..369b667cbcc 100644
--- a/source/blender/gpu/opengl/gl_context.hh
+++ b/source/blender/gpu/opengl/gl_context.hh
@@ -64,6 +64,7 @@ class GLContext : public Context {
static bool texture_cube_map_array_support;
static bool texture_filter_anisotropic_support;
static bool texture_gather_support;
+ static bool texture_storage_support;
static bool vertex_attrib_binding_support;
/** Workarounds. */
diff --git a/source/blender/gpu/opengl/gl_immediate.cc b/source/blender/gpu/opengl/gl_immediate.cc
index cfedfe348f1..c32a6afd8cf 100644
--- a/source/blender/gpu/opengl/gl_immediate.cc
+++ b/source/blender/gpu/opengl/gl_immediate.cc
@@ -139,7 +139,7 @@ void GLImmediate::end()
GLContext::get()->state_manager->apply_state();
/* We convert the offset in vertex offset from the buffer's start.
- * This works because we added some padding to align the first vertex vertex. */
+ * This works because we added some padding to align the first vertex. */
uint v_first = buffer_offset() / vertex_format.stride;
GLVertArray::update_bindings(
vao_id_, v_first, &vertex_format, reinterpret_cast<Shader *>(shader)->interface);
diff --git a/source/blender/gpu/opengl/gl_texture.cc b/source/blender/gpu/opengl/gl_texture.cc
index 22af2dd463f..0a5c7f8e79e 100644
--- a/source/blender/gpu/opengl/gl_texture.cc
+++ b/source/blender/gpu/opengl/gl_texture.cc
@@ -69,9 +69,79 @@ bool GLTexture::init_internal()
return false;
}
- this->ensure_mipmaps(0);
+ GLenum internal_format = to_gl_internal_format(format_);
+ const bool is_cubemap = bool(type_ == GPU_TEXTURE_CUBE);
+ const bool is_layered = bool(type_ & GPU_TEXTURE_ARRAY);
+ const bool is_compressed = bool(format_flag_ & GPU_TEXTURE_ARRAY);
+ const int dimensions = (is_cubemap) ? 2 : this->dimensions_count();
+ GLenum gl_format = to_gl_data_format(format_);
+ GLenum gl_type = to_gl(to_data_format(format_));
+
+ auto mip_size = [&](int h, int w = 1, int d = 1) -> size_t {
+ return divide_ceil_u(w, 4) * divide_ceil_u(h, 4) * divide_ceil_u(d, 4) *
+ to_block_size(format_);
+ };
+ switch (dimensions) {
+ default:
+ case 1:
+ if (GLContext::texture_storage_support) {
+ glTexStorage1D(target_, mipmaps_, internal_format, w_);
+ }
+ else {
+ for (int i = 0, w = w_; i < mipmaps_; i++) {
+ if (is_compressed) {
+ glCompressedTexImage1D(target_, i, internal_format, w, 0, mip_size(w), nullptr);
+ }
+ else {
+ glTexImage1D(target_, i, internal_format, w, 0, gl_format, gl_type, nullptr);
+ }
+ w = max_ii(1, (w / 2));
+ }
+ }
+ break;
+ case 2:
+ if (GLContext::texture_storage_support) {
+ glTexStorage2D(target_, mipmaps_, internal_format, w_, h_);
+ }
+ else {
+ for (int i = 0, w = w_, h = h_; i < mipmaps_; i++) {
+ for (int f = 0; f < (is_cubemap ? 6 : 1); f++) {
+ GLenum target = (is_cubemap) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X + f : target_;
+ if (is_compressed) {
+ glCompressedTexImage2D(target, i, internal_format, w, h, 0, mip_size(w, h), nullptr);
+ }
+ else {
+ glTexImage2D(target, i, internal_format, w, h, 0, gl_format, gl_type, nullptr);
+ }
+ }
+ w = max_ii(1, (w / 2));
+ h = is_layered ? h_ : max_ii(1, (h / 2));
+ }
+ }
+ break;
+ case 3:
+ if (GLContext::texture_storage_support) {
+ glTexStorage3D(target_, mipmaps_, internal_format, w_, h_, d_);
+ }
+ else {
+ for (int i = 0, w = w_, h = h_, d = d_; i < mipmaps_; i++) {
+ if (is_compressed) {
+ glCompressedTexImage3D(
+ target_, i, internal_format, w, h, d, 0, mip_size(w, h, d), nullptr);
+ }
+ else {
+ glTexImage3D(target_, i, internal_format, w, h, d, 0, gl_format, gl_type, nullptr);
+ }
+ w = max_ii(1, (w / 2));
+ h = max_ii(1, (h / 2));
+ d = is_layered ? d_ : max_ii(1, (d / 2));
+ }
+ }
+ break;
+ }
+ this->mip_range_set(0, mipmaps_ - 1);
- /* Avoid issue with incomplete textures. */
+ /* Avoid issue with formats not supporting filtering. Nearest by default. */
if (GLContext::direct_state_access_support) {
glTextureParameteri(tex_id_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
@@ -105,65 +175,26 @@ bool GLTexture::init_internal(GPUVertBuf *vbo)
return true;
}
-void GLTexture::ensure_mipmaps(int miplvl)
+bool GLTexture::init_internal(const GPUTexture *src, int mip_offset, int layer_offset)
{
- int effective_h = (type_ == GPU_TEXTURE_1D_ARRAY) ? 0 : h_;
- int effective_d = (type_ != GPU_TEXTURE_3D) ? 0 : d_;
- int max_dimension = max_iii(w_, effective_h, effective_d);
- int max_miplvl = floor(log2(max_dimension));
- miplvl = min_ii(miplvl, max_miplvl);
-
- while (mipmaps_ < miplvl) {
- int mip = ++mipmaps_;
- const int dimensions = this->dimensions_count();
-
- int w = mip_width_get(mip);
- int h = mip_height_get(mip);
- int d = mip_depth_get(mip);
- GLenum internal_format = to_gl_internal_format(format_);
- GLenum gl_format = to_gl_data_format(format_);
- GLenum gl_type = to_gl(to_data_format(format_));
+ BLI_assert(GLContext::texture_storage_support);
- GLContext::state_manager_active_get()->texture_bind_temp(this);
+ const GLTexture *gl_src = static_cast<const GLTexture *>(unwrap(src));
+ GLenum internal_format = to_gl_internal_format(format_);
+ target_ = to_gl_target(type_);
- if (type_ == GPU_TEXTURE_CUBE) {
- for (int i = 0; i < d; i++) {
- GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
- glTexImage2D(target, mip, internal_format, w, h, 0, gl_format, gl_type, nullptr);
- }
- }
- else if (format_flag_ & GPU_FORMAT_COMPRESSED) {
- size_t size = ((w + 3) / 4) * ((h + 3) / 4) * to_block_size(format_);
- switch (dimensions) {
- default:
- case 1:
- glCompressedTexImage1D(target_, mip, internal_format, w, 0, size, nullptr);
- break;
- case 2:
- glCompressedTexImage2D(target_, mip, internal_format, w, h, 0, size, nullptr);
- break;
- case 3:
- glCompressedTexImage3D(target_, mip, internal_format, w, h, d, 0, size, nullptr);
- break;
- }
- }
- else {
- switch (dimensions) {
- default:
- case 1:
- glTexImage1D(target_, mip, internal_format, w, 0, gl_format, gl_type, nullptr);
- break;
- case 2:
- glTexImage2D(target_, mip, internal_format, w, h, 0, gl_format, gl_type, nullptr);
- break;
- case 3:
- glTexImage3D(target_, mip, internal_format, w, h, d, 0, gl_format, gl_type, nullptr);
- break;
- }
- }
- }
+ glTextureView(tex_id_,
+ target_,
+ gl_src->tex_id_,
+ internal_format,
+ mip_offset,
+ mipmaps_,
+ layer_offset,
+ this->layer_count());
- this->mip_range_set(0, mipmaps_);
+ debug::object_label(GL_TEXTURE, tex_id_, name_);
+
+ return true;
}
/** \} */
@@ -216,9 +247,7 @@ void GLTexture::update_sub(
BLI_assert(validate_data_format(format_, type));
BLI_assert(data != nullptr);
- this->ensure_mipmaps(mip);
-
- if (mip > mipmaps_) {
+ if (mip >= mipmaps_) {
debug::raise_gl_error("Updating a miplvl on a texture too small to have this many levels.");
return;
}
@@ -283,7 +312,6 @@ void GLTexture::update_sub(
*/
void GLTexture::generate_mipmap()
{
- this->ensure_mipmaps(9999);
/* Some drivers have bugs when using #glGenerateMipmap with depth textures (see T56789).
* In this case we just create a complete texture with mipmaps manually without
* down-sampling. You must initialize the texture levels using other methods like
diff --git a/source/blender/gpu/opengl/gl_texture.hh b/source/blender/gpu/opengl/gl_texture.hh
index 07d3bb8c946..d4d024f5e3e 100644
--- a/source/blender/gpu/opengl/gl_texture.hh
+++ b/source/blender/gpu/opengl/gl_texture.hh
@@ -74,11 +74,11 @@ 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);
- /** Will create enough mipmaps up to get to the given level. */
- void ensure_mipmaps(int mip);
void update_sub_direct_state_access(
int mip, int offset[3], int extent[3], GLenum gl_format, GLenum gl_type, const void *data);
GPUFrameBuffer *framebuffer_get();
diff --git a/source/blender/gpu/opengl/gl_vertex_array.cc b/source/blender/gpu/opengl/gl_vertex_array.cc
index 88b69eb5b62..04f60f10d41 100644
--- a/source/blender/gpu/opengl/gl_vertex_array.cc
+++ b/source/blender/gpu/opengl/gl_vertex_array.cc
@@ -54,7 +54,7 @@ static uint16_t vbo_bind(const ShaderInterface *interface,
const char *name = GPU_vertformat_attr_name_get(format, a, n_idx);
const ShaderInput *input = interface->attr_get(name);
- if (input == nullptr) {
+ if (input == nullptr || input->location == -1) {
continue;
}
diff --git a/source/blender/gpu/shaders/infos/gpu_shader_2D_image_overlays_merge_info.hh b/source/blender/gpu/shaders/infos/gpu_shader_2D_image_overlays_merge_info.hh
index d3b70cb67f9..2798846b310 100644
--- a/source/blender/gpu/shaders/infos/gpu_shader_2D_image_overlays_merge_info.hh
+++ b/source/blender/gpu/shaders/infos/gpu_shader_2D_image_overlays_merge_info.hh
@@ -16,6 +16,7 @@ GPU_SHADER_CREATE_INFO(gpu_shader_2D_image_overlays_merge)
.push_constant(Type::MAT4, "ModelViewProjectionMatrix")
.push_constant(Type::BOOL, "display_transform")
.push_constant(Type::BOOL, "overlay")
+ /* Sampler slots should match OCIO's. */
.sampler(0, ImageType::FLOAT_2D, "image_texture")
.sampler(1, ImageType::FLOAT_2D, "overlays_texture")
.vertex_source("gpu_shader_2D_image_vert.glsl")