[Bf-blender-cvs] [2abc21ace5a] blender2.8: Eevee: Fix problem with GPU_texture_generate_mipmap
Clément Foucault
noreply at git.blender.org
Sat Aug 19 02:40:30 CEST 2017
Commit: 2abc21ace5a046ee4043a6b9c8a317defb05a035
Author: Clément Foucault
Date: Fri Aug 18 22:31:06 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB2abc21ace5a046ee4043a6b9c8a317defb05a035
Eevee: Fix problem with GPU_texture_generate_mipmap
This function was called to recreate the lower mip level of the probe texture. But this is not it's usage and it introduced a stall.
This patch add cubemap mipmap level regeneration in eevee_effects.c
===================================================================
M source/blender/draw/CMakeLists.txt
M source/blender/draw/engines/eevee/eevee_effects.c
M source/blender/draw/engines/eevee/eevee_lightprobes.c
M source/blender/draw/engines/eevee/eevee_private.h
A source/blender/draw/engines/eevee/shaders/effect_downsample_cube_frag.glsl
M source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl
===================================================================
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 2a22715baf3..63f466d3792 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -141,6 +141,7 @@ data_to_c_simple(engines/eevee/shaders/effect_dof_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_dof_geom.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_dof_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_downsample_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/effect_downsample_cube_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_gtao_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_motion_blur_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_ssr_frag.glsl SRC)
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index f16393eb35a..45b0d16b2e1 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -98,6 +98,7 @@ static struct {
/* Simple Downsample */
struct GPUShader *downsample_sh;
+ struct GPUShader *downsample_cube_sh;
/* Ground Truth Ambient Occlusion */
struct GPUShader *gtao_sh;
@@ -106,6 +107,7 @@ static struct {
struct GPUTexture *depth_src;
struct GPUTexture *color_src;
int depth_src_layer;
+ float cube_texel_size;
} e_data = {NULL}; /* Engine data */
extern char datatoc_ambient_occlusion_lib_glsl[];
@@ -120,8 +122,11 @@ extern char datatoc_effect_dof_vert_glsl[];
extern char datatoc_effect_dof_geom_glsl[];
extern char datatoc_effect_dof_frag_glsl[];
extern char datatoc_effect_downsample_frag_glsl[];
+extern char datatoc_effect_downsample_cube_frag_glsl[];
extern char datatoc_effect_gtao_frag_glsl[];
extern char datatoc_lightprobe_lib_glsl[];
+extern char datatoc_lightprobe_vert_glsl[];
+extern char datatoc_lightprobe_geom_glsl[];
extern char datatoc_raytrace_lib_glsl[];
extern char datatoc_tonemap_frag_glsl[];
extern char datatoc_volumetric_frag_glsl[];
@@ -248,6 +253,9 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
MEM_freeN(frag_str);
e_data.downsample_sh = DRW_shader_create_fullscreen(datatoc_effect_downsample_frag_glsl, NULL);
+ e_data.downsample_cube_sh = DRW_shader_create(datatoc_lightprobe_vert_glsl,
+ datatoc_lightprobe_geom_glsl,
+ datatoc_effect_downsample_cube_frag_glsl, NULL);
e_data.volumetric_upsample_sh = DRW_shader_create_fullscreen(datatoc_volumetric_frag_glsl, "#define STEP_UPSAMPLE\n");
@@ -905,6 +913,17 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_call_add(grp, quad, NULL);
}
+ {
+ static int zero = 0;
+ psl->color_downsample_cube_ps = DRW_pass_create("Downsample Cube", DRW_STATE_WRITE_COLOR);
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.downsample_cube_sh, psl->color_downsample_cube_ps, quad);
+ DRW_shgroup_uniform_buffer(grp, "source", &e_data.color_src);
+ DRW_shgroup_uniform_float(grp, "texelSize", &e_data.cube_texel_size, 1);
+ DRW_shgroup_uniform_int(grp, "Layer", &zero, 1);
+ for (int i = 0; i < 6; ++i)
+ DRW_shgroup_call_dynamic_add_empty(grp);
+ }
+
{
/* Perform min/max downsample */
psl->minz_downlevel_ps = DRW_pass_create("HiZ Min Down Level", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
@@ -1097,6 +1116,13 @@ static void simple_downsample_cb(void *vedata, int UNUSED(level))
DRW_draw_pass(psl->color_downsample_ps);
}
+static void simple_downsample_cube_cb(void *vedata, int level)
+{
+ EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
+ e_data.cube_texel_size = (float)(1 << level) / (float)GPU_texture_width(e_data.color_src);
+ DRW_draw_pass(psl->color_downsample_cube_ps);
+}
+
void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, GPUTexture *depth_src, int layer)
{
EEVEE_PassList *psl = vedata->psl;
@@ -1153,6 +1179,19 @@ void EEVEE_downsample_buffer(EEVEE_Data *vedata, struct GPUFrameBuffer *fb_src,
DRW_stats_group_end();
}
+/**
+ * Simple downsampling algorithm for cubemap. Reconstruct mip chain up to mip level.
+ **/
+void EEVEE_downsample_cube_buffer(EEVEE_Data *vedata, struct GPUFrameBuffer *fb_src, GPUTexture *texture_src, int level)
+{
+ e_data.color_src = texture_src;
+
+ DRW_stats_group_start("Downsample Cube buffer");
+ /* Create lower levels */
+ DRW_framebuffer_recursive_downsample(fb_src, texture_src, level, &simple_downsample_cube_cb, vedata);
+ DRW_stats_group_end();
+}
+
void EEVEE_effects_do_volumetrics(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_PassList *psl = vedata->psl;
@@ -1493,6 +1532,7 @@ void EEVEE_effects_free(void)
DRW_SHADER_FREE_SAFE(e_data.ssr_sh[i]);
}
DRW_SHADER_FREE_SAFE(e_data.downsample_sh);
+ DRW_SHADER_FREE_SAFE(e_data.downsample_cube_sh);
DRW_SHADER_FREE_SAFE(e_data.gtao_sh);
DRW_SHADER_FREE_SAFE(e_data.gtao_debug_sh);
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index f77637edac0..a20b373d3b1 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -827,14 +827,17 @@ static void downsample_planar(void *vedata, int level)
}
/* Glossy filter probe_rt to probe_pool at index probe_idx */
-static void glossy_filter_probe(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl, int probe_idx)
+static void glossy_filter_probe(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, EEVEE_PassList *psl, int probe_idx)
{
EEVEE_LightProbesInfo *pinfo = sldata->probes;
+ /* Max lod used from the render target probe */
+ pinfo->lod_rt_max = floorf(log2f(PROBE_RT_SIZE)) - 2.0f;
+
/* 2 - Let gpu create Mipmaps for Filtered Importance Sampling. */
/* Bind next framebuffer to be able to gen. mips for probe_rt. */
DRW_framebuffer_bind(sldata->probe_filter_fb);
- DRW_texture_generate_mipmaps(sldata->probe_rt);
+ EEVEE_downsample_cube_buffer(vedata, sldata->probe_filter_fb, sldata->probe_rt, (int)(pinfo->lod_rt_max));
/* 3 - Render to probe array to the specified layer, do prefiltering. */
/* Detach to rebind the right mipmap. */
@@ -843,7 +846,7 @@ static void glossy_filter_probe(EEVEE_SceneLayerData *sldata, EEVEE_PassList *ps
const int maxlevel = (int)floorf(log2f(PROBE_OCTAHEDRON_SIZE));
const int min_lod_level = 3;
for (int i = 0; i < maxlevel - min_lod_level; i++) {
- float bias = (i == 0) ? 0.0f : 1.0f;
+ float bias = (i == 0) ? -1.0f : 1.0f;
pinfo->texel_size = 1.0f / mipsize;
pinfo->padding_size = powf(2.0f, (float)(maxlevel - min_lod_level - 1 - i));
/* XXX : WHY THE HECK DO WE NEED THIS ??? */
@@ -880,7 +883,6 @@ static void glossy_filter_probe(EEVEE_SceneLayerData *sldata, EEVEE_PassList *ps
pinfo->invsamples_ct = 1.0f / pinfo->samples_ct;
pinfo->lodfactor = bias + 0.5f * log((float)(PROBE_RT_SIZE * PROBE_RT_SIZE) * pinfo->invsamples_ct) / log(2);
- pinfo->lod_rt_max = floorf(log2f(PROBE_RT_SIZE)) - 2.0f;
DRW_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->probe_pool, 0, i);
DRW_framebuffer_viewport_size(sldata->probe_filter_fb, 0, 0, mipsize, mipsize);
@@ -898,19 +900,10 @@ static void glossy_filter_probe(EEVEE_SceneLayerData *sldata, EEVEE_PassList *ps
}
/* Diffuse filter probe_rt to irradiance_pool at index probe_idx */
-static void diffuse_filter_probe(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl, int offset)
+static void diffuse_filter_probe(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, EEVEE_PassList *psl, int offset)
{
EEVEE_LightProbesInfo *pinfo = sldata->probes;
- /* 4 - Compute spherical harmonics */
- /* Tweaking parameters to balance perf. vs precision */
- DRW_framebuffer_bind(sldata->probe_filter_fb);
- DRW_texture_generate_mipmaps(sldata->probe_rt);
-
- /* Bind the right texture layer (one layer per irradiance grid) */
- DRW_framebuffer_texture_detach(sldata->probe_pool);
- DRW_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->irradiance_rt, 0, 0);
-
/* find cell position on the virtual 3D texture */
/* NOTE : Keep in sync with load_irradiance_cell() */
#if defined(IRRADIANCE_SH_L2)
@@ -928,6 +921,7 @@ static void diffuse_filter_probe(EEVEE_SceneLayerData *sldata, EEVEE_PassList *p
int y = size[1] * (offset / cell_per_row);
#ifndef IRRADIANCE_SH_L2
+ /* Tweaking parameters to balance perf. vs precision */
const float bias = 0.0f;
pinfo->invsamples_ct = 1.0f / pinfo->samples_ct;
pinfo->lodfactor = bias + 0.5f * log((float)(PROBE_RT_SIZE * PROBE_RT_SIZE) * pinfo->invsamples_ct) / log(2);
@@ -937,6 +931,14 @@ static void diffuse_filter_probe(EEVEE_SceneLayerData *sldata, EEVEE_PassList *p
pinfo->lod_rt_max = 2.0f; /* Improve cache reuse */
#endif
+ /* 4 - Compute spherical harmonics */
+ DRW_framebuffer_bind(sldata->probe_filter_fb);
+ EEVEE_downsample_cube_buffer(vedata, sldata->probe_filter_fb, sldata->probe_rt, (int)(pinfo->lod_rt_max));
+
+ /* Bind the right texture layer (one layer per irradiance grid) */
+ DRW_framebuffer_texture_detach(sldata->probe_pool);
+ DRW_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->irradiance_rt, 0, 0);
+
DRW_framebuffer_viewport_size(sldata->probe_filter_fb, x, y, size[0], size[1]);
DRW_draw_pass(psl->probe_diffuse_compute);
@@ -1199,13 +1201,13 @@ void EEVEE_lightprobes_refresh(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
/* Render world in priority */
if (e_data.update_world) {
render_world_to_probe(sldata, psl);
- glossy_filter_probe(sldata, psl, 0);
- diffuse_filter_probe(sldata, psl, 0);
+ glossy_filter_probe(sldata, vedata, psl, 0);
+ diffuse_filter_probe(sldata, vedata, psl, 0);
/* Swap and redo prefiltering for other rendertarget.
* This way we have world lighting waiting for irradiance grids to catch up. */
SWAP(GPUTexture *, sldata->irradiance_pool, sldata->irradiance_rt);
- diffuse_filter_probe(sldata, psl, 0);
+ diffuse_filter_probe(sldata, vedata, psl, 0);
e_data.update_world = false;
@@ -1258,7 +1260,7 @@ void EEVEE_lightprobes_refresh(EEVEE_SceneLayerData *sldata, EEVEE
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list