EEVEE-Next: Reduce image bindings.

This change combines the diffuse/specular light passes into a single texture
array, freeing up an image binding for cryptomatte.

When diffuse/specular light pass and/or requested a
texture array will be allocated. Only when specular light is requested 2 images will always be allocated. This increases the
memory overhead when viewing the specular light renderpass in the viewport. For final rendering it is a common scenario that none
or both are requested.

Reviewed By: fclem

Differential Revision: https://developer.blender.org/D15701
This commit is contained in:
Jeroen Bakker 2022-08-16 15:10:09 +02:00 committed by Jeroen Bakker
parent a70eace19b
commit 8af983ba78
10 changed files with 75 additions and 45 deletions

View File

@ -389,9 +389,8 @@ void Film::sync()
DRW_shgroup_uniform_texture_ref(grp, "combined_tx", &combined_final_tx_);
DRW_shgroup_uniform_texture_ref(grp, "normal_tx", &rbuffers.normal_tx);
DRW_shgroup_uniform_texture_ref(grp, "vector_tx", &rbuffers.vector_tx);
DRW_shgroup_uniform_texture_ref(grp, "diffuse_light_tx", &rbuffers.diffuse_light_tx);
DRW_shgroup_uniform_texture_ref(grp, "light_tx", &rbuffers.light_tx);
DRW_shgroup_uniform_texture_ref(grp, "diffuse_color_tx", &rbuffers.diffuse_color_tx);
DRW_shgroup_uniform_texture_ref(grp, "specular_light_tx", &rbuffers.specular_light_tx);
DRW_shgroup_uniform_texture_ref(grp, "specular_color_tx", &rbuffers.specular_color_tx);
DRW_shgroup_uniform_texture_ref(grp, "volume_light_tx", &rbuffers.volume_light_tx);
DRW_shgroup_uniform_texture_ref(grp, "emission_tx", &rbuffers.emission_tx);

View File

