[Bf-blender-cvs] [6f92c8ceaca] temp-viewport-compositor-compiler: Viewport Compositor: Compute operations stream

Omar Emara noreply at git.blender.org
Wed Feb 16 16:42:57 CET 2022


Commit: 6f92c8ceacae59ae8366e5d2955814f15711ad9c
Author: Omar Emara
Date:   Wed Feb 16 17:39:54 2022 +0200
Branches: temp-viewport-compositor-compiler
https://developer.blender.org/rB6f92c8ceacae59ae8366e5d2955814f15711ad9c

Viewport Compositor: Compute operations stream

This patch implements the necessary componenets for compilling the node
schedule into an operations stream that can be executed by the
evaluator.

===================================================================

M	source/blender/blenkernel/BKE_node.h
M	source/blender/draw/engines/compositor/compositor_engine.cc
M	source/blender/draw/engines/compositor/compositor_shader.cc
M	source/blender/draw/engines/compositor/compositor_shader.hh
M	source/blender/nodes/NOD_compositor_execute.hh
M	source/blender/nodes/intern/node_compositor_execute.cc

===================================================================

diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index c57224d95a3..2f255bde0ae 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -126,10 +126,10 @@ namespace fn {
 class CPPType;
 class MFDataType;
 }  // namespace fn
-namespace compositor {
+namespace viewport_compositor {
 class Context;
 class NodeOperation;
-}  // namespace compositor
+}  // namespace viewport_compositor
 }  // namespace blender
 
 using CPPTypeHandle = blender::fn::CPPType;
@@ -144,11 +144,11 @@ using SocketGetGeometryNodesCPPValueFunction = void (*)(const struct bNodeSocket
 using NodeGatherSocketLinkOperationsFunction =
     void (*)(blender::nodes::GatherLinkSearchOpParams &params);
 
-using NodeCompositorGetOperationFunction = blender::compositor::NodeOperation (*)(
-    blender::compositor::Context &context, blender::nodes::DNode &node);
+using NodeGetCompositorOperationFunction = blender::viewport_compositor::NodeOperation
+    *(*)(blender::viewport_compositor::Context &context, blender::nodes::DNode node);
 
 #else
-typedef void *NodeCompositorGetOperationFunction;
+typedef void *NodeGetCompositorOperationFunction;
 typedef void *NodeMultiFunctionBuildFunction;
 typedef void *NodeGeometryExecFunction;
 typedef void *NodeDeclareFunction;
@@ -331,8 +331,8 @@ typedef struct bNodeType {
   /* gpu */
   NodeGPUExecFunction gpu_fn;
 
-  /* Execute a compositor node. */
-  NodeCompositorGetOperationFunction compositor_get_operation;
+  /* Get an instance of this node's compositor operation. */
+  NodeGetCompositorOperationFunction get_compositor_operation;
 
   /* Build a multi-function for this node. */
   NodeMultiFunctionBuildFunction build_multi_function;
diff --git a/source/blender/draw/engines/compositor/compositor_engine.cc b/source/blender/draw/engines/compositor/compositor_engine.cc
index 7b86b1592b3..021e916ee52 100644
--- a/source/blender/draw/engines/compositor/compositor_engine.cc
+++ b/source/blender/draw/engines/compositor/compositor_engine.cc
@@ -16,12 +16,6 @@
  * Copyright 2021, Blender Foundation.
  */
 
-/** \file
- * \ingroup draw_engine
- *
- * Engine processing the render buffer using GLSL to apply the scene compositing node tree.
- */
-
 #include "DNA_scene_types.h"
 
 #include "DRW_render.h"
@@ -34,9 +28,10 @@
 
 #include "compositor_shader.hh"
 
-namespace blender::compositor {
+namespace blender::viewport_compositor {
 
 class DRWTexturePool : public TexturePool {
+ public:
   GPUTexture *allocate_texture(int width, int height, eGPUTextureFormat format) override
   {
     DrawEngineType *owner = (DrawEngineType *)this;
@@ -45,6 +40,8 @@ class DRWTexturePool : public TexturePool {
 };
 
 class DRWContext : public Context {
+ public:
+  using Context::Context;
   GPUTexture *get_viewport_texture() override
   {
     return DRW_viewport_texture_list_get()->color;
@@ -56,201 +53,61 @@ class DRWContext : public Context {
   }
 };
 
-/* Keep in sync with CompositorData in compositor_lib.glsl. */
-typedef struct CompositorData {
-  float luminance_coefficients[3];
-  float frame_number;
-} CompositorData;
-
-BLI_STATIC_ASSERT_ALIGN(CompositorData, 16)
-
-static ShaderModule *g_shader_module = nullptr;
-
-class Instance {
- public:
-  ShaderModule &shaders;
-
- private:
-  /** TODO(fclem) multipass. */
-  DRWPass *pass_;
-  /** A UBO storing CompositorData. */
-  GPUUniformBuf *ubo_;
-  GPUMaterial *gpumat_;
-  /** Temp buffers to hold intermediate results or the input color. */
-  GPUTexture *tmp_buffer_ = nullptr;
-  GPUFrameBuffer *tmp_fb_ = nullptr;
-
-  bool enabled_;
-
- public:
-  Instance(ShaderModule &shader_module) : shaders(shader_module)
-  {
-    ubo_ = GPU_uniformbuf_create_ex(sizeof(CompositorData), &ubo_, "CompositorData");
-  };
-
-  ~Instance()
-  {
-    GPU_uniformbuf_free(ubo_);
-    GPU_FRAMEBUFFER_FREE_SAFE(tmp_fb_);
-  }
-
-  void init()
-  {
-    const DRWContextState *ctx_state = DRW_context_state_get();
-    Scene *scene = ctx_state->scene;
-    enabled_ = scene->use_nodes && scene->nodetree;
-
-    if (!enabled_) {
-      return;
-    }
-
-    gpumat_ = shaders.material_get(scene);
-    enabled_ = GPU_material_status(gpumat_) == GPU_MAT_SUCCESS;
-
-    if (!enabled_) {
-      return;
-    }
-
-    /* Create temp double buffer to render to or copy source to. */
-    /* TODO(fclem) with multipass compositing we might need more than one temp buffer. */
-    DrawEngineType *owner = (DrawEngineType *)g_shader_module;
-    eGPUTextureFormat format = GPU_texture_format(DRW_viewport_texture_list_get()->color);
-    tmp_buffer_ = DRW_texture_pool_query_fullscreen(format, owner);
-
-    GPU_framebuffer_ensure_config(&tmp_fb_,
-                                  {
-                                      GPU_ATTACHMENT_NONE,
-                                      GPU_ATTACHMENT_TEXTURE(tmp_buffer_),
-                                  });
-  }
-
-  void sync()
-  {
-    if (!enabled_) {
-      return;
-    }
-
-    pass_ = DRW_pass_create("Compositing", DRW_STATE_WRITE_COLOR);
-    DRWShadingGroup *grp = DRW_shgroup_material_create(gpumat_, pass_);
-
-    sync_compositor_ubo(grp);
-
-    ListBase rpasses = GPU_material_render_passes(gpumat_);
-    LISTBASE_FOREACH (GPUMaterialRenderPass *, gpu_rp, &rpasses) {
-      DRWRenderPass *drw_rp = DRW_render_pass_find(
-          gpu_rp->scene, gpu_rp->viewlayer, gpu_rp->pass_type);
-      if (drw_rp) {
-        DRW_shgroup_uniform_texture_ex(
-            grp, gpu_rp->sampler_name, drw_rp->pass_tx, gpu_rp->sampler_state);
-      }
-    }
-
-    DRW_shgroup_call_procedural_triangles(grp, nullptr, 1);
-  }
-
-  void draw()
-  {
-    if (!enabled_) {
-      return;
-    }
-
-    DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
-
-    /* Reset default view. */
-    DRW_view_set_active(nullptr);
-
-    GPU_framebuffer_bind(tmp_fb_);
-    DRW_draw_pass(pass_);
-
-    /* TODO(fclem) only copy if we need to. Only possible in multipass.
-     * This is because dtxl->color can also be an input to the compositor. */
-    GPU_texture_copy(dtxl->color, tmp_buffer_);
-  }
-
- private:
-  void sync_compositor_ubo(DRWShadingGroup *shading_group)
-  {
-    CompositorData compositor_data;
-    IMB_colormanagement_get_luminance_coefficients(compositor_data.luminance_coefficients);
-    compositor_data.frame_number = (float)DRW_context_state_get()->scene->r.cfra;
-
-    GPU_uniformbuf_update(ubo_, &compositor_data);
-    DRW_shgroup_uniform_block(shading_group, "compositor_block", ubo_);
-  }
-};
-
-}  // namespace blender::compositor
-
-/* -------------------------------------------------------------------- */
-/** \name C interface
- * \{ */
-
-using namespace blender::compositor;
-
-typedef struct COMPOSITOR_Data {
-  DrawEngineType *engine_type;
-  DRWViewportEmptyList *fbl;
-  DRWViewportEmptyList *txl;
-  DRWViewportEmptyList *psl;
-  DRWViewportEmptyList *stl;
-  Instance *instance_data;
-} COMPOSITOR_Data;
-
-static void compositor_engine_init(void *vedata)
+/* Get the scene which includes the compositor node tree. */
+static const Scene *get_scene()
 {
-  COMPOSITOR_Data *ved = (COMPOSITOR_Data *)vedata;
+  return DRW_context_state_get()->scene;
+}
 
-  if (g_shader_module == nullptr) {
-    /* TODO(fclem) threadsafety. */
-    g_shader_module = new ShaderModule();
+/* It is sufficient to check for the scene node tree because the engine will not be enabled when
+ * the viewport shading option is disabled. */
+static bool is_compositor_enabled()
+{
+  const Scene *scene = get_scene();
+  if (scene->use_nodes && scene->nodetree) {
+    return true;
   }
+  return false;
+}
 
-  if (ved->instance_data == nullptr) {
-    ved->instance_data = new Instance(*g_shader_module);
+static void draw()
+{
+  if (!is_compositor_enabled()) {
+    return;
   }
 
-  ved->instance_data->init();
-}
+  /* Reset default view. */
+  DRW_view_set_active(nullptr);
 
-static void compositor_engine_free(void)
-{
-  delete g_shader_module;
-  g_shader_module = nullptr;
+  DRWTexturePool texture_pool;
+  DRWContext context(texture_pool);
+  const Scene *scene = get_scene();
+  Evaluator evaluator(context, scene->nodetree);
+  evaluator.evaluate();
 }
 
-static void compositor_instance_free(void *instance_data_)
-{
-  Instance *instance_data = reinterpret_cast<Instance *>(instance_data_);
-  delete instance_data;
-}
+}  // namespace blender::viewport_compositor
 
-static void compositor_cache_init(void *vedata)
-{
-  COMPOSITOR_Data *ved = (COMPOSITOR_Data *)vedata;
-  ved->instance_data->sync();
-}
+using namespace blender::viewport_compositor;
 
-static void compositor_draw(void *vedata)
+static void compositor_draw(void *UNUSED(data))
 {
-  COMPOSITOR_Data *ved = (COMPOSITOR_Data *)vedata;
-  ved->instance_data->draw();
+  draw();
 }
 
-/** \} */
-
 extern "C" {
 
-static const DrawEngineDataSize compositor_data_size = DRW_VIEWPORT_DATA_SIZE(COMPOSITOR_Data);
+static const DrawEngineDataSize compositor_data_size = {};
 
 DrawEngineType draw_engine_compositor_type = {
     nullptr,
     nullptr,
     N_("Compositor"),
     &compositor_data_size,
-    &compositor_engine_init,
-    &compositor_engine_free,
-    &compositor_instance_free,
-    &compositor_cache_init,
+    nullptr,
+    nullptr,
+    nullptr,
+    nullptr,
     nullptr,
     nullptr,
     &compositor_draw,
diff --git a/source/blender/draw/engines/compositor/compositor_shader.cc b/source/blender/draw/engines/compositor/compositor_shader.cc
index d9e8e4b5f79..17bc28ce759 100644
--- a/source/blender/draw/engines/compositor/compositor_shader.cc
+++ b/source/blender/draw/engines/compositor/compositor_shader.cc
@@ -33,7 +33,7 @@ extern char datatoc_compositor_nodetree_eval_lib_glsl[];
 extern char datatoc_gpu_shader_codegen_lib_glsl[];
 }
 
-namespace blender::compositor {
+namespace blender::viewport_compositor {
 
 ShaderModule::ShaderModule()
 {
@@ -112,4 +112,4 @@ GPUMaterial *ShaderModule::material_get(Scene *scene)
   return DRW_shader_from_compositor(scene, shader_id, true, codegen_callback, this);
 }
 
-}  // namespace blender::compositor
+}  // namespace blender::viewport_compositor
diff --git a/source/blender/draw/engines/compositor/compositor_shader.hh b/source/blender/dra

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list