1
1

Compare commits

...

76 Commits

Author SHA1 Message Date
05517c9bed Merge remote-tracking branch 'origin/blender2.8' into temp-eeveelightcache
# Conflicts:
#	source/blender/draw/engines/eevee/eevee_lightprobes.c
2018-07-09 23:03:21 +02:00
ff11750ee9 GPUTexture: Fix GPU_texture_read for depth stencil format 2018-07-09 22:33:29 +02:00
abbd997193 Eevee: LightCache: Use render visibility to select the probe
If a probe is not visible during render, it will not be selected to be
baked into the lightcache.
2018-07-09 22:29:45 +02:00
0f13e53669 Eevee: LightCache: Fix cache validation. 2018-07-09 22:26:48 +02:00
6100c236fb Eevee: LightCache: Fix wrong mipmap size 2018-07-09 22:23:34 +02:00
0bbccd3741 Eevee: LightCache: Fix problem caused by probe sorting 2018-07-09 22:22:37 +02:00
deaa90b5a5 Eevee: LightCache: Add Light Cache infos in the UI
This is still a bit basic but will be enhance in the future.
2018-07-09 17:08:05 +02:00
a21742a07b Eevee: LightCache: Small fixes and cleanups 2018-07-09 15:48:12 +02:00
65ac6e214d Eevee: LightProbe: UI tweaks 2018-07-09 15:47:30 +02:00
0b9350bb51 Eevee: LightCache: Add free operator. 2018-07-09 15:46:57 +02:00
7bb7c3e5cb GPUTexture: Fix mipmap size calculation. 2018-07-09 15:34:01 +02:00
49099c9048 Eevee: LightCache: Add cubemap only baking button. 2018-07-09 15:33:23 +02:00
1f51b0212f Eevee: LightCache: Add Autobake property
This also add partial probe update per type (only update cubemap if needed)
but it seems to be broken by some double update tagging in the depsgraph.
2018-07-08 09:28:58 +02:00
6d0d237be3 Eevee: LightCache: Add auto update when lightprobe are being modified
One draw back is that there is a significant overhead caused by creating
the batches for the new depsgraph. Caching the depsgraph between subsequent
update is not possible right now because we cannot update it. This is to be
adressed in the future.

There is no option to disable auto update right now.
2018-07-07 12:58:46 +02:00
5402529deb DEG: Fix drawdata type usage 2018-07-06 15:17:58 +02:00
7538716d57 Merge remote-tracking branch 'origin/blender2.8' into temp-eeveelightcache 2018-07-06 14:50:54 +02:00
656739067f Merge remote-tracking branch 'origin/blender2.8' into temp-eeveelightcache 2018-07-05 00:16:21 +02:00
74a17505fd Eevee: LightCache: Sort probes by size
This makes the probes more intuitive to use.

Most of the time, large probes englobe
smaller ones. If they are not sorted, the smaller ones will be occluded
by larger ones influence.
2018-07-05 00:15:42 +02:00
cc6fd329e6 Eevee: LightCache: Fix compilation error. 2018-07-04 18:42:41 +02:00
b1bc3dfb89 GPUTexture: Support GL_R11FG11FB10F textures w/ GPU_DATA_FLOAT data
This was needed for matcaps.
2018-07-04 18:42:23 +02:00
da71d831c3 Merge remote-tracking branch 'origin/blender2.8' into temp-eeveelightcache
# Conflicts:
#	source/blender/draw/engines/eevee/eevee_lightprobes.c
2018-07-04 16:01:28 +02:00
ed7b8e847f Merge remote-tracking branch 'origin/blender2.8' into temp-eeveelightcache
# Conflicts:
#	source/blender/gpu/GPU_texture.h
#	source/blender/gpu/intern/gpu_texture.c
2018-06-28 15:54:48 +02:00
60e2e1058d Eevee: LightCache: Write LightCache to File
This patch does a few things for it to work.
- It port some eevee's struct to DNA for them to be saved in the file.
- Readback the result of the lightcache baking and store it in the scene
  struct.

For small scenes, it's okayish to keep the data around in memory but a
better approach would be to save it to disk.

A standard reflection probe is more than 6 MB of data.
Diffuse irradiance grids are relatively small compared to this.
2018-06-28 15:53:01 +02:00
ce6cc756c3 GPUTexture: Refactor to have more flexibility.
New features:
- Get mipmap level size from a texture.
- Use explicit GPUDataFormat to specify how the input (or output) data
  is formated when uploading (or reading) texture data.
- Can upload different mipmap level after base level.
2018-06-28 15:31:02 +02:00
a1549065f2 Eevee: LightCache: Fix crash when baking with render result window open 2018-06-26 12:37:34 +02:00
0de33fb883 Eevee: LightCache: Make render work with no lightcache
This will only show the same thing as the viewport. It will not compute the
actual cache on the fly.
2018-06-26 12:36:54 +02:00
6364780b63 Merge remote-tracking branch 'origin/blender2.8' into temp-eeveelightcache 2018-06-26 11:43:14 +02:00
93aca278d2 Merge remote-tracking branch 'origin/blender2.8' into temp-eeveelightcache
# Conflicts:
#	source/blender/draw/engines/eevee/eevee_render.c
2018-06-25 18:32:30 +02:00
c5e7dff566 DRW: Codestyle: Add alias for accessing particular matrix in DRWMatrixState 2018-06-25 18:31:31 +02:00
922ebe960c Eevee: LightCache: Add back visibility group. 2018-06-25 18:16:36 +02:00
7f3ea60aa7 Eevee: Add back planar reflection. 2018-06-25 17:41:47 +02:00
7213006cef Fix warning 2018-06-25 17:39:09 +02:00
12d98d8a48 DRW: Change gl_context_mutex type to TicketMutex
This ensure the viewport is not locked indefinitely when rendering or
baking.
2018-06-25 11:17:15 +02:00
7ea7eae41f Eevee: Lookdev: Use own lightcache
This makes possible to have different lookdev settings per viewport without
rendering the environment constantly.
2018-06-25 00:15:30 +02:00
b28b6c62ed Merge remote-tracking branch 'origin/blender2.8' into temp-eeveelightcache 2018-06-24 21:59:11 +02:00
a498ffd4f6 Eevee: LightCache: Fix a warning, a mistake and two oversight 2018-06-24 21:40:50 +02:00
76f49c7a7b Eevee: LightCache: Fix fbos created in wrong context. 2018-06-24 17:54:53 +02:00
e50aa8dc9d Eevee: Fix wrong function order 2018-06-24 17:53:57 +02:00
077dba6ac2 Merge remote-tracking branch 'origin/blender2.8' into temp-eeveelightcache 2018-06-24 15:03:50 +02:00
025b260144 Merge remote-tracking branch 'origin/blender2.8' into temp-eeveelightcache 2018-06-23 21:12:45 +02:00
d73bdecea4 Merge remote-tracking branch 'origin/blender2.8' into temp-eeveelightcache
# Conflicts:
#	source/blender/blenloader/intern/versioning_280.c
2018-06-22 20:20:38 +02:00
c8859d8f66 Eevee: LightCache: Add UI to control visibility of the lighcache data
For the moment we use a per scene setting for that. We could move it to be
per viewport (as an overlay).
2018-06-22 20:19:48 +02:00
77fd1a6a4b Merge remote-tracking branch 'origin/blender2.8' into temp-eeveelightcache
# Conflicts:
#	source/blender/gpu/intern/gpu_texture.c
2018-06-22 17:41:15 +02:00
506f5654fe Eevee: LightCache: Fix sample selection algorithm 2018-06-22 17:39:50 +02:00
d8a7fd1006 DRW: Modify the engines code to work with latest changes 2018-06-22 17:22:22 +02:00
e05b7c1616 DRW: Refactor ObjectEngineData into DrawData
This is because we will use it to store the update flags from the depsgraph.

Use a similar system as AnimationData where the struct is inserted at a
fixed position after the ID struct.
2018-06-22 17:21:39 +02:00
e8d4930c4d Eevee: LightCache: Add fallback cache for world if no scene cache found 2018-06-22 14:00:08 +02:00
02e2428fda DRW: Add option to bypass deferred shader compilation 2018-06-22 13:57:30 +02:00
56fd8978a5 Object Mode: Remove cubemap lightprobes outline
This is because the display code now differs and the outline does not match.
This commit make them uselectable by their display shape (the sphere).

I will revisit this latter.
2018-06-21 18:47:51 +02:00
90fdb427af Eevee: LightProbes: Change/optimize the cubemap probe display 2018-06-21 18:45:47 +02:00
1cbb195f8d Object Mode: Make the LightProbe Grid samples outlines as dots
This is because this display will not always match the position of the baked
samples. Making it as dots also makes it less flickery.
2018-06-21 17:54:28 +02:00
29a834e530 Eevee: LightProbes: Add back and optimize the irradiance sample display 2018-06-21 17:51:37 +02:00
5d280a2397 Eevee: LightCache: Add back progressive rendering. 2018-06-21 16:00:21 +02:00
ce6418fc16 GPUTexture: Add GPU_texture_read
This is to get the texture content from the GPU memory.
2018-06-20 18:31:46 +02:00
873acfb124 Eevee: LightCache: Finish basic cache support.
Still missing: Multi bounce support.
2018-06-20 15:30:58 +02:00
007d3074fa Eevee: Move cache creation to main thread
This fix freeing hazard and use after free.
2018-06-20 11:59:41 +02:00
84c0446150 Merge remote-tracking branch 'origin/blender2.8' into temp-eeveelightcache 2018-06-20 11:23:17 +02:00
fbeae8ab13 Merge remote-tracking branch 'origin/blender2.8' into temp-eeveelightcache 2018-06-19 18:12:56 +02:00
43efefdbba Eevee: LightCache: Add progress bar and cancelation. 2018-06-19 18:12:36 +02:00
8713dd1621 Eevee: LightCache: More work... 2018-06-19 16:35:07 +02:00
38eb004977 Merge remote-tracking branch 'origin/blender2.8' into temp-eeveelightcache 2018-06-19 11:43:27 +02:00
de0c3f563d Eevee: LightCache: Add back world baking support. 2018-06-18 19:22:13 +02:00
51a4af4eb5 GPUTexture: Add GPU_texture_layers
It's actually used to get the depth size of the texture.
This is because GPU_texture_depth is already taken.

We need to clean up this API at some point.
2018-06-18 19:21:29 +02:00
a0f5f3116a Merge remote-tracking branch 'origin/blender2.8' into temp-eeveelightcache
# Conflicts:
#	source/blender/blenloader/intern/readblenentry.c
2018-06-18 11:20:59 +02:00
f00a590fd4 Merge remote-tracking branch 'origin/blender2.8' into temp-eeveelightcache 2018-06-15 18:02:51 +02:00
d3c645f72d Eevee: Move LightCache from ViewLayer to Scene
Also integrate it into the undo system and the depsgraph.

Green light means no cache, red means a baked light cache is used.
2018-06-15 18:02:17 +02:00
ccea4d13b3 DRW: Fix typos leading to locks and crashes. 2018-06-15 17:58:29 +02:00
99e236e4d2 Merge remote-tracking branch 'origin/blender2.8' into temp-eeveelightcache 2018-06-15 12:38:25 +02:00
ffa5468bd9 GPUTexture: Fix missing "\n" in printfs. 2018-06-14 19:11:13 +02:00
8c18f79bd3 Eevee: Remove old lightprobe implementation & start fresh. 2018-06-14 18:54:51 +02:00
44e1c5d817 Merge remote-tracking branch 'origin/blender2.8' into temp-eeveelightcache 2018-06-14 11:30:27 +02:00
60ff71cc40 Eevee: Lightcache: Add own gl context to the baking job
This is to follow the recent changes in how we handle gl context in
threads.
2018-06-13 14:19:04 +02:00
71c2768dcf Merge remote-tracking branch 'origin/blender2.8' into temp-eeveelightcache 2018-06-11 19:09:36 +02:00
312b12d172 Merge remote-tracking branch 'origin/blender2.8' into temp-eeveelightcache 2018-06-11 18:11:38 +02:00
49b0ac57c1 Eevee: Light Cache: Create Probe data and share the lightcache.
The lightcache is now can shared between viewlayers. We need this to share
the lighting data with the original viewlayer with the baking layer.

The cache is still not working.
2018-06-01 14:16:16 +02:00
d380267b61 Eevee: Light Cache: Add Operator and base implementation.
Does nothing at the moment. Just create a job and search all probes in a
view layer.

Only works if copy on write is enabled.
2018-06-01 14:16:16 +02:00
61 changed files with 3539 additions and 1726 deletions

View File

@@ -712,15 +712,49 @@ class RENDER_PT_eevee_indirect_lighting(RenderButtonsPanel, Panel):
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
layout.use_property_split = True layout.use_property_split = True
layout.use_property_decorate = False # No animation.
scene = context.scene scene = context.scene
props = scene.eevee props = scene.eevee
col = layout.column() col = layout.column()
col.operator("scene.light_cache_bake", text="Bake Indirect Lighting", icon='RENDER_STILL')
col.operator("scene.light_cache_bake", text="Bake Cubemap Only", icon='LIGHTPROBE_CUBEMAP').subset = "CUBEMAPS"
col.operator("scene.light_cache_free", text="Free Lighting Cache")
cache_info = scene.eevee.gi_cache_info
if cache_info:
col.label(text=cache_info)
col.prop(props, "gi_auto_bake")
col.prop(props, "gi_diffuse_bounces") col.prop(props, "gi_diffuse_bounces")
col.prop(props, "gi_cubemap_resolution") col.prop(props, "gi_cubemap_resolution")
col.prop(props, "gi_visibility_resolution", text="Diffuse Occlusion") col.prop(props, "gi_visibility_resolution", text="Diffuse Occlusion")
layout.use_property_split = False
row = layout.split(percentage=0.5)
row.alignment = 'RIGHT'
row.label("Cubemap Display")
sub = row.row(align=True)
sub.prop(props, "gi_cubemap_draw_size", text="Size")
if props.gi_show_cubemaps :
sub.prop(props, "gi_show_cubemaps", text="", toggle=True, icon='HIDE_OFF')
else:
sub.prop(props, "gi_show_cubemaps", text="", toggle=True, icon='HIDE_ON')
row = layout.split(percentage=0.5)
row.alignment = 'RIGHT'
row.label("Irradiance Display")
sub = row.row(align=True)
sub.prop(props, "gi_irradiance_draw_size", text="Size")
if props.gi_show_irradiance :
sub.prop(props, "gi_show_irradiance", text="", toggle=True, icon='HIDE_OFF')
else:
sub.prop(props, "gi_show_irradiance", text="", toggle=True, icon='HIDE_ON')
class RENDER_PT_eevee_film(RenderButtonsPanel, Panel): class RENDER_PT_eevee_film(RenderButtonsPanel, Panel):
bl_label = "Film" bl_label = "Film"

View File

@@ -239,7 +239,7 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc)
} }
unsigned char *pixels = MEM_callocN((size_t)gc->p2_width * (size_t)gc->p2_height, "BLF texture init"); unsigned char *pixels = MEM_callocN((size_t)gc->p2_width * (size_t)gc->p2_height, "BLF texture init");
GPUTexture *tex = GPU_texture_create_2D(gc->p2_width, gc->p2_height, GPU_R8, (const float *)pixels, error); GPUTexture *tex = GPU_texture_create_nD(gc->p2_width, gc->p2_height, 0, 2, pixels, GPU_R8, GPU_DATA_UNSIGNED_BYTE, 0, false, error);
MEM_freeN(pixels); MEM_freeN(pixels);
gc->textures[gc->texture_current] = tex; gc->textures[gc->texture_current] = tex;
GPU_texture_bind(tex, 0); GPU_texture_bind(tex, 0);
@@ -476,7 +476,7 @@ void blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y)
BLI_assert(g->height > 0); BLI_assert(g->height > 0);
} }
GPU_texture_update_sub(g->tex, g->bitmap, g->offset_x, g->offset_y, 0, g->width, g->height, 0); GPU_texture_update_sub(g->tex, GPU_DATA_UNSIGNED_BYTE, g->bitmap, g->offset_x, g->offset_y, 0, g->width, g->height, 0);
g->uv[0][0] = ((float)g->offset_x) / ((float)gc->p2_width); g->uv[0][0] = ((float)g->offset_x) / ((float)gc->p2_width);
g->uv[0][1] = ((float)g->offset_y) / ((float)gc->p2_height); g->uv[0][1] = ((float)g->offset_y) / ((float)gc->p2_height);

View File

@@ -44,10 +44,4 @@ struct World *BKE_world_copy(struct Main *bmain, const struct World *wrld);
struct World *BKE_world_localize(struct World *wrld); struct World *BKE_world_localize(struct World *wrld);
void BKE_world_make_local(struct Main *bmain, struct World *wrld, const bool lib_local); void BKE_world_make_local(struct Main *bmain, struct World *wrld, const bool lib_local);
/* Evaluation. */
struct Depsgraph;
void BKE_world_eval(struct Depsgraph *depsgraph, struct World *world);
#endif #endif

View File

@@ -424,6 +424,8 @@ void BKE_object_free(Object *ob)
{ {
BKE_animdata_free((ID *)ob, false); BKE_animdata_free((ID *)ob, false);
DRW_drawdata_free((ID *)ob);
/* BKE_<id>_free shall never touch to ID->us. Never ever. */ /* BKE_<id>_free shall never touch to ID->us. Never ever. */
BKE_object_free_modifiers(ob, LIB_ID_CREATE_NO_USER_REFCOUNT); BKE_object_free_modifiers(ob, LIB_ID_CREATE_NO_USER_REFCOUNT);
@@ -451,13 +453,6 @@ void BKE_object_free(Object *ob)
sbFree(ob); sbFree(ob);
for (ObjectEngineData *oed = ob->drawdata.first; oed; oed = oed->next) {
if (oed->free != NULL) {
oed->free(oed);
}
}
BLI_freelistN(&ob->drawdata);
BKE_sculptsession_free(ob); BKE_sculptsession_free(ob);
BLI_freelistN(&ob->pc_ids); BLI_freelistN(&ob->pc_ids);
@@ -1210,7 +1205,6 @@ void BKE_object_copy_data(Main *UNUSED(bmain), Object *ob_dst, const Object *ob_
ob_dst->derivedFinal = NULL; ob_dst->derivedFinal = NULL;
BLI_listbase_clear(&ob_dst->gpulamp); BLI_listbase_clear(&ob_dst->gpulamp);
BLI_listbase_clear(&ob_dst->drawdata);
BLI_listbase_clear(&ob_dst->pc_ids); BLI_listbase_clear(&ob_dst->pc_ids);
ob_dst->avs = ob_src->avs; ob_dst->avs = ob_src->avs;

View File

@@ -102,6 +102,9 @@
#include "DEG_depsgraph_query.h" #include "DEG_depsgraph_query.h"
#include "RE_engine.h" #include "RE_engine.h"
#include "RE_engine.h"
#include "engines/eevee/eevee_lightcache.h"
#include "PIL_time.h" #include "PIL_time.h"
@@ -316,6 +319,9 @@ void BKE_scene_copy_data(Main *bmain, Scene *sce_dst, const Scene *sce_src, cons
else { else {
sce_dst->preview = NULL; sce_dst->preview = NULL;
} }
sce_dst->eevee.light_cache = NULL;
/* TODO Copy the cache. */
} }
Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type) Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
@@ -511,6 +517,11 @@ void BKE_scene_free_ex(Scene *sce, const bool do_id_user)
sce->master_collection = NULL; sce->master_collection = NULL;
} }
if (sce->eevee.light_cache) {
EEVEE_lightcache_free(sce->eevee.light_cache);
sce->eevee.light_cache = NULL;
}
/* These are freed on doversion. */ /* These are freed on doversion. */
BLI_assert(sce->layer_properties == NULL); BLI_assert(sce->layer_properties == NULL);
} }
@@ -814,6 +825,8 @@ void BKE_scene_init(Scene *sce)
sce->eevee.gi_diffuse_bounces = 3; sce->eevee.gi_diffuse_bounces = 3;
sce->eevee.gi_cubemap_resolution = 512; sce->eevee.gi_cubemap_resolution = 512;
sce->eevee.gi_visibility_resolution = 32; sce->eevee.gi_visibility_resolution = 32;
sce->eevee.gi_cubemap_draw_size = 0.2f;
sce->eevee.gi_irradiance_draw_size = 1.0f;
sce->eevee.taa_samples = 16; sce->eevee.taa_samples = 16;
sce->eevee.taa_render_samples = 64; sce->eevee.taa_render_samples = 64;
@@ -856,6 +869,8 @@ void BKE_scene_init(Scene *sce)
sce->eevee.shadow_cube_size = 512; sce->eevee.shadow_cube_size = 512;
sce->eevee.shadow_cascade_size = 1024; sce->eevee.shadow_cascade_size = 1024;
sce->eevee.light_cache = NULL;
sce->eevee.flag = sce->eevee.flag =
SCE_EEVEE_VOLUMETRIC_LIGHTS | SCE_EEVEE_VOLUMETRIC_LIGHTS |
SCE_EEVEE_VOLUMETRIC_COLORED | SCE_EEVEE_VOLUMETRIC_COLORED |

View File

