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.txt87
-rw-r--r--source/blender/gpu/GPU_batch.h15
-rw-r--r--source/blender/gpu/GPU_buffers.h13
-rw-r--r--source/blender/gpu/GPU_glew.h15
-rw-r--r--source/blender/gpu/GPU_legacy_stubs.h497
-rw-r--r--source/blender/gpu/GPU_material.h18
-rw-r--r--source/blender/gpu/GPU_shader.h10
-rw-r--r--source/blender/gpu/GPU_texture.h1
-rw-r--r--source/blender/gpu/intern/gpu_batch.cc9
-rw-r--r--source/blender/gpu/intern/gpu_batch_private.hh1
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c60
-rw-r--r--source/blender/gpu/intern/gpu_codegen.cc22
-rw-r--r--source/blender/gpu/intern/gpu_material.c52
-rw-r--r--source/blender/gpu/intern/gpu_node_graph.c69
-rw-r--r--source/blender/gpu/intern/gpu_node_graph.h3
-rw-r--r--source/blender/gpu/intern/gpu_platform.cc14
-rw-r--r--source/blender/gpu/intern/gpu_shader.cc22
-rw-r--r--source/blender/gpu/intern/gpu_shader_builder_stubs.cc11
-rw-r--r--source/blender/gpu/intern/gpu_shader_create_info.cc8
-rw-r--r--source/blender/gpu/intern/gpu_shader_create_info.hh45
-rw-r--r--source/blender/gpu/intern/gpu_shader_dependency.cc268
-rw-r--r--source/blender/gpu/intern/gpu_shader_interface.hh21
-rw-r--r--source/blender/gpu/intern/gpu_texture.cc106
-rw-r--r--source/blender/gpu/metal/mtl_query.mm2
-rw-r--r--source/blender/gpu/opengl/gl_backend.cc81
-rw-r--r--source/blender/gpu/opengl/gl_backend.hh4
-rw-r--r--source/blender/gpu/opengl/gl_batch.cc24
-rw-r--r--source/blender/gpu/opengl/gl_batch.hh3
-rw-r--r--source/blender/gpu/opengl/gl_context.cc4
-rw-r--r--source/blender/gpu/opengl/gl_context.hh2
-rw-r--r--source/blender/gpu/opengl/gl_debug.cc17
-rw-r--r--source/blender/gpu/opengl/gl_debug.hh2
-rw-r--r--source/blender/gpu/opengl/gl_framebuffer.hh2
-rw-r--r--source/blender/gpu/opengl/gl_immediate.hh2
-rw-r--r--source/blender/gpu/opengl/gl_index_buffer.hh8
-rw-r--r--source/blender/gpu/opengl/gl_primitive.hh2
-rw-r--r--source/blender/gpu/opengl/gl_query.hh2
-rw-r--r--source/blender/gpu/opengl/gl_shader.cc14
-rw-r--r--source/blender/gpu/opengl/gl_shader.hh2
-rw-r--r--source/blender/gpu/opengl/gl_shader_interface.cc14
-rw-r--r--source/blender/gpu/opengl/gl_shader_interface.hh2
-rw-r--r--source/blender/gpu/opengl/gl_state.cc6
-rw-r--r--source/blender/gpu/opengl/gl_state.hh2
-rw-r--r--source/blender/gpu/opengl/gl_storage_buffer.cc2
-rw-r--r--source/blender/gpu/opengl/gl_storage_buffer.hh2
-rw-r--r--source/blender/gpu/opengl/gl_texture.cc1
-rw-r--r--source/blender/gpu/opengl/gl_texture.hh4
-rw-r--r--source/blender/gpu/opengl/gl_uniform_buffer.cc11
-rw-r--r--source/blender/gpu/opengl/gl_uniform_buffer.hh2
-rw-r--r--source/blender/gpu/opengl/gl_vertex_array.hh2
-rw-r--r--source/blender/gpu/opengl/gl_vertex_buffer.hh2
-rw-r--r--source/blender/gpu/shaders/common/gpu_shader_common_color_utils.glsl119
-rw-r--r--source/blender/gpu/shaders/common/gpu_shader_common_curves.glsl75
-rw-r--r--source/blender/gpu/shaders/common/gpu_shader_common_math_utils.glsl27
-rw-r--r--source/blender/gpu/shaders/common/gpu_shader_common_mix_rgb.glsl46
-rw-r--r--source/blender/gpu/shaders/compositor/compositor_alpha_crop.glsl11
-rw-r--r--source/blender/gpu/shaders/compositor/compositor_bilateral_blur.glsl31
-rw-r--r--source/blender/gpu/shaders/compositor/compositor_bokeh_image.glsl118
-rw-r--r--source/blender/gpu/shaders/compositor/compositor_box_mask.glsl27
-rw-r--r--source/blender/gpu/shaders/compositor/compositor_convert.glsl8
-rw-r--r--source/blender/gpu/shaders/compositor/compositor_despeckle.glsl70
-rw-r--r--source/blender/gpu/shaders/compositor/compositor_directional_blur.glsl21
-rw-r--r--source/blender/gpu/shaders/compositor/compositor_edge_filter.glsl31
-rw-r--r--source/blender/gpu/shaders/compositor/compositor_ellipse_mask.glsl27
-rw-r--r--source/blender/gpu/shaders/compositor/compositor_filter.glsl20
-rw-r--r--source/blender/gpu/shaders/compositor/compositor_flip.glsl15
-rw-r--r--source/blender/gpu/shaders/compositor/compositor_image_crop.glsl7
-rw-r--r--source/blender/gpu/shaders/compositor/compositor_projector_lens_distortion.glsl16
-rw-r--r--source/blender/gpu/shaders/compositor/compositor_realize_on_domain.glsl25
-rw-r--r--source/blender/gpu/shaders/compositor/compositor_screen_lens_distortion.glsl151
-rw-r--r--source/blender/gpu/shaders/compositor/compositor_set_alpha.glsl8
-rw-r--r--source/blender/gpu/shaders/compositor/compositor_split_viewer.glsl14
-rw-r--r--source/blender/gpu/shaders/compositor/infos/compositor_alpha_crop_info.hh12
-rw-r--r--source/blender/gpu/shaders/compositor/infos/compositor_bilateral_blur_info.hh13
-rw-r--r--source/blender/gpu/shaders/compositor/infos/compositor_bokeh_image_info.hh14
-rw-r--r--source/blender/gpu/shaders/compositor/infos/compositor_box_mask_info.hh35
-rw-r--r--source/blender/gpu/shaders/compositor/infos/compositor_convert_info.hh69
-rw-r--r--source/blender/gpu/shaders/compositor/infos/compositor_despeckle_info.hh13
-rw-r--r--source/blender/gpu/shaders/compositor/infos/compositor_directional_blur_info.hh12
-rw-r--r--source/blender/gpu/shaders/compositor/infos/compositor_edge_filter_info.hh12
-rw-r--r--source/blender/gpu/shaders/compositor/infos/compositor_ellipse_mask_info.hh35
-rw-r--r--source/blender/gpu/shaders/compositor/infos/compositor_filter_info.hh12
-rw-r--r--source/blender/gpu/shaders/compositor/infos/compositor_flip_info.hh12
-rw-r--r--source/blender/gpu/shaders/compositor/infos/compositor_image_crop_info.hh11
-rw-r--r--source/blender/gpu/shaders/compositor/infos/compositor_projector_lens_distortion_info.hh11
-rw-r--r--source/blender/gpu/shaders/compositor/infos/compositor_realize_on_domain_info.hh24
-rw-r--r--source/blender/gpu/shaders/compositor/infos/compositor_screen_lens_distortion_info.hh20
-rw-r--r--source/blender/gpu/shaders/compositor/infos/compositor_set_alpha_info.hh11
-rw-r--r--source/blender/gpu/shaders/compositor/infos/compositor_split_viewer_info.hh22
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_alpha_over.glsl48
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_bright_contrast.glsl38
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_channel_matte.glsl52
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_chroma_matte.glsl43
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_balance.glsl34
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_correction.glsl87
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_matte.glsl27
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_spill.glsl13
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_to_luminance.glsl6
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_difference_matte.glsl10
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_distance_matte.glsl26
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_exposure.glsl6
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_gamma.glsl7
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_hue_correct.glsl39
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_hue_saturation_value.glsl16
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_invert.glsl13
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_luminance_matte.glsl14
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_main.glsl7
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_map_value.glsl56
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_normal.glsl9
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_posterize.glsl6
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_separate_combine.glsl132
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_set_alpha.glsl9
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_store_output.glsl26
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_texture_utilities.glsl25
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_type_conversion.glsl29
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_noise.glsl1
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_tex_voronoi.glsl1
-rw-r--r--source/blender/gpu/tests/gpu_shader_test.cc2
118 files changed, 2793 insertions, 782 deletions
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 5e97909a2b8..9469db1d842 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -34,13 +34,12 @@ set(INC
../../../intern/atomic
../../../intern/clog
../../../intern/ghost
- ../../../intern/glew-mx
../../../intern/guardedalloc
../../../intern/mantaflow/extern
)
set(INC_SYS
- ${GLEW_INCLUDE_PATH}
+ ${Epoxy_INCLUDE_DIRS}
)
set(SRC
@@ -93,12 +92,10 @@ set(SRC
GPU_debug.h
GPU_drawlist.h
GPU_framebuffer.h
- GPU_glew.h
GPU_immediate.h
GPU_immediate_util.h
GPU_index_buffer.h
GPU_init_exit.h
- GPU_legacy_stubs.h
GPU_material.h
GPU_matrix.h
GPU_platform.h
@@ -190,8 +187,8 @@ set(OPENGL_SRC
set(METAL_SRC
metal/mtl_backend.mm
- metal/mtl_context.mm
metal/mtl_command_buffer.mm
+ metal/mtl_context.mm
metal/mtl_debug.mm
metal/mtl_framebuffer.mm
metal/mtl_memory.mm
@@ -224,15 +221,9 @@ if(WITH_METAL_BACKEND)
endif()
set(LIB
- ${BLENDER_GL_LIBRARIES}
+ ${Epoxy_LIBRARIES}
)
-if(NOT WITH_SYSTEM_GLEW)
- list(APPEND LIB
- ${BLENDER_GLEW_LIBRARIES}
- )
-endif()
-
set(MSL_SRC
metal/kernels/compute_texture_update.msl
@@ -323,6 +314,51 @@ set(GLSL_SRC
shaders/common/gpu_shader_common_math_utils.glsl
shaders/common/gpu_shader_common_mix_rgb.glsl
+ shaders/compositor/compositor_alpha_crop.glsl
+ shaders/compositor/compositor_bilateral_blur.glsl
+ shaders/compositor/compositor_bokeh_image.glsl
+ shaders/compositor/compositor_box_mask.glsl
+ shaders/compositor/compositor_convert.glsl
+ shaders/compositor/compositor_despeckle.glsl
+ shaders/compositor/compositor_directional_blur.glsl
+ shaders/compositor/compositor_edge_filter.glsl
+ shaders/compositor/compositor_ellipse_mask.glsl
+ shaders/compositor/compositor_filter.glsl
+ shaders/compositor/compositor_flip.glsl
+ shaders/compositor/compositor_image_crop.glsl
+ shaders/compositor/compositor_projector_lens_distortion.glsl
+ shaders/compositor/compositor_realize_on_domain.glsl
+ shaders/compositor/compositor_screen_lens_distortion.glsl
+ shaders/compositor/compositor_set_alpha.glsl
+ shaders/compositor/compositor_split_viewer.glsl
+
+ shaders/compositor/library/gpu_shader_compositor_alpha_over.glsl
+ shaders/compositor/library/gpu_shader_compositor_bright_contrast.glsl
+ shaders/compositor/library/gpu_shader_compositor_channel_matte.glsl
+ shaders/compositor/library/gpu_shader_compositor_chroma_matte.glsl
+ shaders/compositor/library/gpu_shader_compositor_color_balance.glsl
+ shaders/compositor/library/gpu_shader_compositor_color_correction.glsl
+ shaders/compositor/library/gpu_shader_compositor_color_matte.glsl
+ shaders/compositor/library/gpu_shader_compositor_color_spill.glsl
+ shaders/compositor/library/gpu_shader_compositor_color_to_luminance.glsl
+ shaders/compositor/library/gpu_shader_compositor_difference_matte.glsl
+ shaders/compositor/library/gpu_shader_compositor_distance_matte.glsl
+ shaders/compositor/library/gpu_shader_compositor_exposure.glsl
+ shaders/compositor/library/gpu_shader_compositor_gamma.glsl
+ shaders/compositor/library/gpu_shader_compositor_hue_correct.glsl
+ shaders/compositor/library/gpu_shader_compositor_hue_saturation_value.glsl
+ shaders/compositor/library/gpu_shader_compositor_invert.glsl
+ shaders/compositor/library/gpu_shader_compositor_luminance_matte.glsl
+ shaders/compositor/library/gpu_shader_compositor_main.glsl
+ shaders/compositor/library/gpu_shader_compositor_map_value.glsl
+ shaders/compositor/library/gpu_shader_compositor_normal.glsl
+ shaders/compositor/library/gpu_shader_compositor_posterize.glsl
+ shaders/compositor/library/gpu_shader_compositor_separate_combine.glsl
+ shaders/compositor/library/gpu_shader_compositor_set_alpha.glsl
+ shaders/compositor/library/gpu_shader_compositor_store_output.glsl
+ shaders/compositor/library/gpu_shader_compositor_texture_utilities.glsl
+ shaders/compositor/library/gpu_shader_compositor_type_conversion.glsl
+
shaders/material/gpu_shader_material_add_shader.glsl
shaders/material/gpu_shader_material_ambient_occlusion.glsl
shaders/material/gpu_shader_material_anisotropic.glsl
@@ -454,8 +490,12 @@ list(APPEND INC ${CMAKE_CURRENT_BINARY_DIR})
set(SRC_SHADER_CREATE_INFOS
../draw/engines/basic/shaders/infos/basic_depth_info.hh
+ ../draw/engines/eevee_next/shaders/infos/eevee_depth_of_field_info.hh
../draw/engines/eevee_next/shaders/infos/eevee_film_info.hh
+ ../draw/engines/eevee_next/shaders/infos/eevee_hiz_info.hh
+ ../draw/engines/eevee_next/shaders/infos/eevee_light_culling_info.hh
../draw/engines/eevee_next/shaders/infos/eevee_material_info.hh
+ ../draw/engines/eevee_next/shaders/infos/eevee_motion_blur_info.hh
../draw/engines/eevee_next/shaders/infos/eevee_velocity_info.hh
../draw/engines/gpencil/shaders/infos/gpencil_info.hh
../draw/engines/gpencil/shaders/infos/gpencil_vfx_info.hh
@@ -468,8 +508,8 @@ set(SRC_SHADER_CREATE_INFOS
../draw/engines/overlay/shaders/infos/overlay_grid_info.hh
../draw/engines/overlay/shaders/infos/overlay_outline_info.hh
../draw/engines/overlay/shaders/infos/overlay_paint_info.hh
- ../draw/engines/overlay/shaders/infos/overlay_sculpt_info.hh
../draw/engines/overlay/shaders/infos/overlay_sculpt_curves_info.hh
+ ../draw/engines/overlay/shaders/infos/overlay_sculpt_info.hh
../draw/engines/overlay/shaders/infos/overlay_volume_info.hh
../draw/engines/overlay/shaders/infos/overlay_wireframe_info.hh
../draw/engines/select/shaders/infos/select_id_info.hh
@@ -484,6 +524,7 @@ set(SRC_SHADER_CREATE_INFOS
../draw/engines/workbench/shaders/infos/workbench_transparent_resolve_info.hh
../draw/engines/workbench/shaders/infos/workbench_volume_info.hh
../draw/engines/image/shaders/infos/engine_image_info.hh
+ ../draw/intern/shaders/draw_debug_info.hh
../draw/intern/shaders/draw_fullscreen_info.hh
../draw/intern/shaders/draw_hair_refine_info.hh
../draw/intern/shaders/draw_object_infos_info.hh
@@ -524,6 +565,24 @@ set(SRC_SHADER_CREATE_INFOS
shaders/infos/gpu_shader_simple_lighting_info.hh
shaders/infos/gpu_shader_text_info.hh
shaders/infos/gpu_srgb_to_framebuffer_space_info.hh
+
+ shaders/compositor/infos/compositor_alpha_crop_info.hh
+ shaders/compositor/infos/compositor_bilateral_blur_info.hh
+ shaders/compositor/infos/compositor_bokeh_image_info.hh
+ shaders/compositor/infos/compositor_box_mask_info.hh
+ shaders/compositor/infos/compositor_convert_info.hh
+ shaders/compositor/infos/compositor_despeckle_info.hh
+ shaders/compositor/infos/compositor_directional_blur_info.hh
+ shaders/compositor/infos/compositor_edge_filter_info.hh
+ shaders/compositor/infos/compositor_ellipse_mask_info.hh
+ shaders/compositor/infos/compositor_filter_info.hh
+ shaders/compositor/infos/compositor_flip_info.hh
+ shaders/compositor/infos/compositor_image_crop_info.hh
+ shaders/compositor/infos/compositor_projector_lens_distortion_info.hh
+ shaders/compositor/infos/compositor_realize_on_domain_info.hh
+ shaders/compositor/infos/compositor_screen_lens_distortion_info.hh
+ shaders/compositor/infos/compositor_set_alpha_info.hh
+ shaders/compositor/infos/compositor_split_viewer_info.hh
)
set(SHADER_CREATE_INFOS_CONTENT "")
@@ -538,8 +597,6 @@ if(WITH_MOD_FLUID)
add_definitions(-DWITH_FLUID)
endif()
-add_definitions(${GL_DEFINITIONS})
-
if(WITH_IMAGE_DDS)
add_definitions(-DWITH_DDS)
endif()
diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h
index 7fad8dd23be..c085b592a77 100644
--- a/source/blender/gpu/GPU_batch.h
+++ b/source/blender/gpu/GPU_batch.h
@@ -14,6 +14,7 @@
#include "GPU_index_buffer.h"
#include "GPU_shader.h"
+#include "GPU_storage_buffer.h"
#include "GPU_uniform_buffer.h"
#include "GPU_vertex_buffer.h"
@@ -92,8 +93,10 @@ void GPU_batch_init_ex(GPUBatch *batch,
*/
void GPU_batch_copy(GPUBatch *batch_dst, GPUBatch *batch_src);
-#define GPU_batch_create(prim, verts, elem) GPU_batch_create_ex(prim, verts, elem, 0)
-#define GPU_batch_init(batch, prim, verts, elem) GPU_batch_init_ex(batch, prim, verts, elem, 0)
+#define GPU_batch_create(prim, verts, elem) \
+ GPU_batch_create_ex(prim, verts, elem, (eGPUBatchFlag)0)
+#define GPU_batch_init(batch, prim, verts, elem) \
+ GPU_batch_init_ex(batch, prim, verts, elem, (eGPUBatchFlag)0)
/**
* Same as discard but does not free. (does not call free callback).
@@ -171,7 +174,13 @@ void GPU_batch_draw_instanced(GPUBatch *batch, int i_count);
/**
* This does not bind/unbind shader and does not call GPU_matrix_bind().
*/
-void GPU_batch_draw_advanced(GPUBatch *, int v_first, int v_count, int i_first, int i_count);
+void GPU_batch_draw_advanced(GPUBatch *batch, int v_first, int v_count, int i_first, int i_count);
+
+/**
+ * Issue a draw call using GPU computed arguments. The argument are expected to be valid for the
+ * type of geometry drawn (index or non-indexed).
+ */
+void GPU_batch_draw_indirect(GPUBatch *batch, GPUStorageBuf *indirect_buf);
#if 0 /* future plans */
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
index 89473ac0fe0..d1d91cb7508 100644
--- a/source/blender/gpu/GPU_buffers.h
+++ b/source/blender/gpu/GPU_buffers.h
@@ -22,6 +22,7 @@ struct CCGKey;
struct DMFlagMat;
struct GSet;
struct TableGSet;
+struct Mesh;
struct MLoop;
struct MLoopCol;
struct MLoopTri;
@@ -46,14 +47,11 @@ typedef struct GPU_PBVH_Buffers GPU_PBVH_Buffers;
*
* Threaded: do not call any functions that use OpenGL calls!
*/
-GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const struct MPoly *mpoly,
- const struct MLoop *mloop,
+GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const struct Mesh *mesh,
const struct MLoopTri *looptri,
- const struct MVert *mvert,
- const int *face_indices,
const int *sculpt_face_sets,
- int face_indices_len,
- const struct Mesh *mesh);
+ const int *face_indices,
+ int face_indices_len);
/**
* Threaded: do not call any functions that use OpenGL calls!
@@ -91,9 +89,8 @@ enum {
*/
void GPU_pbvh_mesh_buffers_update(PBVHGPUFormat *vbo_id,
GPU_PBVH_Buffers *buffers,
+ const struct Mesh *mesh,
const struct MVert *mvert,
- const CustomData *vdata,
- const CustomData *ldata,
const float *vmask,
const int *sculpt_face_sets,
const int face_sets_color_seed,
diff --git a/source/blender/gpu/GPU_glew.h b/source/blender/gpu/GPU_glew.h
deleted file mode 100644
index 38209a0eb17..00000000000
--- a/source/blender/gpu/GPU_glew.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later
- * Copyright 2012 Blender Foundation. All rights reserved. */
-
-/** \file
- * \ingroup gpu
- */
-
-#pragma once
-
-#if defined(WITH_OPENGL)
-# include "glew-mx.h"
-# ifndef WITH_LEGACY_OPENGL
-# include "GPU_legacy_stubs.h"
-# endif
-#endif
diff --git a/source/blender/gpu/GPU_legacy_stubs.h b/source/blender/gpu/GPU_legacy_stubs.h
deleted file mode 100644
index 5970738a9b3..00000000000
--- a/source/blender/gpu/GPU_legacy_stubs.h
+++ /dev/null
@@ -1,497 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later
- * Copyright 2017 Blender Foundation. All rights reserved. */
-
-/** \file
- * \ingroup gpu
- *
- * This is to mark the transition to OpenGL core profile
- * The idea is to allow Blender 2.8 to be built with OpenGL 3.3 even if it means breaking things
- *
- * This file should be removed in the future
- */
-
-#pragma once
-
-#if defined(__GNUC__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wunused-parameter"
-# pragma GCC diagnostic ignored "-Wunused-function"
-#endif
-
-#include <stdlib.h> /* for abort(). */
-
-#include "BLI_utildefines.h"
-
-/**
- * Empty function, use for break-point when a deprecated
- * OpenGL function is called.
- */
-static void gl_deprecated(void)
-{
- BLI_assert(true);
-}
-
-#define _GL_BOOL BLI_INLINE GLboolean
-#define _GL_BOOL_RET \
- { \
- gl_deprecated(); \
- return false; \
- }
-
-#define _GL_ENUM BLI_INLINE GLenum
-#define _GL_ENUM_RET \
- { \
- gl_deprecated(); \
- return 0; \
- }
-
-#define _GL_INT BLI_INLINE GLint
-#define _GL_INT_RET \
- { \
- gl_deprecated(); \
- return 0; \
- }
-
-#define _GL_UINT BLI_INLINE GLuint
-#define _GL_UINT_RET \
- { \
- gl_deprecated(); \
- return 0; \
- }
-
-#define _GL_VOID BLI_INLINE void
-#define _GL_VOID_RET \
- { \
- gl_deprecated(); \
- }
-
-static bool disable_enable_check(GLenum cap)
-{
- const bool is_deprecated = ELEM(cap,
- GL_ALPHA_TEST,
- GL_LINE_STIPPLE,
- GL_POINT_SPRITE,
- GL_TEXTURE_1D,
- GL_TEXTURE_2D,
- GL_TEXTURE_GEN_S,
- GL_TEXTURE_GEN_T,
- -1);
-
- if (is_deprecated) {
- gl_deprecated();
- }
-
- return is_deprecated;
-}
-
-_GL_VOID USE_CAREFULLY_glDisable(GLenum cap)
-{
- if (!disable_enable_check(cap)) {
- glDisable(cap);
- }
-}
-#define glDisable USE_CAREFULLY_glDisable
-
-_GL_VOID USE_CAREFULLY_glEnable(GLenum cap)
-{
- if (!disable_enable_check(cap)) {
- glEnable(cap);
- }
-}
-#define glEnable USE_CAREFULLY_glEnable
-
-/**
- * Hand written cases
- */
-
-_GL_VOID DO_NOT_USE_glClientActiveTexture(GLenum texture) _GL_VOID_RET
-
-/**
- * List automatically generated from `gl-deprecated.h` and `glew.h`
- */
-
-/**
- * ENUM values
- */
-#define DO_NOT_USE_GL_CURRENT_FOG_COORDINATE 0
-#define DO_NOT_USE_GL_FOG_COORDINATE 0
-#define DO_NOT_USE_GL_FOG_COORDINATE_ARRAY 0
-#define DO_NOT_USE_GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0
-#define DO_NOT_USE_GL_FOG_COORDINATE_ARRAY_POINTER 0
-#define DO_NOT_USE_GL_FOG_COORDINATE_ARRAY_STRIDE 0
-#define DO_NOT_USE_GL_FOG_COORDINATE_ARRAY_TYPE 0
-#define DO_NOT_USE_GL_FOG_COORDINATE_SOURCE 0
-#define DO_NOT_USE_GL_POINT_SIZE_GRANULARITY 0
-#define DO_NOT_USE_GL_POINT_SIZE_RANGE 0
-#define DO_NOT_USE_GL_SOURCE0_ALPHA 0
-#define DO_NOT_USE_GL_SOURCE0_RGB 0
-#define DO_NOT_USE_GL_SOURCE1_ALPHA 0
-#define DO_NOT_USE_GL_SOURCE1_RGB 0
-#define DO_NOT_USE_GL_SOURCE2_ALPHA 0
-#define DO_NOT_USE_GL_SOURCE2_RGB 0
-
- /**
- * Functions
- */
- _GL_VOID DO_NOT_USE_glAccum(GLenum op, GLfloat value) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glAlphaFunc(GLenum func, GLclampf ref) _GL_VOID_RET _GL_BOOL
- DO_NOT_USE_glAreTexturesResident(GLsizei n,
- const GLuint *textures,
- GLboolean *residences) _GL_BOOL_RET _GL_VOID
- DO_NOT_USE_glArrayElement(GLint i) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glBegin(GLenum mode) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glBitmap(GLsizei width,
- GLsizei height,
- GLfloat xorig,
- GLfloat yorig,
- GLfloat xmove,
- GLfloat ymove,
- const GLubyte *bitmap) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glCallList(GLuint list) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glCallLists(GLsizei n, GLenum type, const void *lists) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
- _GL_VOID_RET _GL_VOID DO_NOT_USE_glClearIndex(GLfloat c) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glClipPlane(GLenum plane, const GLdouble *equation) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor3b(GLbyte red, GLbyte green, GLbyte blue) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor3bv(const GLbyte *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor3d(GLdouble red, GLdouble green, GLdouble blue) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor3dv(const GLdouble *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor3f(GLfloat red, GLfloat green, GLfloat blue) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor3fv(const GLfloat *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor3i(GLint red, GLint green, GLint blue) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor3iv(const GLint *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor3s(GLshort red, GLshort green, GLshort blue) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor3sv(const GLshort *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor3ub(GLubyte red, GLubyte green, GLubyte blue) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor3ubv(const GLubyte *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor3ui(GLuint red, GLuint green, GLuint blue) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor3uiv(const GLuint *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor3us(GLushort red, GLushort green, GLushort blue) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor3usv(const GLushort *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor4bv(const GLbyte *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)
- _GL_VOID_RET _GL_VOID DO_NOT_USE_glColor4dv(const GLdouble *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
- _GL_VOID_RET _GL_VOID DO_NOT_USE_glColor4fv(const GLfloat *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor4i(GLint red, GLint green, GLint blue, GLint alpha) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor4iv(const GLint *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha)
- _GL_VOID_RET _GL_VOID DO_NOT_USE_glColor4sv(const GLshort *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
- _GL_VOID_RET _GL_VOID DO_NOT_USE_glColor4ubv(const GLubyte *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha)
- _GL_VOID_RET _GL_VOID DO_NOT_USE_glColor4uiv(const GLuint *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha)
- _GL_VOID_RET _GL_VOID DO_NOT_USE_glColor4usv(const GLushort *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColorMaterial(GLenum face, GLenum mode) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
- _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
- _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glDeleteLists(GLuint list, GLsizei range) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glDisableClientState(GLenum array) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glDrawPixels(GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- const void *pixels) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glEdgeFlag(GLboolean flag) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glEdgeFlagPointer(GLsizei stride, const void *pointer) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glEdgeFlagv(const GLboolean *flag) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glEnableClientState(GLenum array) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glEnd(void) _GL_VOID_RET _GL_VOID DO_NOT_USE_glEndList(void) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glEvalCoord1d(GLdouble u) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glEvalCoord1dv(const GLdouble *u) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glEvalCoord1f(GLfloat u) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glEvalCoord1fv(const GLfloat *u) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glEvalCoord2d(GLdouble u, GLdouble v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glEvalCoord2dv(const GLdouble *u) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glEvalCoord2f(GLfloat u, GLfloat v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glEvalCoord2fv(const GLfloat *u) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glEvalMesh1(GLenum mode, GLint i1, GLint i2) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
- _GL_VOID_RET _GL_VOID DO_NOT_USE_glEvalPoint1(GLint i) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glEvalPoint2(GLint i, GLint j) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glFogf(GLenum pname, GLfloat param) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glFogfv(GLenum pname, const GLfloat *params) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glFogi(GLenum pname, GLint param) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glFogiv(GLenum pname, const GLint *params) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glFrustum(GLdouble left,
- GLdouble right,
- GLdouble bottom,
- GLdouble top,
- GLdouble zNear,
- GLdouble zFar) _GL_VOID_RET _GL_UINT
- DO_NOT_USE_glGenLists(GLsizei range) _GL_UINT_RET _GL_VOID
- DO_NOT_USE_glGetClipPlane(GLenum plane, GLdouble *equation) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glGetLightfv(GLenum light, GLenum pname, GLfloat *params) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glGetLightiv(GLenum light, GLenum pname, GLint *params) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glGetMapdv(GLenum target, GLenum query, GLdouble *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glGetMapfv(GLenum target, GLenum query, GLfloat *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glGetMapiv(GLenum target, GLenum query, GLint *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glGetMaterialiv(GLenum face, GLenum pname, GLint *params) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glGetPixelMapfv(GLenum map, GLfloat *values) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glGetPixelMapuiv(GLenum map, GLuint *values) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glGetPixelMapusv(GLenum map, GLushort *values) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glGetPolygonStipple(GLubyte *mask) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glGetTexEnvfv(GLenum target, GLenum pname, GLfloat *params) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glGetTexEnviv(GLenum target, GLenum pname, GLint *params) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glGetTexGendv(GLenum coord, GLenum pname, GLdouble *params) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glGetTexGenfv(GLenum coord, GLenum pname, GLfloat *params) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glGetTexGeniv(GLenum coord, GLenum pname, GLint *params) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glIndexMask(GLuint mask) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glIndexPointer(GLenum type,
- GLsizei stride,
- const void *pointer) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glIndexd(GLdouble c) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glIndexdv(const GLdouble *c) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glIndexf(GLfloat c) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glIndexfv(const GLfloat *c) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glIndexi(GLint c) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glIndexiv(const GLint *c) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glIndexs(GLshort c) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glIndexsv(const GLshort *c) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glIndexub(GLubyte c) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glIndexubv(const GLubyte *c) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glInitNames(void) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glInterleavedArrays(GLenum format,
- GLsizei stride,
- const void *pointer) _GL_VOID_RET _GL_BOOL
- DO_NOT_USE_glIsList(GLuint list) _GL_BOOL_RET _GL_VOID
- DO_NOT_USE_glLightModelf(GLenum pname, GLfloat param) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glLightModelfv(GLenum pname, const GLfloat *params) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glLightModeli(GLenum pname, GLint param) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glLightModeliv(GLenum pname, const GLint *params) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glLightf(GLenum light, GLenum pname, GLfloat param) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glLightfv(GLenum light, GLenum pname, const GLfloat *params) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glLighti(GLenum light, GLenum pname, GLint param) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glLightiv(GLenum light, GLenum pname, const GLint *params) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glLineStipple(GLint factor, GLushort pattern) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glListBase(GLuint base) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glLoadIdentity(void) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glLoadMatrixd(const GLdouble *m) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glLoadMatrixf(const GLfloat *m) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glLoadName(GLuint name) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glMap1d(GLenum target,
- GLdouble u1,
- GLdouble u2,
- GLint stride,
- GLint order,
- const GLdouble *points) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glMap1f(GLenum target,
- GLfloat u1,
- GLfloat u2,
- GLint stride,
- GLint order,
- const GLfloat *points) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glMap2d(GLenum target,
- GLdouble u1,
- GLdouble u2,
- GLint ustride,
- GLint uorder,
- GLdouble v1,
- GLdouble v2,
- GLint vstride,
- GLint vorder,
- const GLdouble *points) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glMap2f(GLenum target,
- GLfloat u1,
- GLfloat u2,
- GLint ustride,
- GLint uorder,
- GLfloat v1,
- GLfloat v2,
- GLint vstride,
- GLint vorder,
- const GLfloat *points) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glMapGrid1d(GLint un, GLdouble u1, GLdouble u2) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glMapGrid1f(GLint un, GLfloat u1, GLfloat u2) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2)
- _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2)
- _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glMaterialf(GLenum face, GLenum pname, GLfloat param) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glMateriali(GLenum face, GLenum pname, GLint param) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glMaterialiv(GLenum face, GLenum pname, const GLint *params) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glMatrixMode(GLenum mode) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glMultMatrixd(const GLdouble *m) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glMultMatrixf(const GLfloat *m) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glNewList(GLuint list, GLenum mode) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glNormal3bv(const GLbyte *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glNormal3dv(const GLdouble *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glNormal3fv(const GLfloat *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glNormal3i(GLint nx, GLint ny, GLint nz) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glNormal3iv(const GLint *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glNormal3s(GLshort nx, GLshort ny, GLshort nz) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glNormal3sv(const GLshort *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glNormalPointer(GLenum type,
- GLsizei stride,
- const void *pointer) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glOrtho(GLdouble left,
- GLdouble right,
- GLdouble bottom,
- GLdouble top,
- GLdouble zNear,
- GLdouble zFar) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glPassThrough(GLfloat token) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glPixelMapfv(GLenum map,
- GLsizei mapsize,
- const GLfloat *values) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glPixelMapuiv(GLenum map,
- GLsizei mapsize,
- const GLuint *values) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glPixelMapusv(GLenum map,
- GLsizei mapsize,
- const GLushort *values) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glPixelTransferf(GLenum pname, GLfloat param) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glPixelTransferi(GLenum pname, GLint param) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glPixelZoom(GLfloat xfactor, GLfloat yfactor) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glPolygonStipple(const GLubyte *mask) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glPopAttrib(void) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glPopClientAttrib(void) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glPopMatrix(void) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glPopName(void) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glPrioritizeTextures(GLsizei n,
- const GLuint *textures,
- const GLclampf *priorities) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glPushAttrib(GLbitfield mask) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glPushClientAttrib(GLbitfield mask) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glPushMatrix(void) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glPushName(GLuint name) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos2d(GLdouble x, GLdouble y) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos2dv(const GLdouble *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos2f(GLfloat x, GLfloat y) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos2fv(const GLfloat *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos2i(GLint x, GLint y) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos2iv(const GLint *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos2s(GLshort x, GLshort y) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos2sv(const GLshort *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos3d(GLdouble x, GLdouble y, GLdouble z) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos3dv(const GLdouble *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos3f(GLfloat x, GLfloat y, GLfloat z) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos3fv(const GLfloat *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos3i(GLint x, GLint y, GLint z) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos3iv(const GLint *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos3s(GLshort x, GLshort y, GLshort z) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos3sv(const GLshort *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos4dv(const GLdouble *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos4fv(const GLfloat *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos4i(GLint x, GLint y, GLint z, GLint w) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos4iv(const GLint *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRasterPos4sv(const GLshort *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRectdv(const GLdouble *v1, const GLdouble *v2) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRectfv(const GLfloat *v1, const GLfloat *v2) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRecti(GLint x1, GLint y1, GLint x2, GLint y2) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRectiv(const GLint *v1, const GLint *v2) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRectsv(const GLshort *v1, const GLshort *v2) _GL_VOID_RET _GL_INT
- DO_NOT_USE_glRenderMode(GLenum mode) _GL_INT_RET _GL_VOID
- DO_NOT_USE_glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glScaled(GLdouble x, GLdouble y, GLdouble z) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glScalef(GLfloat x, GLfloat y, GLfloat z) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glSelectBuffer(GLsizei size, GLuint *buffer) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glShadeModel(GLenum mode) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord1d(GLdouble s) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord1dv(const GLdouble *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord1f(GLfloat s) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord1fv(const GLfloat *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord1i(GLint s) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord1iv(const GLint *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord1s(GLshort s) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord1sv(const GLshort *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord2d(GLdouble s, GLdouble t) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord2dv(const GLdouble *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord2f(GLfloat s, GLfloat t) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord2fv(const GLfloat *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord2i(GLint s, GLint t) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord2iv(const GLint *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord2s(GLshort s, GLshort t) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord2sv(const GLshort *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord3d(GLdouble s, GLdouble t, GLdouble r) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord3dv(const GLdouble *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord3f(GLfloat s, GLfloat t, GLfloat r) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord3fv(const GLfloat *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord3i(GLint s, GLint t, GLint r) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord3iv(const GLint *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord3s(GLshort s, GLshort t, GLshort r) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord3sv(const GLshort *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord4dv(const GLdouble *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord4fv(const GLfloat *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord4i(GLint s, GLint t, GLint r, GLint q) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord4iv(const GLint *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoord4sv(const GLshort *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
- _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexEnvf(GLenum target, GLenum pname, GLfloat param) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexEnvi(GLenum target, GLenum pname, GLint param) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexEnviv(GLenum target, GLenum pname, const GLint *params) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexGend(GLenum coord, GLenum pname, GLdouble param) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexGendv(GLenum coord, GLenum pname, const GLdouble *params) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexGenf(GLenum coord, GLenum pname, GLfloat param) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexGenfv(GLenum coord, GLenum pname, const GLfloat *params) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexGeni(GLenum coord, GLenum pname, GLint param) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTexGeniv(GLenum coord, GLenum pname, const GLint *params) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTranslated(GLdouble x, GLdouble y, GLdouble z) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glTranslatef(GLfloat x, GLfloat y, GLfloat z) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex2d(GLdouble x, GLdouble y) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex2dv(const GLdouble *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex2f(GLfloat x, GLfloat y) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex2fv(const GLfloat *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex2i(GLint x, GLint y) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex2iv(const GLint *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex2s(GLshort x, GLshort y) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex2sv(const GLshort *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex3d(GLdouble x, GLdouble y, GLdouble z) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex3dv(const GLdouble *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex3f(GLfloat x, GLfloat y, GLfloat z) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex3fv(const GLfloat *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex3i(GLint x, GLint y, GLint z) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex3iv(const GLint *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex3s(GLshort x, GLshort y, GLshort z) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex3sv(const GLshort *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex4dv(const GLdouble *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex4fv(const GLfloat *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex4i(GLint x, GLint y, GLint z, GLint w) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex4iv(const GLint *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex4s(GLshort x, GLshort y, GLshort z, GLshort w) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertex4sv(const GLshort *v) _GL_VOID_RET _GL_VOID
- DO_NOT_USE_glVertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
- _GL_VOID_RET
-
-/**
- * End of automatically generated list
- */
-
-#undef _GL_BOOL
-#undef _GL_BOOL_RET
-#undef _GL_ENUM
-#undef _GL_ENUM_RET
-#undef _GL_INT
-#undef _GL_INT_RET
-#undef _GL_UINT
-#undef _GL_UINT_RET
-#undef _GL_VOID
-#undef _GL_VOID_RET
-
-#if defined(__GNUC__)
-# pragma GCC diagnostic pop
-#endif
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index 3ca465fa57a..1ab06f3369d 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -121,6 +121,7 @@ typedef struct GPUCodegenOutput {
char *surface;
char *volume;
char *thickness;
+ char *composite;
char *material_functions;
GPUShaderCreateInfo *create_info;
@@ -166,10 +167,6 @@ bool GPU_stack_link(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out,
...);
-GPUNodeLink *GPU_uniformbuf_link_out(struct GPUMaterial *mat,
- struct bNode *node,
- struct GPUNodeStack *stack,
- int index);
void GPU_material_output_surface(GPUMaterial *material, GPUNodeLink *link);
void GPU_material_output_volume(GPUMaterial *material, GPUNodeLink *link);
@@ -178,6 +175,8 @@ void GPU_material_output_thickness(GPUMaterial *material, GPUNodeLink *link);
void GPU_material_add_output_link_aov(GPUMaterial *material, GPUNodeLink *link, int hash);
+void GPU_material_add_output_link_composite(GPUMaterial *material, GPUNodeLink *link);
+
/**
* Wrap a part of the material graph into a function. You need then need to call the function by
* using something like #GPU_differentiate_float_function.
@@ -218,6 +217,7 @@ GPUMaterial *GPU_material_from_nodetree(struct Scene *scene,
void *thunk);
void GPU_material_compile(GPUMaterial *mat);
+void GPU_material_free_single(GPUMaterial *material);
void GPU_material_free(struct ListBase *gpumaterial);
void GPU_material_acquire(GPUMaterial *mat);
@@ -319,6 +319,16 @@ struct GHash *GPU_uniform_attr_list_hash_new(const char *info);
void GPU_uniform_attr_list_copy(GPUUniformAttrList *dest, GPUUniformAttrList *src);
void GPU_uniform_attr_list_free(GPUUniformAttrList *set);
+/* A callback passed to GPU_material_from_callbacks to construct the material graph by adding and
+ * linking the necessary GPU material nodes. */
+typedef void (*ConstructGPUMaterialFn)(void *thunk, GPUMaterial *material);
+
+/* Construct a GPU material from a set of callbacks. See the callback types for more information.
+ * The given thunk will be passed as the first parameter of each callback. */
+GPUMaterial *GPU_material_from_callbacks(ConstructGPUMaterialFn construct_function_cb,
+ GPUCodegenCallbackFn generate_code_function_cb,
+ void *thunk);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index 3460d33fe68..529a3da3ab9 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -148,11 +148,19 @@ typedef enum {
GPU_NUM_UNIFORM_BLOCKS, /* Special value, denotes number of builtin uniforms block. */
} GPUUniformBlockBuiltin;
+typedef enum {
+ GPU_STORAGE_BUFFER_DEBUG_VERTS = 0, /* drw_debug_verts_buf */
+ GPU_STORAGE_BUFFER_DEBUG_PRINT, /* drw_debug_print_buf */
+
+ GPU_NUM_STORAGE_BUFFERS, /* Special value, denotes number of builtin buffer blocks. */
+} GPUStorageBufferBuiltin;
+
void GPU_shader_set_srgb_uniform(GPUShader *shader);
int GPU_shader_get_uniform(GPUShader *shader, const char *name);
int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin);
int GPU_shader_get_builtin_block(GPUShader *shader, int builtin);
+int GPU_shader_get_builtin_ssbo(GPUShader *shader, int builtin);
/** DEPRECATED: Kept only because of Python GPU API. */
int GPU_shader_get_uniform_block(GPUShader *shader, const char *name);
int GPU_shader_get_ssbo(GPUShader *shader, const char *name);
@@ -177,7 +185,9 @@ void GPU_shader_uniform_4f(GPUShader *sh, const char *name, float x, float y, fl
void GPU_shader_uniform_2fv(GPUShader *sh, const char *name, const float data[2]);
void GPU_shader_uniform_3fv(GPUShader *sh, const char *name, const float data[3]);
void GPU_shader_uniform_4fv(GPUShader *sh, const char *name, const float data[4]);
+void GPU_shader_uniform_2iv(GPUShader *sh, const char *name, const int data[2]);
void GPU_shader_uniform_mat4(GPUShader *sh, const char *name, const float data[4][4]);
+void GPU_shader_uniform_mat3_as_mat4(GPUShader *sh, const char *name, const float data[3][3]);
void GPU_shader_uniform_2fv_array(GPUShader *sh, const char *name, int len, const float (*val)[2]);
void GPU_shader_uniform_4fv_array(GPUShader *sh, const char *name, int len, const float (*val)[4]);
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index d76185fc71d..30e890b1591 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -331,6 +331,7 @@ int GPU_texture_orig_width(const GPUTexture *tex);
int GPU_texture_orig_height(const GPUTexture *tex);
void GPU_texture_orig_size_set(GPUTexture *tex, int w, int h);
eGPUTextureFormat GPU_texture_format(const GPUTexture *tex);
+const char *GPU_texture_format_description(eGPUTextureFormat texture_format);
bool GPU_texture_array(const GPUTexture *tex);
bool GPU_texture_cube(const GPUTexture *tex);
bool GPU_texture_depth(const GPUTexture *tex);
diff --git a/source/blender/gpu/intern/gpu_batch.cc b/source/blender/gpu/intern/gpu_batch.cc
index 1b34b6e6c69..0b47a7b2952 100644
--- a/source/blender/gpu/intern/gpu_batch.cc
+++ b/source/blender/gpu/intern/gpu_batch.cc
@@ -270,6 +270,15 @@ void GPU_batch_draw_advanced(
batch->draw(v_first, v_count, i_first, i_count);
}
+void GPU_batch_draw_indirect(GPUBatch *gpu_batch, GPUStorageBuf *indirect_buf)
+{
+ BLI_assert(Context::get()->shader != nullptr);
+ BLI_assert(indirect_buf != nullptr);
+ Batch *batch = static_cast<Batch *>(gpu_batch);
+
+ batch->draw_indirect(indirect_buf);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/gpu/intern/gpu_batch_private.hh b/source/blender/gpu/intern/gpu_batch_private.hh
index 23052f601d2..8ca19884fd7 100644
--- a/source/blender/gpu/intern/gpu_batch_private.hh
+++ b/source/blender/gpu/intern/gpu_batch_private.hh
@@ -29,6 +29,7 @@ class Batch : public GPUBatch {
virtual ~Batch() = default;
virtual void draw(int v_first, int v_count, int i_first, int i_count) = 0;
+ virtual void draw_indirect(GPUStorageBuf *indirect_buf) = 0;
/* Convenience casts. */
IndexBuf *elem_() const
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 14bbd82c282..d64b8b4118a 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -211,19 +211,18 @@ static void gpu_pbvh_batch_init(GPU_PBVH_Buffers *buffers, GPUPrimType prim)
* \{ */
static bool gpu_pbvh_is_looptri_visible(const MLoopTri *lt,
- const MVert *mvert,
+ const bool *hide_vert,
const MLoop *mloop,
const int *sculpt_face_sets)
{
- return (!paint_is_face_hidden(lt, mvert, mloop) && sculpt_face_sets &&
+ return (!paint_is_face_hidden(lt, hide_vert, mloop) && sculpt_face_sets &&
sculpt_face_sets[lt->poly] > SCULPT_FACE_SET_NONE);
}
void GPU_pbvh_mesh_buffers_update(PBVHGPUFormat *vbo_id,
GPU_PBVH_Buffers *buffers,
+ const Mesh *mesh,
const MVert *mvert,
- const CustomData *vdata,
- const CustomData *ldata,
const float *vmask,
const int *sculpt_face_sets,
int face_sets_color_seed,
@@ -234,23 +233,23 @@ void GPU_pbvh_mesh_buffers_update(PBVHGPUFormat *vbo_id,
GPUAttrRef vcol_refs[MAX_GPU_ATTR];
GPUAttrRef cd_uvs[MAX_GPU_ATTR];
- Mesh me_query;
- BKE_id_attribute_copy_domains_temp(ID_ME, vdata, NULL, ldata, NULL, NULL, &me_query.id);
+ const bool *hide_vert = (bool *)CustomData_get_layer_named(
+ &mesh->vdata, CD_PROP_BOOL, ".hide_vert");
- CustomDataLayer *actcol = BKE_id_attributes_active_color_get(&me_query.id);
- eAttrDomain actcol_domain = actcol ? BKE_id_attribute_domain(&me_query.id, actcol) :
+ const CustomDataLayer *actcol = BKE_id_attributes_active_color_get(&mesh->id);
+ eAttrDomain actcol_domain = actcol ? BKE_id_attribute_domain(&mesh->id, actcol) :
ATTR_DOMAIN_AUTO;
- CustomDataLayer *rendercol = BKE_id_attributes_render_color_get(&me_query.id);
+ const CustomDataLayer *rendercol = BKE_id_attributes_render_color_get(&mesh->id);
int totcol;
if (update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) {
totcol = gpu_pbvh_make_attr_offs(ATTR_DOMAIN_MASK_COLOR,
CD_MASK_COLOR_ALL,
- vdata,
+ &mesh->vdata,
NULL,
- ldata,
+ &mesh->ldata,
NULL,
vcol_refs,
vbo_id->active_attrs_only,
@@ -267,14 +266,14 @@ void GPU_pbvh_mesh_buffers_update(PBVHGPUFormat *vbo_id,
CD_MASK_MLOOPUV,
NULL,
NULL,
- ldata,
+ &mesh->ldata,
NULL,
cd_uvs,
vbo_id->active_attrs_only,
CD_MLOOPUV,
ATTR_DOMAIN_CORNER,
- get_active_layer(ldata, CD_MLOOPUV),
- get_render_layer(ldata, CD_MLOOPUV));
+ get_active_layer(&mesh->ldata, CD_MLOOPUV),
+ get_render_layer(&mesh->ldata, CD_MLOOPUV));
const bool show_mask = vmask && (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0;
const bool show_face_sets = sculpt_face_sets &&
@@ -308,13 +307,13 @@ void GPU_pbvh_mesh_buffers_update(PBVHGPUFormat *vbo_id,
GPU_vertbuf_attr_get_raw_data(buffers->vert_buf, vbo_id->uv[uv_i], &uv_step);
GPUAttrRef *ref = cd_uvs + uv_i;
- CustomDataLayer *layer = ldata->layers + ref->layer_idx;
+ CustomDataLayer *layer = mesh->ldata.layers + ref->layer_idx;
MLoopUV *muv = layer->data;
for (uint i = 0; i < buffers->face_indices_len; i++) {
const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]];
- if (!gpu_pbvh_is_looptri_visible(lt, mvert, buffers->mloop, sculpt_face_sets)) {
+ if (!gpu_pbvh_is_looptri_visible(lt, hide_vert, buffers->mloop, sculpt_face_sets)) {
continue;
}
@@ -334,7 +333,7 @@ void GPU_pbvh_mesh_buffers_update(PBVHGPUFormat *vbo_id,
MLoopCol *mcol = NULL;
GPUAttrRef *ref = vcol_refs + col_i;
- const CustomData *cdata = ref->domain == ATTR_DOMAIN_POINT ? vdata : ldata;
+ const CustomData *cdata = ref->domain == ATTR_DOMAIN_POINT ? &mesh->vdata : &mesh->ldata;
CustomDataLayer *layer = cdata->layers + ref->layer_idx;
bool color_loops = ref->domain == ATTR_DOMAIN_CORNER;
@@ -354,7 +353,7 @@ void GPU_pbvh_mesh_buffers_update(PBVHGPUFormat *vbo_id,
buffers->mloop[lt->tri[2]].v,
};
- if (!gpu_pbvh_is_looptri_visible(lt, mvert, buffers->mloop, sculpt_face_sets)) {
+ if (!gpu_pbvh_is_looptri_visible(lt, hide_vert, buffers->mloop, sculpt_face_sets)) {
continue;
}
@@ -394,7 +393,7 @@ void GPU_pbvh_mesh_buffers_update(PBVHGPUFormat *vbo_id,
buffers->mloop[lt->tri[2]].v,
};
- if (!gpu_pbvh_is_looptri_visible(lt, mvert, buffers->mloop, sculpt_face_sets)) {
+ if (!gpu_pbvh_is_looptri_visible(lt, hide_vert, buffers->mloop, sculpt_face_sets)) {
continue;
}
@@ -457,21 +456,24 @@ void GPU_pbvh_mesh_buffers_update(PBVHGPUFormat *vbo_id,
buffers->mvert = mvert;
}
-GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const MPoly *mpoly,
- const MLoop *mloop,
+GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const Mesh *mesh,
const MLoopTri *looptri,
- const MVert *mvert,
- const int *face_indices,
const int *sculpt_face_sets,
- const int face_indices_len,
- const struct Mesh *mesh)
+ const int *face_indices,
+ const int face_indices_len)
{
GPU_PBVH_Buffers *buffers;
int i, tottri;
int tot_real_edges = 0;
+ const MPoly *mpoly = mesh->mpoly;
+ const MLoop *mloop = mesh->mloop;
+
buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
+ const bool *hide_vert = (bool *)CustomData_get_layer_named(
+ &mesh->vdata, CD_PROP_BOOL, ".hide_vert");
+
/* smooth or flat for all */
buffers->smooth = mpoly[looptri[face_indices[0]].poly].flag & ME_SMOOTH;
@@ -480,7 +482,7 @@ GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const MPoly *mpoly,
/* Count the number of visible triangles */
for (i = 0, tottri = 0; i < face_indices_len; i++) {
const MLoopTri *lt = &looptri[face_indices[i]];
- if (gpu_pbvh_is_looptri_visible(lt, mvert, mloop, sculpt_face_sets)) {
+ if (gpu_pbvh_is_looptri_visible(lt, hide_vert, mloop, sculpt_face_sets)) {
int r_edges[3];
BKE_mesh_looptri_get_real_edges(mesh, lt, r_edges);
for (int j = 0; j < 3; j++) {
@@ -513,7 +515,7 @@ GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const MPoly *mpoly,
const MLoopTri *lt = &looptri[face_indices[i]];
/* Skip hidden faces */
- if (!gpu_pbvh_is_looptri_visible(lt, mvert, mloop, sculpt_face_sets)) {
+ if (!gpu_pbvh_is_looptri_visible(lt, hide_vert, mloop, sculpt_face_sets)) {
continue;
}
@@ -1246,9 +1248,7 @@ static int gpu_pbvh_make_attr_offs(eAttrDomainMask domain_mask,
}
}
- /* ensure render layer is last
- draw cache code seems to need this
- */
+ /* Ensure render layer is last, draw cache code seems to need this. */
for (int i = 0; i < count; i++) {
GPUAttrRef *ref = r_cd_attrs + i;
diff --git a/source/blender/gpu/intern/gpu_codegen.cc b/source/blender/gpu/intern/gpu_codegen.cc
index 82441c3c89c..4a45a3e63ed 100644
--- a/source/blender/gpu/intern/gpu_codegen.cc
+++ b/source/blender/gpu/intern/gpu_codegen.cc
@@ -280,6 +280,7 @@ class GPUCodegen {
void node_serialize(std::stringstream &eval_ss, const GPUNode *node);
char *graph_serialize(eGPUNodeTag tree_tag, GPUNodeLink *output_link);
+ char *graph_serialize(eGPUNodeTag tree_tag);
static char *extract_c_str(std::stringstream &stream)
{
@@ -500,6 +501,19 @@ char *GPUCodegen::graph_serialize(eGPUNodeTag tree_tag, GPUNodeLink *output_link
return eval_c_str;
}
+char *GPUCodegen::graph_serialize(eGPUNodeTag tree_tag)
+{
+ std::stringstream eval_ss;
+ LISTBASE_FOREACH (GPUNode *, node, &graph.nodes) {
+ if (node->tag & tree_tag) {
+ node_serialize(eval_ss, node);
+ }
+ }
+ char *eval_c_str = extract_c_str(eval_ss);
+ BLI_hash_mm2a_add(&hm2a_, (uchar *)eval_c_str, eval_ss.str().size());
+ return eval_c_str;
+}
+
void GPUCodegen::generate_uniform_buffer()
{
/* Extract uniform inputs. */
@@ -539,6 +553,9 @@ void GPUCodegen::generate_graphs()
output.volume = graph_serialize(GPU_NODE_TAG_VOLUME, graph.outlink_volume);
output.displacement = graph_serialize(GPU_NODE_TAG_DISPLACEMENT, graph.outlink_displacement);
output.thickness = graph_serialize(GPU_NODE_TAG_THICKNESS, graph.outlink_thickness);
+ if (!BLI_listbase_is_empty(&graph.outlink_compositor)) {
+ output.composite = graph_serialize(GPU_NODE_TAG_COMPOSITOR);
+ }
if (!BLI_listbase_is_empty(&graph.material_functions)) {
std::stringstream eval_ss;
@@ -569,9 +586,10 @@ GPUPass *GPU_generate_pass(GPUMaterial *material,
GPUCodegenCallbackFn finalize_source_cb,
void *thunk)
{
- /* Prune the unused nodes and extract attributes before compiling so the
- * generated VBOs are ready to accept the future shader. */
gpu_node_graph_prune_unused(graph);
+
+ /* Extract attributes before compiling so the generated VBOs are ready to accept the future
+ * shader. */
gpu_node_graph_finalize_uniform_attrs(graph);
GPUCodegen codegen(material, graph);
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 4d3ea3e0c99..a4842ef0e43 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -141,7 +141,7 @@ static void gpu_material_ramp_texture_build(GPUMaterial *mat)
mat->coba_builder = NULL;
}
-static void gpu_material_free_single(GPUMaterial *material)
+void GPU_material_free_single(GPUMaterial *material)
{
bool do_free = atomic_sub_and_fetch_uint32(&material->refcount, 1) == 0;
if (!do_free) {
@@ -173,7 +173,7 @@ void GPU_material_free(ListBase *gpumaterial)
LISTBASE_FOREACH (LinkData *, link, gpumaterial) {
GPUMaterial *material = link->data;
DRW_deferred_shader_remove(material);
- gpu_material_free_single(material);
+ GPU_material_free_single(material);
}
BLI_freelistN(gpumaterial);
}
@@ -538,6 +538,13 @@ void GPU_material_add_output_link_aov(GPUMaterial *material, GPUNodeLink *link,
BLI_addtail(&material->graph.outlink_aovs, aov_link);
}
+void GPU_material_add_output_link_composite(GPUMaterial *material, GPUNodeLink *link)
+{
+ GPUNodeGraphOutputLink *compositor_link = MEM_callocN(sizeof(GPUNodeGraphOutputLink), __func__);
+ compositor_link->outlink = link;
+ BLI_addtail(&material->graph.outlink_compositor, compositor_link);
+}
+
char *GPU_material_split_sub_function(GPUMaterial *material,
eGPUType return_type,
GPUNodeLink **link)
@@ -721,7 +728,7 @@ void GPU_material_acquire(GPUMaterial *mat)
void GPU_material_release(GPUMaterial *mat)
{
- gpu_material_free_single(mat);
+ GPU_material_free_single(mat);
}
void GPU_material_compile(GPUMaterial *mat)
@@ -772,3 +779,42 @@ void GPU_materials_free(Main *bmain)
// BKE_world_defaults_free_gpu();
BKE_material_defaults_free_gpu();
}
+
+GPUMaterial *GPU_material_from_callbacks(ConstructGPUMaterialFn construct_function_cb,
+ GPUCodegenCallbackFn generate_code_function_cb,
+ void *thunk)
+{
+ /* Allocate a new material and its material graph, and initialize its reference count. */
+ GPUMaterial *material = MEM_callocN(sizeof(GPUMaterial), "GPUMaterial");
+ material->graph.used_libraries = BLI_gset_new(
+ BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "GPUNodeGraph.used_libraries");
+ material->refcount = 1;
+
+ /* Construct the material graph by adding and linking the necessary GPU material nodes. */
+ construct_function_cb(thunk, material);
+
+ /* Create and initialize the texture storing color bands used by Ramp and Curve nodes. */
+ gpu_material_ramp_texture_build(material);
+
+ /* Lookup an existing pass in the cache or generate a new one. */
+ material->pass = GPU_generate_pass(material, &material->graph, generate_code_function_cb, thunk);
+
+ /* The pass already exists in the pass cache but its shader already failed to compile. */
+ if (material->pass == NULL) {
+ material->status = GPU_MAT_FAILED;
+ gpu_node_graph_free(&material->graph);
+ return material;
+ }
+
+ /* The pass already exists in the pass cache and its shader is already compiled. */
+ GPUShader *shader = GPU_pass_shader_get(material->pass);
+ if (shader != NULL) {
+ material->status = GPU_MAT_SUCCESS;
+ gpu_node_graph_free_nodes(&material->graph);
+ return material;
+ }
+
+ /* The material was created successfully but still needs to be compiled. */
+ material->status = GPU_MAT_CREATED;
+ return material;
+}
diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c
index 684070dbdc0..377cbc53893 100644
--- a/source/blender/gpu/intern/gpu_node_graph.c
+++ b/source/blender/gpu/intern/gpu_node_graph.c
@@ -75,9 +75,26 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const eGPUType
if (STR_ELEM(name, "set_value", "set_rgb", "set_rgba") && (input->type == type)) {
input = MEM_dupallocN(outnode->inputs.first);
+
+ switch (input->source) {
+ case GPU_SOURCE_ATTR:
+ input->attr->users++;
+ break;
+ case GPU_SOURCE_UNIFORM_ATTR:
+ input->uniform_attr->users++;
+ break;
+ case GPU_SOURCE_TEX:
+ case GPU_SOURCE_TEX_TILED_MAPPING:
+ input->texture->users++;
+ break;
+ default:
+ break;
+ }
+
if (input->link) {
input->link->users++;
}
+
BLI_addtail(&node->inputs, input);
return;
}
@@ -179,35 +196,21 @@ static GPUNodeLink *gpu_uniformbuffer_link(GPUMaterial *mat,
BLI_assert(socket != NULL);
BLI_assert(socket->in_out == in_out);
- if ((socket->flag & SOCK_HIDE_VALUE) == 0) {
- GPUNodeLink *link;
- switch (socket->type) {
- case SOCK_FLOAT: {
- bNodeSocketValueFloat *socket_data = socket->default_value;
- link = GPU_uniform(&socket_data->value);
- break;
- }
- case SOCK_VECTOR: {
- bNodeSocketValueVector *socket_data = socket->default_value;
- link = GPU_uniform(socket_data->value);
- break;
- }
- case SOCK_RGBA: {
- bNodeSocketValueRGBA *socket_data = socket->default_value;
- link = GPU_uniform(socket_data->value);
- break;
- }
- default:
- return NULL;
- break;
- }
+ if (socket->flag & SOCK_HIDE_VALUE) {
+ return NULL;
+ }
- if (in_out == SOCK_IN) {
- GPU_link(mat, gpu_uniform_set_function_from_type(socket->type), link, &stack->link);
- }
- return link;
+ if (!ELEM(socket->type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA)) {
+ return NULL;
}
- return NULL;
+
+ GPUNodeLink *link = GPU_uniform(stack->vec);
+
+ if (in_out == SOCK_IN) {
+ GPU_link(mat, gpu_uniform_set_function_from_type(socket->type), link, &stack->link);
+ }
+
+ return link;
}
static void gpu_node_input_socket(
@@ -735,14 +738,6 @@ bool GPU_stack_link(GPUMaterial *material,
return valid;
}
-GPUNodeLink *GPU_uniformbuf_link_out(GPUMaterial *mat,
- bNode *node,
- GPUNodeStack *stack,
- const int index)
-{
- return gpu_uniformbuffer_link(mat, node, stack, index, SOCK_OUT);
-}
-
/* Node Graph */
static void gpu_inputs_free(ListBase *inputs)
@@ -803,6 +798,7 @@ void gpu_node_graph_free(GPUNodeGraph *graph)
{
BLI_freelistN(&graph->outlink_aovs);
BLI_freelistN(&graph->material_functions);
+ BLI_freelistN(&graph->outlink_compositor);
gpu_node_graph_free_nodes(graph);
BLI_freelistN(&graph->textures);
@@ -855,6 +851,9 @@ void gpu_node_graph_prune_unused(GPUNodeGraph *graph)
LISTBASE_FOREACH (GPUNodeGraphFunctionLink *, funclink, &graph->material_functions) {
gpu_nodes_tag(funclink->outlink, GPU_NODE_TAG_FUNCTION);
}
+ LISTBASE_FOREACH (GPUNodeGraphOutputLink *, compositor_link, &graph->outlink_compositor) {
+ gpu_nodes_tag(compositor_link->outlink, GPU_NODE_TAG_COMPOSITOR);
+ }
for (GPUNode *node = graph->nodes.first, *next = NULL; node; node = next) {
next = node->next;
diff --git a/source/blender/gpu/intern/gpu_node_graph.h b/source/blender/gpu/intern/gpu_node_graph.h
index ae472d5b7aa..08ff8bbef58 100644
--- a/source/blender/gpu/intern/gpu_node_graph.h
+++ b/source/blender/gpu/intern/gpu_node_graph.h
@@ -59,6 +59,7 @@ typedef enum {
GPU_NODE_TAG_THICKNESS = (1 << 3),
GPU_NODE_TAG_AOV = (1 << 4),
GPU_NODE_TAG_FUNCTION = (1 << 5),
+ GPU_NODE_TAG_COMPOSITOR = (1 << 6),
} eGPUNodeTag;
ENUM_OPERATORS(eGPUNodeTag, GPU_NODE_TAG_FUNCTION)
@@ -158,6 +159,8 @@ typedef struct GPUNodeGraph {
ListBase outlink_aovs;
/* List of GPUNodeGraphFunctionLink */
ListBase material_functions;
+ /* List of GPUNodeGraphOutputLink */
+ ListBase outlink_compositor;
/* Requested attributes and textures. */
ListBase attributes;
diff --git a/source/blender/gpu/intern/gpu_platform.cc b/source/blender/gpu/intern/gpu_platform.cc
index d108dd468a0..f8e2c0fe6fc 100644
--- a/source/blender/gpu/intern/gpu_platform.cc
+++ b/source/blender/gpu/intern/gpu_platform.cc
@@ -79,11 +79,15 @@ void GPUPlatformGlobal::init(eGPUDeviceType gpu_device,
this->driver = driver_type;
this->support_level = gpu_support_level;
- this->vendor = BLI_strdup(vendor_str);
- this->renderer = BLI_strdup(renderer_str);
- this->version = BLI_strdup(version_str);
- this->support_key = create_key(gpu_support_level, vendor_str, renderer_str, version_str);
- this->gpu_name = create_gpu_name(vendor_str, renderer_str, version_str);
+ const char *vendor = vendor_str ? vendor_str : "UNKNOWN";
+ const char *renderer = renderer_str ? renderer_str : "UNKNOWN";
+ const char *version = version_str ? version_str : "UNKNOWN";
+
+ this->vendor = BLI_strdup(vendor);
+ this->renderer = BLI_strdup(renderer);
+ this->version = BLI_strdup(version);
+ this->support_key = create_key(gpu_support_level, vendor, renderer, version);
+ this->gpu_name = create_gpu_name(vendor, renderer, version);
this->backend = backend;
}
diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc
index fe9aacb95f9..08c768b28ba 100644
--- a/source/blender/gpu/intern/gpu_shader.cc
+++ b/source/blender/gpu/intern/gpu_shader.cc
@@ -7,6 +7,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_math_matrix.h"
#include "BLI_string_utils.h"
#include "GPU_capabilities.h"
@@ -382,6 +383,8 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
sources.append(resources.c_str());
sources.append(layout.c_str());
sources.extend(code);
+ sources.extend(info.dependencies_generated);
+ sources.append(info.compute_source_generated.c_str());
shader->compute_shader_from_glsl(sources);
}
@@ -575,6 +578,12 @@ int GPU_shader_get_builtin_block(GPUShader *shader, int builtin)
return interface->ubo_builtin((GPUUniformBlockBuiltin)builtin);
}
+int GPU_shader_get_builtin_ssbo(GPUShader *shader, int builtin)
+{
+ ShaderInterface *interface = unwrap(shader)->interface;
+ return interface->ssbo_builtin((GPUStorageBufferBuiltin)builtin);
+}
+
int GPU_shader_get_ssbo(GPUShader *shader, const char *name)
{
ShaderInterface *interface = unwrap(shader)->interface;
@@ -702,12 +711,25 @@ void GPU_shader_uniform_4fv(GPUShader *sh, const char *name, const float data[4]
GPU_shader_uniform_vector(sh, loc, 4, 1, data);
}
+void GPU_shader_uniform_2iv(GPUShader *sh, const char *name, const int data[2])
+{
+ const int loc = GPU_shader_get_uniform(sh, name);
+ GPU_shader_uniform_vector_int(sh, loc, 2, 1, data);
+}
+
void GPU_shader_uniform_mat4(GPUShader *sh, const char *name, const float data[4][4])
{
const int loc = GPU_shader_get_uniform(sh, name);
GPU_shader_uniform_vector(sh, loc, 16, 1, (const float *)data);
}
+void GPU_shader_uniform_mat3_as_mat4(GPUShader *sh, const char *name, const float data[3][3])
+{
+ float matrix[4][4];
+ copy_m4_m3(matrix, data);
+ GPU_shader_uniform_mat4(sh, name, matrix);
+}
+
void GPU_shader_uniform_2fv_array(GPUShader *sh, const char *name, int len, const float (*val)[2])
{
const int loc = GPU_shader_get_uniform(sh, name);
diff --git a/source/blender/gpu/intern/gpu_shader_builder_stubs.cc b/source/blender/gpu/intern/gpu_shader_builder_stubs.cc
index d8af2fc584d..575f98bf428 100644
--- a/source/blender/gpu/intern/gpu_shader_builder_stubs.cc
+++ b/source/blender/gpu/intern/gpu_shader_builder_stubs.cc
@@ -111,7 +111,7 @@ void BKE_id_attribute_copy_domains_temp(short UNUSED(id_type),
const struct CustomData *UNUSED(ldata),
const struct CustomData *UNUSED(pdata),
const struct CustomData *UNUSED(cdata),
- struct ID *UNUSED(i_id))
+ struct ID *UNUSED(r_id))
{
}
@@ -137,7 +137,7 @@ eAttrDomain BKE_id_attribute_domain(const struct ID *UNUSED(id),
/** \name Stubs of BKE_paint.h
* \{ */
bool paint_is_face_hidden(const struct MLoopTri *UNUSED(lt),
- const struct MVert *UNUSED(mvert),
+ const bool *UNUSED(hide_vert),
const struct MLoop *UNUSED(mloop))
{
BLI_assert_unreachable();
@@ -225,6 +225,13 @@ bool CustomData_has_layer(const struct CustomData *UNUSED(data), int UNUSED(type
return false;
}
+void *CustomData_get_layer_named(const struct CustomData *UNUSED(data),
+ int UNUSED(type),
+ const char *UNUSED(name))
+{
+ return nullptr;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/gpu/intern/gpu_shader_create_info.cc b/source/blender/gpu/intern/gpu_shader_create_info.cc
index bc0731862cb..110b77f1f52 100644
--- a/source/blender/gpu/intern/gpu_shader_create_info.cc
+++ b/source/blender/gpu/intern/gpu_shader_create_info.cc
@@ -306,6 +306,14 @@ void gpu_shader_create_info_init()
info->builtins_ |= gpu_shader_dependency_get_builtins(info->fragment_source_);
info->builtins_ |= gpu_shader_dependency_get_builtins(info->geometry_source_);
info->builtins_ |= gpu_shader_dependency_get_builtins(info->compute_source_);
+
+ /* Automatically amend the create info for ease of use of the debug feature. */
+ if ((info->builtins_ & BuiltinBits::USE_DEBUG_DRAW) == BuiltinBits::USE_DEBUG_DRAW) {
+ info->additional_info("draw_debug_draw");
+ }
+ if ((info->builtins_ & BuiltinBits::USE_DEBUG_PRINT) == BuiltinBits::USE_DEBUG_PRINT) {
+ info->additional_info("draw_debug_print");
+ }
}
}
diff --git a/source/blender/gpu/intern/gpu_shader_create_info.hh b/source/blender/gpu/intern/gpu_shader_create_info.hh
index 8e05412d0ee..8236e669288 100644
--- a/source/blender/gpu/intern/gpu_shader_create_info.hh
+++ b/source/blender/gpu/intern/gpu_shader_create_info.hh
@@ -127,8 +127,12 @@ enum class BuiltinBits {
VERTEX_ID = (1 << 14),
WORK_GROUP_ID = (1 << 15),
WORK_GROUP_SIZE = (1 << 16),
+
+ /* Not a builtin but a flag we use to tag shaders that use the debug features. */
+ USE_DEBUG_DRAW = (1 << 29),
+ USE_DEBUG_PRINT = (1 << 30),
};
-ENUM_OPERATORS(BuiltinBits, BuiltinBits::WORK_GROUP_SIZE);
+ENUM_OPERATORS(BuiltinBits, BuiltinBits::USE_DEBUG_PRINT);
/**
* Follow convention described in:
@@ -298,6 +302,7 @@ struct ShaderCreateInfo {
/** Manually set generated code. */
std::string vertex_source_generated = "";
std::string fragment_source_generated = "";
+ std::string compute_source_generated = "";
std::string geometry_source_generated = "";
std::string typedef_source_generated = "";
/** Manually set generated dependencies. */
@@ -740,33 +745,16 @@ struct ShaderCreateInfo {
* Used to share parts of the infos that are common to many shaders.
* \{ */
- Self &additional_info(StringRefNull info_name0,
- StringRefNull info_name1 = "",
- StringRefNull info_name2 = "",
- StringRefNull info_name3 = "",
- StringRefNull info_name4 = "",
- StringRefNull info_name5 = "",
- StringRefNull info_name6 = "")
- {
- additional_infos_.append(info_name0);
- if (!info_name1.is_empty()) {
- additional_infos_.append(info_name1);
- }
- if (!info_name2.is_empty()) {
- additional_infos_.append(info_name2);
- }
- if (!info_name3.is_empty()) {
- additional_infos_.append(info_name3);
- }
- if (!info_name4.is_empty()) {
- additional_infos_.append(info_name4);
- }
- if (!info_name5.is_empty()) {
- additional_infos_.append(info_name5);
- }
- if (!info_name6.is_empty()) {
- additional_infos_.append(info_name6);
- }
+ Self &additional_info(StringRefNull info_name)
+ {
+ additional_infos_.append(info_name);
+ return *(Self *)this;
+ }
+
+ template<typename... Args> Self &additional_info(StringRefNull info_name, Args... args)
+ {
+ additional_info(info_name);
+ additional_info(args...);
return *(Self *)this;
}
@@ -818,6 +806,7 @@ struct ShaderCreateInfo {
TEST_EQUAL(*this, b, builtins_);
TEST_EQUAL(*this, b, vertex_source_generated);
TEST_EQUAL(*this, b, fragment_source_generated);
+ TEST_EQUAL(*this, b, compute_source_generated);
TEST_EQUAL(*this, b, typedef_source_generated);
TEST_VECTOR_EQUAL(*this, b, vertex_inputs_);
TEST_EQUAL(*this, b, geometry_layout_);
diff --git a/source/blender/gpu/intern/gpu_shader_dependency.cc b/source/blender/gpu/intern/gpu_shader_dependency.cc
index d91e15243f3..2c59cb6e501 100644
--- a/source/blender/gpu/intern/gpu_shader_dependency.cc
+++ b/source/blender/gpu/intern/gpu_shader_dependency.cc
@@ -11,6 +11,7 @@
#include <algorithm>
#include <iomanip>
#include <iostream>
+#include <regex>
#include <sstream>
#include "BLI_ghash.h"
@@ -42,7 +43,7 @@ struct GPUSource {
StringRefNull source;
Vector<GPUSource *> dependencies;
bool dependencies_init = false;
- shader::BuiltinBits builtins = (shader::BuiltinBits)0;
+ shader::BuiltinBits builtins = shader::BuiltinBits::NONE;
std::string processed_source;
GPUSource(const char *path,
@@ -54,46 +55,45 @@ struct GPUSource {
/* Scan for builtins. */
/* FIXME: This can trigger false positive caused by disabled #if blocks. */
/* TODO(fclem): Could be made faster by scanning once. */
- if (source.find("gl_FragCoord", 0)) {
+ if (source.find("gl_FragCoord", 0) != StringRef::not_found) {
builtins |= shader::BuiltinBits::FRAG_COORD;
}
- if (source.find("gl_FrontFacing", 0)) {
+ if (source.find("gl_FrontFacing", 0) != StringRef::not_found) {
builtins |= shader::BuiltinBits::FRONT_FACING;
}
- if (source.find("gl_GlobalInvocationID", 0)) {
+ if (source.find("gl_GlobalInvocationID", 0) != StringRef::not_found) {
builtins |= shader::BuiltinBits::GLOBAL_INVOCATION_ID;
}
- if (source.find("gl_InstanceID", 0)) {
+ if (source.find("gl_InstanceID", 0) != StringRef::not_found) {
builtins |= shader::BuiltinBits::INSTANCE_ID;
}
- if (source.find("gl_LocalInvocationID", 0)) {
+ if (source.find("gl_LocalInvocationID", 0) != StringRef::not_found) {
builtins |= shader::BuiltinBits::LOCAL_INVOCATION_ID;
}
- if (source.find("gl_LocalInvocationIndex", 0)) {
+ if (source.find("gl_LocalInvocationIndex", 0) != StringRef::not_found) {
builtins |= shader::BuiltinBits::LOCAL_INVOCATION_INDEX;
}
- if (source.find("gl_NumWorkGroup", 0)) {
+ if (source.find("gl_NumWorkGroup", 0) != StringRef::not_found) {
builtins |= shader::BuiltinBits::NUM_WORK_GROUP;
}
- if (source.find("gl_PointCoord", 0)) {
+ if (source.find("gl_PointCoord", 0) != StringRef::not_found) {
builtins |= shader::BuiltinBits::POINT_COORD;
}
- if (source.find("gl_PointSize", 0)) {
+ if (source.find("gl_PointSize", 0) != StringRef::not_found) {
builtins |= shader::BuiltinBits::POINT_SIZE;
}
- if (source.find("gl_PrimitiveID", 0)) {
+ if (source.find("gl_PrimitiveID", 0) != StringRef::not_found) {
builtins |= shader::BuiltinBits::PRIMITIVE_ID;
}
- if (source.find("gl_VertexID", 0)) {
+ if (source.find("gl_VertexID", 0) != StringRef::not_found) {
builtins |= shader::BuiltinBits::VERTEX_ID;
}
- if (source.find("gl_WorkGroupID", 0)) {
+ if (source.find("gl_WorkGroupID", 0) != StringRef::not_found) {
builtins |= shader::BuiltinBits::WORK_GROUP_ID;
}
- if (source.find("gl_WorkGroupSize", 0)) {
+ if (source.find("gl_WorkGroupSize", 0) != StringRef::not_found) {
builtins |= shader::BuiltinBits::WORK_GROUP_SIZE;
}
-
/* TODO(fclem): We could do that at compile time. */
/* Limit to shared header files to avoid the temptation to use C++ syntax in .glsl files. */
if (filename.endswith(".h") || filename.endswith(".hh")) {
@@ -101,6 +101,18 @@ struct GPUSource {
quote_preprocess();
}
else {
+ if (source.find("'") != StringRef::not_found) {
+ char_literals_preprocess();
+ }
+ if (source.find("drw_print") != StringRef::not_found) {
+ string_preprocess();
+ }
+ if ((source.find("drw_debug_") != StringRef::not_found) &&
+ /* Avoid these two files where it makes no sense to add the dependency. */
+ (filename != "common_debug_draw_lib.glsl" &&
+ filename != "draw_debug_draw_display_vert.glsl")) {
+ builtins |= shader::BuiltinBits::USE_DEBUG_DRAW;
+ }
check_no_quotes();
}
@@ -522,6 +534,217 @@ struct GPUSource {
}
}
+ void char_literals_preprocess()
+ {
+ const StringRefNull input = source;
+ std::stringstream output;
+ int64_t cursor = -1;
+ int64_t last_pos = 0;
+
+ while (true) {
+ cursor = find_token(input, '\'', cursor + 1);
+ if (cursor == -1) {
+ break;
+ }
+ /* Output anything between 2 print statement. */
+ output << input.substr(last_pos, cursor - last_pos);
+
+ /* Extract string. */
+ int64_t char_start = cursor + 1;
+ int64_t char_end = find_token(input, '\'', char_start);
+ CHECK(char_end, input, cursor, "Malformed char literal. Missing ending `'`.");
+
+ StringRef input_char = input.substr(char_start, char_end - char_start);
+ if (input_char.size() == 0) {
+ CHECK(-1, input, cursor, "Malformed char literal. Empty character constant");
+ }
+
+ uint8_t char_value = input_char[0];
+
+ if (input_char[0] == '\\') {
+ if (input_char[1] == 'n') {
+ char_value = '\n';
+ }
+ else {
+ CHECK(-1, input, cursor, "Unsupported escaped character");
+ }
+ }
+ else {
+ if (input_char.size() > 1) {
+ CHECK(-1, input, cursor, "Malformed char literal. Multi-character character constant");
+ }
+ }
+
+ char hex[8];
+ SNPRINTF(hex, "0x%.2Xu", char_value);
+ output << hex;
+
+ cursor = last_pos = char_end + 1;
+ }
+ /* If nothing has been changed, do not allocate processed_source. */
+ if (last_pos == 0) {
+ return;
+ }
+
+ if (last_pos != 0) {
+ output << input.substr(last_pos);
+ }
+ processed_source = output.str();
+ source = processed_source.c_str();
+ }
+
+ /* Replace print(string) by equivalent drw_print_char4() sequence. */
+ void string_preprocess()
+ {
+ const StringRefNull input = source;
+ std::stringstream output;
+ int64_t cursor = -1;
+ int64_t last_pos = 0;
+
+ while (true) {
+ cursor = find_keyword(input, "drw_print", cursor + 1);
+ if (cursor == -1) {
+ break;
+ }
+
+ bool do_endl = false;
+ StringRef func = input.substr(cursor);
+ if (func.startswith("drw_print(")) {
+ do_endl = true;
+ }
+ else if (func.startswith("drw_print_no_endl(")) {
+ do_endl = false;
+ }
+ else {
+ continue;
+ }
+
+ /* Output anything between 2 print statement. */
+ output << input.substr(last_pos, cursor - last_pos);
+
+ /* Extract string. */
+ int64_t str_start = input.find('(', cursor) + 1;
+ int64_t semicolon = find_token(input, ';', str_start + 1);
+ CHECK(semicolon, input, cursor, "Malformed print(). Missing `;` .");
+ int64_t str_end = rfind_token(input, ')', semicolon);
+ if (str_end < str_start) {
+ CHECK(-1, input, cursor, "Malformed print(). Missing closing `)` .");
+ }
+
+ std::stringstream sub_output;
+ StringRef input_args = input.substr(str_start, str_end - str_start);
+
+ auto print_string = [&](std::string str) -> int {
+ size_t len_before_pad = str.length();
+ /* Pad string to uint size. */
+ while (str.length() % 4 != 0) {
+ str += " ";
+ }
+ /* Keep everything in one line to not mess with the shader logs. */
+ sub_output << "/* " << str << "*/";
+ sub_output << "drw_print_string_start(" << len_before_pad << ");";
+ for (size_t i = 0; i < len_before_pad; i += 4) {
+ uint8_t chars[4] = {*(reinterpret_cast<const uint8_t *>(str.c_str()) + i + 0),
+ *(reinterpret_cast<const uint8_t *>(str.c_str()) + i + 1),
+ *(reinterpret_cast<const uint8_t *>(str.c_str()) + i + 2),
+ *(reinterpret_cast<const uint8_t *>(str.c_str()) + i + 3)};
+ if (i + 4 > len_before_pad) {
+ chars[len_before_pad - i] = '\0';
+ }
+ char uint_hex[12];
+ SNPRINTF(uint_hex, "0x%.2X%.2X%.2X%.2Xu", chars[3], chars[2], chars[1], chars[0]);
+ sub_output << "drw_print_char4(" << StringRefNull(uint_hex) << ");";
+ }
+ return 0;
+ };
+
+ std::string func_args = input_args;
+ /* Workaround to support function call inside prints. We replace commas by a non control
+ * character `$` in order to use simpler regex later. */
+ bool string_scope = false;
+ int func_scope = 0;
+ for (char &c : func_args) {
+ if (c == '"') {
+ string_scope = !string_scope;
+ }
+ else if (!string_scope) {
+ if (c == '(') {
+ func_scope++;
+ }
+ else if (c == ')') {
+ func_scope--;
+ }
+ else if (c == ',' && func_scope != 0) {
+ c = '$';
+ }
+ }
+ }
+
+ const bool print_as_variable = (input_args[0] != '"') && find_token(input_args, ',') == -1;
+ if (print_as_variable) {
+ /* Variable or expression debugging. */
+ std::string arg = input_args;
+ /* Pad align most values. */
+ while (arg.length() % 4 != 0) {
+ arg += " ";
+ }
+ print_string(arg);
+ print_string("= ");
+ sub_output << "drw_print_value(" << input_args << ");";
+ }
+ else {
+ const std::regex arg_regex(
+ /* String args. */
+ "[\\s]*\"([^\r\n\t\f\v\"]*)\""
+ /* OR. */
+ "|"
+ /* value args. */
+ "([^,]+)");
+ std::smatch args_match;
+ std::string::const_iterator args_search_start(func_args.cbegin());
+ while (std::regex_search(args_search_start, func_args.cend(), args_match, arg_regex)) {
+ args_search_start = args_match.suffix().first;
+ std::string arg_string = args_match[1].str();
+ std::string arg_val = args_match[2].str();
+
+ if (arg_string.empty()) {
+ for (char &c : arg_val) {
+ if (c == '$') {
+ c = ',';
+ }
+ }
+ sub_output << "drw_print_value(" << arg_val << ");";
+ }
+ else {
+ print_string(arg_string);
+ }
+ }
+ }
+
+ if (do_endl) {
+ sub_output << "drw_print_newline();";
+ }
+
+ output << sub_output.str();
+
+ cursor = last_pos = str_end + 1;
+ }
+ /* If nothing has been changed, do not allocate processed_source. */
+ if (last_pos == 0) {
+ return;
+ }
+
+ if (filename != "common_debug_print_lib.glsl") {
+ builtins |= shader::BuiltinBits::USE_DEBUG_PRINT;
+ }
+
+ if (last_pos != 0) {
+ output << input.substr(last_pos);
+ }
+ processed_source = output.str();
+ source = processed_source.c_str();
+ }
+
#undef find_keyword
#undef rfind_keyword
#undef find_token
@@ -537,6 +760,15 @@ struct GPUSource {
this->dependencies_init = true;
int64_t pos = -1;
+ using namespace shader;
+ /* Auto dependency injection for debug capabilities. */
+ if ((builtins & BuiltinBits::USE_DEBUG_DRAW) == BuiltinBits::USE_DEBUG_DRAW) {
+ dependencies.append_non_duplicates(dict.lookup("common_debug_draw_lib.glsl"));
+ }
+ if ((builtins & BuiltinBits::USE_DEBUG_PRINT) == BuiltinBits::USE_DEBUG_PRINT) {
+ dependencies.append_non_duplicates(dict.lookup("common_debug_print_lib.glsl"));
+ }
+
while (true) {
GPUSource *dependency_source = nullptr;
@@ -558,6 +790,7 @@ struct GPUSource {
return 1;
}
}
+
/* Recursive. */
int result = dependency_source->init_dependencies(dict, g_functions);
if (result != 0) {
@@ -583,7 +816,7 @@ struct GPUSource {
shader::BuiltinBits builtins_get() const
{
- shader::BuiltinBits out_builtins = shader::BuiltinBits::NONE;
+ shader::BuiltinBits out_builtins = builtins;
for (auto *dep : dependencies) {
out_builtins |= dep->builtins;
}
@@ -593,7 +826,8 @@ struct GPUSource {
bool is_from_material_library() const
{
return (filename.startswith("gpu_shader_material_") ||
- filename.startswith("gpu_shader_common_")) &&
+ filename.startswith("gpu_shader_common_") ||
+ filename.startswith("gpu_shader_compositor_")) &&
filename.endswith(".glsl");
}
};
diff --git a/source/blender/gpu/intern/gpu_shader_interface.hh b/source/blender/gpu/intern/gpu_shader_interface.hh
index 60344757b43..812244c9b3a 100644
--- a/source/blender/gpu/intern/gpu_shader_interface.hh
+++ b/source/blender/gpu/intern/gpu_shader_interface.hh
@@ -56,6 +56,7 @@ class ShaderInterface {
/** Location of builtin uniforms. Fast access, no lookup needed. */
int32_t builtins_[GPU_NUM_UNIFORMS];
int32_t builtin_blocks_[GPU_NUM_UNIFORM_BLOCKS];
+ int32_t builtin_buffers_[GPU_NUM_STORAGE_BUFFERS];
public:
ShaderInterface();
@@ -116,9 +117,17 @@ class ShaderInterface {
return builtin_blocks_[builtin];
}
+ /* Returns binding position. */
+ inline int32_t ssbo_builtin(const GPUStorageBufferBuiltin builtin) const
+ {
+ BLI_assert(builtin >= 0 && builtin < GPU_NUM_STORAGE_BUFFERS);
+ return builtin_buffers_[builtin];
+ }
+
protected:
static inline const char *builtin_uniform_name(GPUUniformBuiltin u);
static inline const char *builtin_uniform_block_name(GPUUniformBlockBuiltin u);
+ static inline const char *builtin_storage_block_name(GPUStorageBufferBuiltin u);
inline uint32_t set_input_name(ShaderInput *input, char *name, uint32_t name_len) const;
inline void copy_input_name(ShaderInput *input,
@@ -212,6 +221,18 @@ inline const char *ShaderInterface::builtin_uniform_block_name(GPUUniformBlockBu
}
}
+inline const char *ShaderInterface::builtin_storage_block_name(GPUStorageBufferBuiltin u)
+{
+ switch (u) {
+ case GPU_STORAGE_BUFFER_DEBUG_VERTS:
+ return "drw_debug_verts_buf";
+ case GPU_STORAGE_BUFFER_DEBUG_PRINT:
+ return "drw_debug_print_buf";
+ default:
+ return nullptr;
+ }
+}
+
/* Returns string length including '\0' terminator. */
inline uint32_t ShaderInterface::set_input_name(ShaderInput *input,
char *name,
diff --git a/source/blender/gpu/intern/gpu_texture.cc b/source/blender/gpu/intern/gpu_texture.cc
index 9b3ecfea2f8..65daa416cae 100644
--- a/source/blender/gpu/intern/gpu_texture.cc
+++ b/source/blender/gpu/intern/gpu_texture.cc
@@ -641,6 +641,112 @@ eGPUTextureFormat GPU_texture_format(const GPUTexture *tex)
return reinterpret_cast<const Texture *>(tex)->format_get();
}
+const char *GPU_texture_format_description(eGPUTextureFormat texture_format)
+{
+ switch (texture_format) {
+ case GPU_RGBA8UI:
+ return "RGBA8UI";
+ case GPU_RGBA8I:
+ return "RGBA8I";
+ case GPU_RGBA8:
+ return "RGBA8";
+ case GPU_RGBA32UI:
+ return "RGBA32UI";
+ case GPU_RGBA32I:
+ return "RGBA32I";
+ case GPU_RGBA32F:
+ return "RGBA32F";
+ case GPU_RGBA16UI:
+ return "RGBA16UI";
+ case GPU_RGBA16I:
+ return "RGBA16I";
+ case GPU_RGBA16F:
+ return "RGBA16F";
+ case GPU_RGBA16:
+ return "RGBA16";
+ case GPU_RG8UI:
+ return "RG8UI";
+ case GPU_RG8I:
+ return "RG8I";
+ case GPU_RG8:
+ return "RG8";
+ case GPU_RG32UI:
+ return "RG32UI";
+ case GPU_RG32I:
+ return "RG32I";
+ case GPU_RG32F:
+ return "RG32F";
+ case GPU_RG16UI:
+ return "RG16UI";
+ case GPU_RG16I:
+ return "RG16I";
+ case GPU_RG16F:
+ return "RG16F";
+ case GPU_RG16:
+ return "RG16";
+ case GPU_R8UI:
+ return "R8UI";
+ case GPU_R8I:
+ return "R8I";
+ case GPU_R8:
+ return "R8";
+ case GPU_R32UI:
+ return "R32UI";
+ case GPU_R32I:
+ return "R32I";
+ case GPU_R32F:
+ return "R32F";
+ case GPU_R16UI:
+ return "R16UI";
+ case GPU_R16I:
+ return "R16I";
+ case GPU_R16F:
+ return "R16F";
+ case GPU_R16:
+ return "R16";
+
+ /* Special formats texture & render-buffer. */
+ case GPU_RGB10_A2:
+ return "RGB10A2";
+ case GPU_R11F_G11F_B10F:
+ return "R11FG11FB10F";
+ case GPU_DEPTH32F_STENCIL8:
+ return "DEPTH32FSTENCIL8";
+ case GPU_DEPTH24_STENCIL8:
+ return "DEPTH24STENCIL8";
+ case GPU_SRGB8_A8:
+ return "SRGB8A8";
+
+ /* Texture only format */
+ case (GPU_RGB16F):
+ return "RGB16F";
+
+ /* Special formats texture only */
+ case GPU_SRGB8_A8_DXT1:
+ return "SRGB8_A8_DXT1";
+ case GPU_SRGB8_A8_DXT3:
+ return "SRGB8_A8_DXT3";
+ case GPU_SRGB8_A8_DXT5:
+ return "SRGB8_A8_DXT5";
+ case GPU_RGBA8_DXT1:
+ return "RGBA8_DXT1";
+ case GPU_RGBA8_DXT3:
+ return "RGBA8_DXT3";
+ case GPU_RGBA8_DXT5:
+ return "RGBA8_DXT5";
+
+ /* Depth Formats */
+ case GPU_DEPTH_COMPONENT32F:
+ return "DEPTH32F";
+ case GPU_DEPTH_COMPONENT24:
+ return "DEPTH24";
+ case GPU_DEPTH_COMPONENT16:
+ return "DEPTH16";
+ }
+ BLI_assert_unreachable();
+ return "";
+}
+
bool GPU_texture_depth(const GPUTexture *tex)
{
return (reinterpret_cast<const Texture *>(tex)->format_flag_get() & GPU_FORMAT_DEPTH) != 0;
diff --git a/source/blender/gpu/metal/mtl_query.mm b/source/blender/gpu/metal/mtl_query.mm
index dfda0a8de7f..f574140531d 100644
--- a/source/blender/gpu/metal/mtl_query.mm
+++ b/source/blender/gpu/metal/mtl_query.mm
@@ -9,7 +9,7 @@
namespace blender::gpu {
static const size_t VISIBILITY_COUNT_PER_BUFFER = 512;
-/* defined in the documentation but not queryable programmatically:
+/* Defined in the documentation but can't be queried programmatically:
* https://developer.apple.com/documentation/metal/mtlvisibilityresultmode/mtlvisibilityresultmodeboolean?language=objc
*/
static const size_t VISIBILITY_RESULT_SIZE_IN_BYTES = 8;
diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc
index 4869bff2737..6a1577fb907 100644
--- a/source/blender/gpu/opengl/gl_backend.cc
+++ b/source/blender/gpu/opengl/gl_backend.cc
@@ -51,7 +51,12 @@ void GLBackend::platform_init()
os = GPU_OS_UNIX;
#endif
- if (strstr(vendor, "ATI") || strstr(vendor, "AMD")) {
+ if (!vendor) {
+ printf("Warning: No OpenGL vendor detected.\n");
+ device = GPU_DEVICE_UNKNOWN;
+ driver = GPU_DRIVER_ANY;
+ }
+ else if (strstr(vendor, "ATI") || strstr(vendor, "AMD")) {
device = GPU_DEVICE_ATI;
driver = GPU_DRIVER_OFFICIAL;
}
@@ -113,7 +118,7 @@ void GLBackend::platform_init()
}
/* Detect support level */
- if (!GLEW_VERSION_3_3) {
+ if (!(epoxy_gl_version() >= 33)) {
support_level = GPU_SUPPORT_LEVEL_UNSUPPORTED;
}
else {
@@ -243,14 +248,14 @@ static void detect_workarounds()
return;
}
- /* Limit support for GLEW_ARB_base_instance to OpenGL 4.0 and higher. NVIDIA Quadro FX 4800
- * (TeraScale) report that they support GLEW_ARB_base_instance, but the driver does not support
+ /* Limit support for GL_ARB_base_instance to OpenGL 4.0 and higher. NVIDIA Quadro FX 4800
+ * (TeraScale) report that they support GL_ARB_base_instance, but the driver does not support
* GLEW_ARB_draw_indirect as it has an OpenGL3 context what also matches the minimum needed
* requirements.
*
* We use it as a target for glMapBuffer(Range) what is part of the OpenGL 4 API. So better
* disable it when we don't have an OpenGL4 context (See T77657) */
- if (!GLEW_VERSION_4_0) {
+ if (!(epoxy_gl_version() >= 40)) {
GLContext::base_instance_support = false;
}
if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_WIN, GPU_DRIVER_OFFICIAL) &&
@@ -313,7 +318,8 @@ static void detect_workarounds()
/* Limit this fix to older hardware with GL < 4.5. This means Broadwell GPUs are
* covered since they only support GL 4.4 on windows.
* This fixes some issues with workbench anti-aliasing on Win + Intel GPU. (see T76273) */
- if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL) && !GLEW_VERSION_4_5) {
+ if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL) &&
+ !(epoxy_gl_version() >= 45)) {
GLContext::copy_image_support = false;
}
/* Special fix for these specific GPUs.
@@ -328,7 +334,7 @@ static void detect_workarounds()
strstr(renderer, "HD Graphics 2500"))) {
GLContext::texture_cube_map_array_support = false;
}
- /* Maybe not all of these drivers have problems with `GLEW_ARB_base_instance`.
+ /* Maybe not all of these drivers have problems with `GL_ARB_base_instance`.
* But it's hard to test each case.
* We get crashes from some crappy Intel drivers don't work well with shaders created in
* different rendering contexts. */
@@ -353,7 +359,8 @@ static void detect_workarounds()
}
/* There is a bug on older Nvidia GPU where GL_ARB_texture_gather
* is reported to be supported but yield a compile error (see T55802). */
- if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) && !GLEW_VERSION_4_0) {
+ if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) &&
+ !(epoxy_gl_version() >= 40)) {
GLContext::texture_gather_support = false;
}
@@ -457,7 +464,7 @@ float GLContext::derivative_signs[2] = {1.0f, 1.0f};
void GLBackend::capabilities_init()
{
- BLI_assert(GLEW_VERSION_3_3);
+ BLI_assert(epoxy_gl_version() >= 33);
/* Common Capabilities. */
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &GCaps.max_texture_size);
glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &GCaps.max_texture_layers);
@@ -482,9 +489,11 @@ void GLBackend::capabilities_init()
glGetIntegerv(GL_NUM_EXTENSIONS, &GCaps.extensions_len);
GCaps.extension_get = gl_extension_get;
- GCaps.mem_stats_support = GLEW_NVX_gpu_memory_info || GLEW_ATI_meminfo;
- GCaps.shader_image_load_store_support = GLEW_ARB_shader_image_load_store;
- GCaps.compute_shader_support = GLEW_ARB_compute_shader && GLEW_VERSION_4_3;
+ GCaps.mem_stats_support = epoxy_has_gl_extension("GL_NVX_gpu_memory_info") ||
+ epoxy_has_gl_extension("GL_ATI_meminfo");
+ GCaps.shader_image_load_store_support = epoxy_has_gl_extension("GL_ARB_shader_image_load_store");
+ GCaps.compute_shader_support = epoxy_has_gl_extension("GL_ARB_compute_shader") &&
+ epoxy_gl_version() >= 43;
if (GCaps.compute_shader_support) {
glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &GCaps.max_work_group_count[0]);
glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, &GCaps.max_work_group_count[1]);
@@ -496,7 +505,8 @@ void GLBackend::capabilities_init()
&GCaps.max_shader_storage_buffer_bindings);
glGetIntegerv(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, &GCaps.max_compute_shader_storage_blocks);
}
- GCaps.shader_storage_buffer_objects_support = GLEW_ARB_shader_storage_buffer_object;
+ GCaps.shader_storage_buffer_objects_support = epoxy_has_gl_extension(
+ "GL_ARB_shader_storage_buffer_object");
/* GL specific capabilities. */
glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &GLContext::max_texture_3d_size);
glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &GLContext::max_cubemap_size);
@@ -506,25 +516,32 @@ void GLBackend::capabilities_init()
glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &GLContext::max_ssbo_binds);
glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &GLContext::max_ssbo_size);
}
- GLContext::base_instance_support = GLEW_ARB_base_instance;
- GLContext::clear_texture_support = GLEW_ARB_clear_texture;
- GLContext::copy_image_support = GLEW_ARB_copy_image;
- GLContext::debug_layer_support = GLEW_VERSION_4_3 || GLEW_KHR_debug || GLEW_ARB_debug_output;
- GLContext::direct_state_access_support = GLEW_ARB_direct_state_access;
- GLContext::explicit_location_support = GLEW_VERSION_4_3;
- GLContext::geometry_shader_invocations = GLEW_ARB_gpu_shader5;
- GLContext::fixed_restart_index_support = GLEW_ARB_ES3_compatibility;
- GLContext::layered_rendering_support = GLEW_AMD_vertex_shader_layer;
- GLContext::native_barycentric_support = GLEW_AMD_shader_explicit_vertex_parameter;
- GLContext::multi_bind_support = GLEW_ARB_multi_bind;
- GLContext::multi_draw_indirect_support = GLEW_ARB_multi_draw_indirect;
- GLContext::shader_draw_parameters_support = GLEW_ARB_shader_draw_parameters;
- GLContext::stencil_texturing_support = GLEW_VERSION_4_3;
- 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;
+ GLContext::base_instance_support = epoxy_has_gl_extension("GL_ARB_base_instance");
+ GLContext::clear_texture_support = epoxy_has_gl_extension("GL_ARB_clear_texture");
+ GLContext::copy_image_support = epoxy_has_gl_extension("GL_ARB_copy_image");
+ GLContext::debug_layer_support = epoxy_gl_version() >= 43 ||
+ epoxy_has_gl_extension("GL_KHR_debug") ||
+ epoxy_has_gl_extension("GL_ARB_debug_output");
+ GLContext::direct_state_access_support = epoxy_has_gl_extension("GL_ARB_direct_state_access");
+ GLContext::explicit_location_support = epoxy_gl_version() >= 43;
+ GLContext::geometry_shader_invocations = epoxy_has_gl_extension("GL_ARB_gpu_shader5");
+ GLContext::fixed_restart_index_support = epoxy_has_gl_extension("GL_ARB_ES3_compatibility");
+ GLContext::layered_rendering_support = epoxy_has_gl_extension("GL_AMD_vertex_shader_layer");
+ GLContext::native_barycentric_support = epoxy_has_gl_extension(
+ "GL_AMD_shader_explicit_vertex_parameter");
+ GLContext::multi_bind_support = epoxy_has_gl_extension("GL_ARB_multi_bind");
+ GLContext::multi_draw_indirect_support = epoxy_has_gl_extension("GL_ARB_multi_draw_indirect");
+ GLContext::shader_draw_parameters_support = epoxy_has_gl_extension(
+ "GL_ARB_shader_draw_parameters");
+ GLContext::stencil_texturing_support = epoxy_gl_version() >= 43;
+ GLContext::texture_cube_map_array_support = epoxy_has_gl_extension(
+ "GL_ARB_texture_cube_map_array");
+ GLContext::texture_filter_anisotropic_support = epoxy_has_gl_extension(
+ "GL_EXT_texture_filter_anisotropic");
+ GLContext::texture_gather_support = epoxy_has_gl_extension("GL_ARB_texture_gather");
+ GLContext::texture_storage_support = epoxy_gl_version() >= 43;
+ GLContext::vertex_attrib_binding_support = epoxy_has_gl_extension(
+ "GL_ARB_vertex_attrib_binding");
detect_workarounds();
diff --git a/source/blender/gpu/opengl/gl_backend.hh b/source/blender/gpu/opengl/gl_backend.hh
index e425b87afe8..8646d94e2fd 100644
--- a/source/blender/gpu/opengl/gl_backend.hh
+++ b/source/blender/gpu/opengl/gl_backend.hh
@@ -133,11 +133,11 @@ class GLBackend : public GPUBackend {
dynamic_cast<GLStorageBuf *>(indirect_buf)->bind_as(GL_DISPATCH_INDIRECT_BUFFER);
/* This barrier needs to be here as it only work on the currently bound indirect buffer. */
- glMemoryBarrier(GL_DRAW_INDIRECT_BUFFER);
+ glMemoryBarrier(GL_COMMAND_BARRIER_BIT);
glDispatchComputeIndirect((GLintptr)0);
/* Unbind. */
- glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
+ glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0);
}
/* Render Frame Coordination */
diff --git a/source/blender/gpu/opengl/gl_batch.cc b/source/blender/gpu/opengl/gl_batch.cc
index fde2a53bb0f..4ec86b98cbe 100644
--- a/source/blender/gpu/opengl/gl_batch.cc
+++ b/source/blender/gpu/opengl/gl_batch.cc
@@ -18,6 +18,7 @@
#include "gl_debug.hh"
#include "gl_index_buffer.hh"
#include "gl_primitive.hh"
+#include "gl_storage_buffer.hh"
#include "gl_vertex_array.hh"
#include "gl_batch.hh"
@@ -326,4 +327,27 @@ void GLBatch::draw(int v_first, int v_count, int i_first, int i_count)
}
}
+void GLBatch::draw_indirect(GPUStorageBuf *indirect_buf)
+{
+ GL_CHECK_RESOURCES("Batch");
+
+ this->bind(0);
+
+ dynamic_cast<GLStorageBuf *>(unwrap(indirect_buf))->bind_as(GL_DRAW_INDIRECT_BUFFER);
+ /* This barrier needs to be here as it only work on the currently bound indirect buffer. */
+ glMemoryBarrier(GL_COMMAND_BARRIER_BIT);
+
+ GLenum gl_type = to_gl(prim_type);
+ if (elem) {
+ const GLIndexBuf *el = this->elem_();
+ GLenum index_type = to_gl(el->index_type_);
+ glDrawElementsIndirect(gl_type, index_type, (GLvoid *)nullptr);
+ }
+ else {
+ glDrawArraysIndirect(gl_type, (GLvoid *)nullptr);
+ }
+ /* Unbind. */
+ glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
+}
+
/** \} */
diff --git a/source/blender/gpu/opengl/gl_batch.hh b/source/blender/gpu/opengl/gl_batch.hh
index 1a18572c683..0d7ea7c4a9e 100644
--- a/source/blender/gpu/opengl/gl_batch.hh
+++ b/source/blender/gpu/opengl/gl_batch.hh
@@ -17,8 +17,6 @@
#include "gl_index_buffer.hh"
#include "gl_vertex_buffer.hh"
-#include "glew-mx.h"
-
namespace blender {
namespace gpu {
@@ -93,6 +91,7 @@ class GLBatch : public Batch {
public:
void draw(int v_first, int v_count, int i_first, int i_count) override;
+ void draw_indirect(GPUStorageBuf *indirect_buf) override;
void bind(int i_first);
/* Convenience getters. */
diff --git a/source/blender/gpu/opengl/gl_context.cc b/source/blender/gpu/opengl/gl_context.cc
index e6af126e9cd..448e10fb0ed 100644
--- a/source/blender/gpu/opengl/gl_context.cc
+++ b/source/blender/gpu/opengl/gl_context.cc
@@ -304,12 +304,12 @@ void GLContext::vao_cache_unregister(GLVaoCache *cache)
void GLContext::memory_statistics_get(int *r_total_mem, int *r_free_mem)
{
/* TODO(merwin): use Apple's platform API to get this info. */
- if (GLEW_NVX_gpu_memory_info) {
+ if (epoxy_has_gl_extension("GL_NVX_gpu_memory_info")) {
/* Returned value in Kb. */
glGetIntegerv(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, r_total_mem);
glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, r_free_mem);
}
- else if (GLEW_ATI_meminfo) {
+ else if (epoxy_has_gl_extension("GL_ATI_meminfo")) {
int stats[4];
glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, stats);
diff --git a/source/blender/gpu/opengl/gl_context.hh b/source/blender/gpu/opengl/gl_context.hh
index 234bc712513..2f8c2b762f8 100644
--- a/source/blender/gpu/opengl/gl_context.hh
+++ b/source/blender/gpu/opengl/gl_context.hh
@@ -16,8 +16,6 @@
#include "gl_state.hh"
-#include "glew-mx.h"
-
#include <mutex>
namespace blender {
diff --git a/source/blender/gpu/opengl/gl_debug.cc b/source/blender/gpu/opengl/gl_debug.cc
index 79b28642a67..4c9f766c93c 100644
--- a/source/blender/gpu/opengl/gl_debug.cc
+++ b/source/blender/gpu/opengl/gl_debug.cc
@@ -19,8 +19,6 @@
#include "CLG_log.h"
-#include "glew-mx.h"
-
#include "gl_context.hh"
#include "gl_uniform_buffer.hh"
@@ -138,8 +136,8 @@ void init_gl_callbacks()
char msg[256] = "";
const char format[] = "Successfully hooked OpenGL debug callback using %s";
- if (GLEW_VERSION_4_3 || GLEW_KHR_debug) {
- SNPRINTF(msg, format, GLEW_VERSION_4_3 ? "OpenGL 4.3" : "KHR_debug extension");
+ if (epoxy_gl_version() >= 43 || epoxy_has_gl_extension("GL_KHR_debug")) {
+ SNPRINTF(msg, format, epoxy_gl_version() >= 43 ? "OpenGL 4.3" : "KHR_debug extension");
glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback((GLDEBUGPROC)debug_callback, nullptr);
@@ -151,7 +149,7 @@ void init_gl_callbacks()
-1,
msg);
}
- else if (GLEW_ARB_debug_output) {
+ else if (epoxy_has_gl_extension("GL_ARB_debug_output")) {
SNPRINTF(msg, format, "ARB_debug_output");
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallbackARB((GLDEBUGPROCARB)debug_callback, nullptr);
@@ -327,7 +325,8 @@ static const char *to_str_suffix(GLenum type)
void object_label(GLenum type, GLuint object, const char *name)
{
- if ((G.debug & G_DEBUG_GPU) && (GLEW_VERSION_4_3 || GLEW_KHR_debug)) {
+ if ((G.debug & G_DEBUG_GPU) &&
+ (epoxy_gl_version() >= 43 || epoxy_has_gl_extension("GL_KHR_debug"))) {
char label[64];
SNPRINTF(label, "%s%s%s", to_str_prefix(type), name, to_str_suffix(type));
/* Small convenience for caller. */
@@ -365,7 +364,8 @@ namespace blender::gpu {
void GLContext::debug_group_begin(const char *name, int index)
{
- if ((G.debug & G_DEBUG_GPU) && (GLEW_VERSION_4_3 || GLEW_KHR_debug)) {
+ if ((G.debug & G_DEBUG_GPU) &&
+ (epoxy_gl_version() >= 43 || epoxy_has_gl_extension("GL_KHR_debug"))) {
/* Add 10 to avoid collision with other indices from other possible callback layers. */
index += 10;
glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, index, -1, name);
@@ -374,7 +374,8 @@ void GLContext::debug_group_begin(const char *name, int index)
void GLContext::debug_group_end()
{
- if ((G.debug & G_DEBUG_GPU) && (GLEW_VERSION_4_3 || GLEW_KHR_debug)) {
+ if ((G.debug & G_DEBUG_GPU) &&
+ (epoxy_gl_version() >= 43 || epoxy_has_gl_extension("GL_KHR_debug"))) {
glPopDebugGroup();
}
}
diff --git a/source/blender/gpu/opengl/gl_debug.hh b/source/blender/gpu/opengl/gl_debug.hh
index e24b6f2bb23..b573196216d 100644
--- a/source/blender/gpu/opengl/gl_debug.hh
+++ b/source/blender/gpu/opengl/gl_debug.hh
@@ -8,8 +8,6 @@
#include "gl_context.hh"
-#include "glew-mx.h"
-
/* Manual line breaks for readability. */
/* clang-format off */
#define _VA_ARG_LIST1(t) t
diff --git a/source/blender/gpu/opengl/gl_framebuffer.hh b/source/blender/gpu/opengl/gl_framebuffer.hh
index 2dc0936d0fe..8ee04a584bd 100644
--- a/source/blender/gpu/opengl/gl_framebuffer.hh
+++ b/source/blender/gpu/opengl/gl_framebuffer.hh
@@ -11,8 +11,6 @@
#include "MEM_guardedalloc.h"
-#include "glew-mx.h"
-
#include "gpu_framebuffer_private.hh"
namespace blender::gpu {
diff --git a/source/blender/gpu/opengl/gl_immediate.hh b/source/blender/gpu/opengl/gl_immediate.hh
index eb94dc20e21..5c6ff510cef 100644
--- a/source/blender/gpu/opengl/gl_immediate.hh
+++ b/source/blender/gpu/opengl/gl_immediate.hh
@@ -11,8 +11,6 @@
#include "MEM_guardedalloc.h"
-#include "glew-mx.h"
-
#include "gpu_immediate_private.hh"
namespace blender::gpu {
diff --git a/source/blender/gpu/opengl/gl_index_buffer.hh b/source/blender/gpu/opengl/gl_index_buffer.hh
index 8a10884d48b..d9bd85cefb3 100644
--- a/source/blender/gpu/opengl/gl_index_buffer.hh
+++ b/source/blender/gpu/opengl/gl_index_buffer.hh
@@ -11,7 +11,7 @@
#include "gpu_index_buffer_private.hh"
-#include "glew-mx.h"
+#include <epoxy/gl.h>
namespace blender::gpu {
@@ -35,9 +35,11 @@ class GLIndexBuf : public IndexBuf {
{
additional_vertex_offset += index_start_;
if (index_type_ == GPU_INDEX_U32) {
- return (GLuint *)0 + additional_vertex_offset;
+ return reinterpret_cast<void *>(static_cast<intptr_t>(additional_vertex_offset) *
+ sizeof(GLuint));
}
- return (GLushort *)0 + additional_vertex_offset;
+ return reinterpret_cast<void *>(static_cast<intptr_t>(additional_vertex_offset) *
+ sizeof(GLushort));
}
GLuint restart_index() const
diff --git a/source/blender/gpu/opengl/gl_primitive.hh b/source/blender/gpu/opengl/gl_primitive.hh
index 2a8590e8b3e..c4c7734a2cd 100644
--- a/source/blender/gpu/opengl/gl_primitive.hh
+++ b/source/blender/gpu/opengl/gl_primitive.hh
@@ -13,8 +13,6 @@
#include "GPU_primitive.h"
-#include "glew-mx.h"
-
namespace blender::gpu {
static inline GLenum to_gl(GPUPrimType prim_type)
diff --git a/source/blender/gpu/opengl/gl_query.hh b/source/blender/gpu/opengl/gl_query.hh
index e15a2584e07..a851ab4ecdd 100644
--- a/source/blender/gpu/opengl/gl_query.hh
+++ b/source/blender/gpu/opengl/gl_query.hh
@@ -11,7 +11,7 @@
#include "gpu_query.hh"
-#include "glew-mx.h"
+#include <epoxy/gl.h>
namespace blender::gpu {
diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc
index ccdf10c1ed2..a08019cc707 100644
--- a/source/blender/gpu/opengl/gl_shader.cc
+++ b/source/blender/gpu/opengl/gl_shader.cc
@@ -545,7 +545,7 @@ std::string GLShader::vertex_interface_declare(const ShaderCreateInfo &info) con
if (!GLContext::native_barycentric_support) {
/* Disabled or unsupported. */
}
- else if (GLEW_AMD_shader_explicit_vertex_parameter) {
+ else if (epoxy_has_gl_extension("GL_AMD_shader_explicit_vertex_parameter")) {
/* Need this for stable barycentric. */
ss << "flat out vec4 gpu_pos_flat;\n";
ss << "out vec4 gpu_pos;\n";
@@ -581,7 +581,7 @@ std::string GLShader::fragment_interface_declare(const ShaderCreateInfo &info) c
ss << "noperspective in vec3 gpu_BaryCoordNoPersp;\n";
ss << "#define gpu_position_at_vertex(v) gpu_pos[v]\n";
}
- else if (GLEW_AMD_shader_explicit_vertex_parameter) {
+ else if (epoxy_has_gl_extension("GL_AMD_shader_explicit_vertex_parameter")) {
std::cout << "native" << std::endl;
/* NOTE(fclem): This won't work with geometry shader. Hopefully, we don't need geometry
* shader workaround if this extension/feature is detected. */
@@ -612,7 +612,7 @@ std::string GLShader::fragment_interface_declare(const ShaderCreateInfo &info) c
if (info.early_fragment_test_) {
ss << "layout(early_fragment_tests) in;\n";
}
- if (GLEW_ARB_conservative_depth) {
+ if (epoxy_has_gl_extension("GL_ARB_conservative_depth")) {
ss << "layout(" << to_string(info.depth_write_) << ") out float gl_FragDepth;\n";
}
ss << "\n/* Outputs. */\n";
@@ -805,7 +805,7 @@ static char *glsl_patch_default_get()
size_t slen = 0;
/* Version need to go first. */
- if (GLEW_VERSION_4_3) {
+ if (epoxy_gl_version() >= 43) {
STR_CONCAT(patch, slen, "#version 430\n");
}
else {
@@ -816,8 +816,8 @@ static char *glsl_patch_default_get()
* don't use an extension for something already available! */
if (GLContext::texture_gather_support) {
STR_CONCAT(patch, slen, "#extension GL_ARB_texture_gather: enable\n");
- /* Some drivers don't agree on GLEW_ARB_texture_gather and the actual support in the
- * shader so double check the preprocessor define (see T56544). */
+ /* Some drivers don't agree on epoxy_has_gl_extension("GL_ARB_texture_gather") and the actual
+ * support in the shader so double check the preprocessor define (see T56544). */
STR_CONCAT(patch, slen, "#ifdef GL_ARB_texture_gather\n");
STR_CONCAT(patch, slen, "# define GPU_ARB_texture_gather\n");
STR_CONCAT(patch, slen, "#endif\n");
@@ -835,7 +835,7 @@ static char *glsl_patch_default_get()
STR_CONCAT(patch, slen, "#extension GL_ARB_texture_cube_map_array : enable\n");
STR_CONCAT(patch, slen, "#define GPU_ARB_texture_cube_map_array\n");
}
- if (GLEW_ARB_conservative_depth) {
+ if (epoxy_has_gl_extension("GL_ARB_conservative_depth")) {
STR_CONCAT(patch, slen, "#extension GL_ARB_conservative_depth : enable\n");
}
if (GPU_shader_image_load_store_support()) {
diff --git a/source/blender/gpu/opengl/gl_shader.hh b/source/blender/gpu/opengl/gl_shader.hh
index 9c21d0c6230..2774b24cdbe 100644
--- a/source/blender/gpu/opengl/gl_shader.hh
+++ b/source/blender/gpu/opengl/gl_shader.hh
@@ -9,7 +9,7 @@
#include "MEM_guardedalloc.h"
-#include "glew-mx.h"
+#include <epoxy/gl.h>
#include "gpu_shader_create_info.hh"
#include "gpu_shader_private.hh"
diff --git a/source/blender/gpu/opengl/gl_shader_interface.cc b/source/blender/gpu/opengl/gl_shader_interface.cc
index 1b3ab2941a8..4623a14dab3 100644
--- a/source/blender/gpu/opengl/gl_shader_interface.cc
+++ b/source/blender/gpu/opengl/gl_shader_interface.cc
@@ -318,6 +318,13 @@ GLShaderInterface::GLShaderInterface(GLuint program)
builtin_blocks_[u] = (block != nullptr) ? block->binding : -1;
}
+ /* Builtin Storage Buffers */
+ for (int32_t u_int = 0; u_int < GPU_NUM_STORAGE_BUFFERS; u_int++) {
+ GPUStorageBufferBuiltin u = static_cast<GPUStorageBufferBuiltin>(u_int);
+ const ShaderInput *block = this->ssbo_get(builtin_storage_block_name(u));
+ builtin_buffers_[u] = (block != nullptr) ? block->binding : -1;
+ }
+
MEM_freeN(uniforms_from_blocks);
/* Resize name buffer to save some memory. */
@@ -481,6 +488,13 @@ GLShaderInterface::GLShaderInterface(GLuint program, const shader::ShaderCreateI
builtin_blocks_[u] = (block != nullptr) ? block->binding : -1;
}
+ /* Builtin Storage Buffers */
+ for (int32_t u_int = 0; u_int < GPU_NUM_STORAGE_BUFFERS; u_int++) {
+ GPUStorageBufferBuiltin u = static_cast<GPUStorageBufferBuiltin>(u_int);
+ const ShaderInput *block = this->ssbo_get(builtin_storage_block_name(u));
+ builtin_buffers_[u] = (block != nullptr) ? block->binding : -1;
+ }
+
this->sort_inputs();
// this->debug_print();
diff --git a/source/blender/gpu/opengl/gl_shader_interface.hh b/source/blender/gpu/opengl/gl_shader_interface.hh
index e3dce31758b..e31879d4340 100644
--- a/source/blender/gpu/opengl/gl_shader_interface.hh
+++ b/source/blender/gpu/opengl/gl_shader_interface.hh
@@ -16,8 +16,6 @@
#include "BLI_vector.hh"
-#include "glew-mx.h"
-
#include "gpu_shader_create_info.hh"
#include "gpu_shader_interface.hh"
diff --git a/source/blender/gpu/opengl/gl_state.cc b/source/blender/gpu/opengl/gl_state.cc
index 8be4ac29af6..46422124112 100644
--- a/source/blender/gpu/opengl/gl_state.cc
+++ b/source/blender/gpu/opengl/gl_state.cc
@@ -563,14 +563,14 @@ void GLStateManager::image_bind(Texture *tex_, int unit)
}
images_[unit] = tex->tex_id_;
formats_[unit] = to_gl_internal_format(tex->format_);
- tex->is_bound_ = true;
+ tex->is_bound_image_ = true;
dirty_image_binds_ |= 1ULL << unit;
}
void GLStateManager::image_unbind(Texture *tex_)
{
GLTexture *tex = static_cast<GLTexture *>(tex_);
- if (!tex->is_bound_) {
+ if (!tex->is_bound_image_) {
return;
}
@@ -581,7 +581,7 @@ void GLStateManager::image_unbind(Texture *tex_)
dirty_image_binds_ |= 1ULL << i;
}
}
- tex->is_bound_ = false;
+ tex->is_bound_image_ = false;
}
void GLStateManager::image_unbind_all()
diff --git a/source/blender/gpu/opengl/gl_state.hh b/source/blender/gpu/opengl/gl_state.hh
index f29eefbca82..74c68e51755 100644
--- a/source/blender/gpu/opengl/gl_state.hh
+++ b/source/blender/gpu/opengl/gl_state.hh
@@ -13,7 +13,7 @@
#include "gpu_state_private.hh"
-#include "glew-mx.h"
+#include <epoxy/gl.h>
namespace blender {
namespace gpu {
diff --git a/source/blender/gpu/opengl/gl_storage_buffer.cc b/source/blender/gpu/opengl/gl_storage_buffer.cc
index 4592adc3a61..83a56edcf04 100644
--- a/source/blender/gpu/opengl/gl_storage_buffer.cc
+++ b/source/blender/gpu/opengl/gl_storage_buffer.cc
@@ -72,7 +72,7 @@ void GLStorageBuf::bind(int slot)
if (slot >= GLContext::max_ssbo_binds) {
fprintf(
stderr,
- "Error: Trying to bind \"%s\" ssbo to slot %d which is above the reported limit of %d.",
+ "Error: Trying to bind \"%s\" ssbo to slot %d which is above the reported limit of %d.\n",
name_,
slot,
GLContext::max_ssbo_binds);
diff --git a/source/blender/gpu/opengl/gl_storage_buffer.hh b/source/blender/gpu/opengl/gl_storage_buffer.hh
index 96052fe0065..ffe2de12451 100644
--- a/source/blender/gpu/opengl/gl_storage_buffer.hh
+++ b/source/blender/gpu/opengl/gl_storage_buffer.hh
@@ -11,8 +11,6 @@
#include "gpu_storage_buffer_private.hh"
-#include "glew-mx.h"
-
namespace blender {
namespace gpu {
diff --git a/source/blender/gpu/opengl/gl_texture.cc b/source/blender/gpu/opengl/gl_texture.cc
index cfb3184c4a5..2ce205353a3 100644
--- a/source/blender/gpu/opengl/gl_texture.cc
+++ b/source/blender/gpu/opengl/gl_texture.cc
@@ -40,6 +40,7 @@ GLTexture::~GLTexture()
if (ctx != nullptr && is_bound_) {
/* This avoid errors when the texture is still inside the bound texture array. */
ctx->state_manager->texture_unbind(this);
+ ctx->state_manager->image_unbind(this);
}
GLContext::tex_free(tex_id_);
}
diff --git a/source/blender/gpu/opengl/gl_texture.hh b/source/blender/gpu/opengl/gl_texture.hh
index aeb9fc0e6b7..b7d72455c25 100644
--- a/source/blender/gpu/opengl/gl_texture.hh
+++ b/source/blender/gpu/opengl/gl_texture.hh
@@ -13,8 +13,6 @@
#include "gpu_texture_private.hh"
-#include "glew-mx.h"
-
struct GPUFrameBuffer;
namespace blender {
@@ -37,6 +35,8 @@ class GLTexture : public Texture {
/** True if this texture is bound to at least one texture unit. */
/* TODO(fclem): How do we ensure thread safety here? */
bool is_bound_ = false;
+ /** Same as is_bound_ but for image slots. */
+ bool is_bound_image_ = false;
/** True if pixels in the texture have been initialized. */
bool has_pixels_ = false;
diff --git a/source/blender/gpu/opengl/gl_uniform_buffer.cc b/source/blender/gpu/opengl/gl_uniform_buffer.cc
index e58cea9de43..022fbcfdf29 100644
--- a/source/blender/gpu/opengl/gl_uniform_buffer.cc
+++ b/source/blender/gpu/opengl/gl_uniform_buffer.cc
@@ -65,11 +65,12 @@ void GLUniformBuf::update(const void *data)
void GLUniformBuf::bind(int slot)
{
if (slot >= GLContext::max_ubo_binds) {
- fprintf(stderr,
- "Error: Trying to bind \"%s\" ubo to slot %d which is above the reported limit of %d.",
- name_,
- slot,
- GLContext::max_ubo_binds);
+ fprintf(
+ stderr,
+ "Error: Trying to bind \"%s\" ubo to slot %d which is above the reported limit of %d.\n",
+ name_,
+ slot,
+ GLContext::max_ubo_binds);
return;
}
diff --git a/source/blender/gpu/opengl/gl_uniform_buffer.hh b/source/blender/gpu/opengl/gl_uniform_buffer.hh
index 8d945a8e7dc..e602532dc5a 100644
--- a/source/blender/gpu/opengl/gl_uniform_buffer.hh
+++ b/source/blender/gpu/opengl/gl_uniform_buffer.hh
@@ -11,8 +11,6 @@
#include "gpu_uniform_buffer_private.hh"
-#include "glew-mx.h"
-
namespace blender {
namespace gpu {
diff --git a/source/blender/gpu/opengl/gl_vertex_array.hh b/source/blender/gpu/opengl/gl_vertex_array.hh
index d1d6c5604b5..4f417beed29 100644
--- a/source/blender/gpu/opengl/gl_vertex_array.hh
+++ b/source/blender/gpu/opengl/gl_vertex_array.hh
@@ -7,8 +7,6 @@
#pragma once
-#include "glew-mx.h"
-
#include "GPU_batch.h"
#include "gl_shader_interface.hh"
diff --git a/source/blender/gpu/opengl/gl_vertex_buffer.hh b/source/blender/gpu/opengl/gl_vertex_buffer.hh
index e0a21587b60..deb966961f2 100644
--- a/source/blender/gpu/opengl/gl_vertex_buffer.hh
+++ b/source/blender/gpu/opengl/gl_vertex_buffer.hh
@@ -9,8 +9,6 @@
#include "MEM_guardedalloc.h"
-#include "glew-mx.h"
-
#include "GPU_texture.h"
#include "gpu_vertex_buffer_private.hh"
diff --git a/source/blender/gpu/shaders/common/gpu_shader_common_color_utils.glsl b/source/blender/gpu/shaders/common/gpu_shader_common_color_utils.glsl
index fe89985ae7f..33108d3a989 100644
--- a/source/blender/gpu/shaders/common/gpu_shader_common_color_utils.glsl
+++ b/source/blender/gpu/shaders/common/gpu_shader_common_color_utils.glsl
@@ -140,6 +140,84 @@ void hsl_to_rgb(vec4 hsl, out vec4 outcol)
outcol = vec4((nr - 0.5) * chroma + l, (ng - 0.5) * chroma + l, (nb - 0.5) * chroma + l, hsl.w);
}
+/* ** YCCA to RGBA ** */
+
+void ycca_to_rgba_itu_601(vec4 ycca, out vec4 color)
+{
+ ycca.xyz *= 255.0;
+ ycca.xyz -= vec3(16.0, 128.0, 128.0);
+ color.rgb = mat3(vec3(1.164), 0.0, -0.392, 2.017, 1.596, -0.813, 0.0) * ycca.xyz;
+ color.rgb /= 255.0;
+ color.a = ycca.a;
+}
+
+void ycca_to_rgba_itu_709(vec4 ycca, out vec4 color)
+{
+ ycca.xyz *= 255.0;
+ ycca.xyz -= vec3(16.0, 128.0, 128.0);
+ color.rgb = mat3(vec3(1.164), 0.0, -0.213, 2.115, 1.793, -0.534, 0.0) * ycca.xyz;
+ color.rgb /= 255.0;
+ color.a = ycca.a;
+}
+
+void ycca_to_rgba_jpeg(vec4 ycca, out vec4 color)
+{
+ ycca.xyz *= 255.0;
+ color.rgb = mat3(vec3(1.0), 0.0, -0.34414, 1.772, 1.402, -0.71414, 0.0) * ycca.xyz;
+ color.rgb += vec3(-179.456, 135.45984, -226.816);
+ color.rgb /= 255.0;
+ color.a = ycca.a;
+}
+
+/* ** RGBA to YCCA ** */
+
+void rgba_to_ycca_itu_601(vec4 rgba, out vec4 ycca)
+{
+ rgba.rgb *= 255.0;
+ ycca.xyz = mat3(0.257, -0.148, 0.439, 0.504, -0.291, -0.368, 0.098, 0.439, -0.071) * rgba.rgb;
+ ycca.xyz += vec3(16.0, 128.0, 128.0);
+ ycca.xyz /= 255.0;
+ ycca.a = rgba.a;
+}
+
+void rgba_to_ycca_itu_709(vec4 rgba, out vec4 ycca)
+{
+ rgba.rgb *= 255.0;
+ ycca.xyz = mat3(0.183, -0.101, 0.439, 0.614, -0.338, -0.399, 0.062, 0.439, -0.040) * rgba.rgb;
+ ycca.xyz += vec3(16.0, 128.0, 128.0);
+ ycca.xyz /= 255.0;
+ ycca.a = rgba.a;
+}
+
+void rgba_to_ycca_jpeg(vec4 rgba, out vec4 ycca)
+{
+ rgba.rgb *= 255.0;
+ ycca.xyz = mat3(0.299, -0.16874, 0.5, 0.587, -0.33126, -0.41869, 0.114, 0.5, -0.08131) *
+ rgba.rgb;
+ ycca.xyz += vec3(0.0, 128.0, 128.0);
+ ycca.xyz /= 255.0;
+ ycca.a = rgba.a;
+}
+
+/* ** YUVA to RGBA ** */
+
+void yuva_to_rgba_itu_709(vec4 yuva, out vec4 color)
+{
+ color.rgb = mat3(vec3(1.0), 0.0, -0.21482, 2.12798, 1.28033, -0.38059, 0.0) * yuva.xyz;
+ color.a = yuva.a;
+}
+
+/* ** RGBA to YUVA ** */
+
+void rgba_to_yuva_itu_709(vec4 rgba, out vec4 yuva)
+{
+ yuva.xyz = mat3(0.2126, -0.09991, 0.615, 0.7152, -0.33609, -0.55861, 0.0722, 0.436, -0.05639) *
+ rgba.rgb;
+ yuva.a = rgba.a;
+}
+
+/* ** Alpha Handling ** */
+
void color_alpha_clear(vec4 color, out vec4 result)
{
result = vec4(color.rgb, 1.0);
@@ -147,15 +225,50 @@ void color_alpha_clear(vec4 color, out vec4 result)
void color_alpha_premultiply(vec4 color, out vec4 result)
{
- result = vec4(color.rgb * color.a, 1.0);
+ result = vec4(color.rgb * color.a, color.a);
}
void color_alpha_unpremultiply(vec4 color, out vec4 result)
{
if (color.a == 0.0 || color.a == 1.0) {
- result = vec4(color.rgb, 1.0);
+ result = color;
}
else {
- result = vec4(color.rgb / color.a, 1.0);
+ result = vec4(color.rgb / color.a, color.a);
+ }
+}
+
+float linear_rgb_to_srgb(float color)
+{
+ if (color < 0.0031308) {
+ return (color < 0.0) ? 0.0 : color * 12.92;
+ }
+
+ return 1.055 * pow(color, 1.0 / 2.4) - 0.055;
+}
+
+vec3 linear_rgb_to_srgb(vec3 color)
+{
+ return vec3(
+ linear_rgb_to_srgb(color.r), linear_rgb_to_srgb(color.g), linear_rgb_to_srgb(color.b));
+}
+
+float srgb_to_linear_rgb(float color)
+{
+ if (color < 0.04045) {
+ return (color < 0.0) ? 0.0 : color * (1.0 / 12.92);
}
+
+ return pow((color + 0.055) * (1.0 / 1.055), 2.4);
+}
+
+vec3 srgb_to_linear_rgb(vec3 color)
+{
+ return vec3(
+ srgb_to_linear_rgb(color.r), srgb_to_linear_rgb(color.g), srgb_to_linear_rgb(color.b));
+}
+
+float get_luminance(vec3 color, vec3 luminance_coefficients)
+{
+ return dot(color, luminance_coefficients);
}
diff --git a/source/blender/gpu/shaders/common/gpu_shader_common_curves.glsl b/source/blender/gpu/shaders/common/gpu_shader_common_curves.glsl
index 8948ed77557..db8e114ec7a 100644
--- a/source/blender/gpu/shaders/common/gpu_shader_common_curves.glsl
+++ b/source/blender/gpu/shaders/common/gpu_shader_common_curves.glsl
@@ -95,6 +95,81 @@ void curves_combined_only(float factor,
result = mix(color, result, factor);
}
+/* Contrary to standard tone curve implementations, the film-like implementation tries to preserve
+ * the hue of the colors as much as possible. To understand why this might be a problem, consider
+ * the violet color (0.5, 0.0, 1.0). If this color was to be evaluated at a power curve x^4, the
+ * color will be blue (0.0625, 0.0, 1.0). So the color changes and not just its luminosity, which
+ * is what film-like tone curves tries to avoid.
+ *
+ * First, the channels with the lowest and highest values are identified and evaluated at the
+ * curve. Then, the third channel---the median---is computed while maintaining the original hue of
+ * the color. To do that, we look at the equation for deriving the hue from RGB values. Assuming
+ * the maximum, minimum, and median channels are known, and ignoring the 1/3 period offset of the
+ * hue, the equation is:
+ *
+ * hue = (median - min) / (max - min) [1]
+ *
+ * Since we have the new values for the minimum and maximum after evaluating at the curve, we also
+ * have:
+ *
+ * hue = (new_median - new_min) / (new_max - new_min) [2]
+ *
+ * Since we want the hue to be equivalent, by equating [1] and [2] and rearranging:
+ *
+ * (new_median - new_min) / (new_max - new_min) = (median - min) / (max - min)
+ * new_median - new_min = (new_max - new_min) * (median - min) / (max - min)
+ * new_median = new_min + (new_max - new_min) * (median - min) / (max - min)
+ * new_median = new_min + (median - min) * ((new_max - new_min) / (max - min)) [QED]
+ *
+ * Which gives us the median color that preserves the hue. More intuitively, the median is computed
+ * such that the change in the distance from the median to the minimum is proportional to the
+ * change in the distance from the minimum to the maximum. Finally, each of the new minimum,
+ * maximum, and median values are written to the color channel that they were originally extracted
+ * from. */
+void curves_film_like(float factor,
+ vec4 color,
+ vec4 black_level,
+ vec4 white_level,
+ sampler1DArray curve_map,
+ const float layer,
+ float range_minimum,
+ float range_divider,
+ float start_slope,
+ float end_slope,
+ out vec4 result)
+{
+ vec4 balanced = white_balance(color, black_level, white_level);
+
+ /* Find the maximum, minimum, and median of the color channels. */
+ float minimum = min(balanced.r, min(balanced.g, balanced.b));
+ float maximum = max(balanced.r, max(balanced.g, balanced.b));
+ float median = max(min(balanced.r, balanced.g), min(balanced.b, max(balanced.r, balanced.g)));
+
+ /* Evaluate alpha curve map at the maximum and minimum channels. The alpha curve is the Combined
+ * curve in the UI. */
+ float min_parameter = NORMALIZE_PARAMETER(minimum, range_minimum, range_divider);
+ float max_parameter = NORMALIZE_PARAMETER(maximum, range_minimum, range_divider);
+ float new_min = texture(curve_map, vec2(min_parameter, layer)).a;
+ float new_max = texture(curve_map, vec2(max_parameter, layer)).a;
+
+ /* Then, extrapolate if needed. */
+ new_min = extrapolate_if_needed(min_parameter, new_min, start_slope, end_slope);
+ new_max = extrapolate_if_needed(max_parameter, new_max, start_slope, end_slope);
+
+ /* Compute the new median using the ratio between the new and the original range. */
+ float scaling_ratio = (new_max - new_min) / (maximum - minimum);
+ float new_median = new_min + (median - minimum) * scaling_ratio;
+
+ /* Write each value to its original channel. */
+ bvec3 channel_is_min = equal(balanced.rgb, vec3(minimum));
+ vec3 median_or_min = mix(vec3(new_median), vec3(new_min), channel_is_min);
+ bvec3 channel_is_max = equal(balanced.rgb, vec3(maximum));
+ result.rgb = mix(median_or_min, vec3(new_max), channel_is_max);
+ result.a = color.a;
+
+ result = mix(color, result, clamp(factor, 0.0, 1.0));
+}
+
void curves_vector(vec3 vector,
sampler1DArray curve_map,
const float layer,
diff --git a/source/blender/gpu/shaders/common/gpu_shader_common_math_utils.glsl b/source/blender/gpu/shaders/common/gpu_shader_common_math_utils.glsl
index 124654963fd..1ba22b4c5da 100644
--- a/source/blender/gpu/shaders/common/gpu_shader_common_math_utils.glsl
+++ b/source/blender/gpu/shaders/common/gpu_shader_common_math_utils.glsl
@@ -34,6 +34,17 @@ float compatible_pow(float x, float y)
return pow(x, y);
}
+/* A version of pow that returns a fallback value if the computation is undefined. From the spec:
+ * The result is undefined if x < 0 or if x = 0 and y is less than or equal 0. */
+float fallback_pow(float x, float y, float fallback)
+{
+ if (x < 0.0 || (x == 0.0 && y <= 0.0)) {
+ return fallback;
+ }
+
+ return pow(x, y);
+}
+
float wrap(float a, float b, float c)
{
float range = b - c;
@@ -114,8 +125,24 @@ void vector_copy(vec3 normal, out vec3 outnormal)
outnormal = normal;
}
+vec3 fallback_pow(vec3 a, float b, vec3 fallback)
+{
+ return vec3(fallback_pow(a.x, b, fallback.x),
+ fallback_pow(a.y, b, fallback.y),
+ fallback_pow(a.z, b, fallback.z));
+}
+
/* Matirx Math */
+/* Return a 2D rotation matrix with the angle that the input 2D vector makes with the x axis. */
+mat2 vector_to_rotation_matrix(vec2 vector)
+{
+ vec2 normalized_vector = normalize(vector);
+ float cos_angle = normalized_vector.x;
+ float sin_angle = normalized_vector.y;
+ return mat2(cos_angle, sin_angle, -sin_angle, cos_angle);
+}
+
mat3 euler_to_mat3(vec3 euler)
{
float cx = cos(euler.x);
diff --git a/source/blender/gpu/shaders/common/gpu_shader_common_mix_rgb.glsl b/source/blender/gpu/shaders/common/gpu_shader_common_mix_rgb.glsl
index f9652f1150b..39f3c722dd2 100644
--- a/source/blender/gpu/shaders/common/gpu_shader_common_mix_rgb.glsl
+++ b/source/blender/gpu/shaders/common/gpu_shader_common_mix_rgb.glsl
@@ -2,28 +2,24 @@
void mix_blend(float fac, vec4 col1, vec4 col2, out vec4 outcol)
{
- fac = clamp(fac, 0.0, 1.0);
outcol = mix(col1, col2, fac);
outcol.a = col1.a;
}
void mix_add(float fac, vec4 col1, vec4 col2, out vec4 outcol)
{
- fac = clamp(fac, 0.0, 1.0);
outcol = mix(col1, col1 + col2, fac);
outcol.a = col1.a;
}
void mix_mult(float fac, vec4 col1, vec4 col2, out vec4 outcol)
{
- fac = clamp(fac, 0.0, 1.0);
outcol = mix(col1, col1 * col2, fac);
outcol.a = col1.a;
}
void mix_screen(float fac, vec4 col1, vec4 col2, out vec4 outcol)
{
- fac = clamp(fac, 0.0, 1.0);
float facm = 1.0 - fac;
outcol = vec4(1.0) - (vec4(facm) + fac * (vec4(1.0) - col2)) * (vec4(1.0) - col1);
@@ -32,7 +28,6 @@ void mix_screen(float fac, vec4 col1, vec4 col2, out vec4 outcol)
void mix_overlay(float fac, vec4 col1, vec4 col2, out vec4 outcol)
{
- fac = clamp(fac, 0.0, 1.0);
float facm = 1.0 - fac;
outcol = col1;
@@ -61,14 +56,30 @@ void mix_overlay(float fac, vec4 col1, vec4 col2, out vec4 outcol)
void mix_sub(float fac, vec4 col1, vec4 col2, out vec4 outcol)
{
- fac = clamp(fac, 0.0, 1.0);
outcol = mix(col1, col1 - col2, fac);
outcol.a = col1.a;
}
void mix_div(float fac, vec4 col1, vec4 col2, out vec4 outcol)
{
- fac = clamp(fac, 0.0, 1.0);
+ float facm = 1.0 - fac;
+
+ outcol = vec4(vec3(0.0), col1.a);
+
+ if (col2.r != 0.0) {
+ outcol.r = facm * col1.r + fac * col1.r / col2.r;
+ }
+ if (col2.g != 0.0) {
+ outcol.g = facm * col1.g + fac * col1.g / col2.g;
+ }
+ if (col2.b != 0.0) {
+ outcol.b = facm * col1.b + fac * col1.b / col2.b;
+ }
+}
+
+/* A variant of mix_div that fallback to the first color upon zero division. */
+void mix_div_fallback(float fac, vec4 col1, vec4 col2, out vec4 outcol)
+{
float facm = 1.0 - fac;
outcol = col1;
@@ -86,28 +97,24 @@ void mix_div(float fac, vec4 col1, vec4 col2, out vec4 outcol)
void mix_diff(float fac, vec4 col1, vec4 col2, out vec4 outcol)
{
- fac = clamp(fac, 0.0, 1.0);
outcol = mix(col1, abs(col1 - col2), fac);
outcol.a = col1.a;
}
void mix_dark(float fac, vec4 col1, vec4 col2, out vec4 outcol)
{
- fac = clamp(fac, 0.0, 1.0);
outcol.rgb = mix(col1.rgb, min(col1.rgb, col2.rgb), fac);
outcol.a = col1.a;
}
void mix_light(float fac, vec4 col1, vec4 col2, out vec4 outcol)
{
- fac = clamp(fac, 0.0, 1.0);
outcol.rgb = mix(col1.rgb, max(col1.rgb, col2.rgb), fac);
outcol.a = col1.a;
}
void mix_dodge(float fac, vec4 col1, vec4 col2, out vec4 outcol)
{
- fac = clamp(fac, 0.0, 1.0);
outcol = col1;
if (outcol.r != 0.0) {
@@ -150,7 +157,6 @@ void mix_dodge(float fac, vec4 col1, vec4 col2, out vec4 outcol)
void mix_burn(float fac, vec4 col1, vec4 col2, out vec4 outcol)
{
- fac = clamp(fac, 0.0, 1.0);
float tmp, facm = 1.0 - fac;
outcol = col1;
@@ -200,7 +206,6 @@ void mix_burn(float fac, vec4 col1, vec4 col2, out vec4 outcol)
void mix_hue(float fac, vec4 col1, vec4 col2, out vec4 outcol)
{
- fac = clamp(fac, 0.0, 1.0);
float facm = 1.0 - fac;
outcol = col1;
@@ -220,7 +225,6 @@ void mix_hue(float fac, vec4 col1, vec4 col2, out vec4 outcol)
void mix_sat(float fac, vec4 col1, vec4 col2, out vec4 outcol)
{
- fac = clamp(fac, 0.0, 1.0);
float facm = 1.0 - fac;
outcol = col1;
@@ -238,7 +242,6 @@ void mix_sat(float fac, vec4 col1, vec4 col2, out vec4 outcol)
void mix_val(float fac, vec4 col1, vec4 col2, out vec4 outcol)
{
- fac = clamp(fac, 0.0, 1.0);
float facm = 1.0 - fac;
vec4 hsv, hsv2;
@@ -251,7 +254,6 @@ void mix_val(float fac, vec4 col1, vec4 col2, out vec4 outcol)
void mix_color(float fac, vec4 col1, vec4 col2, out vec4 outcol)
{
- fac = clamp(fac, 0.0, 1.0);
float facm = 1.0 - fac;
outcol = col1;
@@ -272,22 +274,26 @@ void mix_color(float fac, vec4 col1, vec4 col2, out vec4 outcol)
void mix_soft(float fac, vec4 col1, vec4 col2, out vec4 outcol)
{
- fac = clamp(fac, 0.0, 1.0);
float facm = 1.0 - fac;
vec4 one = vec4(1.0);
vec4 scr = one - (one - col2) * (one - col1);
outcol = facm * col1 + fac * ((one - col1) * col2 * col1 + col1 * scr);
+ outcol.a = col1.a;
}
void mix_linear(float fac, vec4 col1, vec4 col2, out vec4 outcol)
{
- fac = clamp(fac, 0.0, 1.0);
-
outcol = col1 + fac * (2.0 * (col2 - vec4(0.5)));
+ outcol.a = col1.a;
}
-void clamp_color(vec3 vec, vec3 min, vec3 max, out vec3 out_vec)
+void clamp_color(vec4 vec, const vec4 min, const vec4 max, out vec4 out_vec)
{
out_vec = clamp(vec, min, max);
}
+
+void multiply_by_alpha(float factor, vec4 color, out float result)
+{
+ result = factor * color.a;
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_alpha_crop.glsl b/source/blender/gpu/shaders/compositor/compositor_alpha_crop.glsl
new file mode 100644
index 00000000000..d55c8efd4c6
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_alpha_crop.glsl
@@ -0,0 +1,11 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+ /* The lower bound is inclusive and upper bound is exclusive. */
+ bool is_inside = all(greaterThanEqual(texel, lower_bound)) && all(lessThan(texel, upper_bound));
+ /* Write the pixel color if it is inside the cropping region, otherwise, write zero. */
+ vec4 color = is_inside ? texture_load(input_tx, texel) : vec4(0.0);
+ imageStore(output_img, texel, color);
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_bilateral_blur.glsl b/source/blender/gpu/shaders/compositor/compositor_bilateral_blur.glsl
new file mode 100644
index 00000000000..c7c5ada7a9f
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_bilateral_blur.glsl
@@ -0,0 +1,31 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ vec4 center_determinator = texture_load(determinator_tx, texel);
+
+ /* Go over the pixels in the blur window of the specified radius around the center pixel, and for
+ * pixels whose determinator is close enough to the determinator of the center pixel, accumulate
+ * their color as well as their weights. */
+ float accumulated_weight = 0.0;
+ vec4 accumulated_color = vec4(0.0);
+ for (int y = -radius; y <= radius; y++) {
+ for (int x = -radius; x <= radius; x++) {
+ vec4 determinator = texture_load(determinator_tx, texel + ivec2(x, y));
+ float difference = dot(abs(center_determinator - determinator).rgb, vec3(1.0));
+
+ if (difference < threshold) {
+ accumulated_weight += 1.0;
+ accumulated_color += texture_load(input_tx, texel + ivec2(x, y));
+ }
+ }
+ }
+
+ /* Write the accumulated color divided by the accumulated weight if any pixel in the window was
+ * accumulated, otherwise, write a fallback black color. */
+ vec4 fallback = vec4(vec3(0.0), 1.0);
+ vec4 color = (accumulated_weight != 0.0) ? (accumulated_color / accumulated_weight) : fallback;
+ imageStore(output_img, texel, color);
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_bokeh_image.glsl b/source/blender/gpu/shaders/compositor/compositor_bokeh_image.glsl
new file mode 100644
index 00000000000..6e98aa9fe17
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_bokeh_image.glsl
@@ -0,0 +1,118 @@
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+/* Get the 2D vertex position of the vertex with the given index in the regular polygon
+ * representing this bokeh. The polygon is rotated by the rotation amount and have a unit
+ * circumradius. The regular polygon is one whose vertices' exterior angles are given by
+ * exterior_angle. See the bokeh function for more information. */
+vec2 get_regular_polygon_vertex_position(int vertex_index)
+{
+ float angle = exterior_angle * vertex_index - rotation;
+ return vec2(cos(angle), sin(angle));
+}
+
+/* Find the closest point to the given point on the given line. This assumes the length of the
+ * given line is not zero. */
+vec2 closest_point_on_line(vec2 point, vec2 line_start, vec2 line_end)
+{
+ vec2 line_vector = line_end - line_start;
+ vec2 point_vector = point - line_start;
+ float line_length_squared = dot(line_vector, line_vector);
+ float parameter = dot(point_vector, line_vector) / line_length_squared;
+ return line_start + line_vector * parameter;
+}
+
+/* Compute the value of the bokeh at the given point. The computed bokeh is essentially a regular
+ * polygon centered in space having the given circumradius. The regular polygon is one whose
+ * vertices' exterior angles are given by "exterior_angle", which relates to the number of vertices
+ * n through the equation "exterior angle = 2 pi / n". The regular polygon may additionally morph
+ * into a shape with the given properties:
+ *
+ * - The regular polygon may have a circular hole in its center whose radius is controlled by the
+ * "catadioptric" value.
+ * - The regular polygon is rotated by the "rotation" value.
+ * - The regular polygon can morph into a circle controlled by the "roundness" value, such that it
+ * becomes a full circle at unit roundness.
+ *
+ * The function returns 0 when the point lies inside the regular polygon and 1 otherwise. However,
+ * at the edges, it returns a narrow band gradient as a form of anti-aliasing. */
+float bokeh(vec2 point, float circumradius)
+{
+ /* Get the index of the vertex of the regular polygon whose polar angle is maximum but less than
+ * the polar angle of the given point, taking rotation into account. This essentially finds the
+ * vertex closest to the given point in the clock-wise direction. */
+ float angle = mod(atan(point.y, point.x) + rotation, M_2PI);
+ int vertex_index = int(angle / exterior_angle);
+
+ /* Compute the shortest distance between the origin and the polygon edge composed from the
+ * previously selected vertex and the one following it. */
+ vec2 first_vertex = get_regular_polygon_vertex_position(vertex_index) * circumradius;
+ vec2 second_vertex = get_regular_polygon_vertex_position(vertex_index + 1) * circumradius;
+ vec2 closest_point = closest_point_on_line(point, first_vertex, second_vertex);
+ float distance_to_edge = length(closest_point);
+
+ /* Mix the distance to the edge with the circumradius, making it tend to the distance to a
+ * circle when roundness tends to 1. */
+ float distance_to_edge_round = mix(distance_to_edge, circumradius, roundness);
+
+ /* The point is outside of the bokeh, so we return 0. */
+ float distance = length(point);
+ if (distance > distance_to_edge_round) {
+ return 0.0;
+ }
+
+ /* The point is inside the catadioptric hole and is not part of the bokeh, so we return 0. */
+ float catadioptric_distance = distance_to_edge_round * catadioptric;
+ if (distance < catadioptric_distance) {
+ return 0.0;
+ }
+
+ /* The point is very close to the edge of the bokeh, so we return the difference between the
+ * distance to the edge and the distance as a form of anti-aliasing. */
+ if (distance_to_edge_round - distance < 1.0) {
+ return distance_to_edge_round - distance;
+ }
+
+ /* The point is very close to the edge of the catadioptric hole, so we return the difference
+ * between the distance to the hole and the distance as a form of anti-aliasing. */
+ if (catadioptric != 0.0 && distance - catadioptric_distance < 1.0) {
+ return distance - catadioptric_distance;
+ }
+
+ /* Otherwise, the point is part of the bokeh and we return 1. */
+ return 1.0;
+}
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ /* Since we need the regular polygon to occupy the entirety of the output image, the circumradius
+ * of the regular polygon is half the width of the output image. */
+ float circumradius = float(imageSize(output_img).x) / 2.0;
+
+ /* Move the texel coordinates such that the regular polygon is centered. */
+ vec2 point = vec2(texel) - circumradius;
+
+ /* Each of the color channels of the output image contains a bokeh with a different circumradius.
+ * The largest one occupies the whole image as stated above, while the other two have circumradii
+ * that are shifted by an amount that is proportional to the "lens_shift" value. The alpha
+ * channel of the output is the average of all three values. */
+ float min_shift = abs(lens_shift * circumradius);
+ float min = mix(bokeh(point, circumradius - min_shift), 0.0, min_shift == circumradius);
+
+ float median_shift = min_shift / 2.0;
+ float median = bokeh(point, circumradius - median_shift);
+
+ float max = bokeh(point, circumradius);
+ vec4 bokeh = vec4(min, median, max, (max + median + min) / 3.0);
+
+ /* If the lens shift is negative, swap the min and max bokeh values, which are stored in the red
+ * and blue channels respectively. Note that we take the absolute value of the lens shift above,
+ * so the sign of the lens shift only controls this swap. */
+ if (lens_shift < 0) {
+ bokeh = bokeh.zyxw;
+ }
+
+ imageStore(output_img, texel, bokeh);
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_box_mask.glsl b/source/blender/gpu/shaders/compositor/compositor_box_mask.glsl
new file mode 100644
index 00000000000..fad23f28fde
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_box_mask.glsl
@@ -0,0 +1,27 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ vec2 uv = vec2(texel) / vec2(domain_size - ivec2(1));
+ uv -= location;
+ uv.y *= float(domain_size.y) / float(domain_size.x);
+ uv = mat2(cos_angle, -sin_angle, sin_angle, cos_angle) * uv;
+ bool is_inside = all(lessThan(abs(uv), size));
+
+ float base_mask_value = texture_load(base_mask_tx, texel).x;
+ float value = texture_load(mask_value_tx, texel).x;
+
+#if defined(CMP_NODE_MASKTYPE_ADD)
+ float output_mask_value = is_inside ? max(base_mask_value, value) : base_mask_value;
+#elif defined(CMP_NODE_MASKTYPE_SUBTRACT)
+ float output_mask_value = is_inside ? clamp(base_mask_value - value, 0.0, 1.0) : base_mask_value;
+#elif defined(CMP_NODE_MASKTYPE_MULTIPLY)
+ float output_mask_value = is_inside ? base_mask_value * value : 0.0;
+#elif defined(CMP_NODE_MASKTYPE_NOT)
+ float output_mask_value = is_inside ? (base_mask_value > 0.0 ? 0.0 : value) : base_mask_value;
+#endif
+
+ imageStore(output_mask_img, texel, vec4(output_mask_value));
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_convert.glsl b/source/blender/gpu/shaders/compositor/compositor_convert.glsl
new file mode 100644
index 00000000000..044fb057ca5
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_convert.glsl
@@ -0,0 +1,8 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+ vec4 value = texture_load(input_tx, texel);
+ imageStore(output_img, texel, CONVERT_EXPRESSION(value));
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_despeckle.glsl b/source/blender/gpu/shaders/compositor/compositor_despeckle.glsl
new file mode 100644
index 00000000000..e4743d69d17
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_despeckle.glsl
@@ -0,0 +1,70 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+/* Returns true if the given color is close enough to the given reference color within the
+ * threshold supplied by the user, and returns false otherwise. */
+bool is_close(vec4 reference_color, vec4 color)
+{
+ return all(lessThan(abs(reference_color - color).rgb, vec3(threshold)));
+}
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ /* A 3x3 weights kernel whose weights are the inverse of the distance to the center of the
+ * kernel. So the center weight is zero, the corners weights are (1 / sqrt(2)), and the rest
+ * of the weights are 1. The total sum of weights is 4 plus quadruple the corner weight. */
+ float corner_weight = 1.0 / sqrt(2.0);
+ float sum_of_weights = 4.0 + corner_weight * 4.0;
+ mat3 weights = mat3(vec3(corner_weight, 1.0, corner_weight),
+ vec3(1.0, 0.0, 1.0),
+ vec3(corner_weight, 1.0, corner_weight));
+
+ vec4 center_color = texture_load(input_tx, texel);
+
+ /* Go over the pixels in the 3x3 window around the center pixel and compute the total sum of
+ * their colors multiplied by their weights. Additionally, for pixels whose colors are not close
+ * enough to the color of the center pixel, accumulate their color as well as their weights. */
+ vec4 sum_of_colors = vec4(0);
+ float accumulated_weight = 0.0;
+ vec4 accumulated_color = vec4(0);
+ for (int j = 0; j < 3; j++) {
+ for (int i = 0; i < 3; i++) {
+ float weight = weights[j][i];
+ vec4 color = texture_load(input_tx, texel + ivec2(i - 1, j - 1)) * weight;
+ sum_of_colors += color;
+ if (!is_close(center_color, color)) {
+ accumulated_color += color;
+ accumulated_weight += weight;
+ }
+ }
+ }
+
+ /* If the accumulated weight is zero, that means all pixels in the 3x3 window are similar and no
+ * need to despeckle anything, so write the original center color and return. */
+ if (accumulated_weight == 0.0) {
+ imageStore(output_img, texel, center_color);
+ return;
+ }
+
+ /* If the ratio between the accumulated weights and the total sum of weights is not larger than
+ * the user specified neighbor threshold, then the number of pixels in the neighborhood that are
+ * not close enough to the center pixel is low, and no need to despeckle anything, so write the
+ * original center color and return. */
+ if (accumulated_weight / sum_of_weights < neighbor_threshold) {
+ imageStore(output_img, texel, center_color);
+ return;
+ }
+
+ /* If the weighted average color of the neighborhood is close enough to the center pixel, then no
+ * need to despeckle anything, so write the original center color and return. */
+ if (is_close(center_color, sum_of_colors / sum_of_weights)) {
+ imageStore(output_img, texel, center_color);
+ return;
+ }
+
+ /* We need to despeckle, so write the mean accumulated color. */
+ float factor = texture_load(factor_tx, texel).x;
+ vec4 mean_color = accumulated_color / accumulated_weight;
+ imageStore(output_img, texel, mix(center_color, mean_color, factor));
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_directional_blur.glsl b/source/blender/gpu/shaders/compositor/compositor_directional_blur.glsl
new file mode 100644
index 00000000000..1805cb5a7f5
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_directional_blur.glsl
@@ -0,0 +1,21 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+ ivec2 input_size = texture_size(input_tx);
+
+ /* Add 0.5 to evaluate the input sampler at the center of the pixel. */
+ vec2 coordinates = vec2(texel) + vec2(0.5);
+
+ /* For each iteration, accumulate the input at the normalize coordinates, hence the divide by
+ * input size, then transform the coordinates for the next iteration. */
+ vec4 accumulated_color = vec4(0.0);
+ for (int i = 0; i < iterations; i++) {
+ accumulated_color += texture(input_tx, coordinates / input_size);
+ coordinates = (mat3(inverse_transformation) * vec3(coordinates, 1.0)).xy;
+ }
+
+ /* Write the accumulated color divided by the number of iterations. */
+ imageStore(output_img, texel, accumulated_color / iterations);
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_edge_filter.glsl b/source/blender/gpu/shaders/compositor/compositor_edge_filter.glsl
new file mode 100644
index 00000000000..67e27c22602
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_edge_filter.glsl
@@ -0,0 +1,31 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ /* Compute the dot product between the 3x3 window around the pixel and the edge detection kernel
+ * in the X direction and Y direction. The Y direction kernel is computed by transposing the
+ * given X direction kernel. */
+ vec3 color_x = vec3(0);
+ vec3 color_y = vec3(0);
+ for (int j = 0; j < 3; j++) {
+ for (int i = 0; i < 3; i++) {
+ vec3 color = texture_load(input_tx, texel + ivec2(i - 1, j - 1)).rgb;
+ color_x += color * kernel[j][i];
+ color_y += color * kernel[i][j];
+ }
+ }
+
+ /* Compute the channel-wise magnitude of the 2D vector composed from the X and Y edge detection
+ * filter results. */
+ vec3 magnitude = sqrt(color_x * color_x + color_y * color_y);
+
+ /* Mix the channel-wise magnitude with the original color at the center of the kernel using the
+ * input factor. */
+ vec4 color = texture_load(input_tx, texel);
+ magnitude = mix(color.rgb, magnitude, texture_load(factor_tx, texel).x);
+
+ /* Store the channel-wise magnitude with the original alpha of the input. */
+ imageStore(output_img, texel, vec4(magnitude, color.a));
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_ellipse_mask.glsl b/source/blender/gpu/shaders/compositor/compositor_ellipse_mask.glsl
new file mode 100644
index 00000000000..28f725067e0
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_ellipse_mask.glsl
@@ -0,0 +1,27 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ vec2 uv = vec2(texel) / vec2(domain_size - ivec2(1));
+ uv -= location;
+ uv.y *= float(domain_size.y) / float(domain_size.x);
+ uv = mat2(cos_angle, -sin_angle, sin_angle, cos_angle) * uv;
+ bool is_inside = length(uv / radius) < 1.0;
+
+ float base_mask_value = texture_load(base_mask_tx, texel).x;
+ float value = texture_load(mask_value_tx, texel).x;
+
+#if defined(CMP_NODE_MASKTYPE_ADD)
+ float output_mask_value = is_inside ? max(base_mask_value, value) : base_mask_value;
+#elif defined(CMP_NODE_MASKTYPE_SUBTRACT)
+ float output_mask_value = is_inside ? clamp(base_mask_value - value, 0.0, 1.0) : base_mask_value;
+#elif defined(CMP_NODE_MASKTYPE_MULTIPLY)
+ float output_mask_value = is_inside ? base_mask_value * value : 0.0;
+#elif defined(CMP_NODE_MASKTYPE_NOT)
+ float output_mask_value = is_inside ? (base_mask_value > 0.0 ? 0.0 : value) : base_mask_value;
+#endif
+
+ imageStore(output_mask_img, texel, vec4(output_mask_value));
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_filter.glsl b/source/blender/gpu/shaders/compositor/compositor_filter.glsl
new file mode 100644
index 00000000000..e501c563dda
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_filter.glsl
@@ -0,0 +1,20 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ /* Compute the dot product between the 3x3 window around the pixel and the filter kernel. */
+ vec4 color = vec4(0);
+ for (int j = 0; j < 3; j++) {
+ for (int i = 0; i < 3; i++) {
+ color += texture_load(input_tx, texel + ivec2(i - 1, j - 1)) * kernel[j][i];
+ }
+ }
+
+ /* Mix with the original color at the center of the kernel using the input factor. */
+ color = mix(texture_load(input_tx, texel), color, texture_load(factor_tx, texel).x);
+
+ /* Store the color making sure it is not negative. */
+ imageStore(output_img, texel, max(color, 0.0));
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_flip.glsl b/source/blender/gpu/shaders/compositor/compositor_flip.glsl
new file mode 100644
index 00000000000..919c454ee63
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_flip.glsl
@@ -0,0 +1,15 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+ ivec2 size = texture_size(input_tx);
+ ivec2 flipped_texel = texel;
+ if (flip_x) {
+ flipped_texel.x = size.x - texel.x - 1;
+ }
+ if (flip_y) {
+ flipped_texel.y = size.y - texel.y - 1;
+ }
+ imageStore(output_img, texel, texture_load(input_tx, flipped_texel));
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_image_crop.glsl b/source/blender/gpu/shaders/compositor/compositor_image_crop.glsl
new file mode 100644
index 00000000000..f20e033dee4
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_image_crop.glsl
@@ -0,0 +1,7 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+ imageStore(output_img, texel, texture_load(input_tx, texel + lower_bound));
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_projector_lens_distortion.glsl b/source/blender/gpu/shaders/compositor/compositor_projector_lens_distortion.glsl
new file mode 100644
index 00000000000..cf961b20b34
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_projector_lens_distortion.glsl
@@ -0,0 +1,16 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ /* Get the normalized coordinates of the pixel centers. */
+ vec2 normalized_texel = (vec2(texel) + vec2(0.5)) / vec2(texture_size(input_tx));
+
+ /* Sample the red and blue channels shifted by the dispersion amount. */
+ const float red = texture(input_tx, normalized_texel + vec2(dispersion, 0.0)).r;
+ const float green = texture_load(input_tx, texel).g;
+ const float blue = texture(input_tx, normalized_texel - vec2(dispersion, 0.0)).b;
+
+ imageStore(output_img, texel, vec4(red, green, blue, 1.0));
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_realize_on_domain.glsl b/source/blender/gpu/shaders/compositor/compositor_realize_on_domain.glsl
new file mode 100644
index 00000000000..b2961d07219
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_realize_on_domain.glsl
@@ -0,0 +1,25 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ /* First, transform the input image by transforming the domain coordinates with the inverse of
+ * input image's transformation. The inverse transformation is an affine matrix and thus the
+ * coordinates should be in homogeneous coordinates. */
+ vec2 coordinates = (mat3(inverse_transformation) * vec3(texel, 1.0)).xy;
+
+ /* Since an input image with an identity transformation is supposed to be centered in the domain,
+ * we subtract the offset between the lower left corners of the input image and the domain, which
+ * is half the difference between their sizes, because the difference in size is on both sides of
+ * the centered image. */
+ ivec2 domain_size = imageSize(domain_img);
+ ivec2 input_size = texture_size(input_tx);
+ vec2 offset = (domain_size - input_size) / 2.0;
+
+ /* Subtract the offset and divide by the input image size to get the relevant coordinates into
+ * the sampler's expected [0, 1] range. */
+ vec2 normalized_coordinates = (coordinates - offset) / input_size;
+
+ imageStore(domain_img, texel, texture(input_tx, normalized_coordinates));
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_screen_lens_distortion.glsl b/source/blender/gpu/shaders/compositor/compositor_screen_lens_distortion.glsl
new file mode 100644
index 00000000000..dc572ea5aaf
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_screen_lens_distortion.glsl
@@ -0,0 +1,151 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_hash.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+/* A model that approximates lens distortion parameterized by a distortion parameter and dependent
+ * on the squared distance to the center of the image. The distorted pixel is then computed as the
+ * scalar multiplication of the pixel coordinates with the value returned by this model. See the
+ * compute_distorted_uv function for more details. */
+float compute_distortion_scale(float distortion, float distance_squared)
+{
+ return 1.0 / (1.0 + sqrt(max(0.0, 1.0 - distortion * distance_squared)));
+}
+
+/* A vectorized version of compute_distortion_scale that is applied on the chromatic distortion
+ * parameters passed to the shader. */
+vec3 compute_chromatic_distortion_scale(float distance_squared)
+{
+ return 1.0 / (1.0 + sqrt(max(vec3(0.0), 1.0 - chromatic_distortion * distance_squared)));
+}
+
+/* Compute the image coordinates after distortion by the given distortion scale computed by the
+ * compute_distortion_scale function. Note that the function expects centered normalized UV
+ * coordinates but outputs non-centered image coordinates. */
+vec2 compute_distorted_uv(vec2 uv, float scale)
+{
+ return (uv * scale + 0.5) * texture_size(input_tx) - 0.5;
+}
+
+/* Compute the number of integration steps that should be used to approximate the distorted pixel
+ * using a heuristic, see the compute_number_of_steps function for more details. The numbers of
+ * steps is proportional to the number of pixels spanned by the distortion amount. For jitter
+ * distortion, the square root of the distortion amount plus 1 is used with a minimum of 2 steps.
+ * For non-jitter distortion, the distortion amount plus 1 is used as the number of steps */
+int compute_number_of_integration_steps_heuristic(float distortion)
+{
+#if defined(JITTER)
+ return distortion < 4.0 ? 2 : int(sqrt(distortion + 1.0));
+#else
+ return int(distortion + 1.0);
+#endif
+}
+
+/* Compute the number of integration steps that should be used to compute each channel of the
+ * distorted pixel. Each of the channels are distorted by their respective chromatic distortion
+ * amount, then the amount of distortion between each two consecutive channels is computed, this
+ * amount is then used to heuristically infer the number of needed integration steps, see the
+ * integrate_distortion function for more information. */
+ivec3 compute_number_of_integration_steps(vec2 uv, float distance_squared)
+{
+ /* Distort each channel by its respective chromatic distortion amount. */
+ vec3 distortion_scale = compute_chromatic_distortion_scale(distance_squared);
+ vec2 distorted_uv_red = compute_distorted_uv(uv, distortion_scale.r);
+ vec2 distorted_uv_green = compute_distorted_uv(uv, distortion_scale.g);
+ vec2 distorted_uv_blue = compute_distorted_uv(uv, distortion_scale.b);
+
+ /* Infer the number of needed integration steps to compute the distorted red channel starting
+ * from the green channel. */
+ float distortion_red = distance(distorted_uv_red, distorted_uv_green);
+ int steps_red = compute_number_of_integration_steps_heuristic(distortion_red);
+
+ /* Infer the number of needed integration steps to compute the distorted blue channel starting
+ * from the green channel. */
+ float distortion_blue = distance(distorted_uv_green, distorted_uv_blue);
+ int steps_blue = compute_number_of_integration_steps_heuristic(distortion_blue);
+
+ /* The number of integration steps used to compute the green channel is the sum of both the red
+ * and the blue channel steps because it is computed once with each of them. */
+ return ivec3(steps_red, steps_red + steps_blue, steps_blue);
+}
+
+/* Returns a random jitter amount, which is essentially a random value in the [0, 1] range. If
+ * jitter is not enabled, return a constant 0.5 value instead. */
+float get_jitter(int seed)
+{
+#if defined(JITTER)
+ return hash_uint3_to_float(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y, seed);
+#else
+ return 0.5;
+#endif
+}
+
+/* Each color channel may have a different distortion with the guarantee that the red will have the
+ * lowest distortion while the blue will have the highest one. If each channel is distorted
+ * independently, the image will look disintegrated, with each channel seemingly merely shifted.
+ * Consequently, the distorted pixels needs to be computed by integrating along the path of change
+ * of distortion starting from one channel to another. For instance, to compute the distorted red
+ * from the distorted green, we accumulate the color of the distorted pixel starting from the
+ * distortion of the red, taking small steps until we reach the distortion of the green. The pixel
+ * color is weighted such that it is maximum at the start distortion and zero at the end distortion
+ * in an arithmetic progression. The integration steps can be augmented with random values to
+ * simulate lens jitter. Finally, it should be noted that this function integrates both the start
+ * and end channels in reverse directions for more efficient computation. */
+vec3 integrate_distortion(int start, int end, float distance_squared, vec2 uv, int steps)
+{
+ vec3 accumulated_color = vec3(0.0);
+ float distortion_amount = chromatic_distortion[end] - chromatic_distortion[start];
+ for (int i = 0; i < steps; i++) {
+ /* The increment will be in the [0, 1) range across iterations. */
+ float increment = (i + get_jitter(i)) / steps;
+ float distortion = chromatic_distortion[start] + increment * distortion_amount;
+ float distortion_scale = compute_distortion_scale(distortion, distance_squared);
+
+ /* Sample the color at the distorted coordinates and accumulate it weighted by the increment
+ * value for both the start and end channels. */
+ vec2 distorted_uv = compute_distorted_uv(uv, distortion_scale);
+ vec4 color = texture(input_tx, distorted_uv / texture_size(input_tx));
+ accumulated_color[start] += (1.0 - increment) * color[start];
+ accumulated_color[end] += increment * color[end];
+ }
+ return accumulated_color;
+}
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ /* Compute the UV image coordinates in the range [-1, 1] as well as the squared distance to the
+ * center of the image, which is at (0, 0) in the UV coordinates. */
+ vec2 center = texture_size(input_tx) / 2.0;
+ vec2 uv = scale * (texel + 0.5 - center) / center;
+ float distance_squared = dot(uv, uv);
+
+ /* If any of the color channels will get distorted outside of the screen beyond what is possible,
+ * write a zero transparent color and return. */
+ if (any(greaterThan(chromatic_distortion * distance_squared, vec3(1.0)))) {
+ imageStore(output_img, texel, vec4(0.0));
+ return;
+ }
+
+ /* Compute the number of integration steps that should be used to compute each channel of the
+ * distorted pixel. */
+ ivec3 number_of_steps = compute_number_of_integration_steps(uv, distance_squared);
+
+ /* Integrate the distortion of the red and green, then the green and blue channels. That means
+ * the green will be integrated twice, but this is accounted for in the number of steps which the
+ * color will later be divided by. See the compute_number_of_integration_steps function for more
+ * details. */
+ vec3 color = vec3(0.0);
+ color += integrate_distortion(0, 1, distance_squared, uv, number_of_steps.r);
+ color += integrate_distortion(1, 2, distance_squared, uv, number_of_steps.b);
+
+ /* The integration above performed weighted accumulation, and thus the color needs to be divided
+ * by the sum of the weights. Assuming no jitter, the weights are generated as an arithmetic
+ * progression starting from (0.5 / n) to ((n - 0.5) / n) for n terms. The sum of an arithmetic
+ * progression can be computed as (n * (start + end) / 2), which when subsisting the start and
+ * end reduces to (n / 2). So the color should be multiplied by 2 / n. The jitter sequence
+ * approximately sums to the same value because it is a uniform random value whose mean value is
+ * 0.5, so the expression doesn't change regardless of jitter. */
+ color *= 2.0 / vec3(number_of_steps);
+
+ imageStore(output_img, texel, vec4(color, 1.0));
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_set_alpha.glsl b/source/blender/gpu/shaders/compositor/compositor_set_alpha.glsl
new file mode 100644
index 00000000000..7dd40581790
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_set_alpha.glsl
@@ -0,0 +1,8 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+ vec4 color = vec4(texture_load(image_tx, texel).rgb, texture_load(alpha_tx, texel).x);
+ imageStore(output_img, texel, color);
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_split_viewer.glsl b/source/blender/gpu/shaders/compositor/compositor_split_viewer.glsl
new file mode 100644
index 00000000000..866b9045da2
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_split_viewer.glsl
@@ -0,0 +1,14 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+#if defined(SPLIT_HORIZONTAL)
+ bool condition = (view_size.x * split_ratio) < texel.x;
+#elif defined(SPLIT_VERTICAL)
+ bool condition = (view_size.y * split_ratio) < texel.y;
+#endif
+ vec4 color = condition ? texture_load(first_image_tx, texel) :
+ texture_load(second_image_tx, texel);
+ imageStore(output_img, texel, color);
+}
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_alpha_crop_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_alpha_crop_info.hh
new file mode 100644
index 00000000000..11f2f329cd8
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/infos/compositor_alpha_crop_info.hh
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_alpha_crop)
+ .local_group_size(16, 16)
+ .push_constant(Type::IVEC2, "lower_bound")
+ .push_constant(Type::IVEC2, "upper_bound")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_alpha_crop.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_bilateral_blur_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_bilateral_blur_info.hh
new file mode 100644
index 00000000000..301cd6acd9e
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/infos/compositor_bilateral_blur_info.hh
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_bilateral_blur)
+ .local_group_size(16, 16)
+ .push_constant(Type::INT, "radius")
+ .push_constant(Type::FLOAT, "threshold")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .sampler(1, ImageType::FLOAT_2D, "determinator_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_bilateral_blur.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_bokeh_image_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_bokeh_image_info.hh
new file mode 100644
index 00000000000..3541de53070
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/infos/compositor_bokeh_image_info.hh
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_bokeh_image)
+ .local_group_size(16, 16)
+ .push_constant(Type::FLOAT, "exterior_angle")
+ .push_constant(Type::FLOAT, "rotation")
+ .push_constant(Type::FLOAT, "roundness")
+ .push_constant(Type::FLOAT, "catadioptric")
+ .push_constant(Type::FLOAT, "lens_shift")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_bokeh_image.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_box_mask_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_box_mask_info.hh
new file mode 100644
index 00000000000..ecb253bbab1
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/infos/compositor_box_mask_info.hh
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_box_mask_shared)
+ .local_group_size(16, 16)
+ .push_constant(Type::IVEC2, "domain_size")
+ .push_constant(Type::VEC2, "location")
+ .push_constant(Type::VEC2, "size")
+ .push_constant(Type::FLOAT, "cos_angle")
+ .push_constant(Type::FLOAT, "sin_angle")
+ .sampler(0, ImageType::FLOAT_2D, "base_mask_tx")
+ .sampler(1, ImageType::FLOAT_2D, "mask_value_tx")
+ .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_mask_img")
+ .compute_source("compositor_box_mask.glsl");
+
+GPU_SHADER_CREATE_INFO(compositor_box_mask_add)
+ .additional_info("compositor_box_mask_shared")
+ .define("CMP_NODE_MASKTYPE_ADD")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_box_mask_subtract)
+ .additional_info("compositor_box_mask_shared")
+ .define("CMP_NODE_MASKTYPE_SUBTRACT")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_box_mask_multiply)
+ .additional_info("compositor_box_mask_shared")
+ .define("CMP_NODE_MASKTYPE_MULTIPLY")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_box_mask_not)
+ .additional_info("compositor_box_mask_shared")
+ .define("CMP_NODE_MASKTYPE_NOT")
+ .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_convert_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_convert_info.hh
new file mode 100644
index 00000000000..35e60056736
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/infos/compositor_convert_info.hh
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_convert_shared)
+ .local_group_size(16, 16)
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .typedef_source("gpu_shader_compositor_type_conversion.glsl")
+ .compute_source("compositor_convert.glsl");
+
+GPU_SHADER_CREATE_INFO(compositor_convert_float_to_vector)
+ .additional_info("compositor_convert_shared")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("CONVERT_EXPRESSION(value)", "vec4(vec3_from_float(value.x), 0.0)")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_convert_float_to_color)
+ .additional_info("compositor_convert_shared")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("CONVERT_EXPRESSION(value)", "vec4_from_float(value.x)")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_convert_color_to_float)
+ .additional_info("compositor_convert_shared")
+ .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("CONVERT_EXPRESSION(value)", "vec4(float_from_vec4(value), vec3(0.0))")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_convert_color_to_vector)
+ .additional_info("compositor_convert_shared")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("CONVERT_EXPRESSION(value)", "vec4(vec3_from_vec4(value), 0.0)")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_convert_vector_to_float)
+ .additional_info("compositor_convert_shared")
+ .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("CONVERT_EXPRESSION(value)", "vec4(float_from_vec3(value.xyz), vec3(0.0))")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_convert_vector_to_color)
+ .additional_info("compositor_convert_shared")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("CONVERT_EXPRESSION(value)", "vec4_from_vec3(value.xyz)")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_extract_alpha_from_color)
+ .additional_info("compositor_convert_shared")
+ .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("CONVERT_EXPRESSION(value)", "vec4(value.a, vec3(0.0))")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_convert_color_to_half_color)
+ .additional_info("compositor_convert_shared")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("CONVERT_EXPRESSION(value)", "value")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_convert_float_to_half_float)
+ .additional_info("compositor_convert_shared")
+ .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("CONVERT_EXPRESSION(value)", "vec4(value.r, vec3(0.0))")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_convert_color_to_opaque)
+ .additional_info("compositor_convert_shared")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("CONVERT_EXPRESSION(value)", "vec4(value.rgb, 1.0)")
+ .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_despeckle_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_despeckle_info.hh
new file mode 100644
index 00000000000..df86c3a8258
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/infos/compositor_despeckle_info.hh
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_despeckle)
+ .local_group_size(16, 16)
+ .push_constant(Type::FLOAT, "threshold")
+ .push_constant(Type::FLOAT, "neighbor_threshold")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .sampler(1, ImageType::FLOAT_2D, "factor_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_despeckle.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_directional_blur_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_directional_blur_info.hh
new file mode 100644
index 00000000000..bb9199dcd26
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/infos/compositor_directional_blur_info.hh
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_directional_blur)
+ .local_group_size(16, 16)
+ .push_constant(Type::INT, "iterations")
+ .push_constant(Type::MAT4, "inverse_transformation")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_directional_blur.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_edge_filter_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_edge_filter_info.hh
new file mode 100644
index 00000000000..916ec62bdba
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/infos/compositor_edge_filter_info.hh
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_edge_filter)
+ .local_group_size(16, 16)
+ .push_constant(Type::MAT4, "kernel")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .sampler(1, ImageType::FLOAT_2D, "factor_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_edge_filter.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_ellipse_mask_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_ellipse_mask_info.hh
new file mode 100644
index 00000000000..52db91c94e5
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/infos/compositor_ellipse_mask_info.hh
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_ellipse_mask_shared)
+ .local_group_size(16, 16)
+ .push_constant(Type::IVEC2, "domain_size")
+ .push_constant(Type::VEC2, "location")
+ .push_constant(Type::VEC2, "radius")
+ .push_constant(Type::FLOAT, "cos_angle")
+ .push_constant(Type::FLOAT, "sin_angle")
+ .sampler(0, ImageType::FLOAT_2D, "base_mask_tx")
+ .sampler(1, ImageType::FLOAT_2D, "mask_value_tx")
+ .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_mask_img")
+ .compute_source("compositor_ellipse_mask.glsl");
+
+GPU_SHADER_CREATE_INFO(compositor_ellipse_mask_add)
+ .additional_info("compositor_ellipse_mask_shared")
+ .define("CMP_NODE_MASKTYPE_ADD")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_ellipse_mask_subtract)
+ .additional_info("compositor_ellipse_mask_shared")
+ .define("CMP_NODE_MASKTYPE_SUBTRACT")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_ellipse_mask_multiply)
+ .additional_info("compositor_ellipse_mask_shared")
+ .define("CMP_NODE_MASKTYPE_MULTIPLY")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_ellipse_mask_not)
+ .additional_info("compositor_ellipse_mask_shared")
+ .define("CMP_NODE_MASKTYPE_NOT")
+ .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_filter_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_filter_info.hh
new file mode 100644
index 00000000000..9d565cf4b8a
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/infos/compositor_filter_info.hh
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_filter)
+ .local_group_size(16, 16)
+ .push_constant(Type::MAT4, "kernel")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .sampler(1, ImageType::FLOAT_2D, "factor_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_filter.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_flip_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_flip_info.hh
new file mode 100644
index 00000000000..db831518cb7
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/infos/compositor_flip_info.hh
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_flip)
+ .local_group_size(16, 16)
+ .push_constant(Type::BOOL, "flip_x")
+ .push_constant(Type::BOOL, "flip_y")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_flip.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_image_crop_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_image_crop_info.hh
new file mode 100644
index 00000000000..e7736744c40
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/infos/compositor_image_crop_info.hh
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_image_crop)
+ .local_group_size(16, 16)
+ .push_constant(Type::IVEC2, "lower_bound")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_image_crop.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_projector_lens_distortion_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_projector_lens_distortion_info.hh
new file mode 100644
index 00000000000..98fe1731703
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/infos/compositor_projector_lens_distortion_info.hh
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_projector_lens_distortion)
+ .local_group_size(16, 16)
+ .push_constant(Type::FLOAT, "dispersion")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_projector_lens_distortion.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_realize_on_domain_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_realize_on_domain_info.hh
new file mode 100644
index 00000000000..4528649ae98
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/infos/compositor_realize_on_domain_info.hh
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_realize_on_domain_shared)
+ .local_group_size(16, 16)
+ .push_constant(Type::MAT4, "inverse_transformation")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .compute_source("compositor_realize_on_domain.glsl");
+
+GPU_SHADER_CREATE_INFO(compositor_realize_on_domain_color)
+ .additional_info("compositor_realize_on_domain_shared")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "domain_img")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_realize_on_domain_vector)
+ .additional_info("compositor_realize_on_domain_shared")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "domain_img")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_realize_on_domain_float)
+ .additional_info("compositor_realize_on_domain_shared")
+ .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "domain_img")
+ .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_screen_lens_distortion_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_screen_lens_distortion_info.hh
new file mode 100644
index 00000000000..c42f2b328d4
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/infos/compositor_screen_lens_distortion_info.hh
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_screen_lens_distortion_shared)
+ .local_group_size(16, 16)
+ .push_constant(Type::VEC3, "chromatic_distortion")
+ .push_constant(Type::FLOAT, "scale")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_screen_lens_distortion.glsl");
+
+GPU_SHADER_CREATE_INFO(compositor_screen_lens_distortion)
+ .additional_info("compositor_screen_lens_distortion_shared")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_screen_lens_distortion_jitter)
+ .additional_info("compositor_screen_lens_distortion_shared")
+ .define("JITTER")
+ .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_set_alpha_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_set_alpha_info.hh
new file mode 100644
index 00000000000..ca28194e921
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/infos/compositor_set_alpha_info.hh
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_set_alpha)
+ .local_group_size(16, 16)
+ .sampler(0, ImageType::FLOAT_2D, "image_tx")
+ .sampler(1, ImageType::FLOAT_2D, "alpha_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_set_alpha.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_split_viewer_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_split_viewer_info.hh
new file mode 100644
index 00000000000..d5793b0ce59
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/infos/compositor_split_viewer_info.hh
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_split_viewer_shared)
+ .local_group_size(16, 16)
+ .push_constant(Type::FLOAT, "split_ratio")
+ .push_constant(Type::IVEC2, "view_size")
+ .sampler(0, ImageType::FLOAT_2D, "first_image_tx")
+ .sampler(1, ImageType::FLOAT_2D, "second_image_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_split_viewer.glsl");
+
+GPU_SHADER_CREATE_INFO(compositor_split_viewer_horizontal)
+ .additional_info("compositor_split_viewer_shared")
+ .define("SPLIT_HORIZONTAL")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_split_viewer_vertical)
+ .additional_info("compositor_split_viewer_shared")
+ .define("SPLIT_VERTICAL")
+ .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_alpha_over.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_alpha_over.glsl
new file mode 100644
index 00000000000..8e3e033147f
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_alpha_over.glsl
@@ -0,0 +1,48 @@
+void node_composite_alpha_over_mixed(
+ float factor, vec4 color, vec4 over_color, float premultiply_factor, out vec4 result)
+{
+ if (over_color.a <= 0.0) {
+ result = color;
+ }
+ else if (factor == 1.0 && over_color.a >= 1.0) {
+ result = over_color;
+ }
+ else {
+ float add_factor = 1.0 - premultiply_factor + over_color.a * premultiply_factor;
+ float premultiplier = factor * add_factor;
+ float multiplier = 1.0 - factor * over_color.a;
+
+ result = multiplier * color + vec2(premultiplier, factor).xxxy * over_color;
+ }
+}
+
+void node_composite_alpha_over_key(float factor, vec4 color, vec4 over_color, out vec4 result)
+{
+ if (over_color.a <= 0.0) {
+ result = color;
+ }
+ else if (factor == 1.0 && over_color.a >= 1.0) {
+ result = over_color;
+ }
+ else {
+ result = mix(color, vec4(over_color.rgb, 1.0), factor * over_color.a);
+ }
+}
+
+void node_composite_alpha_over_premultiply(float factor,
+ vec4 color,
+ vec4 over_color,
+ out vec4 result)
+{
+ if (over_color.a < 0.0) {
+ result = color;
+ }
+ else if (factor == 1.0 && over_color.a >= 1.0) {
+ result = over_color;
+ }
+ else {
+ float multiplier = 1.0 - factor * over_color.a;
+
+ result = multiplier * color + factor * over_color;
+ }
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_bright_contrast.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_bright_contrast.glsl
new file mode 100644
index 00000000000..ce71b4fd8a4
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_bright_contrast.glsl
@@ -0,0 +1,38 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+/* The algorithm is by Werner D. Streidt
+ * (http://visca.com/ffactory/archives/5-99/msg00021.html)
+ * Extracted of OpenCV demhist.c
+ */
+
+#define FLT_EPSILON 1.192092896e-07F
+
+void node_composite_bright_contrast(
+ vec4 color, float brightness, float contrast, const float use_premultiply, out vec4 result)
+{
+ brightness /= 100.0;
+ float delta = contrast / 200.0;
+
+ float multiplier, offset;
+ if (contrast > 0.0) {
+ multiplier = 1.0 - delta * 2.0;
+ multiplier = 1.0 / max(multiplier, FLT_EPSILON);
+ offset = multiplier * (brightness - delta);
+ }
+ else {
+ delta *= -1.0;
+ multiplier = max(1.0 - delta * 2.0, 0.0);
+ offset = multiplier * brightness + delta;
+ }
+
+ if (use_premultiply != 0.0) {
+ color_alpha_unpremultiply(color, color);
+ }
+
+ result.rgb = color.rgb * multiplier + offset;
+ result.a = color.a;
+
+ if (use_premultiply != 0.0) {
+ color_alpha_premultiply(result, result);
+ }
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_channel_matte.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_channel_matte.glsl
new file mode 100644
index 00000000000..f2dcc9543f2
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_channel_matte.glsl
@@ -0,0 +1,52 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+#define CMP_NODE_CHANNEL_MATTE_CS_RGB 1.0
+#define CMP_NODE_CHANNEL_MATTE_CS_HSV 2.0
+#define CMP_NODE_CHANNEL_MATTE_CS_YUV 3.0
+#define CMP_NODE_CHANNEL_MATTE_CS_YCC 4.0
+
+void node_composite_channel_matte(vec4 color,
+ const float color_space,
+ const float matte_channel,
+ const vec2 limit_channels,
+ float max_limit,
+ float min_limit,
+ out vec4 result,
+ out float matte)
+{
+ vec4 channels;
+ if (color_space == CMP_NODE_CHANNEL_MATTE_CS_HSV) {
+ rgb_to_hsv(color, channels);
+ }
+ else if (color_space == CMP_NODE_CHANNEL_MATTE_CS_YUV) {
+ rgba_to_yuva_itu_709(color, channels);
+ }
+ else if (color_space == CMP_NODE_CHANNEL_MATTE_CS_YCC) {
+ rgba_to_ycca_itu_709(color, channels);
+ }
+ else {
+ channels = color;
+ }
+
+ float matte_value = channels[int(matte_channel)];
+ float limit_value = max(channels[int(limit_channels.x)], channels[int(limit_channels.y)]);
+
+ float alpha = 1.0 - (matte_value - limit_value);
+ if (alpha > max_limit) {
+ alpha = color.a;
+ }
+ else if (alpha < min_limit) {
+ alpha = 0.0;
+ }
+ else {
+ alpha = (alpha - min_limit) / (max_limit - min_limit);
+ }
+
+ matte = min(alpha, color.a);
+ result = color * matte;
+}
+
+#undef CMP_NODE_CHANNEL_MATTE_CS_RGB
+#undef CMP_NODE_CHANNEL_MATTE_CS_HSV
+#undef CMP_NODE_CHANNEL_MATTE_CS_YUV
+#undef CMP_NODE_CHANNEL_MATTE_CS_YCC
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_chroma_matte.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_chroma_matte.glsl
new file mode 100644
index 00000000000..5d6bea0c9db
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_chroma_matte.glsl
@@ -0,0 +1,43 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_math_utils.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+/* Algorithm from the book Video Demystified. Chapter 7. Chroma Keying. */
+void node_composite_chroma_matte(vec4 color,
+ vec4 key,
+ float acceptance,
+ float cutoff,
+ float falloff,
+ out vec4 result,
+ out float matte)
+{
+ vec4 color_ycca;
+ rgba_to_ycca_itu_709(color, color_ycca);
+ vec4 key_ycca;
+ rgba_to_ycca_itu_709(key, key_ycca);
+
+ /* Normalize the CrCb components into the [-1, 1] range. */
+ vec2 color_cc = color_ycca.yz * 2.0 - 1.0;
+ vec2 key_cc = key_ycca.yz * 2.0 - 1.0;
+
+ /* Rotate the color onto the space of the key such that x axis of the color space passes through
+ * the key color. */
+ color_cc = vector_to_rotation_matrix(key_cc * vec2(1.0, -1.0)) * color_cc;
+
+ /* Compute foreground key. If positive, the value is in the [0, 1] range. */
+ float foreground_key = color_cc.x - (abs(color_cc.y) / acceptance);
+
+ /* Negative foreground key values retain the original alpha. Positive values are scaled by the
+ * falloff, while colors that make an angle less than the cutoff angle get a zero alpha. */
+ float alpha = color.a;
+ if (foreground_key > 0.0) {
+ alpha = 1.0 - (foreground_key / falloff);
+
+ if (abs(atan(color_cc.y, color_cc.x)) < (cutoff / 2.0)) {
+ alpha = 0.0;
+ }
+ }
+
+ /* Compute output. */
+ matte = min(alpha, color.a);
+ result = color * matte;
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_balance.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_balance.glsl
new file mode 100644
index 00000000000..bffb94cdedb
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_balance.glsl
@@ -0,0 +1,34 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void node_composite_color_balance_lgg(
+ float factor, vec4 color, vec3 lift, vec3 gamma, vec3 gain, out vec4 result)
+{
+ lift = 2.0 - lift;
+ vec3 srgb_color = linear_rgb_to_srgb(color.rgb);
+ vec3 lift_balanced = ((srgb_color - 1.0) * lift) + 1.0;
+
+ vec3 gain_balanced = lift_balanced * gain;
+ gain_balanced = max(gain_balanced, vec3(0.0));
+
+ vec3 linear_color = srgb_to_linear_rgb(gain_balanced);
+ gamma = mix(gamma, vec3(1e-6), equal(gamma, vec3(0.0)));
+ vec3 gamma_balanced = pow(linear_color, 1.0 / gamma);
+
+ result.rgb = mix(color.rgb, gamma_balanced, min(factor, 1.0));
+ result.a = color.a;
+}
+
+void node_composite_color_balance_asc_cdl(float factor,
+ vec4 color,
+ vec3 offset,
+ vec3 power,
+ vec3 slope,
+ float offset_basis,
+ out vec4 result)
+{
+ offset += offset_basis;
+ vec3 balanced = color.rgb * slope + offset;
+ balanced = pow(max(balanced, vec3(0.0)), power);
+ result.rgb = mix(color.rgb, balanced, min(factor, 1.0));
+ result.a = color.a;
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_correction.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_correction.glsl
new file mode 100644
index 00000000000..9b4858f03be
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_correction.glsl
@@ -0,0 +1,87 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_math_utils.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void node_composite_color_correction(vec4 color,
+ float mask,
+ const vec3 enabled_channels,
+ float start_midtones,
+ float end_midtones,
+ float master_saturation,
+ float master_contrast,
+ float master_gamma,
+ float master_gain,
+ float master_lift,
+ float shadows_saturation,
+ float shadows_contrast,
+ float shadows_gamma,
+ float shadows_gain,
+ float shadows_lift,
+ float midtones_saturation,
+ float midtones_contrast,
+ float midtones_gamma,
+ float midtones_gain,
+ float midtones_lift,
+ float highlights_saturation,
+ float highlights_contrast,
+ float highlights_gamma,
+ float highlights_gain,
+ float highlights_lift,
+ const vec3 luminance_coefficients,
+ out vec4 result)
+{
+ const float margin = 0.10;
+ const float margin_divider = 0.5 / margin;
+ float level = (color.r + color.g + color.b) / 3.0;
+ float level_shadows = 0.0;
+ float level_midtones = 0.0;
+ float level_highlights = 0.0;
+ if (level < (start_midtones - margin)) {
+ level_shadows = 1.0;
+ }
+ else if (level < (start_midtones + margin)) {
+ level_midtones = ((level - start_midtones) * margin_divider) + 0.5;
+ level_shadows = 1.0 - level_midtones;
+ }
+ else if (level < (end_midtones - margin)) {
+ level_midtones = 1.0;
+ }
+ else if (level < (end_midtones + margin)) {
+ level_highlights = ((level - end_midtones) * margin_divider) + 0.5;
+ level_midtones = 1.0 - level_highlights;
+ }
+ else {
+ level_highlights = 1.0;
+ }
+
+ float contrast = level_shadows * shadows_contrast;
+ contrast += level_midtones * midtones_contrast;
+ contrast += level_highlights * highlights_contrast;
+ contrast *= master_contrast;
+ float saturation = level_shadows * shadows_saturation;
+ saturation += level_midtones * midtones_saturation;
+ saturation += level_highlights * highlights_saturation;
+ saturation *= master_saturation;
+ float gamma = level_shadows * shadows_gamma;
+ gamma += level_midtones * midtones_gamma;
+ gamma += level_highlights * highlights_gamma;
+ gamma *= master_gamma;
+ float gain = level_shadows * shadows_gain;
+ gain += level_midtones * midtones_gain;
+ gain += level_highlights * highlights_gain;
+ gain *= master_gain;
+ float lift = level_shadows * shadows_lift;
+ lift += level_midtones * midtones_lift;
+ lift += level_highlights * highlights_lift;
+ lift += master_lift;
+
+ float inverse_gamma = 1.0 / gamma;
+ float luma = get_luminance(color.rgb, luminance_coefficients);
+
+ vec3 corrected = luma + saturation * (color.rgb - luma);
+ corrected = 0.5 + (corrected - 0.5) * contrast;
+ corrected = fallback_pow(corrected * gain + lift, inverse_gamma, corrected);
+ corrected = mix(color.rgb, corrected, min(mask, 1.0));
+
+ result.rgb = mix(corrected, color.rgb, equal(enabled_channels, vec3(0.0)));
+ result.a = color.a;
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_matte.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_matte.glsl
new file mode 100644
index 00000000000..038471bc1bc
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_matte.glsl
@@ -0,0 +1,27 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void node_composite_color_matte(vec4 color,
+ vec4 key,
+ float hue_epsilon,
+ float saturation_epsilon,
+ float value_epsilon,
+ out vec4 result,
+ out float matte)
+
+{
+ vec4 color_hsva;
+ rgb_to_hsv(color, color_hsva);
+ vec4 key_hsva;
+ rgb_to_hsv(key, key_hsva);
+
+ bool is_within_saturation = distance(color_hsva.y, key_hsva.y) < saturation_epsilon;
+ bool is_within_value = distance(color_hsva.z, key_hsva.z) < value_epsilon;
+ bool is_within_hue = distance(color_hsva.x, key_hsva.x) < hue_epsilon;
+ /* Hue wraps around, so check the distance around the boundary. */
+ float min_hue = min(color_hsva.x, key_hsva.x);
+ float max_hue = max(color_hsva.x, key_hsva.x);
+ is_within_hue = is_within_hue || ((min_hue + (1.0 - max_hue)) < hue_epsilon);
+
+ matte = (is_within_hue && is_within_saturation && is_within_value) ? 0.0 : color.a;
+ result = color * matte;
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_spill.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_spill.glsl
new file mode 100644
index 00000000000..0adad53ad80
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_spill.glsl
@@ -0,0 +1,13 @@
+void node_composite_color_spill(vec4 color,
+ float factor,
+ const float spill_channel,
+ vec3 spill_scale,
+ const vec2 limit_channels,
+ float limit_scale,
+ out vec4 result)
+{
+ float average_limit = (color[int(limit_channels.x)] + color[int(limit_channels.y)]) / 2.0;
+ float map = factor * color[int(spill_channel)] - limit_scale * average_limit;
+ result.rgb = map > 0.0 ? color.rgb + spill_scale * map : color.rgb;
+ result.a = color.a;
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_to_luminance.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_to_luminance.glsl
new file mode 100644
index 00000000000..bcdd625bd4f
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_to_luminance.glsl
@@ -0,0 +1,6 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void color_to_luminance(vec4 color, const vec3 luminance_coefficients, out float result)
+{
+ result = get_luminance(color.rgb, luminance_coefficients);
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_difference_matte.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_difference_matte.glsl
new file mode 100644
index 00000000000..d769cadce3c
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_difference_matte.glsl
@@ -0,0 +1,10 @@
+void node_composite_difference_matte(
+ vec4 color, vec4 key, float tolerance, float falloff, out vec4 result, out float matte)
+{
+ vec4 difference = abs(color - key);
+ float average_difference = (difference.r + difference.g + difference.b) / 3.0;
+ bool is_opaque = average_difference > tolerance + falloff;
+ float alpha = is_opaque ? color.a : (max(0.0, average_difference - tolerance) / falloff);
+ matte = min(alpha, color.a);
+ result = color * matte;
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_distance_matte.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_distance_matte.glsl
new file mode 100644
index 00000000000..9beed66826c
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_distance_matte.glsl
@@ -0,0 +1,26 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void node_composite_distance_matte_rgba(
+ vec4 color, vec4 key, float tolerance, float falloff, out vec4 result, out float matte)
+{
+ float difference = distance(color.rgb, key.rgb);
+ bool is_opaque = difference > tolerance + falloff;
+ float alpha = is_opaque ? color.a : max(0.0, difference - tolerance) / falloff;
+ matte = min(alpha, color.a);
+ result = color * matte;
+}
+
+void node_composite_distance_matte_ycca(
+ vec4 color, vec4 key, float tolerance, float falloff, out vec4 result, out float matte)
+{
+ vec4 color_ycca;
+ rgba_to_ycca_itu_709(color, color_ycca);
+ vec4 key_ycca;
+ rgba_to_ycca_itu_709(key, key_ycca);
+
+ float difference = distance(color_ycca.yz, key_ycca.yz);
+ bool is_opaque = difference > tolerance + falloff;
+ float alpha = is_opaque ? color.a : max(0.0, difference - tolerance) / falloff;
+ matte = min(alpha, color.a);
+ result = color * matte;
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_exposure.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_exposure.glsl
new file mode 100644
index 00000000000..f246635a91e
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_exposure.glsl
@@ -0,0 +1,6 @@
+void node_composite_exposure(vec4 color, float exposure, out vec4 result)
+{
+ float multiplier = exp2(exposure);
+ result.rgb = color.rgb * multiplier;
+ result.a = color.a;
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_gamma.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_gamma.glsl
new file mode 100644
index 00000000000..53070d4b0e2
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_gamma.glsl
@@ -0,0 +1,7 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_math_utils.glsl)
+
+void node_composite_gamma(vec4 color, float gamma, out vec4 result)
+{
+ result.rgb = fallback_pow(color.rgb, gamma, color.rgb);
+ result.a = color.a;
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_hue_correct.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_hue_correct.glsl
new file mode 100644
index 00000000000..99eb125cdf2
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_hue_correct.glsl
@@ -0,0 +1,39 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+/* Curve maps are stored in sampler objects that are evaluated in the [0, 1] range, so normalize
+ * parameters accordingly. */
+#define NORMALIZE_PARAMETER(parameter, minimum, range) ((parameter - minimum) * range)
+
+void node_composite_hue_correct(float factor,
+ vec4 color,
+ sampler1DArray curve_map,
+ const float layer,
+ vec3 minimums,
+ vec3 range_dividers,
+ out vec4 result)
+{
+ vec4 hsv;
+ rgb_to_hsv(color, hsv);
+
+ /* First, adjust the hue channel on its own, since corrections in the saturation and value
+ * channels depends on the new value of the hue, not its original value. A curve map value of 0.5
+ * means no change in hue, so adjust the value to get an identity at 0.5. Since the identity of
+ * addition is 0, we subtract 0.5 (0.5 - 0.5 = 0). */
+ const float hue_parameter = NORMALIZE_PARAMETER(hsv.x, minimums.x, range_dividers.x);
+ hsv.x += texture(curve_map, vec2(hue_parameter, layer)).x - 0.5;
+
+ /* Second, adjust the saturation and value based on the new value of the hue. A curve map value
+ * of 0.5 means no change in hue, so adjust the value to get an identity at 0.5. Since the
+ * identity of duplication is 1, we multiply by 2 (0.5 * 2 = 1). */
+ vec2 parameters = NORMALIZE_PARAMETER(hsv.x, minimums.yz, range_dividers.yz);
+ hsv.y *= texture(curve_map, vec2(parameters.x, layer)).y * 2.0;
+ hsv.z *= texture(curve_map, vec2(parameters.y, layer)).z * 2.0;
+
+ /* Sanitize the new hue and saturation values. */
+ hsv.x = fract(hsv.x);
+ hsv.y = clamp(hsv.y, 0.0, 1.0);
+
+ hsv_to_rgb(hsv, result);
+
+ result = mix(color, result, factor);
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_hue_saturation_value.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_hue_saturation_value.glsl
new file mode 100644
index 00000000000..dd5eb33d318
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_hue_saturation_value.glsl
@@ -0,0 +1,16 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void node_composite_hue_saturation_value(
+ vec4 color, float hue, float saturation, float value, float factor, out vec4 result)
+{
+ vec4 hsv;
+ rgb_to_hsv(color, hsv);
+
+ hsv.x = fract(hsv.x + hue + 0.5);
+ hsv.y = clamp(hsv.y * saturation, 0.0, 1.0);
+ hsv.z = hsv.z * value;
+
+ hsv_to_rgb(hsv, result);
+
+ result = mix(color, result, factor);
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_invert.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_invert.glsl
new file mode 100644
index 00000000000..59be746da7f
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_invert.glsl
@@ -0,0 +1,13 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void node_composite_invert(float fac, vec4 color, float do_rgb, float do_alpha, out vec4 result)
+{
+ result = color;
+ if (do_rgb != 0.0) {
+ result.rgb = 1.0 - result.rgb;
+ }
+ if (do_alpha != 0.0) {
+ result.a = 1.0 - result.a;
+ }
+ result = mix(color, result, fac);
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_luminance_matte.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_luminance_matte.glsl
new file mode 100644
index 00000000000..3647ac583fe
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_luminance_matte.glsl
@@ -0,0 +1,14 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void node_composite_luminance_matte(vec4 color,
+ float high,
+ float low,
+ const vec3 luminance_coefficients,
+ out vec4 result,
+ out float matte)
+{
+ float luminance = get_luminance(color.rgb, luminance_coefficients);
+ float alpha = clamp(0.0, 1.0, (luminance - low) / (high - low));
+ matte = min(alpha, color.a);
+ result = color * matte;
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_main.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_main.glsl
new file mode 100644
index 00000000000..27624223dbc
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_main.glsl
@@ -0,0 +1,7 @@
+/* The compute shader that will be dispatched by the compositor ShaderOperation. It just calls the
+ * evaluate function that will be dynamically generated and appended to this shader in the
+ * ShaderOperation::generate_code method. */
+void main()
+{
+ evaluate();
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_map_value.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_map_value.glsl
new file mode 100644
index 00000000000..20874b4ef44
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_map_value.glsl
@@ -0,0 +1,56 @@
+/* An arbitrary value determined by Blender. */
+#define BLENDER_ZMAX 10000.0
+
+void node_composite_map_range(float value,
+ float from_min,
+ float from_max,
+ float to_min,
+ float to_max,
+ const float should_clamp,
+ out float result)
+{
+ if (abs(from_max - from_min) < 1e-6) {
+ result = 0.0;
+ }
+ else {
+ if (value >= -BLENDER_ZMAX && value <= BLENDER_ZMAX) {
+ result = (value - from_min) / (from_max - from_min);
+ result = to_min + result * (to_max - to_min);
+ }
+ else if (value > BLENDER_ZMAX) {
+ result = to_max;
+ }
+ else {
+ result = to_min;
+ }
+
+ if (should_clamp != 0.0) {
+ if (to_max > to_min) {
+ result = clamp(result, to_min, to_max);
+ }
+ else {
+ result = clamp(result, to_max, to_min);
+ }
+ }
+ }
+}
+
+void node_composite_map_value(float value,
+ float offset,
+ float size,
+ const float use_min,
+ float min,
+ const float use_max,
+ float max,
+ out float result)
+{
+ result = (value + offset) * size;
+
+ if (use_min != 0.0 && result < min) {
+ result = min;
+ }
+
+ if (use_max != 0.0 && result > max) {
+ result = max;
+ }
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_normal.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_normal.glsl
new file mode 100644
index 00000000000..a2e3b6c4aaa
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_normal.glsl
@@ -0,0 +1,9 @@
+void node_composite_normal(vec3 input_vector,
+ vec3 input_normal,
+ out vec3 result_normal,
+ out float result_dot)
+{
+ vec3 normal = normalize(input_normal);
+ result_normal = normal;
+ result_dot = -dot(input_vector, normal);
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_posterize.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_posterize.glsl
new file mode 100644
index 00000000000..ee8ae234abe
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_posterize.glsl
@@ -0,0 +1,6 @@
+void node_composite_posterize(vec4 color, float steps, out vec4 result)
+{
+ steps = clamp(steps, 2.0, 1024.0);
+ result = floor(color * steps) / steps;
+ result.a = color.a;
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_separate_combine.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_separate_combine.glsl
new file mode 100644
index 00000000000..d72d2260394
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_separate_combine.glsl
@@ -0,0 +1,132 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+/* ** Combine/Separate XYZ ** */
+
+void node_composite_combine_xyz(float x, float y, float z, out vec3 vector)
+{
+ vector = vec3(x, y, z);
+}
+
+void node_composite_separate_xyz(vec3 vector, out float x, out float y, out float z)
+{
+ x = vector.x;
+ y = vector.y;
+ z = vector.z;
+}
+
+/* ** Combine/Separate RGBA ** */
+
+void node_composite_combine_rgba(float r, float g, float b, float a, out vec4 color)
+{
+ color = vec4(r, g, b, a);
+}
+
+void node_composite_separate_rgba(vec4 color, out float r, out float g, out float b, out float a)
+{
+ r = color.r;
+ g = color.g;
+ b = color.b;
+ a = color.a;
+}
+
+/* ** Combine/Separate HSVA ** */
+
+void node_composite_combine_hsva(float h, float s, float v, float a, out vec4 color)
+{
+ hsv_to_rgb(vec4(h, s, v, a), color);
+}
+
+void node_composite_separate_hsva(vec4 color, out float h, out float s, out float v, out float a)
+{
+ vec4 hsva;
+ rgb_to_hsv(color, hsva);
+ h = hsva.x;
+ s = hsva.y;
+ v = hsva.z;
+ a = hsva.a;
+}
+
+/* ** Combine/Separate HSLA ** */
+
+void node_composite_combine_hsla(float h, float s, float l, float a, out vec4 color)
+{
+ hsl_to_rgb(vec4(h, s, l, a), color);
+}
+
+void node_composite_separate_hsla(vec4 color, out float h, out float s, out float l, out float a)
+{
+ vec4 hsla;
+ rgb_to_hsl(color, hsla);
+ h = hsla.x;
+ s = hsla.y;
+ l = hsla.z;
+ a = hsla.a;
+}
+
+/* ** Combine/Separate YCCA ** */
+
+void node_composite_combine_ycca_itu_601(float y, float cb, float cr, float a, out vec4 color)
+{
+ ycca_to_rgba_itu_601(vec4(y, cb, cr, a), color);
+}
+
+void node_composite_combine_ycca_itu_709(float y, float cb, float cr, float a, out vec4 color)
+{
+ ycca_to_rgba_itu_709(vec4(y, cb, cr, a), color);
+}
+
+void node_composite_combine_ycca_jpeg(float y, float cb, float cr, float a, out vec4 color)
+{
+ ycca_to_rgba_jpeg(vec4(y, cb, cr, a), color);
+}
+
+void node_composite_separate_ycca_itu_601(
+ vec4 color, out float y, out float cb, out float cr, out float a)
+{
+ vec4 ycca;
+ rgba_to_ycca_itu_601(color, ycca);
+ y = ycca.x;
+ cb = ycca.y;
+ cr = ycca.z;
+ a = ycca.a;
+}
+
+void node_composite_separate_ycca_itu_709(
+ vec4 color, out float y, out float cb, out float cr, out float a)
+{
+ vec4 ycca;
+ rgba_to_ycca_itu_709(color, ycca);
+ y = ycca.x;
+ cb = ycca.y;
+ cr = ycca.z;
+ a = ycca.a;
+}
+
+void node_composite_separate_ycca_jpeg(
+ vec4 color, out float y, out float cb, out float cr, out float a)
+{
+ vec4 ycca;
+ rgba_to_ycca_jpeg(color, ycca);
+ y = ycca.x;
+ cb = ycca.y;
+ cr = ycca.z;
+ a = ycca.a;
+}
+
+/* ** Combine/Separate YUVA ** */
+
+void node_composite_combine_yuva_itu_709(float y, float u, float v, float a, out vec4 color)
+{
+ yuva_to_rgba_itu_709(vec4(y, u, v, a), color);
+}
+
+void node_composite_separate_yuva_itu_709(
+ vec4 color, out float y, out float u, out float v, out float a)
+{
+ vec4 yuva;
+ rgba_to_yuva_itu_709(color, yuva);
+ y = yuva.x;
+ u = yuva.y;
+ v = yuva.z;
+ a = yuva.a;
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_set_alpha.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_set_alpha.glsl
new file mode 100644
index 00000000000..95380d1ed0f
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_set_alpha.glsl
@@ -0,0 +1,9 @@
+void node_composite_set_alpha_apply(vec4 color, float alpha, out vec4 result)
+{
+ result = color * alpha;
+}
+
+void node_composite_set_alpha_replace(vec4 color, float alpha, out vec4 result)
+{
+ result = vec4(color.rgb, alpha);
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_store_output.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_store_output.glsl
new file mode 100644
index 00000000000..7fba26907b5
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_store_output.glsl
@@ -0,0 +1,26 @@
+/* The following functions are called to store the given value in the output identified by the
+ * given ID. The ID is an unsigned integer that is encoded in a float, so floatBitsToUint is called
+ * to get the actual identifier. The functions have an output value as their last argument that is
+ * used to establish an output link that is then used to track the nodes that contribute to the
+ * output of the compositor node tree.
+ *
+ * The store_[float|vector|color] functions are dynamically generated in
+ * ShaderOperation::generate_code_for_outputs. */
+
+void node_compositor_store_output_float(const float id, float value, out float out_value)
+{
+ store_float(floatBitsToUint(id), value);
+ out_value = value;
+}
+
+void node_compositor_store_output_vector(const float id, vec3 vector, out vec3 out_vector)
+{
+ store_vector(floatBitsToUint(id), vector);
+ out_vector = vector;
+}
+
+void node_compositor_store_output_color(const float id, vec4 color, out vec4 out_color)
+{
+ store_color(floatBitsToUint(id), color);
+ out_color = color;
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_texture_utilities.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_texture_utilities.glsl
new file mode 100644
index 00000000000..00e9a391097
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_texture_utilities.glsl
@@ -0,0 +1,25 @@
+/* A shorthand for 1D textureSize with a zero LOD. */
+int texture_size(sampler1D sampler)
+{
+ return textureSize(sampler, 0);
+}
+
+/* A shorthand for 1D texelFetch with zero LOD and bounded access clamped to border. */
+vec4 texture_load(sampler1D sampler, int x)
+{
+ const int texture_bound = texture_size(sampler) - 1;
+ return texelFetch(sampler, clamp(x, 0, texture_bound), 0);
+}
+
+/* A shorthand for 2D textureSize with a zero LOD. */
+ivec2 texture_size(sampler2D sampler)
+{
+ return textureSize(sampler, 0);
+}
+
+/* A shorthand for 2D texelFetch with zero LOD and bounded access clamped to border. */
+vec4 texture_load(sampler2D sampler, ivec2 texel)
+{
+ const ivec2 texture_bounds = texture_size(sampler) - ivec2(1);
+ return texelFetch(sampler, clamp(texel, ivec2(0), texture_bounds), 0);
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_type_conversion.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_type_conversion.glsl
new file mode 100644
index 00000000000..75c76fd7341
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_type_conversion.glsl
@@ -0,0 +1,29 @@
+float float_from_vec4(vec4 vector)
+{
+ return dot(vector.rgb, vec3(1.0)) / 3.0;
+}
+
+float float_from_vec3(vec3 vector)
+{
+ return dot(vector, vec3(1.0)) / 3.0;
+}
+
+vec3 vec3_from_vec4(vec4 vector)
+{
+ return vector.rgb;
+}
+
+vec3 vec3_from_float(float value)
+{
+ return vec3(value);
+}
+
+vec4 vec4_from_vec3(vec3 vector)
+{
+ return vec4(vector, 1.0);
+}
+
+vec4 vec4_from_float(float value)
+{
+ return vec4(vec3(value), 1.0);
+}
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_noise.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_noise.glsl
index 881e38ea11a..480334f9bbd 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_noise.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_noise.glsl
@@ -13,7 +13,6 @@
* + + |
* @ + + + + @ @------> x
* v0 v1
- *
*/
float bi_mix(float v0, float v1, float v2, float v3, float x, float y)
{
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_tex_voronoi.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_tex_voronoi.glsl
index 0fb8ef15f5f..aac3d98b43b 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_tex_voronoi.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_tex_voronoi.glsl
@@ -15,7 +15,6 @@
*
* With optimization to change -2..2 scan window to -1..1 for better performance,
* as explained in https://www.shadertoy.com/view/llG3zy.
- *
*/
/* **** 1D Voronoi **** */
diff --git a/source/blender/gpu/tests/gpu_shader_test.cc b/source/blender/gpu/tests/gpu_shader_test.cc
index ab1409dfcde..35ffc647c97 100644
--- a/source/blender/gpu/tests/gpu_shader_test.cc
+++ b/source/blender/gpu/tests/gpu_shader_test.cc
@@ -14,8 +14,6 @@
#include "gpu_testing.hh"
-#include "GPU_glew.h"
-
namespace blender::gpu::tests {
static void test_gpu_shader_compute_2d()