Commit: c6292918a36b302ab688cffaf4355e1730fdee08
Author: Antony Riakiotakis
Date:   Wed Oct 29 12:01:13 2014 +0100
Branches: viewport_experiments
https://developer.blender.org/rBc6292918a36b302ab688cffaf4355e1730fdee08

Framebuffer compositing:

* Cleanup compositing buffers better when not needed.

* Support passes for the dof effect through defines in main - easy
solution to allow not having too many files for one shader effect.

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

M       source/blender/gpu/GPU_compositing.h
M       source/blender/gpu/intern/gpu_compositing.c
M       source/blender/gpu/intern/gpu_extensions.c
M       source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl

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

diff --git a/source/blender/gpu/GPU_compositing.h 
b/source/blender/gpu/GPU_compositing.h
index a745801..d6c057e 100644
--- a/source/blender/gpu/GPU_compositing.h
+++ b/source/blender/gpu/GPU_compositing.h
@@ -43,12 +43,18 @@ struct Scene;
 /**** Public API *****/
 
 typedef enum GPUFXShaderEffect {
-       GPU_SHADER_FX_SSAO           =  (1<<0),
-       GPU_SHADER_FX_DEPTH_OF_FIELD =  (1<<1),
-       GPU_SHADER_FX_MAX            =  (1<<2),
+       /* Screen space ambient occlusion shader */
+       GPU_SHADER_FX_SSAO           = 1,
+
+       /* depth of field passes. Yep, quite a complex effect */
+       GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_ONE = 2,
+       GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_TWO = 3,
+       GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_THREE = 4,
+       GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FOUR = 5,
 } GPUFXShaderEffect;
 
-#define MAX_FX_SHADERS (GPU_SHADER_FX_MAX - 1)
+/* keep in synch with enum above! */
+#define MAX_FX_SHADERS 6
 
 /* generate a new FX compositor */
 GPUFX *GPU_create_fx_compositor(void);
diff --git a/source/blender/gpu/intern/gpu_compositing.c 
b/source/blender/gpu/intern/gpu_compositing.c
index 862e332..2c41ff3 100644
--- a/source/blender/gpu/intern/gpu_compositing.c
+++ b/source/blender/gpu/intern/gpu_compositing.c
@@ -102,6 +102,21 @@ GPUFX *GPU_create_fx_compositor(void)
        return fx;
 }
 
+static void cleanup_fx_dof_buffers(GPUFX *fx)
+{
+       if (fx->dof_near_coc_blurred_buffer) {
+               GPU_texture_free(fx->dof_near_coc_blurred_buffer);
+               fx->dof_near_coc_blurred_buffer = NULL;
+       }
+       if (fx->dof_near_coc_buffer) {
+               GPU_texture_free(fx->dof_near_coc_buffer);
+               fx->dof_near_coc_buffer = NULL;
+       }
+       if (fx->dof_near_coc_final_buffer) {
+               GPU_texture_free(fx->dof_near_coc_final_buffer);
+               fx->dof_near_coc_final_buffer = NULL;
+       }
+}
 
 static void cleanup_fx_gl_data(GPUFX *fx, bool do_fbo)
 {
@@ -123,18 +138,7 @@ static void cleanup_fx_gl_data(GPUFX *fx, bool do_fbo)
                fx->depth_buffer = NULL;
        }               
 
-       if (fx->dof_near_coc_blurred_buffer) {
-               GPU_texture_free(fx->dof_near_coc_blurred_buffer);
-               fx->dof_near_coc_blurred_buffer = NULL;
-       }
-       if (fx->dof_near_coc_buffer) {
-               GPU_texture_free(fx->dof_near_coc_buffer);
-               fx->dof_near_coc_buffer = NULL;
-       }
-       if (fx->dof_near_coc_final_buffer) {
-               GPU_texture_free(fx->dof_near_coc_final_buffer);
-               fx->dof_near_coc_final_buffer = NULL;
-       }
+       cleanup_fx_dof_buffers(fx);
 
        if (fx->jitter_buffer && do_fbo) {
                GPU_texture_free(fx->jitter_buffer);
@@ -202,6 +206,7 @@ bool GPU_initialize_fx_passes(GPUFX *fx, rcti *rect, rcti 
*scissor_rect, int fxf
 {
        int w = BLI_rcti_size_x(rect) + 1, h = BLI_rcti_size_y(rect) + 1;
        char err_out[256];
+       int num_passes = 0;
 
        fx->effects = 0;
 
@@ -210,6 +215,14 @@ bool GPU_initialize_fx_passes(GPUFX *fx, rcti *rect, rcti 
*scissor_rect, int fxf
                return false;
        }
        
+       fx->num_passes = 0;
+       /* dof really needs a ping-pong buffer to work */
+       if (fxflags & V3D_FX_DEPTH_OF_FIELD) {
+               num_passes++;
+       }
+       if (fxflags & V3D_FX_SSAO)
+               num_passes++;
+
        if (!fx->gbuffer) 
                fx->gbuffer = GPU_framebuffer_create();
        
@@ -238,35 +251,51 @@ bool GPU_initialize_fx_passes(GPUFX *fx, rcti *rect, rcti 
*scissor_rect, int fxf
        }
        
        /* create textures for dof effect */
-       if ((fxflags & V3D_FX_DEPTH_OF_FIELD) &&
-            (!fx->color_buffer_sec || !fx->dof_near_coc_buffer || 
!fx->dof_near_coc_blurred_buffer || !fx->dof_near_coc_final_buffer ||
-             w != fx->gbuffer_dim[0] || h != fx->gbuffer_dim[1]))
-       {
-               fx->dof_near_w = w / 4;
-               fx->dof_near_h = h / 4;
-
-               if (!(fx->color_buffer_sec = GPU_texture_create_2D(w, h, NULL, 
err_out))) {
-                       printf(".256%s\n", err_out);
-                       cleanup_fx_gl_data(fx, true);
-                       return false;
+       if (fxflags & V3D_FX_DEPTH_OF_FIELD) {
+               if (!fx->dof_near_coc_buffer || 
!fx->dof_near_coc_blurred_buffer || !fx->dof_near_coc_final_buffer) {
+                       fx->dof_near_w = w / 4;
+                       fx->dof_near_h = h / 4;
+
+                       if (!(fx->dof_near_coc_buffer = 
GPU_texture_create_2D(fx->dof_near_w, fx->dof_near_h, NULL, err_out))) {
+                               printf("%.256s\n", err_out);
+                               cleanup_fx_gl_data(fx, true);
+                               return false;
+                       }
+                       if (!(fx->dof_near_coc_blurred_buffer = 
GPU_texture_create_2D(fx->dof_near_w, fx->dof_near_h, NULL, err_out))) {
+                               printf("%.256s\n", err_out);
+                               cleanup_fx_gl_data(fx, true);
+                               return false;
+                       }
+                       if (!(fx->dof_near_coc_final_buffer = 
GPU_texture_create_2D(fx->dof_near_w, fx->dof_near_h, NULL, err_out))) {
+                               printf("%.256s\n", err_out);
+                               cleanup_fx_gl_data(fx, true);
+                               return false;
+                       }
                }
+       }
+       else {
+               /* cleanup unnecessary buffers */
+               cleanup_fx_dof_buffers(fx);
+       }
 
-               if (!(fx->dof_near_coc_buffer = 
GPU_texture_create_2D(fx->dof_near_w, fx->dof_near_h, NULL, err_out))) {
-                       printf("%.256s\n", err_out);
-                       cleanup_fx_gl_data(fx, true);
-                       return false;
-               }
-               if (!(fx->dof_near_coc_blurred_buffer = 
GPU_texture_create_2D(fx->dof_near_w, fx->dof_near_h, NULL, err_out))) {
-                       printf("%.256s\n", err_out);
-                       cleanup_fx_gl_data(fx, true);
-                       return false;
+       /* we need to pass data between shader stages, allocate an extra color 
buffer */
+       if (num_passes > 1) {
+               if(!fx->color_buffer_sec) {
+                       if (!(fx->color_buffer_sec = GPU_texture_create_2D(w, 
h, NULL, err_out))) {
+                               printf(".256%s\n", err_out);
+                               cleanup_fx_gl_data(fx, true);
+                               return false;
+                       }
                }
-               if (!(fx->dof_near_coc_final_buffer = 
GPU_texture_create_2D(fx->dof_near_w, fx->dof_near_h, NULL, err_out))) {
-                       printf("%.256s\n", err_out);
-                       cleanup_fx_gl_data(fx, true);
-                       return false;
+       }
+       else {
+               if (fx->color_buffer_sec) {
+                       GPU_framebuffer_texture_detach(fx->gbuffer, 
fx->color_buffer_sec);
+                       GPU_texture_free(fx->color_buffer_sec);
+                       fx->color_buffer_sec = NULL;
                }
        }
+
        /* bind the buffers */
        
        /* first depth buffer, because system assumes read/write buffers */
@@ -289,17 +318,12 @@ bool GPU_initialize_fx_passes(GPUFX *fx, rcti *rect, rcti 
*scissor_rect, int fxf
                                  w_sc, h_sc);
        }
        fx->effects = fxflags;
-       fx->num_passes = 0;
-       /* dof really needs a ping-pong buffer to work */
-       if (fxflags & V3D_FX_DEPTH_OF_FIELD) {
-               fx->num_passes++;
-       }
-       if (fxflags & V3D_FX_SSAO)
-               fx->num_passes++;
 
        fx->gbuffer_dim[0] = w;
        fx->gbuffer_dim[1] = h;
 
+       fx->num_passes = num_passes;
+
        return true;
 }
 
@@ -462,7 +486,7 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, struct View3D 
*v3d, struct RegionView3D
 
        /* second pass, dof */
        if (fx->effects & V3D_FX_DEPTH_OF_FIELD) {
-               fx_shader = 
GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD, rv3d->is_persp);
+               fx_shader = 
GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_ONE, 
rv3d->is_persp);
                if (fx_shader) {
                        float dof_params[4];
                        int screendim_uniform, color_uniform, depth_uniform, 
dof_uniform, blurred_uniform;
diff --git a/source/blender/gpu/intern/gpu_extensions.c 
b/source/blender/gpu/intern/gpu_extensions.c
index 36f9023..46d87a1 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -1564,10 +1564,12 @@ GPUShader 
*GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
        return retval;
 }
 
+#define MAX_DEFINES 100
+
 GPUShader *GPU_shader_get_builtin_fx_shader(int effects, bool persp)
 {
        int offset;
-       const char *defines = NULL;
+       char defines[MAX_DEFINES] = "";
        /* avoid shaders out of range */
        if (effects >= MAX_FX_SHADERS)
                return NULL;
@@ -1576,14 +1578,16 @@ GPUShader *GPU_shader_get_builtin_fx_shader(int 
effects, bool persp)
 
        if (persp) {
                offset += 1;
-               defines = "#define PERSP_MATRIX\n";
+               strcat(defines, "#define PERSP_MATRIX\n");
        }
 
        if (!GG.shaders.fx_shaders[offset]) {
                if (effects == GPU_SHADER_FX_SSAO)
                        GG.shaders.fx_shaders[offset] = 
GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, 
datatoc_gpu_shader_fx_ssao_frag_glsl, datatoc_gpu_shader_fx_lib_glsl, defines);
-               else if (effects == GPU_SHADER_FX_DEPTH_OF_FIELD)
+               else if (effects == GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_ONE) {
+                       strcat(defines, "#define FIRST_PASS\n");
                        GG.shaders.fx_shaders[offset] = 
GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, 
datatoc_gpu_shader_fx_dof_frag_glsl, datatoc_gpu_shader_fx_lib_glsl, defines);
+               }
        }
        
        return GG.shaders.fx_shaders[offset];
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl 
b/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl
index d556164..053c165 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl
@@ -24,7 +24,7 @@ float calculate_dof_coc(in vec3 viewposition)
     return coc * dof_params.z;
 }
 
-void main()
+void first_pass()
 {
     float depth = texture2D(depthbuffer, uvcoordsvar.xy).r;
     vec4 color = texture2D(colorbuffer, uvcoordsvar.xy);
@@ -34,3 +34,13 @@ void main()
 
     gl_FragColor = vec4(coc * color.rgb, 1.0);
 }
+
+void main()
+{
+#ifdef FIRST_PASS
+    first_pass();
+#elif defined(SECOND_PASS)
+#elif defined(THIRD_PASS)
+#elif defined(FOURTH_PASS)
+#endif
+}

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to