[Bf-blender-cvs] [136bdb561b4] master: GPU: Add Image Load Store extension support

Clément Foucault noreply at git.blender.org
Sat Sep 12 15:30:01 CEST 2020


Commit: 136bdb561b4ce05788e7b654c7e734cc35664b91
Author: Clément Foucault
Date:   Sat Sep 12 06:10:11 2020 +0200
Branches: master
https://developer.blender.org/rB136bdb561b4ce05788e7b654c7e734cc35664b91

GPU: Add Image Load Store extension support

This wraps the functionality used to speedup EEVEE volumetrics.

This touches the rendering code of EEVEE as it should fix a mis-usage of
the GL barrier. The barrier changed type and location, removing an
unused barrier.

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

M	source/blender/draw/engines/eevee/eevee_private.h
M	source/blender/draw/engines/eevee/eevee_volumes.c
M	source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl
M	source/blender/draw/intern/DRW_render.h
M	source/blender/draw/intern/draw_manager.h
M	source/blender/draw/intern/draw_manager_data.c
M	source/blender/draw/intern/draw_manager_exec.c
M	source/blender/gpu/GPU_capabilities.h
M	source/blender/gpu/GPU_state.h
M	source/blender/gpu/GPU_texture.h
M	source/blender/gpu/intern/gpu_capabilities.cc
M	source/blender/gpu/intern/gpu_capabilities_private.hh
M	source/blender/gpu/intern/gpu_shader_interface.hh
M	source/blender/gpu/intern/gpu_state.cc
M	source/blender/gpu/intern/gpu_state_private.hh
M	source/blender/gpu/intern/gpu_texture.cc
M	source/blender/gpu/opengl/gl_backend.cc
M	source/blender/gpu/opengl/gl_context.hh
M	source/blender/gpu/opengl/gl_debug.cc
M	source/blender/gpu/opengl/gl_shader_interface.cc
M	source/blender/gpu/opengl/gl_state.cc
M	source/blender/gpu/opengl/gl_state.hh

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

diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 8216d2545ac..e731ed071b2 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -84,9 +84,7 @@ extern struct DrawEngineType draw_engine_eevee_type;
 
 #define EEVEE_PROBE_MAX min_ii(MAX_PROBE, GPU_max_texture_layers() / 6)
 #define EEVEE_VELOCITY_TILE_SIZE 32
-#define USE_VOLUME_OPTI \
-  (GLEW_ARB_shader_image_load_store && GLEW_ARB_shading_language_420pack && \
-   !GPU_crappy_amd_driver())
+#define USE_VOLUME_OPTI (GPU_shader_image_load_store_support())
 
 #define SWAP_DOUBLE_BUFFERS() \
   { \
diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c
index 69b916244b5..93701887b51 100644
--- a/source/blender/draw/engines/eevee/eevee_volumes.c
+++ b/source/blender/draw/engines/eevee/eevee_volumes.c
@@ -601,6 +601,10 @@ void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
     DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
     DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
     DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
+    if (USE_VOLUME_OPTI) {
+      DRW_shgroup_uniform_image_ref(grp, "finalScattering_img", &txl->volume_scatter_history);
+      DRW_shgroup_uniform_image_ref(grp, "finalTransmittance_img", &txl->volume_transmit_history);
+    }
 
     DRW_shgroup_call_procedural_triangles(
         grp, NULL, USE_VOLUME_OPTI ? 1 : common_data->vol_tex_size[2]);
@@ -610,6 +614,7 @@ void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
     DRW_shgroup_uniform_texture_ref(grp, "inScattering", &txl->volume_scatter);
     DRW_shgroup_uniform_texture_ref(grp, "inTransmittance", &txl->volume_transmit);
     DRW_shgroup_uniform_texture_ref(grp, "inSceneDepth", &e_data.depth_src);
+    DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
     DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
     DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
     DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
@@ -714,15 +719,7 @@ void EEVEE_volumes_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
     DRW_draw_pass(psl->volumetric_scatter_ps);
 
     if (USE_VOLUME_OPTI) {
-      int tex_scatter = GPU_texture_opengl_bindcode(txl->volume_scatter_history);
-      int tex_transmit = GPU_texture_opengl_bindcode(txl->volume_transmit_history);
-      /* TODO(fclem) Encapsulate these GL calls into DRWManager. */
-      glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
-      /* Subtlety here! we need to tell the GL that the texture is layered (GL_TRUE)
-       * in order to bind the full 3D texture and not just a 2D slice. */
-      glBindImageTexture(0, tex_scatter, 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_R11F_G11F_B10F);
-      glBindImageTexture(1, tex_transmit, 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_R11F_G11F_B10F);
-
+      /* Avoid feedback loop assert. */
       GPU_framebuffer_bind(fbl->volumetric_fb);
     }
     else {
@@ -731,13 +728,6 @@ void EEVEE_volumes_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
 
     DRW_draw_pass(psl->volumetric_integration_ps);
 
-    if (USE_VOLUME_OPTI) {
-      glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
-
-      glBindImageTexture(0, 0, 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_R11F_G11F_B10F);
-      glBindImageTexture(1, 0, 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_R11F_G11F_B10F);
-    }
-
     SWAP(struct GPUFrameBuffer *, fbl->volumetric_scat_fb, fbl->volumetric_integ_fb);
     SWAP(GPUTexture *, txl->volume_scatter, txl->volume_scatter_history);
     SWAP(GPUTexture *, txl->volume_transmit, txl->volume_transmit_history);
@@ -763,6 +753,10 @@ void EEVEE_volumes_resolve(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *veda
     DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
     e_data.depth_src = dtxl->depth;
 
+    if (USE_VOLUME_OPTI) {
+      GPU_memory_barrier(GPU_BARRIER_TEXTURE_FETCH);
+    }
+
     /* Apply for opaque geometry. */
     GPU_framebuffer_bind(fbl->main_color_fb);
     DRW_draw_pass(psl->volumetric_resolve_ps);
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl
index f4276bd61bd..12b7d8acbea 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl
@@ -11,8 +11,8 @@ uniform sampler3D volumeScattering; /* Result of the scatter step */
 uniform sampler3D volumeExtinction;
 
 #ifdef USE_VOLUME_OPTI
-uniform layout(binding = 0, r11f_g11f_b10f) writeonly restrict image3D finalScattering_img;
-uniform layout(binding = 1, r11f_g11f_b10f) writeonly restrict image3D finalTransmittance_img;
+uniform layout(r11f_g11f_b10f) writeonly restrict image3D finalScattering_img;
+uniform layout(r11f_g11f_b10f) writeonly restrict image3D finalTransmittance_img;
 
 vec3 finalScattering;
 vec3 finalTransmittance;
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 8e3562216e9..30c6f0ad4dc 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -557,6 +557,9 @@ void DRW_shgroup_uniform_ivec4(DRWShadingGroup *shgroup,
                                int arraysize);
 void DRW_shgroup_uniform_mat3(DRWShadingGroup *shgroup, const char *name, const float (*value)[3]);
 void DRW_shgroup_uniform_mat4(DRWShadingGroup *shgroup, const char *name, const float (*value)[4]);
+/* Only to be used when image load store is supported (GPU_shader_image_load_store_support()). */
+void DRW_shgroup_uniform_image(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex);
+void DRW_shgroup_uniform_image_ref(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex);
 /* Store value instead of referencing it. */
 void DRW_shgroup_uniform_int_copy(DRWShadingGroup *shgroup, const char *name, const int value);
 void DRW_shgroup_uniform_ivec2_copy(DRWShadingGroup *shgroup, const char *name, const int *value);
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index c0bcb0e679f..9f6a970ea22 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -278,6 +278,8 @@ typedef enum {
   DRW_UNIFORM_FLOAT_COPY,
   DRW_UNIFORM_TEXTURE,
   DRW_UNIFORM_TEXTURE_REF,
+  DRW_UNIFORM_IMAGE,
+  DRW_UNIFORM_IMAGE_REF,
   DRW_UNIFORM_BLOCK,
   DRW_UNIFORM_BLOCK_REF,
   DRW_UNIFORM_TFEEDBACK_TARGET,
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index a4fc44e9571..81842f5d2ec 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -199,10 +199,12 @@ static void drw_shgroup_uniform_create_ex(DRWShadingGroup *shgroup,
     case DRW_UNIFORM_BLOCK_REF:
       uni->block_ref = (GPUUniformBuf **)value;
       break;
+    case DRW_UNIFORM_IMAGE:
     case DRW_UNIFORM_TEXTURE:
       uni->texture = (GPUTexture *)value;
       uni->sampler_state = sampler_state;
       break;
+    case DRW_UNIFORM_IMAGE_REF:
     case DRW_UNIFORM_TEXTURE_REF:
       uni->texture_ref = (GPUTexture **)value;
       uni->sampler_state = sampler_state;
@@ -261,6 +263,20 @@ void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup, const char *name,
   DRW_shgroup_uniform_texture_ref_ex(shgroup, name, tex, GPU_SAMPLER_MAX);
 }
 
+void DRW_shgroup_uniform_image(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex)
+{
+  BLI_assert(tex != NULL);
+  int loc = GPU_shader_get_texture_binding(shgroup->shader, name);
+  drw_shgroup_uniform_create_ex(shgroup, loc, DRW_UNIFORM_IMAGE, tex, 0, 0, 1);
+}
+
+void DRW_shgroup_uniform_image_ref(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex)
+{
+  BLI_assert(tex != NULL);
+  int loc = GPU_shader_get_texture_binding(shgroup->shader, name);
+  drw_shgroup_uniform_create_ex(shgroup, loc, DRW_UNIFORM_IMAGE_REF, tex, 0, 0, 1);
+}
+
 void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup,
                                const char *name,
                                const GPUUniformBuf *ubo)
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index 79d74e1f67d..84f618c1c15 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -596,6 +596,12 @@ static void draw_update_uniforms(DRWShadingGroup *shgroup,
         case DRW_UNIFORM_TEXTURE_REF:
           GPU_texture_bind_ex(*uni->texture_ref, uni->sampler_state, uni->location, false);
           break;
+        case DRW_UNIFORM_IMAGE:
+          GPU_texture_image_bind(uni->texture, uni->location);
+          break;
+        case DRW_UNIFORM_IMAGE_REF:
+          GPU_texture_image_bind(*uni->texture_ref, uni->location);
+          break;
         case DRW_UNIFORM_BLOCK:
           GPU_uniformbuf_bind(uni->block, uni->location);
           break;
diff --git a/source/blender/gpu/GPU_capabilities.h b/source/blender/gpu/GPU_capabilities.h
index b8a48735548..9d55fe73708 100644
--- a/source/blender/gpu/GPU_capabilities.h
+++ b/source/blender/gpu/GPU_capabilities.h
@@ -45,6 +45,8 @@ bool GPU_depth_blitting_workaround(void);
 bool GPU_use_main_context_workaround(void);
 bool GPU_crappy_amd_driver(void);
 
+bool GPU_shader_image_load_store_support(void);
+
 bool GPU_mem_stats_supported(void);
 void GPU_mem_stats_get(int *totalmem, int *freemem);
 
diff --git a/source/blender/gpu/GPU_state.h b/source/blender/gpu/GPU_state.h
index 5e872001267..aa32c6c75ba 100644
--- a/source/blender/gpu/GPU_state.h
+++ b/source/blender/gpu/GPU_state.h
@@ -35,6 +35,14 @@ typedef enum eGPUWriteMask {
 
 ENUM_OPERATORS(eGPUWriteMask)
 
+typedef enum eGPUBarrier {
+  GPU_BARRIER_NONE = 0,
+  GPU_BARRIER_SHADER_IMAGE_ACCESS = (1 << 0),
+  GPU_BARRIER_TEXTURE_FETCH = (1 << 1),
+} eGPUBarrier;
+
+EN

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list