@ -43,9 +43,8 @@ void WorldPipeline::sync(GPUMaterial *gpumat)
DRW_shgroup_storage_block_ref(grp, "aov_buf", &inst_.film.aovs_info);
/* RenderPasses. Cleared by background (even if bad practice). */
DRW_shgroup_uniform_image_ref(grp, "rp_normal_img", &rbufs.normal_tx);
DRW_shgroup_uniform_image_ref(grp, "rp_diffuse_light_img", &rbufs.diffuse_light_tx);
DRW_shgroup_uniform_image_ref(grp, "rp_light_img", &rbufs.light_tx);
DRW_shgroup_uniform_image_ref(grp, "rp_diffuse_color_img", &rbufs.diffuse_color_tx);
DRW_shgroup_uniform_image_ref(grp, "rp_specular_light_img", &rbufs.specular_light_tx);
DRW_shgroup_uniform_image_ref(grp, "rp_specular_color_img", &rbufs.specular_color_tx);
DRW_shgroup_uniform_image_ref(grp, "rp_emission_img", &rbufs.emission_tx);
/* To allow opaque pass rendering over it. */
@ -122,9 +121,8 @@ DRWShadingGroup *ForwardPipeline::material_opaque_add(::Material *blender_mat, G
DRW_shgroup_storage_block_ref(grp, "aov_buf", &inst_.film.aovs_info);
/* RenderPasses. */
DRW_shgroup_uniform_image_ref(grp, "rp_normal_img", &rbufs.normal_tx);
DRW_shgroup_uniform_image_ref(grp, "rp_diffuse_light_img", &rbufs.diffuse_light_tx);
DRW_shgroup_uniform_image_ref(grp, "rp_light_img", &rbufs.light_tx);
DRW_shgroup_uniform_image_ref(grp, "rp_diffuse_color_img", &rbufs.diffuse_color_tx);
DRW_shgroup_uniform_image_ref(grp, "rp_specular_light_img", &rbufs.specular_light_tx);
DRW_shgroup_uniform_image_ref(grp, "rp_specular_color_img", &rbufs.specular_color_tx);
DRW_shgroup_uniform_image_ref(grp, "rp_emission_img", &rbufs.emission_tx);
@ -206,9 +204,8 @@ DRWShadingGroup *ForwardPipeline::material_transparent_add(::Material *blender_m
DRW_shgroup_storage_block_ref(grp, "aov_buf", &inst_.film.aovs_info);
/* RenderPasses. */
DRW_shgroup_uniform_image_ref(grp, "rp_normal_img", &rbufs.normal_tx);
DRW_shgroup_uniform_image_ref(grp, "rp_diffuse_light_img", &rbufs.diffuse_light_tx);
DRW_shgroup_uniform_image_ref(grp, "rp_light_img", &rbufs.light_tx);
DRW_shgroup_uniform_image_ref(grp, "rp_diffuse_color_img", &rbufs.diffuse_color_tx);
DRW_shgroup_uniform_image_ref(grp, "rp_specular_light_img", &rbufs.specular_light_tx);
DRW_shgroup_uniform_image_ref(grp, "rp_specular_color_img", &rbufs.specular_color_tx);
DRW_shgroup_uniform_image_ref(grp, "rp_emission_img", &rbufs.emission_tx);
}

View File

@ -26,9 +26,11 @@ namespace blender::eevee {
void RenderBuffers::acquire(int2 extent)
{
const eViewLayerEEVEEPassType enabled_passes = inst_.film.enabled_passes_get();
auto pass_extent = [&](eViewLayerEEVEEPassType pass_bit) -> int2 {
/* Use dummy texture for disabled passes. Allows correct bindings. */
return (inst_.film.enabled_passes_get() & pass_bit) ? extent : int2(1);
return (enabled_passes & pass_bit) ? extent : int2(1);
};
eGPUTextureFormat color_format = GPU_RGBA16F;
@ -38,17 +40,22 @@ void RenderBuffers::acquire(int2 extent)
depth_tx.acquire(extent, GPU_DEPTH24_STENCIL8);
combined_tx.acquire(extent, color_format);
bool do_vector_render_pass = (inst_.film.enabled_passes_get() & EEVEE_RENDER_PASS_VECTOR) ||
bool do_vector_render_pass = (enabled_passes & EEVEE_RENDER_PASS_VECTOR) ||
(inst_.motion_blur.postfx_enabled() && !inst_.is_viewport());
uint32_t max_light_color_layer = max_ii(enabled_passes & EEVEE_RENDER_PASS_DIFFUSE_LIGHT ?
RENDER_PASS_LAYER_DIFFUSE_LIGHT :
-1,
enabled_passes & EEVEE_RENDER_PASS_SPECULAR_LIGHT ?
RENDER_PASS_LAYER_SPECULAR_LIGHT :
-1) +
1;
/* Only RG16F when only doing only reprojection or motion blur. */
eGPUTextureFormat vector_format = do_vector_render_pass ? GPU_RGBA16F : GPU_RG16F;
/* TODO(fclem): Make vector pass allocation optional if no TAA or motion blur is needed. */
vector_tx.acquire(extent, vector_format);
normal_tx.acquire(pass_extent(EEVEE_RENDER_PASS_NORMAL), color_format);
diffuse_light_tx.acquire(pass_extent(EEVEE_RENDER_PASS_DIFFUSE_LIGHT), color_format);
diffuse_color_tx.acquire(pass_extent(EEVEE_RENDER_PASS_DIFFUSE_COLOR), color_format);
specular_light_tx.acquire(pass_extent(EEVEE_RENDER_PASS_SPECULAR_LIGHT), color_format);
specular_color_tx.acquire(pass_extent(EEVEE_RENDER_PASS_SPECULAR_COLOR), color_format);
volume_light_tx.acquire(pass_extent(EEVEE_RENDER_PASS_VOLUME_LIGHT), color_format);
emission_tx.acquire(pass_extent(EEVEE_RENDER_PASS_EMIT), color_format);
@ -56,6 +63,10 @@ void RenderBuffers::acquire(int2 extent)
shadow_tx.acquire(pass_extent(EEVEE_RENDER_PASS_SHADOW), float_format);
ambient_occlusion_tx.acquire(pass_extent(EEVEE_RENDER_PASS_AO), float_format);
light_tx.ensure_2d_array(color_format,
max_light_color_layer > 0 ? extent : int2(1),
max_ii(1, max_light_color_layer));
const AOVsInfoData &aovs = inst_.film.aovs_info;
aov_color_tx.ensure_2d_array(
color_format, (aovs.color_len > 0) ? extent : int2(1), max_ii(1, aovs.color_len));
@ -70,9 +81,7 @@ void RenderBuffers::release()
normal_tx.release();
vector_tx.release();
diffuse_light_tx.release();
diffuse_color_tx.release();
specular_light_tx.release();
specular_color_tx.release();
volume_light_tx.release();
emission_tx.release();

View File

@ -28,9 +28,7 @@ class RenderBuffers {
// TextureFromPool mist_tx; /* Derived from depth_tx during accumulation. */
TextureFromPool normal_tx;
TextureFromPool vector_tx;
TextureFromPool diffuse_light_tx;
TextureFromPool diffuse_color_tx;
TextureFromPool specular_light_tx;
TextureFromPool specular_color_tx;
TextureFromPool volume_light_tx;
TextureFromPool emission_tx;
@ -39,6 +37,7 @@ class RenderBuffers {
TextureFromPool ambient_occlusion_tx;
// TextureFromPool cryptomatte_tx; /* TODO */
/* TODO(fclem): Use texture from pool once they support texture array. */
Texture light_tx;
Texture aov_color_tx;
Texture aov_value_tx;

View File

@ -291,6 +291,17 @@ static inline float film_filter_weight(float filter_radius, float sample_distanc
/** \} */
/* -------------------------------------------------------------------- */
/** \name Render passes
* \{ */
enum eRenderPassLayerIndex : uint32_t {
RENDER_PASS_LAYER_DIFFUSE_LIGHT = 0u,
RENDER_PASS_LAYER_SPECULAR_LIGHT = 1u,
};
/** \} */
/* -------------------------------------------------------------------- */
/** \name Arbitrary Output Variables
* \{ */

View File

@ -105,12 +105,18 @@ void film_sample_accum(FilmSample samp, int pass_id, sampler2D tex, inout float
accum += texelFetch(tex, samp.texel, 0).x * samp.weight;
}
void film_sample_accum(FilmSample samp, int pass_id, sampler2DArray tex, inout vec4 accum)
void film_sample_accum(
FilmSample samp, int pass_id, uint layer, sampler2DArray tex, inout vec4 accum)
{
if (pass_id == -1) {
return;
}
accum += texelFetch(tex, ivec3(samp.texel, pass_id), 0) * samp.weight;
accum += texelFetch(tex, ivec3(samp.texel, layer), 0) * samp.weight;
}
void film_sample_accum(FilmSample samp, int pass_id, sampler2DArray tex, inout vec4 accum)
{
film_sample_accum(samp, pass_id, pass_id, tex, accum);
}
void film_sample_accum(FilmSample samp, int pass_id, sampler2DArray tex, inout float accum)
@ -632,8 +638,16 @@ void film_process_data(ivec2 texel_film, out vec4 out_color, out float out_depth
for (int i = 0; i < film_buf.samples_len; i++) {
FilmSample src = film_sample_get(i, texel_film);
film_sample_accum(src, film_buf.diffuse_light_id, diffuse_light_tx, diffuse_light_accum);
film_sample_accum(src, film_buf.specular_light_id, specular_light_tx, specular_light_accum);
film_sample_accum(src,
film_buf.diffuse_light_id,
RENDER_PASS_LAYER_DIFFUSE_LIGHT,
light_tx,
diffuse_light_accum);
film_sample_accum(src,
film_buf.specular_light_id,
RENDER_PASS_LAYER_SPECULAR_LIGHT,
light_tx,
specular_light_accum);
film_sample_accum(src, film_buf.volume_light_id, volume_light_tx, volume_light_accum);
film_sample_accum(src, film_buf.emission_id, emission_tx, emission_accum);
}

View File

@ -99,9 +99,11 @@ void main()
ivec2 out_texel = ivec2(gl_FragCoord.xy);
imageStore(rp_normal_img, out_texel, vec4(out_normal, 1.0));
imageStore(rp_diffuse_light_img, out_texel, vec4(diffuse_light, 1.0));
imageStore(
rp_light_img, ivec3(out_texel, RENDER_PASS_LAYER_DIFFUSE_LIGHT), vec4(diffuse_light, 1.0));
imageStore(
rp_light_img, ivec3(out_texel, RENDER_PASS_LAYER_SPECULAR_LIGHT), vec4(specular_light, 1.0));
imageStore(rp_diffuse_color_img, out_texel, vec4(g_diffuse_data.color, 1.0));
imageStore(rp_specular_light_img, out_texel, vec4(specular_light, 1.0));
imageStore(rp_specular_color_img, out_texel, vec4(specular_color, 1.0));
imageStore(rp_emission_img, out_texel, vec4(g_emission, 1.0));

View File

@ -26,9 +26,11 @@ void main()
ivec2 out_texel = ivec2(gl_FragCoord.xy);
imageStore(rp_normal_img, out_texel, vec4(0.0, 0.0, 0.0, 1.0));
imageStore(rp_diffuse_light_img, out_texel, vec4(0.0, 0.0, 0.0, 1.0));
imageStore(
rp_light_img, ivec3(out_texel, RENDER_PASS_LAYER_DIFFUSE_LIGHT), vec4(0.0, 0.0, 0.0, 1.0));
imageStore(
rp_light_img, ivec3(out_texel, RENDER_PASS_LAYER_SPECULAR_LIGHT), vec4(0.0, 0.0, 0.0, 1.0));
imageStore(rp_diffuse_color_img, out_texel, vec4(0.0, 0.0, 0.0, 1.0));
imageStore(rp_specular_light_img, out_texel, vec4(0.0, 0.0, 0.0, 1.0));
imageStore(rp_specular_color_img, out_texel, vec4(0.0, 0.0, 0.0, 1.0));
imageStore(rp_emission_img, out_texel, vec4(0.0, 0.0, 0.0, 1.0));

View File

@ -9,19 +9,18 @@ GPU_SHADER_CREATE_INFO(eevee_film)
.sampler(1, ImageType::FLOAT_2D, "combined_tx")
.sampler(2, ImageType::FLOAT_2D, "normal_tx")
.sampler(3, ImageType::FLOAT_2D, "vector_tx")
.sampler(4, ImageType::FLOAT_2D, "diffuse_light_tx")
.sampler(4, ImageType::FLOAT_2D_ARRAY, "light_tx")
.sampler(5, ImageType::FLOAT_2D, "diffuse_color_tx")
.sampler(6, ImageType::FLOAT_2D, "specular_light_tx")
.sampler(7, ImageType::FLOAT_2D, "specular_color_tx")
.sampler(8, ImageType::FLOAT_2D, "volume_light_tx")
.sampler(9, ImageType::FLOAT_2D, "emission_tx")
.sampler(10, ImageType::FLOAT_2D, "environment_tx")
.sampler(11, ImageType::FLOAT_2D, "shadow_tx")
.sampler(12, ImageType::FLOAT_2D, "ambient_occlusion_tx")
.sampler(13, ImageType::FLOAT_2D_ARRAY, "aov_color_tx")
.sampler(14, ImageType::FLOAT_2D_ARRAY, "aov_value_tx")
.sampler(6, ImageType::FLOAT_2D, "specular_color_tx")
.sampler(7, ImageType::FLOAT_2D, "volume_light_tx")
.sampler(8, ImageType::FLOAT_2D, "emission_tx")
.sampler(9, ImageType::FLOAT_2D, "environment_tx")
.sampler(10, ImageType::FLOAT_2D, "shadow_tx")
.sampler(11, ImageType::FLOAT_2D, "ambient_occlusion_tx")
.sampler(12, ImageType::FLOAT_2D_ARRAY, "aov_color_tx")
.sampler(13, ImageType::FLOAT_2D_ARRAY, "aov_value_tx")
/* Color History for TAA needs to be sampler to leverage bilinear sampling. */
.sampler(15, ImageType::FLOAT_2D, "in_combined_tx")
.sampler(14, ImageType::FLOAT_2D, "in_combined_tx")
// .sampler(15, ImageType::FLOAT_2D, "cryptomatte_tx") /* TODO */
.image(0, GPU_R32F, Qualifier::READ, ImageType::FLOAT_2D_ARRAY, "in_weight_img")
.image(1, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D_ARRAY, "out_weight_img")

View File

@ -78,8 +78,8 @@ GPU_SHADER_INTERFACE_INFO(eevee_surf_iface, "interp")
GPU_SHADER_CREATE_INFO(eevee_aov_out)
.define("MAT_AOV_SUPPORT")
.image_array_out(6, Qualifier::WRITE, GPU_RGBA16F, "aov_color_img")
.image_array_out(7, Qualifier::WRITE, GPU_R16F, "aov_value_img")
.image_array_out(5, Qualifier::WRITE, GPU_RGBA16F, "aov_color_img")
.image_array_out(6, Qualifier::WRITE, GPU_R16F, "aov_value_img")
.storage_buf(7, Qualifier::READ, "AOVsInfoData", "aov_buf");
GPU_SHADER_CREATE_INFO(eevee_surf_deferred)
@ -113,11 +113,10 @@ GPU_SHADER_CREATE_INFO(eevee_surf_forward)
.fragment_out(0, Type::VEC4, "out_transmittance", DualBlend::SRC_1)
.fragment_source("eevee_surf_forward_frag.glsl")
.image_out(0, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_normal_img")
.image_out(1, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_diffuse_light_img")
.image_array_out(1, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_light_img")
.image_out(2, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_diffuse_color_img")
.image_out(3, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_specular_light_img")
.image_out(4, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_specular_color_img")
.image_out(5, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_emission_img")
.image_out(3, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_specular_color_img")
.image_out(4, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_emission_img")
.additional_info("eevee_aov_out",
"eevee_light_data",
"eevee_utility_texture",
@ -138,11 +137,10 @@ GPU_SHADER_CREATE_INFO(eevee_surf_depth)
GPU_SHADER_CREATE_INFO(eevee_surf_world)
.vertex_out(eevee_surf_iface)
.image_out(0, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_normal_img")
.image_out(1, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_diffuse_light_img")
.image_array_out(1, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_light_img")
.image_out(2, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_diffuse_color_img")
.image_out(3, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_specular_light_img")
.image_out(4, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_specular_color_img")
.image_out(5, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_emission_img")
.image_out(3, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_specular_color_img")
.image_out(4, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_emission_img")
.push_constant(Type::FLOAT, "world_opacity_fade")
.fragment_out(0, Type::VEC4, "out_background")
.fragment_source("eevee_surf_world_frag.glsl")