diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2020-09-12 07:10:11 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2020-09-12 16:29:54 +0300 |
commit | 136bdb561b4ce05788e7b654c7e734cc35664b91 (patch) | |
tree | 7b1dd88c0e36f02498a66f107b99252f6f1c76d5 /source/blender/draw | |
parent | a442da62dc6ea14c43a7aba04a600c9ba7cd7f1b (diff) |
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.
Diffstat (limited to 'source/blender/draw')
7 files changed, 40 insertions, 21 deletions
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; |