Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/intern/scene.c8
-rw-r--r--source/blender/blenloader/intern/readfile.c19
-rw-r--r--source/blender/blenloader/intern/writefile.c6
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc4
-rw-r--r--source/blender/draw/CMakeLists.txt1
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightcache.c152
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightcache.h2
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightprobes.c61
-rw-r--r--source/blender/draw/engines/eevee/eevee_lookdev.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c3
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h17
-rw-r--r--source/blender/draw/engines/eevee/eevee_screen_raytrace.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_shaders.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_subsurface.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_volumes.c2
-rw-r--r--source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl130
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl3
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl22
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl9
-rw-r--r--source/blender/draw/engines/eevee/shaders/octahedron_lib.glsl18
-rw-r--r--source/blender/draw/intern/DRW_render.h2
-rw-r--r--source/blender/draw/intern/draw_manager_texture.c9
-rw-r--r--source/blender/editors/render/render_shading.c14
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c2
-rw-r--r--source/blender/gpu/GPU_extensions.h1
-rw-r--r--source/blender/gpu/GPU_texture.h10
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c8
-rw-r--r--source/blender/gpu/intern/gpu_shader.c6
-rw-r--r--source/blender/gpu/intern/gpu_texture.c217
-rw-r--r--source/blender/makesdna/DNA_lightprobe_types.h12
-rw-r--r--source/blender/makesdna/DNA_scene_defaults.h2
-rw-r--r--source/blender/makesdna/DNA_scene_types.h3
32 files changed, 480 insertions, 273 deletions
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 027933e17c6..6ca14ec9197 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -395,9 +395,9 @@ static void scene_free_data(ID *id)
scene->master_collection = NULL;
}
- if (scene->eevee.light_cache) {
- EEVEE_lightcache_free(scene->eevee.light_cache);
- scene->eevee.light_cache = NULL;
+ if (scene->eevee.light_cache_data) {
+ EEVEE_lightcache_free(scene->eevee.light_cache_data);
+ scene->eevee.light_cache_data = NULL;
}
if (scene->display.shading.prop) {
@@ -583,7 +583,7 @@ void BKE_scene_copy_data_eevee(Scene *sce_dst, const Scene *sce_src)
{
/* Copy eevee data between scenes. */
sce_dst->eevee = sce_src->eevee;
- sce_dst->eevee.light_cache = NULL;
+ sce_dst->eevee.light_cache_data = NULL;
sce_dst->eevee.light_cache_info[0] = '\0';
/* TODO Copy the cache. */
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index f73dc9a5466..49b51c34562 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -157,6 +157,8 @@
#include "RE_engine.h"
+#include "engines/eevee/eevee_lightcache.h"
+
#include "readfile.h"
#include <errno.h>
@@ -1852,8 +1854,8 @@ void blo_make_scene_pointer_map(FileData *fd, Main *oldmain)
fd->scenemap = oldnewmap_new();
for (; sce; sce = sce->id.next) {
- if (sce->eevee.light_cache) {
- struct LightCache *light_cache = sce->eevee.light_cache;
+ if (sce->eevee.light_cache_data) {
+ struct LightCache *light_cache = sce->eevee.light_cache_data;
oldnewmap_insert(fd->scenemap, light_cache, light_cache, 0);
}
}
@@ -1873,7 +1875,7 @@ void blo_end_scene_pointer_map(FileData *fd, Main *oldmain)
}
for (; sce; sce = sce->id.next) {
- sce->eevee.light_cache = newsceadr(fd, sce->eevee.light_cache);
+ sce->eevee.light_cache_data = newsceadr(fd, sce->eevee.light_cache_data);
}
}
@@ -6927,19 +6929,20 @@ static void direct_link_scene(FileData *fd, Scene *sce)
if (fd->memfile) {
/* If it's undo try to recover the cache. */
if (fd->scenemap) {
- sce->eevee.light_cache = newsceadr(fd, sce->eevee.light_cache);
+ sce->eevee.light_cache_data = newsceadr(fd, sce->eevee.light_cache_data);
}
else {
- sce->eevee.light_cache = NULL;
+ sce->eevee.light_cache_data = NULL;
}
}
else {
/* else try to read the cache from file. */
- sce->eevee.light_cache = newdataadr(fd, sce->eevee.light_cache);
- if (sce->eevee.light_cache) {
- direct_link_lightcache(fd, sce->eevee.light_cache);
+ sce->eevee.light_cache_data = newdataadr(fd, sce->eevee.light_cache_data);
+ if (sce->eevee.light_cache_data) {
+ direct_link_lightcache(fd, sce->eevee.light_cache_data);
}
}
+ EEVEE_lightcache_info_update(&sce->eevee);
direct_link_view3dshading(fd, &sce->display.shading);
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 81df00ebdef..a9c5008062b 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -2767,9 +2767,9 @@ static void write_scene(WriteData *wd, Scene *sce)
}
/* Eevee Lightcache */
- if (sce->eevee.light_cache && !wd->use_memfile) {
- writestruct(wd, DATA, LightCache, 1, sce->eevee.light_cache);
- write_lightcache(wd, sce->eevee.light_cache);
+ if (sce->eevee.light_cache_data && !wd->use_memfile) {
+ writestruct(wd, DATA, LightCache, 1, sce->eevee.light_cache_data);
+ write_lightcache(wd, sce->eevee.light_cache_data);
}
write_view3dshading(wd, &sce->display.shading);
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
index 1841f5f024f..50870d1e4aa 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
@@ -804,7 +804,7 @@ void update_id_after_copy(const Depsgraph *depsgraph,
Scene *scene_cow = (Scene *)id_cow;
const Scene *scene_orig = (const Scene *)id_orig;
scene_cow->toolsettings = scene_orig->toolsettings;
- scene_cow->eevee.light_cache = scene_orig->eevee.light_cache;
+ scene_cow->eevee.light_cache_data = scene_orig->eevee.light_cache_data;
scene_setup_view_layers_after_remap(depsgraph, id_node, reinterpret_cast<Scene *>(id_cow));
update_scene_orig_pointers(scene_orig, scene_cow);
break;
@@ -1000,7 +1000,7 @@ void discard_scene_pointers(ID *id_cow)
{
Scene *scene_cow = (Scene *)id_cow;
scene_cow->toolsettings = nullptr;
- scene_cow->eevee.light_cache = nullptr;
+ scene_cow->eevee.light_cache_data = nullptr;
}
/* nullptr-ify all edit mode pointers which points to data from
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index fe03a32fd07..a1213be4be0 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -230,6 +230,7 @@ data_to_c_simple(engines/eevee/shaders/btdf_lut_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/bsdf_common_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/irradiance_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/octahedron_lib.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/cubemap_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/bsdf_sampling_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/raytrace_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/renderpass_postprocess_frag.glsl SRC)
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c
index 2b11a608bd0..ae4c7dec1e1 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.c
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.c
@@ -42,6 +42,7 @@
#include "eevee_private.h"
#include "GPU_context.h"
+#include "GPU_extensions.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -195,6 +196,16 @@ static uint eevee_lightcache_memsize_get(LightCache *lcache)
return size;
}
+static bool eevee_lightcache_version_check(LightCache *lcache)
+{
+ switch (lcache->type) {
+ case LIGHTCACHE_TYPE_STATIC:
+ return lcache->version == LIGHTCACHE_STATIC_VERSION;
+ default:
+ return false;
+ }
+}
+
static int eevee_lightcache_irradiance_sample_count(LightCache *lcache)
{
int total_irr_samples = 0;
@@ -208,9 +219,23 @@ static int eevee_lightcache_irradiance_sample_count(LightCache *lcache)
void EEVEE_lightcache_info_update(SceneEEVEE *eevee)
{
- LightCache *lcache = eevee->light_cache;
+ LightCache *lcache = eevee->light_cache_data;
if (lcache != NULL) {
+ if (!eevee_lightcache_version_check(lcache)) {
+ BLI_strncpy(eevee->light_cache_info,
+ TIP_("Incompatible Light cache version, please bake again"),
+ sizeof(eevee->light_cache_info));
+ return;
+ }
+
+ if (lcache->cube_tx.tex_size[2] > GPU_max_texture_layers()) {
+ BLI_strncpy(eevee->light_cache_info,
+ TIP_("Error: Light cache is too big for your GPU to be loaded"),
+ sizeof(eevee->light_cache_info));
+ return;
+ }
+
if (lcache->flag & LIGHTCACHE_BAKING) {
BLI_strncpy(
eevee->light_cache_info, TIP_("Baking light cache"), sizeof(eevee->light_cache_info));
@@ -266,8 +291,8 @@ static bool EEVEE_lightcache_validate(const LightCache *light_cache,
(irr_size[2] == light_cache->grid_tx.tex_size[2]) && (grid_len == light_cache->grid_len)) {
int mip_len = log2_floor_u(cube_res) - MIN_CUBE_LOD_LEVEL;
if ((cube_res == light_cache->cube_tx.tex_size[0]) &&
- (cube_len == light_cache->cube_tx.tex_size[2]) && (cube_len == light_cache->cube_len) &&
- (mip_len == light_cache->mips_len)) {
+ (cube_len == light_cache->cube_tx.tex_size[2] / 6) &&
+ (cube_len == light_cache->cube_len) && (mip_len == light_cache->mips_len)) {
return true;
}
}
@@ -283,6 +308,9 @@ LightCache *EEVEE_lightcache_create(const int grid_len,
{
LightCache *light_cache = MEM_callocN(sizeof(LightCache), "LightCache");
+ light_cache->version = LIGHTCACHE_STATIC_VERSION;
+ light_cache->type = LIGHTCACHE_TYPE_STATIC;
+
light_cache->cube_data = MEM_callocN(sizeof(EEVEE_LightProbe) * cube_len, "EEVEE_LightProbe");
light_cache->grid_data = MEM_callocN(sizeof(EEVEE_LightGrid) * grid_len, "EEVEE_LightGrid");
@@ -292,13 +320,26 @@ LightCache *EEVEE_lightcache_create(const int grid_len,
light_cache->grid_tx.tex_size[1] = irr_size[1];
light_cache->grid_tx.tex_size[2] = irr_size[2];
- light_cache->cube_tx.tex = DRW_texture_create_2d_array(
- cube_size, cube_size, cube_len, GPU_R11F_G11F_B10F, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
+ int mips_len = log2_floor_u(cube_size) - MIN_CUBE_LOD_LEVEL;
+
+ if (GPU_arb_texture_cube_map_array_is_supported()) {
+ light_cache->cube_tx.tex = DRW_texture_create_cube_array(
+ cube_size, cube_len, GPU_R11F_G11F_B10F, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
+ }
+ else {
+ light_cache->cube_tx.tex = DRW_texture_create_2d_array(cube_size,
+ cube_size,
+ cube_len * 6,
+ GPU_R11F_G11F_B10F,
+ DRW_TEX_FILTER | DRW_TEX_MIPMAP,
+ NULL);
+ }
+
light_cache->cube_tx.tex_size[0] = cube_size;
light_cache->cube_tx.tex_size[1] = cube_size;
- light_cache->cube_tx.tex_size[2] = cube_len;
+ light_cache->cube_tx.tex_size[2] = cube_len * 6;
- light_cache->mips_len = log2_floor_u(cube_size) - MIN_CUBE_LOD_LEVEL;
+ light_cache->mips_len = mips_len;
light_cache->vis_res = vis_size;
light_cache->ref_res = cube_size;
@@ -315,9 +356,19 @@ LightCache *EEVEE_lightcache_create(const int grid_len,
return light_cache;
}
-void EEVEE_lightcache_load(LightCache *lcache)
+static bool eevee_lightcache_static_load(LightCache *lcache)
{
- if (lcache->grid_tx.tex == NULL && lcache->grid_tx.data) {
+ /* We use fallback if a texture is not setup and there is no data to restore it. */
+ if ((!lcache->grid_tx.tex && !lcache->grid_tx.data) ||
+ (!lcache->cube_tx.tex && !lcache->cube_tx.data)) {
+ return false;
+ }
+ /* If cache is too big for this GPU. */
+ if (lcache->cube_tx.tex_size[2] > GPU_max_texture_layers()) {
+ return false;
+ }
+
+ if (lcache->grid_tx.tex == NULL) {
lcache->grid_tx.tex = GPU_texture_create_nD(lcache->grid_tx.tex_size[0],
lcache->grid_tx.tex_size[1],
lcache->grid_tx.tex_size[2],
@@ -333,17 +384,28 @@ void EEVEE_lightcache_load(LightCache *lcache)
GPU_texture_unbind(lcache->grid_tx.tex);
}
- if (lcache->cube_tx.tex == NULL && lcache->cube_tx.data) {
- lcache->cube_tx.tex = GPU_texture_create_nD(lcache->cube_tx.tex_size[0],
- lcache->cube_tx.tex_size[1],
- lcache->cube_tx.tex_size[2],
- 2,
- lcache->cube_tx.data,
- GPU_R11F_G11F_B10F,
- GPU_DATA_10_11_11_REV,
- 0,
- false,
- NULL);
+ if (lcache->cube_tx.tex == NULL) {
+ if (GPU_arb_texture_cube_map_array_is_supported()) {
+ lcache->cube_tx.tex = GPU_texture_cube_create(lcache->cube_tx.tex_size[0],
+ lcache->cube_tx.tex_size[2] / 6,
+ lcache->cube_tx.data,
+ GPU_R11F_G11F_B10F,
+ GPU_DATA_10_11_11_REV,
+ NULL);
+ }
+ else {
+ lcache->cube_tx.tex = GPU_texture_create_nD(lcache->cube_tx.tex_size[0],
+ lcache->cube_tx.tex_size[1],
+ lcache->cube_tx.tex_size[2],
+ 2,
+ lcache->cube_tx.data,
+ GPU_R11F_G11F_B10F,
+ GPU_DATA_10_11_11_REV,
+ 0,
+ false,
+ NULL);
+ }
+
GPU_texture_bind(lcache->cube_tx.tex, 0);
GPU_texture_mipmap_mode(lcache->cube_tx.tex, true, true);
for (int mip = 0; mip < lcache->mips_len; mip++) {
@@ -352,6 +414,25 @@ void EEVEE_lightcache_load(LightCache *lcache)
}
GPU_texture_unbind(lcache->cube_tx.tex);
}
+ return true;
+}
+
+bool EEVEE_lightcache_load(LightCache *lcache)
+{
+ if (lcache == NULL) {
+ return false;
+ }
+
+ if (!eevee_lightcache_version_check(lcache)) {
+ return false;
+ }
+
+ switch (lcache->type) {
+ case LIGHTCACHE_TYPE_STATIC:
+ return eevee_lightcache_static_load(lcache);
+ default:
+ return false;
+ }
}
static void eevee_lightbake_readback_irradiance(LightCache *lcache)
@@ -457,7 +538,7 @@ static void eevee_lightbake_count_probes(EEVEE_LightBake *lbake)
prb->grid_resolution_z;
lbake->grid_len++;
}
- else if (prb->type == LIGHTPROBE_TYPE_CUBE) {
+ else if (prb->type == LIGHTPROBE_TYPE_CUBE && lbake->cube_len < EEVEE_PROBE_MAX) {
lbake->cube_len++;
}
}
@@ -491,8 +572,7 @@ static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
irradiance_pool_size_get(lbake->vis_res, lbake->total_irr_samples, lbake->irr_size);
- lbake->ref_cube_res = octahedral_size_from_cubesize(lbake->rt_res);
-
+ lbake->ref_cube_res = lbake->rt_res;
lbake->cube_prb = MEM_callocN(sizeof(LightProbe *) * lbake->cube_len, "EEVEE Cube visgroup ptr");
lbake->grid_prb = MEM_callocN(sizeof(LightProbe *) * lbake->grid_len, "EEVEE Grid visgroup ptr");
@@ -506,12 +586,12 @@ static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
/* Ensure Light Cache is ready to accept new data. If not recreate one.
* WARNING: All the following must be threadsafe. It's currently protected
* by the DRW mutex. */
- lbake->lcache = eevee->light_cache;
+ lbake->lcache = eevee->light_cache_data;
/* TODO validate irradiance and reflection cache independently... */
if (!EEVEE_lightcache_validate(
lbake->lcache, lbake->cube_len, lbake->ref_cube_res, lbake->grid_len, lbake->irr_size)) {
- eevee->light_cache = lbake->lcache = NULL;
+ eevee->light_cache_data = lbake->lcache = NULL;
}
if (lbake->lcache == NULL) {
@@ -522,10 +602,10 @@ static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
lbake->lcache->vis_res = lbake->vis_res;
lbake->own_light_cache = true;
- eevee->light_cache = lbake->lcache;
+ eevee->light_cache_data = lbake->lcache;
}
- EEVEE_lightcache_load(eevee->light_cache);
+ EEVEE_lightcache_load(eevee->light_cache_data);
lbake->lcache->flag |= LIGHTCACHE_BAKING;
lbake->lcache->cube_len = 1;
@@ -804,7 +884,7 @@ static void eevee_lightbake_render_world_sample(void *ved, void *user_data)
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
EEVEE_LightBake *lbake = (EEVEE_LightBake *)user_data;
Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
- LightCache *lcache = scene_eval->eevee.light_cache;
+ LightCache *lcache = scene_eval->eevee.light_cache_data;
float clamp = scene_eval->eevee.gi_glossy_clamp;
float filter_quality = scene_eval->eevee.gi_filter_quality;
@@ -920,7 +1000,7 @@ static void eevee_lightbake_render_grid_sample(void *ved, void *user_data)
EEVEE_LightGrid *egrid = lbake->grid;
LightProbe *prb = *lbake->probe;
Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
- LightCache *lcache = scene_eval->eevee.light_cache;
+ LightCache *lcache = scene_eval->eevee.light_cache_data;
int grid_loc[3], sample_id, sample_offset, stride;
float pos[3];
const bool is_last_bounce_sample = ((egrid->offset + lbake->grid_sample) ==
@@ -1002,7 +1082,7 @@ static void eevee_lightbake_render_probe_sample(void *ved, void *user_data)
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
EEVEE_LightBake *lbake = (EEVEE_LightBake *)user_data;
Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
- LightCache *lcache = scene_eval->eevee.light_cache;
+ LightCache *lcache = scene_eval->eevee.light_cache_data;
EEVEE_LightProbe *eprobe = lbake->cube;
LightProbe *prb = *lbake->probe;
float clamp = scene_eval->eevee.gi_glossy_clamp;
@@ -1083,7 +1163,7 @@ static void eevee_lightbake_gather_probes(EEVEE_LightBake *lbake)
{
Depsgraph *depsgraph = lbake->depsgraph;
Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
- LightCache *lcache = scene_eval->eevee.light_cache;
+ LightCache *lcache = scene_eval->eevee.light_cache_data;
/* At least one for the world */
int grid_len = 1;
@@ -1106,7 +1186,7 @@ static void eevee_lightbake_gather_probes(EEVEE_LightBake *lbake)
EEVEE_LightGrid *egrid = &lcache->grid_data[grid_len++];
EEVEE_lightprobes_grid_data_from_object(ob, egrid, &total_irr_samples);
}
- else if (prb->type == LIGHTPROBE_TYPE_CUBE) {
+ else if (prb->type == LIGHTPROBE_TYPE_CUBE && cube_len < EEVEE_PROBE_MAX) {
lbake->cube_prb[cube_len] = prb;
EEVEE_LightProbe *eprobe = &lcache->cube_data[cube_len++];
EEVEE_lightprobes_cube_data_from_object(ob, eprobe);
@@ -1136,11 +1216,11 @@ void EEVEE_lightbake_update(void *custom_data)
Scene *scene_orig = lbake->scene;
/* If a new lightcache was created, free the old one and reference the new. */
- if (lbake->lcache && scene_orig->eevee.light_cache != lbake->lcache) {
- if (scene_orig->eevee.light_cache != NULL) {
- EEVEE_lightcache_free(scene_orig->eevee.light_cache);
+ if (lbake->lcache && scene_orig->eevee.light_cache_data != lbake->lcache) {
+ if (scene_orig->eevee.light_cache_data != NULL) {
+ EEVEE_lightcache_free(scene_orig->eevee.light_cache_data);
}
- scene_orig->eevee.light_cache = lbake->lcache;
+ scene_orig->eevee.light_cache_data = lbake->lcache;
lbake->own_light_cache = false;
}
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.h b/source/blender/draw/engines/eevee/eevee_lightcache.h
index ede2de13dce..0db36ce0c2e 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.h
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.h
@@ -60,7 +60,7 @@ struct LightCache *EEVEE_lightcache_create(const int grid_len,
const int vis_size,
const int irr_size[3]);
void EEVEE_lightcache_free(struct LightCache *lcache);
-void EEVEE_lightcache_load(struct LightCache *lcache);
+bool EEVEE_lightcache_load(struct LightCache *lcache);
void EEVEE_lightcache_info_update(struct SceneEEVEE *eevee);
#endif /* __EEVEE_LIGHTCACHE_H__ */
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index 4fbecfe3120..61ca2317572 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -37,6 +37,7 @@
#include "GPU_material.h"
#include "GPU_texture.h"
+#include "GPU_extensions.h"
#include "DEG_depsgraph_query.h"
@@ -171,32 +172,28 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
memset(stl->g_data->world_views, 0, sizeof(stl->g_data->world_views));
memset(stl->g_data->planar_views, 0, sizeof(stl->g_data->planar_views));
- /* Use fallback if we don't have gpu texture allocated an we cannot restore them. */
- bool use_fallback_lightcache = (scene_eval->eevee.light_cache == NULL) ||
- ((scene_eval->eevee.light_cache->grid_tx.tex == NULL) &&
- (scene_eval->eevee.light_cache->grid_tx.data == NULL)) ||
- ((scene_eval->eevee.light_cache->cube_tx.tex == NULL) &&
- (scene_eval->eevee.light_cache->cube_tx.data == NULL));
-
- if (use_fallback_lightcache && (sldata->fallback_lightcache == NULL)) {
+ if (EEVEE_lightcache_load(scene_eval->eevee.light_cache_data)) {
+ stl->g_data->light_cache = scene_eval->eevee.light_cache_data;
+ }
+ else {
+ if (!sldata->fallback_lightcache) {
#if defined(IRRADIANCE_SH_L2)
- int grid_res = 4;
+ int grid_res = 4;
#elif defined(IRRADIANCE_CUBEMAP)
- int grid_res = 8;
+ int grid_res = 8;
#elif defined(IRRADIANCE_HL2)
- int grid_res = 4;
+ int grid_res = 4;
#endif
- int cube_res = octahedral_size_from_cubesize(scene_eval->eevee.gi_cubemap_resolution);
- int vis_res = scene_eval->eevee.gi_visibility_resolution;
- sldata->fallback_lightcache = EEVEE_lightcache_create(
- 1, 1, cube_res, vis_res, (int[3]){grid_res, grid_res, 1});
+ sldata->fallback_lightcache = EEVEE_lightcache_create(
+ 1,
+ 1,
+ scene_eval->eevee.gi_cubemap_resolution,
+ scene_eval->eevee.gi_visibility_resolution,
+ (int[3]){grid_res, grid_res, 1});
+ }
+ stl->g_data->light_cache = sldata->fallback_lightcache;
}
- stl->g_data->light_cache = (use_fallback_lightcache) ? sldata->fallback_lightcache :
- scene_eval->eevee.light_cache;
-
- EEVEE_lightcache_load(stl->g_data->light_cache);
-
if (!sldata->probes) {
sldata->probes = MEM_callocN(sizeof(EEVEE_LightProbesInfo), "EEVEE_LightProbesInfo");
sldata->probe_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_LightProbe) * MAX_PROBE, NULL);
@@ -255,7 +252,7 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata,
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
- DRW_shgroup_call(grp, geom, NULL);
+ DRW_shgroup_call_instances(grp, NULL, geom, 6);
}
{
@@ -508,8 +505,8 @@ void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata
EEVEE_LightProbesInfo *pinfo = sldata->probes;
LightProbe *probe = (LightProbe *)ob->data;
- if ((probe->type == LIGHTPROBE_TYPE_CUBE && pinfo->num_cube >= MAX_PROBE) ||
- (probe->type == LIGHTPROBE_TYPE_GRID && pinfo->num_grid >= MAX_PROBE) ||
+ if ((probe->type == LIGHTPROBE_TYPE_CUBE && pinfo->num_cube >= EEVEE_PROBE_MAX) ||
+ (probe->type == LIGHTPROBE_TYPE_GRID && pinfo->num_grid >= EEVEE_PROBE_MAX) ||
(probe->type == LIGHTPROBE_TYPE_PLANAR && pinfo->num_planar >= MAX_PLANAR)) {
printf("Too many probes in the view !!!\n");
return;
@@ -762,7 +759,7 @@ void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ved
DRW_uniformbuffer_update(sldata->grid_ubo, &sldata->probes->grid_data);
/* For shading, save max level of the octahedron map */
- sldata->common_data.prb_lod_cube_max = (float)light_cache->mips_len - 1.0f;
+ sldata->common_data.prb_lod_cube_max = (float)light_cache->mips_len;
sldata->common_data.prb_lod_planar_max = (float)MAX_PLANAR_LOD_LEVEL;
sldata->common_data.prb_irradiance_vis_size = light_cache->vis_res;
sldata->common_data.prb_irradiance_smooth = square_f(scene_eval->eevee.gi_irradiance_smoothing);
@@ -785,15 +782,15 @@ void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ved
if (draw_ctx->scene->eevee.flag & SCE_EEVEE_GI_AUTOBAKE) {
Scene *scene_orig = DEG_get_input_scene(draw_ctx->depsgraph);
- if (scene_orig->eevee.light_cache != NULL) {
+ if (scene_orig->eevee.light_cache_data != NULL) {
if (pinfo->do_grid_update) {
- scene_orig->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_GRID;
+ scene_orig->eevee.light_cache_data->flag |= LIGHTCACHE_UPDATE_GRID;
}
- /* If we update grid we need to update the cube-maps too.
- * So always refresh cube-maps. */
- scene_orig->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_CUBE;
- /* Tag the light-cache to auto update. */
- scene_orig->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_AUTO;
+ /* If we update grid we need to update the cubemaps too.
+ * So always refresh cubemaps. */
+ scene_orig->eevee.light_cache_data->flag |= LIGHTCACHE_UPDATE_CUBE;
+ /* Tag the lightcache to auto update. */
+ scene_orig->eevee.light_cache_data->flag |= LIGHTCACHE_UPDATE_AUTO;
/* Use a notifier to trigger the operator after drawing. */
WM_event_add_notifier(draw_ctx->evil_C, NC_LIGHTPROBE, scene_orig);
}
@@ -1077,7 +1074,7 @@ void EEVEE_lightbake_filter_glossy(EEVEE_ViewLayerData *sldata,
pinfo->texel_size = 1.0f / (float)mipsize;
pinfo->padding_size = (i == maxlevel) ? 0 : (float)(1 << (maxlevel - i - 1));
pinfo->padding_size *= pinfo->texel_size;
- pinfo->layer = probe_idx;
+ pinfo->layer = probe_idx * 6;
pinfo->roughness = i / (float)maxlevel;
pinfo->roughness *= pinfo->roughness; /* Disney Roughness */
pinfo->roughness *= pinfo->roughness; /* Distribute Roughness accros lod more evenly */
diff --git a/source/blender/draw/engines/eevee/eevee_lookdev.c b/source/blender/draw/engines/eevee/eevee_lookdev.c
index 7be6fc2d030..0cbd3d9ac83 100644
--- a/source/blender/draw/engines/eevee/eevee_lookdev.c
+++ b/source/blender/draw/engines/eevee/eevee_lookdev.c
@@ -116,7 +116,7 @@ void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
EEVEE_shaders_background_studiolight_sh_get();
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
- int cube_res = octahedral_size_from_cubesize(scene_eval->eevee.gi_cubemap_resolution);
+ int cube_res = scene_eval->eevee.gi_cubemap_resolution;
/* If one of the component is missing we start from scratch. */
if ((stl->lookdev_grid_data == NULL) || (stl->lookdev_cube_data == NULL) ||
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 05127585e6c..19d674bfc9c 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -89,6 +89,7 @@ extern char datatoc_common_hair_lib_glsl[];
extern char datatoc_common_view_lib_glsl[];
extern char datatoc_irradiance_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
+extern char datatoc_cubemap_lib_glsl[];
extern char datatoc_lit_surface_frag_glsl[];
extern char datatoc_lit_surface_vert_glsl[];
extern char datatoc_raytrace_lib_glsl[];
@@ -618,6 +619,7 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
datatoc_raytrace_lib_glsl,
datatoc_ssr_lib_glsl,
datatoc_octahedron_lib_glsl,
+ datatoc_cubemap_lib_glsl,
datatoc_irradiance_lib_glsl,
datatoc_lightprobe_lib_glsl,
datatoc_ltc_lib_glsl,
@@ -641,6 +643,7 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
datatoc_bsdf_common_lib_glsl,
datatoc_ambient_occlusion_lib_glsl,
datatoc_octahedron_lib_glsl,
+ datatoc_cubemap_lib_glsl,
datatoc_irradiance_lib_glsl,
datatoc_lightprobe_lib_glsl,
datatoc_ltc_lib_glsl,
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 5ffea393e1f..d266b7793c4 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -78,6 +78,8 @@ extern struct DrawEngineType draw_engine_eevee_type;
SHADER_IRRADIANCE
/* clang-format on */
+#define EEVEE_PROBE_MAX min_ii(MAX_PROBE, GPU_max_texture_layers() / 6)
+
#define SWAP_DOUBLE_BUFFERS() \
{ \
if (effects->swap_double_buffer) { \
@@ -136,20 +138,7 @@ extern struct DrawEngineType draw_engine_eevee_type;
((v3d->shading.type == OB_RENDER) && \
((v3d->shading.flag & V3D_SHADING_SCENE_WORLD_RENDER) == 0))))
-#define MIN_CUBE_LOD_LEVEL 3
-
-BLI_INLINE int octahedral_size_from_cubesize(int cube_size)
-{
- int cube_pixel_count = square_i(cube_size) * 6;
- int octa_size = (int)ceilf(sqrtf(cube_pixel_count));
- int lod_count = log2_floor_u(octa_size) - MIN_CUBE_LOD_LEVEL;
- /* Find lowest lod size and grow back to avoid having non matching mipsizes that would
- * break trilinear interpolation. */
- octa_size /= 1 << lod_count;
- octa_size *= 1 << lod_count;
- return octa_size;
-}
-
+#define MIN_CUBE_LOD_LEVEL 1
#define MAX_PLANAR_LOD_LEVEL 9
/* All the renderpasses that use the GPUMaterial for accumulation */
diff --git a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
index d231edf1383..e875187bdbf 100644
--- a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
+++ b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
@@ -54,6 +54,7 @@ extern char datatoc_common_uniforms_lib_glsl[];
extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_bsdf_sampling_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
+extern char datatoc_cubemap_lib_glsl[];
extern char datatoc_effect_ssr_frag_glsl[];
extern char datatoc_lightprobe_lib_glsl[];
extern char datatoc_raytrace_lib_glsl[];
@@ -67,6 +68,7 @@ static struct GPUShader *eevee_effects_screen_raytrace_shader_get(int options)
datatoc_bsdf_sampling_lib_glsl,
datatoc_ambient_occlusion_lib_glsl,
datatoc_octahedron_lib_glsl,
+ datatoc_cubemap_lib_glsl,
datatoc_lightprobe_lib_glsl,
datatoc_raytrace_lib_glsl,
datatoc_effect_ssr_frag_glsl);
diff --git a/source/blender/draw/engines/eevee/eevee_shaders.c b/source/blender/draw/engines/eevee/eevee_shaders.c
index 2d91e4bb4bd..50b7c5c5f97 100644
--- a/source/blender/draw/engines/eevee/eevee_shaders.c
+++ b/source/blender/draw/engines/eevee/eevee_shaders.c
@@ -88,6 +88,7 @@ extern char datatoc_lightprobe_planar_downsample_vert_glsl[];
extern char datatoc_irradiance_lib_glsl[];
extern char datatoc_lightprobe_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
+extern char datatoc_cubemap_lib_glsl[];
/* Velocity Resolve */
extern char datatoc_effect_velocity_resolve_frag_glsl[];
@@ -196,6 +197,7 @@ GPUShader *EEVEE_shaders_background_studiolight_sh_get(void)
{
if (e_data.probe_background_studiolight_sh == NULL) {
char *frag_str = BLI_string_joinN(datatoc_octahedron_lib_glsl,
+ datatoc_cubemap_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_lightprobe_lib_glsl,
@@ -217,6 +219,7 @@ GPUShader *EEVEE_shaders_probe_cube_display_sh_get(void)
{
if (e_data.probe_cube_display_sh == NULL) {
char *shader_str = BLI_string_joinN(datatoc_octahedron_lib_glsl,
+ datatoc_cubemap_lib_glsl,
datatoc_common_view_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
@@ -238,6 +241,7 @@ GPUShader *EEVEE_shaders_probe_grid_display_sh_get(void)
{
if (e_data.probe_grid_display_sh == NULL) {
char *shader_str = BLI_string_joinN(datatoc_octahedron_lib_glsl,
+ datatoc_cubemap_lib_glsl,
datatoc_common_view_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c
index 98e799acb5e..bab89a8a87b 100644
--- a/source/blender/draw/engines/eevee/eevee_subsurface.c
+++ b/source/blender/draw/engines/eevee/eevee_subsurface.c
@@ -41,6 +41,7 @@ extern char datatoc_common_uniforms_lib_glsl[];
extern char datatoc_lights_lib_glsl[];
extern char datatoc_raytrace_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
+extern char datatoc_cubemap_lib_glsl[];
extern char datatoc_bsdf_sampling_lib_glsl[];
extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_effect_subsurface_frag_glsl[];
@@ -59,6 +60,7 @@ static void eevee_create_shader_subsurface(void)
datatoc_bsdf_sampling_lib_glsl,
datatoc_raytrace_lib_glsl,
datatoc_octahedron_lib_glsl,
+ datatoc_cubemap_lib_glsl,
datatoc_lights_lib_glsl,
datatoc_effect_translucency_frag_glsl);
diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c
index efe2ef5fc17..8c1c72a3c20 100644
--- a/source/blender/draw/engines/eevee/eevee_volumes.c
+++ b/source/blender/draw/engines/eevee/eevee_volumes.c
@@ -72,6 +72,7 @@ extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_common_uniforms_lib_glsl[];
extern char datatoc_common_view_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
+extern char datatoc_cubemap_lib_glsl[];
extern char datatoc_irradiance_lib_glsl[];
extern char datatoc_lights_lib_glsl[];
extern char datatoc_volumetric_accum_frag_glsl[];
@@ -99,6 +100,7 @@ static void eevee_create_shader_volumes(void)
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_octahedron_lib_glsl,
+ datatoc_cubemap_lib_glsl,
datatoc_irradiance_lib_glsl,
datatoc_lights_lib_glsl,
datatoc_volumetric_lib_glsl);
diff --git a/source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl b/source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl
new file mode 100644
index 00000000000..90272400915
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl
@@ -0,0 +1,130 @@
+
+#ifdef GPU_ARB_texture_cube_map_array
+
+# define textureLod_cubemapArray(tex, co, lod) textureLod(tex, co, lod)
+
+#else
+
+/* Fallback implementation for hardware not supporting cubemap arrays. */
+# define samplerCubeArray sampler2DArray
+
+float cubemap_face_index(vec3 P)
+{
+ vec3 aP = abs(P);
+ if (all(greaterThan(aP.xx, aP.yz))) {
+ return (P.x > 0.0) ? 0.0 : 1.0;
+ }
+ else if (all(greaterThan(aP.yy, aP.xz))) {
+ return (P.y > 0.0) ? 2.0 : 3.0;
+ }
+ else {
+ return (P.z > 0.0) ? 4.0 : 5.0;
+ }
+}
+
+vec2 cubemap_face_coord(vec3 P, float face)
+{
+ if (face < 2.0) {
+ return (P.zy / P.x) * vec2(-0.5, -sign(P.x) * 0.5) + 0.5;
+ }
+ else if (face < 4.0) {
+ return (P.xz / P.y) * vec2(sign(P.y) * 0.5, 0.5) + 0.5;
+ }
+ else {
+ return (P.xy / P.z) * vec2(0.5, -sign(P.z) * 0.5) + 0.5;
+ }
+}
+
+vec3 cubemap_adj_x(float face)
+{
+ bool y_axis = (face == 2.0 || face == 3.0);
+ return y_axis ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);
+}
+
+vec3 cubemap_adj_y(float face)
+{
+ bool x_axis = (face < 2.0);
+ return x_axis ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
+}
+
+vec3 cubemap_adj_xy(float face)
+{
+ if (face < 2.0) {
+ return vec3(0.0, 1.0, 1.0);
+ }
+ else if (face < 4.0) {
+ return vec3(1.0, 0.0, 1.0);
+ }
+ else {
+ return vec3(1.0, 1.0, 0.0);
+ }
+}
+
+vec4 cubemap_seamless(sampler2DArray tex, vec4 cubevec, float lod)
+{
+ /* Manual Cube map Layer indexing. */
+ float face = cubemap_face_index(cubevec.xyz);
+ vec2 uv = cubemap_face_coord(cubevec.xyz, face);
+ vec3 coord = vec3(uv, cubevec.w * 6.0 + face);
+
+ vec4 col = textureLod(tex, coord, lod);
+
+ float cube_size = float(textureSize(tex, int(lod)).x);
+
+ vec2 uv_border = (abs(uv - 0.5) + (0.5 / cube_size - 0.5)) * 2.0 * cube_size;
+ bvec2 border = greaterThan(uv_border, vec2(0.0));
+ if (all(border)) {
+ /* Corners case. */
+ vec3 cubevec_adj;
+ float face_adj;
+ /* Get the other face coords. */
+ cubevec_adj = cubevec.xyz * cubemap_adj_x(face);
+ face_adj = cubemap_face_index(cubevec_adj);
+ /* Still use the original cubevec to get the outer texels or the face. */
+ uv = cubemap_face_coord(cubevec.xyz, face_adj);
+ coord = vec3(uv, cubevec.w * 6.0 + face_adj);
+ vec4 col1 = textureLod(tex, coord, lod);
+
+ /* Get the 3rd face coords. */
+ cubevec_adj = cubevec.xyz * cubemap_adj_y(face);
+ face_adj = cubemap_face_index(cubevec_adj);
+ /* Still use the original cubevec to get the outer texels or the face. */
+ uv = cubemap_face_coord(cubevec.xyz, face_adj);
+ coord = vec3(uv, cubevec.w * 6.0 + face_adj);
+ vec4 col2 = textureLod(tex, coord, lod);
+
+ /* Mix all colors to get the corner color. */
+ vec4 col3 = (col + col1 + col2) / 3.0;
+
+ vec2 mix_fac = uv_border * 0.5;
+ return mix(mix(col, col2, mix_fac.x), mix(col1, col3, mix_fac.x), mix_fac.y);
+ }
+ else if (any(border)) {
+ /* Edges case. */
+ /* Get the other face coords. */
+ vec3 cubevec_adj = cubevec.xyz * cubemap_adj_xy(face);
+ face = cubemap_face_index(cubevec_adj);
+ /* Still use the original cubevec to get the outer texels or the face. */
+ uv = cubemap_face_coord(cubevec.xyz, face);
+ coord = vec3(uv, cubevec.w * 6.0 + face);
+
+ float mix_fac = max(uv_border.x, uv_border.y) * 0.5;
+ return mix(col, textureLod(tex, coord, lod), mix_fac);
+ }
+ else {
+ return col;
+ }
+}
+
+vec4 textureLod_cubemapArray(sampler2DArray tex, vec4 cubevec, float lod)
+{
+ float lod1 = floor(lod);
+ float lod2 = ceil(lod);
+
+ vec4 col_lod1 = cubemap_seamless(tex, cubevec, lod1);
+ vec4 col_lod2 = cubemap_seamless(tex, cubevec, lod2);
+
+ return mix(col_lod1, col_lod2, lod - lod1);
+}
+
+#endif
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl
index a852dd47872..96fe94fc41e 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl
@@ -15,6 +15,5 @@ void main()
vec3 view_nor = vec3(quadCoord, sqrt(max(0.0, 1.0 - dist_sqr)));
vec3 world_ref = mat3(ViewMatrixInverse) * reflect(vec3(0.0, 0.0, -1.0), view_nor);
- FragColor = vec4(textureLod_octahedron(probeCubes, vec4(world_ref, pid), 0.0, prbLodCubeMax).rgb,
- 1.0);
+ FragColor = vec4(textureLod_cubemapArray(probeCubes, vec4(world_ref, pid), 0.0).rgb, 1.0);
}
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl
index 06c31272ecd..00eb3c7e200 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl
@@ -33,29 +33,9 @@ vec3 octahedral_to_cubemap_proj(vec2 co)
void main()
{
- vec2 uvs = gl_FragCoord.xy * texelSize;
-
- /* Add a N pixel border to ensure filtering is correct
- * for N mipmap levels. */
- uvs = (uvs - paddingSize) / (1.0 - 2.0 * paddingSize);
-
- /* edge mirroring : only mirror if directly adjacent
- * (not diagonally adjacent) */
- vec2 m = abs(uvs - 0.5) + 0.5;
- vec2 f = floor(m);
- if (f.x - f.y != 0.0) {
- uvs = 1.0 - uvs;
- }
-
- /* clamp to [0-1] */
- uvs = fract(uvs);
-
- /* get cubemap vector */
- vec3 cubevec = octahedral_to_cubemap_proj(uvs);
-
vec3 N, T, B, V;
- vec3 R = normalize(cubevec);
+ vec3 R = normalize(worldPosition);
/* Isotropic assumption */
N = V = R;
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
index ab205b78274..6c6db88139b 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
@@ -1,7 +1,7 @@
/* ----------- Uniforms --------- */
uniform sampler2DArray probePlanars;
-uniform sampler2DArray probeCubes;
+uniform samplerCubeArray probeCubes;
/* ----------- Structures --------- */
@@ -172,15 +172,12 @@ vec3 probe_evaluate_cube(int pd_id, vec3 W, vec3 R, float roughness)
float fac = saturate(original_roughness * 2.0 - 1.0);
R = mix(intersection, R, fac * fac);
- return textureLod_octahedron(
- probeCubes, vec4(R, float(pd_id)), roughness * prbLodCubeMax, prbLodCubeMax)
- .rgb;
+ return textureLod_cubemapArray(probeCubes, vec4(R, float(pd_id)), roughness * prbLodCubeMax).rgb;
}
vec3 probe_evaluate_world_spec(vec3 R, float roughness)
{
- return textureLod_octahedron(probeCubes, vec4(R, 0.0), roughness * prbLodCubeMax, prbLodCubeMax)
- .rgb;
+ return textureLod_cubemapArray(probeCubes, vec4(R, 0.0), roughness * prbLodCubeMax).rgb;
}
vec3 probe_evaluate_planar(
diff --git a/source/blender/draw/engines/eevee/shaders/octahedron_lib.glsl b/source/blender/draw/engines/eevee/shaders/octahedron_lib.glsl
index bfb6bc890ec..e05cc2719fa 100644
--- a/source/blender/draw/engines/eevee/shaders/octahedron_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/octahedron_lib.glsl
@@ -18,21 +18,3 @@ vec2 mapping_octahedron(vec3 cubevec, vec2 texel_size)
return uvs;
}
-
-vec4 textureLod_octahedron(sampler2DArray tex, vec4 cubevec, float lod, float lod_max)
-{
- vec2 texelSize = 1.0 / vec2(textureSize(tex, int(lod_max)));
-
- vec2 uvs = mapping_octahedron(cubevec.xyz, texelSize);
-
- return textureLod(tex, vec3(uvs, cubevec.w), lod);
-}
-
-vec4 texture_octahedron(sampler2DArray tex, vec4 cubevec)
-{
- vec2 texelSize = 1.0 / vec2(textureSize(tex, 0));
-
- vec2 uvs = mapping_octahedron(cubevec.xyz, texelSize);
-
- return texture(tex, vec3(uvs, cubevec.w));
-}
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 5122b1ea1ac..6a6cdd8f51c 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -166,6 +166,8 @@ struct GPUTexture *DRW_texture_create_cube(int w,
eGPUTextureFormat format,
DRWTextureFlag flags,
const float *fpixels);
+struct GPUTexture *DRW_texture_create_cube_array(
+ int w, int d, eGPUTextureFormat format, DRWTextureFlag flags, const float *fpixels);
void DRW_texture_ensure_fullscreen_2d(struct GPUTexture **tex,
eGPUTextureFormat format,
diff --git a/source/blender/draw/intern/draw_manager_texture.c b/source/blender/draw/intern/draw_manager_texture.c
index c75299158a3..3f11fe9d11e 100644
--- a/source/blender/draw/intern/draw_manager_texture.c
+++ b/source/blender/draw/intern/draw_manager_texture.c
@@ -123,6 +123,15 @@ GPUTexture *DRW_texture_create_cube(int w,
return tex;
}
+GPUTexture *DRW_texture_create_cube_array(
+ int w, int d, eGPUTextureFormat format, DRWTextureFlag flags, const float *fpixels)
+{
+ GPUTexture *tex = GPU_texture_create_cube_array(w, d, format, fpixels, NULL);
+ drw_texture_set_parameters(tex, flags);
+
+ return tex;
+}
+
GPUTexture *DRW_texture_pool_query_2d(int w,
int h,
eGPUTextureFormat format,
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 94e210b7243..95d044554f1 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -890,14 +890,14 @@ enum {
static void light_cache_bake_tag_cache(Scene *scene, wmOperator *op)
{
- if (scene->eevee.light_cache != NULL) {
+ if (scene->eevee.light_cache_data != NULL) {
int subset = RNA_enum_get(op->ptr, "subset");
switch (subset) {
case LIGHTCACHE_SUBSET_ALL:
- scene->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_GRID | LIGHTCACHE_UPDATE_CUBE;
+ scene->eevee.light_cache_data->flag |= LIGHTCACHE_UPDATE_GRID | LIGHTCACHE_UPDATE_CUBE;
break;
case LIGHTCACHE_SUBSET_CUBE:
- scene->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_CUBE;
+ scene->eevee.light_cache_data->flag |= LIGHTCACHE_UPDATE_CUBE;
break;
case LIGHTCACHE_SUBSET_DIRTY:
/* Leave tag untouched. */
@@ -1046,7 +1046,7 @@ static bool light_cache_free_poll(bContext *C)
{
Scene *scene = CTX_data_scene(C);
- return scene->eevee.light_cache;
+ return scene->eevee.light_cache_data;
}
static int light_cache_free_exec(bContext *C, wmOperator *UNUSED(op))
@@ -1057,12 +1057,12 @@ static int light_cache_free_exec(bContext *C, wmOperator *UNUSED(op))
wmWindowManager *wm = CTX_wm_manager(C);
WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_LIGHT_BAKE);
- if (!scene->eevee.light_cache) {
+ if (!scene->eevee.light_cache_data) {
return OPERATOR_CANCELLED;
}
- EEVEE_lightcache_free(scene->eevee.light_cache);
- scene->eevee.light_cache = NULL;
+ EEVEE_lightcache_free(scene->eevee.light_cache_data);
+ scene->eevee.light_cache_data = NULL;
EEVEE_lightcache_info_update(&scene->eevee);
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 8c884783913..8ec7d5a166b 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -1422,7 +1422,7 @@ static void space_view3d_listener(wmWindow *UNUSED(win),
static void space_view3d_refresh(const bContext *C, ScrArea *UNUSED(sa))
{
Scene *scene = CTX_data_scene(C);
- LightCache *lcache = scene->eevee.light_cache;
+ LightCache *lcache = scene->eevee.light_cache_data;
if (lcache && (lcache->flag & LIGHTCACHE_UPDATE_AUTO) != 0) {
lcache->flag &= ~LIGHTCACHE_UPDATE_AUTO;
diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h
index 245f7f47510..4ffe4a53a52 100644
--- a/source/blender/gpu/GPU_extensions.h
+++ b/source/blender/gpu/GPU_extensions.h
@@ -44,6 +44,7 @@ int GPU_max_ubo_size(void);
float GPU_max_line_width(void);
void GPU_get_dfdy_factors(float fac[2]);
bool GPU_arb_base_instance_is_supported(void);
+bool GPU_arb_texture_cube_map_array_is_supported(void);
bool GPU_mip_render_workaround(void);
bool GPU_depth_blitting_workaround(void);
bool GPU_unused_fb_slot_workaround(void);
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index bd15030d135..892452a2738 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -162,6 +162,12 @@ GPUTexture *GPU_texture_create_nD(int w,
int samples,
const bool can_rescale,
char err_out[256]);
+GPUTexture *GPU_texture_cube_create(int w,
+ int d,
+ const void *pixels,
+ eGPUTextureFormat tex_format,
+ eGPUDataFormat gpu_data_format,
+ char err_out[256]);
GPUTexture *GPU_texture_create_1d(int w,
eGPUTextureFormat data_type,
@@ -185,6 +191,9 @@ GPUTexture *GPU_texture_create_cube(int w,
eGPUTextureFormat data_type,
const float *pixels,
char err_out[256]);
+GPUTexture *GPU_texture_create_cube_array(
+ int w, int d, eGPUTextureFormat data_type, const float *pixels, char err_out[256]);
+
GPUTexture *GPU_texture_create_from_vertbuf(struct GPUVertBuf *vert);
GPUTexture *GPU_texture_create_buffer(eGPUTextureFormat data_type, const uint buffer);
@@ -252,6 +261,7 @@ void GPU_texture_orig_size_set(GPUTexture *tex, int w, int h);
int GPU_texture_layers(const GPUTexture *tex);
eGPUTextureFormat GPU_texture_format(const GPUTexture *tex);
int GPU_texture_samples(const GPUTexture *tex);
+bool GPU_texture_array(const GPUTexture *tex);
bool GPU_texture_cube(const GPUTexture *tex);
bool GPU_texture_depth(const GPUTexture *tex);
bool GPU_texture_stencil(const GPUTexture *tex);
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index 5a2b74f3407..f497ed22bec 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -78,6 +78,8 @@ static struct GPUGlobal {
/* Some Intel drivers have limited support for `GLEW_ARB_base_instance` so in
* these cases it is best to indicate that it is not supported. See T67951 */
bool glew_arb_base_instance_is_supported;
+ /* Cubemap Array support. */
+ bool glew_arb_texture_cube_map_array_is_supported;
/* Some Intel drivers have issues with using mips as framebuffer targets if
* GL_TEXTURE_MAX_LEVEL is higher than the target mip.
* We need a workaround in this cases. */
@@ -197,6 +199,11 @@ bool GPU_arb_base_instance_is_supported(void)
return GG.glew_arb_base_instance_is_supported;
}
+bool GPU_arb_texture_cube_map_array_is_supported(void)
+{
+ return GG.glew_arb_texture_cube_map_array_is_supported;
+}
+
bool GPU_mip_render_workaround(void)
{
return GG.mip_render_workaround;
@@ -281,6 +288,7 @@ void gpu_extensions_init(void)
}
GG.glew_arb_base_instance_is_supported = GLEW_ARB_base_instance;
+ GG.glew_arb_texture_cube_map_array_is_supported = GLEW_ARB_texture_cube_map_array;
gpu_detect_mip_render_workaround();
if (G.debug & G_DEBUG_GPU_FORCE_WORKAROUNDS) {
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index c950a1daaa5..0993d69e14d 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -46,7 +46,7 @@
/* Adjust these constants as needed. */
#define MAX_DEFINE_LENGTH 256
-#define MAX_EXT_DEFINE_LENGTH 256
+#define MAX_EXT_DEFINE_LENGTH 512
/* Non-generated shaders */
extern char datatoc_gpu_shader_depth_only_frag_glsl[];
@@ -235,6 +235,10 @@ static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH])
if (GLEW_ARB_shader_draw_parameters) {
strcat(defines, "#extension GL_ARB_shader_draw_parameters : enable\n");
}
+ if (GPU_arb_texture_cube_map_array_is_supported()) {
+ strcat(defines, "#extension GL_ARB_texture_cube_map_array : enable\n");
+ strcat(defines, "#define GPU_ARB_texture_cube_map_array\n");
+ }
}
static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH])
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c
index 2fd3e618664..7b51b03096f 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.c
@@ -109,7 +109,7 @@ static uint gpu_texture_memory_footprint_compute(GPUTexture *tex)
return tex->bytesize * tex->w * tex->h * tex->d * samp;
case GL_TEXTURE_CUBE_MAP:
return tex->bytesize * 6 * tex->w * tex->h * samp;
- case GL_TEXTURE_CUBE_MAP_ARRAY:
+ case GL_TEXTURE_CUBE_MAP_ARRAY_ARB:
return tex->bytesize * 6 * tex->w * tex->h * tex->d * samp;
default:
return 0;
@@ -138,6 +138,7 @@ static const char *gl_enum_to_str(GLenum e)
#define ENUM_TO_STRING(e) [GL_##e] = STRINGIFY_ARG(e)
static const char *enum_strings[] = {
ENUM_TO_STRING(TEXTURE_CUBE_MAP),
+ ENUM_TO_STRING(TEXTURE_CUBE_MAP_ARRAY),
ENUM_TO_STRING(TEXTURE_2D),
ENUM_TO_STRING(TEXTURE_2D_ARRAY),
ENUM_TO_STRING(TEXTURE_1D),
@@ -202,6 +203,25 @@ static int gpu_get_component_count(eGPUTextureFormat format)
}
}
+static uint gpu_get_data_format_bytesize(int comp, eGPUDataFormat data_format)
+{
+ switch (data_format) {
+ case GPU_DATA_FLOAT:
+ return sizeof(float) * comp;
+ case GPU_DATA_INT:
+ case GPU_DATA_UNSIGNED_INT:
+ return sizeof(int) * comp;
+ case GPU_DATA_UNSIGNED_INT_24_8:
+ case GPU_DATA_10_11_11_REV:
+ return sizeof(int);
+ case GPU_DATA_UNSIGNED_BYTE:
+ return sizeof(char) * comp;
+ default:
+ BLI_assert(0);
+ return 0;
+ }
+}
+
/* Definitely not complete, edit according to the gl specification. */
static void gpu_validate_data_format(eGPUTextureFormat tex_format, eGPUDataFormat data_format)
{
@@ -679,6 +699,7 @@ GPUTexture *GPU_texture_create_nD(int w,
}
else {
tex->target_base = tex->target = GL_TEXTURE_2D_ARRAY;
+ tex->format_flag |= GPU_FORMAT_ARRAY;
}
}
else if (n == 1) {
@@ -687,6 +708,7 @@ GPUTexture *GPU_texture_create_nD(int w,
}
else {
tex->target_base = tex->target = GL_TEXTURE_1D_ARRAY;
+ tex->format_flag |= GPU_FORMAT_ARRAY;
}
}
else if (n == 3) {
@@ -839,17 +861,12 @@ GPUTexture *GPU_texture_create_nD(int w,
return tex;
}
-static GPUTexture *GPU_texture_cube_create(int w,
- int d,
- const float *fpixels_px,
- const float *fpixels_py,
- const float *fpixels_pz,
- const float *fpixels_nx,
- const float *fpixels_ny,
- const float *fpixels_nz,
- eGPUTextureFormat tex_format,
- eGPUDataFormat gpu_data_format,
- char err_out[256])
+GPUTexture *GPU_texture_cube_create(int w,
+ int d,
+ const void *pixels,
+ eGPUTextureFormat tex_format,
+ eGPUDataFormat gpu_data_format,
+ char err_out[256])
{
GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
tex->w = w;
@@ -867,8 +884,21 @@ static GPUTexture *GPU_texture_cube_create(int w,
tex->target_base = tex->target = GL_TEXTURE_CUBE_MAP;
}
else {
- BLI_assert(false && "Cubemap array Not implemented yet");
- // tex->target_base = tex->target = GL_TEXTURE_CUBE_MAP_ARRAY;
+ tex->target_base = tex->target = GL_TEXTURE_CUBE_MAP_ARRAY_ARB;
+ tex->format_flag |= GPU_FORMAT_ARRAY;
+
+ if (!GPU_arb_texture_cube_map_array_is_supported()) {
+ fprintf(stderr, "ERROR: Attempt to create a cubemap array without hardware support!\n");
+ BLI_assert(0);
+ GPU_texture_free(tex);
+ return NULL;
+ }
+
+ if (d > GPU_max_texture_layers() / 6) {
+ BLI_assert(0);
+ GPU_texture_free(tex);
+ return NULL;
+ }
}
GLenum internalformat = gpu_get_gl_internalformat(tex_format);
@@ -905,60 +935,42 @@ static GPUTexture *GPU_texture_cube_create(int w,
glBindTexture(tex->target, tex->bindcode);
/* Upload Texture */
- glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X,
- 0,
- internalformat,
- tex->w,
- tex->h,
- 0,
- data_format,
- data_type,
- fpixels_px);
- glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
- 0,
- internalformat,
- tex->w,
- tex->h,
- 0,
- data_format,
- data_type,
- fpixels_py);
- glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
- 0,
- internalformat,
- tex->w,
- tex->h,
- 0,
- data_format,
- data_type,
- fpixels_pz);
- glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
- 0,
- internalformat,
- tex->w,
- tex->h,
- 0,
- data_format,
- data_type,
- fpixels_nx);
- glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
- 0,
- internalformat,
- tex->w,
- tex->h,
- 0,
- data_format,
- data_type,
- fpixels_ny);
- glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
- 0,
- internalformat,
- tex->w,
- tex->h,
- 0,
- data_format,
- data_type,
- fpixels_nz);
+ if (d == 0) {
+ const char *pixels_px, *pixels_py, *pixels_pz, *pixels_nx, *pixels_ny, *pixels_nz;
+
+ if (pixels) {
+ size_t face_ofs = w * w * gpu_get_data_format_bytesize(tex->components, gpu_data_format);
+ pixels_px = (char *)pixels + 0 * face_ofs;
+ pixels_nx = (char *)pixels + 1 * face_ofs;
+ pixels_py = (char *)pixels + 2 * face_ofs;
+ pixels_ny = (char *)pixels + 3 * face_ofs;
+ pixels_pz = (char *)pixels + 4 * face_ofs;
+ pixels_nz = (char *)pixels + 5 * face_ofs;
+ }
+ else {
+ pixels_px = pixels_py = pixels_pz = pixels_nx = pixels_ny = pixels_nz = NULL;
+ }
+
+ GLuint face = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+ glTexImage2D(face++, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, pixels_px);
+ glTexImage2D(face++, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, pixels_nx);
+ glTexImage2D(face++, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, pixels_py);
+ glTexImage2D(face++, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, pixels_ny);
+ glTexImage2D(face++, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, pixels_pz);
+ glTexImage2D(face++, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, pixels_nz);
+ }
+ else {
+ glTexImage3D(tex->target,
+ 0,
+ internalformat,
+ tex->w,
+ tex->h,
+ tex->d * 6,
+ 0,
+ data_format,
+ data_type,
+ pixels);
+ }
/* Texture Parameters */
if (GPU_texture_stencil(tex) || /* Does not support filtering */
@@ -1131,33 +1143,16 @@ GPUTexture *GPU_texture_create_cube(int w,
char err_out[256])
{
BLI_assert(w > 0);
- const float *fpixels_px, *fpixels_py, *fpixels_pz, *fpixels_nx, *fpixels_ny, *fpixels_nz;
- const int channels = gpu_get_component_count(tex_format);
-
- if (fpixels) {
- int face_ofs = w * w * channels;
- fpixels_px = fpixels + 0 * face_ofs;
- fpixels_nx = fpixels + 1 * face_ofs;
- fpixels_py = fpixels + 2 * face_ofs;
- fpixels_ny = fpixels + 3 * face_ofs;
- fpixels_pz = fpixels + 4 * face_ofs;
- fpixels_nz = fpixels + 5 * face_ofs;
- }
- else {
- fpixels_px = fpixels_py = fpixels_pz = fpixels_nx = fpixels_ny = fpixels_nz = NULL;
- }
+ eGPUDataFormat data_format = gpu_get_data_format_from_tex_format(tex_format);
+ return GPU_texture_cube_create(w, 0, fpixels, tex_format, data_format, err_out);
+}
- return GPU_texture_cube_create(w,
- 0,
- fpixels_px,
- fpixels_py,
- fpixels_pz,
- fpixels_nx,
- fpixels_ny,
- fpixels_nz,
- tex_format,
- GPU_DATA_FLOAT,
- err_out);
+GPUTexture *GPU_texture_create_cube_array(
+ int w, int d, eGPUTextureFormat tex_format, const float *fpixels, char err_out[256])
+{
+ BLI_assert(w > 0 && d > 0);
+ eGPUDataFormat data_format = gpu_get_data_format_from_tex_format(tex_format);
+ return GPU_texture_cube_create(w, d, fpixels, tex_format, data_format, err_out);
}
GPUTexture *GPU_texture_create_from_vertbuf(GPUVertBuf *vert)
@@ -1297,6 +1292,7 @@ void GPU_texture_add_mipmap(GPUTexture *tex,
break;
case GL_TEXTURE_3D:
case GL_TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_CUBE_MAP_ARRAY_ARB:
glTexImage3D(tex->target,
miplvl,
internalformat,
@@ -1385,29 +1381,13 @@ void *GPU_texture_read(GPUTexture *tex, eGPUDataFormat gpu_data_format, int mipl
gpu_validate_data_format(tex->format, gpu_data_format);
- size_t buf_size = gpu_texture_memory_footprint_compute(tex);
size_t samples_count = max_ii(1, tex->samples);
-
samples_count *= size[0];
samples_count *= max_ii(1, size[1]);
samples_count *= max_ii(1, size[2]);
- samples_count *= (GPU_texture_cube(tex)) ? 6 : 1;
+ samples_count *= (GPU_texture_cube(tex) && !GPU_texture_array(tex)) ? 6 : 1;
- switch (gpu_data_format) {
- case GPU_DATA_FLOAT:
- buf_size = sizeof(float) * samples_count * tex->components;
- break;
- case GPU_DATA_INT:
- case GPU_DATA_UNSIGNED_INT:
- buf_size = sizeof(int) * samples_count * tex->components;
- break;
- case GPU_DATA_UNSIGNED_INT_24_8:
- case GPU_DATA_10_11_11_REV:
- buf_size = sizeof(int) * samples_count;
- break;
- case GPU_DATA_UNSIGNED_BYTE:
- break;
- }
+ size_t buf_size = samples_count * gpu_get_data_format_bytesize(tex->components, gpu_data_format);
/* AMD Pro driver have a bug that write 8 bytes past buffer size
* if the texture is big. (see T66573) */
@@ -1418,7 +1398,7 @@ void *GPU_texture_read(GPUTexture *tex, eGPUDataFormat gpu_data_format, int mipl
glBindTexture(tex->target, tex->bindcode);
- if (GPU_texture_cube(tex)) {
+ if (GPU_texture_cube(tex) && !GPU_texture_array(tex)) {
int cube_face_size = buf_size / 6;
for (int i = 0; i < 6; i++) {
glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
@@ -1763,6 +1743,11 @@ int GPU_texture_samples(const GPUTexture *tex)
return tex->samples;
}
+bool GPU_texture_array(const GPUTexture *tex)
+{
+ return (tex->format_flag & GPU_FORMAT_ARRAY) != 0;
+}
+
bool GPU_texture_depth(const GPUTexture *tex)
{
return (tex->format_flag & GPU_FORMAT_DEPTH) != 0;
@@ -1828,8 +1813,12 @@ void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *size)
size[1] = max_ii(1, tex->h / div);
}
- if (tex->target == GL_TEXTURE_2D_ARRAY) {
+ if (GPU_texture_array(tex)) {
size[2] = tex->d;
+ /* Return the number of face layers. */
+ if (GPU_texture_cube(tex)) {
+ size[2] *= 6;
+ }
}
else if (tex->d > 0) {
size[2] = max_ii(1, tex->d / div);
diff --git a/source/blender/makesdna/DNA_lightprobe_types.h b/source/blender/makesdna/DNA_lightprobe_types.h
index 6ffdd60a094..d9cc549229d 100644
--- a/source/blender/makesdna/DNA_lightprobe_types.h
+++ b/source/blender/makesdna/DNA_lightprobe_types.h
@@ -160,6 +160,10 @@ typedef struct LightCacheTexture {
typedef struct LightCache {
int flag;
+ /** Version number to know if the cache data is compatible with this version of blender. */
+ int version;
+ /** Type of data this cache contains. */
+ int type;
/* only a single cache for now */
/** Number of probes to use for rendering. */
int cube_len, grid_len;
@@ -181,6 +185,14 @@ typedef struct LightCache {
LightGridCache *grid_data;
} LightCache;
+/* Bump the version number for lightcache data structure changes. */
+#define LIGHTCACHE_STATIC_VERSION 1
+
+/* LightCache->type */
+enum {
+ LIGHTCACHE_TYPE_STATIC = 0,
+};
+
/* LightCache->flag */
enum {
LIGHTCACHE_BAKED = (1 << 0),
diff --git a/source/blender/makesdna/DNA_scene_defaults.h b/source/blender/makesdna/DNA_scene_defaults.h
index db3566710b4..4b6f079aa28 100644
--- a/source/blender/makesdna/DNA_scene_defaults.h
+++ b/source/blender/makesdna/DNA_scene_defaults.h
@@ -224,7 +224,7 @@
.shadow_cube_size = 512, \
.shadow_cascade_size = 1024, \
\
- .light_cache = NULL, \
+ .light_cache_data = NULL, \
.light_threshold = 0.01f, \
\
.overscan = 3.0f, \
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 5759b237f83..aac976fbabd 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -1633,7 +1633,8 @@ typedef struct SceneEEVEE {
int shadow_cube_size;
int shadow_cascade_size;
- struct LightCache *light_cache;
+ struct LightCache *light_cache DNA_DEPRECATED;
+ struct LightCache *light_cache_data;
char light_cache_info[64];
float overscan;