@@ -239,8 +239,8 @@ static void studiolight_create_equirectangular_radiance_gputexture(StudioLight *
offset3 += 3; offset3 += 3;
offset4 += 4; offset4 += 4;
} }
sl->equirectangular_radiance_gputexture = GPU_texture_create_2D( sl->equirectangular_radiance_gputexture = GPU_texture_create_nD(
ibuf->x, ibuf->y, GPU_R11F_G11F_B10F, sl->gpu_matcap_3components, error); ibuf->x, ibuf->y, 0, 2, sl->gpu_matcap_3components, GPU_R11F_G11F_B10F, GPU_DATA_FLOAT, 0, false, error);
} }
else { else {
sl->equirectangular_radiance_gputexture = GPU_texture_create_2D( sl->equirectangular_radiance_gputexture = GPU_texture_create_2D(

View File

@@ -53,6 +53,8 @@
#include "BKE_node.h" #include "BKE_node.h"
#include "BKE_world.h" #include "BKE_world.h"
#include "DRW_engine.h"
#include "DEG_depsgraph.h" #include "DEG_depsgraph.h"
#include "GPU_material.h" #include "GPU_material.h"
@@ -62,6 +64,8 @@ void BKE_world_free(World *wrld)
{ {
BKE_animdata_free((ID *)wrld, false); BKE_animdata_free((ID *)wrld, false);
DRW_drawdata_free((ID *)wrld);
/* is no lib link block, but world extension */ /* is no lib link block, but world extension */
if (wrld->nodetree) { if (wrld->nodetree) {
ntreeFreeTree(wrld->nodetree); ntreeFreeTree(wrld->nodetree);
@@ -163,10 +167,3 @@ void BKE_world_make_local(Main *bmain, World *wrld, const bool lib_local)
BKE_id_make_local_generic(bmain, &wrld->id, true, lib_local); BKE_id_make_local_generic(bmain, &wrld->id, true, lib_local);
} }
void BKE_world_eval(struct Depsgraph *depsgraph, World *world)
{
DEG_debug_print_eval(depsgraph, __func__, world->id.name, world);
if (!BLI_listbase_is_empty(&world->gpumaterial)) {
world->update_flag = 1;
}
}

View File

@@ -30,6 +30,7 @@ set(INC
../blenlib ../blenlib
../blentranslation ../blentranslation
../depsgraph ../depsgraph
../draw
../imbuf ../imbuf
../makesdna ../makesdna
../makesrna ../makesrna

View File

@@ -393,6 +393,9 @@ BlendFileData *BLO_read_from_memfile(
/* makes lookup of existing images in old main */ /* makes lookup of existing images in old main */
blo_make_image_pointer_map(fd, oldmain); blo_make_image_pointer_map(fd, oldmain);
/* makes lookup of existing light caches in old main */
blo_make_scene_pointer_map(fd, oldmain);
/* makes lookup of existing video clips in old main */ /* makes lookup of existing video clips in old main */
blo_make_movieclip_pointer_map(fd, oldmain); blo_make_movieclip_pointer_map(fd, oldmain);
@@ -403,6 +406,9 @@ BlendFileData *BLO_read_from_memfile(
bfd = blo_read_file_internal(fd, filename); bfd = blo_read_file_internal(fd, filename);
/* ensures relinked light caches are not freed */
blo_end_scene_pointer_map(fd, oldmain);
/* ensures relinked images are not freed */ /* ensures relinked images are not freed */
blo_end_image_pointer_map(fd, oldmain); blo_end_image_pointer_map(fd, oldmain);

View File

@@ -158,6 +158,8 @@
#include "BKE_colortools.h" #include "BKE_colortools.h"
#include "BKE_workspace.h" #include "BKE_workspace.h"
#include "DRW_engine.h"
#include "DEG_depsgraph.h" #include "DEG_depsgraph.h"
#include "NOD_common.h" #include "NOD_common.h"
@@ -1339,6 +1341,8 @@ void blo_freefiledata(FileData *fd)
oldnewmap_free(fd->imamap); oldnewmap_free(fd->imamap);
if (fd->movieclipmap) if (fd->movieclipmap)
oldnewmap_free(fd->movieclipmap); oldnewmap_free(fd->movieclipmap);
if (fd->scenemap)
oldnewmap_free(fd->scenemap);
if (fd->soundmap) if (fd->soundmap)
oldnewmap_free(fd->soundmap); oldnewmap_free(fd->soundmap);
if (fd->packedmap) if (fd->packedmap)
@@ -1526,6 +1530,13 @@ static void *newimaadr(FileData *fd, const void *adr) /* used to restore im
return NULL; return NULL;
} }
static void *newsceadr(FileData *fd, const void *adr) /* used to restore scene data after undo */
{
if (fd->scenemap && adr)
return oldnewmap_lookup_and_inc(fd->scenemap, adr, true);
return NULL;
}
static void *newmclipadr(FileData *fd, const void *adr) /* used to restore movie clip data after undo */ static void *newmclipadr(FileData *fd, const void *adr) /* used to restore movie clip data after undo */
{ {
if (fd->movieclipmap && adr) if (fd->movieclipmap && adr)
@@ -1631,6 +1642,37 @@ void blo_clear_proxy_pointers_from_lib(Main *oldmain)
} }
} }
void blo_make_scene_pointer_map(FileData *fd, Main *oldmain)
{
Scene *sce = oldmain->scene.first;
fd->scenemap = oldnewmap_new();
for (; sce; sce = sce->id.next) {
if (sce->eevee.light_cache) {
struct LightCache *light_cache = sce->eevee.light_cache;
oldnewmap_insert(fd->scenemap, light_cache, light_cache, 0);
}
}
}
void blo_end_scene_pointer_map(FileData *fd, Main *oldmain)
{
OldNew *entry = fd->scenemap->entries;
Scene *sce = oldmain->scene.first;
int i;
/* used entries were restored, so we put them to zero */
for (i = 0; i < fd->scenemap->nentries; i++, entry++) {
if (entry->nr > 0)
entry->newp = NULL;
}
for (; sce; sce = sce->id.next) {
sce->eevee.light_cache = newsceadr(fd, sce->eevee.light_cache);
}
}
void blo_make_image_pointer_map(FileData *fd, Main *oldmain) void blo_make_image_pointer_map(FileData *fd, Main *oldmain)
{ {
Image *ima = oldmain->image.first; Image *ima = oldmain->image.first;
@@ -2301,6 +2343,11 @@ static void direct_link_id(FileData *fd, ID *id)
id->override_static = newdataadr(fd, id->override_static); id->override_static = newdataadr(fd, id->override_static);
link_list_ex(fd, &id->override_static->properties, direct_link_id_override_property_cb); link_list_ex(fd, &id->override_static->properties, direct_link_id_override_property_cb);
} }
DrawDataList *drawdata = DRW_drawdatalist_from_id(id);
if (drawdata) {
BLI_listbase_clear((ListBase *)drawdata);
}
} }
/* ************ READ CurveMapping *************** */ /* ************ READ CurveMapping *************** */
@@ -5493,7 +5540,6 @@ static void direct_link_object(FileData *fd, Object *ob)
ob->derivedFinal = NULL; ob->derivedFinal = NULL;
BKE_object_runtime_reset(ob); BKE_object_runtime_reset(ob);
BLI_listbase_clear(&ob->gpulamp); BLI_listbase_clear(&ob->gpulamp);
BLI_listbase_clear(&ob->drawdata);
link_list(fd, &ob->pc_ids); link_list(fd, &ob->pc_ids);
/* Runtime curve data */ /* Runtime curve data */
@@ -5740,6 +5786,41 @@ static void lib_link_sequence_modifiers(FileData *fd, Scene *scene, ListBase *lb
} }
} }
static void direct_link_lightcache_texture(FileData *fd, LightCacheTexture *lctex)
{
lctex->tex = NULL;
if (lctex->data) {
lctex->data = newdataadr(fd, lctex->data);
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
int data_size = lctex->components * lctex->tex_size[0] * lctex->tex_size[1] * lctex->tex_size[2];
if (lctex->data_type == LIGHTCACHETEX_FLOAT) {
BLI_endian_switch_float_array((float *)lctex->data, data_size * sizeof(float));
}
else if (lctex->data_type == LIGHTCACHETEX_UINT) {
BLI_endian_switch_uint32_array((unsigned int *)lctex->data, data_size * sizeof(unsigned int));
}
}
}
}
static void direct_link_lightcache(FileData *fd, LightCache *cache)
{
direct_link_lightcache_texture(fd, &cache->cube_tx);
direct_link_lightcache_texture(fd, &cache->grid_tx);
if (cache->cube_mips) {
cache->cube_mips = newdataadr(fd, cache->cube_mips);
for (int i = 0; i < cache->mips_len; ++i) {
direct_link_lightcache_texture(fd, &cache->cube_mips[i]);
}
}
cache->cube_data = newdataadr(fd, cache->cube_data);
cache->grid_data = newdataadr(fd, cache->grid_data);
}
/* check for cyclic set-scene, /* check for cyclic set-scene,
* libs can cause this case which is normally prevented, see (T#####) */ * libs can cause this case which is normally prevented, see (T#####) */
#define USE_SETSCENE_CHECK #define USE_SETSCENE_CHECK
@@ -6300,6 +6381,19 @@ static void direct_link_scene(FileData *fd, Scene *sce)
direct_link_view_layer(fd, view_layer); direct_link_view_layer(fd, view_layer);
} }
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);
else sce->eevee.light_cache = NULL;
}
else {
/* else read the cache from file. */
if (sce->eevee.light_cache) {
sce->eevee.light_cache = newdataadr(fd, sce->eevee.light_cache);
direct_link_lightcache(fd, sce->eevee.light_cache);
}
}
sce->layer_properties = newdataadr(fd, sce->layer_properties); sce->layer_properties = newdataadr(fd, sce->layer_properties);
IDP_DirectLinkGroup_OrFree(&sce->layer_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); IDP_DirectLinkGroup_OrFree(&sce->layer_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
} }

View File

@@ -90,6 +90,7 @@ typedef struct FileData {
struct OldNewMap *libmap; struct OldNewMap *libmap;
struct OldNewMap *imamap; struct OldNewMap *imamap;
struct OldNewMap *movieclipmap; struct OldNewMap *movieclipmap;
struct OldNewMap *scenemap;
struct OldNewMap *soundmap; struct OldNewMap *soundmap;
struct OldNewMap *packedmap; struct OldNewMap *packedmap;
@@ -140,6 +141,8 @@ FileData *blo_openblendermemfile(struct MemFile *memfile, struct ReportList *rep
void blo_clear_proxy_pointers_from_lib(Main *oldmain); void blo_clear_proxy_pointers_from_lib(Main *oldmain);
void blo_make_image_pointer_map(FileData *fd, Main *oldmain); void blo_make_image_pointer_map(FileData *fd, Main *oldmain);
void blo_end_image_pointer_map(FileData *fd, Main *oldmain); void blo_end_image_pointer_map(FileData *fd, Main *oldmain);
void blo_make_scene_pointer_map(FileData *fd, Main *oldmain);
void blo_end_scene_pointer_map(FileData *fd, Main *oldmain);
void blo_make_movieclip_pointer_map(FileData *fd, Main *oldmain); void blo_make_movieclip_pointer_map(FileData *fd, Main *oldmain);
void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain); void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain);
void blo_make_sound_pointer_map(FileData *fd, Main *oldmain); void blo_make_sound_pointer_map(FileData *fd, Main *oldmain);

View File

@@ -1530,6 +1530,13 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
} }
} }
if (!DNA_struct_elem_find(fd->filesdna, "SceneEEVEE", "float", "gi_cubemap_draw_size")) {
for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
scene->eevee.gi_irradiance_draw_size = 0.2f;
scene->eevee.gi_cubemap_draw_size = 1.0f;
}
}
for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) { for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
if (scene->toolsettings->manipulator_flag == 0) { if (scene->toolsettings->manipulator_flag == 0) {
scene->toolsettings->manipulator_flag = SCE_MANIP_TRANSLATE | SCE_MANIP_ROTATE | SCE_MANIP_SCALE; scene->toolsettings->manipulator_flag = SCE_MANIP_TRANSLATE | SCE_MANIP_ROTATE | SCE_MANIP_SCALE;

View File

@@ -2479,6 +2479,36 @@ static void write_view_layer(WriteData *wd, ViewLayer *view_layer)
write_layer_collections(wd, &view_layer->layer_collections); write_layer_collections(wd, &view_layer->layer_collections);
} }
static void write_lightcache_texture(WriteData *wd, LightCacheTexture *tex)
{
if (tex->data) {
size_t data_size = tex->components * tex->tex_size[0] * tex->tex_size[1] * tex->tex_size[2];
if (tex->data_type == LIGHTCACHETEX_FLOAT) {
data_size *= sizeof(float);
}
else if (tex->data_type == LIGHTCACHETEX_UINT) {
data_size *= sizeof(unsigned int);
}
writedata(wd, DATA, data_size, tex->data);
}
}
static void write_lightcache(WriteData *wd, LightCache *cache)
{
write_lightcache_texture(wd, &cache->grid_tx);
write_lightcache_texture(wd, &cache->cube_tx);
if (cache->cube_mips) {
writestruct(wd, DATA, LightCacheTexture, cache->mips_len, cache->cube_mips);
for (int i = 0; i < cache->mips_len; ++i) {
write_lightcache_texture(wd, &cache->cube_mips[i]);
}
}
writestruct(wd, DATA, LightGridCache, cache->grid_len, cache->grid_data);
writestruct(wd, DATA, LightProbeCache, cache->cube_len, cache->cube_data);
}
static void write_scene(WriteData *wd, Scene *sce) static void write_scene(WriteData *wd, Scene *sce)
{ {
/* write LibData */ /* write LibData */
@@ -2679,6 +2709,12 @@ static void write_scene(WriteData *wd, Scene *sce)
write_collection_nolib(wd, sce->master_collection); write_collection_nolib(wd, sce->master_collection);
} }
/* 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);
}
/* Freed on doversion. */ /* Freed on doversion. */
BLI_assert(sce->layer_properties == NULL); BLI_assert(sce->layer_properties == NULL);
} }

View File

@@ -28,6 +28,7 @@ set(INC
../blenkernel ../blenkernel
../blenlib ../blenlib
../bmesh ../bmesh
../draw
../makesdna ../makesdna
../makesrna ../makesrna
../modifiers ../modifiers

View File

@@ -873,9 +873,7 @@ void DepsgraphNodeBuilder::build_world(World *world)
/* world itself */ /* world itself */
add_operation_node(&world->id, add_operation_node(&world->id,
DEG_NODE_TYPE_SHADING, DEG_NODE_TYPE_SHADING,
function_bind(BKE_world_eval, NULL,
_1,
get_cow_datablock(world)),
DEG_OPCODE_WORLD_UPDATE); DEG_OPCODE_WORLD_UPDATE);
/* world's nodetree */ /* world's nodetree */
if (world->nodetree != NULL) { if (world->nodetree != NULL) {

View File

@@ -553,6 +553,13 @@ void update_special_pointers(const Depsgraph *depsgraph,
update_particle_system_orig_pointers(object_orig, object_cow); update_particle_system_orig_pointers(object_orig, object_cow);
break; break;
} }
case ID_SCE:
{
Scene *scene_cow = (Scene *)id_cow;
const Scene *scene_orig = (const Scene *)id_orig;
scene_cow->eevee.light_cache = scene_orig->eevee.light_cache;
break;
}
default: default:
break; break;
} }
@@ -713,7 +720,7 @@ typedef struct ObjectRuntimeBackup {
CurveCache *curve_cache; CurveCache *curve_cache;
Object_Runtime runtime; Object_Runtime runtime;
short base_flag; short base_flag;
ListBase drawdata; DrawDataList drawdata;
} ObjectRuntimeBackup; } ObjectRuntimeBackup;
/* Make a backup of object's evaluation runtime data, additionally /* Make a backup of object's evaluation runtime data, additionally
@@ -742,7 +749,7 @@ static void deg_backup_object_runtime(
object_runtime_backup->base_flag = object->base_flag; object_runtime_backup->base_flag = object->base_flag;
/* Make backup of object draw data.*/ /* Make backup of object draw data.*/
object_runtime_backup->drawdata = object->drawdata; object_runtime_backup->drawdata = object->drawdata;
BLI_listbase_clear(&object->drawdata); BLI_listbase_clear((ListBase *)&object->drawdata);
} }
static void deg_restore_object_runtime( static void deg_restore_object_runtime(
@@ -917,6 +924,12 @@ void discard_mesh_edit_mode_pointers(ID *id_cow)
mesh_cow->edit_btmesh = NULL; mesh_cow->edit_btmesh = NULL;
} }
void discard_scene_pointers(ID *id_cow)
{
Scene *scene_cow = (Scene *)id_cow;
scene_cow->eevee.light_cache = NULL;
}
/* NULL-ify all edit mode pointers which points to data from /* NULL-ify all edit mode pointers which points to data from
* original object. * original object.
*/ */
@@ -939,6 +952,11 @@ void discard_edit_mode_pointers(ID *id_cow)
case ID_LT: case ID_LT:
discard_lattice_edit_mode_pointers(id_cow); discard_lattice_edit_mode_pointers(id_cow);
break; break;
case ID_SCE:
/* Not really edit mode but still needs to run before
* BKE_libblock_free_datablock() */
discard_scene_pointers(id_cow);
break;
default: default:
break; break;
} }

View File

