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/* -------------------------------------------------------------------- */
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_;
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));
58 pass.barrier(GPU_BARRIER_TEXTURE_FETCH);
59 }
60 {
61 PassSimple &pass = hiz_update_layer_ps_;
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));
78 pass.barrier(GPU_BARRIER_TEXTURE_FETCH);
79 }
80
82 debug_draw_ps_.init();
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{
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
126} // namespace blender::eevee
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 submit(PassSimple &pass, View &view)
void bind_resources(U &resources)
Definition draw_pass.hh:426
void draw_procedural(GPUPrimType primitive, uint instance_len, uint vertex_len, uint vertex_first=-1, ResourceHandle handle={0}, uint custom_id=0)
Definition draw_pass.hh:833
void state_set(DRWState state, int clip_plane_count=0)
Definition draw_pass.hh:954
void shader_set(GPUShader *shader)
Definition draw_pass.hh:971
int2 render_extent_get() const
void debug_draw(View &view, GPUFrameBuffer *view_fb)
struct blender::eevee::HiZBuffer::@195 front
SphereProbeModule sphere_probes
void info_append(const char *msg, Args &&...args)
GPUShader * static_shader_get(eShaderType shader_type)
@ 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
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