Blender V5.0
eevee_shadow_shared.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#pragma once
10
11#include "eevee_light_shared.hh"
12#include "eevee_transform.hh"
13
14#ifndef GPU_SHADER
15namespace blender::eevee {
16#endif
17
18/* -------------------------------------------------------------------- */
30
31enum eCubeFace : uint32_t {
32 /* Ordering by culling order. If cone aperture is shallow, we cull the later view. */
33 Z_NEG = 0u,
34 X_POS = 1u,
35 X_NEG = 2u,
36 Y_POS = 3u,
37 Y_NEG = 4u,
38 Z_POS = 5u,
39};
40
46
47static inline int2 shadow_cascade_grid_offset(int2 base_offset, int level_relative)
48{
49 return (base_offset * level_relative) / (1 << 16);
50}
51
91
92
120
121
133 /* Transform the shadow is rendered with. Used to detect updates on GPU. */
135 /* Integer offset of the center of the 16x16 tiles from the origin of the tile space. */
137 int _pad0;
138 int _pad1;
139};
141
159
179
180
198
199#define ShadowTileDataPacked uint
200
201enum eShadowFlag : uint32_t {
203 SHADOW_IS_CACHED = (1u << 27u),
204 SHADOW_IS_ALLOCATED = (1u << 28u),
205 SHADOW_DO_UPDATE = (1u << 29u),
206 SHADOW_IS_RENDERED = (1u << 30u),
207 SHADOW_IS_USED = (1u << 31u)
208};
209
210/* NOTE: Trust the input to be in valid range (max is [3,3,255]).
211 * If it is in valid range, it should pack to 12bits so that `shadow_tile_pack()` can use it.
212 * But sometime this is used to encode invalid pages uint3(-1) and it needs to output uint(-1).
213 */
214static inline uint shadow_page_pack(uint3 page)
215{
216 return (page.x << 0u) | (page.y << 2u) | (page.z << 4u);
217}
219{
220 uint3 page;
221 BLI_STATIC_ASSERT(SHADOW_PAGE_PER_ROW <= 4 && SHADOW_PAGE_PER_COL <= 4, "Update page packing")
222 page.x = (data >> 0u) & 3u;
223 page.y = (data >> 2u) & 3u;
224 BLI_STATIC_ASSERT(SHADOW_MAX_PAGE <= 4096, "Update page packing")
225 page.z = (data >> 4u) & 255u;
226 return page;
227}
228
230{
233 /* -- 12 bits -- */
234 /* Unused bits. */
235 /* -- 15 bits -- */
236 BLI_STATIC_ASSERT(SHADOW_MAX_PAGE <= 4096, "Update page packing")
237 tile.cache_index = (data >> 15u) & 4095u;
238 /* -- 27 bits -- */
239 tile.is_used = (data & SHADOW_IS_USED) != 0;
240 tile.is_cached = (data & SHADOW_IS_CACHED) != 0;
241 tile.is_allocated = (data & SHADOW_IS_ALLOCATED) != 0;
242 tile.is_rendered = (data & SHADOW_IS_RENDERED) != 0;
243 tile.do_update = (data & SHADOW_DO_UPDATE) != 0;
244 return tile;
245}
246
248{
249 uint data;
250 /* NOTE: Page might be set to invalid values for tracking invalid usages.
251 * So we have to mask the result. */
253 data |= (tile.cache_index & 4095u) << 15u;
254 data |= (tile.is_used ? uint(SHADOW_IS_USED) : 0);
255 data |= (tile.is_allocated ? uint(SHADOW_IS_ALLOCATED) : 0);
256 data |= (tile.is_cached ? uint(SHADOW_IS_CACHED) : 0);
257 data |= (tile.is_rendered ? uint(SHADOW_IS_RENDERED) : 0);
258 data |= (tile.do_update ? uint(SHADOW_DO_UPDATE) : 0);
259 return data;
260}
261
277
278#define ShadowSamplingTilePacked uint
279
280/* NOTE: Trust the input to be in valid range [0, (1 << SHADOW_TILEMAP_MAX_CLIPMAP_LOD) - 1].
281 * Maximum LOD level index we can store is SHADOW_TILEMAP_MAX_CLIPMAP_LOD,
282 * so we need SHADOW_TILEMAP_MAX_CLIPMAP_LOD bits to store the offset in each dimension.
283 * Result fits into SHADOW_TILEMAP_MAX_CLIPMAP_LOD * 2 bits. */
285{
286 BLI_STATIC_ASSERT(SHADOW_TILEMAP_MAX_CLIPMAP_LOD <= 8, "Update page packing")
287 return ofs.x | (ofs.y << SHADOW_TILEMAP_MAX_CLIPMAP_LOD);
288}
294
296{
299 /* -- 12 bits -- */
300 /* Max value is actually SHADOW_TILEMAP_MAX_CLIPMAP_LOD but we mask the bits. */
301 tile.lod = (data >> 12u) & 15u;
302 /* -- 16 bits -- */
303 tile.lod_offset = shadow_lod_offset_unpack(data >> 16u);
304 /* -- 32 bits -- */
305 tile.is_valid = data != 0u;
306#ifndef GPU_SHADER
307 /* Make tests pass on CPU but it is not required for proper rendering. */
308 if (tile.lod == 0) {
309 tile.lod_offset.x = 0;
310 }
311#endif
312 return tile;
313}
314
316{
317 if (!tile.is_valid) {
318 return 0u;
319 }
320 /* Tag a valid tile of LOD0 valid by setting their offset to 1.
321 * This doesn't change the sampling and allows to use of all bits for data.
322 * This makes sure no valid packed tile is 0u. */
323 if (tile.lod == 0) {
324 tile.lod_offset.x = 1;
325 }
327 /* Max value is actually SHADOW_TILEMAP_MAX_CLIPMAP_LOD but we mask the bits. */
328 data |= (tile.lod & 15u) << 12u;
329 data |= shadow_lod_offset_pack(tile.lod_offset) << 16u;
330 return data;
331}
332
334{
336 tile.page = tile_data.page;
337 tile.lod = lod;
338 tile.lod_offset = uint2(0, 0); /* Computed during tilemap amend phase. */
339 /* At this point, it should be the case that all given tiles that have been tagged as used are
340 * ready for sampling. Otherwise tile_data should be SHADOW_NO_DATA. */
341 tile.is_valid = tile_data.is_used;
342 return tile;
343}
344
346
347#ifndef GPU_SHADER
348} // namespace blender::eevee
349#endif
#define BLI_STATIC_ASSERT_ALIGN(st, align)
Definition BLI_assert.h:86
unsigned int uint
int32_t bool32_t
BMesh const char void * data
#define SHADOW_PAGE_PER_ROW
#define SHADOW_TILEMAP_MAX_CLIPMAP_LOD
#define SHADOW_PAGE_PER_COL
#define SHADOW_MAX_PAGE
#define ShadowTileDataPacked
#define ShadowSamplingTilePacked
const ccl_global KernelWorkTile * tile
BLI_STATIC_ASSERT(MBC_BATCH_LEN< 64, "Number of batches exceeded the limit of bit fields")
static int2 shadow_cascade_grid_offset(int2 base_offset, int level_relative)
static ShadowTileDataPacked shadow_tile_pack(ShadowTileData tile)
static ShadowSamplingTilePacked shadow_sampling_tile_pack(ShadowSamplingTile tile)
static ShadowTileData shadow_tile_unpack(ShadowTileDataPacked data)
static uint2 shadow_lod_offset_unpack(uint data)
static uint3 shadow_page_unpack(uint data)
static uint shadow_page_pack(uint3 page)
static uint shadow_lod_offset_pack(uint2 ofs)
static ShadowSamplingTile shadow_sampling_tile_create(ShadowTileData tile_data, uint lod)
static ShadowSamplingTile shadow_sampling_tile_unpack(ShadowSamplingTilePacked data)
VecBase< uint32_t, 2 > uint2
VecBase< uint32_t, 3 > uint3
MatBase< float, 4, 4 > float4x4
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2