@@ -46,6 +46,8 @@
extern "C" { extern "C" {
#include "DNA_object_types.h" #include "DNA_object_types.h"
#include "DRW_engine.h"
} /* extern "C" */ } /* extern "C" */
#include "DEG_depsgraph.h" #include "DEG_depsgraph.h"
@@ -219,12 +221,12 @@ BLI_INLINE OperationDepsNode *flush_schedule_children(
void flush_engine_data_update(ID *id) void flush_engine_data_update(ID *id)
{ {
if (GS(id->name) != ID_OB) { DrawDataList *drawdata = DRW_drawdatalist_from_id(id);
if (drawdata == NULL) {
return; return;
} }
Object *object = (Object *)id; LISTBASE_FOREACH(DrawData *, dd, drawdata) {
LISTBASE_FOREACH(ObjectEngineData *, engine_data, &object->drawdata) { dd->recalc |= id->recalc;
engine_data->recalc |= id->recalc;
} }
} }

View File

@@ -96,6 +96,7 @@ set(SRC
engines/eevee/eevee_depth_of_field.c engines/eevee/eevee_depth_of_field.c
engines/eevee/eevee_effects.c engines/eevee/eevee_effects.c
engines/eevee/eevee_engine.c engines/eevee/eevee_engine.c
engines/eevee/eevee_lightcache.c
engines/eevee/eevee_lightprobes.c engines/eevee/eevee_lightprobes.c
engines/eevee/eevee_lights.c engines/eevee/eevee_lights.c
engines/eevee/eevee_lookdev.c engines/eevee/eevee_lookdev.c
@@ -137,6 +138,7 @@ set(SRC
modes/edit_mesh_mode_intern.h modes/edit_mesh_mode_intern.h
engines/basic/basic_engine.h engines/basic/basic_engine.h
engines/eevee/eevee_engine.h engines/eevee/eevee_engine.h
engines/eevee/eevee_lightcache.h
engines/eevee/eevee_lut.h engines/eevee/eevee_lut.h
engines/eevee/eevee_private.h engines/eevee/eevee_private.h
engines/external/external_engine.h engines/external/external_engine.h

View File

@@ -136,6 +136,14 @@ void DRW_opengl_context_destroy(void);
void DRW_opengl_context_enable(void); void DRW_opengl_context_enable(void);
void DRW_opengl_context_disable(void); void DRW_opengl_context_disable(void);
void DRW_opengl_render_context_enable(void *re_gl_context);
void DRW_opengl_render_context_disable(void *re_gl_context);
void DRW_gawain_render_context_enable(void *re_gwn_context);
void DRW_gawain_render_context_disable(void *re_gwn_context);
void DRW_deferred_shader_remove(struct GPUMaterial *mat); void DRW_deferred_shader_remove(struct GPUMaterial *mat);
struct DrawDataList *DRW_drawdatalist_from_id(struct ID *id);
void DRW_drawdata_free(struct ID *id);
#endif /* __DRW_ENGINE_H__ */ #endif /* __DRW_ENGINE_H__ */

View File

@@ -28,6 +28,7 @@
#include "DRW_render.h" #include "DRW_render.h"
#include "eevee_private.h" #include "eevee_private.h"
#include "eevee_lightcache.h"
static void eevee_view_layer_data_free(void *storage) static void eevee_view_layer_data_free(void *storage)
{ {
@@ -53,6 +54,11 @@ static void eevee_view_layer_data_free(void *storage)
MEM_SAFE_FREE(sldata->shcasters_buffers[1].shadow_casters); MEM_SAFE_FREE(sldata->shcasters_buffers[1].shadow_casters);
MEM_SAFE_FREE(sldata->shcasters_buffers[1].flags); MEM_SAFE_FREE(sldata->shcasters_buffers[1].flags);
if (sldata->fallback_lightcache) {
EEVEE_lightcache_free(sldata->fallback_lightcache);
sldata->fallback_lightcache = NULL;
}
/* Probes */ /* Probes */
MEM_SAFE_FREE(sldata->probes); MEM_SAFE_FREE(sldata->probes);
DRW_UBO_FREE_SAFE(sldata->probe_ubo); DRW_UBO_FREE_SAFE(sldata->probe_ubo);
@@ -60,15 +66,6 @@ static void eevee_view_layer_data_free(void *storage)
DRW_UBO_FREE_SAFE(sldata->planar_ubo); DRW_UBO_FREE_SAFE(sldata->planar_ubo);
DRW_UBO_FREE_SAFE(sldata->common_ubo); DRW_UBO_FREE_SAFE(sldata->common_ubo);
DRW_UBO_FREE_SAFE(sldata->clip_ubo); DRW_UBO_FREE_SAFE(sldata->clip_ubo);
GPU_FRAMEBUFFER_FREE_SAFE(sldata->probe_filter_fb);
for (int i = 0; i < 6; ++i) {
GPU_FRAMEBUFFER_FREE_SAFE(sldata->probe_face_fb[i]);
}
DRW_TEXTURE_FREE_SAFE(sldata->probe_rt);
DRW_TEXTURE_FREE_SAFE(sldata->probe_depth_rt);
DRW_TEXTURE_FREE_SAFE(sldata->probe_pool);
DRW_TEXTURE_FREE_SAFE(sldata->irradiance_pool);
DRW_TEXTURE_FREE_SAFE(sldata->irradiance_rt);
} }
EEVEE_ViewLayerData *EEVEE_view_layer_data_get(void) EEVEE_ViewLayerData *EEVEE_view_layer_data_get(void)
@@ -77,6 +74,18 @@ EEVEE_ViewLayerData *EEVEE_view_layer_data_get(void)
&draw_engine_eevee_type); &draw_engine_eevee_type);
} }
EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure_ex(struct ViewLayer *view_layer)
{
EEVEE_ViewLayerData **sldata = (EEVEE_ViewLayerData **)DRW_view_layer_engine_data_ensure_ex(
view_layer, &draw_engine_eevee_type, &eevee_view_layer_data_free);
if (*sldata == NULL) {
*sldata = MEM_callocN(sizeof(**sldata), "EEVEE_ViewLayerData");
}
return *sldata;
}
EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure(void) EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure(void)
{ {
EEVEE_ViewLayerData **sldata = (EEVEE_ViewLayerData **)DRW_view_layer_engine_data_ensure( EEVEE_ViewLayerData **sldata = (EEVEE_ViewLayerData **)DRW_view_layer_engine_data_ensure(
@@ -91,9 +100,9 @@ EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure(void)
/* Object data. */ /* Object data. */
static void eevee_object_data_init(ObjectEngineData *engine_data) static void eevee_object_data_init(DrawData *dd)
{ {
EEVEE_ObjectEngineData *eevee_data = (EEVEE_ObjectEngineData *)engine_data; EEVEE_ObjectEngineData *eevee_data = (EEVEE_ObjectEngineData *)dd;
eevee_data->shadow_caster_id = -1; eevee_data->shadow_caster_id = -1;
} }
@@ -102,15 +111,15 @@ EEVEE_ObjectEngineData *EEVEE_object_data_get(Object *ob)
if (ELEM(ob->type, OB_LIGHTPROBE, OB_LAMP)) { if (ELEM(ob->type, OB_LIGHTPROBE, OB_LAMP)) {
return NULL; return NULL;
} }
return (EEVEE_ObjectEngineData *)DRW_object_engine_data_get( return (EEVEE_ObjectEngineData *)DRW_drawdata_get(
ob, &draw_engine_eevee_type); &ob->id, &draw_engine_eevee_type);
} }
EEVEE_ObjectEngineData *EEVEE_object_data_ensure(Object *ob) EEVEE_ObjectEngineData *EEVEE_object_data_ensure(Object *ob)
{ {
BLI_assert(!ELEM(ob->type, OB_LIGHTPROBE, OB_LAMP)); BLI_assert(!ELEM(ob->type, OB_LIGHTPROBE, OB_LAMP));
return (EEVEE_ObjectEngineData *)DRW_object_engine_data_ensure( return (EEVEE_ObjectEngineData *)DRW_drawdata_ensure(
ob, &ob->id,
&draw_engine_eevee_type, &draw_engine_eevee_type,
sizeof(EEVEE_ObjectEngineData), sizeof(EEVEE_ObjectEngineData),
eevee_object_data_init, eevee_object_data_init,
@@ -119,18 +128,10 @@ EEVEE_ObjectEngineData *EEVEE_object_data_ensure(Object *ob)
/* Light probe data. */ /* Light probe data. */
static void eevee_lightprobe_data_init(ObjectEngineData *engine_data) static void eevee_lightprobe_data_init(DrawData *dd)
{ {
EEVEE_LightProbeEngineData *ped = (EEVEE_LightProbeEngineData *)engine_data; EEVEE_LightProbeEngineData *ped = (EEVEE_LightProbeEngineData *)dd;
ped->need_full_update = true; ped->need_update = false;
ped->need_update = true;
}
static void eevee_lightprobe_data_free(ObjectEngineData *engine_data)
{
EEVEE_LightProbeEngineData *ped = (EEVEE_LightProbeEngineData *)engine_data;
BLI_freelistN(&ped->captured_object_list);
} }
EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_get(Object *ob) EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_get(Object *ob)
@@ -138,26 +139,26 @@ EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_get(Object *ob)
if (ob->type != OB_LIGHTPROBE) { if (ob->type != OB_LIGHTPROBE) {
return NULL; return NULL;
} }
return (EEVEE_LightProbeEngineData *)DRW_object_engine_data_get( return (EEVEE_LightProbeEngineData *)DRW_drawdata_get(
ob, &draw_engine_eevee_type); &ob->id, &draw_engine_eevee_type);
} }
EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_ensure(Object *ob) EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_ensure(Object *ob)
{ {
BLI_assert(ob->type == OB_LIGHTPROBE); BLI_assert(ob->type == OB_LIGHTPROBE);
return (EEVEE_LightProbeEngineData *)DRW_object_engine_data_ensure( return (EEVEE_LightProbeEngineData *)DRW_drawdata_ensure(
ob, &ob->id,
&draw_engine_eevee_type, &draw_engine_eevee_type,
sizeof(EEVEE_LightProbeEngineData), sizeof(EEVEE_LightProbeEngineData),
eevee_lightprobe_data_init, eevee_lightprobe_data_init,
eevee_lightprobe_data_free); NULL);
} }
/* Lamp data. */ /* Lamp data. */
static void eevee_lamp_data_init(ObjectEngineData *engine_data) static void eevee_lamp_data_init(DrawData *dd)
{ {
EEVEE_LampEngineData *led = (EEVEE_LampEngineData *)engine_data; EEVEE_LampEngineData *led = (EEVEE_LampEngineData *)dd;
led->need_update = true; led->need_update = true;
led->prev_cube_shadow_id = -1; led->prev_cube_shadow_id = -1;
} }
@@ -167,17 +168,41 @@ EEVEE_LampEngineData *EEVEE_lamp_data_get(Object *ob)
if (ob->type != OB_LAMP) { if (ob->type != OB_LAMP) {
return NULL; return NULL;
} }
return (EEVEE_LampEngineData *)DRW_object_engine_data_get( return (EEVEE_LampEngineData *)DRW_drawdata_get(
ob, &draw_engine_eevee_type); &ob->id, &draw_engine_eevee_type);
} }
EEVEE_LampEngineData *EEVEE_lamp_data_ensure(Object *ob) EEVEE_LampEngineData *EEVEE_lamp_data_ensure(Object *ob)
{ {
BLI_assert(ob->type == OB_LAMP); BLI_assert(ob->type == OB_LAMP);
return (EEVEE_LampEngineData *)DRW_object_engine_data_ensure( return (EEVEE_LampEngineData *)DRW_drawdata_ensure(
ob, &ob->id,
&draw_engine_eevee_type, &draw_engine_eevee_type,
sizeof(EEVEE_LampEngineData), sizeof(EEVEE_LampEngineData),
eevee_lamp_data_init, eevee_lamp_data_init,
NULL); NULL);
} }
/* World data. */
static void eevee_world_data_init(DrawData *dd)
{
EEVEE_WorldEngineData *wed = (EEVEE_WorldEngineData *)dd;
wed->dd.recalc |= 1;
}
EEVEE_WorldEngineData *EEVEE_world_data_get(World *wo)
{
return (EEVEE_WorldEngineData *)DRW_drawdata_get(
&wo->id, &draw_engine_eevee_type);
}
EEVEE_WorldEngineData *EEVEE_world_data_ensure(World *wo)
{
return (EEVEE_WorldEngineData *)DRW_drawdata_ensure(
&wo->id,
&draw_engine_eevee_type,
sizeof(EEVEE_WorldEngineData),
eevee_world_data_init,
NULL);
}

View File

@@ -123,7 +123,7 @@ static void eevee_cache_init(void *vedata)
EEVEE_volumes_cache_init(sldata, vedata); EEVEE_volumes_cache_init(sldata, vedata);
} }
static void eevee_cache_populate(void *vedata, Object *ob) void EEVEE_cache_populate(void *vedata, Object *ob)
{ {
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure(); EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
@@ -146,7 +146,7 @@ static void eevee_cache_populate(void *vedata, Object *ob)
/* TODO: Special case for dupli objects because we cannot save the object pointer. */ /* TODO: Special case for dupli objects because we cannot save the object pointer. */
} }
else { else {
EEVEE_lightprobes_cache_add(sldata, ob); EEVEE_lightprobes_cache_add(sldata, vedata, ob);
} }
} }
else if (ob->type == OB_LAMP) { else if (ob->type == OB_LAMP) {
@@ -282,7 +282,9 @@ static void eevee_draw_background(void *vedata)
EEVEE_subsurface_compute(sldata, vedata); EEVEE_subsurface_compute(sldata, vedata);
EEVEE_reflection_compute(sldata, vedata); EEVEE_reflection_compute(sldata, vedata);
EEVEE_occlusion_draw_debug(sldata, vedata); EEVEE_occlusion_draw_debug(sldata, vedata);
DRW_draw_pass(psl->probe_display); if (psl->probe_display) {
DRW_draw_pass(psl->probe_display);
}
EEVEE_refraction_compute(sldata, vedata); EEVEE_refraction_compute(sldata, vedata);
/* Opaque refraction */ /* Opaque refraction */
@@ -365,21 +367,35 @@ static void eevee_view_update(void *vedata)
static void eevee_id_object_update(void *UNUSED(vedata), Object *object) static void eevee_id_object_update(void *UNUSED(vedata), Object *object)
{ {
/* This is a bit mask of components which update is to be ignored. */
EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_get(object); EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_get(object);
if (ped != NULL && ped->engine_data.recalc != 0) { if (ped != NULL && ped->dd.recalc != 0) {
ped->need_full_update = true; ped->need_update = (ped->dd.recalc & (ID_RECALC_TRANSFORM | ID_RECALC_COPY_ON_WRITE)) != 0;
ped->engine_data.recalc = 0; ped->dd.recalc = 0;
} }
EEVEE_LampEngineData *led = EEVEE_lamp_data_get(object); EEVEE_LampEngineData *led = EEVEE_lamp_data_get(object);
if (led != NULL && led->engine_data.recalc != 0) { if (led != NULL && led->dd.recalc != 0) {
led->need_update = true; led->need_update = true;
led->engine_data.recalc = 0; led->dd.recalc = 0;
} }
EEVEE_ObjectEngineData *oedata = EEVEE_object_data_get(object); EEVEE_ObjectEngineData *oedata = EEVEE_object_data_get(object);
if (oedata != NULL && oedata->engine_data.recalc != 0) { if (oedata != NULL && oedata->dd.recalc != 0) {
oedata->need_update = true; oedata->need_update = true;
oedata->engine_data.recalc = 0; oedata->dd.recalc = 0;
}
}
static void eevee_id_world_update(void *vedata, World *wo)
{
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
LightCache *lcache = stl->g_data->light_cache;
EEVEE_WorldEngineData *wedata = EEVEE_world_data_ensure(wo);
if (wedata != NULL && wedata->dd.recalc != 0) {
if ((lcache->flag & (LIGHTCACHE_BAKED | LIGHTCACHE_BAKING)) == 0) {
lcache->flag |= LIGHTCACHE_UPDATE_WORLD;
}
wedata->dd.recalc = 0;
} }
} }
@@ -387,6 +403,9 @@ static void eevee_id_update(void *vedata, ID *id)
{ {
/* Handle updates based on ID type. */ /* Handle updates based on ID type. */
switch (GS(id->name)) { switch (GS(id->name)) {
case ID_WO:
eevee_id_world_update(vedata, (World *)id);
break;
case ID_OB: case ID_OB:
eevee_id_object_update(vedata, (Object *)id); eevee_id_object_update(vedata, (Object *)id);
break; break;
@@ -433,7 +452,7 @@ DrawEngineType draw_engine_eevee_type = {
&eevee_engine_init, &eevee_engine_init,
&eevee_engine_free, &eevee_engine_free,
&eevee_cache_init, &eevee_cache_init,
&eevee_cache_populate, &EEVEE_cache_populate,
&eevee_cache_finish, &eevee_cache_finish,
&eevee_draw_background, &eevee_draw_background,
NULL, /* Everything is drawn in the background pass (see comment on function) */ NULL, /* Everything is drawn in the background pass (see comment on function) */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,59 @@
/*
* Copyright 2018, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Blender Institute
*
*/
/** \file eevee_lightcache.h
* \ingroup eevee
*/
#ifndef __EEVEE_LIGHTCACHE_H__
#define __EEVEE_LIGHTCACHE_H__
#include "BLI_sys_types.h" /* for bool */
struct ViewLayer;
struct Scene;
struct SceneEEVEE;
struct LightCache;
struct EEVEE_ViewLayerData;
struct EEVEE_Data;
struct EEVEE_LightBake;
/* Light Bake */
struct wmJob *EEVEE_lightbake_job_create(
struct wmWindowManager *wm, struct wmWindow *win, struct Main *bmain,
struct ViewLayer *view_layer, struct Scene *scene, int delay);
void *EEVEE_lightbake_job_data_alloc(struct Main *bmain, struct ViewLayer *viewlayer, struct Scene *scene, bool run_as_job);
void EEVEE_lightbake_job_data_free(void *custom_data);
void EEVEE_lightbake_update(void *custom_data);
void EEVEE_lightbake_job(void *custom_data, short *stop, short *do_update, float *progress);
void EEVEE_lightbake_update_world_quick(struct EEVEE_ViewLayerData *sldata, struct EEVEE_Data *vedata, const Scene *scene);
/* Light Cache */
struct LightCache *EEVEE_lightcache_create(
const int grid_len, const int cube_len,
const int cube_size, const int vis_size,
const int irr_size[3]);
void EEVEE_lightcache_free(struct LightCache *lcache);
void EEVEE_lightcache_load(struct LightCache *lcache);
void EEVEE_lightcache_info_update(struct SceneEEVEE *eevee);
#endif /* __EEVEE_LIGHTCACHE_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -148,7 +148,7 @@ void EEVEE_lights_init(EEVEE_ViewLayerData *sldata)
DRW_TEXTURE_FREE_SAFE(sldata->shadow_cube_blur); DRW_TEXTURE_FREE_SAFE(sldata->shadow_cube_blur);
/* Compute adequate size for the octahedral map. */ /* Compute adequate size for the octahedral map. */
linfo->shadow_cube_store_size = (int)ceil(sqrt((sh_cube_size * sh_cube_size) * 6.0f)); linfo->shadow_cube_store_size = OCTAHEDRAL_SIZE_FROM_CUBESIZE(sh_cube_size);
CLAMP(linfo->shadow_cube_store_size, 1, 4096); CLAMP(linfo->shadow_cube_store_size, 1, 4096);
CLAMP(sh_cube_size, 1, 4096); CLAMP(sh_cube_size, 1, 4096);

View File

@@ -30,15 +30,31 @@
#include "DNA_screen_types.h" #include "DNA_screen_types.h"
#include "DNA_world_types.h" #include "DNA_world_types.h"
#include "DEG_depsgraph_query.h"
#include "ED_screen.h" #include "ED_screen.h"
#include "eevee_private.h" #include "eevee_private.h"
#include "eevee_lightcache.h"
static void eevee_lookdev_lightcache_delete(EEVEE_Data *vedata)
{
EEVEE_StorageList *stl = vedata->stl;
EEVEE_TextureList *txl = vedata->txl;
MEM_SAFE_FREE(stl->lookdev_lightcache);
MEM_SAFE_FREE(stl->lookdev_grid_data);
MEM_SAFE_FREE(stl->lookdev_cube_data);
DRW_TEXTURE_FREE_SAFE(txl->lookdev_grid_tx);
DRW_TEXTURE_FREE_SAFE(txl->lookdev_cube_tx);
}
void EEVEE_lookdev_cache_init( void EEVEE_lookdev_cache_init(
EEVEE_Data *vedata, DRWShadingGroup **grp, GPUShader *shader, DRWPass *pass, EEVEE_Data *vedata, DRWShadingGroup **grp, GPUShader *shader, DRWPass *pass,
World *world, EEVEE_LightProbesInfo *pinfo) World *world, EEVEE_LightProbesInfo *pinfo)
{ {
EEVEE_StorageList *stl = vedata->stl; EEVEE_StorageList *stl = vedata->stl;
EEVEE_TextureList *txl = vedata->txl;
const DRWContextState *draw_ctx = DRW_context_state_get(); const DRWContextState *draw_ctx = DRW_context_state_get();
View3D *v3d = draw_ctx->v3d; View3D *v3d = draw_ctx->v3d;
if (LOOK_DEV_STUDIO_LIGHT_ENABLED(v3d)) { if (LOOK_DEV_STUDIO_LIGHT_ENABLED(v3d)) {
@@ -47,6 +63,43 @@ void EEVEE_lookdev_cache_init(
struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get(); struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
GPUTexture *tex = NULL; GPUTexture *tex = NULL;
/* If one of the component is missing we start from scratch. */
if ((stl->lookdev_grid_data == NULL) ||
(stl->lookdev_cube_data == NULL) ||
(txl->lookdev_grid_tx == NULL) ||
(txl->lookdev_cube_tx == NULL))
{
eevee_lookdev_lightcache_delete(vedata);
}
if (stl->lookdev_lightcache == NULL) {
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
#if defined(IRRADIANCE_SH_L2)
int grid_res = 4;
#elif defined(IRRADIANCE_CUBEMAP)
int grid_res = 8;
#elif defined(IRRADIANCE_HL2)
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;
stl->lookdev_lightcache = EEVEE_lightcache_create(1, 1, cube_res, vis_res, (int[3]){grid_res, grid_res, 1});
/* We do this to use a special light cache for lookdev.
* This lightcache needs to be per viewport. But we need to
* have correct freeing when the viewport is closed. So we
* need to reference all textures to the txl and the memblocks
* to the stl. */
stl->lookdev_grid_data = stl->lookdev_lightcache->grid_data;
stl->lookdev_cube_data = stl->lookdev_lightcache->cube_data;
stl->lookdev_cube_mips = stl->lookdev_lightcache->cube_mips;
txl->lookdev_grid_tx = stl->lookdev_lightcache->grid_tx.tex;
txl->lookdev_cube_tx = stl->lookdev_lightcache->cube_tx.tex;
}
stl->g_data->light_cache = stl->lookdev_lightcache;
*grp = DRW_shgroup_create(shader, pass); *grp = DRW_shgroup_create(shader, pass);
axis_angle_to_mat3_single(stl->g_data->studiolight_matrix, 'Z', v3d->shading.studiolight_rot_z); axis_angle_to_mat3_single(stl->g_data->studiolight_matrix, 'Z', v3d->shading.studiolight_rot_z);
DRW_shgroup_uniform_mat3(*grp, "StudioLightMatrix", stl->g_data->studiolight_matrix); DRW_shgroup_uniform_mat3(*grp, "StudioLightMatrix", stl->g_data->studiolight_matrix);
@@ -77,11 +130,9 @@ void EEVEE_lookdev_cache_init(
((pinfo->studiolight_index != sl->index) || ((pinfo->studiolight_index != sl->index) ||
(pinfo->studiolight_rot_z != v3d->shading.studiolight_rot_z))) (pinfo->studiolight_rot_z != v3d->shading.studiolight_rot_z)))
{ {
pinfo->update_world |= PROBE_UPDATE_ALL; stl->lookdev_lightcache->flag |= LIGHTCACHE_UPDATE_WORLD;
pinfo->studiolight_index = sl->index; pinfo->studiolight_index = sl->index;
pinfo->studiolight_rot_z = v3d->shading.studiolight_rot_z; pinfo->studiolight_rot_z = v3d->shading.studiolight_rot_z;
pinfo->prev_wo_sh_compiled = false;
pinfo->prev_world = NULL;
} }
} }
} }

View File

@@ -362,6 +362,8 @@ static void add_standard_uniforms(
DRWShadingGroup *shgrp, EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, DRWShadingGroup *shgrp, EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata,
int *ssr_id, float *refract_depth, bool use_ssrefraction, bool use_alpha_blend) int *ssr_id, float *refract_depth, bool use_ssrefraction, bool use_alpha_blend)
{ {
LightCache *lcache = vedata->stl->g_data->light_cache;
if (ssr_id == NULL) { if (ssr_id == NULL) {
static int no_ssr = -1.0f; static int no_ssr = -1.0f;
ssr_id = &no_ssr; ssr_id = &no_ssr;
@@ -393,12 +395,12 @@ static void add_standard_uniforms(
/* TODO if diffuse bsdf */ /* TODO if diffuse bsdf */
if (true) { if (true) {
DRW_shgroup_uniform_texture_ref(shgrp, "irradianceGrid", &sldata->irradiance_pool); DRW_shgroup_uniform_texture_ref(shgrp, "irradianceGrid", &lcache->grid_tx.tex);
} }
/* TODO if glossy bsdf */ /* TODO if glossy bsdf */
if (true) { if (true) {
DRW_shgroup_uniform_texture_ref(shgrp, "probeCubes", &sldata->probe_pool); DRW_shgroup_uniform_texture_ref(shgrp, "probeCubes", &lcache->cube_tx.tex);
DRW_shgroup_uniform_texture_ref(shgrp, "probePlanars", &vedata->txl->planar_pool); DRW_shgroup_uniform_texture_ref(shgrp, "probePlanars", &vedata->txl->planar_pool);
DRW_shgroup_uniform_int(shgrp, "outputSsrId", ssr_id, 1); DRW_shgroup_uniform_int(shgrp, "outputSsrId", ssr_id, 1);
} }
@@ -654,14 +656,14 @@ struct GPUMaterial *EEVEE_material_world_lightprobe_get(struct Scene *scene, Wor
const void *engine = &DRW_engine_viewport_eevee_type; const void *engine = &DRW_engine_viewport_eevee_type;
const int options = VAR_WORLD_PROBE; const int options = VAR_WORLD_PROBE;
GPUMaterial *mat = DRW_shader_find_from_world(wo, engine, options); GPUMaterial *mat = DRW_shader_find_from_world(wo, engine, options, false);
if (mat != NULL) { if (mat != NULL) {
return mat; return mat;
} }
return DRW_shader_create_from_world( return DRW_shader_create_from_world(
scene, wo, engine, options, scene, wo, engine, options,
datatoc_background_vert_glsl, NULL, e_data.frag_shader_lib, datatoc_background_vert_glsl, NULL, e_data.frag_shader_lib,
SHADER_DEFINES "#define PROBE_CAPTURE\n"); SHADER_DEFINES "#define PROBE_CAPTURE\n", false);
} }
struct GPUMaterial *EEVEE_material_world_background_get(struct Scene *scene, World *wo) struct GPUMaterial *EEVEE_material_world_background_get(struct Scene *scene, World *wo)
@@ -669,14 +671,14 @@ struct GPUMaterial *EEVEE_material_world_background_get(struct Scene *scene, Wor
const void *engine = &DRW_engine_viewport_eevee_type; const void *engine = &DRW_engine_viewport_eevee_type;
int options = VAR_WORLD_BACKGROUND; int options = VAR_WORLD_BACKGROUND;
GPUMaterial *mat = DRW_shader_find_from_world(wo, engine, options); GPUMaterial *mat = DRW_shader_find_from_world(wo, engine, options, true);
if (mat != NULL) { if (mat != NULL) {
return mat; return mat;
} }
return DRW_shader_create_from_world( return DRW_shader_create_from_world(
scene, wo, engine, options, scene, wo, engine, options,
datatoc_background_vert_glsl, NULL, e_data.frag_shader_lib, datatoc_background_vert_glsl, NULL, e_data.frag_shader_lib,
SHADER_DEFINES "#define WORLD_BACKGROUND\n"); SHADER_DEFINES "#define WORLD_BACKGROUND\n", true);
} }
struct GPUMaterial *EEVEE_material_world_volume_get(struct Scene *scene, World *wo) struct GPUMaterial *EEVEE_material_world_volume_get(struct Scene *scene, World *wo)
@@ -684,7 +686,7 @@ struct GPUMaterial *EEVEE_material_world_volume_get(struct Scene *scene, World *
const void *engine = &DRW_engine_viewport_eevee_type; const void *engine = &DRW_engine_viewport_eevee_type;
int options = VAR_WORLD_VOLUME; int options = VAR_WORLD_VOLUME;
GPUMaterial *mat = DRW_shader_find_from_world(wo, engine, options); GPUMaterial *mat = DRW_shader_find_from_world(wo, engine, options, true);
if (mat != NULL) { if (mat != NULL) {
return mat; return mat;
} }
@@ -694,7 +696,7 @@ struct GPUMaterial *EEVEE_material_world_volume_get(struct Scene *scene, World *
mat = DRW_shader_create_from_world( mat = DRW_shader_create_from_world(
scene, wo, engine, options, scene, wo, engine, options,
datatoc_volumetric_vert_glsl, datatoc_volumetric_geom_glsl, e_data.volume_shader_lib, datatoc_volumetric_vert_glsl, datatoc_volumetric_geom_glsl, e_data.volume_shader_lib,
defines); defines, true);
MEM_freeN(defines); MEM_freeN(defines);
@@ -719,7 +721,7 @@ struct GPUMaterial *EEVEE_material_mesh_get(
options |= eevee_material_shadow_option(shadow_method); options |= eevee_material_shadow_option(shadow_method);
GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options); GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options, true);
if (mat) { if (mat) {
return mat; return mat;
} }
@@ -729,7 +731,7 @@ struct GPUMaterial *EEVEE_material_mesh_get(
mat = DRW_shader_create_from_material( mat = DRW_shader_create_from_material(
scene, ma, engine, options, scene, ma, engine, options,
e_data.vert_shader_str, NULL, e_data.frag_shader_lib, e_data.vert_shader_str, NULL, e_data.frag_shader_lib,
defines); defines, true);
MEM_freeN(defines); MEM_freeN(defines);
@@ -741,7 +743,7 @@ struct GPUMaterial *EEVEE_material_mesh_volume_get(struct Scene *scene, Material
const void *engine = &DRW_engine_viewport_eevee_type; const void *engine = &DRW_engine_viewport_eevee_type;
int options = VAR_MAT_VOLUME; int options = VAR_MAT_VOLUME;
GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options); GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options, true);
if (mat != NULL) { if (mat != NULL) {
return mat; return mat;
} }
@@ -751,7 +753,7 @@ struct GPUMaterial *EEVEE_material_mesh_volume_get(struct Scene *scene, Material
mat = DRW_shader_create_from_material( mat = DRW_shader_create_from_material(
scene, ma, engine, options, scene, ma, engine, options,
datatoc_volumetric_vert_glsl, datatoc_volumetric_geom_glsl, e_data.volume_shader_lib, datatoc_volumetric_vert_glsl, datatoc_volumetric_geom_glsl, e_data.volume_shader_lib,
defines); defines, true);
MEM_freeN(defines); MEM_freeN(defines);
@@ -775,7 +777,7 @@ struct GPUMaterial *EEVEE_material_mesh_depth_get(
if (is_shadow) if (is_shadow)
options |= VAR_MAT_SHADOW; options |= VAR_MAT_SHADOW;
GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options); GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options, true);
if (mat) { if (mat) {
return mat; return mat;
} }
@@ -791,7 +793,8 @@ struct GPUMaterial *EEVEE_material_mesh_depth_get(
(is_shadow) ? datatoc_shadow_vert_glsl : e_data.vert_shader_str, (is_shadow) ? datatoc_shadow_vert_glsl : e_data.vert_shader_str,
NULL, NULL,
frag_str, frag_str,
defines); defines,
true);
MEM_freeN(frag_str); MEM_freeN(frag_str);
MEM_freeN(defines); MEM_freeN(defines);
@@ -807,7 +810,7 @@ struct GPUMaterial *EEVEE_material_hair_get(
options |= eevee_material_shadow_option(shadow_method); options |= eevee_material_shadow_option(shadow_method);
GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options); GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options, true);
if (mat) { if (mat) {
return mat; return mat;
} }
@@ -817,7 +820,7 @@ struct GPUMaterial *EEVEE_material_hair_get(
mat = DRW_shader_create_from_material( mat = DRW_shader_create_from_material(
scene, ma, engine, options, scene, ma, engine, options,
e_data.vert_shader_str, NULL, e_data.frag_shader_lib, e_data.vert_shader_str, NULL, e_data.frag_shader_lib,
defines); defines, true);
MEM_freeN(defines); MEM_freeN(defines);
@@ -971,7 +974,6 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_call_add(grp, geom, NULL); DRW_shgroup_call_add(grp, geom, NULL);
break; break;
case GPU_MAT_QUEUED: case GPU_MAT_QUEUED:
sldata->probes->all_materials_updated = false;
/* TODO Bypass probe compilation. */ /* TODO Bypass probe compilation. */
col = compile_col; col = compile_col;
break; break;
@@ -1228,7 +1230,6 @@ static void material_opaque(
} }
case GPU_MAT_QUEUED: case GPU_MAT_QUEUED:
{ {
sldata->probes->all_materials_updated = false;
/* TODO Bypass probe compilation. */ /* TODO Bypass probe compilation. */
color_p = compile_col; color_p = compile_col;
metal_p = spec_p = rough_p = &half; metal_p = spec_p = rough_p = &half;
@@ -1315,7 +1316,6 @@ static void material_transparent(
} }
case GPU_MAT_QUEUED: case GPU_MAT_QUEUED:
{ {
sldata->probes->all_materials_updated = false;
/* TODO Bypass probe compilation. */ /* TODO Bypass probe compilation. */
color_p = compile_col; color_p = compile_col;
metal_p = spec_p = rough_p = &half; metal_p = spec_p = rough_p = &half;
@@ -1645,7 +1645,6 @@ void EEVEE_hair_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata,
} }
case GPU_MAT_QUEUED: case GPU_MAT_QUEUED:
{ {
sldata->probes->all_materials_updated = false;
color_p = compile_col; color_p = compile_col;
metal_p = spec_p = rough_p = &half; metal_p = spec_p = rough_p = &half;
break; break;

View File

@@ -26,11 +26,14 @@
#ifndef __EEVEE_PRIVATE_H__ #ifndef __EEVEE_PRIVATE_H__
#define __EEVEE_PRIVATE_H__ #define __EEVEE_PRIVATE_H__
#include "DNA_lightprobe_types.h"
struct Object; struct Object;
struct EEVEE_BoundSphere; struct EEVEE_BoundSphere;
struct EEVEE_ShadowCasterBuffer; struct EEVEE_ShadowCasterBuffer;
struct RenderLayer; struct RenderLayer;
struct RenderResult; struct RenderResult;
struct GPUFrameBuffer;
extern struct DrawEngineType draw_engine_eevee_type; extern struct DrawEngineType draw_engine_eevee_type;
@@ -98,6 +101,10 @@ extern struct DrawEngineType draw_engine_eevee_type;
#define USE_SCENE_LIGHT(v3d) ((!v3d) || (!LOOK_DEV_MODE_ENABLED(v3d)) || ((LOOK_DEV_MODE_ENABLED(v3d) && (v3d->shading.flag & V3D_SHADING_SCENE_LIGHTS)))) #define USE_SCENE_LIGHT(v3d) ((!v3d) || (!LOOK_DEV_MODE_ENABLED(v3d)) || ((LOOK_DEV_MODE_ENABLED(v3d) && (v3d->shading.flag & V3D_SHADING_SCENE_LIGHTS))))
#define LOOK_DEV_STUDIO_LIGHT_ENABLED(v3d) (LOOK_DEV_MODE_ENABLED(v3d) && !(v3d->shading.flag & V3D_SHADING_SCENE_WORLD)) #define LOOK_DEV_STUDIO_LIGHT_ENABLED(v3d) (LOOK_DEV_MODE_ENABLED(v3d) && !(v3d->shading.flag & V3D_SHADING_SCENE_WORLD))
#define OCTAHEDRAL_SIZE_FROM_CUBESIZE(cube_size) ((int)ceilf(sqrtf((cube_size * cube_size) * 6.0f)))
#define MIN_CUBE_LOD_LEVEL 3
#define MAX_PLANAR_LOD_LEVEL 9
/* World shader variations */ /* World shader variations */
enum { enum {
VAR_WORLD_BACKGROUND = 0, VAR_WORLD_BACKGROUND = 0,
@@ -132,6 +139,27 @@ enum {
VAR_MAT_SSSALBED = (1 << 17), VAR_MAT_SSSALBED = (1 << 17),
}; };
/* ************ PROBE UBO ************* */
/* They are the same struct as their Cache siblings.
* typedef'ing just to keep the naming consistent with
* other eevee types. */
typedef LightProbeCache EEVEE_LightProbe;
typedef LightGridCache EEVEE_LightGrid;
typedef struct EEVEE_PlanarReflection {
float plane_equation[4];
float clip_vec_x[3], attenuation_scale;
float clip_vec_y[3], attenuation_bias;
float clip_edge_x_pos, clip_edge_x_neg;
float clip_edge_y_pos, clip_edge_y_neg;
float facing_scale, facing_bias, clipsta, pad;
float reflectionmat[4][4]; /* Used for sampling the texture. */
float mtx[4][4]; /* Not used in shader. TODO move elsewhere. */
} EEVEE_PlanarReflection;
/* --------------------------------------- */
typedef struct EEVEE_BoundSphere { typedef struct EEVEE_BoundSphere {
float center[3], radius; float center[3], radius;
} EEVEE_BoundSphere; } EEVEE_BoundSphere;
@@ -272,6 +300,9 @@ typedef struct EEVEE_TextureList {
struct GPUTexture *volume_scatter_history; struct GPUTexture *volume_scatter_history;
struct GPUTexture *volume_transmittance_history; struct GPUTexture *volume_transmittance_history;
struct GPUTexture *lookdev_grid_tx;
struct GPUTexture *lookdev_cube_tx;
struct GPUTexture *planar_pool; struct GPUTexture *planar_pool;
struct GPUTexture *planar_depth; struct GPUTexture *planar_depth;
@@ -288,6 +319,10 @@ typedef struct EEVEE_StorageList {
struct EEVEE_PrivateData *g_data; struct EEVEE_PrivateData *g_data;
struct LightCache *lookdev_lightcache;
EEVEE_LightProbe *lookdev_cube_data;
EEVEE_LightGrid *lookdev_grid_data;
LightCacheTexture *lookdev_cube_mips;
} EEVEE_StorageList; } EEVEE_StorageList;
/* ************ LIGHT UBO ************* */ /* ************ LIGHT UBO ************* */
@@ -392,42 +427,11 @@ enum {
LIGHT_UPDATE_SHADOW_CUBE = (1 << 0), LIGHT_UPDATE_SHADOW_CUBE = (1 << 0),
}; };
/* ************ PROBE UBO ************* */
typedef struct EEVEE_LightProbe {
float position[3], parallax_type;
float attenuation_fac;
float attenuation_type;
float pad3[2];
float attenuationmat[4][4];
float parallaxmat[4][4];
} EEVEE_LightProbe;
typedef struct EEVEE_LightGrid {
float mat[4][4];
int resolution[3], offset;
float corner[3], attenuation_scale;
float increment_x[3], attenuation_bias; /* world space vector between 2 opposite cells */
float increment_y[3], level_bias;
float increment_z[3], pad4;
float visibility_bias, visibility_bleed, visibility_range, pad5;
} EEVEE_LightGrid;
typedef struct EEVEE_PlanarReflection {
float plane_equation[4];
float clip_vec_x[3], attenuation_scale;
float clip_vec_y[3], attenuation_bias;
float clip_edge_x_pos, clip_edge_x_neg;
float clip_edge_y_pos, clip_edge_y_neg;
float facing_scale, facing_bias, pad[2];
float reflectionmat[4][4];
} EEVEE_PlanarReflection;
/* ************ PROBE DATA ************* */ /* ************ PROBE DATA ************* */
typedef struct EEVEE_LightProbeVisTest { typedef struct EEVEE_LightProbeVisTest {
struct Collection *collection; /* Skip test if NULL */
bool invert; bool invert;
bool cached; /* Reuse last test results */ bool cached; /* Reuse last test results */
struct Collection *collection; /* Skip test if NULL */
} EEVEE_LightProbeVisTest; } EEVEE_LightProbeVisTest;
typedef struct EEVEE_LightProbesInfo { typedef struct EEVEE_LightProbesInfo {
@@ -440,13 +444,9 @@ typedef struct EEVEE_LightProbesInfo {
int updated_bounce; int updated_bounce;
int num_bounce; int num_bounce;
int cubemap_res; int cubemap_res;
int target_size; /* Update */
int grid_initialized;
struct World *prev_world;
int update_world;
bool prev_wo_sh_compiled;
bool do_cube_update; bool do_cube_update;
bool all_materials_updated; bool do_grid_update;
/* For rendering probes */ /* For rendering probes */
float probemat[6][4][4]; float probemat[6][4][4];
int layer; int layer;
@@ -465,15 +465,11 @@ typedef struct EEVEE_LightProbesInfo {
int shres; int shres;
int studiolight_index; int studiolight_index;
float studiolight_rot_z; float studiolight_rot_z;
/* List of probes in the scene. */ EEVEE_LightProbeVisTest planar_vis_tests[MAX_PLANAR];
/* XXX This is fragile, can get out of sync quickly. */
struct Object *probes_cube_ref[MAX_PROBE];
struct Object *probes_grid_ref[MAX_GRID];
struct Object *probes_planar_ref[MAX_PLANAR];
/* UBO Storage : data used by UBO */ /* UBO Storage : data used by UBO */
struct EEVEE_LightProbe probe_data[MAX_PROBE]; EEVEE_LightProbe probe_data[MAX_PROBE];
struct EEVEE_LightGrid grid_data[MAX_GRID]; EEVEE_LightGrid grid_data[MAX_GRID];
struct EEVEE_PlanarReflection planar_data[MAX_PLANAR]; EEVEE_PlanarReflection planar_data[MAX_PLANAR];
/* Probe Visibility Collection */ /* Probe Visibility Collection */
EEVEE_LightProbeVisTest vis_data; EEVEE_LightProbeVisTest vis_data;
} EEVEE_LightProbesInfo; } EEVEE_LightProbesInfo;
@@ -673,24 +669,18 @@ typedef struct EEVEE_ViewLayerData {
struct GPUUniformBuffer *grid_ubo; struct GPUUniformBuffer *grid_ubo;
struct GPUUniformBuffer *planar_ubo; struct GPUUniformBuffer *planar_ubo;
struct GPUFrameBuffer *probe_filter_fb;
struct GPUFrameBuffer *probe_face_fb[6];
struct GPUTexture *probe_rt;
struct GPUTexture *probe_depth_rt;
struct GPUTexture *probe_pool;
struct GPUTexture *irradiance_pool;
struct GPUTexture *irradiance_rt;
/* Common Uniform Buffer */ /* Common Uniform Buffer */
struct EEVEE_CommonUniformBuffer common_data; struct EEVEE_CommonUniformBuffer common_data;
struct GPUUniformBuffer *common_ubo; struct GPUUniformBuffer *common_ubo;
struct EEVEE_ClipPlanesUniformBuffer clip_data; struct EEVEE_ClipPlanesUniformBuffer clip_data;
struct GPUUniformBuffer *clip_ubo; struct GPUUniformBuffer *clip_ubo;
struct LightCache *fallback_lightcache;
} EEVEE_ViewLayerData; } EEVEE_ViewLayerData;
/* ************ OBJECT DATA ************ */ /* ************ OBJECT DATA ************ */
typedef struct EEVEE_LightData { typedef struct EEVEE_LightData {
short light_id, shadow_id; short light_id, shadow_id;
} EEVEE_LightData; } EEVEE_LightData;
@@ -711,7 +701,7 @@ typedef struct EEVEE_ShadowCascadeData {
* It works with even if the object is in multiple layers * It works with even if the object is in multiple layers
* because we don't get the same "Object *" for each layer. */ * because we don't get the same "Object *" for each layer. */
typedef struct EEVEE_LampEngineData { typedef struct EEVEE_LampEngineData {
ObjectEngineData engine_data; DrawData dd;
bool need_update; bool need_update;
/* This needs to be out of the union to avoid undefined behaviour. */ /* This needs to be out of the union to avoid undefined behaviour. */
@@ -724,35 +714,13 @@ typedef struct EEVEE_LampEngineData {
} EEVEE_LampEngineData; } EEVEE_LampEngineData;
typedef struct EEVEE_LightProbeEngineData { typedef struct EEVEE_LightProbeEngineData {
ObjectEngineData engine_data; DrawData dd;
/* NOTE: need_full_update is set by dependency graph when the probe or it's
* object is updated. This triggers full probe update, including it's
* "progressive" GI refresh.
*
* need_update is always set to truth when need_full_update is tagged, but
* might also be forced to be kept truth during GI refresh stages.
*
* TODO(sergey): Is there a way to avoid two flags here, or at least make
* it more clear what's going on here?
*/
bool need_full_update;
bool need_update; bool need_update;
bool ready_to_shade;
int updated_cells;
int updated_lvl;
int num_cell;
int max_lvl;
int probe_id; /* Only used for display data */
float probe_size; /* Only used for display data */
DRWMatrixState mats; /* For planar probes */
float planer_eq_offset[4];
struct ListBase captured_object_list;
} EEVEE_LightProbeEngineData; } EEVEE_LightProbeEngineData;
typedef struct EEVEE_ObjectEngineData { typedef struct EEVEE_ObjectEngineData {
ObjectEngineData engine_data; DrawData dd;
Object *ob; /* self reference */ Object *ob; /* self reference */
EEVEE_LightProbeVisTest *test_data; EEVEE_LightProbeVisTest *test_data;
@@ -762,6 +730,10 @@ typedef struct EEVEE_ObjectEngineData {
uint shadow_caster_id; uint shadow_caster_id;
} EEVEE_ObjectEngineData; } EEVEE_ObjectEngineData;
typedef struct EEVEE_WorldEngineData {
DrawData dd;
} EEVEE_WorldEngineData;
/* *********************************** */ /* *********************************** */
typedef struct EEVEE_Data { typedef struct EEVEE_Data {
@@ -786,6 +758,8 @@ typedef struct EEVEE_PrivateData {
struct DRWShadingGroup *planar_display_shgrp; struct DRWShadingGroup *planar_display_shgrp;
struct GHash *material_hash; struct GHash *material_hash;
float background_alpha; /* TODO find a better place for this. */ float background_alpha; /* TODO find a better place for this. */
/* Chosen lightcache: can come from Lookdev or the viewlayer. */
struct LightCache *light_cache;
/* For planar probes */ /* For planar probes */
float planar_texel_size[2]; float planar_texel_size[2];
/* For double buffering */ /* For double buffering */
@@ -803,6 +777,7 @@ typedef struct EEVEE_PrivateData {
/* eevee_data.c */ /* eevee_data.c */
EEVEE_ViewLayerData *EEVEE_view_layer_data_get(void); EEVEE_ViewLayerData *EEVEE_view_layer_data_get(void);
EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure_ex(struct ViewLayer *view_layer);
EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure(void); EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure(void);
EEVEE_ObjectEngineData *EEVEE_object_data_get(Object *ob); EEVEE_ObjectEngineData *EEVEE_object_data_get(Object *ob);
EEVEE_ObjectEngineData *EEVEE_object_data_ensure(Object *ob); EEVEE_ObjectEngineData *EEVEE_object_data_ensure(Object *ob);
@@ -810,6 +785,8 @@ EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_get(Object *ob);
EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_ensure(Object *ob); EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_ensure(Object *ob);
EEVEE_LampEngineData *EEVEE_lamp_data_get(Object *ob); EEVEE_LampEngineData *EEVEE_lamp_data_get(Object *ob);
EEVEE_LampEngineData *EEVEE_lamp_data_ensure(Object *ob); EEVEE_LampEngineData *EEVEE_lamp_data_ensure(Object *ob);
EEVEE_WorldEngineData *EEVEE_world_data_get(World *wo);
EEVEE_WorldEngineData *EEVEE_world_data_ensure(World *wo);
/* eevee_materials.c */ /* eevee_materials.c */
struct GPUTexture *EEVEE_materials_get_util_tex(void); /* XXX */ struct GPUTexture *EEVEE_materials_get_util_tex(void); /* XXX */
@@ -849,17 +826,37 @@ void EEVEE_lights_update(EEVEE_ViewLayerData *sldata);
void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl); void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl);
void EEVEE_lights_free(void); void EEVEE_lights_free(void);
/* eevee_lightprobes.c */ /* eevee_lightprobes.c */
bool EEVEE_lightprobes_obj_visibility_cb(bool vis_in, void *user_data); bool EEVEE_lightprobes_obj_visibility_cb(bool vis_in, void *user_data);
bool EEVEE_lightprobes_all_probes_ready(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, Object *ob); void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object *ob);
void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_lightprobes_refresh_planar(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_lightprobes_refresh_planar(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_lightprobes_free(void); void EEVEE_lightprobes_free(void);
void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, GPUTexture *rt_color, GPUTexture *rt_depth);
void EEVEE_lightbake_render_world(
EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, struct GPUFrameBuffer *face_fb[6]);
void EEVEE_lightbake_render_scene(
EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, struct GPUFrameBuffer *face_fb[6],
const float pos[3], float near_clip, float far_clip);
void EEVEE_lightbake_filter_glossy(
EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, struct GPUTexture *rt_color, struct GPUFrameBuffer *fb,
int probe_idx, float intensity, int maxlevel);
void EEVEE_lightbake_filter_diffuse(
EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, struct GPUTexture *rt_color, struct GPUFrameBuffer *fb,
int grid_offset, float intensity);
void EEVEE_lightbake_filter_visibility(
EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, struct GPUTexture *rt_depth, struct GPUFrameBuffer *fb,
int grid_offset, float clipsta, float clipend, float vis_range, float vis_blur, int vis_size);
void EEVEE_lightprobes_grid_data_from_object(Object *ob, EEVEE_LightGrid *prb_data, int *offset);
void EEVEE_lightprobes_cube_data_from_object(Object *ob, EEVEE_LightProbe *prb_data);
void EEVEE_lightprobes_planar_data_from_object(Object *ob, EEVEE_PlanarReflection *eplanar, EEVEE_LightProbeVisTest *vis_test);
/* eevee_depth_of_field.c */ /* eevee_depth_of_field.c */
int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object *camera); int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object *camera);
void EEVEE_depth_of_field_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_depth_of_field_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
@@ -948,6 +945,9 @@ void EEVEE_render_update_passes(struct RenderEngine *engine, struct Scene *scene
void EEVEE_lookdev_cache_init(EEVEE_Data *vedata, DRWShadingGroup **grp, GPUShader *shader, DRWPass *pass, struct World *world, EEVEE_LightProbesInfo *pinfo); void EEVEE_lookdev_cache_init(EEVEE_Data *vedata, DRWShadingGroup **grp, GPUShader *shader, DRWPass *pass, struct World *world, EEVEE_LightProbesInfo *pinfo);
void EEVEE_lookdev_draw_background(EEVEE_Data *vedata); void EEVEE_lookdev_draw_background(EEVEE_Data *vedata);
/** eevee_engine.c */
void EEVEE_cache_populate(void *vedata, Object *ob);
/* Shadow Matrix */ /* Shadow Matrix */
static const float texcomat[4][4] = { /* From NDC to TexCo */ static const float texcomat[4][4] = { /* From NDC to TexCo */
{0.5f, 0.0f, 0.0f, 0.0f}, {0.5f, 0.0f, 0.0f, 0.0f},

View File

@@ -134,17 +134,31 @@ void EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
EEVEE_volumes_cache_init(sldata, vedata); EEVEE_volumes_cache_init(sldata, vedata);
} }
/* Used by light cache. in this case engine is NULL. */
void EEVEE_render_cache( void EEVEE_render_cache(
void *vedata, struct Object *ob, void *vedata, struct Object *ob,
struct RenderEngine *engine, struct Depsgraph *UNUSED(depsgraph)) struct RenderEngine *engine, struct Depsgraph *UNUSED(depsgraph))
{ {
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure(); EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
EEVEE_LightProbesInfo *pinfo = sldata->probes;
char info[42];
BLI_snprintf(info, sizeof(info), "Syncing %s", ob->id.name + 2);
RE_engine_update_stats(engine, NULL, info);
bool cast_shadow = false; bool cast_shadow = false;
if (pinfo->vis_data.collection) {
/* Used for rendering probe with visibility groups. */
bool ob_vis = BKE_collection_has_object_recursive(pinfo->vis_data.collection, ob);
ob_vis = (pinfo->vis_data.invert) ? !ob_vis : ob_vis;
if (!ob_vis) {
return;
}
}
if (engine) {
char info[42];
BLI_snprintf(info, sizeof(info), "Syncing %s", ob->id.name + 2);
RE_engine_update_stats(engine, NULL, info);
}
if (ob->base_flag & BASE_VISIBLE) { if (ob->base_flag & BASE_VISIBLE) {
EEVEE_hair_cache_populate(vedata, sldata, ob, &cast_shadow); EEVEE_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
} }
@@ -154,7 +168,7 @@ void EEVEE_render_cache(
EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow); EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow);
} }
else if (ob->type == OB_LIGHTPROBE) { else if (ob->type == OB_LIGHTPROBE) {
EEVEE_lightprobes_cache_add(sldata, ob); EEVEE_lightprobes_cache_add(sldata, vedata, ob);
} }
else if (ob->type == OB_LAMP) { else if (ob->type == OB_LAMP) {
EEVEE_lights_cache_add(sldata, ob); EEVEE_lights_cache_add(sldata, ob);
@@ -477,14 +491,8 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
DRW_viewport_matrix_override_set(g_data->viewinv, DRW_MAT_VIEWINV); DRW_viewport_matrix_override_set(g_data->viewinv, DRW_MAT_VIEWINV);
/* Refresh Probes */ /* Refresh Probes */
while (EEVEE_lightprobes_all_probes_ready(sldata, vedata) == false) { RE_engine_update_stats(engine, NULL, "Updating Probes");
RE_engine_update_stats(engine, NULL, "Updating Probes"); EEVEE_lightprobes_refresh(sldata, vedata);
EEVEE_lightprobes_refresh(sldata, vedata);
/* Refreshing probes can take some times, allow exit. */
if (RE_engine_test_break(engine)) {
return;
}
}
EEVEE_lightprobes_refresh_planar(sldata, vedata); EEVEE_lightprobes_refresh_planar(sldata, vedata);
DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data); DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);

View File

@@ -187,6 +187,7 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v
EEVEE_StorageList *stl = vedata->stl; EEVEE_StorageList *stl = vedata->stl;
EEVEE_TextureList *txl = vedata->txl; EEVEE_TextureList *txl = vedata->txl;
EEVEE_EffectsInfo *effects = stl->effects; EEVEE_EffectsInfo *effects = stl->effects;
LightCache *lcache = stl->g_data->light_cache;
struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get(); struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get();
@@ -230,7 +231,7 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src); DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input); DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
DRW_shgroup_uniform_texture_ref(grp, "specroughBuffer", &effects->ssr_specrough_input); DRW_shgroup_uniform_texture_ref(grp, "specroughBuffer", &effects->ssr_specrough_input);
DRW_shgroup_uniform_texture_ref(grp, "probeCubes", &sldata->probe_pool); DRW_shgroup_uniform_texture_ref(grp, "probeCubes", &lcache->cube_tx.tex);
DRW_shgroup_uniform_texture_ref(grp, "probePlanars", &vedata->txl->planar_pool); DRW_shgroup_uniform_texture_ref(grp, "probePlanars", &vedata->txl->planar_pool);
DRW_shgroup_uniform_texture_ref(grp, "planarDepth", &vedata->txl->planar_depth); DRW_shgroup_uniform_texture_ref(grp, "planarDepth", &vedata->txl->planar_depth);
DRW_shgroup_uniform_texture_ref(grp, "hitBuffer", &effects->ssr_hit_output); DRW_shgroup_uniform_texture_ref(grp, "hitBuffer", &effects->ssr_hit_output);

View File

@@ -349,6 +349,7 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
EEVEE_StorageList *stl = vedata->stl; EEVEE_StorageList *stl = vedata->stl;
EEVEE_TextureList *txl = vedata->txl; EEVEE_TextureList *txl = vedata->txl;
EEVEE_EffectsInfo *effects = stl->effects; EEVEE_EffectsInfo *effects = stl->effects;
LightCache *lcache = stl->g_data->light_cache;
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data; EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) { if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
@@ -417,7 +418,7 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
psl->volumetric_scatter_ps = DRW_pass_create("Volumetric Scattering", DRW_STATE_WRITE_COLOR); psl->volumetric_scatter_ps = DRW_pass_create("Volumetric Scattering", DRW_STATE_WRITE_COLOR);
grp = DRW_shgroup_empty_tri_batch_create(scatter_sh, psl->volumetric_scatter_ps, grp = DRW_shgroup_empty_tri_batch_create(scatter_sh, psl->volumetric_scatter_ps,
common_data->vol_tex_size[2]); common_data->vol_tex_size[2]);
DRW_shgroup_uniform_texture_ref(grp, "irradianceGrid", &sldata->irradiance_pool); DRW_shgroup_uniform_texture_ref(grp, "irradianceGrid", &lcache->grid_tx.tex);
DRW_shgroup_uniform_texture_ref(grp, "shadowCubeTexture", &sldata->shadow_cube_pool); DRW_shgroup_uniform_texture_ref(grp, "shadowCubeTexture", &sldata->shadow_cube_pool);
DRW_shgroup_uniform_texture_ref(grp, "shadowCascadeTexture", &sldata->shadow_cascade_pool); DRW_shgroup_uniform_texture_ref(grp, "shadowCascadeTexture", &sldata->shadow_cascade_pool);
DRW_shgroup_uniform_texture_ref(grp, "volumeScattering", &txl->volume_prop_scattering); DRW_shgroup_uniform_texture_ref(grp, "volumeScattering", &txl->volume_prop_scattering);

View File

@@ -1,15 +1,18 @@
flat in int pid; flat in int pid;
in vec3 worldNormal; in vec2 quadCoord;
in vec3 worldPosition;
out vec4 FragColor; out vec4 FragColor;
void main() void main()
{ {
vec3 V = (ProjectionMatrix[3][3] == 0.0) /* if perspective */ float dist_sqr = dot(quadCoord, quadCoord);
? normalize(cameraPos - worldPosition)
: cameraForward; /* Discard outside the circle. */
vec3 N = normalize(worldNormal); if (dist_sqr > 1.0)
FragColor = vec4(textureLod_octahedron(probeCubes, vec4(reflect(-V, N), pid), 0.0, prbLodCubeMax).rgb, 1.0); discard;
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);
} }

View File

@@ -1,26 +1,43 @@
in vec3 pos; /* XXX TODO fix code duplication */
struct CubeData {
vec4 position_type;
vec4 attenuation_fac_type;
mat4 influencemat;
mat4 parallaxmat;
};
/* Instance attrib */ layout(std140) uniform probe_block {
in int probe_id; CubeData probes_data[MAX_PROBE];
in vec3 probe_location; };
in float sphere_size;
uniform float sphere_size;
uniform vec3 screen_vecs[2];
flat out int pid; flat out int pid;
out vec3 worldNormal; out vec2 quadCoord;
out vec3 worldPosition;
const vec2 pos[6] = vec2[6](
vec2(-1.0, -1.0),
vec2( 1.0, -1.0),
vec2(-1.0, 1.0),
vec2( 1.0, -1.0),
vec2( 1.0, 1.0),
vec2(-1.0, 1.0)
);
void main() void main()
{ {
pid = probe_id; pid = 1 + (gl_VertexID / 6); /* +1 for the world */
int vert_id = gl_VertexID % 6;
/* While this is not performant, we do this to quadCoord = pos[vert_id];
* match the object mode engine instancing shader. */
mat4 offsetmat = mat4(1.0); /* Identity */
offsetmat[3].xyz = probe_location;
vec4 wpos = offsetmat * vec4(pos * sphere_size, 1.0); vec3 ws_location = probes_data[pid].position_type.xyz;
worldPosition = wpos.xyz; vec3 screen_pos = screen_vecs[0] * quadCoord.x + screen_vecs[1] * quadCoord.y;
gl_Position = ViewProjectionMatrix * wpos; ws_location += screen_pos * sphere_size;
worldNormal = normalize(pos);
gl_Position = ViewProjectionMatrix * vec4(ws_location, 1.0);
gl_Position.z += 0.0001; /* Small bias to let the icon draw without zfighting */
} }

View File

@@ -1,11 +1,19 @@
flat in int cellOffset; flat in int cellOffset;
in vec3 worldNormal; in vec2 quadCoord;
out vec4 FragColor; out vec4 FragColor;
void main() void main()
{ {
IrradianceData ir_data = load_irradiance_cell(cellOffset, worldNormal); float dist_sqr = dot(quadCoord, quadCoord);
FragColor = vec4(compute_irradiance(worldNormal, ir_data), 1.0);
/* Discard outside the circle. */
if (dist_sqr > 1.0)
discard;
vec3 view_nor = vec3(quadCoord, sqrt(max(0.0, 1.0 - dist_sqr)));
vec3 world_nor = mat3(ViewMatrixInverse) * view_nor;
IrradianceData ir_data = load_irradiance_cell(cellOffset, world_nor);
FragColor = vec4(compute_irradiance(world_nor, ir_data), 1.0);
} }

View File

@@ -1,6 +1,4 @@
in vec3 pos;
uniform float sphere_size; uniform float sphere_size;
uniform int offset; uniform int offset;
uniform ivec3 grid_resolution; uniform ivec3 grid_resolution;
@@ -8,25 +6,44 @@ uniform vec3 corner;
uniform vec3 increment_x; uniform vec3 increment_x;
uniform vec3 increment_y; uniform vec3 increment_y;
uniform vec3 increment_z; uniform vec3 increment_z;
uniform vec3 screen_vecs[2];
flat out int cellOffset; flat out int cellOffset;
out vec3 worldNormal; out vec2 quadCoord;
const vec2 pos[6] = vec2[6](
vec2(-1.0, -1.0),
vec2( 1.0, -1.0),
vec2(-1.0, 1.0),
vec2( 1.0, -1.0),
vec2( 1.0, 1.0),
vec2(-1.0, 1.0)
);
void main() void main()
{ {
int cell_id = gl_VertexID / 6;
int vert_id = gl_VertexID % 6;
vec3 ls_cell_location; vec3 ls_cell_location;
/* Keep in sync with update_irradiance_probe */ /* Keep in sync with update_irradiance_probe */
ls_cell_location.z = float(gl_InstanceID % grid_resolution.z); ls_cell_location.z = float(cell_id % grid_resolution.z);
ls_cell_location.y = float((gl_InstanceID / grid_resolution.z) % grid_resolution.y); ls_cell_location.y = float((cell_id / grid_resolution.z) % grid_resolution.y);
ls_cell_location.x = float(gl_InstanceID / (grid_resolution.z * grid_resolution.y)); ls_cell_location.x = float(cell_id / (grid_resolution.z * grid_resolution.y));
cellOffset = offset + gl_InstanceID; cellOffset = offset + cell_id;
vec3 ws_cell_location = corner + vec3 ws_cell_location = corner +
(increment_x * ls_cell_location.x + (increment_x * ls_cell_location.x +
increment_y * ls_cell_location.y + increment_y * ls_cell_location.y +
increment_z * ls_cell_location.z); increment_z * ls_cell_location.z);
gl_Position = ViewProjectionMatrix * vec4(pos * 0.02 * sphere_size + ws_cell_location, 1.0);
worldNormal = normalize(pos); quadCoord = pos[vert_id];
vec3 screen_pos = screen_vecs[0] * quadCoord.x + screen_vecs[1] * quadCoord.y;
ws_cell_location += screen_pos * sphere_size;
gl_Position = ViewProjectionMatrix * vec4(ws_cell_location , 1.0);
gl_Position.z += 0.0001; /* Small bias to let the icon draw without zfighting */
} }

View File

@@ -27,6 +27,7 @@ struct PlanarData {
vec4 clip_edges; vec4 clip_edges;
vec4 facing_scale_bias; vec4 facing_scale_bias;
mat4 reflectionmat; /* transform world space into reflection texture space */ mat4 reflectionmat; /* transform world space into reflection texture space */
mat4 unused;
}; };
#define pl_plane_eq plane_equation #define pl_plane_eq plane_equation

View File

@@ -256,7 +256,7 @@ void CLOSURE_NAME(
PlanarData pd = planars_data[i]; PlanarData pd = planars_data[i];
/* Fade on geometric normal. */ /* Fade on geometric normal. */
float fade = probe_attenuation_planar(pd, worldPosition, worldNormal, roughness); float fade = probe_attenuation_planar(pd, worldPosition, (gl_FrontFacing) ? worldNormal : -worldNormal, roughness);
if (fade > 0.0) { if (fade > 0.0) {
if (!(ssrToggle && ssr_id == outputSsrId)) { if (!(ssrToggle && ssr_id == outputSsrId)) {
@@ -404,7 +404,7 @@ void CLOSURE_NAME(
spec_occlu = 1.0; spec_occlu = 1.0;
} }
out_spec += spec_accum.rgb * ssr_spec * spec_occlu * float(specToggle); out_spec += spec_accum.rgb * ssr_spec * spec_occlu;
#endif #endif
#ifdef CLOSURE_REFRACTION #ifdef CLOSURE_REFRACTION
@@ -419,7 +419,12 @@ void CLOSURE_NAME(
vec2 C_brdf_lut = texture(utilTex, vec3(C_uv, 1.0)).rg; vec2 C_brdf_lut = texture(utilTex, vec3(C_uv, 1.0)).rg;
vec3 C_fresnel = F_ibl(vec3(0.04), brdf_lut) * specular_occlusion(NV, final_ao, C_roughness); vec3 C_fresnel = F_ibl(vec3(0.04), brdf_lut) * specular_occlusion(NV, final_ao, C_roughness);
out_spec += C_spec_accum.rgb * C_fresnel * float(specToggle) * C_intensity; out_spec += C_spec_accum.rgb * C_fresnel * C_intensity;
#endif
#ifdef CLOSURE_GLOSSY
/* Global toggle for lightprobe baking. */
out_spec *= float(specToggle);
#endif #endif
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */

View File

@@ -258,9 +258,9 @@ static struct GPUTexture *create_jitter_texture(int num_samples)
/* Functions */ /* Functions */
static void workbench_init_object_data(ObjectEngineData *engine_data) static void workbench_init_object_data(DrawData *dd)
{ {
WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)engine_data; WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)dd;
data->object_id = ((e_data.next_object_id++) & 0xff) + 1; data->object_id = ((e_data.next_object_id++) & 0xff) + 1;
data->shadow_bbox_dirty = true; data->shadow_bbox_dirty = true;
} }
@@ -561,8 +561,8 @@ static WORKBENCH_MaterialData *get_or_create_material_data(
WORKBENCH_PassList *psl = vedata->psl; WORKBENCH_PassList *psl = vedata->psl;
WORKBENCH_PrivateData *wpd = stl->g_data; WORKBENCH_PrivateData *wpd = stl->g_data;
WORKBENCH_MaterialData *material; WORKBENCH_MaterialData *material;
WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_object_engine_data_ensure( WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_drawdata_ensure(
ob, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL); &ob->id, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL);
WORKBENCH_MaterialData material_template; WORKBENCH_MaterialData material_template;
/* Solid */ /* Solid */
@@ -731,8 +731,8 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
// DRW_shgroup_call_sculpt_add(wpd->shadow_shgrp, ob, ob->obmat); // DRW_shgroup_call_sculpt_add(wpd->shadow_shgrp, ob, ob->obmat);
} }
else { else {
WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_object_engine_data_ensure( WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_drawdata_ensure(
ob, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL); &ob->id, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL);
if (studiolight_object_cast_visible_shadow(wpd, ob, engine_object_data)) { if (studiolight_object_cast_visible_shadow(wpd, ob, engine_object_data)) {

View File

@@ -126,9 +126,9 @@ static char *workbench_build_forward_composite_frag(void)
return str; return str;
} }
static void workbench_init_object_data(ObjectEngineData *engine_data) static void workbench_init_object_data(DrawData *dd)
{ {
WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)engine_data; WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)dd;
data->object_id = ((e_data.next_object_id++) & 0xff) + 1; data->object_id = ((e_data.next_object_id++) & 0xff) + 1;
} }
@@ -139,8 +139,8 @@ static WORKBENCH_MaterialData *get_or_create_material_data(
WORKBENCH_PassList *psl = vedata->psl; WORKBENCH_PassList *psl = vedata->psl;
WORKBENCH_PrivateData *wpd = stl->g_data; WORKBENCH_PrivateData *wpd = stl->g_data;
WORKBENCH_MaterialData *material; WORKBENCH_MaterialData *material;
WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_object_engine_data_ensure( WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_drawdata_ensure(
ob, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL); &ob->id, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL);
WORKBENCH_MaterialData material_template; WORKBENCH_MaterialData material_template;
DRWShadingGroup *grp; DRWShadingGroup *grp;

View File

@@ -201,12 +201,8 @@ typedef struct WORKBENCH_MaterialData {
} WORKBENCH_MaterialData; } WORKBENCH_MaterialData;
typedef struct WORKBENCH_ObjectData { typedef struct WORKBENCH_ObjectData {
struct ObjectEngineData *next, *prev; DrawData dd;
struct DrawEngineType *engine_type;
/* Only nested data, NOT the engine data itself. */
ObjectEngineDataFreeCb free;
/* Accumulated recalc flags, which corresponds to ID->recalc flags. */
int recalc;
/* Shadow direction in local object space. */ /* Shadow direction in local object space. */
float shadow_dir[3], shadow_depth; float shadow_dir[3], shadow_depth;
float shadow_min[3], shadow_max[3]; /* Min, max in shadow space */ float shadow_min[3], shadow_max[3]; /* Min, max in shadow space */

View File

@@ -44,6 +44,7 @@
#include "DNA_lamp_types.h" #include "DNA_lamp_types.h"
#include "DNA_material_types.h" #include "DNA_material_types.h"
#include "DNA_scene_types.h" #include "DNA_scene_types.h"
#include "DNA_world_types.h"
#include "GPU_framebuffer.h" #include "GPU_framebuffer.h"
#include "GPU_texture.h" #include "GPU_texture.h"
@@ -239,14 +240,14 @@ struct GPUShader *DRW_shader_create_2D(const char *frag, const char *defines);
struct GPUShader *DRW_shader_create_3D(const char *frag, const char *defines); struct GPUShader *DRW_shader_create_3D(const char *frag, const char *defines);
struct GPUShader *DRW_shader_create_fullscreen(const char *frag, const char *defines); struct GPUShader *DRW_shader_create_fullscreen(const char *frag, const char *defines);
struct GPUShader *DRW_shader_create_3D_depth_only(void); struct GPUShader *DRW_shader_create_3D_depth_only(void);
struct GPUMaterial *DRW_shader_find_from_world(struct World *wo, const void *engine_type, int options); struct GPUMaterial *DRW_shader_find_from_world(struct World *wo, const void *engine_type, int options, bool no_deferred);
struct GPUMaterial *DRW_shader_find_from_material(struct Material *ma, const void *engine_type, int options); struct GPUMaterial *DRW_shader_find_from_material(struct Material *ma, const void *engine_type, int options, bool no_deferred);
struct GPUMaterial *DRW_shader_create_from_world( struct GPUMaterial *DRW_shader_create_from_world(
struct Scene *scene, struct World *wo, const void *engine_type, int options, struct Scene *scene, struct World *wo, const void *engine_type, int options,
const char *vert, const char *geom, const char *frag_lib, const char *defines); const char *vert, const char *geom, const char *frag_lib, const char *defines, bool no_deferred);
struct GPUMaterial *DRW_shader_create_from_material( struct GPUMaterial *DRW_shader_create_from_material(
struct Scene *scene, struct Material *ma, const void *engine_type, int options, struct Scene *scene, struct Material *ma, const void *engine_type, int options,
const char *vert, const char *geom, const char *frag_lib, const char *defines); const char *vert, const char *geom, const char *frag_lib, const char *defines, bool no_deferred);
void DRW_shader_free(struct GPUShader *shader); void DRW_shader_free(struct GPUShader *shader);
#define DRW_SHADER_FREE_SAFE(shader) do { \ #define DRW_SHADER_FREE_SAFE(shader) do { \
if (shader != NULL) { \ if (shader != NULL) { \
@@ -409,6 +410,7 @@ void DRW_pass_sort_shgroup_z(DRWPass *pass);
/* Viewport */ /* Viewport */
typedef enum { typedef enum {
/* keep in sync with the union struct DRWMatrixState. */
DRW_MAT_PERS = 0, DRW_MAT_PERS = 0,
DRW_MAT_PERSINV, DRW_MAT_PERSINV,
DRW_MAT_VIEW, DRW_MAT_VIEW,
@@ -420,7 +422,18 @@ typedef enum {
} DRWViewportMatrixType; } DRWViewportMatrixType;
typedef struct DRWMatrixState { typedef struct DRWMatrixState {
float mat[DRW_MAT_COUNT][4][4]; union {
float mat[DRW_MAT_COUNT][4][4];
struct {
/* keep in sync with the enum DRWViewportMatrixType. */
float persmat[4][4];
float persinv[4][4];
float viewmat[4][4];
float viewinv[4][4];
float winmat[4][4];
float wininv[4][4];
};
};
} DRWMatrixState; } DRWMatrixState;
void DRW_viewport_init(const bContext *C); void DRW_viewport_init(const bContext *C);
@@ -453,6 +466,12 @@ void DRW_render_object_iter(
void (*callback)(void *vedata, struct Object *ob, struct RenderEngine *engine, struct Depsgraph *depsgraph)); void (*callback)(void *vedata, struct Object *ob, struct RenderEngine *engine, struct Depsgraph *depsgraph));
void DRW_render_instance_buffer_finish(void); void DRW_render_instance_buffer_finish(void);
void DRW_custom_pipeline(
DrawEngineType *draw_engine_type,
struct Depsgraph *depsgraph,
void (*callback)(void *vedata, void *user_data),
void *user_data);
/* ViewLayers */ /* ViewLayers */
void *DRW_view_layer_engine_data_get(DrawEngineType *engine_type); void *DRW_view_layer_engine_data_get(DrawEngineType *engine_type);
void **DRW_view_layer_engine_data_ensure_ex( void **DRW_view_layer_engine_data_ensure_ex(
@@ -460,16 +479,14 @@ void **DRW_view_layer_engine_data_ensure_ex(
void **DRW_view_layer_engine_data_ensure( void **DRW_view_layer_engine_data_ensure(
DrawEngineType *engine_type, void (*callback)(void *storage)); DrawEngineType *engine_type, void (*callback)(void *storage));
/* Objects */ /* DrawData */
ObjectEngineData *DRW_object_engine_data_get(Object *ob, DrawEngineType *engine_type); DrawData *DRW_drawdata_get(ID *ib, DrawEngineType *engine_type);
ObjectEngineData *DRW_object_engine_data_ensure( DrawData *DRW_drawdata_ensure(
Object *ob, ID *id,
DrawEngineType *engine_type, DrawEngineType *engine_type,
size_t size, size_t size,
ObjectEngineDataInitCb init_cb, DrawDataInitCb init_cb,
ObjectEngineDataFreeCb free_cb); DrawDataFreeCb free_cb);
struct LampEngineData *DRW_lamp_engine_data_ensure(Object *ob, struct RenderEngineType *engine_type);
void DRW_lamp_engine_data_free(struct LampEngineData *led);
/* Settings */ /* Settings */
bool DRW_object_is_renderable(struct Object *ob); bool DRW_object_is_renderable(struct Object *ob);

View File

@@ -44,6 +44,7 @@
#include "DNA_camera_types.h" #include "DNA_camera_types.h"
#include "DNA_mesh_types.h" #include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h" #include "DNA_meshdata_types.h"
#include "DNA_world_types.h"
#include "ED_space_api.h" #include "ED_space_api.h"
#include "ED_screen.h" #include "ED_screen.h"
@@ -696,34 +697,96 @@ void **DRW_view_layer_engine_data_ensure(DrawEngineType *engine_type, void (*cal
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
/** \name Objects (DRW_object) /** \name Draw Data (DRW_drawdata)
* \{ */ * \{ */
ObjectEngineData *DRW_object_engine_data_get(Object *ob, DrawEngineType *engine_type) /* Used for DRW_drawdata_from_id()
* All ID-datablocks which have their own 'local' DrawData
* should have the same arrangement in their structs.
*/
typedef struct IdDdtTemplate {
ID id;
struct AnimData *adt;
DrawDataList drawdata;
} IdDdtTemplate;
/* Check if ID can have AnimData */
static bool id_type_can_have_drawdata(const short id_type)
{ {
for (ObjectEngineData *oed = ob->drawdata.first; oed; oed = oed->next) { /* Only some ID-blocks have this info for now */
if (oed->engine_type == engine_type) { /* TODO: finish adding this for the other blocktypes */
return oed; switch (id_type) {
/* has DrawData */
case ID_OB:
case ID_WO:
return true;
/* no DrawData */
default:
return false;
}
}
static bool id_can_have_drawdata(const ID *id)
{
/* sanity check */
if (id == NULL)
return false;
return id_type_can_have_drawdata(GS(id->name));
}
/* Get DrawData from the given ID-block. In order for this to work, we assume that
* the DrawData pointer is stored in the struct in the same fashion as in IdDdtTemplate.
*/
DrawDataList *DRW_drawdatalist_from_id(ID *id)
{
/* only some ID-blocks have this info for now, so we cast the
* types that do to be of type IdDdtTemplate, and extract the
* DrawData that way
*/
if (id_can_have_drawdata(id)) {
IdDdtTemplate *idt = (IdDdtTemplate *)id;
return &idt->drawdata;
}
else
return NULL;
}
DrawData *DRW_drawdata_get(ID *id, DrawEngineType *engine_type)
{
DrawDataList *drawdata = DRW_drawdatalist_from_id(id);
if (drawdata == NULL)
return NULL;
LISTBASE_FOREACH(DrawData *, dd, drawdata) {
if (dd->engine_type == engine_type) {
return dd;
} }
} }
return NULL; return NULL;
} }
ObjectEngineData *DRW_object_engine_data_ensure( DrawData *DRW_drawdata_ensure(
Object *ob, ID *id,
DrawEngineType *engine_type, DrawEngineType *engine_type,
size_t size, size_t size,
ObjectEngineDataInitCb init_cb, DrawDataInitCb init_cb,
ObjectEngineDataFreeCb free_cb) DrawDataFreeCb free_cb)
{ {
BLI_assert(size >= sizeof(ObjectEngineData)); BLI_assert(size >= sizeof(DrawData));
BLI_assert(id_can_have_drawdata(id));
/* Try to re-use existing data. */ /* Try to re-use existing data. */
ObjectEngineData *oed = DRW_object_engine_data_get(ob, engine_type); DrawData *dd = DRW_drawdata_get(id, engine_type);
if (oed != NULL) { if (dd != NULL) {
return oed; return dd;
} }
DrawDataList *drawdata = DRW_drawdatalist_from_id(id);
/* Allocate new data. */ /* Allocate new data. */
if ((ob->base_flag & BASE_FROMDUPLI) != 0) { if ((GS(id->name) == ID_OB) && (((Object *)id)->base_flag & BASE_FROMDUPLI) != 0) {
/* NOTE: data is not persistent in this case. It is reset each redraw. */ /* NOTE: data is not persistent in this case. It is reset each redraw. */
BLI_assert(free_cb == NULL); /* No callback allowed. */ BLI_assert(free_cb == NULL); /* No callback allowed. */
/* Round to sizeof(float) for DRW_instance_data_request(). */ /* Round to sizeof(float) for DRW_instance_data_request(). */
@@ -734,21 +797,37 @@ ObjectEngineData *DRW_object_engine_data_ensure(
if (DST.object_instance_data[fsize] == NULL) { if (DST.object_instance_data[fsize] == NULL) {
DST.object_instance_data[fsize] = DRW_instance_data_request(DST.idatalist, fsize); DST.object_instance_data[fsize] = DRW_instance_data_request(DST.idatalist, fsize);
} }
oed = (ObjectEngineData *)DRW_instance_data_next(DST.object_instance_data[fsize]); dd = (DrawData *)DRW_instance_data_next(DST.object_instance_data[fsize]);
memset(oed, 0, size); memset(dd, 0, size);
} }
else { else {
oed = MEM_callocN(size, "ObjectEngineData"); dd = MEM_callocN(size, "DrawData");
} }
oed->engine_type = engine_type; dd->engine_type = engine_type;
oed->free = free_cb; dd->free = free_cb;
/* Perform user-side initialization, if needed. */ /* Perform user-side initialization, if needed. */
if (init_cb != NULL) { if (init_cb != NULL) {
init_cb(oed); init_cb(dd);
} }
/* Register in the list. */ /* Register in the list. */
BLI_addtail(&ob->drawdata, oed); BLI_addtail((ListBase *)drawdata, dd);
return oed; return dd;
}
void DRW_drawdata_free(ID *id)
{
DrawDataList *drawdata = DRW_drawdatalist_from_id(id);
if (drawdata == NULL)
return;
LISTBASE_FOREACH(DrawData *, dd, drawdata) {
if (dd->free != NULL) {
dd->free(dd);
}
}
BLI_freelistN((ListBase *)drawdata);
} }
/** \} */ /** \} */
@@ -794,6 +873,22 @@ static void drw_engines_cache_init(void)
} }
} }
static void drw_engines_world_update(Scene *scene)
{
if (scene->world == NULL) {
return;
}
for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
DrawEngineType *engine = link->data;
ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
if (engine->id_update) {
engine->id_update(data, &scene->world->id);
}
}
}
static void drw_engines_cache_populate(Object *ob) static void drw_engines_cache_populate(Object *ob)
{ {
DST.ob_state = NULL; DST.ob_state = NULL;
@@ -1161,7 +1256,7 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
/* XXX Really nasty locking. But else this could /* XXX Really nasty locking. But else this could
* be executed by the material previews thread * be executed by the material previews thread
* while rendering a viewport. */ * while rendering a viewport. */
BLI_mutex_lock(&DST.gl_context_mutex); BLI_ticket_mutex_lock(DST.gl_context_mutex);
/* Reset before using it. */ /* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST); drw_state_prepare_clean_for_draw(&DST);
@@ -1189,7 +1284,7 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
drw_engines_disable(); drw_engines_disable();
BLI_mutex_unlock(&DST.gl_context_mutex); BLI_ticket_mutex_unlock(DST.gl_context_mutex);
} }
} }
@@ -1273,6 +1368,7 @@ void DRW_draw_render_loop_ex(
{ {
PROFILE_START(stime); PROFILE_START(stime);
drw_engines_cache_init(); drw_engines_cache_init();
drw_engines_world_update(scene);
const int object_type_exclude_viewport = v3d->object_type_exclude_viewport; const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob) DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob)
@@ -1458,14 +1554,10 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
/* Changing Context */ /* Changing Context */
if (re_gl_context != NULL) { if (re_gl_context != NULL) {
/* TODO get rid of the blocking. Only here because of the static global DST. */ DRW_opengl_render_context_enable(re_gl_context);
BLI_mutex_lock(&DST.gl_context_mutex); /* We need to query gwn context after a gl context has been bound. */
WM_opengl_context_activate(re_gl_context);
re_gwn_context = RE_gwn_context_get(render); re_gwn_context = RE_gwn_context_get(render);
if (GWN_context_active_get() == NULL) { DRW_gawain_render_context_enable(re_gwn_context);
GWN_context_active_set(re_gwn_context);
}
DRW_shape_cache_reset(); /* XXX fix that too. */
} }
else { else {
DRW_opengl_context_enable(); DRW_opengl_context_enable();
@@ -1544,12 +1636,8 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
/* Changing Context */ /* Changing Context */
if (re_gl_context != NULL) { if (re_gl_context != NULL) {
DRW_shape_cache_reset(); /* XXX fix that too. */ DRW_gawain_render_context_disable(re_gwn_context);
glFlush(); DRW_opengl_render_context_disable(re_gl_context);
GWN_context_active_set(NULL);
WM_opengl_context_release(re_gl_context);
/* TODO get rid of the blocking. */
BLI_mutex_unlock(&DST.gl_context_mutex);
} }
else { else {
DRW_opengl_context_disable(); DRW_opengl_context_disable();
@@ -1575,6 +1663,56 @@ void DRW_render_object_iter(
DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END
} }
/* Assume a valid gl context is bound (and that the gl_context_mutex has been aquired).
* This function only setup DST and execute the given function.
* Warning: similar to DRW_render_to_image you cannot use default lists (dfbl & dtxl). */
void DRW_custom_pipeline(
DrawEngineType *draw_engine_type,
struct Depsgraph *depsgraph,
void (*callback)(void *vedata, void *user_data),
void *user_data)
{
Scene *scene = DEG_get_evaluated_scene(depsgraph);
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
DST.options.is_image_render = true;
DST.options.is_scene_render = true;
DST.options.draw_background = false;
DST.draw_ctx = (DRWContextState){
.scene = scene,
.view_layer = view_layer,
.engine_type = NULL,
.depsgraph = depsgraph,
.object_mode = OB_MODE_OBJECT,
};
drw_context_state_init();
DST.viewport = GPU_viewport_create();
const int size[2] = {1, 1};
GPU_viewport_size_set(DST.viewport, size);
drw_viewport_var_init();
DRW_hair_init();
ViewportEngineData *data = drw_viewport_engine_data_ensure(draw_engine_type);
/* Execute the callback */
callback(data, user_data);
DST.buffer_finish_called = false;
GPU_viewport_free(DST.viewport);
GPU_framebuffer_restore();
#ifdef DEBUG
/* Avoid accidental reuse. */
drw_state_ensure_not_reused(&DST);
#endif
}
static struct DRWSelectBuffer { static struct DRWSelectBuffer {
struct GPUFrameBuffer *framebuffer; struct GPUFrameBuffer *framebuffer;
struct GPUTexture *texture_depth; struct GPUTexture *texture_depth;
@@ -1697,6 +1835,7 @@ void DRW_draw_select_loop(
{ {
drw_engines_cache_init(); drw_engines_cache_init();
drw_engines_world_update(scene);
if (use_obedit) { if (use_obedit) {
#if 0 #if 0
@@ -1891,6 +2030,7 @@ void DRW_draw_depth_loop(
{ {
drw_engines_cache_init(); drw_engines_cache_init();
drw_engines_world_update(scene);
const int object_type_exclude_viewport = v3d->object_type_exclude_viewport; const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob) DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob)
@@ -2182,7 +2322,7 @@ void DRW_opengl_context_create(void)
{ {
BLI_assert(DST.gl_context == NULL); /* Ensure it's called once */ BLI_assert(DST.gl_context == NULL); /* Ensure it's called once */
BLI_mutex_init(&DST.gl_context_mutex); DST.gl_context_mutex = BLI_ticket_mutex_alloc();
if (!G.background) { if (!G.background) {
immDeactivate(); immDeactivate();
} }
@@ -2207,7 +2347,7 @@ void DRW_opengl_context_destroy(void)
GWN_context_active_set(DST.gwn_context); GWN_context_active_set(DST.gwn_context);
GWN_context_discard(DST.gwn_context); GWN_context_discard(DST.gwn_context);
WM_opengl_context_dispose(DST.gl_context); WM_opengl_context_dispose(DST.gl_context);
BLI_mutex_end(&DST.gl_context_mutex); BLI_ticket_mutex_free(DST.gl_context_mutex);
} }
} }
@@ -2217,7 +2357,7 @@ void DRW_opengl_context_enable(void)
/* IMPORTANT: We dont support immediate mode in render mode! /* IMPORTANT: We dont support immediate mode in render mode!
* This shall remain in effect until immediate mode supports * This shall remain in effect until immediate mode supports
* multiple threads. */ * multiple threads. */
BLI_mutex_lock(&DST.gl_context_mutex); BLI_ticket_mutex_lock(DST.gl_context_mutex);
if (BLI_thread_is_main()) { if (BLI_thread_is_main()) {
if (!G.background) { if (!G.background) {
immDeactivate(); immDeactivate();
@@ -2251,8 +2391,43 @@ void DRW_opengl_context_disable(void)
GWN_context_active_set(NULL); GWN_context_active_set(NULL);
} }
BLI_mutex_unlock(&DST.gl_context_mutex); BLI_ticket_mutex_unlock(DST.gl_context_mutex);
} }
} }
void DRW_opengl_render_context_enable(void *re_gl_context)
{
/* If thread is main you should use DRW_opengl_context_enable(). */
BLI_assert(!BLI_thread_is_main());
/* TODO get rid of the blocking. Only here because of the static global DST. */
BLI_ticket_mutex_lock(DST.gl_context_mutex);
WM_opengl_context_activate(re_gl_context);
}
void DRW_opengl_render_context_disable(void *re_gl_context)
{
glFlush();
WM_opengl_context_release(re_gl_context);
/* TODO get rid of the blocking. */
BLI_ticket_mutex_unlock(DST.gl_context_mutex);
}
/* Needs to be called AFTER DRW_opengl_render_context_enable() */
void DRW_gawain_render_context_enable(void *re_gwn_context)
{
/* If thread is main you should use DRW_opengl_context_enable(). */
BLI_assert(!BLI_thread_is_main());
GWN_context_active_set(re_gwn_context);
DRW_shape_cache_reset(); /* XXX fix that too. */
}
/* Needs to be called BEFORE DRW_opengl_render_context_disable() */
void DRW_gawain_render_context_disable(void *UNUSED(re_gwn_context))
{
DRW_shape_cache_reset(); /* XXX fix that too. */
GWN_context_active_set(NULL);
}
/** \} */ /** \} */

View File

@@ -373,7 +373,7 @@ typedef struct DRWManager {
* the top portion of the struct so DO NOT MOVE IT! */ * the top portion of the struct so DO NOT MOVE IT! */
void *gl_context; /* Unique ghost context used by the draw manager. */ void *gl_context; /* Unique ghost context used by the draw manager. */
Gwn_Context *gwn_context; Gwn_Context *gwn_context;
ThreadMutex gl_context_mutex; /* Mutex to lock the drw manager and avoid concurent context usage. */ TicketMutex *gl_context_mutex; /* Mutex to lock the drw manager and avoid concurent context usage. */
/** GPU Resource State: Memory storage between drawing. */ /** GPU Resource State: Memory storage between drawing. */
struct { struct {

View File

@@ -154,10 +154,10 @@ static void drw_deferred_shader_compilation_free(void *custom_data)
MEM_freeN(comp); MEM_freeN(comp);
} }
static void drw_deferred_shader_add(GPUMaterial *mat) static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred)
{ {
/* Do not deferre the compilation if we are rendering for image. */ /* Do not deferre the compilation if we are rendering for image. */
if (DRW_state_is_image_render() || !USE_DEFERRED_COMPILATION) { if (DRW_state_is_image_render() || !USE_DEFERRED_COMPILATION || !deferred) {
/* Double checking that this GPUMaterial is not going to be /* Double checking that this GPUMaterial is not going to be
* compiled by another thread. */ * compiled by another thread. */
DRW_deferred_shader_remove(mat); DRW_deferred_shader_remove(mat);
@@ -308,10 +308,10 @@ GPUShader *DRW_shader_create_3D_depth_only(void)
return GPU_shader_get_builtin_shader(GPU_SHADER_3D_DEPTH_ONLY); return GPU_shader_get_builtin_shader(GPU_SHADER_3D_DEPTH_ONLY);
} }
GPUMaterial *DRW_shader_find_from_world(World *wo, const void *engine_type, int options) GPUMaterial *DRW_shader_find_from_world(World *wo, const void *engine_type, int options, bool deferred)
{ {
GPUMaterial *mat = GPU_material_from_nodetree_find(&wo->gpumaterial, engine_type, options); GPUMaterial *mat = GPU_material_from_nodetree_find(&wo->gpumaterial, engine_type, options);
if (DRW_state_is_image_render()) { if (DRW_state_is_image_render() || !deferred) {
if (mat != NULL && GPU_material_status(mat) == GPU_MAT_QUEUED) { if (mat != NULL && GPU_material_status(mat) == GPU_MAT_QUEUED) {
/* XXX Hack : we return NULL so that the engine will call DRW_shader_create_from_XXX /* XXX Hack : we return NULL so that the engine will call DRW_shader_create_from_XXX
* with the shader code and we will resume the compilation from there. */ * with the shader code and we will resume the compilation from there. */
@@ -321,10 +321,10 @@ GPUMaterial *DRW_shader_find_from_world(World *wo, const void *engine_type, int
return mat; return mat;
} }
GPUMaterial *DRW_shader_find_from_material(Material *ma, const void *engine_type, int options) GPUMaterial *DRW_shader_find_from_material(Material *ma, const void *engine_type, int options, bool deferred)
{ {
GPUMaterial *mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine_type, options); GPUMaterial *mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine_type, options);
if (DRW_state_is_image_render()) { if (DRW_state_is_image_render() || !deferred) {
if (mat != NULL && GPU_material_status(mat) == GPU_MAT_QUEUED) { if (mat != NULL && GPU_material_status(mat) == GPU_MAT_QUEUED) {
/* XXX Hack : we return NULL so that the engine will call DRW_shader_create_from_XXX /* XXX Hack : we return NULL so that the engine will call DRW_shader_create_from_XXX
* with the shader code and we will resume the compilation from there. */ * with the shader code and we will resume the compilation from there. */
@@ -336,7 +336,7 @@ GPUMaterial *DRW_shader_find_from_material(Material *ma, const void *engine_type
GPUMaterial *DRW_shader_create_from_world( GPUMaterial *DRW_shader_create_from_world(
struct Scene *scene, World *wo, const void *engine_type, int options, struct Scene *scene, World *wo, const void *engine_type, int options,
const char *vert, const char *geom, const char *frag_lib, const char *defines) const char *vert, const char *geom, const char *frag_lib, const char *defines, bool deferred)
{ {
GPUMaterial *mat = NULL; GPUMaterial *mat = NULL;
if (DRW_state_is_image_render()) { if (DRW_state_is_image_render()) {
@@ -350,7 +350,7 @@ GPUMaterial *DRW_shader_create_from_world(
} }
if (GPU_material_status(mat) == GPU_MAT_QUEUED) { if (GPU_material_status(mat) == GPU_MAT_QUEUED) {
drw_deferred_shader_add(mat); drw_deferred_shader_add(mat, deferred);
} }
return mat; return mat;
@@ -358,7 +358,7 @@ GPUMaterial *DRW_shader_create_from_world(
GPUMaterial *DRW_shader_create_from_material( GPUMaterial *DRW_shader_create_from_material(
struct Scene *scene, Material *ma, const void *engine_type, int options, struct Scene *scene, Material *ma, const void *engine_type, int options,
const char *vert, const char *geom, const char *frag_lib, const char *defines) const char *vert, const char *geom, const char *frag_lib, const char *defines, bool deferred)
{ {
GPUMaterial *mat = NULL; GPUMaterial *mat = NULL;
if (DRW_state_is_image_render()) { if (DRW_state_is_image_render()) {
@@ -372,7 +372,7 @@ GPUMaterial *DRW_shader_create_from_material(
} }
if (GPU_material_status(mat) == GPU_MAT_QUEUED) { if (GPU_material_status(mat) == GPU_MAT_QUEUED) {
drw_deferred_shader_add(mat); drw_deferred_shader_add(mat, deferred);
} }
return mat; return mat;

View File

@@ -908,7 +908,7 @@ static void OBJECT_cache_init(void *vedata)
} }
{ {
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL; DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_POINT;
DRWPass *pass = psl->lightprobes = DRW_pass_create("Object Probe Pass", state); DRWPass *pass = psl->lightprobes = DRW_pass_create("Object Probe Pass", state);
struct Gwn_Batch *sphere = DRW_cache_sphere_get(); struct Gwn_Batch *sphere = DRW_cache_sphere_get();
struct Gwn_Batch *quad = DRW_cache_quad_get(); struct Gwn_Batch *quad = DRW_cache_quad_get();
@@ -1355,14 +1355,14 @@ static void DRW_shgroup_lamp(OBJECT_StorageList *stl, Object *ob, ViewLayer *vie
static float zero = 0.0f; static float zero = 0.0f;
typedef struct LampEngineData { typedef struct LampEngineData {
ObjectEngineData engine_data; DrawData dd;
float shape_mat[4][4]; float shape_mat[4][4];
float spot_blend_mat[4][4]; float spot_blend_mat[4][4];
} LampEngineData; } LampEngineData;
LampEngineData *lamp_engine_data = LampEngineData *lamp_engine_data =
(LampEngineData *)DRW_object_engine_data_ensure( (LampEngineData *)DRW_drawdata_ensure(
ob, &ob->id,
&draw_engine_object_type, &draw_engine_object_type,
sizeof(LampEngineData), sizeof(LampEngineData),
NULL, NULL,
@@ -1712,7 +1712,7 @@ static void DRW_shgroup_speaker(OBJECT_StorageList *stl, Object *ob, ViewLayer *
} }
typedef struct OBJECT_LightProbeEngineData { typedef struct OBJECT_LightProbeEngineData {
ObjectEngineData engine_data; DrawData dd;
float prb_mats[6][4][4]; float prb_mats[6][4][4];
float probe_cube_mat[4][4]; float probe_cube_mat[4][4];
@@ -1733,8 +1733,8 @@ static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, OBJECT_PassList *psl
int theme_id = DRW_object_wire_theme_get(ob, view_layer, &color); int theme_id = DRW_object_wire_theme_get(ob, view_layer, &color);
OBJECT_LightProbeEngineData *prb_data = OBJECT_LightProbeEngineData *prb_data =
(OBJECT_LightProbeEngineData *)DRW_object_engine_data_ensure( (OBJECT_LightProbeEngineData *)DRW_drawdata_ensure(
ob, &ob->id,
&draw_engine_object_type, &draw_engine_object_type,
sizeof(OBJECT_LightProbeEngineData), sizeof(OBJECT_LightProbeEngineData),
NULL, NULL,
@@ -1785,8 +1785,7 @@ static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, OBJECT_PassList *psl
DRW_shgroup_uniform_vec3(grp, "increment_y", prb_data->increment_y, 1); DRW_shgroup_uniform_vec3(grp, "increment_y", prb_data->increment_y, 1);
DRW_shgroup_uniform_vec3(grp, "increment_z", prb_data->increment_z, 1); DRW_shgroup_uniform_vec3(grp, "increment_z", prb_data->increment_z, 1);
DRW_shgroup_uniform_ivec3(grp, "grid_resolution", &prb->grid_resolution_x, 1); DRW_shgroup_uniform_ivec3(grp, "grid_resolution", &prb->grid_resolution_x, 1);
DRW_shgroup_uniform_float(grp, "sphere_size", &prb->data_draw_size, 1); DRW_shgroup_call_procedural_points_add(grp, prb_data->cell_count, NULL);
DRW_shgroup_call_instances_add(grp, DRW_cache_sphere_get(), NULL, &prb_data->cell_count);
} }
else if (prb->type == LIGHTPROBE_TYPE_CUBE) { else if (prb->type == LIGHTPROBE_TYPE_CUBE) {
prb_data->draw_size = prb->data_draw_size * 0.1f; prb_data->draw_size = prb->data_draw_size * 0.1f;
@@ -1794,6 +1793,9 @@ static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, OBJECT_PassList *psl
copy_v3_v3(prb_data->probe_cube_mat[3], ob->obmat[3]); copy_v3_v3(prb_data->probe_cube_mat[3], ob->obmat[3]);
DRWShadingGroup *grp = shgroup_theme_id_to_probe_cube_outline_shgrp(stl, theme_id); DRWShadingGroup *grp = shgroup_theme_id_to_probe_cube_outline_shgrp(stl, theme_id);
/* TODO remove or change the drawing of the cube probes. Theses line draws nothing on purpose
* to keep the call ids correct. */
zero_m4(prb_data->probe_cube_mat);
DRW_shgroup_call_dynamic_add(grp, call_id, &prb_data->draw_size, prb_data->probe_cube_mat); DRW_shgroup_call_dynamic_add(grp, call_id, &prb_data->draw_size, prb_data->probe_cube_mat);
} }
else { else {

View File

@@ -1,7 +1,4 @@
in vec3 pos;
in vec3 nor;
uniform mat4 ViewProjectionMatrix; uniform mat4 ViewProjectionMatrix;
uniform float sphere_size; uniform float sphere_size;
@@ -10,6 +7,7 @@ uniform vec3 corner;
uniform vec3 increment_x; uniform vec3 increment_x;
uniform vec3 increment_y; uniform vec3 increment_y;
uniform vec3 increment_z; uniform vec3 increment_z;
uniform vec3 screen_vecs[2];
uniform int call_id; /* we don't want the builtin callId which would be 0. */ uniform int call_id; /* we don't want the builtin callId which would be 0. */
uniform int baseId; uniform int baseId;
@@ -20,16 +18,17 @@ void main()
{ {
vec3 ls_cell_location; vec3 ls_cell_location;
/* Keep in sync with update_irradiance_probe */ /* Keep in sync with update_irradiance_probe */
ls_cell_location.z = float(gl_InstanceID % grid_resolution.z); ls_cell_location.z = float(gl_VertexID % grid_resolution.z);
ls_cell_location.y = float((gl_InstanceID / grid_resolution.z) % grid_resolution.y); ls_cell_location.y = float((gl_VertexID / grid_resolution.z) % grid_resolution.y);
ls_cell_location.x = float(gl_InstanceID / (grid_resolution.z * grid_resolution.y)); ls_cell_location.x = float(gl_VertexID / (grid_resolution.z * grid_resolution.y));
vec3 ws_cell_location = corner + vec3 ws_cell_location = corner +
(increment_x * ls_cell_location.x + (increment_x * ls_cell_location.x +
increment_y * ls_cell_location.y + increment_y * ls_cell_location.y +
increment_z * ls_cell_location.z); increment_z * ls_cell_location.z);
gl_Position = ViewProjectionMatrix * vec4(pos * 0.02 * sphere_size + ws_cell_location, 1.0); gl_Position = ViewProjectionMatrix * vec4(ws_cell_location, 1.0);
gl_PointSize = 2.0f;
finalId = uint(baseId + call_id); finalId = uint(baseId + call_id);
} }

View File

@@ -56,6 +56,9 @@ void MATERIAL_OT_paste(struct wmOperatorType *ot);
void SCENE_OT_view_layer_add(struct wmOperatorType *ot); void SCENE_OT_view_layer_add(struct wmOperatorType *ot);
void SCENE_OT_view_layer_remove(struct wmOperatorType *ot); void SCENE_OT_view_layer_remove(struct wmOperatorType *ot);
void SCENE_OT_light_cache_bake(struct wmOperatorType *ot);
void SCENE_OT_light_cache_free(struct wmOperatorType *ot);
void SCENE_OT_render_view_add(struct wmOperatorType *ot); void SCENE_OT_render_view_add(struct wmOperatorType *ot);
void SCENE_OT_render_view_remove(struct wmOperatorType *ot); void SCENE_OT_render_view_remove(struct wmOperatorType *ot);

View File

@@ -62,6 +62,9 @@ void ED_operatortypes_render(void)
WM_operatortype_append(SCENE_OT_render_view_add); WM_operatortype_append(SCENE_OT_render_view_add);
WM_operatortype_append(SCENE_OT_render_view_remove); WM_operatortype_append(SCENE_OT_render_view_remove);
WM_operatortype_append(SCENE_OT_light_cache_bake);
WM_operatortype_append(SCENE_OT_light_cache_free);
#ifdef WITH_FREESTYLE #ifdef WITH_FREESTYLE
WM_operatortype_append(SCENE_OT_freestyle_module_add); WM_operatortype_append(SCENE_OT_freestyle_module_add);
WM_operatortype_append(SCENE_OT_freestyle_module_remove); WM_operatortype_append(SCENE_OT_freestyle_module_remove);

View File

@@ -33,6 +33,7 @@
#include "DNA_curve_types.h" #include "DNA_curve_types.h"
#include "DNA_lamp_types.h" #include "DNA_lamp_types.h"
#include "DNA_lightprobe_types.h"
#include "DNA_material_types.h" #include "DNA_material_types.h"
#include "DNA_node_types.h" #include "DNA_node_types.h"
#include "DNA_object_types.h" #include "DNA_object_types.h"
@@ -94,6 +95,8 @@
#include "RE_pipeline.h" #include "RE_pipeline.h"
#include "engines/eevee/eevee_lightcache.h"
#include "render_intern.h" // own include #include "render_intern.h" // own include
/********************** material slot operators *********************/ /********************** material slot operators *********************/
@@ -673,6 +676,185 @@ void SCENE_OT_view_layer_remove(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
} }
/********************** light cache operators *********************/
enum {
LIGHTCACHE_SUBSET_ALL = 0,
LIGHTCACHE_SUBSET_DIRTY,
LIGHTCACHE_SUBSET_CUBE,
};
static void light_cache_bake_tag_cache(Scene *scene, wmOperator *op)
{
if (scene->eevee.light_cache != 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;
break;
case LIGHTCACHE_SUBSET_CUBE:
scene->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_CUBE;
break;
case LIGHTCACHE_SUBSET_DIRTY:
/* Leave tag untouched. */
break;
}
}
}
/* catch esc */
static int light_cache_bake_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = (Scene *) op->customdata;
/* no running blender, remove handler and pass through */
if (0 == WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_RENDER)) {
return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
}
/* running render */
switch (event->type) {
case ESCKEY:
return OPERATOR_RUNNING_MODAL;
}
return OPERATOR_PASS_THROUGH;
}
static void light_cache_bake_cancel(bContext *C, wmOperator *op)
{
wmWindowManager *wm = CTX_wm_manager(C);
Scene *scene = (Scene *) op->customdata;
/* kill on cancel, because job is using op->reports */
WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_RENDER);
}
/* executes blocking render */
static int light_cache_bake_exec(bContext *C, wmOperator *op)
{
ViewLayer *view_layer = CTX_data_view_layer(C);
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
G.is_break = false;
/* TODO abort if selected engine is not eevee. */
void *rj = EEVEE_lightbake_job_data_alloc(bmain, view_layer, scene, false);
light_cache_bake_tag_cache(scene, op);
short stop = 0, do_update; float progress; /* Not actually used. */
EEVEE_lightbake_job(rj, &stop, &do_update, &progress);
EEVEE_lightbake_update(rj);
EEVEE_lightbake_job_data_free(rj);
// no redraw needed, we leave state as we entered it
ED_update_for_newframe(bmain, CTX_data_depsgraph(C));
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene);
return OPERATOR_FINISHED;
}
static int light_cache_bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
int delay = RNA_int_get(op->ptr, "delay");
wmJob *wm_job = EEVEE_lightbake_job_create(wm, win, bmain, view_layer, scene, delay);
if (!wm_job) {
return OPERATOR_CANCELLED;
}
/* add modal handler for ESC */
WM_event_add_modal_handler(C, op);
light_cache_bake_tag_cache(scene, op);
/* store actual owner of job, so modal operator could check for it,
* the reason of this is that active scene could change when rendering
* several layers from compositor [#31800]
*/
op->customdata = scene;
WM_jobs_start(wm, wm_job);
WM_cursor_wait(0);
return OPERATOR_RUNNING_MODAL;
}
void SCENE_OT_light_cache_bake(wmOperatorType *ot)
{
static const EnumPropertyItem light_cache_subset_items[] = {
{LIGHTCACHE_SUBSET_ALL, "ALL", 0, "All LightProbes", "Bake both irradiance grids and reflection cubemaps"},
{LIGHTCACHE_SUBSET_DIRTY, "DIRTY", 0, "Dirty Only", "Only bake lightprobes that are marked as dirty"},
{LIGHTCACHE_SUBSET_CUBE, "CUBEMAPS", 0, "Cubemaps Only", "Try to only bake reflection cubemaps if irradiance "
"grids are up to date"},
{0, NULL, 0, NULL, NULL}
};
/* identifiers */
ot->name = "Bake Light Cache";
ot->idname = "SCENE_OT_light_cache_bake";
ot->description = "Bake the active view layer lighting";
/* api callbacks */
ot->invoke = light_cache_bake_invoke;
ot->modal = light_cache_bake_modal;
ot->cancel = light_cache_bake_cancel;
ot->exec = light_cache_bake_exec;
ot->prop = RNA_def_int(ot->srna, "delay", 0, 0, 2000, "Delay", "Delay in millisecond before baking starts", 0, 2000);
RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
ot->prop = RNA_def_enum(ot->srna, "subset", light_cache_subset_items, 0, "Subset", "Subset of probes to update");
RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
}
static bool light_cache_free_poll(bContext *C)
{
Scene *scene = CTX_data_scene(C);
return scene->eevee.light_cache;
}
static int light_cache_free_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
if (!scene->eevee.light_cache) {
return OPERATOR_CANCELLED;
}
EEVEE_lightcache_free(scene->eevee.light_cache);
scene->eevee.light_cache = NULL;
EEVEE_lightcache_info_update(&scene->eevee);
DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE);
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
return OPERATOR_FINISHED;
}
void SCENE_OT_light_cache_free(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Free Light Cache";
ot->idname = "SCENE_OT_light_cache_free";
ot->description = "Free cached indirect lighting";
/* api callbacks */
ot->exec = light_cache_free_exec;
ot->poll = light_cache_free_poll;
}
/********************** render view operators *********************/ /********************** render view operators *********************/
static bool render_view_remove_poll(bContext *C) static bool render_view_remove_poll(bContext *C)

View File

@@ -294,9 +294,6 @@ static void world_changed(Main *UNUSED(bmain), World *wo)
/* icons */ /* icons */
BKE_icon_changed(BKE_icon_id_ensure(&wo->id)); BKE_icon_changed(BKE_icon_id_ensure(&wo->id));
/* XXX temporary flag waiting for depsgraph proper tagging */
wo->update_flag = 1;
/* glsl */ /* glsl */
if (wo->id.recalc & ID_RECALC) { if (wo->id.recalc & ID_RECALC) {
if (!BLI_listbase_is_empty(&defmaterial.gpumaterial)) { if (!BLI_listbase_is_empty(&defmaterial.gpumaterial)) {

View File

@@ -683,6 +683,18 @@ static void view3d_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)
} }
} }
static void view3d_lightcache_update(bContext *C)
{
PointerRNA op_ptr;
WM_operator_properties_create(&op_ptr, "SCENE_OT_light_cache_bake");
RNA_int_set(&op_ptr, "delay", 200);
RNA_enum_set_identifier(C, &op_ptr, "subset", "DIRTY");
WM_operator_name_call(C, "SCENE_OT_light_cache_bake", WM_OP_INVOKE_DEFAULT, &op_ptr);
WM_operator_properties_free(&op_ptr);
}
/* region dropbox definition */ /* region dropbox definition */
static void view3d_dropboxes(void) static void view3d_dropboxes(void)
@@ -980,6 +992,9 @@ static void view3d_main_region_listener(
break; break;
} }
break; break;
case NC_LIGHTPROBE:
ED_area_tag_refresh(sa);
break;
case NC_IMAGE: case NC_IMAGE:
/* this could be more fine grained checks if we had /* this could be more fine grained checks if we had
* more context than just the region */ * more context than just the region */
@@ -1409,6 +1424,13 @@ static void space_view3d_listener(
} }
} }
static void space_view3d_refresh(const bContext *C, ScrArea *UNUSED(sa))
{
/* This is only used by the auto lightprobe refresh for the moment.
* So we don't need to check anything to know what to do. */
view3d_lightcache_update((bContext *)C);
}
const char *view3d_context_dir[] = { const char *view3d_context_dir[] = {
"active_base", "active_object", NULL "active_base", "active_object", NULL
}; };
@@ -1509,6 +1531,7 @@ void ED_spacetype_view3d(void)
st->free = view3d_free; st->free = view3d_free;
st->init = view3d_init; st->init = view3d_init;
st->listener = space_view3d_listener; st->listener = space_view3d_listener;
st->refresh = space_view3d_refresh;
st->duplicate = view3d_duplicate; st->duplicate = view3d_duplicate;
st->operatortypes = view3d_operatortypes; st->operatortypes = view3d_operatortypes;
st->keymap = view3d_keymap; st->keymap = view3d_keymap;

View File

@@ -144,8 +144,23 @@ typedef enum GPUTextureFormat {
GPU_DEPTH_COMPONENT16, GPU_DEPTH_COMPONENT16,
} GPUTextureFormat; } GPUTextureFormat;
typedef enum GPUDataFormat {
GPU_DATA_FLOAT,
GPU_DATA_INT,
GPU_DATA_UNSIGNED_INT,
GPU_DATA_UNSIGNED_BYTE,
GPU_DATA_UNSIGNED_INT_24_8,
GPU_DATA_10_11_11_REV,
} GPUDataFormat;
unsigned int GPU_texture_memory_usage_get(void); unsigned int GPU_texture_memory_usage_get(void);
/* TODO make it static function again. (create function with GPUDataFormat exposed) */
GPUTexture *GPU_texture_create_nD(
int w, int h, int d, int n, const void *pixels,
GPUTextureFormat tex_format, GPUDataFormat gpu_data_format, int samples,
const bool can_rescale, char err_out[256]);
GPUTexture *GPU_texture_create_1D( GPUTexture *GPU_texture_create_1D(
int w, GPUTextureFormat data_type, const float *pixels, char err_out[256]); int w, GPUTextureFormat data_type, const float *pixels, char err_out[256]);
GPUTexture *GPU_texture_create_2D( GPUTexture *GPU_texture_create_2D(
@@ -168,11 +183,15 @@ GPUTexture *GPU_texture_from_blender(
struct Image *ima, struct ImageUser *iuser, int textarget, bool is_data, double time); struct Image *ima, struct ImageUser *iuser, int textarget, bool is_data, double time);
GPUTexture *GPU_texture_from_preview(struct PreviewImage *prv, int mipmap); GPUTexture *GPU_texture_from_preview(struct PreviewImage *prv, int mipmap);
void GPU_texture_update(GPUTexture *tex, const void *pixels); void GPU_texture_add_mipmap(GPUTexture *tex, GPUDataFormat gpu_data_format, int miplvl, const void *pixels);
void GPU_texture_update(GPUTexture *tex, GPUDataFormat data_format, const void *pixels);
void GPU_texture_update_sub( void GPU_texture_update_sub(
GPUTexture *tex, const void *pixels, GPUTexture *tex, GPUDataFormat gpu_data_format, const void *pixels,
int offset_x, int offset_y, int offset_z, int width, int height, int depth); int offset_x, int offset_y, int offset_z, int width, int height, int depth);
void *GPU_texture_read(GPUTexture *tex, GPUDataFormat gpu_data_format, int miplvl);
void GPU_invalid_tex_init(void); void GPU_invalid_tex_init(void);
void GPU_invalid_tex_bind(int mode); void GPU_invalid_tex_bind(int mode);
void GPU_invalid_tex_free(void); void GPU_invalid_tex_free(void);
@@ -202,6 +221,7 @@ int GPU_texture_detach_framebuffer(GPUTexture *tex, struct GPUFrameBuffer *fb);
int GPU_texture_target(const GPUTexture *tex); int GPU_texture_target(const GPUTexture *tex);
int GPU_texture_width(const GPUTexture *tex); int GPU_texture_width(const GPUTexture *tex);
int GPU_texture_height(const GPUTexture *tex); int GPU_texture_height(const GPUTexture *tex);
int GPU_texture_layers(const GPUTexture *tex);
GPUTextureFormat GPU_texture_format(const GPUTexture *tex); GPUTextureFormat GPU_texture_format(const GPUTexture *tex);
int GPU_texture_samples(const GPUTexture *tex); int GPU_texture_samples(const GPUTexture *tex);
bool GPU_texture_cube(const GPUTexture *tex); bool GPU_texture_cube(const GPUTexture *tex);
@@ -210,6 +230,8 @@ bool GPU_texture_stencil(const GPUTexture *tex);
bool GPU_texture_integer(const GPUTexture *tex); bool GPU_texture_integer(const GPUTexture *tex);
int GPU_texture_opengl_bindcode(const GPUTexture *tex); int GPU_texture_opengl_bindcode(const GPUTexture *tex);
void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *size);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -134,73 +134,159 @@ unsigned int GPU_texture_memory_usage_get(void)
/* -------------------------------- */ /* -------------------------------- */
static GLenum gpu_texture_get_format( static int gpu_get_component_count(GPUTextureFormat format)
int components, GPUTextureFormat data_type, {
GLenum *format, GLenum *data_format, GPUTextureFormatFlag *format_flag, unsigned int *bytesize) switch (format) {
case GPU_RGBA8:
case GPU_RGBA16F:
case GPU_RGBA16:
case GPU_RGBA32F:
return 4;
case GPU_RGB16F:
case GPU_R11F_G11F_B10F:
return 3;
case GPU_RG8:
case GPU_RG16:
case GPU_RG16F:
case GPU_RG16I:
case GPU_RG16UI:
case GPU_RG32F:
return 2;
default:
return 1;
}
}
/* Definitely not complete, edit according to the gl specification. */
static void gpu_validate_data_format(GPUTextureFormat tex_format, GPUDataFormat data_format)
{
if (ELEM(tex_format, GPU_DEPTH_COMPONENT24,
GPU_DEPTH_COMPONENT16,
GPU_DEPTH_COMPONENT32F))
{
BLI_assert(data_format == GPU_DATA_FLOAT);
}
else if (tex_format == GPU_DEPTH24_STENCIL8) {
BLI_assert(data_format == GPU_DATA_UNSIGNED_INT_24_8);
}
else {
/* Integer formats */
if (ELEM(tex_format, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) {
if (ELEM(tex_format, GPU_R16UI, GPU_RG16UI, GPU_R32UI)) {
BLI_assert(data_format == GPU_DATA_UNSIGNED_INT);
}
else {
BLI_assert(data_format == GPU_DATA_INT);
}
}
/* Byte formats */
else if (ELEM(tex_format, GPU_R8, GPU_RG8, GPU_RGBA8)) {
BLI_assert(ELEM(data_format, GPU_DATA_UNSIGNED_BYTE, GPU_DATA_FLOAT));
}
/* Special case */
else if (ELEM(tex_format, GPU_R11F_G11F_B10F)) {
BLI_assert(ELEM(data_format, GPU_DATA_10_11_11_REV, GPU_DATA_FLOAT));
}
/* Float formats */
else {
BLI_assert(ELEM(data_format, GPU_DATA_FLOAT));
}
}
}
static GPUDataFormat gpu_get_data_format_from_tex_format(GPUTextureFormat tex_format)
{
if (ELEM(tex_format, GPU_DEPTH_COMPONENT24,
GPU_DEPTH_COMPONENT16,
GPU_DEPTH_COMPONENT32F))
{
return GPU_DATA_FLOAT;
}
else if (tex_format == GPU_DEPTH24_STENCIL8) {
return GPU_DATA_UNSIGNED_INT_24_8;
}
else {
/* Integer formats */
if (ELEM(tex_format, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) {
if (ELEM(tex_format, GPU_R16UI, GPU_RG16UI, GPU_R32UI)) {
return GPU_DATA_UNSIGNED_INT;
}
else {
return GPU_DATA_INT;
}
}
/* Byte formats */
else if (ELEM(tex_format, GPU_R8)) {
return GPU_DATA_UNSIGNED_BYTE;
}
/* Special case */
else if (ELEM(tex_format, GPU_R11F_G11F_B10F)) {
return GPU_DATA_10_11_11_REV;
}
else {
return GPU_DATA_FLOAT;
}
}
}
/* Definitely not complete, edit according to the gl specification. */
static GLenum gpu_get_gl_dataformat(GPUTextureFormat data_type, GPUTextureFormatFlag *format_flag)
{ {
if (ELEM(data_type, GPU_DEPTH_COMPONENT24, if (ELEM(data_type, GPU_DEPTH_COMPONENT24,
GPU_DEPTH_COMPONENT16, GPU_DEPTH_COMPONENT16,
GPU_DEPTH_COMPONENT32F)) GPU_DEPTH_COMPONENT32F))
{ {
*format_flag |= GPU_FORMAT_DEPTH; *format_flag |= GPU_FORMAT_DEPTH;
*data_format = GL_FLOAT; return GL_DEPTH_COMPONENT;
*format = GL_DEPTH_COMPONENT;
} }
else if (data_type == GPU_DEPTH24_STENCIL8) { else if (data_type == GPU_DEPTH24_STENCIL8) {
*format_flag |= GPU_FORMAT_DEPTH | GPU_FORMAT_STENCIL; *format_flag |= GPU_FORMAT_DEPTH | GPU_FORMAT_STENCIL;
*data_format = GL_UNSIGNED_INT_24_8; return GL_DEPTH_STENCIL;
*format = GL_DEPTH_STENCIL;
} }
else { else {
/* Integer formats */ /* Integer formats */
if (ELEM(data_type, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) { if (ELEM(data_type, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) {
if (ELEM(data_type, GPU_R16UI, GPU_RG16UI, GPU_R32UI)) {
*data_format = GL_UNSIGNED_INT;
}
else {
*data_format = GL_INT;
}
*format_flag |= GPU_FORMAT_INTEGER; *format_flag |= GPU_FORMAT_INTEGER;
switch (components) { switch (gpu_get_component_count(data_type)) {
case 1: *format = GL_RED_INTEGER; break; case 1: return GL_RED_INTEGER; break;
case 2: *format = GL_RG_INTEGER; break; case 2: return GL_RG_INTEGER; break;
case 3: *format = GL_RGB_INTEGER; break; case 3: return GL_RGB_INTEGER; break;
case 4: *format = GL_RGBA_INTEGER; break; case 4: return GL_RGBA_INTEGER; break;
default: break;
} }
} }
else if (ELEM(data_type, GPU_R8)) { else if (ELEM(data_type, GPU_R8)) {
*data_format = GL_UNSIGNED_BYTE; *format_flag |= GPU_FORMAT_FLOAT;
*format = GL_RED; return GL_RED;
} }
else { else {
*data_format = GL_FLOAT;
*format_flag |= GPU_FORMAT_FLOAT; *format_flag |= GPU_FORMAT_FLOAT;
switch (components) { switch (gpu_get_component_count(data_type)) {
case 1: *format = GL_RED; break; case 1: return GL_RED; break;
case 2: *format = GL_RG; break; case 2: return GL_RG; break;
case 3: *format = GL_RGB; break; case 3: return GL_RGB; break;
case 4: *format = GL_RGBA; break; case 4: return GL_RGBA; break;
default: break;
} }
} }
} }
BLI_assert(0);
*format_flag |= GPU_FORMAT_FLOAT;
return GL_RGBA;
}
static unsigned int gpu_get_bytesize(GPUTextureFormat data_type)
{
switch (data_type) { switch (data_type) {
case GPU_RGBA32F: case GPU_RGBA32F:
*bytesize = 32; return 32;
break;
case GPU_RG32F: case GPU_RG32F:
case GPU_RGBA16F: case GPU_RGBA16F:
case GPU_RGBA16: case GPU_RGBA16:
*bytesize = 16; return 16;
break;
case GPU_RGB16F: case GPU_RGB16F:
*bytesize = 12; return 12;
break;
case GPU_RG16F: case GPU_RG16F:
case GPU_RG16I: case GPU_RG16I:
case GPU_RG16UI: case GPU_RG16UI:
@@ -212,28 +298,28 @@ static GLenum gpu_texture_get_format(
case GPU_R32F: case GPU_R32F:
case GPU_R32UI: case GPU_R32UI:
case GPU_R32I: case GPU_R32I:
*bytesize = 4; return 4;
break;
case GPU_DEPTH_COMPONENT24: case GPU_DEPTH_COMPONENT24:
*bytesize = 3; return 3;
break;
case GPU_DEPTH_COMPONENT16: case GPU_DEPTH_COMPONENT16:
case GPU_R16F: case GPU_R16F:
case GPU_R16UI:
case GPU_R16I: case GPU_R16I:
case GPU_RG8: case GPU_RG8:
*bytesize = 2; return 2;
break;
case GPU_R8: case GPU_R8:
*bytesize = 1; return 1;
break;
default: default:
*bytesize = 0; BLI_assert(!"Texture format incorrect or unsupported\n");
break; return 0;
} }
}
static GLenum gpu_get_gl_internalformat(GPUTextureFormat format)
{
/* You can add any of the available type to this list /* You can add any of the available type to this list
* For available types see GPU_texture.h */ * For available types see GPU_texture.h */
switch (data_type) { switch (format) {
/* Formats texture & renderbuffer */ /* Formats texture & renderbuffer */
case GPU_RGBA32F: return GL_RGBA32F; case GPU_RGBA32F: return GL_RGBA32F;
case GPU_RGBA16F: return GL_RGBA16F; case GPU_RGBA16F: return GL_RGBA16F;
@@ -265,31 +351,29 @@ static GLenum gpu_texture_get_format(
case GPU_DEPTH_COMPONENT24: return GL_DEPTH_COMPONENT24; case GPU_DEPTH_COMPONENT24: return GL_DEPTH_COMPONENT24;
case GPU_DEPTH_COMPONENT16: return GL_DEPTH_COMPONENT16; case GPU_DEPTH_COMPONENT16: return GL_DEPTH_COMPONENT16;
default: default:
fprintf(stderr, "Texture format incorrect or unsupported\n"); BLI_assert(!"Texture format incorrect or unsupported\n");
return 0; return 0;
} }
} }
static int gpu_texture_get_component_count(GPUTextureFormat format) static GLenum gpu_get_gl_datatype(GPUDataFormat format)
{ {
switch (format) { switch (format) {
case GPU_RGBA8: case GPU_DATA_FLOAT:
case GPU_RGBA16F: return GL_FLOAT;
case GPU_RGBA16: case GPU_DATA_INT:
case GPU_RGBA32F: return GL_INT;
return 4; case GPU_DATA_UNSIGNED_INT:
case GPU_RGB16F: return GL_UNSIGNED_INT;
case GPU_R11F_G11F_B10F: case GPU_DATA_UNSIGNED_BYTE:
return 3; return GL_UNSIGNED_BYTE;
case GPU_RG8: case GPU_DATA_UNSIGNED_INT_24_8:
case GPU_RG16: return GL_UNSIGNED_INT_24_8;
case GPU_RG16F: case GPU_DATA_10_11_11_REV:
case GPU_RG16I: return GL_UNSIGNED_INT_10F_11F_11F_REV;
case GPU_RG16UI:
case GPU_RG32F:
return 2;
default: default:
return 1; BLI_assert(!"Unhandled data format");
return GL_FLOAT;
} }
} }
@@ -331,22 +415,22 @@ static float *GPU_texture_3D_rescale(GPUTexture *tex, int w, int h, int d, int c
/* This tries to allocate video memory for a given texture /* This tries to allocate video memory for a given texture
* If alloc fails, lower the resolution until it fits. */ * If alloc fails, lower the resolution until it fits. */
static bool gpu_texture_try_alloc( static bool gpu_texture_try_alloc(
GPUTexture *tex, GLenum proxy, GLenum internalformat, GLenum format, GLenum data_format, GPUTexture *tex, GLenum proxy, GLenum internalformat, GLenum data_format, GLenum data_type,
int channels, bool try_rescale, const float *fpixels, float **rescaled_fpixels) int channels, bool try_rescale, const float *fpixels, float **rescaled_fpixels)
{ {
int r_width; int r_width;
switch (proxy) { switch (proxy) {
case GL_PROXY_TEXTURE_1D: case GL_PROXY_TEXTURE_1D:
glTexImage1D(proxy, 0, internalformat, tex->w, 0, format, data_format, NULL); glTexImage1D(proxy, 0, internalformat, tex->w, 0, data_format, data_type, NULL);
break; break;
case GL_PROXY_TEXTURE_1D_ARRAY: case GL_PROXY_TEXTURE_1D_ARRAY:
case GL_PROXY_TEXTURE_2D: case GL_PROXY_TEXTURE_2D:
glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, format, data_format, NULL); glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, NULL);
break; break;
case GL_PROXY_TEXTURE_2D_ARRAY: case GL_PROXY_TEXTURE_2D_ARRAY:
case GL_PROXY_TEXTURE_3D: case GL_PROXY_TEXTURE_3D:
glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, format, data_format, NULL); glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, data_format, data_type, NULL);
break; break;
} }
@@ -367,11 +451,11 @@ static bool gpu_texture_try_alloc(
if (tex->d == 0 && proxy == GL_PROXY_TEXTURE_3D) break; if (tex->d == 0 && proxy == GL_PROXY_TEXTURE_3D) break;
if (proxy == GL_PROXY_TEXTURE_1D) if (proxy == GL_PROXY_TEXTURE_1D)
glTexImage1D(proxy, 0, internalformat, tex->w, 0, format, data_format, NULL); glTexImage1D(proxy, 0, internalformat, tex->w, 0, data_format, data_type, NULL);
else if (proxy == GL_PROXY_TEXTURE_2D) else if (proxy == GL_PROXY_TEXTURE_2D)
glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, format, data_format, NULL); glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, NULL);
else if (proxy == GL_PROXY_TEXTURE_3D) else if (proxy == GL_PROXY_TEXTURE_3D)
glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, format, data_format, NULL); glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, data_format, data_type, NULL);
glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &r_width); glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &r_width);
} }
@@ -384,6 +468,7 @@ static bool gpu_texture_try_alloc(
/* Do nothing for now */ /* Do nothing for now */
return false; return false;
case GL_PROXY_TEXTURE_3D: case GL_PROXY_TEXTURE_3D:
BLI_assert(data_type == GL_FLOAT);
*rescaled_fpixels = GPU_texture_3D_rescale(tex, w, h, d, channels, fpixels); *rescaled_fpixels = GPU_texture_3D_rescale(tex, w, h, d, channels, fpixels);
return (bool)*rescaled_fpixels; return (bool)*rescaled_fpixels;
} }
@@ -393,9 +478,9 @@ static bool gpu_texture_try_alloc(
return (r_width > 0); return (r_width > 0);
} }
static GPUTexture *GPU_texture_create_nD( GPUTexture *GPU_texture_create_nD(
int w, int h, int d, int n, const float *fpixels, int w, int h, int d, int n, const void *pixels,
GPUTextureFormat data_type, int samples, GPUTextureFormat tex_format, GPUDataFormat gpu_data_format, int samples,
const bool can_rescale, char err_out[256]) const bool can_rescale, char err_out[256])
{ {
if (samples) { if (samples) {
@@ -409,8 +494,9 @@ static GPUTexture *GPU_texture_create_nD(
tex->samples = samples; tex->samples = samples;
tex->number = -1; tex->number = -1;
tex->refcount = 1; tex->refcount = 1;
tex->format = data_type; tex->format = tex_format;
tex->components = gpu_texture_get_component_count(data_type); tex->components = gpu_get_component_count(tex_format);
tex->bytesize = gpu_get_bytesize(tex_format);
tex->format_flag = 0; tex->format_flag = 0;
if (n == 2) { if (n == 2) {
@@ -434,12 +520,14 @@ static GPUTexture *GPU_texture_create_nD(
return NULL; return NULL;
} }
gpu_validate_data_format(tex_format, gpu_data_format);
if (samples && n == 2 && d == 0) if (samples && n == 2 && d == 0)
tex->target = GL_TEXTURE_2D_MULTISAMPLE; tex->target = GL_TEXTURE_2D_MULTISAMPLE;
GLenum format, internalformat, data_format; GLenum internalformat = gpu_get_gl_internalformat(tex_format);
internalformat = gpu_texture_get_format(tex->components, data_type, &format, &data_format, GLenum data_format = gpu_get_gl_dataformat(tex_format, &tex->format_flag);
&tex->format_flag, &tex->bytesize); GLenum data_type = gpu_get_gl_datatype(gpu_data_format);
gpu_texture_memory_footprint_add(tex); gpu_texture_memory_footprint_add(tex);
@@ -448,9 +536,9 @@ static GPUTexture *GPU_texture_create_nD(
if (!tex->bindcode) { if (!tex->bindcode) {
if (err_out) if (err_out)
BLI_snprintf(err_out, 256, "GPUTexture: texture create failed"); BLI_snprintf(err_out, 256, "GPUTexture: texture create failed\n");
else else
fprintf(stderr, "GPUTexture: texture create failed"); fprintf(stderr, "GPUTexture: texture create failed\n");
GPU_texture_free(tex); GPU_texture_free(tex);
return NULL; return NULL;
} }
@@ -474,9 +562,9 @@ static GPUTexture *GPU_texture_create_nD(
proxy = GL_PROXY_TEXTURE_3D; proxy = GL_PROXY_TEXTURE_3D;
} }
float *rescaled_fpixels = NULL; float *rescaled_pixels = NULL;
bool valid = gpu_texture_try_alloc(tex, proxy, internalformat, format, data_format, tex->components, can_rescale, bool valid = gpu_texture_try_alloc(tex, proxy, internalformat, data_format, data_type, tex->components, can_rescale,
fpixels, &rescaled_fpixels); pixels, &rescaled_pixels);
if (!valid) { if (!valid) {
if (err_out) if (err_out)
BLI_snprintf(err_out, 256, "GPUTexture: texture alloc failed"); BLI_snprintf(err_out, 256, "GPUTexture: texture alloc failed");
@@ -487,7 +575,7 @@ static GPUTexture *GPU_texture_create_nD(
} }
/* Upload Texture */ /* Upload Texture */
const float *pix = (rescaled_fpixels) ? rescaled_fpixels : fpixels; const float *pix = (rescaled_pixels) ? rescaled_pixels : pixels;
if (tex->target == GL_TEXTURE_2D || if (tex->target == GL_TEXTURE_2D ||
tex->target == GL_TEXTURE_2D_MULTISAMPLE || tex->target == GL_TEXTURE_2D_MULTISAMPLE ||
@@ -496,21 +584,21 @@ static GPUTexture *GPU_texture_create_nD(
if (samples) { if (samples) {
glTexImage2DMultisample(tex->target, samples, internalformat, tex->w, tex->h, true); glTexImage2DMultisample(tex->target, samples, internalformat, tex->w, tex->h, true);
if (pix) if (pix)
glTexSubImage2D(tex->target, 0, 0, 0, tex->w, tex->h, format, data_format, pix); glTexSubImage2D(tex->target, 0, 0, 0, tex->w, tex->h, data_format, data_type, pix);
} }
else { else {
glTexImage2D(tex->target, 0, internalformat, tex->w, tex->h, 0, format, data_format, pix); glTexImage2D(tex->target, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, pix);
} }
} }
else if (tex->target == GL_TEXTURE_1D) { else if (tex->target == GL_TEXTURE_1D) {
glTexImage1D(tex->target, 0, internalformat, tex->w, 0, format, data_format, pix); glTexImage1D(tex->target, 0, internalformat, tex->w, 0, data_format, data_type, pix);
} }
else { else {
glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->d, 0, format, data_format, pix); glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->d, 0, data_format, data_type, pix);
} }
if (rescaled_fpixels) if (rescaled_pixels)
MEM_freeN(rescaled_fpixels); MEM_freeN(rescaled_pixels);
/* Texture Parameters */ /* Texture Parameters */
if (GPU_texture_stencil(tex) || /* Does not support filtering */ if (GPU_texture_stencil(tex) || /* Does not support filtering */
@@ -547,11 +635,9 @@ static GPUTexture *GPU_texture_cube_create(
int w, int d, int w, int d,
const float *fpixels_px, const float *fpixels_py, const float *fpixels_pz, const float *fpixels_px, const float *fpixels_py, const float *fpixels_pz,
const float *fpixels_nx, const float *fpixels_ny, const float *fpixels_nz, const float *fpixels_nx, const float *fpixels_ny, const float *fpixels_nz,
GPUTextureFormat data_type, GPUTextureFormat tex_format, GPUDataFormat gpu_data_format,
char err_out[256]) char err_out[256])
{ {
GLenum format, internalformat, data_format;
GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture"); GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
tex->w = w; tex->w = w;
tex->h = w; tex->h = w;
@@ -559,8 +645,9 @@ static GPUTexture *GPU_texture_cube_create(
tex->samples = 0; tex->samples = 0;
tex->number = -1; tex->number = -1;
tex->refcount = 1; tex->refcount = 1;
tex->format = data_type; tex->format = tex_format;
tex->components = gpu_texture_get_component_count(data_type); tex->components = gpu_get_component_count(tex_format);
tex->bytesize = gpu_get_bytesize(tex_format);
tex->format_flag = GPU_FORMAT_CUBE; tex->format_flag = GPU_FORMAT_CUBE;
if (d == 0) { if (d == 0) {
@@ -571,8 +658,9 @@ static GPUTexture *GPU_texture_cube_create(
// tex->target_base = tex->target = GL_TEXTURE_CUBE_MAP_ARRAY; // tex->target_base = tex->target = GL_TEXTURE_CUBE_MAP_ARRAY;
} }
internalformat = gpu_texture_get_format(tex->components, data_type, &format, &data_format, GLenum internalformat = gpu_get_gl_internalformat(tex_format);
&tex->format_flag, &tex->bytesize); GLenum data_format = gpu_get_gl_dataformat(tex_format, &tex->format_flag);
GLenum data_type = gpu_get_gl_datatype(gpu_data_format);
gpu_texture_memory_footprint_add(tex); gpu_texture_memory_footprint_add(tex);
@@ -581,9 +669,9 @@ static GPUTexture *GPU_texture_cube_create(
if (!tex->bindcode) { if (!tex->bindcode) {
if (err_out) if (err_out)
BLI_snprintf(err_out, 256, "GPUTexture: texture create failed"); BLI_snprintf(err_out, 256, "GPUTexture: texture create failed\n");
else else
fprintf(stderr, "GPUTexture: texture create failed"); fprintf(stderr, "GPUTexture: texture create failed\n");
GPU_texture_free(tex); GPU_texture_free(tex);
return NULL; return NULL;
} }
@@ -591,12 +679,12 @@ static GPUTexture *GPU_texture_cube_create(
glBindTexture(tex->target, tex->bindcode); glBindTexture(tex->target, tex->bindcode);
/* Upload Texture */ /* Upload Texture */
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, internalformat, tex->w, tex->h, 0, format, data_format, fpixels_px); 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, format, data_format, fpixels_py); 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, format, data_format, fpixels_pz); 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, format, data_format, fpixels_nx); 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, format, data_format, fpixels_ny); 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, format, data_format, fpixels_nz); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, fpixels_nz);
/* Texture Parameters */ /* Texture Parameters */
if (GPU_texture_stencil(tex) || /* Does not support filtering */ if (GPU_texture_stencil(tex) || /* Does not support filtering */
@@ -625,36 +713,37 @@ static GPUTexture *GPU_texture_cube_create(
return tex; return tex;
} }
/* Special buffer textures. data_type must be compatible with the buffer content. */ /* Special buffer textures. tex_format must be compatible with the buffer content. */
GPUTexture *GPU_texture_create_buffer(GPUTextureFormat data_type, const GLuint buffer) GPUTexture *GPU_texture_create_buffer(GPUTextureFormat tex_format, const GLuint buffer)
{ {
GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture"); GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
tex->number = -1; tex->number = -1;
tex->refcount = 1; tex->refcount = 1;
tex->format = data_type; tex->format = tex_format;
tex->components = gpu_texture_get_component_count(data_type); tex->components = gpu_get_component_count(tex_format);
tex->format_flag = 0; tex->format_flag = 0;
tex->target_base = tex->target = GL_TEXTURE_BUFFER; tex->target_base = tex->target = GL_TEXTURE_BUFFER;
tex->bytesize = gpu_get_bytesize(tex_format);
GLenum format, internalformat, data_format; GLenum internalformat = gpu_get_gl_internalformat(tex_format);
internalformat = gpu_texture_get_format(tex->components, data_type, &format, &data_format,
&tex->format_flag, &tex->bytesize);
if (!(ELEM(data_type, GPU_R8, GPU_R16) || gpu_get_gl_dataformat(tex_format, &tex->format_flag);
ELEM(data_type, GPU_R16F, GPU_R32F) ||
ELEM(data_type, GPU_R8I, GPU_R16I, GPU_R32I) || if (!(ELEM(tex_format, GPU_R8, GPU_R16) ||
ELEM(data_type, GPU_R8UI, GPU_R16UI, GPU_R32UI) || ELEM(tex_format, GPU_R16F, GPU_R32F) ||
ELEM(data_type, GPU_RG8, GPU_RG16) || ELEM(tex_format, GPU_R8I, GPU_R16I, GPU_R32I) ||
ELEM(data_type, GPU_RG16F, GPU_RG32F) || ELEM(tex_format, GPU_R8UI, GPU_R16UI, GPU_R32UI) ||
ELEM(data_type, GPU_RG8I, GPU_RG16I, GPU_RG32I) || ELEM(tex_format, GPU_RG8, GPU_RG16) ||
ELEM(data_type, GPU_RG8UI, GPU_RG16UI, GPU_RG32UI) || ELEM(tex_format, GPU_RG16F, GPU_RG32F) ||
//ELEM(data_type, GPU_RGB32F, GPU_RGB32I, GPU_RGB32UI) || /* Not available until gl 4.0 */ ELEM(tex_format, GPU_RG8I, GPU_RG16I, GPU_RG32I) ||
ELEM(data_type, GPU_RGBA8, GPU_RGBA16) || ELEM(tex_format, GPU_RG8UI, GPU_RG16UI, GPU_RG32UI) ||
ELEM(data_type, GPU_RGBA16F, GPU_RGBA32F) || //ELEM(tex_format, GPU_RGB32F, GPU_RGB32I, GPU_RGB32UI) || /* Not available until gl 4.0 */
ELEM(data_type, GPU_RGBA8I, GPU_RGBA16I, GPU_RGBA32I) || ELEM(tex_format, GPU_RGBA8, GPU_RGBA16) ||
ELEM(data_type, GPU_RGBA8UI, GPU_RGBA16UI, GPU_RGBA32UI))) ELEM(tex_format, GPU_RGBA16F, GPU_RGBA32F) ||
ELEM(tex_format, GPU_RGBA8I, GPU_RGBA16I, GPU_RGBA32I) ||
ELEM(tex_format, GPU_RGBA8UI, GPU_RGBA16UI, GPU_RGBA32UI)))
{ {
fprintf(stderr, "GPUTexture: invalid format for texture buffer"); fprintf(stderr, "GPUTexture: invalid format for texture buffer\n");
GPU_texture_free(tex); GPU_texture_free(tex);
return NULL; return NULL;
} }
@@ -663,9 +752,9 @@ GPUTexture *GPU_texture_create_buffer(GPUTextureFormat data_type, const GLuint b
glGenTextures(1, &tex->bindcode); glGenTextures(1, &tex->bindcode);
if (!tex->bindcode) { if (!tex->bindcode) {
fprintf(stderr, "GPUTexture: texture create failed"); fprintf(stderr, "GPUTexture: texture create failed\n");
GPU_texture_free(tex); GPU_texture_free(tex);
BLI_assert(0 && "glGenTextures failled: Are you sure a valid OGL context is active on this thread?"); BLI_assert(0 && "glGenTextures failled: Are you sure a valid OGL context is active on this thread?\n");
return NULL; return NULL;
} }
@@ -766,40 +855,45 @@ GPUTexture *GPU_texture_from_preview(PreviewImage *prv, int mipmap)
} }
GPUTexture *GPU_texture_create_1D( GPUTexture *GPU_texture_create_1D(
int w, GPUTextureFormat data_type, const float *pixels, char err_out[256]) int w, GPUTextureFormat tex_format, const float *pixels, char err_out[256])
{ {
return GPU_texture_create_nD(w, 0, 0, 1, pixels, data_type, 0, false, err_out); GPUDataFormat data_format = gpu_get_data_format_from_tex_format(tex_format);
return GPU_texture_create_nD(w, 0, 0, 1, pixels, tex_format, data_format, 0, false, err_out);
} }
GPUTexture *GPU_texture_create_2D( GPUTexture *GPU_texture_create_2D(
int w, int h, GPUTextureFormat data_type, const float *pixels, char err_out[256]) int w, int h, GPUTextureFormat tex_format, const float *pixels, char err_out[256])
{ {
return GPU_texture_create_nD(w, h, 0, 2, pixels, data_type, 0, false, err_out); GPUDataFormat data_format = gpu_get_data_format_from_tex_format(tex_format);
return GPU_texture_create_nD(w, h, 0, 2, pixels, tex_format, data_format, 0, false, err_out);
} }
GPUTexture *GPU_texture_create_2D_multisample( GPUTexture *GPU_texture_create_2D_multisample(
int w, int h, GPUTextureFormat data_type, const float *pixels, int samples, char err_out[256]) int w, int h, GPUTextureFormat tex_format, const float *pixels, int samples, char err_out[256])
{ {
return GPU_texture_create_nD(w, h, 0, 2, pixels, data_type, samples, false, err_out); GPUDataFormat data_format = gpu_get_data_format_from_tex_format(tex_format);
return GPU_texture_create_nD(w, h, 0, 2, pixels, tex_format, data_format, samples, false, err_out);
} }
GPUTexture *GPU_texture_create_2D_array( GPUTexture *GPU_texture_create_2D_array(
int w, int h, int d, GPUTextureFormat data_type, const float *pixels, char err_out[256]) int w, int h, int d, GPUTextureFormat tex_format, const float *pixels, char err_out[256])
{ {
return GPU_texture_create_nD(w, h, d, 2, pixels, data_type, 0, false, err_out); GPUDataFormat data_format = gpu_get_data_format_from_tex_format(tex_format);
return GPU_texture_create_nD(w, h, d, 2, pixels, tex_format, data_format, 0, false, err_out);
} }
GPUTexture *GPU_texture_create_3D( GPUTexture *GPU_texture_create_3D(
int w, int h, int d, GPUTextureFormat data_type, const float *pixels, char err_out[256]) int w, int h, int d, GPUTextureFormat tex_format, const float *pixels, char err_out[256])
{ {
return GPU_texture_create_nD(w, h, d, 3, pixels, data_type, 0, true, err_out); GPUDataFormat data_format = gpu_get_data_format_from_tex_format(tex_format);
return GPU_texture_create_nD(w, h, d, 3, pixels, tex_format, data_format, 0, true, err_out);
} }
GPUTexture *GPU_texture_create_cube( GPUTexture *GPU_texture_create_cube(
int w, GPUTextureFormat data_type, const float *fpixels, char err_out[256]) int w, GPUTextureFormat tex_format, const float *fpixels, char err_out[256])
{ {
const float *fpixels_px, *fpixels_py, *fpixels_pz, *fpixels_nx, *fpixels_ny, *fpixels_nz; const float *fpixels_px, *fpixels_py, *fpixels_pz, *fpixels_nx, *fpixels_ny, *fpixels_nz;
const int channels = gpu_texture_get_component_count(data_type); const int channels = gpu_get_component_count(tex_format);
if (fpixels) { if (fpixels) {
fpixels_px = fpixels + 0 * w * w * channels; fpixels_px = fpixels + 0 * w * w * channels;
@@ -814,7 +908,7 @@ GPUTexture *GPU_texture_create_cube(
} }
return GPU_texture_cube_create(w, 0, fpixels_px, fpixels_py, fpixels_pz, fpixels_nx, fpixels_ny, fpixels_nz, return GPU_texture_cube_create(w, 0, fpixels_px, fpixels_py, fpixels_pz, fpixels_nx, fpixels_ny, fpixels_nz,
data_type, err_out); tex_format, GPU_DATA_FLOAT, err_out);
} }
GPUTexture *GPU_texture_create_from_vertbuf(Gwn_VertBuf *vert) GPUTexture *GPU_texture_create_from_vertbuf(Gwn_VertBuf *vert)
@@ -886,17 +980,56 @@ GPUTexture *GPU_texture_create_from_vertbuf(Gwn_VertBuf *vert)
return GPU_texture_create_buffer(data_type, vert->vbo_id); return GPU_texture_create_buffer(data_type, vert->vbo_id);
} }
void GPU_texture_add_mipmap(
GPUTexture *tex, GPUDataFormat gpu_data_format, int miplvl, const void *pixels)
{
BLI_assert((int)tex->format > -1);
BLI_assert(tex->components > -1);
gpu_validate_data_format(tex->format, gpu_data_format);
GLenum internalformat = gpu_get_gl_internalformat(tex->format);
GLenum data_format = gpu_get_gl_dataformat(tex->format, &tex->format_flag);
GLenum data_type = gpu_get_gl_datatype(gpu_data_format);
glBindTexture(tex->target, tex->bindcode);
int size[3];
GPU_texture_get_mipmap_size(tex, miplvl, size);
switch (tex->target) {
case GL_TEXTURE_1D:
glTexImage1D(tex->target, miplvl, internalformat, size[0], 0, data_format, data_type, pixels);
break;
case GL_TEXTURE_2D:
case GL_TEXTURE_1D_ARRAY:
glTexImage2D(tex->target, miplvl, internalformat, size[0], size[1], 0, data_format, data_type, pixels);
break;
case GL_TEXTURE_3D:
case GL_TEXTURE_2D_ARRAY:
glTexImage3D(tex->target, miplvl, internalformat, size[0], size[1], size[2], 0, data_format, data_type, pixels);
break;
case GL_TEXTURE_2D_MULTISAMPLE:
/* Multisample textures cannot have mipmaps. */
default:
BLI_assert(!"tex->target mode not supported");
}
glTexParameteri(GPU_texture_target(tex), GL_TEXTURE_MAX_LEVEL, miplvl);
glBindTexture(tex->target, 0);
}
void GPU_texture_update_sub( void GPU_texture_update_sub(
GPUTexture *tex, const void *pixels, GPUTexture *tex, GPUDataFormat gpu_data_format, const void *pixels,
int offset_x, int offset_y, int offset_z, int width, int height, int depth) int offset_x, int offset_y, int offset_z, int width, int height, int depth)
{ {
BLI_assert((int)tex->format > -1); BLI_assert((int)tex->format > -1);
BLI_assert(tex->components > -1); BLI_assert(tex->components > -1);
GLenum format, data_format; GLenum data_format = gpu_get_gl_dataformat(tex->format, &tex->format_flag);
GLenum data_type = gpu_get_gl_datatype(gpu_data_format);
GLint alignment; GLint alignment;
gpu_texture_get_format(tex->components, tex->format, &format, &data_format,
&tex->format_flag, &tex->bytesize);
/* The default pack size for textures is 4, which won't work for byte based textures */ /* The default pack size for textures is 4, which won't work for byte based textures */
if (tex->bytesize == 1) { if (tex->bytesize == 1) {
@@ -906,21 +1039,21 @@ void GPU_texture_update_sub(
glBindTexture(tex->target, tex->bindcode); glBindTexture(tex->target, tex->bindcode);
switch (tex->target) { switch (tex->target) {
case GL_TEXTURE_1D:
glTexSubImage1D(tex->target, 0, offset_x, width, data_format, data_type, pixels);
break;
case GL_TEXTURE_2D: case GL_TEXTURE_2D:
case GL_TEXTURE_2D_MULTISAMPLE: case GL_TEXTURE_2D_MULTISAMPLE:
case GL_TEXTURE_1D_ARRAY: case GL_TEXTURE_1D_ARRAY:
glTexSubImage2D( glTexSubImage2D(
tex->target, 0, offset_x, offset_y, tex->target, 0, offset_x, offset_y,
width, height, format, data_format, pixels); width, height, data_format, data_type, pixels);
break;
case GL_TEXTURE_1D:
glTexSubImage1D(tex->target, 0, offset_x, width, format, data_format, pixels);
break; break;
case GL_TEXTURE_3D: case GL_TEXTURE_3D:
case GL_TEXTURE_2D_ARRAY: case GL_TEXTURE_2D_ARRAY:
glTexSubImage3D( glTexSubImage3D(
tex->target, 0, offset_x, offset_y, offset_z, tex->target, 0, offset_x, offset_y, offset_z,
width, height, depth, format, data_format, pixels); width, height, depth, data_format, data_type, pixels);
break; break;
default: default:
BLI_assert(!"tex->target mode not supported"); BLI_assert(!"tex->target mode not supported");
@@ -933,9 +1066,53 @@ void GPU_texture_update_sub(
glBindTexture(tex->target, 0); glBindTexture(tex->target, 0);
} }
void GPU_texture_update(GPUTexture *tex, const void *pixels) void *GPU_texture_read(GPUTexture *tex, GPUDataFormat gpu_data_format, int miplvl)
{ {
GPU_texture_update_sub(tex, pixels, 0, 0, 0, tex->w, tex->h, tex->d); int size[3] = {0, 0, 0};
GPU_texture_get_mipmap_size(tex, miplvl, size);
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]);
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;
}
void *buf = MEM_mallocN(buf_size, "GPU_texture_read");
GLenum data_format = gpu_get_gl_dataformat(tex->format, &tex->format_flag);
GLenum data_type = gpu_get_gl_datatype(gpu_data_format);
glBindTexture(tex->target, tex->bindcode);
glGetTexImage(tex->target, miplvl, data_format, data_type, buf);
glBindTexture(tex->target, 0);
return buf;
}
void GPU_texture_update(GPUTexture *tex, GPUDataFormat data_format, const void *pixels)
{
GPU_texture_update_sub(tex, data_format, pixels, 0, 0, 0, tex->w, tex->h, tex->d);
} }
void GPU_invalid_tex_init(void) void GPU_invalid_tex_init(void)
@@ -1199,6 +1376,11 @@ int GPU_texture_height(const GPUTexture *tex)
return tex->h; return tex->h;
} }
int GPU_texture_layers(const GPUTexture *tex)
{
return tex->d;
}
GPUTextureFormat GPU_texture_format(const GPUTexture *tex) GPUTextureFormat GPU_texture_format(const GPUTexture *tex)
{ {
return tex->format; return tex->format;
@@ -1260,3 +1442,24 @@ int GPU_texture_detach_framebuffer(GPUTexture *tex, GPUFrameBuffer *fb)
BLI_assert(!"Error: Texture: Framebuffer is not attached"); BLI_assert(!"Error: Texture: Framebuffer is not attached");
return 0; return 0;
} }
void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *size)
{
/* TODO assert if lvl is bellow the limit of 1px in each dimension. */
int div = 1 << lvl;
size[0] = max_ii(1, tex->w / div);
if (tex->target == GL_TEXTURE_1D_ARRAY) {
size[1] = tex->h;
}
else if (tex->h > 0) {
size[1] = max_ii(1, tex->h / div);
}
if (tex->target == GL_TEXTURE_2D_ARRAY) {
size[2] = tex->d;
}
else if (tex->d > 0) {
size[2] = max_ii(1, tex->d / div);
}
}

View File

@@ -45,6 +45,27 @@ struct ID;
struct PackedFile; struct PackedFile;
struct GPUTexture; struct GPUTexture;
/* Runtime display data */
struct DrawData;
typedef void (*DrawDataInitCb)(struct DrawData *engine_data);
typedef void (*DrawDataFreeCb)(struct DrawData *engine_data);
#
#
typedef struct DrawData {
struct DrawData *next, *prev;
struct DrawEngineType *engine_type;
/* Only nested data, NOT the engine data itself. */
DrawDataFreeCb free;
/* Accumulated recalc flags, which corresponds to ID->recalc flags. */
int recalc;
} DrawData;
typedef struct DrawDataList {
struct DrawData *first, *last;
} DrawDataList;
typedef struct IDPropertyData { typedef struct IDPropertyData {
void *pointer; void *pointer;
ListBase group; ListBase group;

View File

@@ -106,6 +106,78 @@ enum {
LIGHTPROBE_SHAPE_BOX = 1, LIGHTPROBE_SHAPE_BOX = 1,
}; };
/* ------- Eevee LightProbes ------- */
/* Needs to be there because written to file
* with the lightcache. */
typedef struct LightProbeCache {
float position[3], parallax_type;
float attenuation_fac;
float attenuation_type;
float pad3[2];
float attenuationmat[4][4];
float parallaxmat[4][4];
} LightProbeCache;
typedef struct LightGridCache {
float mat[4][4];
int resolution[3], offset; /* offset to the first irradiance sample in the pool. */
float corner[3], attenuation_scale;
float increment_x[3], attenuation_bias; /* world space vector between 2 opposite cells */
float increment_y[3], level_bias;
float increment_z[3], pad4;
float visibility_bias, visibility_bleed, visibility_range, pad5;
} LightGridCache;
/* ------ Eevee Lightcache ------- */
typedef struct LightCacheTexture {
struct GPUTexture *tex;
/* Copy of GPU datas to create GPUTextures on file read. */
char *data;
int tex_size[3];
char data_type;
char components;
char pad[2];
} LightCacheTexture;
typedef struct LightCache {
int flag;
/* only a single cache for now */
int cube_len, grid_len; /* Number of probes to use for rendering. */
int mips_len; /* Number of mipmap level to use. */
int vis_res, ref_res; /* Size of a visibility/reflection sample. */
int pad[2];
/* In the future, we could create a bigger texture containing
* multiple caches (for animation) and interpolate between the
* caches overtime to another texture. */
LightCacheTexture grid_tx;
LightCacheTexture cube_tx; /* Contains data for mipmap level 0. */
LightCacheTexture *cube_mips; /* Does not contains valid GPUTexture, only data. */
/* All lightprobes data contained in the cache. */
LightProbeCache *cube_data;
LightGridCache *grid_data;
} LightCache;
/* LightCache->flag */
enum {
LIGHTCACHE_BAKED = (1 << 0),
LIGHTCACHE_BAKING = (1 << 1),
LIGHTCACHE_CUBE_READY = (1 << 2),
LIGHTCACHE_GRID_READY = (1 << 3),
/* Update tagging */
LIGHTCACHE_UPDATE_CUBE = (1 << 4),
LIGHTCACHE_UPDATE_GRID = (1 << 5),
LIGHTCACHE_UPDATE_WORLD = (1 << 6),
};
/* EEVEE_LightCacheTexture->data_type */
enum {
LIGHTCACHETEX_BYTE = (1 << 0),
LIGHTCACHETEX_FLOAT = (1 << 1),
LIGHTCACHETEX_UINT = (1 << 2),
};
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -76,22 +76,6 @@ typedef struct bFaceMap {
char pad[7]; char pad[7];
} bFaceMap; } bFaceMap;
/* Object Runtime display data */
struct ObjectEngineData;
typedef void (*ObjectEngineDataInitCb)(struct ObjectEngineData *engine_data);
typedef void (*ObjectEngineDataFreeCb)(struct ObjectEngineData *engine_data);
#
#
typedef struct ObjectEngineData {
struct ObjectEngineData *next, *prev;
struct DrawEngineType *engine_type;
/* Only nested data, NOT the engine data itself. */
ObjectEngineDataFreeCb free;
/* Accumulated recalc flags, which corresponds to ID->recalc flags. */
int recalc;
} ObjectEngineData;
#define MAX_VGROUP_NAME 64 #define MAX_VGROUP_NAME 64
/* bDeformGroup->flag */ /* bDeformGroup->flag */
@@ -163,6 +147,7 @@ typedef struct Object_Runtime {
typedef struct Object { typedef struct Object {
ID id; ID id;
struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */ struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */
struct DrawDataList drawdata; /* runtime (must be immediately after id for utilities to use it). */
struct SculptSession *sculpt; struct SculptSession *sculpt;
@@ -312,7 +297,6 @@ typedef struct Object {
struct PreviewImage *preview; struct PreviewImage *preview;
ListBase drawdata; /* runtime, ObjectEngineData */
int pad6; int pad6;
int select_color; int select_color;

View File

@@ -1389,6 +1389,9 @@ typedef struct SceneEEVEE {
int gi_cubemap_resolution; int gi_cubemap_resolution;
int gi_visibility_resolution; int gi_visibility_resolution;
float gi_cubemap_draw_size;
float gi_irradiance_draw_size;
int taa_samples; int taa_samples;
int taa_render_samples; int taa_render_samples;
int sss_samples; int sss_samples;
@@ -1428,6 +1431,9 @@ typedef struct SceneEEVEE {
int shadow_method; int shadow_method;
int shadow_cube_size; int shadow_cube_size;
int shadow_cascade_size; int shadow_cascade_size;
struct LightCache *light_cache;
char light_cache_info[64];
} SceneEEVEE; } SceneEEVEE;
/* *************************************************************** */ /* *************************************************************** */
@@ -2101,6 +2107,9 @@ enum {
SCE_EEVEE_SSR_ENABLED = (1 << 14), SCE_EEVEE_SSR_ENABLED = (1 << 14),
SCE_EEVEE_SSR_REFRACTION = (1 << 15), SCE_EEVEE_SSR_REFRACTION = (1 << 15),
SCE_EEVEE_SSR_HALF_RESOLUTION = (1 << 16), SCE_EEVEE_SSR_HALF_RESOLUTION = (1 << 16),
SCE_EEVEE_SHOW_IRRADIANCE = (1 << 17),
SCE_EEVEE_SHOW_CUBEMAPS = (1 << 18),
SCE_EEVEE_GI_AUTOBAKE = (1 << 19),
}; };
/* SceneEEVEE->shadow_method */ /* SceneEEVEE->shadow_method */

View File

@@ -51,6 +51,7 @@ struct MTex;
typedef struct World { typedef struct World {
ID id; ID id;
struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */ struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */
DrawDataList drawdata; /* runtime (must be immediately after id for utilities to use it). */
char _pad0[4]; char _pad0[4];
short texact, mistype; short texact, mistype;
@@ -81,8 +82,7 @@ typedef struct World {
short flag, pad3[3]; short flag, pad3[3];
struct Ipo *ipo DNA_DEPRECATED; /* old animation system, deprecated for 2.5 */ struct Ipo *ipo DNA_DEPRECATED; /* old animation system, deprecated for 2.5 */
short pr_texture, use_nodes, pad; short pr_texture, use_nodes, pad[2];
short update_flag; /* XXX temporary flag waiting for depsgraph proper tagging */
/* previews */ /* previews */
struct PreviewImage *preview; struct PreviewImage *preview;

View File

@@ -5814,6 +5814,38 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
"Size of the shadow map applied to each irradiance sample"); "Size of the shadow map applied to each irradiance sample");
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "gi_show_irradiance", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SHOW_IRRADIANCE);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "Show Irradiance Cache", "Display irradiance samples in the viewport");
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "gi_show_cubemaps", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SHOW_CUBEMAPS);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "Show Cubemap Cache", "Display captured cubemaps in the viewport");
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "gi_irradiance_draw_size", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.05f, 10.0f);
RNA_def_property_float_default(prop, 0.2f);
RNA_def_property_ui_text(prop, "Irradiance Draw Size", "Size of the irradiance sample spheres to debug captured light");
prop = RNA_def_property(srna, "gi_cubemap_draw_size", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.05f, 10.0f);
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_ui_text(prop, "Cubemap Draw Size", "Size of the cubemap spheres to debug captured light");
prop = RNA_def_property(srna, "gi_auto_bake", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_GI_AUTOBAKE);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "Auto Bake", "Auto bake indirect lighting when editing probes");
prop = RNA_def_property(srna, "gi_cache_info", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "light_cache_info");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Light Cache Info", "Info on current cache status");
/* Temporal Anti-Aliasing (super sampling) */ /* Temporal Anti-Aliasing (super sampling) */
prop = RNA_def_property(srna, "taa_samples", PROP_INT, PROP_NONE); prop = RNA_def_property(srna, "taa_samples", PROP_INT, PROP_NONE);
RNA_def_property_int_default(prop, 16); RNA_def_property_int_default(prop, 16);

View File

@@ -524,6 +524,7 @@ enum {
WM_JOB_TYPE_ALEMBIC, WM_JOB_TYPE_ALEMBIC,
WM_JOB_TYPE_SHADER_COMPILATION, WM_JOB_TYPE_SHADER_COMPILATION,
WM_JOB_TYPE_STUDIOLIGHT, WM_JOB_TYPE_STUDIOLIGHT,
WM_JOB_TYPE_LIGHT_BAKE,
/* add as needed, screencast, seq proxy build /* add as needed, screencast, seq proxy build
* if having hard coded values is a problem */ * if having hard coded values is a problem */
}; };

View File

@@ -257,6 +257,7 @@ typedef struct wmNotifier {
#define NC_GPENCIL (22<<24) #define NC_GPENCIL (22<<24)
#define NC_LINESTYLE (23<<24) #define NC_LINESTYLE (23<<24)
#define NC_CAMERA (24<<24) #define NC_CAMERA (24<<24)
#define NC_LIGHTPROBE (25<<24)
/* data type, 256 entries is enough, it can overlap */ /* data type, 256 entries is enough, it can overlap */
#define NOTE_DATA 0x00FF0000 #define NOTE_DATA 0x00FF0000