Blender V4.3
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 "BKE_global.hh"
6
7#include "eevee_instance.hh"
8
9#include "eevee_hizbuffer.hh"
10
11namespace blender::eevee {
12
13/* -------------------------------------------------------------------- */
17
19{
20 int2 render_extent = inst_.film.render_extent_get();
21 int2 probe_extent = int2(inst_.sphere_probes.probe_render_extent());
22 /* Padding to avoid complexity during down-sampling and screen tracing. */
23 int2 hiz_extent = math::ceil_to_multiple(math::max(render_extent, probe_extent),
24 int2(1u << (HIZ_MIP_COUNT - 1)));
25 int2 dispatch_size = math::divide_ceil(hiz_extent, int2(HIZ_GROUP_SIZE));
26
28 for ([[maybe_unused]] const int i : IndexRange(hiz_tx_.size())) {
29 hiz_tx_.current().ensure_2d(GPU_R32F, hiz_extent, usage, nullptr, HIZ_MIP_COUNT);
30 hiz_tx_.current().ensure_mip_views();
31 GPU_texture_mipmap_mode(hiz_tx_.current(), true, false);
32 hiz_tx_.swap();
33 }
34
35 data_.uv_scale = float2(render_extent) / float2(hiz_extent);
36
37 /* TODO(@fclem): There might be occasions where we might not want to
38 * copy mip 0 for performance reasons if there is no need for it. */
39 bool update_mip_0 = true;
40
41 {
42 PassSimple &pass = hiz_update_ps_;
43 GPUShader *sh = inst_.shaders.static_shader_get(HIZ_UPDATE);
44 pass.init();
45 pass.specialize_constant(sh, "update_mip_0", update_mip_0);
46 pass.shader_set(sh);
47 pass.bind_ssbo("finished_tile_counter", atomic_tile_counter_);
48 /* TODO(fclem): Should be a parameter to avoid confusion. */
49 pass.bind_texture("depth_tx", &src_tx_, with_filter);
50 pass.bind_image("out_mip_0", &hiz_mip_ref_[0]);
51 pass.bind_image("out_mip_1", &hiz_mip_ref_[1]);
52 pass.bind_image("out_mip_2", &hiz_mip_ref_[2]);
53 pass.bind_image("out_mip_3", &hiz_mip_ref_[3]);
54 pass.bind_image("out_mip_4", &hiz_mip_ref_[4]);
55 pass.bind_image("out_mip_5", &hiz_mip_ref_[5]);
56 pass.bind_image("out_mip_6", &hiz_mip_ref_[6]);
57 pass.dispatch(int3(dispatch_size, 1));
59 }
60 {
61 PassSimple &pass = hiz_update_layer_ps_;
62 GPUShader *sh = inst_.shaders.static_shader_get(HIZ_UPDATE_LAYER);
63 pass.init();
64 pass.specialize_constant(sh, "update_mip_0", update_mip_0);
65 pass.shader_set(sh);
66 pass.bind_ssbo("finished_tile_counter", atomic_tile_counter_);
67 /* TODO(fclem): Should be a parameter to avoid confusion. */
68 pass.bind_texture("depth_layered_tx", &src_tx_, with_filter);
69 pass.bind_image("out_mip_0", &hiz_mip_ref_[0]);
70 pass.bind_image("out_mip_1", &hiz_mip_ref_[1]);
71 pass.bind_image("out_mip_2", &hiz_mip_ref_[2]);
72 pass.bind_image("out_mip_3", &hiz_mip_ref_[3]);
73 pass.bind_image("out_mip_4", &hiz_mip_ref_[4]);
74 pass.bind_image("out_mip_5", &hiz_mip_ref_[5]);
75 pass.bind_image("out_mip_6", &hiz_mip_ref_[6]);
76 pass.push_constant("layer_id", &layer_id_);
77 pass.dispatch(int3(dispatch_size, 1));
79 }
80
81 if (inst_.debug_mode == eDebugMode::DEBUG_HIZ_VALIDATION) {
82 debug_draw_ps_.init();
83 debug_draw_ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM);
84 debug_draw_ps_.shader_set(inst_.shaders.static_shader_get(HIZ_DEBUG));
85 debug_draw_ps_.bind_resources(this->front);
86 debug_draw_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
87 }
88}
89
91{
92 if (!is_dirty_) {
93 return;
94 }
95
96 src_tx_ = *src_tx_ptr_;
97 for (const int i : IndexRange(HIZ_MIP_COUNT)) {
98 hiz_mip_ref_[i] = hiz_tx_.current().mip_view(i);
99 }
100
101 if (layer_id_ == -1) {
102 inst_.manager->submit(hiz_update_ps_);
103 }
104 else {
105 inst_.manager->submit(hiz_update_layer_ps_);
106 }
107
108 is_dirty_ = false;
109}
110
111void HiZBuffer::debug_draw(View &view, GPUFrameBuffer *view_fb)
112{
113 if (inst_.debug_mode == eDebugMode::DEBUG_HIZ_VALIDATION) {
114 inst_.info_append(
115 "Debug Mode: HiZ Validation\n"
116 " - Red: pixel in front of HiZ tile value.\n"
117 " - Blue: No error.");
118 inst_.hiz_buffer.update();
119 GPU_framebuffer_bind(view_fb);
120 inst_.manager->submit(debug_draw_ps_, view);
121 }
122}
123
125
126} // namespace blender::eevee
static AppView * view
void GPU_framebuffer_bind(GPUFrameBuffer *framebuffer)
@ 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)
struct GPUShader GPUShader
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:874
void barrier(eGPUBarrier type)
Definition draw_pass.hh:943
void push_constant(const char *name, const float &data)
void bind_ssbo(const char *name, GPUStorageBuf *buffer)
void shader_set(GPUShader *shader)
Definition draw_pass.hh:971
void debug_draw(View &view, GPUFrameBuffer *view_fb)
struct blender::eevee::HiZBuffer::@333276274241261234242230221004020010346271237200 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
constexpr GPUSamplerState with_filter
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