diff options
Diffstat (limited to 'source/blender/draw/engines/eevee_next/eevee_pipeline.cc')
-rw-r--r-- | source/blender/draw/engines/eevee_next/eevee_pipeline.cc | 326 |
1 files changed, 138 insertions, 188 deletions
diff --git a/source/blender/draw/engines/eevee_next/eevee_pipeline.cc b/source/blender/draw/engines/eevee_next/eevee_pipeline.cc index 9185ce7904a..33978518ffc 100644 --- a/source/blender/draw/engines/eevee_next/eevee_pipeline.cc +++ b/source/blender/draw/engines/eevee_next/eevee_pipeline.cc @@ -24,37 +24,36 @@ namespace blender::eevee { void WorldPipeline::sync(GPUMaterial *gpumat) { + Manager &manager = *inst_.manager; RenderBuffers &rbufs = inst_.render_buffers; - DRWState state = DRW_STATE_WRITE_COLOR; - world_ps_ = DRW_pass_create("World", state); + ResourceHandle handle = manager.resource_handle(float4x4::identity().ptr()); - /* Push a matrix at the same location as the camera. */ - float4x4 camera_mat = float4x4::identity(); - // copy_v3_v3(camera_mat[3], inst_.camera.data_get().viewinv[3]); - - DRWShadingGroup *grp = DRW_shgroup_material_create(gpumat, world_ps_); - DRW_shgroup_uniform_texture(grp, "utility_tx", inst_.pipelines.utility_tx); - DRW_shgroup_call_obmat(grp, DRW_cache_fullscreen_quad_get(), camera_mat.ptr()); - DRW_shgroup_uniform_float_copy(grp, "world_opacity_fade", inst_.film.background_opacity_get()); + world_ps_.init(); + world_ps_.state_set(DRW_STATE_WRITE_COLOR); + world_ps_.material_set(manager, gpumat); + world_ps_.push_constant("world_opacity_fade", inst_.film.background_opacity_get()); + world_ps_.bind_texture("utility_tx", inst_.pipelines.utility_tx); /* AOVs. */ - DRW_shgroup_uniform_image_ref(grp, "aov_color_img", &rbufs.aov_color_tx); - DRW_shgroup_uniform_image_ref(grp, "aov_value_img", &rbufs.aov_value_tx); - DRW_shgroup_storage_block_ref(grp, "aov_buf", &inst_.film.aovs_info); + world_ps_.bind_image("aov_color_img", &rbufs.aov_color_tx); + world_ps_.bind_image("aov_value_img", &rbufs.aov_value_tx); + world_ps_.bind_ssbo("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_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); + world_ps_.bind_image("rp_normal_img", &rbufs.normal_tx); + world_ps_.bind_image("rp_light_img", &rbufs.light_tx); + world_ps_.bind_image("rp_diffuse_color_img", &rbufs.diffuse_color_tx); + world_ps_.bind_image("rp_specular_color_img", &rbufs.specular_color_tx); + world_ps_.bind_image("rp_emission_img", &rbufs.emission_tx); + world_ps_.bind_image("rp_cryptomatte_img", &rbufs.cryptomatte_tx); + + world_ps_.draw(DRW_cache_fullscreen_quad_get(), handle); /* To allow opaque pass rendering over it. */ - DRW_shgroup_barrier(grp, GPU_BARRIER_SHADER_IMAGE_ACCESS); + world_ps_.barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS); } -void WorldPipeline::render() +void WorldPipeline::render(View &view) { - DRW_draw_pass(world_ps_); + inst_.manager->submit(world_ps_, view); } /** \} */ @@ -67,216 +66,167 @@ void WorldPipeline::render() void ForwardPipeline::sync() { + camera_forward_ = inst_.camera.forward(); + + DRWState state_depth_only = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS; + DRWState state_depth_color = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | + DRW_STATE_WRITE_COLOR; { - DRWState state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS; - prepass_ps_ = DRW_pass_create("Forward.Opaque.Prepass", state); - prepass_velocity_ps_ = DRW_pass_create("Forward.Opaque.Prepass.Velocity", - state | DRW_STATE_WRITE_COLOR); + prepass_ps_.init(); - state |= DRW_STATE_CULL_BACK; - prepass_culled_ps_ = DRW_pass_create("Forward.Opaque.Prepass.Culled", state); - prepass_culled_velocity_ps_ = DRW_pass_create("Forward.Opaque.Prepass.Velocity", - state | DRW_STATE_WRITE_COLOR); + { + /* Common resources. */ - DRW_pass_link(prepass_ps_, prepass_velocity_ps_); - DRW_pass_link(prepass_velocity_ps_, prepass_culled_ps_); - DRW_pass_link(prepass_culled_ps_, prepass_culled_velocity_ps_); - } - { - DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL; - opaque_ps_ = DRW_pass_create("Forward.Opaque", state); + /* Textures. */ + prepass_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx); - state |= DRW_STATE_CULL_BACK; - opaque_culled_ps_ = DRW_pass_create("Forward.Opaque.Culled", state); + inst_.velocity.bind_resources(&prepass_ps_); + inst_.sampling.bind_resources(&prepass_ps_); + } + + prepass_double_sided_static_ps_ = &prepass_ps_.sub("DoubleSided.Static"); + prepass_double_sided_static_ps_->state_set(state_depth_only); + + prepass_single_sided_static_ps_ = &prepass_ps_.sub("SingleSided.Static"); + prepass_single_sided_static_ps_->state_set(state_depth_only | DRW_STATE_CULL_BACK); - DRW_pass_link(opaque_ps_, opaque_culled_ps_); + prepass_double_sided_moving_ps_ = &prepass_ps_.sub("DoubleSided.Moving"); + prepass_double_sided_moving_ps_->state_set(state_depth_color); + + prepass_single_sided_moving_ps_ = &prepass_ps_.sub("SingleSided.Moving"); + prepass_single_sided_moving_ps_->state_set(state_depth_color | DRW_STATE_CULL_BACK); } { - DRWState state = DRW_STATE_DEPTH_LESS_EQUAL; - transparent_ps_ = DRW_pass_create("Forward.Transparent", state); + opaque_ps_.init(); + + { + /* Common resources. */ + + /* RenderPasses. */ + opaque_ps_.bind_image(RBUFS_NORMAL_SLOT, &inst_.render_buffers.normal_tx); + opaque_ps_.bind_image(RBUFS_LIGHT_SLOT, &inst_.render_buffers.light_tx); + opaque_ps_.bind_image(RBUFS_DIFF_COLOR_SLOT, &inst_.render_buffers.diffuse_color_tx); + opaque_ps_.bind_image(RBUFS_SPEC_COLOR_SLOT, &inst_.render_buffers.specular_color_tx); + opaque_ps_.bind_image(RBUFS_EMISSION_SLOT, &inst_.render_buffers.emission_tx); + /* AOVs. */ + opaque_ps_.bind_image(RBUFS_AOV_COLOR_SLOT, &inst_.render_buffers.aov_color_tx); + opaque_ps_.bind_image(RBUFS_AOV_VALUE_SLOT, &inst_.render_buffers.aov_value_tx); + /* Cryptomatte. */ + opaque_ps_.bind_image(RBUFS_CRYPTOMATTE_SLOT, &inst_.render_buffers.cryptomatte_tx); + /* Storage Buf. */ + opaque_ps_.bind_ssbo(RBUFS_AOV_BUF_SLOT, &inst_.film.aovs_info); + /* Textures. */ + opaque_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx); + + inst_.lights.bind_resources(&opaque_ps_); + inst_.sampling.bind_resources(&opaque_ps_); + inst_.cryptomatte.bind_resources(&opaque_ps_); + } + + opaque_single_sided_ps_ = &opaque_ps_.sub("SingleSided"); + opaque_single_sided_ps_->state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | + DRW_STATE_CULL_BACK); + + opaque_double_sided_ps_ = &opaque_ps_.sub("DoubleSided"); + opaque_double_sided_ps_->state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL); } -} + { + transparent_ps_.init(); + /* Workaround limitation of PassSortable. Use dummy pass that will be sorted first in all + * circumstances. */ + PassMain::Sub &sub = transparent_ps_.sub("ResourceBind", -FLT_MAX); -DRWShadingGroup *ForwardPipeline::material_opaque_add(::Material *blender_mat, GPUMaterial *gpumat) -{ - RenderBuffers &rbufs = inst_.render_buffers; - DRWPass *pass = (blender_mat->blend_flag & MA_BL_CULL_BACKFACE) ? opaque_culled_ps_ : opaque_ps_; - LightModule &lights = inst_.lights; - Sampling &sampling = inst_.sampling; - // LightProbeModule &lightprobes = inst_.lightprobes; - // RaytracingModule &raytracing = inst_.raytracing; - // eGPUSamplerState no_interp = GPU_SAMPLER_DEFAULT; - DRWShadingGroup *grp = DRW_shgroup_material_create(gpumat, pass); - lights.bind_resources(grp); - sampling.bind_resources(grp); - // DRW_shgroup_uniform_block(grp, "sampling_buf", inst_.sampling.ubo_get()); - // DRW_shgroup_uniform_block(grp, "grids_buf", lightprobes.grid_ubo_get()); - // DRW_shgroup_uniform_block(grp, "cubes_buf", lightprobes.cube_ubo_get()); - // DRW_shgroup_uniform_block(grp, "probes_buf", lightprobes.info_ubo_get()); - // DRW_shgroup_uniform_texture_ref(grp, "lightprobe_grid_tx", lightprobes.grid_tx_ref_get()); - // DRW_shgroup_uniform_texture_ref(grp, "lightprobe_cube_tx", lightprobes.cube_tx_ref_get()); - DRW_shgroup_uniform_texture(grp, "utility_tx", inst_.pipelines.utility_tx); - /* AOVs. */ - DRW_shgroup_uniform_image_ref(grp, "aov_color_img", &rbufs.aov_color_tx); - DRW_shgroup_uniform_image_ref(grp, "aov_value_img", &rbufs.aov_value_tx); - 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_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); - - /* TODO(fclem): Make this only needed if material uses it ... somehow. */ - // if (true) { - // DRW_shgroup_uniform_texture_ref( - // grp, "sss_transmittance_tx", inst_.subsurface.transmittance_ref_get()); - // } - // if (raytracing.enabled()) { - // DRW_shgroup_uniform_block(grp, "rt_diffuse_buf", raytracing.diffuse_data); - // DRW_shgroup_uniform_block(grp, "rt_reflection_buf", raytracing.reflection_data); - // DRW_shgroup_uniform_block(grp, "rt_refraction_buf", raytracing.refraction_data); - // DRW_shgroup_uniform_texture_ref_ex(grp, "radiance_tx", &input_screen_radiance_tx_, - // no_interp); - // } - // if (raytracing.enabled()) { - // DRW_shgroup_uniform_block(grp, "hiz_buf", inst_.hiz.ubo_get()); - // DRW_shgroup_uniform_texture_ref(grp, "hiz_tx", inst_.hiz_front.texture_ref_get()); - // } - return grp; -} + /* Common resources. */ -DRWShadingGroup *ForwardPipeline::prepass_opaque_add(::Material *blender_mat, - GPUMaterial *gpumat, - bool has_motion) -{ - DRWPass *pass = (blender_mat->blend_flag & MA_BL_CULL_BACKFACE) ? - (has_motion ? prepass_culled_velocity_ps_ : prepass_culled_ps_) : - (has_motion ? prepass_velocity_ps_ : prepass_ps_); - DRWShadingGroup *grp = DRW_shgroup_material_create(gpumat, pass); - if (has_motion) { - inst_.velocity.bind_resources(grp); + /* Textures. */ + sub.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx); + + inst_.lights.bind_resources(&sub); + inst_.sampling.bind_resources(&sub); } - return grp; } -DRWShadingGroup *ForwardPipeline::material_transparent_add(::Material *blender_mat, - GPUMaterial *gpumat) +PassMain::Sub *ForwardPipeline::prepass_opaque_add(::Material *blender_mat, + GPUMaterial *gpumat, + bool has_motion) { - RenderBuffers &rbufs = inst_.render_buffers; - LightModule &lights = inst_.lights; - Sampling &sampling = inst_.sampling; - // LightProbeModule &lightprobes = inst_.lightprobes; - // RaytracingModule &raytracing = inst_.raytracing; - // eGPUSamplerState no_interp = GPU_SAMPLER_DEFAULT; - DRWShadingGroup *grp = DRW_shgroup_material_create(gpumat, transparent_ps_); - lights.bind_resources(grp); - sampling.bind_resources(grp); - // DRW_shgroup_uniform_block(grp, "sampling_buf", inst_.sampling.ubo_get()); - // DRW_shgroup_uniform_block(grp, "grids_buf", lightprobes.grid_ubo_get()); - // DRW_shgroup_uniform_block(grp, "cubes_buf", lightprobes.cube_ubo_get()); - // DRW_shgroup_uniform_block(grp, "probes_buf", lightprobes.info_ubo_get()); - // DRW_shgroup_uniform_texture_ref(grp, "lightprobe_grid_tx", lightprobes.grid_tx_ref_get()); - // DRW_shgroup_uniform_texture_ref(grp, "lightprobe_cube_tx", lightprobes.cube_tx_ref_get()); - DRW_shgroup_uniform_texture(grp, "utility_tx", inst_.pipelines.utility_tx); - /* TODO(fclem): Make this only needed if material uses it ... somehow. */ - // if (true) { - // DRW_shgroup_uniform_texture_ref( - // grp, "sss_transmittance_tx", inst_.subsurface.transmittance_ref_get()); - // } - // if (raytracing.enabled()) { - // DRW_shgroup_uniform_block(grp, "rt_diffuse_buf", raytracing.diffuse_data); - // DRW_shgroup_uniform_block(grp, "rt_reflection_buf", raytracing.reflection_data); - // DRW_shgroup_uniform_block(grp, "rt_refraction_buf", raytracing.refraction_data); - // DRW_shgroup_uniform_texture_ref_ex( - // grp, "rt_radiance_tx", &input_screen_radiance_tx_, no_interp); - // } - // if (raytracing.enabled()) { - // DRW_shgroup_uniform_block(grp, "hiz_buf", inst_.hiz.ubo_get()); - // DRW_shgroup_uniform_texture_ref(grp, "hiz_tx", inst_.hiz_front.texture_ref_get()); - // } - { - /* TODO(fclem): This is not needed. This is only to please the OpenGL debug Layer. - * If we are to introduce transparency render-passes support, it would be through a separate - * pass. */ - /* AOVs. */ - DRW_shgroup_uniform_image_ref(grp, "aov_color_img", &rbufs.aov_color_tx); - DRW_shgroup_uniform_image_ref(grp, "aov_value_img", &rbufs.aov_value_tx); - 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_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); - } + PassMain::Sub *pass = (blender_mat->blend_flag & MA_BL_CULL_BACKFACE) ? + (has_motion ? prepass_single_sided_moving_ps_ : + prepass_single_sided_static_ps_) : + (has_motion ? prepass_double_sided_moving_ps_ : + prepass_double_sided_static_ps_); + return &pass->sub(GPU_material_get_name(gpumat)); +} - DRWState state_disable = DRW_STATE_WRITE_DEPTH; - DRWState state_enable = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM; - if (blender_mat->blend_flag & MA_BL_CULL_BACKFACE) { - state_enable |= DRW_STATE_CULL_BACK; - } - DRW_shgroup_state_disable(grp, state_disable); - DRW_shgroup_state_enable(grp, state_enable); - return grp; +PassMain::Sub *ForwardPipeline::material_opaque_add(::Material *blender_mat, GPUMaterial *gpumat) +{ + PassMain::Sub *pass = (blender_mat->blend_flag & MA_BL_CULL_BACKFACE) ? opaque_single_sided_ps_ : + opaque_double_sided_ps_; + return &pass->sub(GPU_material_get_name(gpumat)); } -DRWShadingGroup *ForwardPipeline::prepass_transparent_add(::Material *blender_mat, - GPUMaterial *gpumat) +PassMain::Sub *ForwardPipeline::prepass_transparent_add(const Object *ob, + ::Material *blender_mat, + GPUMaterial *gpumat) { if ((blender_mat->blend_flag & MA_BL_HIDE_BACKFACE) == 0) { return nullptr; } + DRWState state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL; + if ((blender_mat->blend_flag & MA_BL_CULL_BACKFACE)) { + state |= DRW_STATE_CULL_BACK; + } + float sorting_value = math::dot(float3(ob->obmat[3]), camera_forward_); + PassMain::Sub *pass = &transparent_ps_.sub(GPU_material_get_name(gpumat), sorting_value); + pass->state_set(state); + pass->material_set(*inst_.manager, gpumat); + return pass; +} - DRWShadingGroup *grp = DRW_shgroup_material_create(gpumat, transparent_ps_); - - DRWState state_disable = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM; - DRWState state_enable = DRW_STATE_WRITE_DEPTH; - if (blender_mat->blend_flag & MA_BL_CULL_BACKFACE) { - state_enable |= DRW_STATE_CULL_BACK; +PassMain::Sub *ForwardPipeline::material_transparent_add(const Object *ob, + ::Material *blender_mat, + GPUMaterial *gpumat) +{ + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM | DRW_STATE_DEPTH_LESS_EQUAL; + if ((blender_mat->blend_flag & MA_BL_CULL_BACKFACE)) { + state |= DRW_STATE_CULL_BACK; } - DRW_shgroup_state_disable(grp, state_disable); - DRW_shgroup_state_enable(grp, state_enable); - return grp; + float sorting_value = math::dot(float3(ob->obmat[3]), camera_forward_); + PassMain::Sub *pass = &transparent_ps_.sub(GPU_material_get_name(gpumat), sorting_value); + pass->state_set(state); + pass->material_set(*inst_.manager, gpumat); + return pass; } -void ForwardPipeline::render(const DRWView *view, +void ForwardPipeline::render(View &view, Framebuffer &prepass_fb, Framebuffer &combined_fb, - GPUTexture *depth_tx, GPUTexture *UNUSED(combined_tx)) { - UNUSED_VARS(view, depth_tx, prepass_fb, combined_fb); - // HiZBuffer &hiz = inst_.hiz_front; + UNUSED_VARS(view); - DRW_stats_group_start("ForwardOpaque"); + DRW_stats_group_start("Forward.Opaque"); GPU_framebuffer_bind(prepass_fb); - DRW_draw_pass(prepass_ps_); + inst_.manager->submit(prepass_ps_, view); - // hiz.set_dirty(); + // if (!DRW_pass_is_empty(prepass_ps_)) { + inst_.hiz_buffer.set_dirty(); + // } // if (inst_.raytracing.enabled()) { // rt_buffer.radiance_copy(combined_tx); - // hiz.update(depth_tx); + // inst_.hiz_buffer.update(); // } // inst_.shadows.set_view(view, depth_tx); GPU_framebuffer_bind(combined_fb); - DRW_draw_pass(opaque_ps_); + inst_.manager->submit(opaque_ps_, view); DRW_stats_group_end(); - DRW_stats_group_start("ForwardTransparent"); - /* TODO(fclem) This is suboptimal. We could sort during sync. */ - /* FIXME(fclem) This wont work for panoramic, where we need - * to sort by distance to camera, not by z. */ - DRW_pass_sort_shgroup_z(transparent_ps_); - DRW_draw_pass(transparent_ps_); - DRW_stats_group_end(); + inst_.manager->submit(transparent_ps_, view); // if (inst_.raytracing.enabled()) { // gbuffer.ray_radiance_tx.release(); |