Blender V4.5
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(GPU_R32F, hiz_extent, usage, nullptr, HIZ_MIP_COUNT);
28 hiz_tx_.current().ensure_mip_views();
29 GPU_texture_mipmap_mode(hiz_tx_.current(), true, false);
30 hiz_tx_.swap();
31 }
32
33 data_.uv_scale = float2(render_extent) / float2(hiz_extent);
34
35 /* TODO(@fclem): There might be occasions where we might not want to
36 * copy mip 0 for performance reasons if there is no need for it. */
37 bool update_mip_0 = true;
38
39 {
40 PassSimple &pass = hiz_update_ps_;
41 GPUShader *sh = inst_.shaders.static_shader_get(HIZ_UPDATE);
42 pass.init();
43 pass.specialize_constant(sh, "update_mip_0", update_mip_0);
44 pass.shader_set(sh);
45 pass.bind_ssbo("finished_tile_counter", atomic_tile_counter_);
46 /* TODO(fclem): Should be a parameter to avoid confusion. */
47 pass.bind_texture("depth_tx", &src_tx_);
48 pass.bind_image("out_mip_0", &hiz_mip_ref_[0]);
49 pass.bind_image("out_mip_1", &hiz_mip_ref_[1]);
50 pass.bind_image("out_mip_2", &hiz_mip_ref_[2]);
51 pass.bind_image("out_mip_3", &hiz_mip_ref_[3]);
52 pass.bind_image("out_mip_4", &hiz_mip_ref_[4]);
53 pass.bind_image("out_mip_5", &hiz_mip_ref_[5]);
54 pass.bind_image("out_mip_6", &hiz_mip_ref_[6]);
55 pass.dispatch(int3(dispatch_size, 1));
57 }
58 {
59 PassSimple &pass = hiz_update_layer_ps_;
60 GPUShader *sh = inst_.shaders.static_shader_get(HIZ_UPDATE_LAYER);
61 pass.init();
62 pass.specialize_constant(sh, "update_mip_0", update_mip_0);
63 pass.shader_set(sh);
64 pass.bind_ssbo("finished_tile_counter", atomic_tile_counter_);
65 /* TODO(fclem): Should be a parameter to avoid confusion. */
66 pass.bind_texture("depth_layered_tx", &src_tx_);
67 pass.bind_image("out_mip_0", &hiz_mip_ref_[0]);
68 pass.bind_image("out_mip_1", &hiz_mip_ref_[1]);
69 pass.bind_image("out_mip_2", &hiz_mip_ref_[2]);
70 pass.bind_image("out_mip_3", &hiz_mip_ref_[3]);
71 pass.bind_image("out_mip_4", &hiz_mip_ref_[4]);
72 pass.bind_image("out_mip_5", &hiz_mip_ref_[5]);
73 pass.bind_image("out_mip_6", &hiz_mip_ref_[6]);
74 pass.push_constant("layer_id", &layer_id_);
75 pass.dispatch(int3(dispatch_size, 1));
77 }
78
79 if (inst_.debug_mode == eDebugMode::DEBUG_HIZ_VALIDATION) {
80 debug_draw_ps_.init();
81 debug_draw_ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM);
82 debug_draw_ps_.shader_set(inst_.shaders.static_shader_get(HIZ_DEBUG));
83 debug_draw_ps_.bind_resources(this->front);
84 debug_draw_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
85 }
86}
87
89{
90 if (!is_dirty_) {
91 return;
92 }
93
94 src_tx_ = *src_tx_ptr_;
95 for (const int i : IndexRange(HIZ_MIP_COUNT)) {
96 hiz_mip_ref_[i] = hiz_tx_.current().mip_view(i);
97 }
98
99 if (layer_id_ == -1) {
100 inst_.manager->submit(hiz_update_ps_);
101 }
102 else {
103 inst_.manager->submit(hiz_update_layer_ps_);
104 }
105
106 is_dirty_ = false;
107}
108
109void HiZBuffer::debug_draw(View &view, GPUFrameBuffer *view_fb)
110{
111 if (inst_.debug_mode == eDebugMode::DEBUG_HIZ_VALIDATION) {
112 inst_.info_append(
113 "Debug Mode: HiZ Validation\n"
114 " - Red: pixel in front of HiZ tile value.\n"
115 " - Blue: No error.");
116 inst_.hiz_buffer.update();
117 GPU_framebuffer_bind(view_fb);
118 inst_.manager->submit(debug_draw_ps_, view);
119 }
120}
121
123
124} // namespace blender::eevee
static AppView * view
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
@ GPU_PRIM_TRIS
@ GPU_BARRIER_TEXTURE_FETCH
Definition GPU_state.hh:37
eGPUTextureUsage
@ GPU_TEXTURE_USAGE_SHADER_READ
@ GPU_TEXTURE_USAGE_SHADER_WRITE
void GPU_texture_mipmap_mode(GPUTexture *texture, bool use_mipmap, bool use_filter)
@ GPU_R32F
void bind_texture(const char *name, GPUTexture *texture, GPUSamplerState state=sampler_auto)
void bind_image(const char *name, GPUTexture *image)
void specialize_constant(GPUShader *shader, const char *name, const float &data)
void dispatch(int group_len)
Definition draw_pass.hh:994
void barrier(eGPUBarrier type)
void push_constant(const char *name, const float &data)
void bind_ssbo(const char *name, GPUStorageBuf *buffer)
void shader_set(GPUShader *shader)
void debug_draw(View &view, GPUFrameBuffer *view_fb)
struct blender::eevee::HiZBuffer::@117223074165324154125050272272211024005337204302 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