mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
EEVEE: Add 1.5 and 2 GB shadow pool options
This is a highly requested feature. The Virtual shadow map system is not perfect and hitting the 1GB limit is quite easy in production files. When there is VRAM available, increasing the pool size is easier than to deal with scene settings or tweaking certain lights. The shadow page packing needed to be updated to add 1 more bit to the page index. And that's mostly it! Pull Request: https://projects.blender.org/blender/blender/pulls/158344
This commit is contained in:
parent
d685c5eaab
commit
4385d9e53c
5 changed files with 51 additions and 28 deletions
|
|
@ -110,14 +110,15 @@
|
|||
#define SHADOW_AABB_TAG_GROUP_SIZE 64
|
||||
#define SHADOW_MAX_TILEMAP 4096
|
||||
#define SHADOW_MAX_TILE (SHADOW_MAX_TILEMAP * SHADOW_TILEDATA_PER_TILEMAP)
|
||||
#define SHADOW_MAX_PAGE 4096
|
||||
#define SHADOW_MAX_PAGE 8192
|
||||
#define SHADOW_BOUNDS_GROUP_SIZE 64
|
||||
#define SHADOW_CLIPMAP_GROUP_SIZE 64
|
||||
#define SHADOW_VIEW_MAX 64 /* Must match DRW_VIEW_MAX. */
|
||||
#define SHADOW_RENDER_MAP_SIZE (SHADOW_VIEW_MAX * SHADOW_TILEMAP_LOD0_LEN)
|
||||
#define SHADOW_ATOMIC 1
|
||||
#define SHADOW_PAGE_PER_ROW 4
|
||||
#define SHADOW_PAGE_PER_COL 4
|
||||
#define SHADOW_PAGE_PER_ROW 8
|
||||
#define SHADOW_PAGE_PER_COL 8
|
||||
#define SHADOW_PAGE_MAX_LAYER 128
|
||||
#define SHADOW_PAGE_PER_LAYER (SHADOW_PAGE_PER_ROW * SHADOW_PAGE_PER_COL)
|
||||
#define SHADOW_MAX_STEP 16
|
||||
#define SHADOW_MAX_RAY 4
|
||||
|
|
|
|||
|
|
@ -601,12 +601,13 @@ void ShadowModule::init()
|
|||
}
|
||||
|
||||
/* Pool size is in MBytes. */
|
||||
const size_t pool_byte_size = enabled_ ? scene.eevee.shadow_pool_size * square_i(1024) : 1;
|
||||
const size_t pool_byte_size = enabled_ ? size_t(scene.eevee.shadow_pool_size) * square_i(1024) :
|
||||
1;
|
||||
const size_t page_byte_size = square_i(shadow_page_size_) * sizeof(int);
|
||||
shadow_page_len_ = int(divide_ceil_ul(pool_byte_size, page_byte_size));
|
||||
shadow_page_len_ = min_ii(shadow_page_len_, SHADOW_MAX_PAGE);
|
||||
|
||||
const int2 atlas_extent = shadow_page_size_ * int2(SHADOW_PAGE_PER_ROW);
|
||||
const int2 atlas_extent = shadow_page_size_ * int2(SHADOW_PAGE_PER_ROW, SHADOW_PAGE_PER_COL);
|
||||
const int atlas_layers = divide_ceil_u(shadow_page_len_, SHADOW_PAGE_PER_LAYER);
|
||||
|
||||
eGPUTextureUsage tex_usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_SHADER_WRITE |
|
||||
|
|
|
|||
|
|
@ -205,22 +205,26 @@ enum [[host_shared]] eShadowFlag : uint32_t {
|
|||
SHADOW_TAG_UPDATE = (1u << 31u)
|
||||
};
|
||||
|
||||
/* NOTE: Trust the input to be in valid range (max is [3,3,255]).
|
||||
* If it is in valid range, it should pack to 12bits so that `shadow_tile_pack()` can use it.
|
||||
/* NOTE: Trust the input to be in valid range (max is [7,7,127]).
|
||||
* If it is in valid range, it should pack to 14bits so that `shadow_tile_pack()` can use it.
|
||||
* But sometime this is used to encode invalid pages uint3(-1) and it needs to output uint(-1).
|
||||
*/
|
||||
static inline uint shadow_page_pack(uint3 page)
|
||||
{
|
||||
return (page.x << 0u) | (page.y << 2u) | (page.z << 4u);
|
||||
return (page.x << 0u) | (page.y << 3u) | (page.z << 6u);
|
||||
}
|
||||
static inline uint3 shadow_page_unpack(uint data)
|
||||
{
|
||||
uint3 page;
|
||||
BLI_STATIC_ASSERT(SHADOW_PAGE_PER_ROW <= 4 && SHADOW_PAGE_PER_COL <= 4, "Update page packing")
|
||||
page.x = (data >> 0u) & 3u;
|
||||
page.y = (data >> 2u) & 3u;
|
||||
BLI_STATIC_ASSERT(SHADOW_MAX_PAGE <= 4096, "Update page packing")
|
||||
page.z = (data >> 4u) & 255u;
|
||||
BLI_STATIC_ASSERT(SHADOW_PAGE_PER_ROW <= 8 && SHADOW_PAGE_PER_COL <= 8 &&
|
||||
SHADOW_PAGE_MAX_LAYER <= 128,
|
||||
"Update page packing")
|
||||
page.x = (data >> 0u) & 7u;
|
||||
page.y = (data >> 3u) & 7u;
|
||||
page.z = (data >> 6u) & 127u;
|
||||
BLI_STATIC_ASSERT(SHADOW_MAX_PAGE ==
|
||||
(SHADOW_PAGE_PER_ROW * SHADOW_PAGE_PER_COL * SHADOW_PAGE_MAX_LAYER),
|
||||
"Update page packing")
|
||||
return page;
|
||||
}
|
||||
|
||||
|
|
@ -228,11 +232,11 @@ static inline ShadowTileData shadow_tile_unpack(ShadowTileDataPacked data)
|
|||
{
|
||||
ShadowTileData tile;
|
||||
tile.page = shadow_page_unpack(data);
|
||||
/* -- 12 bits -- */
|
||||
/* -- 13 bits -- */
|
||||
/* Unused bits. */
|
||||
/* -- 15 bits -- */
|
||||
BLI_STATIC_ASSERT(SHADOW_MAX_PAGE <= 4096, "Update page packing")
|
||||
tile.cache_index = (data >> 15u) & 4095u;
|
||||
/* -- 14 bits -- */
|
||||
BLI_STATIC_ASSERT(SHADOW_MAX_PAGE <= 8192, "Update page packing")
|
||||
tile.cache_index = (data >> 14u) & 8191u;
|
||||
/* -- 27 bits -- */
|
||||
tile.is_used = (data & SHADOW_IS_USED) != 0;
|
||||
tile.is_cached = (data & SHADOW_IS_CACHED) != 0;
|
||||
|
|
@ -248,7 +252,8 @@ static inline ShadowTileDataPacked shadow_tile_pack(ShadowTileData tile)
|
|||
/* NOTE: Page might be set to invalid values for tracking invalid usages.
|
||||
* So we have to mask the result. */
|
||||
data = shadow_page_pack(tile.page) & uint(SHADOW_MAX_PAGE - 1);
|
||||
data |= (tile.cache_index & 4095u) << 15u;
|
||||
BLI_STATIC_ASSERT(SHADOW_MAX_PAGE <= 8192, "Update page packing")
|
||||
data |= (tile.cache_index & 8191u) << 14u;
|
||||
data |= (tile.is_used ? uint(SHADOW_IS_USED) : 0);
|
||||
data |= (tile.is_allocated ? uint(SHADOW_IS_ALLOCATED) : 0);
|
||||
data |= (tile.is_cached ? uint(SHADOW_IS_CACHED) : 0);
|
||||
|
|
@ -294,9 +299,10 @@ static inline ShadowSamplingTile shadow_sampling_tile_unpack(ShadowSamplingTileP
|
|||
{
|
||||
ShadowSamplingTile tile;
|
||||
tile.page = shadow_page_unpack(data);
|
||||
/* -- 12 bits -- */
|
||||
/* -- 13 bits -- */
|
||||
/* Max value is actually SHADOW_TILEMAP_MAX_CLIPMAP_LOD but we mask the bits. */
|
||||
tile.lod = (data >> 12u) & 15u;
|
||||
BLI_STATIC_ASSERT(SHADOW_TILEMAP_MAX_CLIPMAP_LOD <= 8u, "Update lod packing")
|
||||
tile.lod = (data >> 13u) & 7u;
|
||||
/* -- 16 bits -- */
|
||||
tile.lod_offset = shadow_lod_offset_unpack(data >> 16u);
|
||||
/* -- 32 bits -- */
|
||||
|
|
@ -322,8 +328,10 @@ static inline ShadowSamplingTilePacked shadow_sampling_tile_pack(ShadowSamplingT
|
|||
tile.lod_offset.x = 1;
|
||||
}
|
||||
uint data = shadow_page_pack(tile.page);
|
||||
BLI_STATIC_ASSERT(SHADOW_MAX_PAGE <= 8192, "Update page packing")
|
||||
/* Max value is actually SHADOW_TILEMAP_MAX_CLIPMAP_LOD but we mask the bits. */
|
||||
data |= (tile.lod & 15u) << 12u;
|
||||
BLI_STATIC_ASSERT(SHADOW_TILEMAP_MAX_CLIPMAP_LOD <= 8u, "Update lod packing")
|
||||
data |= (tile.lod & 7u) << 13u;
|
||||
data |= shadow_lod_offset_pack(tile.lod_offset) << 16u;
|
||||
return data;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -813,27 +813,27 @@ static void test_eevee_shadow_finalize()
|
|||
tile.do_update = true;
|
||||
tiles_data[lod2_ofs] = shadow_tile_pack(tile);
|
||||
|
||||
tile.page = uint3(0, 1, 0);
|
||||
tile.page = uint3(4, 0, 0);
|
||||
tile.do_update = true;
|
||||
tiles_data[lod3_ofs] = shadow_tile_pack(tile);
|
||||
|
||||
tile.page = uint3(1, 1, 0);
|
||||
tile.page = uint3(5, 0, 0);
|
||||
tile.do_update = true;
|
||||
tiles_data[lod4_ofs] = shadow_tile_pack(tile);
|
||||
|
||||
tile.page = uint3(2, 1, 0);
|
||||
tile.page = uint3(6, 0, 0);
|
||||
tile.do_update = true;
|
||||
tiles_data[lod5_ofs] = shadow_tile_pack(tile);
|
||||
|
||||
tile.page = uint3(3, 1, 0);
|
||||
tile.page = uint3(7, 0, 0);
|
||||
tile.do_update = true;
|
||||
tiles_data[lod0_ofs + 31] = shadow_tile_pack(tile);
|
||||
|
||||
tile.page = uint3(0, 2, 0);
|
||||
tile.page = uint3(0, 1, 0);
|
||||
tile.do_update = true;
|
||||
tiles_data[lod3_ofs + 8] = shadow_tile_pack(tile);
|
||||
|
||||
tile.page = uint3(1, 2, 0);
|
||||
tile.page = uint3(1, 1, 0);
|
||||
tile.do_update = true;
|
||||
tiles_data[lod0_ofs + 32 * 16 - 8] = shadow_tile_pack(tile);
|
||||
|
||||
|
|
|
|||
|
|
@ -8216,6 +8216,19 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
|
|||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem eevee_shadow_pool_size_items[] = {
|
||||
{16, "16", 0, "16 MB", ""},
|
||||
{32, "32", 0, "32 MB", ""},
|
||||
{64, "64", 0, "64 MB", ""},
|
||||
{128, "128", 0, "128 MB", ""},
|
||||
{256, "256", 0, "256 MB", ""},
|
||||
{512, "512", 0, "512 MB", ""},
|
||||
{1024, "1024", 0, "1 GB", ""},
|
||||
{1536, "1536", 0, "1.5 GB", ""},
|
||||
{2048, "2048", 0, "2 GB", ""},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem eevee_gi_visibility_size_items[] = {
|
||||
{8, "8", 0, "8 px", ""},
|
||||
{16, "16", 0, "16 px", ""},
|
||||
|
|
@ -8630,7 +8643,7 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
|
|||
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, nullptr);
|
||||
|
||||
prop = RNA_def_property(srna, "shadow_pool_size", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, eevee_pool_size_items);
|
||||
RNA_def_property_enum_items(prop, eevee_shadow_pool_size_items);
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Shadow Pool Size",
|
||||
"Size of the shadow pool, "
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue