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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2018-03-01 21:27:38 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-03-02 20:35:59 +0300
commitd63829117c21c0d926cf0a9df645c3ed5cd8057a (patch)
tree5497f58c4b52cd894f4811fb35da3727fb059d8f /source/blender
parent62390527b2e9b6a6a2939df120f87b5b2a54e74b (diff)
DRW: Refactor simple instancing.
Instead of creating a new instancing shading group without attrib, we now have instancing calls. The benefits is that they can be culled. They can be used in conjuction with the standard and generate calls but shader must support it (which is generally not the case). We store a pointer to the actual count so that the number can be tweaked between redraw. This will makes multi layer rendering more efficient.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/draw/engines/eevee/eevee_effects.c6
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c3
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightprobes.c19
-rw-r--r--source/blender/draw/engines/eevee/eevee_lights.c51
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c8
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h8
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c2
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_vert.glsl4
-rw-r--r--source/blender/draw/intern/DRW_render.h8
-rw-r--r--source/blender/draw/intern/draw_manager.h6
-rw-r--r--source/blender/draw/intern/draw_manager_data.c60
-rw-r--r--source/blender/draw/intern/draw_manager_exec.c37
-rw-r--r--source/blender/draw/modes/object_mode.c7
13 files changed, 112 insertions, 107 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index 3427bb1d397..1030fe1ce3a 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -240,13 +240,13 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
static int zero = 0;
+ static unsigned int six = 6;
psl->color_downsample_cube_ps = DRW_pass_create("Downsample Cube", DRW_STATE_WRITE_COLOR);
- DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.downsample_cube_sh, psl->color_downsample_cube_ps,
- quad, NULL);
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.downsample_cube_sh, psl->color_downsample_cube_ps);
DRW_shgroup_uniform_buffer(grp, "source", &e_data.color_src);
DRW_shgroup_uniform_float(grp, "texelSize", &e_data.cube_texel_size, 1);
DRW_shgroup_uniform_int(grp, "Layer", &zero, 1);
- DRW_shgroup_set_instance_count(grp, 6);
+ DRW_shgroup_call_instances_add(grp, quad, NULL, &six);
}
{
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index ded927d19f7..406d0ff7049 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -96,14 +96,13 @@ static void eevee_engine_init(void *ved)
static void eevee_cache_init(void *vedata)
{
- EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
EEVEE_bloom_cache_init(sldata, vedata);
EEVEE_depth_of_field_cache_init(sldata, vedata);
EEVEE_effects_cache_init(sldata, vedata);
EEVEE_lightprobes_cache_init(sldata, vedata);
- EEVEE_lights_cache_init(sldata, psl);
+ EEVEE_lights_cache_init(sldata, vedata);
EEVEE_materials_cache_init(vedata);
EEVEE_motion_blur_cache_init(sldata, vedata);
EEVEE_occlusion_cache_init(sldata, vedata);
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index b4de6081457..cf6d1e153dc 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -538,14 +538,10 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
{
psl->probe_planar_downsample_ps = DRW_pass_create("LightProbe Planar Downsample", DRW_STATE_WRITE_COLOR);
- struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
- DRWShadingGroup *grp = DRW_shgroup_instance_create(
- e_data.probe_planar_downsample_sh,
- psl->probe_planar_downsample_ps,
- geom, NULL);
- stl->g_data->planar_downsample = grp;
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.probe_planar_downsample_sh, psl->probe_planar_downsample_ps);
DRW_shgroup_uniform_buffer(grp, "source", &txl->planar_pool);
DRW_shgroup_uniform_float(grp, "fireflyFactor", &sldata->common_data.ssr_firefly_fac, 1);
+ DRW_shgroup_call_instances_add(grp, DRW_cache_fullscreen_quad_get(), NULL, (unsigned int *)&pinfo->num_planar);
}
}
@@ -846,12 +842,7 @@ static void EEVEE_lightprobes_updates(EEVEE_ViewLayerData *sldata, EEVEE_PassLis
if (DRW_state_draw_support() &&
(probe->flag & LIGHTPROBE_FLAG_SHOW_DATA))
{
- struct Gwn_Batch *geom = DRW_cache_sphere_get();
- DRWShadingGroup *grp = DRW_shgroup_instance_create(
- e_data.probe_grid_display_sh,
- psl->probe_display,
- geom, NULL);
- DRW_shgroup_set_instance_count(grp, ped->num_cell);
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.probe_grid_display_sh, psl->probe_display);
DRW_shgroup_uniform_int(grp, "offset", &egrid->offset, 1);
DRW_shgroup_uniform_ivec3(grp, "grid_resolution", egrid->resolution, 1);
DRW_shgroup_uniform_vec3(grp, "corner", egrid->corner, 1);
@@ -860,6 +851,7 @@ static void EEVEE_lightprobes_updates(EEVEE_ViewLayerData *sldata, EEVEE_PassLis
DRW_shgroup_uniform_vec3(grp, "increment_z", egrid->increment_z, 1);
DRW_shgroup_uniform_buffer(grp, "irradianceGrid", &sldata->irradiance_pool);
DRW_shgroup_uniform_float(grp, "sphere_size", &probe->data_draw_size, 1);
+ DRW_shgroup_call_instances_add(grp, DRW_cache_sphere_get(), NULL, (unsigned int *)&ped->num_cell);
}
}
}
@@ -898,9 +890,6 @@ void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ved
/* XXX this should be run each frame as it ensure planar_depth is set */
planar_pool_ensure_alloc(vedata, pinfo->num_planar);
- /* Setup planar filtering pass */
- DRW_shgroup_set_instance_count(stl->g_data->planar_downsample, pinfo->num_planar);
-
if (!sldata->probe_pool) {
sldata->probe_pool = DRW_texture_create_2D_array(pinfo->cubemap_res, pinfo->cubemap_res, max_ff(1, pinfo->num_cube),
DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index 635f713c8ae..9eb6a761e1d 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -205,9 +205,11 @@ void EEVEE_lights_init(EEVEE_ViewLayerData *sldata)
}
}
-void EEVEE_lights_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl)
+void EEVEE_lights_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_LampsInfo *linfo = sldata->lamps;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_PassList *psl = vedata->psl;
linfo->shcaster_frontbuffer->count = 0;
linfo->num_light = 0;
@@ -271,15 +273,11 @@ void EEVEE_lights_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl)
}
{
- psl->shadow_cube_pass = DRW_pass_create(
- "Shadow Cube Pass",
- DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
- }
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS;
+ psl->shadow_pass = DRW_pass_create("Shadow Pass", state);
- {
- psl->shadow_cascade_pass = DRW_pass_create(
- "Shadow Cascade Pass",
- DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+ DRWShadingGroup *grp = stl->g_data->shadow_shgrp = DRW_shgroup_create(e_data.shadow_sh, psl->shadow_pass);
+ DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
}
}
@@ -378,24 +376,20 @@ void EEVEE_lights_cache_add(EEVEE_ViewLayerData *sldata, Object *ob)
/* Add a shadow caster to the shadowpasses */
void EEVEE_lights_cache_shcaster_add(
- EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl, struct Gwn_Batch *geom, float (*obmat)[4])
+ EEVEE_ViewLayerData *sldata, EEVEE_StorageList *stl, struct Gwn_Batch *geom, Object *ob)
{
- DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.shadow_sh, psl->shadow_cube_pass, geom, NULL);
- DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
- DRW_shgroup_uniform_mat4(grp, "ShadowModelMatrix", (float *)obmat);
- DRW_shgroup_set_instance_count(grp, 6);
-
- grp = DRW_shgroup_instance_create(e_data.shadow_sh, psl->shadow_cascade_pass, geom, NULL);
- DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
- DRW_shgroup_uniform_mat4(grp, "ShadowModelMatrix", (float *)obmat);
- DRW_shgroup_set_instance_count(grp, MAX_CASCADE_NUM);
+ DRW_shgroup_call_object_instances_add(
+ stl->g_data->shadow_shgrp,
+ geom, ob,
+ &sldata->lamps->shadow_instance_count);
}
void EEVEE_lights_cache_shcaster_material_add(
EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl, struct GPUMaterial *gpumat,
struct Gwn_Batch *geom, struct Object *ob, float (*obmat)[4], float *alpha_threshold)
{
- DRWShadingGroup *grp = DRW_shgroup_material_instance_create(gpumat, psl->shadow_cube_pass, geom, ob, NULL);
+ /* TODO / PERF : reuse the same shading group for objects with the same material */
+ DRWShadingGroup *grp = DRW_shgroup_material_create(gpumat, psl->shadow_pass);
if (grp == NULL) return;
@@ -405,16 +399,7 @@ void EEVEE_lights_cache_shcaster_material_add(
if (alpha_threshold != NULL)
DRW_shgroup_uniform_float(grp, "alphaThreshold", alpha_threshold, 1);
- DRW_shgroup_set_instance_count(grp, 6);
-
- grp = DRW_shgroup_material_instance_create(gpumat, psl->shadow_cascade_pass, geom, ob, NULL);
- DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
- DRW_shgroup_uniform_mat4(grp, "ShadowModelMatrix", (float *)obmat);
-
- if (alpha_threshold != NULL)
- DRW_shgroup_uniform_float(grp, "alphaThreshold", alpha_threshold, 1);
-
- DRW_shgroup_set_instance_count(grp, MAX_CASCADE_NUM);
+ DRW_shgroup_call_object_instances_add(grp, geom, ob, &sldata->lamps->shadow_instance_count);
}
/* Make that object update shadow casting lamps inside its influence bounding box. */
@@ -1036,7 +1021,8 @@ void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl)
DRW_framebuffer_clear(true, true, false, clear_col, 1.0f);
/* Render shadow cube */
- DRW_draw_pass(psl->shadow_cube_pass);
+ linfo->shadow_instance_count = 6;
+ DRW_draw_pass(psl->shadow_pass);
/* 0.001f is arbitrary, but it should be relatively small so that filter size is not too big. */
float filter_texture_size = la->soft * 0.001f;
@@ -1110,7 +1096,8 @@ void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl)
DRW_framebuffer_clear(false, true, false, NULL, 1.0);
/* Render shadow cascades */
- DRW_draw_pass(psl->shadow_cascade_pass);
+ linfo->shadow_instance_count = la->cascade_count;
+ DRW_draw_pass(psl->shadow_pass);
/* TODO: OPTI: Filter all cascade in one/two draw call */
for (linfo->current_shadow_cascade = 0;
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 0e444039573..31ef26a1e9e 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -1232,8 +1232,8 @@ static void material_transparent(
void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob)
{
- EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
- EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_StorageList *stl = vedata->stl;
const DRWContextState *draw_ctx = DRW_context_state_get();
Scene *scene = draw_ctx->scene;
GHash *material_hash = stl->g_data->material_hash;
@@ -1349,7 +1349,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld
struct GPUMaterial *gpumat;
switch (ma->blend_shadow) {
case MA_BS_SOLID:
- EEVEE_lights_cache_shcaster_add(sldata, psl, mat_geom[i], ob->obmat);
+ EEVEE_lights_cache_shcaster_add(sldata, stl, mat_geom[i], ob);
break;
case MA_BS_CLIP:
gpumat = EEVEE_material_mesh_depth_get(scene, ma, false, true);
@@ -1365,7 +1365,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld
}
}
else {
- EEVEE_lights_cache_shcaster_add(sldata, psl, mat_geom[i], ob->obmat);
+ EEVEE_lights_cache_shcaster_add(sldata, stl, mat_geom[i], ob);
}
}
}
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index dc059e0b084..fa23d6f72ef 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -142,10 +142,8 @@ typedef struct EEVEE_BoundBox {
typedef struct EEVEE_PassList {
/* Shadows */
struct DRWPass *shadow_pass;
- struct DRWPass *shadow_cube_pass;
struct DRWPass *shadow_cube_copy_pass;
struct DRWPass *shadow_cube_store_pass;
- struct DRWPass *shadow_cascade_pass;
struct DRWPass *shadow_cascade_copy_pass;
struct DRWPass *shadow_cascade_store_pass;
@@ -367,6 +365,7 @@ typedef struct EEVEE_LampsInfo {
int shadow_cube_target_size;
int current_shadow_cascade;
int current_shadow_face;
+ unsigned int shadow_instance_count;
float filter_size;
/* List of lights in the scene. */
/* XXX This is fragile, can get out of sync quickly. */
@@ -734,7 +733,6 @@ typedef struct EEVEE_PrivateData {
struct DRWShadingGroup *refract_depth_shgrp_clip_cull;
struct DRWShadingGroup *cube_display_shgrp;
struct DRWShadingGroup *planar_display_shgrp;
- struct DRWShadingGroup *planar_downsample;
struct GHash *material_hash;
struct GHash *hair_material_hash;
struct GPUTexture *minzbuffer;
@@ -785,10 +783,10 @@ void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const d
/* eevee_lights.c */
void EEVEE_lights_init(EEVEE_ViewLayerData *sldata);
-void EEVEE_lights_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl);
+void EEVEE_lights_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_lights_cache_add(EEVEE_ViewLayerData *sldata, struct Object *ob);
void EEVEE_lights_cache_shcaster_add(
- EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl, struct Gwn_Batch *geom, float (*obmat)[4]);
+ EEVEE_ViewLayerData *sldata, EEVEE_StorageList *stl, struct Gwn_Batch *geom, Object *ob);
void EEVEE_lights_cache_shcaster_material_add(
EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl,
struct GPUMaterial *gpumat, struct Gwn_Batch *geom, struct Object *ob,
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index 673532dd304..b86edad9d14 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -115,7 +115,7 @@ void EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
EEVEE_depth_of_field_cache_init(sldata, vedata);
EEVEE_effects_cache_init(sldata, vedata);
EEVEE_lightprobes_cache_init(sldata, vedata);
- EEVEE_lights_cache_init(sldata, psl);
+ EEVEE_lights_cache_init(sldata, vedata);
EEVEE_materials_cache_init(vedata);
EEVEE_motion_blur_cache_init(sldata, vedata);
EEVEE_occlusion_cache_init(sldata, vedata);
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
index 777902ccba8..29cbcfdd6e4 100644
--- a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
@@ -1,5 +1,5 @@
-uniform mat4 ShadowModelMatrix;
+uniform mat4 ModelMatrix;
#ifdef MESH_SHADER
uniform mat3 WorldNormalMatrix;
#endif
@@ -17,7 +17,7 @@ out vec3 vNor;
flat out int face;
void main() {
- vPos = ShadowModelMatrix * vec4(pos, 1.0);
+ vPos = ModelMatrix * vec4(pos, 1.0);
face = gl_InstanceID;
#ifdef MESH_SHADER
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index c83b67b00e5..1713960597e 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -347,6 +347,11 @@ void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct Gwn_Batch *batc
void DRW_shgroup_free(struct DRWShadingGroup *shgroup);
void DRW_shgroup_call_add(DRWShadingGroup *shgroup, struct Gwn_Batch *geom, float (*obmat)[4]);
void DRW_shgroup_call_object_add(DRWShadingGroup *shgroup, struct Gwn_Batch *geom, struct Object *ob);
+/* Used for drawing a batch with instancing without instance attribs. */
+void DRW_shgroup_call_instances_add(
+ DRWShadingGroup *shgroup, struct Gwn_Batch *geom, float (*obmat)[4], unsigned int *count);
+void DRW_shgroup_call_object_instances_add(
+ DRWShadingGroup *shgroup, struct Gwn_Batch *geom, struct Object *ob, unsigned int *count);
void DRW_shgroup_call_sculpt_add(DRWShadingGroup *shgroup, struct Object *ob, float (*obmat)[4]);
void DRW_shgroup_call_generate_add(
DRWShadingGroup *shgroup, DRWCallGenerateFn *geometry_fn, void *user_data, float (*obmat)[4]);
@@ -355,8 +360,7 @@ void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *at
const void *array[] = {__VA_ARGS__}; \
DRW_shgroup_call_dynamic_add_array(shgroup, array, (sizeof(array) / sizeof(*array))); \
} while (0)
-/* Use this to set a high number of instances. */
-void DRW_shgroup_set_instance_count(DRWShadingGroup *shgroup, unsigned int count);
+
unsigned int DRW_shgroup_get_instance_count(const DRWShadingGroup *shgroup);
void DRW_shgroup_state_enable(DRWShadingGroup *shgroup, DRWState state);
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index a037915fff1..58973471c4e 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -128,6 +128,7 @@ typedef struct DRWCallState {
typedef enum {
DRW_CALL_SINGLE, /* A single batch */
+ DRW_CALL_INSTANCES, /* Draw instances without any instancing attribs. */
DRW_CALL_GENERATE, /* Uses a callback to draw with any number of batches. */
} DRWCallType;
@@ -139,6 +140,11 @@ typedef struct DRWCall {
struct { /* type == DRW_CALL_SINGLE */
Gwn_Batch *geometry;
} single;
+ struct { /* type == DRW_CALL_INSTANCES */
+ Gwn_Batch *geometry;
+ /* Count can be adjusted between redraw. If needed, we can add fixed count. */
+ unsigned int *count;
+ } instances;
struct { /* type == DRW_CALL_GENERATE */
DRWCallGenerateFn *geometry_fn;
void *user_data;
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index b955bd3000c..fd4652a0305 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -335,6 +335,41 @@ void DRW_shgroup_call_object_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, Obje
BLI_LINKS_APPEND(&shgroup->calls, call);
}
+void DRW_shgroup_call_instances_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, float (*obmat)[4], unsigned int *count)
+{
+ BLI_assert(geom != NULL);
+ BLI_assert(shgroup->type == DRW_SHG_NORMAL);
+
+ DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
+ call->state = drw_call_state_create(shgroup, obmat, NULL);
+ call->type = DRW_CALL_INSTANCES;
+ call->instances.geometry = geom;
+ call->instances.count = count;
+#ifdef USE_GPU_SELECT
+ call->select_id = DST.select_id;
+#endif
+
+ BLI_LINKS_APPEND(&shgroup->calls, call);
+}
+
+/* These calls can be culled and are optimized for redraw */
+void DRW_shgroup_call_object_instances_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, Object *ob, unsigned int *count)
+{
+ BLI_assert(geom != NULL);
+ BLI_assert(shgroup->type == DRW_SHG_NORMAL);
+
+ DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
+ call->state = drw_call_state_object(shgroup, ob->obmat, ob);
+ call->type = DRW_CALL_INSTANCES;
+ call->instances.geometry = geom;
+ call->instances.count = count;
+#ifdef USE_GPU_SELECT
+ call->select_id = DST.select_id;
+#endif
+
+ BLI_LINKS_APPEND(&shgroup->calls, call);
+}
+
void DRW_shgroup_call_generate_add(
DRWShadingGroup *shgroup,
DRWCallGenerateFn *geometry_fn, void *user_data,
@@ -466,18 +501,17 @@ static void drw_interface_instance_init(
{
BLI_assert(shgroup->type == DRW_SHG_INSTANCE);
BLI_assert(batch != NULL);
+ BLI_assert(format != NULL);
drw_interface_init(shgroup, shader);
shgroup->instance_geom = batch;
#ifndef NDEBUG
- shgroup->attribs_count = (format != NULL) ? format->attrib_ct : 0;
+ shgroup->attribs_count = format->attrib_ct;
#endif
- if (format != NULL) {
- DRW_instancing_buffer_request(DST.idatalist, format, batch, shgroup,
- &shgroup->instance_geom, &shgroup->instance_vbo);
- }
+ DRW_instancing_buffer_request(DST.idatalist, format, batch, shgroup,
+ &shgroup->instance_geom, &shgroup->instance_vbo);
}
static void drw_interface_batching_init(
@@ -741,22 +775,6 @@ void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct Gwn_Batch *batc
#endif
}
-/* Used for instancing with no attributes */
-void DRW_shgroup_set_instance_count(DRWShadingGroup *shgroup, unsigned int count)
-{
- BLI_assert(shgroup->type == DRW_SHG_INSTANCE);
- BLI_assert(shgroup->instance_count == 0);
- BLI_assert(shgroup->attribs_count == 0);
-
-#ifdef USE_GPU_SELECT
- if (G.f & G_PICKSEL) {
- shgroup->override_selectid = DST.select_id;
- }
-#endif
-
- shgroup->instance_count = count;
-}
-
unsigned int DRW_shgroup_get_instance_count(const DRWShadingGroup *shgroup)
{
return shgroup->instance_count;
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index 0cdf5d78a43..055baff6a96 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -618,7 +618,7 @@ static void draw_geometry_prepare(DRWShadingGroup *shgroup, DRWCallState *state)
}
static void draw_geometry_execute_ex(
- DRWShadingGroup *shgroup, Gwn_Batch *geom, unsigned int start, unsigned int count)
+ DRWShadingGroup *shgroup, Gwn_Batch *geom, unsigned int start, unsigned int count, bool draw_instance)
{
/* Special case: empty drawcall, placement is done via shader, don't bind anything. */
if (geom == NULL) {
@@ -632,18 +632,15 @@ static void draw_geometry_execute_ex(
GWN_batch_program_set_no_use(geom, GPU_shader_get_program(shgroup->shader), GPU_shader_get_interface(shgroup->shader));
/* XXX hacking gawain. we don't want to call glUseProgram! (huge performance loss) */
geom->program_in_use = true;
- if (ELEM(shgroup->type, DRW_SHG_INSTANCE, DRW_SHG_INSTANCE_EXTERNAL)) {
- GWN_batch_draw_range_ex(geom, start, count, true);
- }
- else {
- GWN_batch_draw_range(geom, start, count);
- }
+
+ GWN_batch_draw_range_ex(geom, start, count, draw_instance);
+
geom->program_in_use = false; /* XXX hacking gawain */
}
static void draw_geometry_execute(DRWShadingGroup *shgroup, Gwn_Batch *geom)
{
- draw_geometry_execute_ex(shgroup, geom, 0, 0);
+ draw_geometry_execute_ex(shgroup, geom, 0, 0, false);
}
static void bind_texture(GPUTexture *tex)
@@ -817,7 +814,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
if (shgroup->instance_geom != NULL) {
GPU_SELECT_LOAD_IF_PICKSEL(shgroup->override_selectid);
draw_geometry_prepare(shgroup, NULL);
- draw_geometry_execute(shgroup, shgroup->instance_geom);
+ draw_geometry_execute_ex(shgroup, shgroup->instance_geom, 0, 0, true);
}
}
else {
@@ -826,7 +823,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
draw_geometry_prepare(shgroup, NULL);
GPU_SELECT_LOAD_IF_PICKSEL_LIST(shgroup, start, count)
{
- draw_geometry_execute_ex(shgroup, shgroup->instance_geom, start, count);
+ draw_geometry_execute_ex(shgroup, shgroup->instance_geom, start, count, true);
}
GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(start, count)
}
@@ -839,7 +836,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
draw_geometry_prepare(shgroup, NULL);
GPU_SELECT_LOAD_IF_PICKSEL_LIST(shgroup, start, count)
{
- draw_geometry_execute_ex(shgroup, shgroup->batch_geom, start, count);
+ draw_geometry_execute_ex(shgroup, shgroup->batch_geom, start, count, false);
}
GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(start, count)
}
@@ -865,12 +862,18 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
GPU_SELECT_LOAD_IF_PICKSEL_CALL(call);
draw_geometry_prepare(shgroup, call->state);
- if (call->type == DRW_CALL_SINGLE) {
- draw_geometry_execute(shgroup, call->single.geometry);
- }
- else {
- BLI_assert(call->type == DRW_CALL_GENERATE);
- call->generate.geometry_fn(shgroup, draw_geometry_execute, call->generate.user_data);
+ switch (call->type) {
+ case DRW_CALL_SINGLE:
+ draw_geometry_execute(shgroup, call->single.geometry);
+ break;
+ case DRW_CALL_INSTANCES:
+ draw_geometry_execute_ex(shgroup, call->instances.geometry, 0, *call->instances.count, true);
+ break;
+ case DRW_CALL_GENERATE:
+ call->generate.geometry_fn(shgroup, draw_geometry_execute, call->generate.user_data);
+ break;
+ default:
+ BLI_assert(0);
}
}
/* Reset state */
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index 0ae5352f4c9..ded2bc68062 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -1547,6 +1547,7 @@ typedef struct OBJECT_LightProbeEngineData {
float increment_y[3];
float increment_z[3];
float corner[3];
+ unsigned int cell_count;
} OBJECT_LightProbeEngineData;
static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, OBJECT_PassList *psl, Object *ob, ViewLayer *view_layer)
@@ -1600,9 +1601,8 @@ static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, OBJECT_PassList *psl
mul_m4_v3(ob->obmat, prb_data->increment_z);
sub_v3_v3(prb_data->increment_z, prb_data->corner);
- DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.lightprobe_grid_sh, psl->lightprobes,
- DRW_cache_sphere_get(), NULL);
- DRW_shgroup_set_instance_count(grp, prb->grid_resolution_x * prb->grid_resolution_y * prb->grid_resolution_z);
+ prb_data->cell_count = prb->grid_resolution_x * prb->grid_resolution_y * prb->grid_resolution_z;
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.lightprobe_grid_sh, psl->lightprobes);
DRW_shgroup_uniform_vec4(grp, "color", color, 1);
DRW_shgroup_uniform_vec3(grp, "corner", prb_data->corner, 1);
DRW_shgroup_uniform_vec3(grp, "increment_x", prb_data->increment_x, 1);
@@ -1610,6 +1610,7 @@ static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, OBJECT_PassList *psl
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_float(grp, "sphere_size", &prb->data_draw_size, 1);
+ DRW_shgroup_call_instances_add(grp, DRW_cache_sphere_get(), NULL, &prb_data->cell_count);
}
else if (prb->type == LIGHTPROBE_TYPE_CUBE) {
prb_data->draw_size = prb->data_draw_size * 0.1f;