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>2019-05-31 02:45:41 +0300
committerClément Foucault <foucault.clem@gmail.com>2019-09-13 18:32:18 +0300
commitce34a6b0d727bbde6ae373afa8ec6c42bc8980ce (patch)
treef8cc84f7e2038f2a81ac0141d79205f1df649e4e /source/blender/draw/modes
parentf7e8b580989ec70d1cf8f15a11d4f09e6b36f407 (diff)
DRW: Refactor to support draw call batching
Reviewers: brecht Differential Revision: D4997
Diffstat (limited to 'source/blender/draw/modes')
-rw-r--r--source/blender/draw/modes/edit_curve_mode.c2
-rw-r--r--source/blender/draw/modes/object_mode.c329
-rw-r--r--source/blender/draw/modes/overlay_mode.c26
-rw-r--r--source/blender/draw/modes/shaders/common_view_lib.glsl67
-rw-r--r--source/blender/draw/modes/shaders/object_lightprobe_grid_vert.glsl12
-rw-r--r--source/blender/draw/modes/shaders/object_outline_detect_frag.glsl40
-rw-r--r--source/blender/draw/modes/shaders/object_outline_prepass_frag.glsl14
-rw-r--r--source/blender/draw/modes/shaders/object_outline_prepass_geom.glsl7
-rw-r--r--source/blender/draw/modes/shaders/object_outline_prepass_vert.glsl17
9 files changed, 218 insertions, 296 deletions
diff --git a/source/blender/draw/modes/edit_curve_mode.c b/source/blender/draw/modes/edit_curve_mode.c
index e68e03c2438..8933767bda8 100644
--- a/source/blender/draw/modes/edit_curve_mode.c
+++ b/source/blender/draw/modes/edit_curve_mode.c
@@ -126,7 +126,7 @@ static void EDIT_CURVE_engine_init(void *UNUSED(vedata))
datatoc_edit_curve_overlay_normals_vert_glsl,
NULL},
.frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
- .defs = (const char *[]){sh_cfg_data->def, NULL},
+ .defs = (const char *[]){sh_cfg_data->def, "#define IN_PLACE_INSTANCES\n", NULL},
});
}
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index 2b87e04b6b4..5c529892206 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -286,15 +286,10 @@ typedef struct OBJECT_PrivateData {
DRWShadingGroup *outlines_transform;
/* Lightprobes */
- DRWCallBuffer *lightprobes_cube_select;
- DRWCallBuffer *lightprobes_cube_select_dupli;
- DRWCallBuffer *lightprobes_cube_active;
- DRWCallBuffer *lightprobes_cube_transform;
-
- DRWCallBuffer *lightprobes_planar_select;
- DRWCallBuffer *lightprobes_planar_select_dupli;
- DRWCallBuffer *lightprobes_planar_active;
- DRWCallBuffer *lightprobes_planar_transform;
+ DRWShadingGroup *probe_outlines_transform;
+ DRWShadingGroup *probe_outlines_select;
+ DRWShadingGroup *probe_outlines_select_dupli;
+ DRWShadingGroup *probe_outlines_active;
/* Objects Centers */
DRWCallBuffer *center_active;
@@ -303,17 +298,6 @@ typedef struct OBJECT_PrivateData {
DRWCallBuffer *center_selected_lib;
DRWCallBuffer *center_deselected_lib;
- /* Outlines id offset (accessed as an array) */
- int id_ofs_active;
- int id_ofs_select;
- int id_ofs_select_dupli;
- int id_ofs_transform;
-
- int id_ofs_prb_active;
- int id_ofs_prb_select;
- int id_ofs_prb_select_dupli;
- int id_ofs_prb_transform;
-
bool xray_enabled;
bool xray_enabled_and_not_wire;
} OBJECT_PrivateData; /* Transient data */
@@ -417,7 +401,10 @@ static void OBJECT_engine_init(void *vedata)
if (!sh_data->outline_resolve) {
/* Outline */
sh_data->outline_prepass = GPU_shader_create_from_arrays({
- .vert = (const char *[]){sh_cfg_data->lib, datatoc_gpu_shader_3D_vert_glsl, NULL},
+ .vert = (const char *[]){sh_cfg_data->lib,
+ datatoc_common_view_lib_glsl,
+ datatoc_object_outline_prepass_vert_glsl,
+ NULL},
.frag = (const char *[]){datatoc_object_outline_prepass_frag_glsl, NULL},
.defs = (const char *[]){sh_cfg_data->def, NULL},
});
@@ -431,7 +418,7 @@ static void OBJECT_engine_init(void *vedata)
datatoc_object_outline_prepass_geom_glsl,
NULL},
.frag = (const char *[]){datatoc_object_outline_prepass_frag_glsl, NULL},
- .defs = (const char *[]){sh_cfg_data->def, NULL},
+ .defs = (const char *[]){sh_cfg_data->def, "#define USE_GEOM\n", NULL},
});
sh_data->outline_resolve = DRW_shader_create_fullscreen(
@@ -539,10 +526,11 @@ static void OBJECT_engine_init(void *vedata)
/* Lightprobes */
sh_data->lightprobe_grid = GPU_shader_create_from_arrays({
.vert = (const char *[]){sh_cfg_data->lib,
+ datatoc_common_view_lib_glsl,
datatoc_common_globals_lib_glsl,
datatoc_object_lightprobe_grid_vert_glsl,
NULL},
- .frag = (const char *[]){datatoc_gpu_shader_flat_id_frag_glsl, NULL},
+ .frag = (const char *[]){datatoc_object_outline_prepass_frag_glsl, NULL},
.defs = (const char *[]){sh_cfg_data->def, NULL},
});
@@ -697,12 +685,12 @@ static void OBJECT_engine_free(void)
}
static DRWShadingGroup *shgroup_outline(DRWPass *pass,
- const int *ofs,
+ int outline_id,
GPUShader *sh,
eGPUShaderConfig sh_cfg)
{
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
- DRW_shgroup_uniform_int(grp, "baseId", ofs, 1);
+ DRW_shgroup_uniform_int_copy(grp, "outlineId", outline_id);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_state_enable(grp, DRW_STATE_CLIP_PLANES);
@@ -741,128 +729,89 @@ static DRWShadingGroup *shgroup_points(DRWPass *pass,
return grp;
}
-static int *shgroup_theme_id_to_probe_outline_counter(OBJECT_StorageList *stl,
- int theme_id,
- const int base_flag)
-{
- if (UNLIKELY(base_flag & BASE_FROM_DUPLI)) {
- switch (theme_id) {
- case TH_ACTIVE:
- case TH_SELECT:
- return &stl->g_data->id_ofs_prb_select_dupli;
- case TH_TRANSFORM:
- default:
- return &stl->g_data->id_ofs_prb_transform;
- }
- }
-
- switch (theme_id) {
- case TH_ACTIVE:
- return &stl->g_data->id_ofs_prb_active;
- case TH_SELECT:
- return &stl->g_data->id_ofs_prb_select;
- case TH_TRANSFORM:
- default:
- return &stl->g_data->id_ofs_prb_transform;
- }
-}
-
-static int *shgroup_theme_id_to_outline_counter(OBJECT_StorageList *stl,
- int theme_id,
- const int base_flag)
+static DRWShadingGroup *shgroup_theme_id_to_outline_or_null(OBJECT_StorageList *stl,
+ int theme_id,
+ const int base_flag)
{
if (UNLIKELY(base_flag & BASE_FROM_DUPLI)) {
switch (theme_id) {
case TH_ACTIVE:
case TH_SELECT:
- return &stl->g_data->id_ofs_select_dupli;
+ return stl->g_data->outlines_select_dupli;
case TH_TRANSFORM:
+ return stl->g_data->outlines_transform;
default:
- return &stl->g_data->id_ofs_transform;
+ return NULL;
}
}
switch (theme_id) {
case TH_ACTIVE:
- return &stl->g_data->id_ofs_active;
- case TH_SELECT:
- return &stl->g_data->id_ofs_select;
- case TH_TRANSFORM:
- default:
- return &stl->g_data->id_ofs_transform;
- }
-}
-
-static DRWCallBuffer *buffer_theme_id_to_probe_planar_outline_shgrp(OBJECT_StorageList *stl,
- int theme_id)
-{
- /* does not increment counter */
- switch (theme_id) {
- case TH_ACTIVE:
- return stl->g_data->lightprobes_planar_active;
+ return stl->g_data->outlines_active;
case TH_SELECT:
- return stl->g_data->lightprobes_planar_select;
+ return stl->g_data->outlines_select;
case TH_TRANSFORM:
+ return stl->g_data->outlines_transform;
default:
- return stl->g_data->lightprobes_planar_transform;
+ return NULL;
}
}
-static DRWCallBuffer *buffer_theme_id_to_probe_cube_outline_shgrp(OBJECT_StorageList *stl,
+static DRWShadingGroup *shgroup_theme_id_to_probe_outline_or_null(OBJECT_StorageList *stl,
int theme_id,
const int base_flag)
{
- /* does not increment counter */
+ if (UNLIKELY(DRW_state_is_select())) {
+ return stl->g_data->probe_outlines_select;
+ }
+
if (UNLIKELY(base_flag & BASE_FROM_DUPLI)) {
switch (theme_id) {
case TH_ACTIVE:
case TH_SELECT:
- return stl->g_data->lightprobes_cube_select_dupli;
+ return stl->g_data->probe_outlines_select_dupli;
case TH_TRANSFORM:
+ return stl->g_data->probe_outlines_transform;
default:
- return stl->g_data->lightprobes_cube_transform;
+ return NULL;
}
}
switch (theme_id) {
case TH_ACTIVE:
- return stl->g_data->lightprobes_cube_active;
+ return stl->g_data->probe_outlines_active;
case TH_SELECT:
- return stl->g_data->lightprobes_cube_select;
+ return stl->g_data->probe_outlines_select;
case TH_TRANSFORM:
+ return stl->g_data->probe_outlines_transform;
default:
- return stl->g_data->lightprobes_cube_transform;
+ return NULL;
}
}
-static DRWShadingGroup *shgroup_theme_id_to_outline_or_null(OBJECT_StorageList *stl,
- int theme_id,
- const int base_flag)
+static int shgroup_theme_id_to_outline_id(int theme_id, const int base_flag)
{
- int *counter = shgroup_theme_id_to_outline_counter(stl, theme_id, base_flag);
- *counter += 1;
-
if (UNLIKELY(base_flag & BASE_FROM_DUPLI)) {
switch (theme_id) {
case TH_ACTIVE:
case TH_SELECT:
- return stl->g_data->outlines_select_dupli;
+ return 2;
case TH_TRANSFORM:
- return stl->g_data->outlines_transform;
+ return 0;
default:
- return NULL;
+ return -1;
}
}
switch (theme_id) {
case TH_ACTIVE:
- return stl->g_data->outlines_active;
+ return 3;
case TH_SELECT:
- return stl->g_data->outlines_select;
+ return 1;
case TH_TRANSFORM:
- return stl->g_data->outlines_transform;
+ return 0;
default:
- return NULL;
+ return -1;
}
}
@@ -1346,7 +1295,8 @@ static void OBJECT_cache_init(void *vedata)
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
OBJECT_PrivateData *g_data;
const DRWContextState *draw_ctx = DRW_context_state_get();
- OBJECT_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
+ eGPUShaderConfig cfg = draw_ctx->sh_cfg;
+ OBJECT_Shaders *sh_data = &e_data.sh_data[cfg];
const float outline_width = UI_GetThemeValuef(TH_OUTLINE_WIDTH);
const bool do_outline_expand = (U.pixelsize > 1.0) || (outline_width > 2.0f);
@@ -1367,59 +1317,25 @@ static void OBJECT_cache_init(void *vedata)
{
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
- psl->outlines = DRW_pass_create("Outlines Depth Pass", state);
+ psl->lightprobes = DRW_pass_create("Outlines Probe Pass", state);
GPUShader *sh = sh_data->outline_prepass;
+ g_data->probe_outlines_transform = shgroup_outline(psl->lightprobes, 0, sh, cfg);
+ g_data->probe_outlines_select = shgroup_outline(psl->lightprobes, 1, sh, cfg);
+ g_data->probe_outlines_select_dupli = shgroup_outline(psl->lightprobes, 2, sh, cfg);
+ g_data->probe_outlines_active = shgroup_outline(psl->lightprobes, 3, sh, cfg);
+
+ psl->outlines = DRW_pass_create("Outlines Depth Pass", state);
+
if (g_data->xray_enabled_and_not_wire) {
sh = sh_data->outline_prepass_wire;
}
- g_data->outlines_select = shgroup_outline(
- psl->outlines, &g_data->id_ofs_select, sh, draw_ctx->sh_cfg);
- g_data->outlines_select_dupli = shgroup_outline(
- psl->outlines, &g_data->id_ofs_select_dupli, sh, draw_ctx->sh_cfg);
- g_data->outlines_transform = shgroup_outline(
- psl->outlines, &g_data->id_ofs_transform, sh, draw_ctx->sh_cfg);
- g_data->outlines_active = shgroup_outline(
- psl->outlines, &g_data->id_ofs_active, sh, draw_ctx->sh_cfg);
-
- g_data->id_ofs_select = 0;
- g_data->id_ofs_select_dupli = 0;
- g_data->id_ofs_active = 0;
- g_data->id_ofs_transform = 0;
- }
-
- {
- DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
- DRWPass *pass = psl->lightprobes = DRW_pass_create("Object Probe Pass", state);
- struct GPUBatch *sphere = DRW_cache_sphere_get();
- struct GPUBatch *quad = DRW_cache_quad_get();
-
- /* Cubemap */
- g_data->lightprobes_cube_select = buffer_instance_outline(
- pass, sphere, &g_data->id_ofs_prb_select, draw_ctx->sh_cfg);
- g_data->lightprobes_cube_select_dupli = buffer_instance_outline(
- pass, sphere, &g_data->id_ofs_prb_select_dupli, draw_ctx->sh_cfg);
- g_data->lightprobes_cube_active = buffer_instance_outline(
- pass, sphere, &g_data->id_ofs_prb_active, draw_ctx->sh_cfg);
- g_data->lightprobes_cube_transform = buffer_instance_outline(
- pass, sphere, &g_data->id_ofs_prb_transform, draw_ctx->sh_cfg);
-
- /* Planar */
- g_data->lightprobes_planar_select = buffer_instance_outline(
- pass, quad, &g_data->id_ofs_prb_select, draw_ctx->sh_cfg);
- g_data->lightprobes_planar_select_dupli = buffer_instance_outline(
- pass, quad, &g_data->id_ofs_prb_select_dupli, draw_ctx->sh_cfg);
- g_data->lightprobes_planar_active = buffer_instance_outline(
- pass, quad, &g_data->id_ofs_prb_active, draw_ctx->sh_cfg);
- g_data->lightprobes_planar_transform = buffer_instance_outline(
- pass, quad, &g_data->id_ofs_prb_transform, draw_ctx->sh_cfg);
-
- g_data->id_ofs_prb_select = 0;
- g_data->id_ofs_prb_select_dupli = 0;
- g_data->id_ofs_prb_active = 0;
- g_data->id_ofs_prb_transform = 0;
+ g_data->outlines_transform = shgroup_outline(psl->outlines, 0, sh, cfg);
+ g_data->outlines_select = shgroup_outline(psl->outlines, 1, sh, cfg);
+ g_data->outlines_select_dupli = shgroup_outline(psl->outlines, 2, sh, cfg);
+ g_data->outlines_active = shgroup_outline(psl->outlines, 3, sh, cfg);
}
{
@@ -1438,7 +1354,6 @@ static void OBJECT_cache_init(void *vedata)
DRW_shgroup_uniform_texture_ref(grp, "sceneDepth", &dtxl->depth);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_float_copy(grp, "alphaOcclu", alphaOcclu);
- DRW_shgroup_uniform_int(grp, "idOffsets", &stl->g_data->id_ofs_active, 4);
DRW_shgroup_call(grp, quad, NULL);
/* This is the bleed pass if do_outline_expand is false. */
@@ -2766,15 +2681,6 @@ static void DRW_shgroup_speaker(OBJECT_ShadingGroupList *sgl, Object *ob, ViewLa
DRW_buffer_add_entry(sgl->speaker, color, &one, ob->obmat);
}
-typedef struct OBJECT_LightProbeEngineData {
- DrawData dd;
-
- float increment_x[3];
- float increment_y[3];
- float increment_z[3];
- float corner[3];
-} OBJECT_LightProbeEngineData;
-
static void DRW_shgroup_lightprobe(OBJECT_Shaders *sh_data,
OBJECT_StorageList *stl,
OBJECT_PassList *psl,
@@ -2791,13 +2697,10 @@ static void DRW_shgroup_lightprobe(OBJECT_Shaders *sh_data,
OBJECT_ShadingGroupList *sgl = (ob->dtx & OB_DRAWXRAY) ? &stl->g_data->sgl_ghost :
&stl->g_data->sgl;
- OBJECT_LightProbeEngineData *prb_data = (OBJECT_LightProbeEngineData *)DRW_drawdata_ensure(
- &ob->id, &draw_engine_object_type, sizeof(OBJECT_LightProbeEngineData), NULL, NULL);
-
if (DRW_state_is_select() || do_outlines) {
- int *call_id = shgroup_theme_id_to_probe_outline_counter(stl, theme_id, ob->base_flag);
-
if (prb->type == LIGHTPROBE_TYPE_GRID) {
+ float corner[3];
+ float increment[3][3];
/* Update transforms */
float cell_dim[3], half_cell_dim[3];
cell_dim[0] = 2.0f / (float)(prb->grid_resolution_x);
@@ -2807,65 +2710,40 @@ static void DRW_shgroup_lightprobe(OBJECT_Shaders *sh_data,
mul_v3_v3fl(half_cell_dim, cell_dim, 0.5f);
/* First cell. */
- copy_v3_fl(prb_data->corner, -1.0f);
- add_v3_v3(prb_data->corner, half_cell_dim);
- mul_m4_v3(ob->obmat, prb_data->corner);
+ copy_v3_fl(corner, -1.0f);
+ add_v3_v3(corner, half_cell_dim);
+ mul_m4_v3(ob->obmat, corner);
/* Opposite neighbor cell. */
- copy_v3_fl3(prb_data->increment_x, cell_dim[0], 0.0f, 0.0f);
- add_v3_v3(prb_data->increment_x, half_cell_dim);
- add_v3_fl(prb_data->increment_x, -1.0f);
- mul_m4_v3(ob->obmat, prb_data->increment_x);
- sub_v3_v3(prb_data->increment_x, prb_data->corner);
-
- copy_v3_fl3(prb_data->increment_y, 0.0f, cell_dim[1], 0.0f);
- add_v3_v3(prb_data->increment_y, half_cell_dim);
- add_v3_fl(prb_data->increment_y, -1.0f);
- mul_m4_v3(ob->obmat, prb_data->increment_y);
- sub_v3_v3(prb_data->increment_y, prb_data->corner);
-
- copy_v3_fl3(prb_data->increment_z, 0.0f, 0.0f, cell_dim[2]);
- add_v3_v3(prb_data->increment_z, half_cell_dim);
- add_v3_fl(prb_data->increment_z, -1.0f);
- mul_m4_v3(ob->obmat, prb_data->increment_z);
- sub_v3_v3(prb_data->increment_z, prb_data->corner);
+ copy_v3_fl3(increment[0], cell_dim[0], 0.0f, 0.0f);
+ copy_v3_fl3(increment[1], 0.0f, cell_dim[1], 0.0f);
+ copy_v3_fl3(increment[2], 0.0f, 0.0f, cell_dim[2]);
+ for (int i = 0; i < 3; i++) {
+ add_v3_v3(increment[i], half_cell_dim);
+ add_v3_fl(increment[i], -1.0f);
+ mul_m4_v3(ob->obmat, increment[i]);
+ sub_v3_v3(increment[i], corner);
+ }
+
+ int outline_id = shgroup_theme_id_to_outline_id(theme_id, ob->base_flag);
uint cell_count = prb->grid_resolution_x * prb->grid_resolution_y * prb->grid_resolution_z;
DRWShadingGroup *grp = DRW_shgroup_create(sh_data->lightprobe_grid, psl->lightprobes);
- DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
- DRW_shgroup_uniform_int_copy(grp, "call_id", *call_id);
- DRW_shgroup_uniform_int(grp, "baseId", call_id, 1); /* that's correct */
- DRW_shgroup_uniform_vec3(grp, "corner", prb_data->corner, 1);
- DRW_shgroup_uniform_vec3(grp, "increment_x", prb_data->increment_x, 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_ivec3(grp, "grid_resolution", &prb->grid_resolution_x, 1);
+ DRW_shgroup_uniform_int_copy(grp, "outlineId", outline_id);
+ DRW_shgroup_uniform_vec3_copy(grp, "corner", corner);
+ DRW_shgroup_uniform_vec3_copy(grp, "increment_x", increment[0]);
+ DRW_shgroup_uniform_vec3_copy(grp, "increment_y", increment[1]);
+ DRW_shgroup_uniform_vec3_copy(grp, "increment_z", increment[2]);
+ DRW_shgroup_uniform_ivec3_copy(grp, "grid_resolution", &prb->grid_resolution_x);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_state_enable(grp, DRW_STATE_CLIP_PLANES);
}
DRW_shgroup_call_procedural_points(grp, NULL, cell_count);
- *call_id += 1;
}
- else if (prb->type == LIGHTPROBE_TYPE_CUBE) {
- float draw_size = 1.0f;
- float probe_cube_mat[4][4];
- // prb_data->draw_size = prb->data_draw_size * 0.1f;
- // unit_m4(prb_data->probe_cube_mat);
- // copy_v3_v3(prb_data->probe_cube_mat[3], ob->obmat[3]);
-
- DRWCallBuffer *buf = buffer_theme_id_to_probe_cube_outline_shgrp(
+ else if (prb->type == LIGHTPROBE_TYPE_PLANAR && (prb->flag & LIGHTPROBE_FLAG_SHOW_DATA)) {
+ DRWShadingGroup *grp = shgroup_theme_id_to_probe_outline_or_null(
stl, theme_id, ob->base_flag);
- /* TODO remove or change the drawing of the cube probes. This line draws nothing on purpose
- * to keep the call ids correct. */
- zero_m4(probe_cube_mat);
- DRW_buffer_add_entry(buf, call_id, &draw_size, probe_cube_mat);
- *call_id += 1;
- }
- else if (prb->flag & LIGHTPROBE_FLAG_SHOW_DATA) {
- float draw_size = 1.0f;
- DRWCallBuffer *buf = buffer_theme_id_to_probe_planar_outline_shgrp(stl, theme_id);
- DRW_buffer_add_entry(buf, call_id, &draw_size, ob->obmat);
- *call_id += 1;
+ DRW_shgroup_call_no_cull(grp, DRW_cache_quad_get(), ob);
}
}
@@ -3782,19 +3660,7 @@ static void OBJECT_draw_scene(void *vedata)
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- int id_len_select = g_data->id_ofs_select;
- int id_len_select_dupli = g_data->id_ofs_select_dupli;
- int id_len_active = g_data->id_ofs_active;
- int id_len_transform = g_data->id_ofs_transform;
-
- int id_len_prb_select = g_data->id_ofs_prb_select;
- int id_len_prb_select_dupli = g_data->id_ofs_prb_select_dupli;
- int id_len_prb_active = g_data->id_ofs_prb_active;
- int id_len_prb_transform = g_data->id_ofs_prb_transform;
-
- int outline_calls = id_len_select + id_len_select_dupli + id_len_active + id_len_transform;
- outline_calls += id_len_prb_select + id_len_prb_select_dupli + id_len_prb_active +
- id_len_prb_transform;
+ int do_outlines = !DRW_pass_is_empty(psl->outlines) || !DRW_pass_is_empty(psl->lightprobes);
float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f};
@@ -3802,35 +3668,24 @@ static void OBJECT_draw_scene(void *vedata)
/* Don't draw Transparent passes in MSAA buffer. */
// DRW_draw_pass(psl->bone_envelope); /* Never drawn in Object mode currently. */
- DRW_draw_pass(stl->g_data->sgl.transp_shapes);
+ DRW_draw_pass(g_data->sgl.transp_shapes);
MULTISAMPLE_SYNC_ENABLE(dfbl, dtxl);
- DRW_draw_pass(stl->g_data->sgl.bone_solid);
- DRW_draw_pass(stl->g_data->sgl.bone_wire);
- DRW_draw_pass(stl->g_data->sgl.bone_outline);
- DRW_draw_pass(stl->g_data->sgl.non_meshes);
+ DRW_draw_pass(g_data->sgl.bone_solid);
+ DRW_draw_pass(g_data->sgl.bone_wire);
+ DRW_draw_pass(g_data->sgl.bone_outline);
+ DRW_draw_pass(g_data->sgl.non_meshes);
DRW_draw_pass(psl->particle);
- DRW_draw_pass(stl->g_data->sgl.bone_axes);
+ DRW_draw_pass(g_data->sgl.bone_axes);
MULTISAMPLE_SYNC_DISABLE(dfbl, dtxl);
- DRW_draw_pass(stl->g_data->sgl.image_empties);
+ DRW_draw_pass(g_data->sgl.image_empties);
- if (DRW_state_is_fbo() && outline_calls > 0) {
+ if (DRW_state_is_fbo() && do_outlines) {
DRW_stats_group_start("Outlines");
- g_data->id_ofs_active = 1;
- g_data->id_ofs_select = g_data->id_ofs_active + id_len_active + id_len_prb_active + 1;
- g_data->id_ofs_select_dupli = g_data->id_ofs_select + id_len_select + id_len_prb_select + 1;
- g_data->id_ofs_transform = g_data->id_ofs_select_dupli + id_len_select_dupli +
- id_len_prb_select_dupli + 1;
-
- g_data->id_ofs_prb_active = g_data->id_ofs_active + id_len_active;
- g_data->id_ofs_prb_select = g_data->id_ofs_select + id_len_select;
- g_data->id_ofs_prb_select_dupli = g_data->id_ofs_select_dupli + id_len_select_dupli;
- g_data->id_ofs_prb_transform = g_data->id_ofs_transform + id_len_transform;
-
/* Render filled polygon on a separate framebuffer */
GPU_framebuffer_bind(fbl->outlines_fb);
GPU_framebuffer_clear_color_depth(fbl->outlines_fb, clearcol, 1.0f);
@@ -3865,7 +3720,7 @@ static void OBJECT_draw_scene(void *vedata)
}
/* Combine with scene buffer last */
- if (outline_calls > 0) {
+ if (do_outlines) {
DRW_draw_pass(psl->outlines_resolve);
}
}
diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c
index a5b1133abf4..2433f4c1df5 100644
--- a/source/blender/draw/modes/overlay_mode.c
+++ b/source/blender/draw/modes/overlay_mode.c
@@ -23,8 +23,6 @@
#include "DNA_mesh_types.h"
#include "DNA_view3d_types.h"
-#include "BIF_glutil.h"
-
#include "BKE_editmesh.h"
#include "BKE_global.h"
#include "BKE_object.h"
@@ -77,7 +75,6 @@ typedef struct OVERLAY_PrivateData {
DRWShadingGroup *face_wires_shgrp;
DRWShadingGroup *face_wires_xray_shgrp;
DRWView *view_wires;
- BLI_mempool *wire_color_mempool;
View3DOverlay overlay;
float wire_step_param;
bool clear_stencil;
@@ -208,10 +205,6 @@ static void overlay_cache_init(void *vedata)
if (v3d->shading.type == OB_WIRE) {
g_data->overlay.flag |= V3D_OVERLAY_WIREFRAMES;
-
- if (ELEM(v3d->shading.wire_color_type, V3D_SHADING_OBJECT_COLOR, V3D_SHADING_RANDOM_COLOR)) {
- g_data->wire_color_mempool = BLI_mempool_create(sizeof(float[3]), 0, 512, 0);
- }
}
{
@@ -256,7 +249,6 @@ static void overlay_cache_init(void *vedata)
}
static void overlay_wire_color_get(const View3D *v3d,
- const OVERLAY_PrivateData *pd,
const Object *ob,
const bool use_coloring,
float **rim_col,
@@ -305,8 +297,10 @@ static void overlay_wire_color_get(const View3D *v3d,
if (v3d->shading.type == OB_WIRE) {
if (ELEM(v3d->shading.wire_color_type, V3D_SHADING_OBJECT_COLOR, V3D_SHADING_RANDOM_COLOR)) {
- *wire_col = BLI_mempool_alloc(pd->wire_color_mempool);
- *rim_col = BLI_mempool_alloc(pd->wire_color_mempool);
+ /* Theses stays valid until next call. So we need to copy them when using them as uniform. */
+ static float wire_col_val[3], rim_col_val[3];
+ *wire_col = wire_col_val;
+ *rim_col = rim_col_val;
if (v3d->shading.wire_color_type == V3D_SHADING_OBJECT_COLOR) {
linearrgb_to_srgb_v3_v3(*wire_col, ob->color);
@@ -427,9 +421,9 @@ static void overlay_cache_populate(void *vedata, Object *ob)
if (!(DRW_state_is_select() || DRW_state_is_depth())) {
float *rim_col, *wire_col;
- overlay_wire_color_get(v3d, pd, ob, use_coloring, &rim_col, &wire_col);
- DRW_shgroup_uniform_vec3(shgrp, "wireColor", wire_col, 1);
- DRW_shgroup_uniform_vec3(shgrp, "rimColor", rim_col, 1);
+ overlay_wire_color_get(v3d, ob, use_coloring, &rim_col, &wire_col);
+ DRW_shgroup_uniform_vec3_copy(shgrp, "wireColor", wire_col);
+ DRW_shgroup_uniform_vec3_copy(shgrp, "rimColor", rim_col);
DRW_shgroup_stencil_mask(shgrp,
(is_xray && (is_wire || !pd->clear_stencil)) ? 0x00 : 0xFF);
}
@@ -506,12 +500,6 @@ static void overlay_draw_scene(void *vedata)
/* TODO(fclem): find a way to unify the multisample pass together
* (non meshes + armature + wireframe) */
MULTISAMPLE_SYNC_DISABLE(dfbl, dtxl);
-
- /* XXX TODO(fclem) do not discard data after drawing! Store them per viewport. */
- if (stl->g_data->wire_color_mempool) {
- BLI_mempool_destroy(stl->g_data->wire_color_mempool);
- stl->g_data->wire_color_mempool = NULL;
- }
}
static void overlay_engine_free(void)
diff --git a/source/blender/draw/modes/shaders/common_view_lib.glsl b/source/blender/draw/modes/shaders/common_view_lib.glsl
index 20a54947db7..a554db7d4a4 100644
--- a/source/blender/draw/modes/shaders/common_view_lib.glsl
+++ b/source/blender/draw/modes/shaders/common_view_lib.glsl
@@ -1,4 +1,5 @@
#define COMMON_VIEW_LIB
+#define DRW_RESOURCE_CHUNK_LEN 512
/* keep in sync with DRWManager.view_data */
layout(std140) uniform viewBlock
@@ -23,8 +24,74 @@ layout(std140) uniform viewBlock
_world_clip_planes_calc_clip_distance(p, clipPlanes)
#endif
+uniform int resourceChunk;
+
+#ifdef GPU_VERTEX_SHADER
+# ifdef GL_ARB_shader_draw_parameters
+# define baseInstance gl_BaseInstanceARB
+# else /* no ARB_shader_draw_parameters */
+uniform int baseInstance;
+# endif
+
+# ifdef IN_PLACE_INSTANCES
+/* When drawing instances of an object at the same position. */
+# define instanceId 0
+# elif defined(GPU_CRAPPY_AMD_DRIVER)
+/* NOTE: This does contain the baseInstance ofset */
+in int _instanceId;
+# define instanceId (_instanceId - baseInstance)
+# else
+# define instanceId gl_InstanceID
+# endif
+
+# define resource_id (baseInstance + instanceId)
+
+/* Use this to declare and pass the value if
+ * the fragment shader uses the resource_id. */
+# define RESOURCE_ID_VARYING flat out int resourceIDFrag;
+# define RESOURCE_ID_VARYING_GEOM flat out int resourceIDGeom;
+# define PASS_RESOURCE_ID resourceIDFrag = resource_id;
+# define PASS_RESOURCE_ID_GEOM resourceIDGeom = resource_id;
+#endif
+
+/* If used in a fragment / geometry shader, we pass
+ * resource_id as varying. */
+#ifdef GPU_GEOMETRY_SHADER
+# define RESOURCE_ID_VARYING \
+ flat out int resourceIDFrag; \
+ flat in int resourceIDGeom[];
+
+# define resource_id resourceIDGeom
+# define PASS_RESOURCE_ID(i) resourceIDFrag = resource_id[i];
+#endif
+
+#ifdef GPU_FRAGMENT_SHADER
+flat in int resourceIDFrag;
+# define resource_id resourceIDFrag
+#endif
+
+#ifndef GPU_INTEL
+struct ObjectMatrices {
+ mat4 drw_modelMatrix;
+ mat4 drw_modelMatrixInverse;
+};
+
+layout(std140) uniform modelBlock
+{
+ ObjectMatrices drw_matrices[DRW_RESOURCE_CHUNK_LEN];
+};
+
+# define ModelMatrix (drw_matrices[resource_id].drw_modelMatrix)
+# define ModelMatrixInverse (drw_matrices[resource_id].drw_modelMatrixInverse)
+
+#else /* GPU_INTEL */
+/* Intel GPU seems to suffer performance impact when the model matrix is in UBO storage.
+ * So for now we just force using the legacy path. */
uniform mat4 ModelMatrix;
uniform mat4 ModelMatrixInverse;
+#endif
+
+#define resource_handle (resourceChunk * DRW_RESOURCE_CHUNK_LEN + resource_id)
/** Transform shortcuts. */
/* Rule of thumb: Try to reuse world positions and normals because converting though viewspace
diff --git a/source/blender/draw/modes/shaders/object_lightprobe_grid_vert.glsl b/source/blender/draw/modes/shaders/object_lightprobe_grid_vert.glsl
index d27d55c3fd6..144024a7d5d 100644
--- a/source/blender/draw/modes/shaders/object_lightprobe_grid_vert.glsl
+++ b/source/blender/draw/modes/shaders/object_lightprobe_grid_vert.glsl
@@ -1,18 +1,11 @@
-uniform mat4 ViewProjectionMatrix;
-
-uniform float sphere_size;
uniform ivec3 grid_resolution;
uniform vec3 corner;
uniform vec3 increment_x;
uniform vec3 increment_y;
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 baseId;
-flat out uint finalId;
+flat out int objectId;
void main()
{
@@ -29,7 +22,8 @@ void main()
gl_Position = ViewProjectionMatrix * vec4(ws_cell_location, 1.0);
gl_PointSize = 2.0f;
- finalId = uint(baseId + call_id);
+ /* ID 0 is nothing (background) */
+ objectId = resource_handle + 1;
#ifdef USE_WORLD_CLIP_PLANES
world_clip_planes_calc_clip_distance(ws_cell_location);
diff --git a/source/blender/draw/modes/shaders/object_outline_detect_frag.glsl b/source/blender/draw/modes/shaders/object_outline_detect_frag.glsl
index 7668a0c2c94..7b86d477a39 100644
--- a/source/blender/draw/modes/shaders/object_outline_detect_frag.glsl
+++ b/source/blender/draw/modes/shaders/object_outline_detect_frag.glsl
@@ -7,30 +7,9 @@ uniform usampler2D outlineId;
uniform sampler2D outlineDepth;
uniform sampler2D sceneDepth;
-uniform int idOffsets[4];
-
uniform float alphaOcclu;
uniform vec2 viewportSize;
-vec4 convert_id_to_color(int id)
-{
- if (id == 0) {
- return vec4(0.0);
- }
- if (id < idOffsets[1]) {
- return colorActive;
- }
- else if (id < idOffsets[2]) {
- return colorSelect;
- }
- else if (id < idOffsets[3]) {
- return colorDupliSelect;
- }
- else {
- return colorTransform;
- }
-}
-
void main()
{
ivec2 texel = ivec2(gl_FragCoord.xy);
@@ -85,7 +64,24 @@ void main()
const float epsilon = 3.0 / 8388608.0;
bool occluded = (ref_depth > scene_depth + epsilon);
- FragColor = convert_id_to_color(int(ref_id));
+ /* WATCH: Keep in sync with outlineId of the prepass. */
+ uint color_id = ref_id >> 14u;
+ if (ref_id == 0u) {
+ FragColor = vec4(0.0);
+ }
+ else if (color_id == 1u) {
+ FragColor = colorSelect;
+ }
+ else if (color_id == 2u) {
+ FragColor = colorDupliSelect;
+ }
+ else if (color_id == 3u) {
+ FragColor = colorActive;
+ }
+ else {
+ FragColor = colorTransform;
+ }
+
FragColor.a *= (occluded) ? alphaOcclu : 1.0;
FragColor.a = (outline) ? FragColor.a : 0.0;
}
diff --git a/source/blender/draw/modes/shaders/object_outline_prepass_frag.glsl b/source/blender/draw/modes/shaders/object_outline_prepass_frag.glsl
index c3447456ea6..5d6c4881b5b 100644
--- a/source/blender/draw/modes/shaders/object_outline_prepass_frag.glsl
+++ b/source/blender/draw/modes/shaders/object_outline_prepass_frag.glsl
@@ -1,10 +1,18 @@
-uniform int callId;
-uniform int baseId;
+
+/* Should be 2 bits only [0..3]. */
+uniform int outlineId;
+
+flat in int objectId;
/* using uint because 16bit uint can contain more ids than int. */
out uint outId;
+/* Replace top 2 bits (of the 16bit output) by outlineId.
+ * This leaves 16K different IDs to create outlines between objects.
+ * SHIFT = (32 - (16 - 2)) */
+#define SHIFT 18u
+
void main()
{
- outId = uint(baseId + callId);
+ outId = (uint(outlineId) << 14u) | ((uint(objectId) << SHIFT) >> SHIFT);
}
diff --git a/source/blender/draw/modes/shaders/object_outline_prepass_geom.glsl b/source/blender/draw/modes/shaders/object_outline_prepass_geom.glsl
index 5a3eb38fb6b..b32913dcd60 100644
--- a/source/blender/draw/modes/shaders/object_outline_prepass_geom.glsl
+++ b/source/blender/draw/modes/shaders/object_outline_prepass_geom.glsl
@@ -2,12 +2,15 @@
layout(lines_adjacency) in;
layout(line_strip, max_vertices = 2) out;
-in vec4 pPos[];
in vec3 vPos[];
+in int objectId_g[];
+
+flat out int objectId;
void vert_from_gl_in(int v)
{
- gl_Position = pPos[v];
+ gl_Position = gl_in[v].gl_Position;
+ objectId = objectId_g[v];
#ifdef USE_WORLD_CLIP_PLANES
world_clip_planes_set_clip_distance(gl_in[v].gl_ClipDistance);
#endif
diff --git a/source/blender/draw/modes/shaders/object_outline_prepass_vert.glsl b/source/blender/draw/modes/shaders/object_outline_prepass_vert.glsl
index e34afe95b5e..7740f9a4af2 100644
--- a/source/blender/draw/modes/shaders/object_outline_prepass_vert.glsl
+++ b/source/blender/draw/modes/shaders/object_outline_prepass_vert.glsl
@@ -1,16 +1,27 @@
in vec3 pos;
-out vec4 pPos;
+#ifdef USE_GEOM
out vec3 vPos;
+out int objectId_g;
+# define objectId objectId_g
+#else
+
+flat out int objectId;
+#endif
void main()
{
vec3 world_pos = point_object_to_world(pos);
+#ifdef USE_GEOM
vPos = point_world_to_view(world_pos);
- pPos = point_world_to_ndc(world_pos);
+#endif
+ gl_Position = point_world_to_ndc(world_pos);
/* Small bias to always be on top of the geom. */
- pPos.z -= 1e-3;
+ gl_Position.z -= 1e-3;
+
+ /* ID 0 is nothing (background) */
+ objectId = resource_handle + 1;
#ifdef USE_WORLD_CLIP_PLANES
world_clip_planes_calc_clip_distance(world_pos);