Blender V5.0
eevee_hizbuffer.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2022 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "eevee_instance.hh"
6
7#include "eevee_hizbuffer.hh"
8
9namespace blender::eevee {
10
11/* -------------------------------------------------------------------- */
15
17{
18 int2 render_extent = inst_.film.render_extent_get();
19 int2 probe_extent = int2(inst_.sphere_probes.probe_render_extent());
20 /* Padding to avoid complexity during down-sampling and screen tracing. */
21 int2 hiz_extent = math::ceil_to_multiple(math::max(render_extent, probe_extent),
22 int2(1u << (HIZ_MIP_COUNT - 1)));
23 int2 dispatch_size = math::divide_ceil(hiz_extent, int2(HIZ_GROUP_SIZE));
24
26 for ([[maybe_unused]] const int i : IndexRange(hiz_tx_.size())) {
27 hiz_tx_.current().ensure_2d(
28 gpu::TextureFormat::SFLOAT_32, hiz_extent, usage, nullptr, HIZ_MIP_COUNT);
29 hiz_tx_.current().ensure_mip_views();
30 GPU_texture_mipmap_mode(hiz_tx_.current(), true, false);
31 hiz_tx_.swap();
32 }
33
34 data_.uv_scale = float2(render_extent) / float2(hiz_extent);
35
36 /* TODO(@fclem): There might be occasions where we might not want to
37 * copy mip 0 for performance reasons if there is no need for it. */
38 bool update_mip_0 = true;
39
40 {
41 PassSimple &pass = hiz_update_ps_;
42 gpu::Shader *sh = inst_.shaders.static_shader_get(HIZ_UPDATE);
43 pass.init();
44 pass.specialize_constant(sh, "update_mip_0", update_mip_0);
45 pass.shader_set(sh);
46 pass.bind_ssbo("finished_tile_counter", atomic_tile_counter_);
47 /* TODO(fclem): Should be a parameter to avoid confusion. */
48 pass.bind_texture("depth_tx", &src_tx_);
49 pass.bind_image("out_mip_0", &hiz_mip_ref_[0]);
50 pass.bind_image("out_mip_1", &hiz_mip_ref_[1]);
51 pass.bind_image("out_mip_2", &hiz_mip_ref_[2]);
52 pass.bind_image("out_mip_3", &hiz_mip_ref_[3]);
53 pass.bind_image("out_mip_4", &hiz_mip_ref_[4]);
54 pass.bind_image("out_mip_5", &hiz_mip_ref_[5]);
55 pass.bind_image("out_mip_6", &hiz_mip_ref_[6]);
56 pass.dispatch(int3(dispatch_size, 1));
58 }
59 {
60 PassSimple &pass = hiz_update_layer_ps_;
61 gpu::Shader *sh = inst_.shaders.static_shader_get(HIZ_UPDATE_LAYER);
62 pass.init();
63 pass.specialize_constant(sh, "update_mip_0", update_mip_0);
64 pass.shader_set(sh);
65 pass.bind_ssbo("finished_tile_counter", atomic_tile_counter_);
66 /* TODO(fclem): Should be a parameter to avoid confusion. */
67 pass.bind_texture("depth_layered_tx", &src_tx_);
68 pass.bind_image("out_mip_0", &hiz_mip_ref_[0]);
69 pass.bind_image("out_mip_1", &hiz_mip_ref_[1]);
70 pass.bind_image("out_mip_2", &hiz_mip_ref_[2]);
71 pass.bind_image("out_mip_3", &hiz_mip_ref_[3]);
72 pass.bind_image("out_mip_4", &hiz_mip_ref_[4]);
73 pass.bind_image("out_mip_5", &hiz_mip_ref_[5]);
74 pass.bind_image("out_mip_6", &hiz_mip_ref_[6]);
75 pass.push_constant("layer_id", &layer_id_);
76 pass.dispatch(int3(dispatch_size, 1));
78 }
79
80 if (inst_.debug_mode == eDebugMode::DEBUG_HIZ_VALIDATION) {
81 debug_draw_ps_.init();
82 debug_draw_ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM);
83 debug_draw_ps_.shader_set(inst_.shaders.static_shader_get(HIZ_DEBUG));
84 debug_draw_ps_.bind_resources(this->front);
85 debug_draw_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
86 }
87}
88
90{
91 if (!is_dirty_) {
92 return;
93 }
94
95 src_tx_ = *src_tx_ptr_;
96 for (const int i : IndexRange(HIZ_MIP_COUNT)) {
97 hiz_mip_ref_[i] = hiz_tx_.current().mip_view(i);
98 }
99
100 if (layer_id_ == -1) {
101 inst_.manager->submit(hiz_update_ps_);
102 }
103 else {
104 inst_.manager->submit(hiz_update_layer_ps_);
105 }
106
107 is_dirty_ = false;
108}
109
111{
112 if (inst_.debug_mode == eDebugMode::DEBUG_HIZ_VALIDATION) {
113 inst_.info_append(
114 "Debug Mode: HiZ Validation\n"
115 " - Red: pixel in front of HiZ tile value.\n"
116 " - Blue: No error.");
117 inst_.hiz_buffer.update();
118 GPU_framebuffer_bind(view_fb);
119 inst_.manager->submit(debug_draw_ps_, view);
120 }
121}
122
124
125} // namespace blender::eevee
static AppView * view
void GPU_framebuffer_bind(blender::gpu::FrameBuffer *fb)
@ GPU_PRIM_TRIS
@ GPU_BARRIER_TEXTURE_FETCH
Definition GPU_state.hh:37
void GPU_texture_mipmap_mode(blender::gpu::Texture *texture, bool use_mipmap, bool use_filter)
eGPUTextureUsage
@ GPU_TEXTURE_USAGE_SHADER_READ
@ GPU_TEXTURE_USAGE_SHADER_WRITE
void shader_set(gpu::Shader *shader)
void bind_texture(const char *name, gpu::Texture *texture, GPUSamplerState state=sampler_auto)
void specialize_constant(gpu::Shader *shader, const char *name, const float &data)
void bind_image(const char *name, gpu::Texture *image)
void dispatch(int group_len)
void barrier(GPUBarrier type)
void push_constant(const char *name, const float &data)
void bind_ssbo(const char *name, gpu::StorageBuf *buffer)
void debug_draw(View &view, gpu::FrameBuffer *view_fb)
struct blender::eevee::HiZBuffer::@312272073133116306117315271010160007344264367302 front
@ DRW_STATE_WRITE_COLOR
Definition draw_state.hh:30
@ DRW_STATE_BLEND_CUSTOM
Definition draw_state.hh:63
#define HIZ_MIP_COUNT
#define HIZ_GROUP_SIZE
detail::Pass< command::DrawCommandBuf > PassSimple
VecBase< T, Size > divide_ceil(const VecBase< T, Size > &a, const VecBase< T, Size > &b)
VecBase< T, Size > ceil_to_multiple(const VecBase< T, Size > &a, const VecBase< T, Size > &b)
T max(const T &a, const T &b)
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
VecBase< int32_t, 3 > int3
i
Definition text_draw.cc:230