Revert "DRW: Refactor to support draw call batching"
This reverts commit ce34a6b0d7
.
This commit is contained in:
parent
c80564ef9f
commit
fd5c1972cd
|
@ -30,20 +30,16 @@ extern "C" {
|
|||
|
||||
#include "BLI_compiler_attrs.h"
|
||||
|
||||
#define BLI_MEM_BLOCK_CHUNK_SIZE (1 << 15) /* 32KiB */
|
||||
|
||||
struct BLI_memblock;
|
||||
|
||||
typedef struct BLI_memblock BLI_memblock;
|
||||
typedef void (*MemblockValFreeFP)(void *val);
|
||||
|
||||
BLI_memblock *BLI_memblock_create_ex(uint elem_size, uint chunk_size) ATTR_WARN_UNUSED_RESULT;
|
||||
void *BLI_memblock_alloc(BLI_memblock *mblk) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
|
||||
BLI_memblock *BLI_memblock_create(uint elem_size) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
|
||||
void *BLI_memblock_alloc(BLI_memblock *mblk) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
|
||||
void BLI_memblock_clear(BLI_memblock *mblk, MemblockValFreeFP valfreefp) ATTR_NONNULL(1);
|
||||
void BLI_memblock_destroy(BLI_memblock *mblk, MemblockValFreeFP free_callback) ATTR_NONNULL(1);
|
||||
|
||||
#define BLI_memblock_create(elem_size) BLI_memblock_create_ex(elem_size, BLI_MEM_BLOCK_CHUNK_SIZE)
|
||||
|
||||
typedef struct BLI_memblock_iter {
|
||||
void **chunk_list;
|
||||
int cur_index;
|
||||
|
@ -57,9 +53,6 @@ typedef struct BLI_memblock_iter {
|
|||
void BLI_memblock_iternew(BLI_memblock *pool, BLI_memblock_iter *iter) ATTR_NONNULL();
|
||||
void *BLI_memblock_iterstep(BLI_memblock_iter *iter) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
|
||||
|
||||
void *BLI_memblock_elem_get(BLI_memblock *mblk, int chunk, int elem) ATTR_WARN_UNUSED_RESULT
|
||||
ATTR_NONNULL();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
#include "BLI_strict_flags.h" /* keep last */
|
||||
|
||||
#define BLI_MEM_BLOCK_CHUNK_SIZE (1 << 15) /* 32KiB */
|
||||
#define CHUNK_LIST_SIZE 16
|
||||
|
||||
struct BLI_memblock {
|
||||
|
@ -60,19 +61,18 @@ struct BLI_memblock {
|
|||
int chunk_len;
|
||||
};
|
||||
|
||||
BLI_memblock *BLI_memblock_create_ex(uint elem_size, uint chunk_size)
|
||||
BLI_memblock *BLI_memblock_create(uint elem_size)
|
||||
{
|
||||
BLI_assert(elem_size < chunk_size);
|
||||
BLI_assert(elem_size < BLI_MEM_BLOCK_CHUNK_SIZE);
|
||||
|
||||
BLI_memblock *mblk = MEM_mallocN(sizeof(BLI_memblock), "BLI_memblock");
|
||||
mblk->elem_size = (int)elem_size;
|
||||
mblk->elem_next = 0;
|
||||
mblk->elem_last = -1;
|
||||
mblk->chunk_size = (int)chunk_size;
|
||||
mblk->chunk_size = BLI_MEM_BLOCK_CHUNK_SIZE;
|
||||
mblk->chunk_len = CHUNK_LIST_SIZE;
|
||||
mblk->chunk_list = MEM_callocN(sizeof(void *) * (uint)mblk->chunk_len, "chunk list");
|
||||
mblk->chunk_list[0] = MEM_mallocN_aligned((uint)mblk->chunk_size, 32, "BLI_memblock chunk");
|
||||
memset(mblk->chunk_list[0], 0x0, (uint)mblk->chunk_size);
|
||||
mblk->chunk_list[0] = MEM_callocN((uint)mblk->chunk_size, "BLI_memblock chunk");
|
||||
mblk->chunk_max_ofs = (mblk->chunk_size / mblk->elem_size) * mblk->elem_size;
|
||||
mblk->elem_next_ofs = 0;
|
||||
mblk->chunk_next = 0;
|
||||
|
@ -143,9 +143,8 @@ void *BLI_memblock_alloc(BLI_memblock *mblk)
|
|||
}
|
||||
|
||||
if (UNLIKELY(mblk->chunk_list[mblk->chunk_next] == NULL)) {
|
||||
mblk->chunk_list[mblk->chunk_next] = MEM_mallocN_aligned(
|
||||
(uint)mblk->chunk_size, 32, "BLI_memblock chunk");
|
||||
memset(mblk->chunk_list[mblk->chunk_next], 0x0, (uint)mblk->chunk_size);
|
||||
mblk->chunk_list[mblk->chunk_next] = MEM_callocN((uint)mblk->chunk_size,
|
||||
"BLI_memblock chunk");
|
||||
}
|
||||
}
|
||||
return ptr;
|
||||
|
@ -181,11 +180,3 @@ void *BLI_memblock_iterstep(BLI_memblock_iter *iter)
|
|||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Direct access. elem is element index inside the chosen chunk. */
|
||||
void *BLI_memblock_elem_get(BLI_memblock *mblk, int chunk, int elem)
|
||||
{
|
||||
BLI_assert(chunk < mblk->chunk_len);
|
||||
BLI_assert(elem < (mblk->chunk_size / mblk->elem_size));
|
||||
return (char *)(mblk->chunk_list[chunk]) + mblk->elem_size * elem;
|
||||
}
|
||||
|
|
|
@ -48,9 +48,6 @@ static struct {
|
|||
char *frag_shader_lib;
|
||||
char *vert_shader_str;
|
||||
char *vert_shadow_shader_str;
|
||||
char *vert_background_shader_str;
|
||||
char *vert_volume_shader_str;
|
||||
char *geom_volume_shader_str;
|
||||
char *volume_shader_lib;
|
||||
|
||||
struct GPUShader *default_prepass_sh;
|
||||
|
@ -568,15 +565,6 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
|
|||
e_data.vert_shadow_shader_str = BLI_string_joinN(
|
||||
datatoc_common_view_lib_glsl, datatoc_common_hair_lib_glsl, datatoc_shadow_vert_glsl);
|
||||
|
||||
e_data.vert_background_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
|
||||
datatoc_background_vert_glsl);
|
||||
|
||||
e_data.vert_volume_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
|
||||
datatoc_volumetric_vert_glsl);
|
||||
|
||||
e_data.geom_volume_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
|
||||
datatoc_volumetric_geom_glsl);
|
||||
|
||||
e_data.default_background = DRW_shader_create_with_lib(datatoc_background_vert_glsl,
|
||||
NULL,
|
||||
datatoc_default_world_frag_glsl,
|
||||
|
@ -649,7 +637,7 @@ struct GPUMaterial *EEVEE_material_world_lightprobe_get(struct Scene *scene, Wor
|
|||
wo,
|
||||
engine,
|
||||
options,
|
||||
e_data.vert_background_shader_str,
|
||||
datatoc_background_vert_glsl,
|
||||
NULL,
|
||||
e_data.frag_shader_lib,
|
||||
SHADER_DEFINES "#define PROBE_CAPTURE\n",
|
||||
|
@ -669,7 +657,7 @@ struct GPUMaterial *EEVEE_material_world_background_get(struct Scene *scene, Wor
|
|||
wo,
|
||||
engine,
|
||||
options,
|
||||
e_data.vert_background_shader_str,
|
||||
datatoc_background_vert_glsl,
|
||||
NULL,
|
||||
e_data.frag_shader_lib,
|
||||
SHADER_DEFINES "#define WORLD_BACKGROUND\n",
|
||||
|
@ -692,8 +680,8 @@ struct GPUMaterial *EEVEE_material_world_volume_get(struct Scene *scene, World *
|
|||
wo,
|
||||
engine,
|
||||
options,
|
||||
e_data.vert_volume_shader_str,
|
||||
e_data.geom_volume_shader_str,
|
||||
datatoc_volumetric_vert_glsl,
|
||||
datatoc_volumetric_geom_glsl,
|
||||
e_data.volume_shader_lib,
|
||||
defines,
|
||||
true);
|
||||
|
@ -753,8 +741,8 @@ struct GPUMaterial *EEVEE_material_mesh_volume_get(struct Scene *scene, Material
|
|||
ma,
|
||||
engine,
|
||||
options,
|
||||
e_data.vert_volume_shader_str,
|
||||
e_data.geom_volume_shader_str,
|
||||
datatoc_volumetric_vert_glsl,
|
||||
datatoc_volumetric_geom_glsl,
|
||||
e_data.volume_shader_lib,
|
||||
defines,
|
||||
true);
|
||||
|
@ -1350,24 +1338,6 @@ static void material_transparent(Material *ma,
|
|||
const float *spec_p = &ma->spec;
|
||||
const float *rough_p = &ma->roughness;
|
||||
|
||||
const bool use_prepass = ((ma->blend_flag & MA_BL_HIDE_BACKFACE) != 0);
|
||||
|
||||
DRWState cur_state;
|
||||
DRWState all_state = (DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_CULL_BACK |
|
||||
DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_DEPTH_EQUAL |
|
||||
DRW_STATE_BLEND_CUSTOM);
|
||||
|
||||
/* Depth prepass */
|
||||
if (use_prepass) {
|
||||
*shgrp_depth = DRW_shgroup_create(e_data.default_prepass_clip_sh, psl->transparent_pass);
|
||||
|
||||
cur_state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
|
||||
cur_state |= (do_cull) ? DRW_STATE_CULL_BACK : 0;
|
||||
|
||||
DRW_shgroup_state_disable(*shgrp_depth, all_state);
|
||||
DRW_shgroup_state_enable(*shgrp_depth, cur_state);
|
||||
}
|
||||
|
||||
if (ma->use_nodes && ma->nodetree) {
|
||||
static float error_col[3] = {1.0f, 0.0f, 1.0f};
|
||||
static float compile_col[3] = {0.5f, 0.5f, 0.5f};
|
||||
|
@ -1424,13 +1394,30 @@ static void material_transparent(Material *ma,
|
|||
DRW_shgroup_uniform_float(*shgrp, "roughness", rough_p, 1);
|
||||
}
|
||||
|
||||
cur_state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM;
|
||||
const bool use_prepass = ((ma->blend_flag & MA_BL_HIDE_BACKFACE) != 0);
|
||||
|
||||
DRWState all_state = (DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_CULL_BACK |
|
||||
DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_DEPTH_EQUAL |
|
||||
DRW_STATE_BLEND_CUSTOM);
|
||||
|
||||
DRWState cur_state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM;
|
||||
cur_state |= (use_prepass) ? DRW_STATE_DEPTH_EQUAL : DRW_STATE_DEPTH_LESS_EQUAL;
|
||||
cur_state |= (do_cull) ? DRW_STATE_CULL_BACK : 0;
|
||||
|
||||
/* Disable other blend modes and use the one we want. */
|
||||
DRW_shgroup_state_disable(*shgrp, all_state);
|
||||
DRW_shgroup_state_enable(*shgrp, cur_state);
|
||||
|
||||
/* Depth prepass */
|
||||
if (use_prepass) {
|
||||
*shgrp_depth = DRW_shgroup_create(e_data.default_prepass_clip_sh, psl->transparent_pass);
|
||||
|
||||
cur_state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
|
||||
cur_state |= (do_cull) ? DRW_STATE_CULL_BACK : 0;
|
||||
|
||||
DRW_shgroup_state_disable(*shgrp_depth, all_state);
|
||||
DRW_shgroup_state_enable(*shgrp_depth, cur_state);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return correct material or &defmaterial if slot is empty. */
|
||||
|
@ -1747,9 +1734,6 @@ void EEVEE_materials_free(void)
|
|||
MEM_SAFE_FREE(e_data.frag_shader_lib);
|
||||
MEM_SAFE_FREE(e_data.vert_shader_str);
|
||||
MEM_SAFE_FREE(e_data.vert_shadow_shader_str);
|
||||
MEM_SAFE_FREE(e_data.vert_background_shader_str);
|
||||
MEM_SAFE_FREE(e_data.vert_volume_shader_str);
|
||||
MEM_SAFE_FREE(e_data.geom_volume_shader_str);
|
||||
MEM_SAFE_FREE(e_data.volume_shader_lib);
|
||||
DRW_SHADER_FREE_SAFE(e_data.default_hair_prepass_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.default_hair_prepass_clip_sh);
|
||||
|
|
|
@ -415,7 +415,6 @@ static DRWShadingGroup *gpencil_shgroup_fill_create(GPENCIL_Data *vedata,
|
|||
DRWPass *pass,
|
||||
GPUShader *shader,
|
||||
Object *ob,
|
||||
float (*obmat)[4],
|
||||
bGPdata *gpd,
|
||||
bGPDlayer *gpl,
|
||||
MaterialGPencilStyle *gp_style,
|
||||
|
@ -429,8 +428,6 @@ static DRWShadingGroup *gpencil_shgroup_fill_create(GPENCIL_Data *vedata,
|
|||
/* e_data.gpencil_fill_sh */
|
||||
DRWShadingGroup *grp = DRW_shgroup_create(shader, pass);
|
||||
|
||||
DRW_shgroup_uniform_mat4(grp, "gpModelMatrix", obmat);
|
||||
|
||||
DRW_shgroup_uniform_vec4(grp, "color2", gp_style->mix_rgba, 1);
|
||||
|
||||
/* set style type */
|
||||
|
@ -564,7 +561,6 @@ DRWShadingGroup *gpencil_shgroup_stroke_create(GPENCIL_Data *vedata,
|
|||
DRWPass *pass,
|
||||
GPUShader *shader,
|
||||
Object *ob,
|
||||
float (*obmat)[4],
|
||||
bGPdata *gpd,
|
||||
bGPDlayer *gpl,
|
||||
bGPDstroke *gps,
|
||||
|
@ -586,8 +582,6 @@ DRWShadingGroup *gpencil_shgroup_stroke_create(GPENCIL_Data *vedata,
|
|||
|
||||
DRW_shgroup_uniform_float(grp, "pixsize", stl->storage->pixsize, 1);
|
||||
|
||||
DRW_shgroup_uniform_mat4(grp, "gpModelMatrix", obmat);
|
||||
|
||||
/* avoid wrong values */
|
||||
if ((gpd) && (gpd->pixfactor == 0.0f)) {
|
||||
gpd->pixfactor = GP_DEFAULT_PIX_FACTOR;
|
||||
|
@ -730,7 +724,6 @@ static DRWShadingGroup *gpencil_shgroup_point_create(GPENCIL_Data *vedata,
|
|||
DRWPass *pass,
|
||||
GPUShader *shader,
|
||||
Object *ob,
|
||||
float (*obmat)[4],
|
||||
bGPdata *gpd,
|
||||
bGPDlayer *gpl,
|
||||
bGPDstroke *gps,
|
||||
|
@ -751,8 +744,6 @@ static DRWShadingGroup *gpencil_shgroup_point_create(GPENCIL_Data *vedata,
|
|||
DRW_shgroup_uniform_vec2(grp, "Viewport", viewport_size, 1);
|
||||
DRW_shgroup_uniform_float(grp, "pixsize", stl->storage->pixsize, 1);
|
||||
|
||||
DRW_shgroup_uniform_mat4(grp, "gpModelMatrix", obmat);
|
||||
|
||||
/* avoid wrong values */
|
||||
if ((gpd) && (gpd->pixfactor == 0.0f)) {
|
||||
gpd->pixfactor = GP_DEFAULT_PIX_FACTOR;
|
||||
|
@ -1577,9 +1568,6 @@ void gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data,
|
|||
copy_v2_v2(stl->storage->gradient_s, brush->gpencil_settings->gradient_s);
|
||||
stl->storage->alignment_mode = (gp_style) ? gp_style->alignment_mode : GP_STYLE_FOLLOW_PATH;
|
||||
|
||||
float unit_mat[4][4];
|
||||
unit_m4(unit_mat);
|
||||
|
||||
/* if only one point, don't need to draw buffer because the user has no time to see it */
|
||||
if (gpd->runtime.sbuffer_used > 1) {
|
||||
if ((gp_style) && (gp_style->mode == GP_STYLE_MODE_LINE)) {
|
||||
|
@ -1588,7 +1576,6 @@ void gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data,
|
|||
psl->drawing_pass,
|
||||
e_data->gpencil_stroke_sh,
|
||||
NULL,
|
||||
unit_mat,
|
||||
gpd,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -1613,7 +1600,6 @@ void gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data,
|
|||
psl->drawing_pass,
|
||||
e_data->gpencil_point_sh,
|
||||
NULL,
|
||||
unit_mat,
|
||||
gpd,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -1800,7 +1786,6 @@ static void gpencil_shgroups_create(GPENCIL_e_data *e_data,
|
|||
stroke_pass,
|
||||
e_data->gpencil_stroke_sh,
|
||||
ob,
|
||||
obmat,
|
||||
gpd,
|
||||
gpl,
|
||||
gps,
|
||||
|
@ -1809,26 +1794,23 @@ static void gpencil_shgroups_create(GPENCIL_e_data *e_data,
|
|||
elm->onion,
|
||||
scale,
|
||||
cache_ob->shading_type);
|
||||
if ((do_onion) || (elm->onion == false)) {
|
||||
DRW_shgroup_call_range_obmat(shgrp, cache->b_stroke.batch, obmat, start_stroke, len);
|
||||
}
|
||||
stl->storage->shgroup_id++;
|
||||
start_stroke = elm->vertex_idx;
|
||||
|
||||
/* set stencil mask id */
|
||||
if (gpencil_is_stencil_required(gp_style)) {
|
||||
if (stencil_id == 1) {
|
||||
/* Clear previous stencils. */
|
||||
DRW_shgroup_clear_framebuffer(shgrp, GPU_STENCIL_BIT, 0, 0, 0, 0, 0.0f, 0x0);
|
||||
}
|
||||
DRW_shgroup_stencil_mask(shgrp, stencil_id);
|
||||
stencil_id++;
|
||||
}
|
||||
else {
|
||||
/* Disable stencil for this type */
|
||||
DRW_shgroup_state_disable(shgrp, DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_NEQUAL);
|
||||
/* set stencil mask id as not used */
|
||||
DRW_shgroup_stencil_mask(shgrp, 0x0);
|
||||
}
|
||||
|
||||
if ((do_onion) || (elm->onion == false)) {
|
||||
DRW_shgroup_call_range(shgrp, cache->b_stroke.batch, start_stroke, len);
|
||||
}
|
||||
stl->storage->shgroup_id++;
|
||||
start_stroke = elm->vertex_idx;
|
||||
break;
|
||||
}
|
||||
case eGpencilBatchGroupType_Point: {
|
||||
|
@ -1838,7 +1820,6 @@ static void gpencil_shgroups_create(GPENCIL_e_data *e_data,
|
|||
stroke_pass,
|
||||
e_data->gpencil_point_sh,
|
||||
ob,
|
||||
obmat,
|
||||
gpd,
|
||||
gpl,
|
||||
gps,
|
||||
|
@ -1848,14 +1829,16 @@ static void gpencil_shgroups_create(GPENCIL_e_data *e_data,
|
|||
scale,
|
||||
cache_ob->shading_type);
|
||||
|
||||
/* Disable stencil for this type */
|
||||
DRW_shgroup_state_disable(shgrp, DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_NEQUAL);
|
||||
|
||||
if ((do_onion) || (elm->onion == false)) {
|
||||
DRW_shgroup_call_range(shgrp, cache->b_point.batch, start_point, len);
|
||||
DRW_shgroup_call_range_obmat(shgrp, cache->b_point.batch, obmat, start_point, len);
|
||||
}
|
||||
stl->storage->shgroup_id++;
|
||||
start_point = elm->vertex_idx;
|
||||
|
||||
/* Disable stencil for this type */
|
||||
DRW_shgroup_state_disable(shgrp, DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_NEQUAL);
|
||||
/* set stencil mask id as not used */
|
||||
DRW_shgroup_stencil_mask(shgrp, 0x0);
|
||||
break;
|
||||
}
|
||||
case eGpencilBatchGroupType_Fill: {
|
||||
|
@ -1865,32 +1848,30 @@ static void gpencil_shgroups_create(GPENCIL_e_data *e_data,
|
|||
stroke_pass,
|
||||
e_data->gpencil_fill_sh,
|
||||
ob,
|
||||
obmat,
|
||||
gpd,
|
||||
gpl,
|
||||
gp_style,
|
||||
stl->storage->shgroup_id,
|
||||
cache_ob->shading_type);
|
||||
|
||||
/* Disable stencil for this type */
|
||||
DRW_shgroup_state_disable(shgrp, DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_NEQUAL);
|
||||
|
||||
if ((do_onion) || (elm->onion == false)) {
|
||||
DRW_shgroup_call_range(shgrp, cache->b_fill.batch, start_fill, len);
|
||||
DRW_shgroup_call_range_obmat(shgrp, cache->b_fill.batch, obmat, start_fill, len);
|
||||
}
|
||||
stl->storage->shgroup_id++;
|
||||
start_fill = elm->vertex_idx;
|
||||
|
||||
/* Disable stencil for this type */
|
||||
DRW_shgroup_state_disable(shgrp, DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_NEQUAL);
|
||||
/* set stencil mask id as not used */
|
||||
DRW_shgroup_stencil_mask(shgrp, 0x0);
|
||||
break;
|
||||
}
|
||||
case eGpencilBatchGroupType_Edit: {
|
||||
if (stl->g_data->shgrps_edit_point) {
|
||||
const int len = elm->vertex_idx - start_edit;
|
||||
|
||||
shgrp = DRW_shgroup_create_sub(stl->g_data->shgrps_edit_point);
|
||||
DRW_shgroup_uniform_mat4(shgrp, "gpModelMatrix", obmat);
|
||||
/* use always the same group */
|
||||
DRW_shgroup_call_range(
|
||||
stl->g_data->shgrps_edit_point, cache->b_edit.batch, start_edit, len);
|
||||
DRW_shgroup_call_range_obmat(
|
||||
stl->g_data->shgrps_edit_point, cache->b_edit.batch, obmat, start_edit, len);
|
||||
|
||||
start_edit = elm->vertex_idx;
|
||||
}
|
||||
|
@ -1899,12 +1880,9 @@ static void gpencil_shgroups_create(GPENCIL_e_data *e_data,
|
|||
case eGpencilBatchGroupType_Edlin: {
|
||||
if (stl->g_data->shgrps_edit_line) {
|
||||
const int len = elm->vertex_idx - start_edlin;
|
||||
|
||||
shgrp = DRW_shgroup_create_sub(stl->g_data->shgrps_edit_line);
|
||||
DRW_shgroup_uniform_mat4(shgrp, "gpModelMatrix", obmat);
|
||||
/* use always the same group */
|
||||
DRW_shgroup_call_range(
|
||||
stl->g_data->shgrps_edit_line, cache->b_edlin.batch, start_edlin, len);
|
||||
DRW_shgroup_call_range_obmat(
|
||||
stl->g_data->shgrps_edit_line, cache->b_edlin.batch, obmat, start_edlin, len);
|
||||
|
||||
start_edlin = elm->vertex_idx;
|
||||
}
|
||||
|
|
|
@ -61,8 +61,6 @@ extern char datatoc_gpencil_edit_point_geom_glsl[];
|
|||
extern char datatoc_gpencil_edit_point_frag_glsl[];
|
||||
extern char datatoc_gpencil_blend_frag_glsl[];
|
||||
|
||||
extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
|
||||
|
||||
extern char datatoc_common_colormanagement_lib_glsl[];
|
||||
extern char datatoc_common_view_lib_glsl[];
|
||||
|
||||
|
@ -223,12 +221,7 @@ static void GPENCIL_create_shaders(void)
|
|||
|
||||
/* used for edit lines for edit modes */
|
||||
if (!e_data.gpencil_line_sh) {
|
||||
e_data.gpencil_line_sh = DRW_shader_create_with_lib(
|
||||
datatoc_gpencil_edit_point_vert_glsl,
|
||||
NULL,
|
||||
datatoc_gpu_shader_3D_smooth_color_frag_glsl,
|
||||
datatoc_common_view_lib_glsl,
|
||||
NULL);
|
||||
e_data.gpencil_line_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_FLAT_COLOR);
|
||||
}
|
||||
|
||||
/* used to filling during drawing */
|
||||
|
@ -286,7 +279,6 @@ static void GPENCIL_engine_free(void)
|
|||
DRW_SHADER_FREE_SAFE(e_data.gpencil_stroke_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.gpencil_point_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.gpencil_edit_point_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.gpencil_line_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.gpencil_fullscreen_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.gpencil_simple_fullscreen_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.gpencil_blend_fullscreen_sh);
|
||||
|
@ -842,13 +834,76 @@ static void gpencil_draw_pass_range(GPENCIL_FramebufferList *fbl,
|
|||
|
||||
const bool do_antialiasing = ((!stl->storage->is_mat_preview) && (multi));
|
||||
|
||||
DRWShadingGroup *shgrp = init_shgrp;
|
||||
DRWShadingGroup *from_shgrp = init_shgrp;
|
||||
DRWShadingGroup *to_shgrp = init_shgrp;
|
||||
int stencil_tot = 0;
|
||||
bool do_last = true;
|
||||
|
||||
if (do_antialiasing) {
|
||||
MULTISAMPLE_GP_SYNC_ENABLE(stl->storage->multisamples, fbl);
|
||||
}
|
||||
|
||||
DRW_draw_pass_subset(GPENCIL_3D_DRAWMODE(ob, gpd) ? psl->stroke_pass_3d : psl->stroke_pass_2d,
|
||||
init_shgrp,
|
||||
end_shgrp);
|
||||
/* Loop all shading groups to separate by stencil groups. */
|
||||
while ((shgrp) && (shgrp != end_shgrp)) {
|
||||
do_last = true;
|
||||
/* Count number of groups using stencil. */
|
||||
if (DRW_shgroup_stencil_mask_get(shgrp) != 0) {
|
||||
stencil_tot++;
|
||||
}
|
||||
|
||||
/* Draw stencil group and clear stencil bit. This is required because the number of
|
||||
* shading groups can be greater than the limit of 255 stencil values.
|
||||
* Only count as stencil if the shading group has an stencil value assigned. This reduces
|
||||
* the number of clears because Dots, Fills and some Line strokes don't need stencil.
|
||||
*/
|
||||
if (stencil_tot == 255) {
|
||||
DRW_draw_pass_subset(GPENCIL_3D_DRAWMODE(ob, gpd) ? psl->stroke_pass_3d :
|
||||
psl->stroke_pass_2d,
|
||||
from_shgrp,
|
||||
to_shgrp);
|
||||
/* Clear Stencil and prepare for next group. */
|
||||
if (do_antialiasing) {
|
||||
GPU_framebuffer_clear_stencil(fbl->multisample_fb, 0x0);
|
||||
}
|
||||
else {
|
||||
GPU_framebuffer_clear_stencil(fb, 0x0);
|
||||
}
|
||||
|
||||
/* Set new init group and reset. */
|
||||
do_last = false;
|
||||
|
||||
shgrp = DRW_shgroup_get_next(shgrp);
|
||||
if (shgrp) {
|
||||
from_shgrp = to_shgrp = shgrp;
|
||||
stencil_tot = 0;
|
||||
if (shgrp != end_shgrp) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
do_last = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* No more groups. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Still below stencil group limit. */
|
||||
shgrp = DRW_shgroup_get_next(shgrp);
|
||||
if (shgrp) {
|
||||
to_shgrp = shgrp;
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw last pending groups. */
|
||||
if (do_last) {
|
||||
DRW_draw_pass_subset(GPENCIL_3D_DRAWMODE(ob, gpd) ? psl->stroke_pass_3d : psl->stroke_pass_2d,
|
||||
from_shgrp,
|
||||
to_shgrp);
|
||||
}
|
||||
|
||||
if (do_antialiasing) {
|
||||
MULTISAMPLE_GP_SYNC_DISABLE(stl->storage->multisamples, fbl, fb, txl);
|
||||
|
|
|
@ -390,7 +390,6 @@ struct DRWShadingGroup *gpencil_shgroup_stroke_create(struct GPENCIL_Data *vedat
|
|||
struct DRWPass *pass,
|
||||
struct GPUShader *shader,
|
||||
struct Object *ob,
|
||||
float (*obmat)[4],
|
||||
struct bGPdata *gpd,
|
||||
struct bGPDlayer *gpl,
|
||||
struct bGPDstroke *gps,
|
||||
|
|
|
@ -308,9 +308,6 @@ void GPENCIL_render_to_image(void *vedata,
|
|||
DRW_render_object_iter(vedata, engine, draw_ctx->depsgraph, GPENCIL_render_cache);
|
||||
|
||||
GPENCIL_cache_finish(vedata);
|
||||
|
||||
DRW_render_instance_buffer_finish();
|
||||
|
||||
GPENCIL_draw_scene(vedata);
|
||||
|
||||
/* combined data */
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
|
||||
uniform mat4 gpModelMatrix;
|
||||
|
||||
in vec3 pos;
|
||||
in vec4 color;
|
||||
in float size;
|
||||
|
@ -10,7 +8,7 @@ out float finalThickness;
|
|||
|
||||
void main()
|
||||
{
|
||||
gl_Position = point_world_to_ndc((gpModelMatrix * vec4(pos, 1.0)).xyz);
|
||||
gl_Position = point_object_to_ndc(pos);
|
||||
finalColor = color;
|
||||
finalThickness = size;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
|
||||
uniform mat4 gpModelMatrix;
|
||||
|
||||
in vec3 pos;
|
||||
in vec4 color;
|
||||
in vec2 texCoord;
|
||||
|
@ -10,7 +8,7 @@ out vec2 texCoord_interp;
|
|||
|
||||
void main(void)
|
||||
{
|
||||
gl_Position = point_world_to_ndc((gpModelMatrix * vec4(pos, 1.0)).xyz);
|
||||
gl_Position = point_object_to_ndc(pos);
|
||||
finalColor = color;
|
||||
texCoord_interp = texCoord;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ uniform float pixfactor;
|
|||
uniform int viewport_xray;
|
||||
uniform int shading_type[2];
|
||||
uniform vec4 wire_color;
|
||||
uniform mat4 gpModelMatrix;
|
||||
|
||||
in vec3 pos;
|
||||
in vec4 color;
|
||||
|
@ -31,8 +30,8 @@ float defaultpixsize = pixsize * (1000.0 / pixfactor);
|
|||
|
||||
void main()
|
||||
{
|
||||
gl_Position = point_world_to_ndc((gpModelMatrix * vec4(pos, 1.0)).xyz);
|
||||
finalprev_pos = point_world_to_ndc((gpModelMatrix * vec4(prev_pos, 1.0)).xyz);
|
||||
gl_Position = point_object_to_ndc(pos);
|
||||
finalprev_pos = point_object_to_ndc(prev_pos);
|
||||
finalColor = color;
|
||||
|
||||
if (keep_size == TRUE) {
|
||||
|
|
|
@ -6,7 +6,6 @@ uniform float pixfactor;
|
|||
uniform int viewport_xray;
|
||||
uniform int shading_type[2];
|
||||
uniform vec4 wire_color;
|
||||
uniform mat4 gpModelMatrix;
|
||||
|
||||
in vec3 pos;
|
||||
in vec4 color;
|
||||
|
@ -29,7 +28,7 @@ float defaultpixsize = pixsize * (1000.0 / pixfactor);
|
|||
|
||||
void main(void)
|
||||
{
|
||||
gl_Position = point_world_to_ndc((gpModelMatrix * vec4(pos, 1.0)).xyz);
|
||||
gl_Position = point_object_to_ndc(pos);
|
||||
finalColor = color;
|
||||
|
||||
if (keep_size == TRUE) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
|
||||
uniform int object_id = 0;
|
||||
layout(location = 0) out uint objectId;
|
||||
|
||||
uniform float ImageTransparencyCutoff = 0.1;
|
||||
#ifdef V3D_SHADING_TEXTURE_COLOR
|
||||
uniform sampler2D image;
|
||||
|
@ -11,10 +10,11 @@ in vec2 uv_interp;
|
|||
void main()
|
||||
{
|
||||
#ifdef V3D_SHADING_TEXTURE_COLOR
|
||||
if (texture(image, uv_interp).a < ImageTransparencyCutoff) {
|
||||
vec4 diffuse_color = texture(image, uv_interp);
|
||||
if (diffuse_color.a < ImageTransparencyCutoff) {
|
||||
discard;
|
||||
}
|
||||
#endif
|
||||
|
||||
objectId = uint(resource_id + 1) & 0xFFu;
|
||||
objectId = uint(object_id);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,8 @@ uniform float alpha = 0.5;
|
|||
uniform vec2 invertedViewportSize;
|
||||
uniform vec4 viewvecs[3];
|
||||
|
||||
uniform vec4 materialColorAndMetal;
|
||||
uniform vec3 materialDiffuseColor;
|
||||
uniform vec3 materialSpecularColor;
|
||||
uniform float materialRoughness;
|
||||
|
||||
uniform float shadowMultiplier = 0.5;
|
||||
|
@ -41,17 +42,17 @@ layout(location = 1) out
|
|||
|
||||
void main()
|
||||
{
|
||||
vec4 base_color;
|
||||
vec4 diffuse_color;
|
||||
|
||||
#if defined(V3D_SHADING_TEXTURE_COLOR)
|
||||
base_color = workbench_sample_texture(image, uv_interp, imageNearest, imagePremultiplied);
|
||||
if (base_color.a < ImageTransparencyCutoff) {
|
||||
diffuse_color = workbench_sample_texture(image, uv_interp, imageNearest, imagePremultiplied);
|
||||
if (diffuse_color.a < ImageTransparencyCutoff) {
|
||||
discard;
|
||||
}
|
||||
#elif defined(V3D_SHADING_VERTEX_COLOR)
|
||||
base_color.rgb = vertexColor;
|
||||
diffuse_color = vec4(vertexColor, 1.0);
|
||||
#else
|
||||
base_color.rgb = materialColorAndMetal.rgb;
|
||||
diffuse_color = vec4(materialDiffuseColor, 1.0);
|
||||
#endif /* V3D_SHADING_TEXTURE_COLOR */
|
||||
|
||||
vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize;
|
||||
|
@ -63,7 +64,7 @@ void main()
|
|||
|
||||
/* -------- SHADING --------- */
|
||||
#ifdef V3D_LIGHTING_FLAT
|
||||
vec3 shaded_color = base_color.rgb;
|
||||
vec3 shaded_color = diffuse_color.rgb;
|
||||
|
||||
#elif defined(V3D_LIGHTING_MATCAP)
|
||||
bool flipped = world_data.matcap_orientation != 0;
|
||||
|
@ -74,20 +75,11 @@ void main()
|
|||
# else
|
||||
vec3 matcap_specular = vec3(0.0);
|
||||
# endif
|
||||
vec3 shaded_color = matcap_diffuse * base_color.rgb + matcap_specular;
|
||||
vec3 shaded_color = matcap_diffuse * diffuse_color.rgb + matcap_specular;
|
||||
|
||||
#elif defined(V3D_LIGHTING_STUDIO)
|
||||
# ifdef V3D_SHADING_SPECULAR_HIGHLIGHT
|
||||
float metallic = materialColorAndMetal.a;
|
||||
vec3 specular_color = mix(vec3(0.05), base_color.rgb, metallic);
|
||||
vec3 diffuse_color = mix(base_color.rgb, vec3(0.0), metallic);
|
||||
# else
|
||||
vec3 specular_color = vec3(0.0);
|
||||
vec3 diffuse_color = base_color.rgb;
|
||||
# endif
|
||||
|
||||
vec3 shaded_color = get_world_lighting(
|
||||
world_data, diffuse_color, specular_color, materialRoughness, nor, I_vs);
|
||||
world_data, diffuse_color.rgb, materialSpecularColor, materialRoughness, nor, I_vs);
|
||||
#endif
|
||||
|
||||
#ifdef V3D_SHADING_SHADOW
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
uniform int object_id = 0;
|
||||
|
||||
uniform vec4 materialColorAndMetal;
|
||||
uniform vec3 materialDiffuseColor;
|
||||
uniform float materialMetallic;
|
||||
uniform float materialRoughness;
|
||||
|
||||
uniform sampler2D image;
|
||||
|
@ -46,7 +48,7 @@ void main()
|
|||
# elif defined(V3D_SHADING_VERTEX_COLOR)
|
||||
color.rgb = vertexColor;
|
||||
# else
|
||||
color.rgb = materialColorAndMetal.rgb;
|
||||
color.rgb = materialDiffuseColor;
|
||||
# endif
|
||||
|
||||
# ifdef V3D_LIGHTING_MATCAP
|
||||
|
@ -54,7 +56,7 @@ void main()
|
|||
metallic = float(gl_FrontFacing);
|
||||
roughness = 0.0;
|
||||
# else
|
||||
metallic = materialColorAndMetal.a;
|
||||
metallic = materialMetallic;
|
||||
roughness = materialRoughness;
|
||||
# endif
|
||||
|
||||
|
@ -62,7 +64,7 @@ void main()
|
|||
/* Add some variation to the hairs to avoid uniform look. */
|
||||
float hair_variation = hair_rand * 0.1;
|
||||
color = clamp(color - hair_variation, 0.0, 1.0);
|
||||
metallic = clamp(materialColorAndMetal.a - hair_variation, 0.0, 1.0);
|
||||
metallic = clamp(materialMetallic - hair_variation, 0.0, 1.0);
|
||||
roughness = clamp(materialRoughness - hair_variation, 0.0, 1.0);
|
||||
# endif
|
||||
|
||||
|
@ -71,7 +73,7 @@ void main()
|
|||
#endif /* MATDATA_PASS_ENABLED */
|
||||
|
||||
#ifdef OBJECT_ID_PASS_ENABLED
|
||||
objectId = uint(resource_id + 1) & 0xFFu;
|
||||
objectId = uint(object_id);
|
||||
#endif
|
||||
|
||||
#ifdef NORMAL_VIEWPORT_PASS_ENABLED
|
||||
|
|
|
@ -25,10 +25,6 @@ out vec2 uv_interp;
|
|||
out vec3 vertexColor;
|
||||
#endif
|
||||
|
||||
#ifdef OBJECT_ID_PASS_ENABLED
|
||||
RESOURCE_ID_VARYING
|
||||
#endif
|
||||
|
||||
/* From http://libnoise.sourceforge.net/noisegen/index.html */
|
||||
float integer_noise(int n)
|
||||
{
|
||||
|
@ -95,18 +91,12 @@ void main()
|
|||
#endif
|
||||
|
||||
#ifdef NORMAL_VIEWPORT_PASS_ENABLED
|
||||
# ifndef HAIR_SHADER
|
||||
normal_viewport = normal_object_to_view(nor);
|
||||
# ifndef HAIR_SHADER
|
||||
normal_viewport = normalize(normal_viewport);
|
||||
# else
|
||||
normal_viewport = normal_world_to_view(nor);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef OBJECT_ID_PASS_ENABLED
|
||||
PASS_RESOURCE_ID
|
||||
#endif
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(world_pos);
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
|
||||
uniform vec3 OrcoTexCoFactors[2];
|
||||
|
||||
uniform sampler2D depthBuffer;
|
||||
|
||||
uniform sampler3D densityTexture;
|
||||
|
@ -214,13 +216,13 @@ void main()
|
|||
vs_ray_dir /= abs(vs_ray_dir.z);
|
||||
|
||||
/* TODO(fclem) Precompute the matrix/ */
|
||||
vec3 ls_ray_dir = mat3(ViewMatrixInverse) * vs_ray_dir * OrcoTexCoFactors[1].xyz * 2.0;
|
||||
vec3 ls_ray_dir = mat3(ViewMatrixInverse) * vs_ray_dir * OrcoTexCoFactors[1] * 2.0;
|
||||
ls_ray_dir = mat3(ModelMatrixInverse) * ls_ray_dir;
|
||||
vec3 ls_ray_ori = point_view_to_object(vs_ray_ori);
|
||||
vec3 ls_ray_end = point_view_to_object(vs_ray_end);
|
||||
|
||||
ls_ray_ori = (OrcoTexCoFactors[0].xyz + ls_ray_ori * OrcoTexCoFactors[1].xyz) * 2.0 - 1.0;
|
||||
ls_ray_end = (OrcoTexCoFactors[0].xyz + ls_ray_end * OrcoTexCoFactors[1].xyz) * 2.0 - 1.0;
|
||||
ls_ray_ori = (OrcoTexCoFactors[0] + ls_ray_ori * OrcoTexCoFactors[1]) * 2.0 - 1.0;
|
||||
ls_ray_end = (OrcoTexCoFactors[0] + ls_ray_end * OrcoTexCoFactors[1]) * 2.0 - 1.0;
|
||||
|
||||
/* TODO: Align rays to volume center so that it mimics old behaviour of slicing the volume. */
|
||||
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
|
||||
uniform vec3 OrcoTexCoFactors[2];
|
||||
uniform float slicePosition;
|
||||
uniform int sliceAxis; /* -1 is no slice, 0 is X, 1 is Y, 2 is Z. */
|
||||
|
||||
in vec3 pos;
|
||||
|
||||
RESOURCE_ID_VARYING
|
||||
|
||||
#ifdef VOLUME_SLICE
|
||||
in vec3 uvs;
|
||||
|
||||
|
@ -28,8 +27,6 @@ void main()
|
|||
#else
|
||||
vec3 final_pos = pos;
|
||||
#endif
|
||||
final_pos = ((final_pos * 0.5 + 0.5) - OrcoTexCoFactors[0].xyz) / OrcoTexCoFactors[1].xyz;
|
||||
final_pos = ((final_pos * 0.5 + 0.5) - OrcoTexCoFactors[0]) / OrcoTexCoFactors[1];
|
||||
gl_Position = point_object_to_ndc(final_pos);
|
||||
|
||||
PASS_RESOURCE_ID
|
||||
}
|
||||
|
|
|
@ -83,6 +83,7 @@ static struct {
|
|||
struct GPUTexture *composite_buffer_tx; /* ref only, not alloced */
|
||||
|
||||
SceneDisplay display; /* world light direction for shadows */
|
||||
int next_object_id;
|
||||
|
||||
struct GPUUniformBuffer *sampling_ubo;
|
||||
struct GPUTexture *jitter_tx;
|
||||
|
@ -146,7 +147,6 @@ static char *workbench_build_prepass_frag(void)
|
|||
{
|
||||
DynStr *ds = BLI_dynstr_new();
|
||||
|
||||
BLI_dynstr_append(ds, datatoc_common_view_lib_glsl);
|
||||
BLI_dynstr_append(ds, datatoc_workbench_data_lib_glsl);
|
||||
BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl);
|
||||
BLI_dynstr_append(ds, datatoc_workbench_prepass_frag_glsl);
|
||||
|
@ -330,6 +330,7 @@ static struct GPUTexture *create_jitter_texture(int num_samples)
|
|||
static void workbench_init_object_data(DrawData *dd)
|
||||
{
|
||||
WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)dd;
|
||||
data->object_id = ((e_data.next_object_id++) & 0xff) + 1;
|
||||
data->shadow_bbox_dirty = true;
|
||||
}
|
||||
|
||||
|
@ -378,10 +379,11 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
|
|||
workbench_effect_info_init(stl->effects);
|
||||
}
|
||||
|
||||
if (!e_data.shadow_pass_sh) {
|
||||
if (!e_data.next_object_id) {
|
||||
WORKBENCH_DEFERRED_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
|
||||
memset(sh_data->prepass_sh_cache, 0, sizeof(sh_data->prepass_sh_cache));
|
||||
memset(e_data.composite_sh_cache, 0, sizeof(e_data.composite_sh_cache));
|
||||
e_data.next_object_id = 1;
|
||||
#ifdef DEBUG_SHADOW_VOLUME
|
||||
const char *shadow_frag = datatoc_workbench_shadow_debug_frag_glsl;
|
||||
#else
|
||||
|
@ -866,11 +868,18 @@ static WORKBENCH_MaterialData *get_or_create_material_data(WORKBENCH_Data *vedat
|
|||
WORKBENCH_PassList *psl = vedata->psl;
|
||||
WORKBENCH_PrivateData *wpd = stl->g_data;
|
||||
WORKBENCH_MaterialData *material;
|
||||
WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_drawdata_ensure(
|
||||
&ob->id,
|
||||
&draw_engine_workbench_solid,
|
||||
sizeof(WORKBENCH_ObjectData),
|
||||
&workbench_init_object_data,
|
||||
NULL);
|
||||
WORKBENCH_MaterialData material_template;
|
||||
const bool is_ghost = (ob->dtx & OB_DRAWXRAY);
|
||||
|
||||
/* Solid */
|
||||
workbench_material_update_data(wpd, ob, mat, &material_template, color_type);
|
||||
material_template.object_id = OBJECT_ID_PASS_ENABLED(wpd) ? engine_object_data->object_id : 1;
|
||||
material_template.color_type = color_type;
|
||||
material_template.ima = ima;
|
||||
material_template.iuser = iuser;
|
||||
|
@ -890,7 +899,8 @@ static WORKBENCH_MaterialData *get_or_create_material_data(WORKBENCH_Data *vedat
|
|||
shader, (ob->dtx & OB_DRAWXRAY) ? psl->ghost_prepass_pass : psl->prepass_pass);
|
||||
workbench_material_copy(material, &material_template);
|
||||
DRW_shgroup_stencil_mask(material->shgrp, (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF);
|
||||
workbench_material_shgroup_uniform(wpd, material->shgrp, material, ob, true, interp);
|
||||
DRW_shgroup_uniform_int(material->shgrp, "object_id", &material->object_id, 1);
|
||||
workbench_material_shgroup_uniform(wpd, material->shgrp, material, ob, true, true, interp);
|
||||
BLI_ghash_insert(wpd->material_hash, POINTER_FROM_UINT(hash), material);
|
||||
}
|
||||
return material;
|
||||
|
@ -933,7 +943,8 @@ static void workbench_cache_populate_particles(WORKBENCH_Data *vedata, Object *o
|
|||
(ob->dtx & OB_DRAWXRAY) ? psl->ghost_prepass_hair_pass : psl->prepass_hair_pass,
|
||||
shader);
|
||||
DRW_shgroup_stencil_mask(shgrp, (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF);
|
||||
workbench_material_shgroup_uniform(wpd, shgrp, material, ob, true, interp);
|
||||
DRW_shgroup_uniform_int(shgrp, "object_id", &material->object_id, 1);
|
||||
workbench_material_shgroup_uniform(wpd, shgrp, material, ob, true, true, interp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,6 +63,8 @@ static struct {
|
|||
struct GPUTexture *transparent_accum_tx; /* ref only, not alloced */
|
||||
struct GPUTexture *transparent_revealage_tx; /* ref only, not alloced */
|
||||
struct GPUTexture *composite_buffer_tx; /* ref only, not alloced */
|
||||
|
||||
int next_object_id;
|
||||
} e_data = {{{{NULL}}}};
|
||||
|
||||
/* Shaders */
|
||||
|
@ -96,18 +98,6 @@ static char *workbench_build_forward_vert(bool is_hair)
|
|||
return str;
|
||||
}
|
||||
|
||||
static char *workbench_build_forward_outline_frag(void)
|
||||
{
|
||||
DynStr *ds = BLI_dynstr_new();
|
||||
|
||||
BLI_dynstr_append(ds, datatoc_common_view_lib_glsl);
|
||||
BLI_dynstr_append(ds, datatoc_workbench_forward_depth_frag_glsl);
|
||||
|
||||
char *str = BLI_dynstr_get_cstring(ds);
|
||||
BLI_dynstr_free(ds);
|
||||
return str;
|
||||
}
|
||||
|
||||
static char *workbench_build_forward_transparent_accum_frag(void)
|
||||
{
|
||||
DynStr *ds = BLI_dynstr_new();
|
||||
|
@ -139,6 +129,12 @@ static char *workbench_build_forward_composite_frag(void)
|
|||
return str;
|
||||
}
|
||||
|
||||
static void workbench_init_object_data(DrawData *dd)
|
||||
{
|
||||
WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)dd;
|
||||
data->object_id = ((e_data.next_object_id++) & 0xff) + 1;
|
||||
}
|
||||
|
||||
WORKBENCH_MaterialData *workbench_forward_get_or_create_material_data(WORKBENCH_Data *vedata,
|
||||
Object *ob,
|
||||
Material *mat,
|
||||
|
@ -153,11 +149,18 @@ WORKBENCH_MaterialData *workbench_forward_get_or_create_material_data(WORKBENCH_
|
|||
WORKBENCH_PassList *psl = vedata->psl;
|
||||
WORKBENCH_PrivateData *wpd = stl->g_data;
|
||||
WORKBENCH_MaterialData *material;
|
||||
WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_drawdata_ensure(
|
||||
&ob->id,
|
||||
&draw_engine_workbench_solid,
|
||||
sizeof(WORKBENCH_ObjectData),
|
||||
&workbench_init_object_data,
|
||||
NULL);
|
||||
WORKBENCH_MaterialData material_template;
|
||||
DRWShadingGroup *grp;
|
||||
|
||||
/* Solid */
|
||||
workbench_material_update_data(wpd, ob, mat, &material_template, color_type);
|
||||
material_template.object_id = OBJECT_ID_PASS_ENABLED(wpd) ? engine_object_data->object_id : 1;
|
||||
material_template.color_type = color_type;
|
||||
material_template.ima = ima;
|
||||
material_template.iuser = iuser;
|
||||
|
@ -202,7 +205,7 @@ WORKBENCH_MaterialData *workbench_forward_get_or_create_material_data(WORKBENCH_
|
|||
DRW_shgroup_uniform_float_copy(grp, "shadowFocus", wpd->shadow_focus);
|
||||
}
|
||||
|
||||
workbench_material_shgroup_uniform(wpd, grp, material, ob, false, interp);
|
||||
workbench_material_shgroup_uniform(wpd, grp, material, ob, false, false, interp);
|
||||
material->shgrp = grp;
|
||||
|
||||
/* Depth */
|
||||
|
@ -216,6 +219,8 @@ WORKBENCH_MaterialData *workbench_forward_get_or_create_material_data(WORKBENCH_
|
|||
material->shgrp_object_outline = DRW_shgroup_create(sh_data->object_outline_sh,
|
||||
psl->object_outline_pass);
|
||||
}
|
||||
material->object_id = engine_object_data->object_id;
|
||||
DRW_shgroup_uniform_int(material->shgrp_object_outline, "object_id", &material->object_id, 1);
|
||||
if (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) {
|
||||
DRW_shgroup_state_enable(material->shgrp_object_outline, DRW_STATE_CLIP_PLANES);
|
||||
}
|
||||
|
@ -287,30 +292,26 @@ void workbench_forward_outline_shaders_ensure(WORKBENCH_PrivateData *wpd, eGPUSh
|
|||
char *defines_texture = workbench_material_build_defines(wpd, true, false, false);
|
||||
char *defines_hair = workbench_material_build_defines(wpd, false, true, false);
|
||||
char *forward_vert = workbench_build_forward_vert(false);
|
||||
char *forward_frag = workbench_build_forward_outline_frag();
|
||||
char *forward_hair_vert = workbench_build_forward_vert(true);
|
||||
|
||||
const char *define_id_pass = "#define OBJECT_ID_PASS_ENABLED\n";
|
||||
|
||||
sh_data->object_outline_sh = GPU_shader_create_from_arrays({
|
||||
.vert = (const char *[]){sh_cfg_data->lib, forward_vert, NULL},
|
||||
.frag = (const char *[]){forward_frag, NULL},
|
||||
.defs = (const char *[]){sh_cfg_data->def, defines, define_id_pass, NULL},
|
||||
.frag = (const char *[]){datatoc_workbench_forward_depth_frag_glsl, NULL},
|
||||
.defs = (const char *[]){sh_cfg_data->def, defines, NULL},
|
||||
});
|
||||
sh_data->object_outline_texture_sh = GPU_shader_create_from_arrays({
|
||||
.vert = (const char *[]){sh_cfg_data->lib, forward_vert, NULL},
|
||||
.frag = (const char *[]){forward_frag, NULL},
|
||||
.defs = (const char *[]){sh_cfg_data->def, defines_texture, define_id_pass, NULL},
|
||||
.frag = (const char *[]){datatoc_workbench_forward_depth_frag_glsl, NULL},
|
||||
.defs = (const char *[]){sh_cfg_data->def, defines_texture, NULL},
|
||||
});
|
||||
sh_data->object_outline_hair_sh = GPU_shader_create_from_arrays({
|
||||
.vert = (const char *[]){sh_cfg_data->lib, forward_hair_vert, NULL},
|
||||
.frag = (const char *[]){forward_frag, NULL},
|
||||
.defs = (const char *[]){sh_cfg_data->def, defines_hair, define_id_pass, NULL},
|
||||
.frag = (const char *[]){datatoc_workbench_forward_depth_frag_glsl, NULL},
|
||||
.defs = (const char *[]){sh_cfg_data->def, defines_hair, NULL},
|
||||
});
|
||||
|
||||
MEM_freeN(forward_hair_vert);
|
||||
MEM_freeN(forward_vert);
|
||||
MEM_freeN(forward_frag);
|
||||
MEM_freeN(defines);
|
||||
MEM_freeN(defines_texture);
|
||||
MEM_freeN(defines_hair);
|
||||
|
@ -526,7 +527,7 @@ static void workbench_forward_cache_populate_particles(WORKBENCH_Data *vedata, O
|
|||
DRWShadingGroup *shgrp = DRW_shgroup_hair_create(
|
||||
ob, psys, md, psl->transparent_accum_pass, shader);
|
||||
DRW_shgroup_uniform_block(shgrp, "world_block", wpd->world_ubo);
|
||||
workbench_material_shgroup_uniform(wpd, shgrp, material, ob, false, interp);
|
||||
workbench_material_shgroup_uniform(wpd, shgrp, material, ob, false, false, interp);
|
||||
DRW_shgroup_uniform_vec4(shgrp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
|
||||
/* Hairs have lots of layer and can rapidly become the most prominent surface.
|
||||
* So lower their alpha artificially. */
|
||||
|
@ -550,6 +551,7 @@ static void workbench_forward_cache_populate_particles(WORKBENCH_Data *vedata, O
|
|||
WORKBENCH_FORWARD_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
|
||||
shgrp = DRW_shgroup_hair_create(
|
||||
ob, psys, md, vedata->psl->object_outline_pass, sh_data->object_outline_hair_sh);
|
||||
DRW_shgroup_uniform_int(shgrp, "object_id", &material->object_id, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,15 +44,20 @@ void workbench_material_update_data(WORKBENCH_PrivateData *wpd,
|
|||
WORKBENCH_MaterialData *data,
|
||||
int color_type)
|
||||
{
|
||||
copy_v3_fl3(data->diffuse_color, 0.8f, 0.8f, 0.8f);
|
||||
copy_v3_v3(data->base_color, data->diffuse_color);
|
||||
copy_v3_fl3(data->specular_color, 0.05f, 0.05f, 0.05f); /* Dielectric: 5% reflective. */
|
||||
data->metallic = 0.0f;
|
||||
data->roughness = 0.632455532f; /* sqrtf(0.4f); */
|
||||
data->alpha = wpd->shading.xray_alpha;
|
||||
|
||||
if (color_type == V3D_SHADING_SINGLE_COLOR) {
|
||||
copy_v3_v3(data->base_color, wpd->shading.single_color);
|
||||
copy_v3_v3(data->diffuse_color, wpd->shading.single_color);
|
||||
copy_v3_v3(data->base_color, data->diffuse_color);
|
||||
}
|
||||
else if (color_type == V3D_SHADING_ERROR_COLOR) {
|
||||
copy_v3_fl3(data->base_color, 0.8, 0.0, 0.8);
|
||||
copy_v3_fl3(data->diffuse_color, 0.8, 0.0, 0.8);
|
||||
copy_v3_v3(data->base_color, data->diffuse_color);
|
||||
}
|
||||
else if (color_type == V3D_SHADING_RANDOM_COLOR) {
|
||||
uint hash = BLI_ghashutil_strhash_p_murmur(ob->id.name);
|
||||
|
@ -62,24 +67,30 @@ void workbench_material_update_data(WORKBENCH_PrivateData *wpd,
|
|||
|
||||
float hue = BLI_hash_int_01(hash);
|
||||
float hsv[3] = {hue, HSV_SATURATION, HSV_VALUE};
|
||||
hsv_to_rgb_v(hsv, data->base_color);
|
||||
hsv_to_rgb_v(hsv, data->diffuse_color);
|
||||
copy_v3_v3(data->base_color, data->diffuse_color);
|
||||
}
|
||||
else if (ELEM(color_type, V3D_SHADING_OBJECT_COLOR, V3D_SHADING_VERTEX_COLOR)) {
|
||||
copy_v3_v3(data->diffuse_color, ob->color);
|
||||
copy_v3_v3(data->base_color, data->diffuse_color);
|
||||
data->alpha *= ob->color[3];
|
||||
copy_v3_v3(data->base_color, ob->color);
|
||||
}
|
||||
else {
|
||||
/* V3D_SHADING_MATERIAL_COLOR or V3D_SHADING_TEXTURE_COLOR */
|
||||
if (mat) {
|
||||
data->alpha *= mat->a;
|
||||
copy_v3_v3(data->base_color, &mat->r);
|
||||
if (workbench_is_specular_highlight_enabled(wpd)) {
|
||||
copy_v3_v3(data->base_color, &mat->r);
|
||||
mul_v3_v3fl(data->diffuse_color, &mat->r, 1.0f - mat->metallic);
|
||||
mul_v3_v3fl(data->specular_color, &mat->r, mat->metallic);
|
||||
add_v3_fl(data->specular_color, 0.05f * (1.0f - mat->metallic));
|
||||
data->metallic = mat->metallic;
|
||||
data->roughness = sqrtf(mat->roughness); /* Remap to disney roughness. */
|
||||
}
|
||||
}
|
||||
else {
|
||||
copy_v3_fl(data->base_color, 0.8f);
|
||||
else {
|
||||
copy_v3_v3(data->base_color, &mat->r);
|
||||
copy_v3_v3(data->diffuse_color, &mat->r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -149,40 +160,34 @@ char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd,
|
|||
return str;
|
||||
}
|
||||
|
||||
uint workbench_material_get_hash(WORKBENCH_MaterialData *mat, bool is_ghost)
|
||||
uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template, bool is_ghost)
|
||||
{
|
||||
union {
|
||||
struct {
|
||||
/* WHATCH: Keep in sync with View3DShading.color_type max value. */
|
||||
uchar color_type;
|
||||
uchar diff_r;
|
||||
uchar diff_g;
|
||||
uchar diff_b;
|
||||
uint input[4];
|
||||
uint result;
|
||||
float *color = material_template->diffuse_color;
|
||||
input[0] = (uint)(color[0] * 512);
|
||||
input[1] = (uint)(color[1] * 512);
|
||||
input[2] = (uint)(color[2] * 512);
|
||||
input[3] = material_template->object_id;
|
||||
result = BLI_ghashutil_uinthash_v4_murmur(input);
|
||||
|
||||
uchar alpha;
|
||||
uchar ghost;
|
||||
uchar metal;
|
||||
uchar roughness;
|
||||
color = material_template->specular_color;
|
||||
input[0] = (uint)(color[0] * 512);
|
||||
input[1] = (uint)(color[1] * 512);
|
||||
input[2] = (uint)(color[2] * 512);
|
||||
input[3] = (uint)(material_template->roughness * 512);
|
||||
result += BLI_ghashutil_uinthash_v4_murmur(input);
|
||||
|
||||
void *ima;
|
||||
};
|
||||
/* HACK to ensure input is 4 uint long. */
|
||||
uint a[4];
|
||||
} input = {.color_type = (uchar)(mat->color_type),
|
||||
.diff_r = (uchar)(mat->base_color[0] * 0xFF),
|
||||
.diff_g = (uchar)(mat->base_color[1] * 0xFF),
|
||||
.diff_b = (uchar)(mat->base_color[2] * 0xFF),
|
||||
result += BLI_ghashutil_uinthash((uint)(material_template->alpha * 512));
|
||||
result += BLI_ghashutil_uinthash((uint)is_ghost);
|
||||
result += BLI_ghashutil_uinthash(material_template->color_type);
|
||||
|
||||
.alpha = (uint)(mat->alpha * 0xFF),
|
||||
.ghost = (uchar)is_ghost,
|
||||
.metal = (uchar)(mat->metallic * 0xFF),
|
||||
.roughness = (uchar)(mat->roughness * 0xFF),
|
||||
/* add texture reference */
|
||||
if (material_template->ima) {
|
||||
result += BLI_ghashutil_inthash_p_murmur(material_template->ima);
|
||||
}
|
||||
|
||||
.ima = mat->ima};
|
||||
|
||||
BLI_assert(sizeof(input) == sizeof(uint) * 4);
|
||||
|
||||
return BLI_ghashutil_uinthash_v4((uint *)&input);
|
||||
return result;
|
||||
}
|
||||
|
||||
int workbench_material_get_composite_shader_index(WORKBENCH_PrivateData *wpd)
|
||||
|
@ -310,28 +315,35 @@ void workbench_material_shgroup_uniform(WORKBENCH_PrivateData *wpd,
|
|||
DRWShadingGroup *grp,
|
||||
WORKBENCH_MaterialData *material,
|
||||
Object *ob,
|
||||
const bool use_metallic,
|
||||
const bool deferred,
|
||||
const int interp)
|
||||
{
|
||||
if (!(!deferred || workbench_is_matdata_pass_enabled(wpd))) {
|
||||
return;
|
||||
}
|
||||
if (!deferred || workbench_is_matdata_pass_enabled(wpd)) {
|
||||
if (workbench_material_determine_color_type(wpd, material->ima, ob, false) ==
|
||||
V3D_SHADING_TEXTURE_COLOR) {
|
||||
GPUTexture *tex = GPU_texture_from_blender(material->ima, material->iuser, GL_TEXTURE_2D);
|
||||
DRW_shgroup_uniform_texture(grp, "image", tex);
|
||||
DRW_shgroup_uniform_bool_copy(
|
||||
grp, "imagePremultiplied", (material->ima->alpha_mode == IMA_ALPHA_PREMUL));
|
||||
DRW_shgroup_uniform_bool_copy(grp, "imageNearest", (interp == SHD_INTERP_CLOSEST));
|
||||
}
|
||||
else {
|
||||
DRW_shgroup_uniform_vec3(grp,
|
||||
"materialDiffuseColor",
|
||||
(use_metallic) ? material->base_color : material->diffuse_color,
|
||||
1);
|
||||
}
|
||||
|
||||
const bool use_highlight = workbench_is_specular_highlight_enabled(wpd);
|
||||
const bool use_texture = (V3D_SHADING_TEXTURE_COLOR == workbench_material_determine_color_type(
|
||||
wpd, material->ima, ob, false));
|
||||
if (use_texture) {
|
||||
GPUTexture *tex = GPU_texture_from_blender(material->ima, material->iuser, GL_TEXTURE_2D);
|
||||
DRW_shgroup_uniform_texture(grp, "image", tex);
|
||||
DRW_shgroup_uniform_bool_copy(
|
||||
grp, "imagePremultiplied", (material->ima->alpha_mode == IMA_ALPHA_PREMUL));
|
||||
DRW_shgroup_uniform_bool_copy(grp, "imageNearest", (interp == SHD_INTERP_CLOSEST));
|
||||
}
|
||||
|
||||
DRW_shgroup_uniform_vec4(grp, "materialColorAndMetal", material->base_color, 1);
|
||||
|
||||
if (use_highlight) {
|
||||
DRW_shgroup_uniform_float(grp, "materialRoughness", &material->roughness, 1);
|
||||
if (workbench_is_specular_highlight_enabled(wpd)) {
|
||||
if (use_metallic) {
|
||||
DRW_shgroup_uniform_float(grp, "materialMetallic", &material->metallic, 1);
|
||||
}
|
||||
else {
|
||||
DRW_shgroup_uniform_vec3(grp, "materialSpecularColor", material->specular_color, 1);
|
||||
}
|
||||
DRW_shgroup_uniform_float(grp, "materialRoughness", &material->roughness, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (WORLD_CLIPPING_ENABLED(wpd)) {
|
||||
|
@ -342,7 +354,10 @@ void workbench_material_shgroup_uniform(WORKBENCH_PrivateData *wpd,
|
|||
void workbench_material_copy(WORKBENCH_MaterialData *dest_material,
|
||||
const WORKBENCH_MaterialData *source_material)
|
||||
{
|
||||
dest_material->object_id = source_material->object_id;
|
||||
copy_v3_v3(dest_material->base_color, source_material->base_color);
|
||||
copy_v3_v3(dest_material->diffuse_color, source_material->diffuse_color);
|
||||
copy_v3_v3(dest_material->specular_color, source_material->specular_color);
|
||||
dest_material->metallic = source_material->metallic;
|
||||
dest_material->roughness = source_material->roughness;
|
||||
dest_material->ima = source_material->ima;
|
||||
|
|
|
@ -281,8 +281,13 @@ typedef struct WORKBENCH_EffectInfo {
|
|||
} WORKBENCH_EffectInfo;
|
||||
|
||||
typedef struct WORKBENCH_MaterialData {
|
||||
float base_color[3], metallic;
|
||||
float roughness, alpha;
|
||||
float base_color[3];
|
||||
float diffuse_color[3];
|
||||
float specular_color[3];
|
||||
float alpha;
|
||||
float metallic;
|
||||
float roughness;
|
||||
int object_id;
|
||||
int color_type;
|
||||
int interp;
|
||||
Image *ima;
|
||||
|
@ -303,6 +308,8 @@ typedef struct WORKBENCH_ObjectData {
|
|||
float shadow_min[3], shadow_max[3];
|
||||
BoundBox shadow_bbox;
|
||||
bool shadow_bbox_dirty;
|
||||
|
||||
int object_id;
|
||||
} WORKBENCH_ObjectData;
|
||||
|
||||
/* inline helper functions */
|
||||
|
@ -493,6 +500,7 @@ void workbench_material_shgroup_uniform(WORKBENCH_PrivateData *wpd,
|
|||
DRWShadingGroup *grp,
|
||||
WORKBENCH_MaterialData *material,
|
||||
Object *ob,
|
||||
const bool use_metallic,
|
||||
const bool deferred,
|
||||
const int interp);
|
||||
void workbench_material_copy(WORKBENCH_MaterialData *dest_material,
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
#include "BLI_rand.h"
|
||||
#include "BLI_dynstr.h"
|
||||
#include "BLI_string_utils.h"
|
||||
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_object_force_types.h"
|
||||
|
@ -55,7 +54,6 @@ static struct {
|
|||
extern char datatoc_workbench_volume_vert_glsl[];
|
||||
extern char datatoc_workbench_volume_frag_glsl[];
|
||||
extern char datatoc_common_view_lib_glsl[];
|
||||
extern char datatoc_gpu_shader_common_obinfos_lib_glsl[];
|
||||
|
||||
static GPUShader *volume_shader_get(bool slice, bool coba, bool cubic)
|
||||
{
|
||||
|
@ -80,16 +78,12 @@ static GPUShader *volume_shader_get(bool slice, bool coba, bool cubic)
|
|||
char *defines = BLI_dynstr_get_cstring(ds);
|
||||
BLI_dynstr_free(ds);
|
||||
|
||||
char *libs = BLI_string_joinN(datatoc_common_view_lib_glsl,
|
||||
datatoc_gpu_shader_common_obinfos_lib_glsl);
|
||||
|
||||
e_data.volume_sh[id] = DRW_shader_create_with_lib(datatoc_workbench_volume_vert_glsl,
|
||||
NULL,
|
||||
datatoc_workbench_volume_frag_glsl,
|
||||
libs,
|
||||
datatoc_common_view_lib_glsl,
|
||||
defines);
|
||||
|
||||
MEM_freeN(libs);
|
||||
MEM_freeN(defines);
|
||||
}
|
||||
|
||||
|
|
|
@ -80,6 +80,8 @@ typedef struct DRWPass DRWPass;
|
|||
typedef struct DRWShadingGroup DRWShadingGroup;
|
||||
typedef struct DRWUniform DRWUniform;
|
||||
typedef struct DRWView DRWView;
|
||||
|
||||
/* Opaque type to avoid usage as a DRWCall but it is exactly the same thing. */
|
||||
typedef struct DRWCallBuffer DRWCallBuffer;
|
||||
|
||||
/* TODO Put it somewhere else? */
|
||||
|
@ -402,29 +404,35 @@ void DRW_shgroup_call_ex(DRWShadingGroup *shgroup,
|
|||
Object *ob,
|
||||
float (*obmat)[4],
|
||||
struct GPUBatch *geom,
|
||||
uint v_sta,
|
||||
uint v_ct,
|
||||
bool bypass_culling,
|
||||
void *user_data);
|
||||
|
||||
/* If ob is NULL, unit modelmatrix is assumed and culling is bypassed. */
|
||||
#define DRW_shgroup_call(shgrp, geom, ob) DRW_shgroup_call_ex(shgrp, ob, NULL, geom, false, NULL)
|
||||
#define DRW_shgroup_call(shgrp, geom, ob) \
|
||||
DRW_shgroup_call_ex(shgrp, ob, NULL, geom, 0, 0, false, NULL)
|
||||
|
||||
/* Same as DRW_shgroup_call but override the obmat. Not culled. */
|
||||
#define DRW_shgroup_call_obmat(shgrp, geom, obmat) \
|
||||
DRW_shgroup_call_ex(shgrp, NULL, obmat, geom, false, NULL)
|
||||
DRW_shgroup_call_ex(shgrp, NULL, obmat, geom, 0, 0, false, NULL)
|
||||
|
||||
/* TODO(fclem) remove this when we have DRWView */
|
||||
/* user_data is used by DRWCallVisibilityFn defined in DRWView. */
|
||||
#define DRW_shgroup_call_with_callback(shgrp, geom, ob, user_data) \
|
||||
DRW_shgroup_call_ex(shgrp, ob, NULL, geom, false, user_data)
|
||||
DRW_shgroup_call_ex(shgrp, ob, NULL, geom, 0, 0, false, user_data)
|
||||
|
||||
/* Same as DRW_shgroup_call but bypass culling even if ob is not NULL. */
|
||||
#define DRW_shgroup_call_no_cull(shgrp, geom, ob) \
|
||||
DRW_shgroup_call_ex(shgrp, ob, NULL, geom, true, NULL)
|
||||
DRW_shgroup_call_ex(shgrp, ob, NULL, geom, 0, 0, true, NULL)
|
||||
|
||||
void DRW_shgroup_call_range(DRWShadingGroup *shgroup,
|
||||
struct GPUBatch *geom,
|
||||
uint v_sta,
|
||||
uint v_ct);
|
||||
/* Only draw a certain range of geom. */
|
||||
#define DRW_shgroup_call_range(shgrp, geom, ob, v_sta, v_ct) \
|
||||
DRW_shgroup_call_ex(shgrp, ob, NULL, geom, v_sta, v_ct, false, NULL)
|
||||
|
||||
/* Same as DRW_shgroup_call_range but override the obmat. Special for gpencil. */
|
||||
#define DRW_shgroup_call_range_obmat(shgrp, geom, obmat, v_sta, v_ct) \
|
||||
DRW_shgroup_call_ex(shgrp, NULL, obmat, geom, v_sta, v_ct, false, NULL)
|
||||
|
||||
void DRW_shgroup_call_procedural_points(DRWShadingGroup *sh, Object *ob, uint point_ct);
|
||||
void DRW_shgroup_call_procedural_lines(DRWShadingGroup *sh, Object *ob, uint line_ct);
|
||||
|
@ -461,16 +469,6 @@ void DRW_shgroup_state_enable(DRWShadingGroup *shgroup, DRWState state);
|
|||
void DRW_shgroup_state_disable(DRWShadingGroup *shgroup, DRWState state);
|
||||
void DRW_shgroup_stencil_mask(DRWShadingGroup *shgroup, uint mask);
|
||||
|
||||
/* Issue a clear command. */
|
||||
void DRW_shgroup_clear_framebuffer(DRWShadingGroup *shgroup,
|
||||
eGPUFrameBufferBits channels,
|
||||
uchar r,
|
||||
uchar g,
|
||||
uchar b,
|
||||
uchar a,
|
||||
float depth,
|
||||
uchar stencil);
|
||||
|
||||
void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup,
|
||||
const char *name,
|
||||
const struct GPUTexture *tex);
|
||||
|
@ -527,17 +525,17 @@ void DRW_shgroup_uniform_mat3(DRWShadingGroup *shgroup, const char *name, const
|
|||
void DRW_shgroup_uniform_mat4(DRWShadingGroup *shgroup, const char *name, const float (*value)[4]);
|
||||
/* Store value instead of referencing it. */
|
||||
void DRW_shgroup_uniform_int_copy(DRWShadingGroup *shgroup, const char *name, const int value);
|
||||
void DRW_shgroup_uniform_ivec2_copy(DRWShadingGroup *shgrp, const char *name, const int *value);
|
||||
void DRW_shgroup_uniform_ivec3_copy(DRWShadingGroup *shgrp, const char *name, const int *value);
|
||||
void DRW_shgroup_uniform_ivec4_copy(DRWShadingGroup *shgrp, const char *name, const int *value);
|
||||
void DRW_shgroup_uniform_bool_copy(DRWShadingGroup *shgroup, const char *name, const bool value);
|
||||
void DRW_shgroup_uniform_float_copy(DRWShadingGroup *shgroup, const char *name, const float value);
|
||||
void DRW_shgroup_uniform_vec2_copy(DRWShadingGroup *shgroup, const char *name, const float *value);
|
||||
void DRW_shgroup_uniform_vec3_copy(DRWShadingGroup *shgroup, const char *name, const float *value);
|
||||
void DRW_shgroup_uniform_vec4_copy(DRWShadingGroup *shgroup, const char *name, const float *value);
|
||||
|
||||
bool DRW_shgroup_is_empty(DRWShadingGroup *shgroup);
|
||||
|
||||
/* TODO: workaround functions waiting for the clearing operation to be available inside the
|
||||
* shgroups. */
|
||||
DRWShadingGroup *DRW_shgroup_get_next(DRWShadingGroup *shgroup);
|
||||
uint DRW_shgroup_stencil_mask_get(DRWShadingGroup *shgroup);
|
||||
|
||||
/* Passes */
|
||||
DRWPass *DRW_pass_create(const char *name, DRWState state);
|
||||
/* TODO Replace with passes inheritance. */
|
||||
|
|
|
@ -215,7 +215,7 @@ static void MPATH_cache_motion_path(MPATH_PassList *psl,
|
|||
DRW_shgroup_uniform_vec3(shgrp, "customColor", mpath->color, 1);
|
||||
}
|
||||
/* Only draw the required range. */
|
||||
DRW_shgroup_call_range(shgrp, mpath_batch_line_get(mpath), start_index, len);
|
||||
DRW_shgroup_call_range(shgrp, mpath_batch_line_get(mpath), NULL, start_index, len);
|
||||
}
|
||||
|
||||
/* Draw points. */
|
||||
|
@ -231,7 +231,7 @@ static void MPATH_cache_motion_path(MPATH_PassList *psl,
|
|||
DRW_shgroup_uniform_vec3(shgrp, "customColor", mpath->color, 1);
|
||||
}
|
||||
/* Only draw the required range. */
|
||||
DRW_shgroup_call_range(shgrp, mpath_batch_points_get(mpath), start_index, len);
|
||||
DRW_shgroup_call_range(shgrp, mpath_batch_points_get(mpath), NULL, start_index, len);
|
||||
|
||||
/* Draw frame numbers at each framestep value */
|
||||
bool show_kf_no = (avs->path_viewflag & MOTIONPATH_VIEW_KFNOS) != 0;
|
||||
|
|
|
@ -1095,7 +1095,7 @@ struct GPUShader *volume_velocity_shader_get(bool use_needle)
|
|||
NULL,
|
||||
datatoc_gpu_shader_flat_color_frag_glsl,
|
||||
datatoc_common_view_lib_glsl,
|
||||
"#define USE_NEEDLE\n");
|
||||
"#define USE_NEEDLE");
|
||||
}
|
||||
return sh_data->volume_velocity_needle_sh;
|
||||
}
|
||||
|
|
|
@ -201,33 +201,30 @@ static DRWShadingGroup *drw_shgroup_create_hair_procedural_ex(Object *object,
|
|||
/* Transform Feedback subdiv. */
|
||||
if (need_ft_update) {
|
||||
int final_points_len = hair_cache->final[subdiv].strands_res * hair_cache->strands_len;
|
||||
if (final_points_len) {
|
||||
GPUShader *tf_shader = hair_refine_shader_get(PART_REFINE_CATMULL_ROM);
|
||||
GPUShader *tf_shader = hair_refine_shader_get(PART_REFINE_CATMULL_ROM);
|
||||
|
||||
#ifdef USE_TRANSFORM_FEEDBACK
|
||||
DRWShadingGroup *tf_shgrp = DRW_shgroup_transform_feedback_create(
|
||||
tf_shader, g_tf_pass, hair_cache->final[subdiv].proc_buf);
|
||||
DRWShadingGroup *tf_shgrp = DRW_shgroup_transform_feedback_create(
|
||||
tf_shader, g_tf_pass, hair_cache->final[subdiv].proc_buf);
|
||||
#else
|
||||
DRWShadingGroup *tf_shgrp = DRW_shgroup_create(tf_shader, g_tf_pass);
|
||||
DRWShadingGroup *tf_shgrp = DRW_shgroup_create(tf_shader, g_tf_pass);
|
||||
|
||||
ParticleRefineCall *pr_call = MEM_mallocN(sizeof(*pr_call), __func__);
|
||||
pr_call->next = g_tf_calls;
|
||||
pr_call->vbo = hair_cache->final[subdiv].proc_buf;
|
||||
pr_call->shgrp = tf_shgrp;
|
||||
pr_call->vert_len = final_points_len;
|
||||
g_tf_calls = pr_call;
|
||||
DRW_shgroup_uniform_int(tf_shgrp, "targetHeight", &g_tf_target_height, 1);
|
||||
DRW_shgroup_uniform_int(tf_shgrp, "targetWidth", &g_tf_target_width, 1);
|
||||
DRW_shgroup_uniform_int(tf_shgrp, "idOffset", &g_tf_id_offset, 1);
|
||||
ParticleRefineCall *pr_call = MEM_mallocN(sizeof(*pr_call), __func__);
|
||||
pr_call->next = g_tf_calls;
|
||||
pr_call->vbo = hair_cache->final[subdiv].proc_buf;
|
||||
pr_call->shgrp = tf_shgrp;
|
||||
pr_call->vert_len = final_points_len;
|
||||
g_tf_calls = pr_call;
|
||||
DRW_shgroup_uniform_int(tf_shgrp, "targetHeight", &g_tf_target_height, 1);
|
||||
DRW_shgroup_uniform_int(tf_shgrp, "targetWidth", &g_tf_target_width, 1);
|
||||
DRW_shgroup_uniform_int(tf_shgrp, "idOffset", &g_tf_id_offset, 1);
|
||||
#endif
|
||||
|
||||
DRW_shgroup_uniform_texture(tf_shgrp, "hairPointBuffer", hair_cache->point_tex);
|
||||
DRW_shgroup_uniform_texture(tf_shgrp, "hairStrandBuffer", hair_cache->strand_tex);
|
||||
DRW_shgroup_uniform_texture(tf_shgrp, "hairStrandSegBuffer", hair_cache->strand_seg_tex);
|
||||
DRW_shgroup_uniform_int(
|
||||
tf_shgrp, "hairStrandsRes", &hair_cache->final[subdiv].strands_res, 1);
|
||||
DRW_shgroup_call_procedural_points(tf_shgrp, NULL, final_points_len);
|
||||
}
|
||||
DRW_shgroup_uniform_texture(tf_shgrp, "hairPointBuffer", hair_cache->point_tex);
|
||||
DRW_shgroup_uniform_texture(tf_shgrp, "hairStrandBuffer", hair_cache->strand_tex);
|
||||
DRW_shgroup_uniform_texture(tf_shgrp, "hairStrandSegBuffer", hair_cache->strand_seg_tex);
|
||||
DRW_shgroup_uniform_int(tf_shgrp, "hairStrandsRes", &hair_cache->final[subdiv].strands_res, 1);
|
||||
DRW_shgroup_call_procedural_points(tf_shgrp, NULL, final_points_len);
|
||||
}
|
||||
|
||||
return shgrp;
|
||||
|
|
|
@ -64,7 +64,7 @@ typedef struct DRWTempBufferHandle {
|
|||
/** Format pointer for reuse. */
|
||||
GPUVertFormat *format;
|
||||
/** Touched vertex length for resize. */
|
||||
int *vert_len;
|
||||
uint *vert_len;
|
||||
} DRWTempBufferHandle;
|
||||
|
||||
static ListBase g_idatalists = {NULL, NULL};
|
||||
|
@ -112,7 +112,7 @@ static void instance_batch_free(GPUBatch *geom, void *UNUSED(user_data))
|
|||
*/
|
||||
GPUVertBuf *DRW_temp_buffer_request(DRWInstanceDataList *idatalist,
|
||||
GPUVertFormat *format,
|
||||
int *vert_len)
|
||||
uint *vert_len)
|
||||
{
|
||||
BLI_assert(format != NULL);
|
||||
BLI_assert(vert_len != NULL);
|
||||
|
|
|
@ -40,7 +40,7 @@ DRWInstanceData *DRW_instance_data_request(DRWInstanceDataList *idatalist, uint
|
|||
|
||||
GPUVertBuf *DRW_temp_buffer_request(DRWInstanceDataList *idatalist,
|
||||
GPUVertFormat *format,
|
||||
int *vert_len);
|
||||
uint *vert_len);
|
||||
GPUBatch *DRW_temp_batch_instance_request(DRWInstanceDataList *idatalist,
|
||||
GPUVertBuf *buf,
|
||||
GPUBatch *geom);
|
||||
|
|
|
@ -537,11 +537,8 @@ static void drw_viewport_cache_resize(void)
|
|||
GPU_texture_free(*tex);
|
||||
}
|
||||
|
||||
BLI_memblock_clear(DST.vmempool->commands, NULL);
|
||||
BLI_memblock_clear(DST.vmempool->commands_small, NULL);
|
||||
BLI_memblock_clear(DST.vmempool->callbuffers, NULL);
|
||||
BLI_memblock_clear(DST.vmempool->obmats, NULL);
|
||||
BLI_memblock_clear(DST.vmempool->obinfos, NULL);
|
||||
BLI_memblock_clear(DST.vmempool->calls, NULL);
|
||||
BLI_memblock_clear(DST.vmempool->states, NULL);
|
||||
BLI_memblock_clear(DST.vmempool->cullstates, NULL);
|
||||
BLI_memblock_clear(DST.vmempool->shgroups, NULL);
|
||||
BLI_memblock_clear(DST.vmempool->uniforms, NULL);
|
||||
|
@ -589,28 +586,28 @@ static void drw_context_state_init(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void draw_unit_state_create(void)
|
||||
static DRWCallState *draw_unit_state_create(void)
|
||||
{
|
||||
DRWObjectInfos *infos = BLI_memblock_alloc(DST.vmempool->obinfos);
|
||||
DRWObjectMatrix *mats = BLI_memblock_alloc(DST.vmempool->obmats);
|
||||
DRWCullingState *culling = BLI_memblock_alloc(DST.vmempool->cullstates);
|
||||
DRWCallState *state = BLI_memblock_alloc(DST.vmempool->states);
|
||||
state->flag = 0;
|
||||
state->matflag = 0;
|
||||
|
||||
unit_m4(mats->model);
|
||||
unit_m4(mats->modelinverse);
|
||||
unit_m4(state->model);
|
||||
unit_m4(state->modelinverse);
|
||||
|
||||
copy_v3_fl(infos->orcotexfac[0], 0.0f);
|
||||
copy_v3_fl(infos->orcotexfac[1], 1.0f);
|
||||
copy_v3_fl(state->orcotexfac[0], 0.0f);
|
||||
copy_v3_fl(state->orcotexfac[1], 1.0f);
|
||||
|
||||
infos->ob_index = 0;
|
||||
infos->ob_random = 0.0f;
|
||||
infos->ob_neg_scale = 1.0f;
|
||||
copy_v3_fl(infos->ob_color, 1.0f);
|
||||
state->ob_index = 0;
|
||||
state->ob_random = 0.0f;
|
||||
copy_v3_fl(state->ob_color, 1.0f);
|
||||
|
||||
/* TODO(fclem) get rid of this. */
|
||||
culling->bsphere.radius = -1.0f;
|
||||
culling->user_data = NULL;
|
||||
state->culling = BLI_memblock_alloc(DST.vmempool->cullstates);
|
||||
state->culling->bsphere.radius = -1.0f;
|
||||
state->culling->user_data = NULL;
|
||||
|
||||
DRW_handle_increment(&DST.resource_handle);
|
||||
return state;
|
||||
}
|
||||
|
||||
/* It also stores viewport variable to an immutable place: DST
|
||||
|
@ -635,48 +632,33 @@ static void drw_viewport_var_init(void)
|
|||
|
||||
DST.vmempool = GPU_viewport_mempool_get(DST.viewport);
|
||||
|
||||
if (DST.vmempool->commands == NULL) {
|
||||
DST.vmempool->commands = BLI_memblock_create(sizeof(DRWCommandChunk));
|
||||
if (DST.vmempool->calls == NULL) {
|
||||
DST.vmempool->calls = BLI_memblock_create(sizeof(DRWCall));
|
||||
}
|
||||
if (DST.vmempool->commands_small == NULL) {
|
||||
DST.vmempool->commands_small = BLI_memblock_create(sizeof(DRWCommandSmallChunk));
|
||||
}
|
||||
if (DST.vmempool->callbuffers == NULL) {
|
||||
DST.vmempool->callbuffers = BLI_memblock_create(sizeof(DRWCallBuffer));
|
||||
}
|
||||
if (DST.vmempool->obmats == NULL) {
|
||||
uint chunk_len = sizeof(DRWObjectMatrix) * DRW_RESOURCE_CHUNK_LEN;
|
||||
DST.vmempool->obmats = BLI_memblock_create_ex(sizeof(DRWObjectMatrix), chunk_len);
|
||||
}
|
||||
if (DST.vmempool->obinfos == NULL) {
|
||||
uint chunk_len = sizeof(DRWObjectInfos) * DRW_RESOURCE_CHUNK_LEN;
|
||||
DST.vmempool->obinfos = BLI_memblock_create_ex(sizeof(DRWObjectInfos), chunk_len);
|
||||
if (DST.vmempool->states == NULL) {
|
||||
DST.vmempool->states = BLI_memblock_create(sizeof(DRWCallState));
|
||||
}
|
||||
if (DST.vmempool->cullstates == NULL) {
|
||||
uint chunk_len = sizeof(DRWCullingState) * DRW_RESOURCE_CHUNK_LEN;
|
||||
DST.vmempool->cullstates = BLI_memblock_create_ex(sizeof(DRWCullingState), chunk_len);
|
||||
DST.vmempool->cullstates = BLI_memblock_create(sizeof(DRWCullingState));
|
||||
}
|
||||
if (DST.vmempool->shgroups == NULL) {
|
||||
DST.vmempool->shgroups = BLI_memblock_create(sizeof(DRWShadingGroup));
|
||||
}
|
||||
if (DST.vmempool->uniforms == NULL) {
|
||||
DST.vmempool->uniforms = BLI_memblock_create(sizeof(DRWUniformChunk));
|
||||
DST.vmempool->uniforms = BLI_memblock_create(sizeof(DRWUniform));
|
||||
}
|
||||
if (DST.vmempool->views == NULL) {
|
||||
DST.vmempool->views = BLI_memblock_create(sizeof(DRWView));
|
||||
}
|
||||
if (DST.vmempool->passes == NULL) {
|
||||
uint chunk_len = sizeof(DRWPass) * DRW_RESOURCE_CHUNK_LEN;
|
||||
DST.vmempool->passes = BLI_memblock_create_ex(sizeof(DRWPass), chunk_len);
|
||||
DST.vmempool->passes = BLI_memblock_create(sizeof(DRWPass));
|
||||
}
|
||||
if (DST.vmempool->images == NULL) {
|
||||
DST.vmempool->images = BLI_memblock_create(sizeof(GPUTexture *));
|
||||
}
|
||||
|
||||
DST.resource_handle = 0;
|
||||
DST.pass_handle = 0;
|
||||
|
||||
draw_unit_state_create();
|
||||
/* Alloc default unit state */
|
||||
DST.unit_state = draw_unit_state_create();
|
||||
|
||||
DST.idatalist = GPU_viewport_instance_data_list_get(DST.viewport);
|
||||
DRW_instance_data_list_reset(DST.idatalist);
|
||||
|
@ -690,6 +672,8 @@ static void drw_viewport_var_init(void)
|
|||
|
||||
DST.default_framebuffer = NULL;
|
||||
DST.vmempool = NULL;
|
||||
|
||||
DST.unit_state = NULL;
|
||||
}
|
||||
|
||||
DST.primary_view_ct = 0;
|
||||
|
@ -732,10 +716,6 @@ static void drw_viewport_var_init(void)
|
|||
G_draw.view_ubo = DRW_uniformbuffer_create(sizeof(DRWViewUboStorage), NULL);
|
||||
}
|
||||
|
||||
if (DST.draw_list == NULL) {
|
||||
DST.draw_list = GPU_draw_list_create(DRW_DRAWLIST_LEN);
|
||||
}
|
||||
|
||||
memset(DST.object_instance_data, 0x0, sizeof(DST.object_instance_data));
|
||||
}
|
||||
|
||||
|
@ -1119,7 +1099,7 @@ static void drw_engines_world_update(Scene *scene)
|
|||
|
||||
static void drw_engines_cache_populate(Object *ob)
|
||||
{
|
||||
DST.ob_handle = 0;
|
||||
DST.ob_state = NULL;
|
||||
|
||||
/* HACK: DrawData is copied by COW from the duplicated object.
|
||||
* This is valid for IDs that cannot be instantiated but this
|
||||
|
@ -1937,8 +1917,6 @@ void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph
|
|||
RenderResult *render_result = RE_engine_get_result(engine);
|
||||
RenderLayer *render_layer = RE_GetRenderLayer(render_result, view_layer->name);
|
||||
|
||||
DST.buffer_finish_called = false;
|
||||
|
||||
DRW_render_gpencil_to_image(engine, render_layer, &render_rect);
|
||||
|
||||
/* Force cache to reset. */
|
||||
|
@ -2049,15 +2027,13 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
|
|||
RE_SetActiveRenderView(render, render_view->name);
|
||||
drw_view_reset();
|
||||
engine_type->draw_engine->render_to_image(data, engine, render_layer, &render_rect);
|
||||
DST.buffer_finish_called = false;
|
||||
|
||||
/* grease pencil: render result is merged in the previous render result. */
|
||||
if (DRW_render_check_grease_pencil(depsgraph)) {
|
||||
DRW_state_reset();
|
||||
drw_view_reset();
|
||||
DRW_render_gpencil_to_image(engine, render_layer, &render_rect);
|
||||
DST.buffer_finish_called = false;
|
||||
}
|
||||
DST.buffer_finish_called = false;
|
||||
}
|
||||
|
||||
RE_engine_end_result(engine, render_result, false, false, false);
|
||||
|
@ -2103,7 +2079,7 @@ void DRW_render_object_iter(
|
|||
if ((object_type_exclude_viewport & (1 << ob->type)) == 0) {
|
||||
DST.dupli_parent = data_.dupli_parent;
|
||||
DST.dupli_source = data_.dupli_object_current;
|
||||
DST.ob_handle = 0;
|
||||
DST.ob_state = NULL;
|
||||
drw_duplidata_load(DST.dupli_source);
|
||||
|
||||
if (!DST.dupli_source) {
|
||||
|
@ -2210,7 +2186,6 @@ void DRW_render_instance_buffer_finish(void)
|
|||
BLI_assert(!DST.buffer_finish_called && "DRW_render_instance_buffer_finish called twice!");
|
||||
DST.buffer_finish_called = true;
|
||||
DRW_instance_buffer_finish(DST.idatalist);
|
||||
drw_resource_buffer_finish(DST.vmempool);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2234,7 +2209,7 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
|
|||
Object *obact = OBACT(view_layer);
|
||||
Object *obedit = OBEDIT_FROM_OBACT(obact);
|
||||
#ifndef USE_GPU_SELECT
|
||||
UNUSED_VARS(scene, view_layer, v3d, ar, rect);
|
||||
UNUSED_VARS(vc, scene, view_layer, v3d, ar, rect);
|
||||
#else
|
||||
RegionView3D *rv3d = ar->regiondata;
|
||||
|
||||
|
@ -2959,10 +2934,6 @@ void DRW_engines_free(void)
|
|||
|
||||
MEM_SAFE_FREE(DST.uniform_names.buffer);
|
||||
|
||||
if (DST.draw_list) {
|
||||
GPU_draw_list_discard(DST.draw_list);
|
||||
}
|
||||
|
||||
DRW_opengl_context_disable();
|
||||
}
|
||||
|
||||
|
|
|
@ -28,10 +28,8 @@
|
|||
#include "DRW_engine.h"
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "BLI_assert.h"
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_threads.h"
|
||||
#include "BLI_memblock.h"
|
||||
|
||||
#include "GPU_batch.h"
|
||||
#include "GPU_context.h"
|
||||
|
@ -45,9 +43,6 @@
|
|||
/* Use draw manager to call GPU_select, see: DRW_draw_select_loop */
|
||||
#define USE_GPU_SELECT
|
||||
|
||||
/* Use drawcall batching using instanced rendering. */
|
||||
#define USE_BATCHING 1
|
||||
|
||||
// #define DRW_DEBUG_CULLING
|
||||
#define DRW_DEBUG_USE_UNIFORM_NAME 0
|
||||
#define DRW_UNIFORM_BUFFER_NAME 64
|
||||
|
@ -95,6 +90,20 @@
|
|||
* > DRWUniform
|
||||
*/
|
||||
|
||||
/* Used by DRWCallState.flag */
|
||||
enum {
|
||||
DRW_CALL_NEGSCALE = (1 << 1),
|
||||
};
|
||||
|
||||
/* Used by DRWCallState.matflag */
|
||||
enum {
|
||||
DRW_CALL_MODELINVERSE = (1 << 0),
|
||||
DRW_CALL_MODELVIEWPROJECTION = (1 << 1),
|
||||
DRW_CALL_ORCOTEXFAC = (1 << 2),
|
||||
DRW_CALL_OBJECTINFO = (1 << 3),
|
||||
DRW_CALL_OBJECTCOLOR = (1 << 4),
|
||||
};
|
||||
|
||||
typedef struct DRWCullingState {
|
||||
uint32_t mask;
|
||||
/* Culling: Using Bounding Sphere for now for faster culling.
|
||||
|
@ -104,161 +113,38 @@ typedef struct DRWCullingState {
|
|||
void *user_data;
|
||||
} DRWCullingState;
|
||||
|
||||
/* Minimum max UBO size is 64KiB. We take the largest
|
||||
* UBO struct and alloc the max number.
|
||||
* ((1 << 16) / sizeof(DRWObjectMatrix)) = 512
|
||||
* Keep in sync with common_view_lib.glsl */
|
||||
#define DRW_RESOURCE_CHUNK_LEN 512
|
||||
|
||||
/**
|
||||
* Identifier used to sort similar drawcalls together.
|
||||
* Also used to reference elements inside memory blocks.
|
||||
*
|
||||
* From MSB to LSB
|
||||
* 1 bit for negative scale.
|
||||
* 22 bits for chunk id.
|
||||
* 9 bits for resource id inside the chunk. (can go up to 511)
|
||||
* |-|----------------------|---------|
|
||||
*
|
||||
* Use manual bitsift and mask instead of bitfields to avoid
|
||||
* compiler dependant behavior that would mess the ordering of
|
||||
* the members thus changing the sorting order.
|
||||
*/
|
||||
typedef uint32_t DRWResourceHandle;
|
||||
|
||||
BLI_INLINE uint32_t DRW_handle_negative_scale_get(const DRWResourceHandle *handle)
|
||||
{
|
||||
return (*handle & 0x80000000) != 0;
|
||||
}
|
||||
|
||||
BLI_INLINE uint32_t DRW_handle_chunk_get(const DRWResourceHandle *handle)
|
||||
{
|
||||
return (*handle & 0x7FFFFFFF) >> 9;
|
||||
}
|
||||
|
||||
BLI_INLINE uint32_t DRW_handle_id_get(const DRWResourceHandle *handle)
|
||||
{
|
||||
return (*handle & 0x000001FF);
|
||||
}
|
||||
|
||||
BLI_INLINE void DRW_handle_increment(DRWResourceHandle *handle)
|
||||
{
|
||||
*handle += 1;
|
||||
}
|
||||
|
||||
BLI_INLINE void DRW_handle_negative_scale_enable(DRWResourceHandle *handle)
|
||||
{
|
||||
*handle |= 0x80000000;
|
||||
}
|
||||
|
||||
BLI_INLINE void *DRW_memblock_elem_from_handle(struct BLI_memblock *memblock,
|
||||
const DRWResourceHandle *handle)
|
||||
{
|
||||
int elem = DRW_handle_id_get(handle);
|
||||
int chunk = DRW_handle_chunk_get(handle);
|
||||
return BLI_memblock_elem_get(memblock, chunk, elem);
|
||||
}
|
||||
|
||||
typedef struct DRWObjectMatrix {
|
||||
typedef struct DRWCallState {
|
||||
DRWCullingState *culling;
|
||||
uchar flag;
|
||||
uchar matflag; /* Which matrices to compute. */
|
||||
short ob_index;
|
||||
/* Matrices */
|
||||
float model[4][4];
|
||||
float modelinverse[4][4];
|
||||
} DRWObjectMatrix;
|
||||
|
||||
typedef struct DRWObjectInfos {
|
||||
float orcotexfac[2][4];
|
||||
float ob_color[4];
|
||||
float ob_index;
|
||||
float pad; /* UNUSED*/
|
||||
float orcotexfac[2][3];
|
||||
float ob_random;
|
||||
float ob_neg_scale;
|
||||
} DRWObjectInfos;
|
||||
float ob_color[4];
|
||||
} DRWCallState;
|
||||
|
||||
BLI_STATIC_ASSERT_ALIGN(DRWObjectMatrix, 16)
|
||||
BLI_STATIC_ASSERT_ALIGN(DRWObjectInfos, 16)
|
||||
typedef struct DRWCall {
|
||||
struct DRWCall *next;
|
||||
DRWCallState *state;
|
||||
|
||||
typedef enum {
|
||||
/* Draw Commands */
|
||||
DRW_CMD_DRAW = 0, /* Only sortable type. Must be 0. */
|
||||
DRW_CMD_DRAW_RANGE = 1,
|
||||
DRW_CMD_DRAW_INSTANCE = 2,
|
||||
DRW_CMD_DRAW_PROCEDURAL = 3,
|
||||
/* Other Commands */
|
||||
DRW_CMD_CLEAR = 12,
|
||||
DRW_CMD_DRWSTATE = 13,
|
||||
DRW_CMD_STENCIL = 14,
|
||||
DRW_CMD_SELECTID = 15,
|
||||
/* Needs to fit in 4bits */
|
||||
} eDRWCommandType;
|
||||
|
||||
#define DRW_MAX_DRAW_CMD_TYPE DRW_CMD_DRAW_PROCEDURAL
|
||||
|
||||
typedef struct DRWCommandDraw {
|
||||
GPUBatch *batch;
|
||||
DRWResourceHandle handle;
|
||||
} DRWCommandDraw;
|
||||
|
||||
/* Assume DRWResourceHandle to be 0. */
|
||||
typedef struct DRWCommandDrawRange {
|
||||
GPUBatch *batch;
|
||||
uint vert_first;
|
||||
uint vert_count;
|
||||
} DRWCommandDrawRange;
|
||||
|
||||
typedef struct DRWCommandDrawInstance {
|
||||
GPUBatch *batch;
|
||||
DRWResourceHandle handle;
|
||||
uint inst_count;
|
||||
} DRWCommandDrawInstance;
|
||||
|
||||
typedef struct DRWCommandDrawProcedural {
|
||||
GPUBatch *batch;
|
||||
DRWResourceHandle handle;
|
||||
uint vert_count;
|
||||
} DRWCommandDrawProcedural;
|
||||
|
||||
typedef struct DRWCommandSetMutableState {
|
||||
/** State changes (or'd or and'd with the pass's state) */
|
||||
DRWState enable;
|
||||
DRWState disable;
|
||||
} DRWCommandSetMutableState;
|
||||
|
||||
typedef struct DRWCommandSetStencil {
|
||||
uint mask;
|
||||
} DRWCommandSetStencil;
|
||||
|
||||
typedef struct DRWCommandSetSelectID {
|
||||
GPUVertBuf *select_buf;
|
||||
uint select_id;
|
||||
} DRWCommandSetSelectID;
|
||||
|
||||
typedef struct DRWCommandClear {
|
||||
eGPUFrameBufferBits clear_channels;
|
||||
uchar r, g, b, a; /* [0..1] for each channels. Normalized. */
|
||||
float depth; /* [0..1] for depth. Normalized. */
|
||||
uchar stencil; /* Stencil value [0..255] */
|
||||
} DRWCommandClear;
|
||||
|
||||
typedef union DRWCommand {
|
||||
DRWCommandDraw draw;
|
||||
DRWCommandDrawRange range;
|
||||
DRWCommandDrawInstance instance;
|
||||
DRWCommandDrawProcedural procedural;
|
||||
DRWCommandSetMutableState state;
|
||||
DRWCommandSetStencil stencil;
|
||||
DRWCommandSetSelectID select_id;
|
||||
DRWCommandClear clear;
|
||||
} DRWCommand;
|
||||
|
||||
/* Used for agregating calls into GPUVertBufs. */
|
||||
struct DRWCallBuffer {
|
||||
GPUVertBuf *buf;
|
||||
GPUVertBuf *buf_select;
|
||||
int count;
|
||||
};
|
||||
#ifdef USE_GPU_SELECT
|
||||
/* TODO(fclem) remove once we have a dedicated selection engine. */
|
||||
int select_id;
|
||||
GPUVertBuf *inst_selectid;
|
||||
#endif
|
||||
} DRWCall;
|
||||
|
||||
/* Used by DRWUniform.type */
|
||||
typedef enum {
|
||||
DRW_UNIFORM_INT = 0,
|
||||
DRW_UNIFORM_INT,
|
||||
DRW_UNIFORM_INT_COPY,
|
||||
DRW_UNIFORM_FLOAT,
|
||||
DRW_UNIFORM_FLOAT_COPY,
|
||||
|
@ -267,56 +153,55 @@ typedef enum {
|
|||
DRW_UNIFORM_TEXTURE_REF,
|
||||
DRW_UNIFORM_BLOCK,
|
||||
DRW_UNIFORM_BLOCK_PERSIST,
|
||||
DRW_UNIFORM_TFEEDBACK_TARGET,
|
||||
/** Per drawcall uniforms/UBO */
|
||||
DRW_UNIFORM_BLOCK_OBMATS,
|
||||
DRW_UNIFORM_BLOCK_OBINFOS,
|
||||
DRW_UNIFORM_RESOURCE_CHUNK,
|
||||
/** Legacy / Fallback */
|
||||
DRW_UNIFORM_BASE_INSTANCE,
|
||||
DRW_UNIFORM_MODEL_MATRIX,
|
||||
DRW_UNIFORM_MODEL_MATRIX_INVERSE,
|
||||
DRW_UNIFORM_MODELVIEWPROJECTION_MATRIX,
|
||||
/* WARNING: set DRWUniform->type
|
||||
* bit length accordingly. */
|
||||
} DRWUniformType;
|
||||
|
||||
struct DRWUniform {
|
||||
DRWUniform *next; /* single-linked list */
|
||||
union {
|
||||
/* For reference or array/vector types. */
|
||||
const void *pvalue;
|
||||
/* Single values. */
|
||||
float fvalue[4];
|
||||
int ivalue[4];
|
||||
float fvalue[2];
|
||||
int ivalue[2];
|
||||
};
|
||||
int name_ofs; /* name offset in name buffer. */
|
||||
int location;
|
||||
uint32_t type : 5; /* DRWUniformType */
|
||||
uint32_t length : 5; /* cannot be more than 16 */
|
||||
uint32_t arraysize : 5; /* cannot be more than 16 too */
|
||||
uint32_t name_ofs : 17; /* name offset in name buffer. */
|
||||
char type; /* DRWUniformType */
|
||||
char length; /* cannot be more than 16 */
|
||||
char arraysize; /* cannot be more than 16 too */
|
||||
};
|
||||
|
||||
struct DRWShadingGroup {
|
||||
DRWShadingGroup *next;
|
||||
|
||||
GPUShader *shader; /* Shader to bind */
|
||||
struct DRWUniformChunk *uniforms; /* Uniforms pointers */
|
||||
GPUShader *shader; /* Shader to bind */
|
||||
DRWUniform *uniforms; /* Uniforms pointers */
|
||||
|
||||
struct {
|
||||
/* Chunks of draw calls. */
|
||||
struct DRWCommandChunk *first, *last;
|
||||
} cmd;
|
||||
DRWCall *first, *last; /* Linked list of DRWCall */
|
||||
} calls;
|
||||
|
||||
union {
|
||||
struct {
|
||||
int objectinfo; /* Equal to 1 if the shader needs obinfos. */
|
||||
DRWResourceHandle pass_handle; /* Memblock key to parent pass. */
|
||||
};
|
||||
struct {
|
||||
float distance; /* Distance from camera. */
|
||||
uint original_index; /* Original position inside the shgroup list. */
|
||||
} z_sorting;
|
||||
};
|
||||
/** TODO Maybe remove from here */
|
||||
struct GPUVertBuf *tfeedback_target;
|
||||
|
||||
/** State changes for this batch only (or'd with the pass's state) */
|
||||
DRWState state_extra;
|
||||
/** State changes for this batch only (and'd with the pass's state) */
|
||||
DRWState state_extra_disable;
|
||||
/** Stencil mask to use for stencil test / write operations */
|
||||
uint stencil_mask;
|
||||
|
||||
/* Builtin matrices locations */
|
||||
int model;
|
||||
int modelinverse;
|
||||
int modelviewprojection;
|
||||
int orcotexfac;
|
||||
int callid;
|
||||
int objectinfo;
|
||||
int objectcolor;
|
||||
uchar matflag; /* Matrices needed, same as DRWCall.flag */
|
||||
|
||||
DRWPass *pass_parent; /* backlink to pass we're in */
|
||||
};
|
||||
|
||||
#define MAX_PASS_NAME 32
|
||||
|
@ -328,7 +213,6 @@ struct DRWPass {
|
|||
DRWShadingGroup *last;
|
||||
} shgroups;
|
||||
|
||||
DRWResourceHandle handle;
|
||||
DRWState state;
|
||||
char name[MAX_PASS_NAME];
|
||||
};
|
||||
|
@ -348,8 +232,6 @@ typedef struct DRWViewUboStorage {
|
|||
float viewcamtexcofac[4];
|
||||
} DRWViewUboStorage;
|
||||
|
||||
BLI_STATIC_ASSERT_ALIGN(DRWViewUboStorage, 16)
|
||||
|
||||
#define MAX_CULLED_VIEWS 32
|
||||
|
||||
struct DRWView {
|
||||
|
@ -371,45 +253,13 @@ struct DRWView {
|
|||
void *user_data;
|
||||
};
|
||||
|
||||
/* ------------ Data Chunks --------------- */
|
||||
/**
|
||||
* In order to keep a cache friendly data structure,
|
||||
* we alloc most of our little data into chunks of multiple item.
|
||||
* Iteration, allocation and memory usage are better.
|
||||
* We loose a bit of memory by allocating more than what we need
|
||||
* but it's counterbalanced by not needing the linked-list pointers
|
||||
* for each item.
|
||||
**/
|
||||
|
||||
typedef struct DRWUniformChunk {
|
||||
struct DRWUniformChunk *next; /* single-linked list */
|
||||
uint32_t uniform_len;
|
||||
uint32_t uniform_used;
|
||||
DRWUniform uniforms[10];
|
||||
} DRWUniformChunk;
|
||||
|
||||
typedef struct DRWCommandChunk {
|
||||
struct DRWCommandChunk *next;
|
||||
uint32_t command_len;
|
||||
uint32_t command_used;
|
||||
/* 4bits for each command. */
|
||||
uint64_t command_type[6];
|
||||
/* -- 64 bytes aligned -- */
|
||||
DRWCommand commands[96];
|
||||
/* -- 64 bytes aligned -- */
|
||||
} DRWCommandChunk;
|
||||
|
||||
typedef struct DRWCommandSmallChunk {
|
||||
struct DRWCommandChunk *next;
|
||||
uint32_t command_len;
|
||||
uint32_t command_used;
|
||||
/* 4bits for each command. */
|
||||
/* TODO reduce size of command_type. */
|
||||
uint64_t command_type[6];
|
||||
DRWCommand commands[6];
|
||||
} DRWCommandSmallChunk;
|
||||
|
||||
BLI_STATIC_ASSERT_ALIGN(DRWCommandChunk, 16);
|
||||
/* TODO(fclem): Future awaits */
|
||||
#if 0
|
||||
typedef struct ModelUboStorage {
|
||||
float model[4][4];
|
||||
float modelinverse[4][4];
|
||||
} ModelUboStorage;
|
||||
#endif
|
||||
|
||||
/* ------------- DRAW DEBUG ------------ */
|
||||
|
||||
|
@ -430,31 +280,21 @@ typedef struct DRWDebugSphere {
|
|||
#define DST_MAX_SLOTS 64 /* Cannot be changed without modifying RST.bound_tex_slots */
|
||||
#define MAX_CLIP_PLANES 6 /* GL_MAX_CLIP_PLANES is at least 6 */
|
||||
#define STENCIL_UNDEFINED 256
|
||||
#define DRW_DRAWLIST_LEN 256
|
||||
typedef struct DRWManager {
|
||||
/* TODO clean up this struct a bit */
|
||||
/* Cache generation */
|
||||
ViewportMemoryPool *vmempool;
|
||||
DRWInstanceDataList *idatalist;
|
||||
DRWInstanceData *object_instance_data[MAX_INSTANCE_DATA_SIZE];
|
||||
/* Default Unit model matrix state without culling. */
|
||||
DRWCallState *unit_state;
|
||||
/* State of the object being evaluated if already allocated. */
|
||||
DRWResourceHandle ob_handle;
|
||||
/** True if current DST.ob_state has its matching DRWObjectInfos init. */
|
||||
bool ob_state_obinfo_init;
|
||||
/** Handle of current object resource in object resource arrays (DRWObjectMatrices/Infos). */
|
||||
DRWResourceHandle resource_handle;
|
||||
/** Handle of next DRWPass to be allocated. */
|
||||
DRWResourceHandle pass_handle;
|
||||
|
||||
/** Dupli state. NULL if not dupli. */
|
||||
DRWCallState *ob_state;
|
||||
struct DupliObject *dupli_source;
|
||||
struct Object *dupli_parent;
|
||||
struct Object *dupli_origin;
|
||||
/** Ghash containing original objects. */
|
||||
struct GHash *dupli_ghash;
|
||||
/** TODO(fclem) try to remove usage of this. */
|
||||
DRWInstanceData *object_instance_data[MAX_INSTANCE_DATA_SIZE];
|
||||
/* Array of dupli_data (one for each enabled engine) to handle duplis. */
|
||||
void **dupli_datas;
|
||||
void **dupli_datas; /* Array of dupli_data (one for each enabled engine) to handle duplis. */
|
||||
|
||||
/* Rendering state */
|
||||
GPUShader *shader;
|
||||
|
@ -517,8 +357,6 @@ typedef struct DRWManager {
|
|||
/** Mutex to lock the drw manager and avoid concurrent context usage. */
|
||||
TicketMutex *gl_context_mutex;
|
||||
|
||||
GPUDrawList *draw_list;
|
||||
|
||||
/** GPU Resource State: Memory storage between drawing. */
|
||||
struct {
|
||||
/* High end GPUs supports up to 32 binds per shader stage.
|
||||
|
@ -559,13 +397,9 @@ void drw_state_set(DRWState state);
|
|||
void drw_debug_draw(void);
|
||||
void drw_debug_init(void);
|
||||
|
||||
eDRWCommandType command_type_get(uint64_t *command_type_bits, int index);
|
||||
|
||||
void drw_batch_cache_validate(Object *ob);
|
||||
void drw_batch_cache_generate_requested(struct Object *ob);
|
||||
|
||||
void drw_resource_buffer_finish(ViewportMemoryPool *vmempool);
|
||||
|
||||
/* Procedural Drawing */
|
||||
GPUBatch *drw_cache_procedural_points_get(void);
|
||||
GPUBatch *drw_cache_procedural_lines_get(void);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -36,41 +36,16 @@
|
|||
# include "GPU_select.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_GPU_SELECT
|
||||
void DRW_select_load_id(uint id)
|
||||
{
|
||||
#ifdef USE_GPU_SELECT
|
||||
BLI_assert(G.f & G_FLAG_PICKSEL);
|
||||
DST.select_id = id;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#define DEBUG_UBO_BINDING
|
||||
|
||||
typedef struct DRWCommandsState {
|
||||
GPUBatch *batch;
|
||||
int resource_chunk;
|
||||
int base_inst;
|
||||
int inst_count;
|
||||
int v_first;
|
||||
int v_count;
|
||||
bool neg_scale;
|
||||
/* Resource location. */
|
||||
int obmats_loc;
|
||||
int obinfos_loc;
|
||||
int baseinst_loc;
|
||||
int chunkid_loc;
|
||||
/* Legacy matrix support. */
|
||||
int obmat_loc;
|
||||
int obinv_loc;
|
||||
int mvp_loc;
|
||||
/* Selection ID state. */
|
||||
GPUVertBuf *select_buf;
|
||||
uint select_id;
|
||||
/* Drawing State */
|
||||
DRWState drw_state_enabled;
|
||||
DRWState drw_state_disabled;
|
||||
} DRWCommandsState;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Draw State (DRW_state)
|
||||
* \{ */
|
||||
|
@ -432,10 +407,9 @@ void DRW_state_reset(void)
|
|||
/** \name Culling (DRW_culling)
|
||||
* \{ */
|
||||
|
||||
static bool draw_call_is_culled(const DRWResourceHandle *handle, DRWView *view)
|
||||
static bool draw_call_is_culled(DRWCall *call, DRWView *view)
|
||||
{
|
||||
DRWCullingState *culling = DRW_memblock_elem_from_handle(DST.vmempool->cullstates, handle);
|
||||
return (culling->mask & view->culling_mask) != 0;
|
||||
return (call->state->culling->mask & view->culling_mask) != 0;
|
||||
}
|
||||
|
||||
/* Set active view for rendering. */
|
||||
|
@ -614,96 +588,66 @@ static void draw_compute_culling(DRWView *view)
|
|||
/** \name Draw (DRW_draw)
|
||||
* \{ */
|
||||
|
||||
BLI_INLINE void draw_legacy_matrix_update(DRWShadingGroup *shgroup,
|
||||
DRWResourceHandle *handle,
|
||||
float obmat_loc,
|
||||
float obinv_loc,
|
||||
float mvp_loc)
|
||||
static void draw_geometry_prepare(DRWShadingGroup *shgroup, DRWCall *call)
|
||||
{
|
||||
/* Still supported for compatibility with gpu_shader_* but should be forbidden. */
|
||||
DRWObjectMatrix *ob_mats = DRW_memblock_elem_from_handle(DST.vmempool->obmats, handle);
|
||||
if (obmat_loc != -1) {
|
||||
GPU_shader_uniform_vector(shgroup->shader, obmat_loc, 16, 1, (float *)ob_mats->model);
|
||||
BLI_assert(call);
|
||||
DRWCallState *state = call->state;
|
||||
|
||||
if (shgroup->model != -1) {
|
||||
GPU_shader_uniform_vector(shgroup->shader, shgroup->model, 16, 1, (float *)state->model);
|
||||
}
|
||||
if (obinv_loc != -1) {
|
||||
GPU_shader_uniform_vector(shgroup->shader, obinv_loc, 16, 1, (float *)ob_mats->modelinverse);
|
||||
if (shgroup->modelinverse != -1) {
|
||||
GPU_shader_uniform_vector(
|
||||
shgroup->shader, shgroup->modelinverse, 16, 1, (float *)state->modelinverse);
|
||||
}
|
||||
if (shgroup->objectinfo != -1) {
|
||||
float infos[4];
|
||||
infos[0] = state->ob_index;
|
||||
// infos[1]; /* UNUSED. */
|
||||
infos[2] = state->ob_random;
|
||||
infos[3] = (state->flag & DRW_CALL_NEGSCALE) ? -1.0f : 1.0f;
|
||||
GPU_shader_uniform_vector(shgroup->shader, shgroup->objectinfo, 4, 1, (float *)infos);
|
||||
}
|
||||
if (shgroup->objectcolor != -1) {
|
||||
GPU_shader_uniform_vector(
|
||||
shgroup->shader, shgroup->objectcolor, 4, 1, (float *)state->ob_color);
|
||||
}
|
||||
if (shgroup->orcotexfac != -1) {
|
||||
GPU_shader_uniform_vector(
|
||||
shgroup->shader, shgroup->orcotexfac, 3, 2, (float *)state->orcotexfac);
|
||||
}
|
||||
/* Still supported for compatibility with gpu_shader_* but should be forbidden
|
||||
* and is slow (since it does not cache the result). */
|
||||
if (mvp_loc != -1) {
|
||||
if (shgroup->modelviewprojection != -1) {
|
||||
float mvp[4][4];
|
||||
mul_m4_m4m4(mvp, DST.view_active->storage.persmat, ob_mats->model);
|
||||
GPU_shader_uniform_vector(shgroup->shader, mvp_loc, 16, 1, (float *)mvp);
|
||||
mul_m4_m4m4(mvp, DST.view_active->storage.persmat, state->model);
|
||||
GPU_shader_uniform_vector(shgroup->shader, shgroup->modelviewprojection, 16, 1, (float *)mvp);
|
||||
}
|
||||
}
|
||||
|
||||
BLI_INLINE void draw_geometry_bind(DRWShadingGroup *shgroup, GPUBatch *geom)
|
||||
{
|
||||
/* XXX hacking #GPUBatch. we don't want to call glUseProgram! (huge performance loss) */
|
||||
if (DST.batch) {
|
||||
DST.batch->program_in_use = false;
|
||||
}
|
||||
|
||||
DST.batch = geom;
|
||||
|
||||
GPU_batch_program_set_no_use(
|
||||
geom, GPU_shader_get_program(shgroup->shader), GPU_shader_get_interface(shgroup->shader));
|
||||
|
||||
geom->program_in_use = true; /* XXX hacking #GPUBatch */
|
||||
|
||||
GPU_batch_bind(geom);
|
||||
}
|
||||
|
||||
BLI_INLINE void draw_geometry_execute(DRWShadingGroup *shgroup,
|
||||
GPUBatch *geom,
|
||||
int vert_first,
|
||||
int vert_count,
|
||||
int inst_first,
|
||||
int inst_count,
|
||||
int baseinst_loc)
|
||||
uint vert_first,
|
||||
uint vert_count,
|
||||
uint inst_first,
|
||||
uint inst_count)
|
||||
{
|
||||
/* inst_count can be -1. */
|
||||
inst_count = max_ii(0, inst_count);
|
||||
|
||||
if (baseinst_loc != -1) {
|
||||
/* Fallback when ARB_shader_draw_parameters is not supported. */
|
||||
GPU_shader_uniform_vector_int(shgroup->shader, baseinst_loc, 1, 1, (int *)&inst_first);
|
||||
/* Avoids VAO reconfiguration on older hardware. (see GPU_batch_draw_advanced) */
|
||||
inst_first = 0;
|
||||
}
|
||||
|
||||
/* bind vertex array */
|
||||
if (DST.batch != geom) {
|
||||
draw_geometry_bind(shgroup, geom);
|
||||
DST.batch = geom;
|
||||
|
||||
GPU_batch_program_set_no_use(
|
||||
geom, GPU_shader_get_program(shgroup->shader), GPU_shader_get_interface(shgroup->shader));
|
||||
|
||||
GPU_batch_bind(geom);
|
||||
}
|
||||
|
||||
/* XXX hacking #GPUBatch. we don't want to call glUseProgram! (huge performance loss) */
|
||||
geom->program_in_use = true;
|
||||
|
||||
GPU_batch_draw_advanced(geom, vert_first, vert_count, inst_first, inst_count);
|
||||
}
|
||||
|
||||
BLI_INLINE void draw_indirect_call(DRWShadingGroup *shgroup, DRWCommandsState *state)
|
||||
{
|
||||
if (state->inst_count == 0) {
|
||||
return;
|
||||
}
|
||||
if (state->baseinst_loc == -1) {
|
||||
/* bind vertex array */
|
||||
if (DST.batch != state->batch) {
|
||||
GPU_draw_list_submit(DST.draw_list);
|
||||
draw_geometry_bind(shgroup, state->batch);
|
||||
}
|
||||
GPU_draw_list_command_add(
|
||||
DST.draw_list, state->v_first, state->v_count, state->base_inst, state->inst_count);
|
||||
}
|
||||
/* Fallback when unsupported */
|
||||
else {
|
||||
draw_geometry_execute(shgroup,
|
||||
state->batch,
|
||||
state->v_first,
|
||||
state->v_count,
|
||||
state->base_inst,
|
||||
state->inst_count,
|
||||
state->baseinst_loc);
|
||||
}
|
||||
geom->program_in_use = false; /* XXX hacking #GPUBatch */
|
||||
}
|
||||
|
||||
enum {
|
||||
|
@ -775,9 +719,6 @@ static void bind_ubo(GPUUniformBuffer *ubo, char bind_type)
|
|||
/* UBO isn't bound yet. Find an empty slot and bind it. */
|
||||
idx = get_empty_slot_index(DST.RST.bound_ubo_slots);
|
||||
|
||||
/* [0..1] are reserved ubo slots. */
|
||||
idx += 2;
|
||||
|
||||
if (idx < GPU_max_ubo_binds()) {
|
||||
GPUUniformBuffer **gpu_ubo_slot = &DST.RST.bound_ubos[idx];
|
||||
/* Unbind any previous UBO. */
|
||||
|
@ -797,13 +738,10 @@ static void bind_ubo(GPUUniformBuffer *ubo, char bind_type)
|
|||
}
|
||||
}
|
||||
else {
|
||||
BLI_assert(idx < 64);
|
||||
/* This UBO slot was released but the UBO is
|
||||
* still bound here. Just flag the slot again. */
|
||||
BLI_assert(DST.RST.bound_ubos[idx] == ubo);
|
||||
}
|
||||
/* Remove offset for flag bitfield. */
|
||||
idx -= 2;
|
||||
set_bound_flags(&DST.RST.bound_ubo_slots, &DST.RST.bound_ubo_slots_persist, idx, bind_type);
|
||||
}
|
||||
|
||||
|
@ -847,12 +785,8 @@ static bool ubo_bindings_validate(DRWShadingGroup *shgroup)
|
|||
printf("Trying to draw with missing UBO binding.\n");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
DRWPass *parent_pass = DRW_memblock_elem_from_handle(DST.vmempool->passes,
|
||||
&shgroup->pass_handle);
|
||||
|
||||
printf("Pass : %s, Shader : %s, Block : %s\n",
|
||||
parent_pass->name,
|
||||
shgroup->pass_parent->name,
|
||||
shgroup->shader->name,
|
||||
blockname);
|
||||
}
|
||||
|
@ -884,330 +818,119 @@ static void release_ubo_slots(bool with_persist)
|
|||
}
|
||||
}
|
||||
|
||||
static void draw_update_uniforms(DRWShadingGroup *shgroup,
|
||||
DRWCommandsState *state,
|
||||
bool *use_tfeedback)
|
||||
static void draw_update_uniforms(DRWShadingGroup *shgroup)
|
||||
{
|
||||
for (DRWUniformChunk *unichunk = shgroup->uniforms; unichunk; unichunk = unichunk->next) {
|
||||
DRWUniform *uni = unichunk->uniforms;
|
||||
for (int i = 0; i < unichunk->uniform_used; i++, uni++) {
|
||||
GPUTexture *tex;
|
||||
GPUUniformBuffer *ubo;
|
||||
if (uni->location == -2) {
|
||||
uni->location = GPU_shader_get_uniform_ensure(shgroup->shader,
|
||||
DST.uniform_names.buffer + uni->name_ofs);
|
||||
if (uni->location == -1) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
const void *data = uni->pvalue;
|
||||
if (ELEM(uni->type, DRW_UNIFORM_INT_COPY, DRW_UNIFORM_FLOAT_COPY)) {
|
||||
data = uni->fvalue;
|
||||
}
|
||||
switch (uni->type) {
|
||||
case DRW_UNIFORM_INT_COPY:
|
||||
case DRW_UNIFORM_INT:
|
||||
GPU_shader_uniform_vector_int(
|
||||
shgroup->shader, uni->location, uni->length, uni->arraysize, data);
|
||||
break;
|
||||
case DRW_UNIFORM_FLOAT_COPY:
|
||||
case DRW_UNIFORM_FLOAT:
|
||||
GPU_shader_uniform_vector(
|
||||
shgroup->shader, uni->location, uni->length, uni->arraysize, data);
|
||||
break;
|
||||
case DRW_UNIFORM_TEXTURE:
|
||||
tex = (GPUTexture *)uni->pvalue;
|
||||
BLI_assert(tex);
|
||||
bind_texture(tex, BIND_TEMP);
|
||||
GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
|
||||
break;
|
||||
case DRW_UNIFORM_TEXTURE_PERSIST:
|
||||
tex = (GPUTexture *)uni->pvalue;
|
||||
BLI_assert(tex);
|
||||
bind_texture(tex, BIND_PERSIST);
|
||||
GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
|
||||
break;
|
||||
case DRW_UNIFORM_TEXTURE_REF:
|
||||
tex = *((GPUTexture **)uni->pvalue);
|
||||
BLI_assert(tex);
|
||||
bind_texture(tex, BIND_TEMP);
|
||||
GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
|
||||
break;
|
||||
case DRW_UNIFORM_BLOCK:
|
||||
ubo = (GPUUniformBuffer *)uni->pvalue;
|
||||
bind_ubo(ubo, BIND_TEMP);
|
||||
GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo);
|
||||
break;
|
||||
case DRW_UNIFORM_BLOCK_PERSIST:
|
||||
ubo = (GPUUniformBuffer *)uni->pvalue;
|
||||
bind_ubo(ubo, BIND_PERSIST);
|
||||
GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo);
|
||||
break;
|
||||
case DRW_UNIFORM_BLOCK_OBMATS:
|
||||
state->obmats_loc = uni->location;
|
||||
ubo = DST.vmempool->matrices_ubo[0];
|
||||
GPU_uniformbuffer_bind(ubo, 0);
|
||||
GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo);
|
||||
break;
|
||||
case DRW_UNIFORM_BLOCK_OBINFOS:
|
||||
state->obinfos_loc = uni->location;
|
||||
ubo = DST.vmempool->obinfos_ubo[0];
|
||||
GPU_uniformbuffer_bind(ubo, 1);
|
||||
GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo);
|
||||
break;
|
||||
case DRW_UNIFORM_RESOURCE_CHUNK:
|
||||
state->chunkid_loc = uni->location;
|
||||
GPU_shader_uniform_int(shgroup->shader, uni->location, 0);
|
||||
break;
|
||||
case DRW_UNIFORM_TFEEDBACK_TARGET:
|
||||
BLI_assert(data && (*use_tfeedback == false));
|
||||
*use_tfeedback = GPU_shader_transform_feedback_enable(shgroup->shader,
|
||||
((GPUVertBuf *)data)->vbo_id);
|
||||
break;
|
||||
/* Legacy/Fallback support. */
|
||||
case DRW_UNIFORM_BASE_INSTANCE:
|
||||
state->baseinst_loc = uni->location;
|
||||
break;
|
||||
case DRW_UNIFORM_MODEL_MATRIX:
|
||||
state->obmat_loc = uni->location;
|
||||
break;
|
||||
case DRW_UNIFORM_MODEL_MATRIX_INVERSE:
|
||||
state->obinv_loc = uni->location;
|
||||
break;
|
||||
case DRW_UNIFORM_MODELVIEWPROJECTION_MATRIX:
|
||||
state->mvp_loc = uni->location;
|
||||
break;
|
||||
for (DRWUniform *uni = shgroup->uniforms; uni; uni = uni->next) {
|
||||
GPUTexture *tex;
|
||||
GPUUniformBuffer *ubo;
|
||||
if (uni->location == -2) {
|
||||
uni->location = GPU_shader_get_uniform_ensure(shgroup->shader,
|
||||
DST.uniform_names.buffer + uni->name_ofs);
|
||||
if (uni->location == -1) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
const void *data = uni->pvalue;
|
||||
if (ELEM(uni->type, DRW_UNIFORM_INT_COPY, DRW_UNIFORM_FLOAT_COPY)) {
|
||||
data = uni->fvalue;
|
||||
}
|
||||
switch (uni->type) {
|
||||
case DRW_UNIFORM_INT_COPY:
|
||||
case DRW_UNIFORM_INT:
|
||||
GPU_shader_uniform_vector_int(
|
||||
shgroup->shader, uni->location, uni->length, uni->arraysize, data);
|
||||
break;
|
||||
case DRW_UNIFORM_FLOAT_COPY:
|
||||
case DRW_UNIFORM_FLOAT:
|
||||
GPU_shader_uniform_vector(
|
||||
shgroup->shader, uni->location, uni->length, uni->arraysize, data);
|
||||
break;
|
||||
case DRW_UNIFORM_TEXTURE:
|
||||
tex = (GPUTexture *)uni->pvalue;
|
||||
BLI_assert(tex);
|
||||
bind_texture(tex, BIND_TEMP);
|
||||
GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
|
||||
break;
|
||||
case DRW_UNIFORM_TEXTURE_PERSIST:
|
||||
tex = (GPUTexture *)uni->pvalue;
|
||||
BLI_assert(tex);
|
||||
bind_texture(tex, BIND_PERSIST);
|
||||
GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
|
||||
break;
|
||||
case DRW_UNIFORM_TEXTURE_REF:
|
||||
tex = *((GPUTexture **)uni->pvalue);
|
||||
BLI_assert(tex);
|
||||
bind_texture(tex, BIND_TEMP);
|
||||
GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
|
||||
break;
|
||||
case DRW_UNIFORM_BLOCK:
|
||||
ubo = (GPUUniformBuffer *)uni->pvalue;
|
||||
bind_ubo(ubo, BIND_TEMP);
|
||||
GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo);
|
||||
break;
|
||||
case DRW_UNIFORM_BLOCK_PERSIST:
|
||||
ubo = (GPUUniformBuffer *)uni->pvalue;
|
||||
bind_ubo(ubo, BIND_PERSIST);
|
||||
GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BLI_assert(ubo_bindings_validate(shgroup));
|
||||
}
|
||||
|
||||
BLI_INLINE void draw_select_buffer(DRWShadingGroup *shgroup,
|
||||
DRWCommandsState *state,
|
||||
GPUBatch *batch,
|
||||
const DRWResourceHandle *handle)
|
||||
BLI_INLINE bool draw_select_do_call(DRWShadingGroup *shgroup, DRWCall *call)
|
||||
{
|
||||
const bool is_instancing = (batch->inst != NULL);
|
||||
int start = 0;
|
||||
int count = 1;
|
||||
int tot = is_instancing ? batch->inst->vertex_len : batch->verts[0]->vertex_len;
|
||||
/* Hack : get "vbo" data without actually drawing. */
|
||||
int *select_id = (void *)state->select_buf->data;
|
||||
|
||||
/* Batching */
|
||||
if (!is_instancing) {
|
||||
/* FIXME: Meh a bit nasty. */
|
||||
if (batch->gl_prim_type == convert_prim_type_to_gl(GPU_PRIM_TRIS)) {
|
||||
count = 3;
|
||||
}
|
||||
else if (batch->gl_prim_type == convert_prim_type_to_gl(GPU_PRIM_LINES)) {
|
||||
count = 2;
|
||||
}
|
||||
#ifdef USE_GPU_SELECT
|
||||
if ((G.f & G_FLAG_PICKSEL) == 0) {
|
||||
return false;
|
||||
}
|
||||
if (call->inst_selectid != NULL) {
|
||||
const bool is_instancing = (call->inst_count != 0);
|
||||
uint start = 0;
|
||||
uint count = 1;
|
||||
uint tot = is_instancing ? call->inst_count : call->vert_count;
|
||||
/* Hack : get vbo data without actually drawing. */
|
||||
GPUVertBufRaw raw;
|
||||
GPU_vertbuf_attr_get_raw_data(call->inst_selectid, 0, &raw);
|
||||
int *select_id = GPU_vertbuf_raw_step(&raw);
|
||||
|
||||
while (start < tot) {
|
||||
GPU_select_load_id(select_id[start]);
|
||||
if (is_instancing) {
|
||||
draw_geometry_execute(shgroup, batch, 0, 0, start, count, state->baseinst_loc);
|
||||
}
|
||||
else {
|
||||
draw_geometry_execute(
|
||||
shgroup, batch, start, count, DRW_handle_id_get(handle), 0, state->baseinst_loc);
|
||||
}
|
||||
start += count;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct DRWCommandIterator {
|
||||
int cmd_index;
|
||||
DRWCommandChunk *curr_chunk;
|
||||
} DRWCommandIterator;
|
||||
|
||||
static void draw_command_iter_begin(DRWCommandIterator *iter, DRWShadingGroup *shgroup)
|
||||
{
|
||||
iter->curr_chunk = shgroup->cmd.first;
|
||||
iter->cmd_index = 0;
|
||||
}
|
||||
|
||||
static DRWCommand *draw_command_iter_step(DRWCommandIterator *iter, eDRWCommandType *cmd_type)
|
||||
{
|
||||
if (iter->curr_chunk) {
|
||||
if (iter->cmd_index == iter->curr_chunk->command_len) {
|
||||
iter->curr_chunk = iter->curr_chunk->next;
|
||||
iter->cmd_index = 0;
|
||||
}
|
||||
if (iter->curr_chunk) {
|
||||
*cmd_type = command_type_get(iter->curr_chunk->command_type, iter->cmd_index);
|
||||
if (iter->cmd_index < iter->curr_chunk->command_used) {
|
||||
return iter->curr_chunk->commands + iter->cmd_index++;
|
||||
/* Batching */
|
||||
if (!is_instancing) {
|
||||
/* FIXME: Meh a bit nasty. */
|
||||
if (call->batch->gl_prim_type == convert_prim_type_to_gl(GPU_PRIM_TRIS)) {
|
||||
count = 3;
|
||||
}
|
||||
else if (call->batch->gl_prim_type == convert_prim_type_to_gl(GPU_PRIM_LINES)) {
|
||||
count = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void draw_call_resource_bind(DRWCommandsState *state, const DRWResourceHandle *handle)
|
||||
{
|
||||
/* Front face is not a resource but it is inside the resource handle. */
|
||||
bool neg_scale = DRW_handle_negative_scale_get(handle);
|
||||
if (neg_scale != state->neg_scale) {
|
||||
glFrontFace((neg_scale) ? GL_CW : GL_CCW);
|
||||
state->neg_scale = neg_scale;
|
||||
}
|
||||
|
||||
int chunk = DRW_handle_chunk_get(handle);
|
||||
if (state->resource_chunk != chunk) {
|
||||
if (state->chunkid_loc != -1) {
|
||||
GPU_shader_uniform_int(NULL, state->chunkid_loc, chunk);
|
||||
while (start < tot) {
|
||||
GPU_select_load_id(select_id[start]);
|
||||
if (is_instancing) {
|
||||
draw_geometry_execute(shgroup, call->batch, 0, 0, start, count);
|
||||
}
|
||||
else {
|
||||
draw_geometry_execute(shgroup, call->batch, start, count, 0, 0);
|
||||
}
|
||||
start += count;
|
||||
}
|
||||
if (state->obmats_loc != -1) {
|
||||
GPU_uniformbuffer_unbind(DST.vmempool->matrices_ubo[state->resource_chunk]);
|
||||
GPU_uniformbuffer_bind(DST.vmempool->matrices_ubo[chunk], 0);
|
||||
}
|
||||
if (state->obinfos_loc != -1) {
|
||||
GPU_uniformbuffer_unbind(DST.vmempool->obinfos_ubo[state->resource_chunk]);
|
||||
GPU_uniformbuffer_bind(DST.vmempool->obinfos_ubo[chunk], 1);
|
||||
}
|
||||
state->resource_chunk = chunk;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_call_batching_flush(DRWShadingGroup *shgroup, DRWCommandsState *state)
|
||||
{
|
||||
draw_indirect_call(shgroup, state);
|
||||
GPU_draw_list_submit(DST.draw_list);
|
||||
|
||||
state->batch = NULL;
|
||||
state->inst_count = 0;
|
||||
state->base_inst = -1;
|
||||
}
|
||||
|
||||
static void draw_call_single_do(DRWShadingGroup *shgroup,
|
||||
DRWCommandsState *state,
|
||||
GPUBatch *batch,
|
||||
DRWResourceHandle handle,
|
||||
int vert_first,
|
||||
int vert_count,
|
||||
int inst_count)
|
||||
{
|
||||
draw_call_batching_flush(shgroup, state);
|
||||
|
||||
draw_call_resource_bind(state, &handle);
|
||||
|
||||
/* TODO This is Legacy. Need to be removed. */
|
||||
if (state->obmats_loc == -1 &&
|
||||
(state->obmat_loc != -1 || state->obinv_loc != -1 || state->mvp_loc != -1)) {
|
||||
draw_legacy_matrix_update(
|
||||
shgroup, &handle, state->obmat_loc, state->obinv_loc, state->mvp_loc);
|
||||
}
|
||||
|
||||
if (G.f & G_FLAG_PICKSEL) {
|
||||
if (state->select_buf != NULL) {
|
||||
draw_select_buffer(shgroup, state, batch, &handle);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
GPU_select_load_id(state->select_id);
|
||||
}
|
||||
}
|
||||
|
||||
draw_geometry_execute(shgroup,
|
||||
batch,
|
||||
vert_first,
|
||||
vert_count,
|
||||
DRW_handle_id_get(&handle),
|
||||
inst_count,
|
||||
state->baseinst_loc);
|
||||
}
|
||||
|
||||
static void draw_call_batching_start(DRWCommandsState *state)
|
||||
{
|
||||
state->neg_scale = false;
|
||||
state->resource_chunk = 0;
|
||||
state->base_inst = 0;
|
||||
state->inst_count = 0;
|
||||
state->v_first = 0;
|
||||
state->v_count = 0;
|
||||
state->batch = NULL;
|
||||
|
||||
state->select_id = -1;
|
||||
state->select_buf = NULL;
|
||||
}
|
||||
|
||||
static void draw_call_batching_do(DRWShadingGroup *shgroup,
|
||||
DRWCommandsState *state,
|
||||
DRWCommandDraw *call)
|
||||
{
|
||||
/* If any condition requires to interupt the merging. */
|
||||
bool neg_scale = DRW_handle_negative_scale_get(&call->handle);
|
||||
int chunk = DRW_handle_chunk_get(&call->handle);
|
||||
int id = DRW_handle_id_get(&call->handle);
|
||||
if ((state->neg_scale != neg_scale) || /* Need to change state. */
|
||||
(state->resource_chunk != chunk) || /* Need to change UBOs. */
|
||||
(state->batch != call->batch) /* Need to change VAO. */
|
||||
) {
|
||||
draw_call_batching_flush(shgroup, state);
|
||||
|
||||
state->batch = call->batch;
|
||||
state->v_first = (call->batch->elem) ? call->batch->elem->index_start : 0;
|
||||
state->v_count = (call->batch->elem) ? call->batch->elem->index_len :
|
||||
call->batch->verts[0]->vertex_len;
|
||||
state->inst_count = 1;
|
||||
state->base_inst = id;
|
||||
|
||||
draw_call_resource_bind(state, &call->handle);
|
||||
|
||||
GPU_draw_list_init(DST.draw_list, state->batch);
|
||||
}
|
||||
/* Is the id consecutive? */
|
||||
else if (id != state->base_inst + state->inst_count) {
|
||||
/* We need to add a draw command for the pending instances. */
|
||||
draw_indirect_call(shgroup, state);
|
||||
state->inst_count = 1;
|
||||
state->base_inst = id;
|
||||
}
|
||||
/* We avoid a drawcall by merging with the precedent
|
||||
* drawcall using instancing. */
|
||||
else {
|
||||
state->inst_count++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Flush remaining pending drawcalls. */
|
||||
static void draw_call_batching_finish(DRWShadingGroup *shgroup, DRWCommandsState *state)
|
||||
{
|
||||
draw_call_batching_flush(shgroup, state);
|
||||
|
||||
/* Reset state */
|
||||
if (state->neg_scale) {
|
||||
glFrontFace(GL_CCW);
|
||||
}
|
||||
if (state->obmats_loc != -1) {
|
||||
GPU_uniformbuffer_unbind(DST.vmempool->matrices_ubo[state->resource_chunk]);
|
||||
}
|
||||
if (state->obinfos_loc != -1) {
|
||||
GPU_uniformbuffer_unbind(DST.vmempool->obinfos_ubo[state->resource_chunk]);
|
||||
GPU_select_load_id(call->select_id);
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
|
||||
{
|
||||
BLI_assert(shgroup->shader);
|
||||
|
||||
DRWCommandsState state = {
|
||||
.obmats_loc = -1,
|
||||
.obinfos_loc = -1,
|
||||
.baseinst_loc = -1,
|
||||
.chunkid_loc = -1,
|
||||
.obmat_loc = -1,
|
||||
.obinv_loc = -1,
|
||||
.mvp_loc = -1,
|
||||
.drw_state_enabled = 0,
|
||||
.drw_state_disabled = 0,
|
||||
};
|
||||
|
||||
const bool shader_changed = (DST.shader != shgroup->shader);
|
||||
bool use_tfeedback = false;
|
||||
|
||||
|
@ -1217,115 +940,56 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
|
|||
}
|
||||
GPU_shader_bind(shgroup->shader);
|
||||
DST.shader = shgroup->shader;
|
||||
/* XXX hacking gawain */
|
||||
if (DST.batch) {
|
||||
DST.batch->program_in_use = false;
|
||||
}
|
||||
DST.batch = NULL;
|
||||
}
|
||||
|
||||
if (shgroup->tfeedback_target != NULL) {
|
||||
use_tfeedback = GPU_shader_transform_feedback_enable(shgroup->shader,
|
||||
shgroup->tfeedback_target->vbo_id);
|
||||
}
|
||||
|
||||
release_ubo_slots(shader_changed);
|
||||
release_texture_slots(shader_changed);
|
||||
|
||||
draw_update_uniforms(shgroup, &state, &use_tfeedback);
|
||||
drw_state_set((pass_state & shgroup->state_extra_disable) | shgroup->state_extra);
|
||||
drw_stencil_set(shgroup->stencil_mask);
|
||||
|
||||
drw_state_set(pass_state);
|
||||
draw_update_uniforms(shgroup);
|
||||
|
||||
/* Rendering Calls */
|
||||
{
|
||||
DRWCommandIterator iter;
|
||||
DRWCommand *cmd;
|
||||
eDRWCommandType cmd_type;
|
||||
bool prev_neg_scale = false;
|
||||
int callid = 0;
|
||||
for (DRWCall *call = shgroup->calls.first; call; call = call->next) {
|
||||
|
||||
draw_command_iter_begin(&iter, shgroup);
|
||||
|
||||
draw_call_batching_start(&state);
|
||||
|
||||
while ((cmd = draw_command_iter_step(&iter, &cmd_type))) {
|
||||
|
||||
switch (cmd_type) {
|
||||
case DRW_CMD_DRWSTATE:
|
||||
case DRW_CMD_STENCIL:
|
||||
draw_call_batching_flush(shgroup, &state);
|
||||
break;
|
||||
case DRW_CMD_DRAW:
|
||||
case DRW_CMD_DRAW_PROCEDURAL:
|
||||
case DRW_CMD_DRAW_INSTANCE:
|
||||
if (draw_call_is_culled(&cmd->instance.handle, DST.view_active)) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (draw_call_is_culled(call, DST.view_active)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (cmd_type) {
|
||||
case DRW_CMD_CLEAR:
|
||||
GPU_framebuffer_clear(
|
||||
#ifndef NDEBUG
|
||||
GPU_framebuffer_active_get(),
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
cmd->clear.clear_channels,
|
||||
(float[4]){cmd->clear.r / 255.0f,
|
||||
cmd->clear.g / 255.0f,
|
||||
cmd->clear.b / 255.0f,
|
||||
cmd->clear.a / 255.0f},
|
||||
cmd->clear.depth,
|
||||
cmd->clear.stencil);
|
||||
break;
|
||||
case DRW_CMD_DRWSTATE:
|
||||
state.drw_state_enabled |= cmd->state.enable;
|
||||
state.drw_state_disabled |= cmd->state.disable;
|
||||
drw_state_set((pass_state & ~state.drw_state_disabled) | state.drw_state_enabled);
|
||||
break;
|
||||
case DRW_CMD_STENCIL:
|
||||
drw_stencil_set(cmd->stencil.mask);
|
||||
break;
|
||||
case DRW_CMD_SELECTID:
|
||||
state.select_id = cmd->select_id.select_id;
|
||||
state.select_buf = cmd->select_id.select_buf;
|
||||
break;
|
||||
case DRW_CMD_DRAW:
|
||||
if (!USE_BATCHING || state.obmats_loc == -1 || (G.f & G_FLAG_PICKSEL)) {
|
||||
draw_call_single_do(shgroup, &state, cmd->draw.batch, cmd->draw.handle, 0, 0, 0);
|
||||
}
|
||||
else {
|
||||
draw_call_batching_do(shgroup, &state, &cmd->draw);
|
||||
}
|
||||
break;
|
||||
case DRW_CMD_DRAW_PROCEDURAL:
|
||||
draw_call_single_do(shgroup,
|
||||
&state,
|
||||
cmd->procedural.batch,
|
||||
cmd->procedural.handle,
|
||||
0,
|
||||
cmd->procedural.vert_count,
|
||||
1);
|
||||
break;
|
||||
case DRW_CMD_DRAW_INSTANCE:
|
||||
draw_call_single_do(shgroup,
|
||||
&state,
|
||||
cmd->instance.batch,
|
||||
cmd->instance.handle,
|
||||
0,
|
||||
0,
|
||||
cmd->instance.inst_count);
|
||||
break;
|
||||
case DRW_CMD_DRAW_RANGE:
|
||||
draw_call_single_do(shgroup,
|
||||
&state,
|
||||
cmd->range.batch,
|
||||
(DRWResourceHandle)0,
|
||||
cmd->range.vert_first,
|
||||
cmd->range.vert_count,
|
||||
1);
|
||||
break;
|
||||
/* XXX small exception/optimisation for outline rendering. */
|
||||
if (shgroup->callid != -1) {
|
||||
GPU_shader_uniform_vector_int(shgroup->shader, shgroup->callid, 1, 1, &callid);
|
||||
callid += 1;
|
||||
}
|
||||
|
||||
/* Negative scale objects */
|
||||
bool neg_scale = call->state->flag & DRW_CALL_NEGSCALE;
|
||||
if (neg_scale != prev_neg_scale) {
|
||||
glFrontFace((neg_scale) ? GL_CW : GL_CCW);
|
||||
prev_neg_scale = neg_scale;
|
||||
}
|
||||
|
||||
draw_geometry_prepare(shgroup, call);
|
||||
|
||||
if (draw_select_do_call(shgroup, call)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
draw_geometry_execute(
|
||||
shgroup, call->batch, call->vert_first, call->vert_count, 0, call->inst_count);
|
||||
}
|
||||
|
||||
draw_call_batching_finish(shgroup, &state);
|
||||
/* Reset state */
|
||||
glFrontFace(GL_CCW);
|
||||
}
|
||||
|
||||
if (use_tfeedback) {
|
||||
|
@ -1401,11 +1065,6 @@ static void drw_draw_pass_ex(DRWPass *pass,
|
|||
DST.shader = NULL;
|
||||
}
|
||||
|
||||
if (DST.batch) {
|
||||
DST.batch->program_in_use = false;
|
||||
DST.batch = NULL;
|
||||
}
|
||||
|
||||
/* HACK: Rasterized discard can affect clear commands which are not
|
||||
* part of a DRWPass (as of now). So disable rasterized discard here
|
||||
* if it has been enabled. */
|
||||
|
|
|
@ -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, "#define IN_PLACE_INSTANCES\n", NULL},
|
||||
.defs = (const char *[]){sh_cfg_data->def, NULL},
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -286,10 +286,15 @@ typedef struct OBJECT_PrivateData {
|
|||
DRWShadingGroup *outlines_transform;
|
||||
|
||||
/* Lightprobes */
|
||||
DRWShadingGroup *probe_outlines_transform;
|
||||
DRWShadingGroup *probe_outlines_select;
|
||||
DRWShadingGroup *probe_outlines_select_dupli;
|
||||
DRWShadingGroup *probe_outlines_active;
|
||||
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;
|
||||
|
||||
/* Objects Centers */
|
||||
DRWCallBuffer *center_active;
|
||||
|
@ -298,6 +303,17 @@ 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 */
|
||||
|
@ -401,10 +417,7 @@ 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_common_view_lib_glsl,
|
||||
datatoc_object_outline_prepass_vert_glsl,
|
||||
NULL},
|
||||
.vert = (const char *[]){sh_cfg_data->lib, datatoc_gpu_shader_3D_vert_glsl, NULL},
|
||||
.frag = (const char *[]){datatoc_object_outline_prepass_frag_glsl, NULL},
|
||||
.defs = (const char *[]){sh_cfg_data->def, NULL},
|
||||
});
|
||||
|
@ -418,7 +431,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, "#define USE_GEOM\n", NULL},
|
||||
.defs = (const char *[]){sh_cfg_data->def, NULL},
|
||||
});
|
||||
|
||||
sh_data->outline_resolve = DRW_shader_create_fullscreen(
|
||||
|
@ -526,11 +539,10 @@ 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_object_outline_prepass_frag_glsl, NULL},
|
||||
.frag = (const char *[]){datatoc_gpu_shader_flat_id_frag_glsl, NULL},
|
||||
.defs = (const char *[]){sh_cfg_data->def, NULL},
|
||||
});
|
||||
|
||||
|
@ -685,12 +697,12 @@ static void OBJECT_engine_free(void)
|
|||
}
|
||||
|
||||
static DRWShadingGroup *shgroup_outline(DRWPass *pass,
|
||||
int outline_id,
|
||||
const int *ofs,
|
||||
GPUShader *sh,
|
||||
eGPUShaderConfig sh_cfg)
|
||||
{
|
||||
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
|
||||
DRW_shgroup_uniform_int_copy(grp, "outlineId", outline_id);
|
||||
DRW_shgroup_uniform_int(grp, "baseId", ofs, 1);
|
||||
|
||||
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
|
||||
DRW_shgroup_state_enable(grp, DRW_STATE_CLIP_PLANES);
|
||||
|
@ -729,10 +741,107 @@ 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)
|
||||
{
|
||||
if (UNLIKELY(base_flag & BASE_FROM_DUPLI)) {
|
||||
switch (theme_id) {
|
||||
case TH_ACTIVE:
|
||||
case TH_SELECT:
|
||||
return &stl->g_data->id_ofs_select_dupli;
|
||||
case TH_TRANSFORM:
|
||||
default:
|
||||
return &stl->g_data->id_ofs_transform;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
case TH_SELECT:
|
||||
return stl->g_data->lightprobes_planar_select;
|
||||
case TH_TRANSFORM:
|
||||
default:
|
||||
return stl->g_data->lightprobes_planar_transform;
|
||||
}
|
||||
}
|
||||
|
||||
static DRWCallBuffer *buffer_theme_id_to_probe_cube_outline_shgrp(OBJECT_StorageList *stl,
|
||||
int theme_id,
|
||||
const int base_flag)
|
||||
{
|
||||
/* does not increment counter */
|
||||
if (UNLIKELY(base_flag & BASE_FROM_DUPLI)) {
|
||||
switch (theme_id) {
|
||||
case TH_ACTIVE:
|
||||
case TH_SELECT:
|
||||
return stl->g_data->lightprobes_cube_select_dupli;
|
||||
case TH_TRANSFORM:
|
||||
default:
|
||||
return stl->g_data->lightprobes_cube_transform;
|
||||
}
|
||||
}
|
||||
|
||||
switch (theme_id) {
|
||||
case TH_ACTIVE:
|
||||
return stl->g_data->lightprobes_cube_active;
|
||||
case TH_SELECT:
|
||||
return stl->g_data->lightprobes_cube_select;
|
||||
case TH_TRANSFORM:
|
||||
default:
|
||||
return stl->g_data->lightprobes_cube_transform;
|
||||
}
|
||||
}
|
||||
|
||||
static DRWShadingGroup *shgroup_theme_id_to_outline_or_null(OBJECT_StorageList *stl,
|
||||
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:
|
||||
|
@ -757,64 +866,6 @@ static DRWShadingGroup *shgroup_theme_id_to_outline_or_null(OBJECT_StorageList *
|
|||
}
|
||||
}
|
||||
|
||||
static DRWShadingGroup *shgroup_theme_id_to_probe_outline_or_null(OBJECT_StorageList *stl,
|
||||
int theme_id,
|
||||
const int base_flag)
|
||||
{
|
||||
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->probe_outlines_select_dupli;
|
||||
case TH_TRANSFORM:
|
||||
return stl->g_data->probe_outlines_transform;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
switch (theme_id) {
|
||||
case TH_ACTIVE:
|
||||
return stl->g_data->probe_outlines_active;
|
||||
case TH_SELECT:
|
||||
return stl->g_data->probe_outlines_select;
|
||||
case TH_TRANSFORM:
|
||||
return stl->g_data->probe_outlines_transform;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int shgroup_theme_id_to_outline_id(int theme_id, const int base_flag)
|
||||
{
|
||||
if (UNLIKELY(base_flag & BASE_FROM_DUPLI)) {
|
||||
switch (theme_id) {
|
||||
case TH_ACTIVE:
|
||||
case TH_SELECT:
|
||||
return 2;
|
||||
case TH_TRANSFORM:
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
switch (theme_id) {
|
||||
case TH_ACTIVE:
|
||||
return 3;
|
||||
case TH_SELECT:
|
||||
return 1;
|
||||
case TH_TRANSFORM:
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static DRWShadingGroup *shgroup_theme_id_to_wire(OBJECT_ShadingGroupList *sgl,
|
||||
int theme_id,
|
||||
const short base_flag)
|
||||
|
@ -1295,8 +1346,7 @@ 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();
|
||||
eGPUShaderConfig cfg = draw_ctx->sh_cfg;
|
||||
OBJECT_Shaders *sh_data = &e_data.sh_data[cfg];
|
||||
OBJECT_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
|
||||
|
||||
const float outline_width = UI_GetThemeValuef(TH_OUTLINE_WIDTH);
|
||||
const bool do_outline_expand = (U.pixelsize > 1.0) || (outline_width > 2.0f);
|
||||
|
@ -1317,25 +1367,59 @@ static void OBJECT_cache_init(void *vedata)
|
|||
|
||||
{
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
|
||||
psl->lightprobes = DRW_pass_create("Outlines Probe Pass", state);
|
||||
psl->outlines = DRW_pass_create("Outlines Depth 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_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);
|
||||
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;
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -1354,6 +1438,7 @@ 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. */
|
||||
|
@ -2681,6 +2766,15 @@ 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,
|
||||
|
@ -2697,10 +2791,13 @@ 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);
|
||||
|
@ -2710,40 +2807,65 @@ static void DRW_shgroup_lightprobe(OBJECT_Shaders *sh_data,
|
|||
mul_v3_v3fl(half_cell_dim, cell_dim, 0.5f);
|
||||
|
||||
/* First cell. */
|
||||
copy_v3_fl(corner, -1.0f);
|
||||
add_v3_v3(corner, half_cell_dim);
|
||||
mul_m4_v3(ob->obmat, corner);
|
||||
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);
|
||||
|
||||
/* Opposite neighbor cell. */
|
||||
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]);
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
|
||||
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_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);
|
||||
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);
|
||||
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_PLANAR && (prb->flag & LIGHTPROBE_FLAG_SHOW_DATA)) {
|
||||
DRWShadingGroup *grp = shgroup_theme_id_to_probe_outline_or_null(
|
||||
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(
|
||||
stl, theme_id, ob->base_flag);
|
||||
DRW_shgroup_call_no_cull(grp, DRW_cache_quad_get(), ob);
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3660,7 +3782,19 @@ static void OBJECT_draw_scene(void *vedata)
|
|||
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
|
||||
int do_outlines = !DRW_pass_is_empty(psl->outlines) || !DRW_pass_is_empty(psl->lightprobes);
|
||||
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;
|
||||
|
||||
float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
|
||||
|
@ -3668,24 +3802,35 @@ 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(g_data->sgl.transp_shapes);
|
||||
DRW_draw_pass(stl->g_data->sgl.transp_shapes);
|
||||
|
||||
MULTISAMPLE_SYNC_ENABLE(dfbl, dtxl);
|
||||
|
||||
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(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(psl->particle);
|
||||
DRW_draw_pass(g_data->sgl.bone_axes);
|
||||
DRW_draw_pass(stl->g_data->sgl.bone_axes);
|
||||
|
||||
MULTISAMPLE_SYNC_DISABLE(dfbl, dtxl);
|
||||
|
||||
DRW_draw_pass(g_data->sgl.image_empties);
|
||||
DRW_draw_pass(stl->g_data->sgl.image_empties);
|
||||
|
||||
if (DRW_state_is_fbo() && do_outlines) {
|
||||
if (DRW_state_is_fbo() && outline_calls > 0) {
|
||||
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);
|
||||
|
@ -3720,7 +3865,7 @@ static void OBJECT_draw_scene(void *vedata)
|
|||
}
|
||||
|
||||
/* Combine with scene buffer last */
|
||||
if (do_outlines) {
|
||||
if (outline_calls > 0) {
|
||||
DRW_draw_pass(psl->outlines_resolve);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#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"
|
||||
|
@ -75,6 +77,7 @@ 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;
|
||||
|
@ -205,6 +208,10 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -249,6 +256,7 @@ 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,
|
||||
|
@ -297,10 +305,8 @@ 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)) {
|
||||
/* 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;
|
||||
*wire_col = BLI_mempool_alloc(pd->wire_color_mempool);
|
||||
*rim_col = BLI_mempool_alloc(pd->wire_color_mempool);
|
||||
|
||||
if (v3d->shading.wire_color_type == V3D_SHADING_OBJECT_COLOR) {
|
||||
linearrgb_to_srgb_v3_v3(*wire_col, ob->color);
|
||||
|
@ -421,9 +427,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, 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);
|
||||
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);
|
||||
DRW_shgroup_stencil_mask(shgrp,
|
||||
(is_xray && (is_wire || !pd->clear_stencil)) ? 0x00 : 0xFF);
|
||||
}
|
||||
|
@ -500,6 +506,12 @@ 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)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#define COMMON_VIEW_LIB
|
||||
#define DRW_RESOURCE_CHUNK_LEN 512
|
||||
|
||||
/* keep in sync with DRWManager.view_data */
|
||||
layout(std140) uniform viewBlock
|
||||
|
@ -24,74 +23,8 @@ 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
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
|
||||
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];
|
||||
|
||||
flat out int objectId;
|
||||
uniform int call_id; /* we don't want the builtin callId which would be 0. */
|
||||
uniform int baseId;
|
||||
|
||||
flat out uint finalId;
|
||||
|
||||
void main()
|
||||
{
|
||||
|
@ -22,8 +29,7 @@ void main()
|
|||
gl_Position = ViewProjectionMatrix * vec4(ws_cell_location, 1.0);
|
||||
gl_PointSize = 2.0f;
|
||||
|
||||
/* ID 0 is nothing (background) */
|
||||
objectId = resource_handle + 1;
|
||||
finalId = uint(baseId + call_id);
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(ws_cell_location);
|
||||
|
|
|
@ -7,9 +7,30 @@ 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);
|
||||
|
@ -64,24 +85,7 @@ void main()
|
|||
const float epsilon = 3.0 / 8388608.0;
|
||||
bool occluded = (ref_depth > scene_depth + epsilon);
|
||||
|
||||
/* 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 = convert_id_to_color(int(ref_id));
|
||||
FragColor.a *= (occluded) ? alphaOcclu : 1.0;
|
||||
FragColor.a = (outline) ? FragColor.a : 0.0;
|
||||
}
|
||||
|
|
|
@ -1,18 +1,10 @@
|
|||
|
||||
/* Should be 2 bits only [0..3]. */
|
||||
uniform int outlineId;
|
||||
|
||||
flat in int objectId;
|
||||
uniform int callId;
|
||||
uniform int baseId;
|
||||
|
||||
/* 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(outlineId) << 14u) | ((uint(objectId) << SHIFT) >> SHIFT);
|
||||
outId = uint(baseId + callId);
|
||||
}
|
||||
|
|
|
@ -2,15 +2,12 @@
|
|||
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 = gl_in[v].gl_Position;
|
||||
objectId = objectId_g[v];
|
||||
gl_Position = pPos[v];
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_set_clip_distance(gl_in[v].gl_ClipDistance);
|
||||
#endif
|
||||
|
|
|
@ -1,27 +1,16 @@
|
|||
|
||||
in vec3 pos;
|
||||
|
||||
#ifdef USE_GEOM
|
||||
out vec4 pPos;
|
||||
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);
|
||||
#endif
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
pPos = point_world_to_ndc(world_pos);
|
||||
/* Small bias to always be on top of the geom. */
|
||||
gl_Position.z -= 1e-3;
|
||||
|
||||
/* ID 0 is nothing (background) */
|
||||
objectId = resource_handle + 1;
|
||||
pPos.z -= 1e-3;
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(world_pos);
|
||||
|
|
|
@ -101,19 +101,17 @@ static int bm_face_isect_pair_swap(BMFace *f, void *UNUSED(user_data))
|
|||
/**
|
||||
* Use for intersect and boolean.
|
||||
*/
|
||||
static void edbm_intersect_select(BMEditMesh *em, bool do_select)
|
||||
static void edbm_intersect_select(BMEditMesh *em)
|
||||
{
|
||||
if (do_select) {
|
||||
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
|
||||
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
|
||||
|
||||
if (em->bm->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) {
|
||||
BMIter iter;
|
||||
BMEdge *e;
|
||||
if (em->bm->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) {
|
||||
BMIter iter;
|
||||
BMEdge *e;
|
||||
|
||||
BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
|
||||
if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
|
||||
BM_edge_select_set(em->bm, e, true);
|
||||
}
|
||||
BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
|
||||
if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
|
||||
BM_edge_select_set(em->bm, e, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -212,9 +210,10 @@ static int edbm_intersect_exec(bContext *C, wmOperator *op)
|
|||
em->bm, BM_elem_cb_check_hflag_enabled_simple(const BMFace *, BM_ELEM_SELECT));
|
||||
}
|
||||
|
||||
edbm_intersect_select(em, has_isect);
|
||||
|
||||
if (!has_isect) {
|
||||
if (has_isect) {
|
||||
edbm_intersect_select(em);
|
||||
}
|
||||
else {
|
||||
isect_len++;
|
||||
}
|
||||
}
|
||||
|
@ -318,9 +317,10 @@ static int edbm_intersect_boolean_exec(bContext *C, wmOperator *op)
|
|||
boolean_operation,
|
||||
eps);
|
||||
|
||||
edbm_intersect_select(em, has_isect);
|
||||
|
||||
if (!has_isect) {
|
||||
if (has_isect) {
|
||||
edbm_intersect_select(em);
|
||||
}
|
||||
else {
|
||||
isect_len++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -330,8 +330,6 @@ data_to_c_simple(shaders/gpu_shader_gpencil_fill_frag.glsl SRC)
|
|||
|
||||
data_to_c_simple(shaders/gpu_shader_cfg_world_clip_lib.glsl SRC)
|
||||
|
||||
data_to_c_simple(shaders/gpu_shader_common_obinfos_lib.glsl SRC)
|
||||
|
||||
|
||||
if(WITH_MOD_SMOKE)
|
||||
add_definitions(-DWITH_SMOKE)
|
||||
|
|
|
@ -193,17 +193,6 @@ GPUBatch *create_BatchInGeneral(GPUPrimType, VertexBufferStuff, ElementListStuff
|
|||
|
||||
#endif /* future plans */
|
||||
|
||||
/* GPUDrawList is an API to do lots of similar drawcalls very fast using multidrawindirect.
|
||||
* There is a fallback if the feature is not supported. */
|
||||
typedef struct GPUDrawList GPUDrawList;
|
||||
|
||||
GPUDrawList *GPU_draw_list_create(int length);
|
||||
void GPU_draw_list_discard(GPUDrawList *list);
|
||||
void GPU_draw_list_init(GPUDrawList *list, GPUBatch *batch);
|
||||
void GPU_draw_list_command_add(
|
||||
GPUDrawList *list, int v_first, int v_count, int i_first, int i_count);
|
||||
void GPU_draw_list_submit(GPUDrawList *list);
|
||||
|
||||
void gpu_batch_init(void);
|
||||
void gpu_batch_exit(void);
|
||||
|
||||
|
|
|
@ -45,12 +45,13 @@ typedef enum {
|
|||
GPU_UNIFORM_VIEWPROJECTION_INV, /* mat4 ViewProjectionMatrixInverse */
|
||||
|
||||
GPU_UNIFORM_NORMAL, /* mat3 NormalMatrix */
|
||||
GPU_UNIFORM_ORCO, /* vec4 OrcoTexCoFactors[] */
|
||||
GPU_UNIFORM_ORCO, /* vec3 OrcoTexCoFactors[] */
|
||||
GPU_UNIFORM_CLIPPLANES, /* vec4 WorldClipPlanes[] */
|
||||
|
||||
GPU_UNIFORM_COLOR, /* vec4 color */
|
||||
GPU_UNIFORM_BASE_INSTANCE, /* int baseInstance */
|
||||
GPU_UNIFORM_RESOURCE_CHUNK, /* int resourceChunk */
|
||||
GPU_UNIFORM_COLOR, /* vec4 color */
|
||||
GPU_UNIFORM_CALLID, /* int callId */
|
||||
GPU_UNIFORM_OBJECT_INFO, /* vec3 objectInfo */
|
||||
GPU_UNIFORM_OBJECT_COLOR, /* vec4 objectColor */
|
||||
|
||||
GPU_UNIFORM_CUSTOM, /* custom uniform, not one of the above built-ins */
|
||||
|
||||
|
|
|
@ -37,20 +37,14 @@ typedef struct GPUViewport GPUViewport;
|
|||
|
||||
/* Contains memory pools information */
|
||||
typedef struct ViewportMemoryPool {
|
||||
struct BLI_memblock *commands;
|
||||
struct BLI_memblock *commands_small;
|
||||
struct BLI_memblock *callbuffers;
|
||||
struct BLI_memblock *obmats;
|
||||
struct BLI_memblock *obinfos;
|
||||
struct BLI_memblock *calls;
|
||||
struct BLI_memblock *states;
|
||||
struct BLI_memblock *cullstates;
|
||||
struct BLI_memblock *shgroups;
|
||||
struct BLI_memblock *uniforms;
|
||||
struct BLI_memblock *views;
|
||||
struct BLI_memblock *passes;
|
||||
struct BLI_memblock *images;
|
||||
struct GPUUniformBuffer **matrices_ubo;
|
||||
struct GPUUniformBuffer **obinfos_ubo;
|
||||
uint ubo_len;
|
||||
} ViewportMemoryPool;
|
||||
|
||||
/* All FramebufferLists are just the same pointers with different names */
|
||||
|
|
|
@ -39,9 +39,8 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
static void batch_update_program_bindings(GPUBatch *batch, uint i_first);
|
||||
static void batch_update_program_bindings(GPUBatch *batch, uint v_first);
|
||||
|
||||
void GPU_batch_vao_cache_clear(GPUBatch *batch)
|
||||
{
|
||||
|
@ -447,51 +446,20 @@ static void create_bindings(GPUVertBuf *verts,
|
|||
}
|
||||
}
|
||||
|
||||
static void instance_id_workaround(GPUBatch *batch)
|
||||
{
|
||||
/**
|
||||
* A driver bug make it so that when using an attribute with GL_INT_2_10_10_10_REV as format,
|
||||
* the gl_InstanceID is incremented by the 2 bit component of the attrib. To workaround this,
|
||||
* we create a new vertex attrib containing the expected value of gl_InstanceID.
|
||||
**/
|
||||
const GPUShaderInput *input = GPU_shaderinterface_attr(batch->interface, "_instanceId");
|
||||
if (input) {
|
||||
#define DRW_RESOURCE_CHUNK_LEN 512 /* Keep in sync. */
|
||||
static GLint vbo_id = 0;
|
||||
if (vbo_id == 0) {
|
||||
short data[DRW_RESOURCE_CHUNK_LEN];
|
||||
for (int i = 0; i < DRW_RESOURCE_CHUNK_LEN; i++) {
|
||||
data[i] = i;
|
||||
}
|
||||
/* GPU_context takes care of deleting `vbo_id` at the end. */
|
||||
vbo_id = GPU_buf_alloc();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
|
||||
}
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
glEnableVertexAttribArray(input->location);
|
||||
glVertexAttribIPointer(input->location, 1, GL_SHORT, 0, NULL);
|
||||
glVertexAttribDivisor(input->location, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void batch_update_program_bindings(GPUBatch *batch, uint i_first)
|
||||
static void batch_update_program_bindings(GPUBatch *batch, uint v_first)
|
||||
{
|
||||
/* Reverse order so first vbos have more prevalence (in term of attrib override). */
|
||||
for (int v = GPU_BATCH_VBO_MAX_LEN - 1; v > -1; v--) {
|
||||
if (batch->verts[v] != NULL) {
|
||||
create_bindings(batch->verts[v], batch->interface, 0, false);
|
||||
create_bindings(batch->verts[v], batch->interface, (batch->inst) ? 0 : v_first, false);
|
||||
}
|
||||
}
|
||||
if (batch->inst) {
|
||||
create_bindings(batch->inst, batch->interface, i_first, true);
|
||||
create_bindings(batch->inst, batch->interface, v_first, true);
|
||||
}
|
||||
if (batch->elem) {
|
||||
GPU_indexbuf_use(batch->elem);
|
||||
}
|
||||
if (GPU_crappy_amd_driver()) {
|
||||
instance_id_workaround(batch);
|
||||
}
|
||||
}
|
||||
|
||||
void GPU_batch_program_use_begin(GPUBatch *batch)
|
||||
|
@ -650,14 +618,6 @@ void GPU_batch_draw(GPUBatch *batch)
|
|||
GPU_batch_program_use_end(batch);
|
||||
}
|
||||
|
||||
#if GPU_TRACK_INDEX_RANGE
|
||||
# define BASE_INDEX(el) ((el)->base_index)
|
||||
# define INDEX_TYPE(el) ((el)->gl_index_type)
|
||||
#else
|
||||
# define BASE_INDEX(el) 0
|
||||
# define INDEX_TYPE(el) GL_UNSIGNED_INT
|
||||
#endif
|
||||
|
||||
void GPU_batch_draw_advanced(GPUBatch *batch, int v_first, int v_count, int i_first, int i_count)
|
||||
{
|
||||
#if TRUST_NO_ONE
|
||||
|
@ -672,13 +632,8 @@ void GPU_batch_draw_advanced(GPUBatch *batch, int v_first, int v_count, int i_fi
|
|||
i_count = (batch->inst) ? batch->inst->vertex_len : 1;
|
||||
}
|
||||
|
||||
if (v_count == 0 || i_count == 0) {
|
||||
/* Nothing to draw. */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GPU_arb_base_instance_is_supported()) {
|
||||
if (i_first > 0) {
|
||||
if (i_first > 0 && i_count > 0) {
|
||||
/* If using offset drawing with instancing, we must
|
||||
* use the default VAO and redo bindings. */
|
||||
glBindVertexArray(GPU_vao_default());
|
||||
|
@ -693,8 +648,13 @@ void GPU_batch_draw_advanced(GPUBatch *batch, int v_first, int v_count, int i_fi
|
|||
|
||||
if (batch->elem) {
|
||||
const GPUIndexBuf *el = batch->elem;
|
||||
GLenum index_type = INDEX_TYPE(el);
|
||||
GLint base_index = BASE_INDEX(el);
|
||||
#if GPU_TRACK_INDEX_RANGE
|
||||
GLenum index_type = el->gl_index_type;
|
||||
GLint base_index = el->base_index;
|
||||
#else
|
||||
GLenum index_type = GL_UNSIGNED_INT;
|
||||
GLint base_index = 0;
|
||||
#endif
|
||||
void *v_first_ofs = elem_offset(el, v_first);
|
||||
|
||||
if (GPU_arb_base_instance_is_supported()) {
|
||||
|
@ -736,179 +696,6 @@ void GPU_draw_primitive(GPUPrimType prim_type, int v_count)
|
|||
// glBindVertexArray(0);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Indirect Draw Calls
|
||||
* \{ */
|
||||
|
||||
#if 0
|
||||
# define USE_MULTI_DRAW_INDIRECT 0
|
||||
#else
|
||||
# define USE_MULTI_DRAW_INDIRECT \
|
||||
(GL_ARB_multi_draw_indirect && GPU_arb_base_instance_is_supported())
|
||||
#endif
|
||||
|
||||
typedef struct GPUDrawCommand {
|
||||
uint v_count;
|
||||
uint i_count;
|
||||
uint v_first;
|
||||
uint i_first;
|
||||
} GPUDrawCommand;
|
||||
|
||||
typedef struct GPUDrawCommandIndexed {
|
||||
uint v_count;
|
||||
uint i_count;
|
||||
uint v_first;
|
||||
uint base_index;
|
||||
uint i_first;
|
||||
} GPUDrawCommandIndexed;
|
||||
|
||||
struct GPUDrawList {
|
||||
GPUBatch *batch;
|
||||
uint base_index; /* Avoid dereferencing batch. */
|
||||
uint cmd_offset; /* in bytes, offset inside indirect command buffer. */
|
||||
uint cmd_len; /* Number of used command for the next call. */
|
||||
uint buffer_size; /* in bytes, size of indirect command buffer. */
|
||||
GLuint buffer_id; /* Draw Indirect Buffer id */
|
||||
union {
|
||||
GPUDrawCommand *commands;
|
||||
GPUDrawCommandIndexed *commands_indexed;
|
||||
};
|
||||
};
|
||||
|
||||
GPUDrawList *GPU_draw_list_create(int length)
|
||||
{
|
||||
GPUDrawList *list = MEM_callocN(sizeof(GPUDrawList), "GPUDrawList");
|
||||
/* Alloc the biggest possible command list which is indexed. */
|
||||
list->buffer_size = sizeof(GPUDrawCommandIndexed) * length;
|
||||
if (USE_MULTI_DRAW_INDIRECT) {
|
||||
list->buffer_id = GPU_buf_alloc();
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, list->buffer_id);
|
||||
glBufferData(GL_DRAW_INDIRECT_BUFFER, list->buffer_size, NULL, GL_DYNAMIC_DRAW);
|
||||
}
|
||||
else {
|
||||
list->commands = MEM_mallocN(list->buffer_size, "GPUDrawList data");
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
void GPU_draw_list_discard(GPUDrawList *list)
|
||||
{
|
||||
if (list->buffer_id) {
|
||||
GPU_buf_free(list->buffer_id);
|
||||
}
|
||||
else {
|
||||
MEM_SAFE_FREE(list->commands);
|
||||
}
|
||||
MEM_freeN(list);
|
||||
}
|
||||
|
||||
void GPU_draw_list_init(GPUDrawList *list, GPUBatch *batch)
|
||||
{
|
||||
BLI_assert(batch->phase == GPU_BATCH_READY_TO_DRAW);
|
||||
list->batch = batch;
|
||||
list->base_index = batch->elem ? BASE_INDEX(batch->elem) : UINT_MAX;
|
||||
list->cmd_len = 0;
|
||||
|
||||
if (USE_MULTI_DRAW_INDIRECT) {
|
||||
if (list->commands == NULL) {
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, list->buffer_id);
|
||||
if (list->cmd_offset >= list->buffer_size) {
|
||||
/* Orphan buffer data and start fresh. */
|
||||
glBufferData(GL_DRAW_INDIRECT_BUFFER, list->buffer_size, NULL, GL_DYNAMIC_DRAW);
|
||||
list->cmd_offset = 0;
|
||||
}
|
||||
GLenum flags = GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_FLUSH_EXPLICIT_BIT;
|
||||
list->commands = glMapBufferRange(
|
||||
GL_DRAW_INDIRECT_BUFFER, list->cmd_offset, list->buffer_size - list->cmd_offset, flags);
|
||||
}
|
||||
}
|
||||
else {
|
||||
list->cmd_offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void GPU_draw_list_command_add(
|
||||
GPUDrawList *list, int v_first, int v_count, int i_first, int i_count)
|
||||
{
|
||||
BLI_assert(list->commands);
|
||||
|
||||
if (list->base_index != UINT_MAX) {
|
||||
GPUDrawCommandIndexed *cmd = list->commands_indexed + list->cmd_len;
|
||||
cmd->v_first = v_first;
|
||||
cmd->v_count = v_count;
|
||||
cmd->i_count = i_count;
|
||||
cmd->base_index = list->base_index;
|
||||
cmd->i_first = i_first;
|
||||
}
|
||||
else {
|
||||
GPUDrawCommand *cmd = list->commands + list->cmd_len;
|
||||
cmd->v_first = v_first;
|
||||
cmd->v_count = v_count;
|
||||
cmd->i_count = i_count;
|
||||
cmd->i_first = i_first;
|
||||
}
|
||||
|
||||
list->cmd_len++;
|
||||
uint offset = list->cmd_offset + list->cmd_len * sizeof(GPUDrawCommandIndexed);
|
||||
|
||||
if (offset == list->buffer_size) {
|
||||
GPU_draw_list_submit(list);
|
||||
GPU_draw_list_init(list, list->batch);
|
||||
}
|
||||
}
|
||||
|
||||
void GPU_draw_list_submit(GPUDrawList *list)
|
||||
{
|
||||
GPUBatch *batch = list->batch;
|
||||
|
||||
if (list->cmd_len == 0)
|
||||
return;
|
||||
|
||||
BLI_assert(list->commands);
|
||||
BLI_assert(batch->program_in_use);
|
||||
/* TODO could assert that VAO is bound. */
|
||||
|
||||
/* TODO We loose a bit of memory here if we only draw arrays. Fix that. */
|
||||
uintptr_t offset = list->cmd_offset;
|
||||
uint cmd_len = list->cmd_len;
|
||||
size_t bytes_used = cmd_len * sizeof(GPUDrawCommandIndexed);
|
||||
list->cmd_offset += bytes_used;
|
||||
list->cmd_len = 0; /* Avoid reuse. */
|
||||
|
||||
if (USE_MULTI_DRAW_INDIRECT) {
|
||||
GLenum prim = batch->gl_prim_type;
|
||||
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, list->buffer_id);
|
||||
glFlushMappedBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, bytes_used);
|
||||
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
|
||||
list->commands = NULL; /* Unmapped */
|
||||
|
||||
if (batch->elem) {
|
||||
glMultiDrawElementsIndirect(prim, INDEX_TYPE(batch->elem), (void *)offset, cmd_len, 0);
|
||||
}
|
||||
else {
|
||||
glMultiDrawArraysIndirect(prim, (void *)offset, cmd_len, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Fallback */
|
||||
if (batch->elem) {
|
||||
GPUDrawCommandIndexed *cmd = list->commands_indexed;
|
||||
for (int i = 0; i < cmd_len; i++, cmd++) {
|
||||
GPU_batch_draw_advanced(batch, cmd->v_first, cmd->v_count, cmd->i_first, cmd->i_count);
|
||||
}
|
||||
}
|
||||
else {
|
||||
GPUDrawCommand *cmd = list->commands;
|
||||
for (int i = 0; i < cmd_len; i++, cmd++) {
|
||||
GPU_batch_draw_advanced(batch, cmd->v_first, cmd->v_count, cmd->i_first, cmd->i_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Utilities
|
||||
* \{ */
|
||||
|
|
|
@ -55,12 +55,6 @@
|
|||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
extern char datatoc_gpu_shader_material_glsl[];
|
||||
extern char datatoc_gpu_shader_geometry_glsl[];
|
||||
|
||||
extern char datatoc_gpu_shader_common_obinfos_lib_glsl[];
|
||||
extern char datatoc_common_view_lib_glsl[];
|
||||
|
||||
/* -------------------- GPUPass Cache ------------------ */
|
||||
/**
|
||||
* Internal shader cache: This prevent the shader recompilation / stall when
|
||||
|
@ -784,12 +778,6 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final
|
|||
else if (input->builtin == GPU_OBJECT_MATRIX) {
|
||||
BLI_dynstr_append(ds, "objmat");
|
||||
}
|
||||
else if (input->builtin == GPU_OBJECT_INFO) {
|
||||
BLI_dynstr_append(ds, "ObjectInfo");
|
||||
}
|
||||
else if (input->builtin == GPU_OBJECT_COLOR) {
|
||||
BLI_dynstr_append(ds, "ObjectColor");
|
||||
}
|
||||
else if (input->builtin == GPU_INVERSE_OBJECT_MATRIX) {
|
||||
BLI_dynstr_append(ds, "objinv");
|
||||
}
|
||||
|
@ -852,10 +840,6 @@ static char *code_generate_fragment(GPUMaterial *material,
|
|||
codegen_set_unique_ids(nodes);
|
||||
*rbuiltins = builtins = codegen_process_uniforms_functions(material, ds, nodes);
|
||||
|
||||
if (builtins & (GPU_OBJECT_INFO | GPU_OBJECT_COLOR)) {
|
||||
BLI_dynstr_append(ds, datatoc_gpu_shader_common_obinfos_lib_glsl);
|
||||
}
|
||||
|
||||
if (builtins & GPU_BARYCENTRIC_TEXCO) {
|
||||
BLI_dynstr_append(ds, "in vec2 barycentricTexCo;\n");
|
||||
}
|
||||
|
@ -1004,7 +988,7 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
|
|||
/* NOTE : Replicate changes to mesh_render_data_create() in draw_cache_impl_mesh.c */
|
||||
if (input->attr_type == CD_ORCO) {
|
||||
/* OPTI : orco is computed from local positions, but only if no modifier is present. */
|
||||
BLI_dynstr_append(ds, datatoc_gpu_shader_common_obinfos_lib_glsl);
|
||||
BLI_dynstr_append(ds, "uniform vec3 OrcoTexCoFactors[2];\n");
|
||||
BLI_dynstr_append(ds, "DEFINE_ATTR(vec4, orco);\n");
|
||||
}
|
||||
else if (input->attr_name[0] == '\0') {
|
||||
|
@ -1086,8 +1070,6 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
|
|||
|
||||
BLI_dynstr_append(ds, "\n");
|
||||
|
||||
BLI_dynstr_append(ds, use_geom ? "RESOURCE_ID_VARYING_GEOM\n" : "RESOURCE_ID_VARYING\n");
|
||||
|
||||
BLI_dynstr_append(ds,
|
||||
"#define USE_ATTR\n"
|
||||
"vec3 srgb_to_linear_attr(vec3 c) {\n"
|
||||
|
@ -1117,8 +1099,6 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
|
|||
|
||||
BLI_dynstr_append(ds, "void pass_attr(in vec3 position) {\n");
|
||||
|
||||
BLI_dynstr_append(ds, use_geom ? "\tPASS_RESOURCE_ID_GEOM\n" : "\tPASS_RESOURCE_ID\n");
|
||||
|
||||
BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
|
||||
|
||||
if (builtins & GPU_BARYCENTRIC_TEXCO) {
|
||||
|
@ -1145,8 +1125,8 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
|
|||
}
|
||||
else if (input->attr_type == CD_ORCO) {
|
||||
BLI_dynstr_appendf(ds,
|
||||
"\tvar%d%s = OrcoTexCoFactors[0].xyz + (ModelMatrixInverse * "
|
||||
"vec4(hair_get_strand_pos(), 1.0)).xyz * OrcoTexCoFactors[1].xyz;\n",
|
||||
"\tvar%d%s = OrcoTexCoFactors[0] + (ModelMatrixInverse * "
|
||||
"vec4(hair_get_strand_pos(), 1.0)).xyz * OrcoTexCoFactors[1];\n",
|
||||
input->attr_id,
|
||||
use_geom ? "g" : "");
|
||||
/* TODO: fix ORCO with modifiers. */
|
||||
|
@ -1201,8 +1181,7 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
|
|||
}
|
||||
else if (input->attr_type == CD_ORCO) {
|
||||
BLI_dynstr_appendf(ds,
|
||||
"\tvar%d%s = OrcoTexCoFactors[0].xyz + position *"
|
||||
" OrcoTexCoFactors[1].xyz;\n",
|
||||
"\tvar%d%s = OrcoTexCoFactors[0] + position * OrcoTexCoFactors[1];\n",
|
||||
input->attr_id,
|
||||
use_geom ? "g" : "");
|
||||
/* See mesh_create_loop_orco() for explanation. */
|
||||
|
@ -1317,8 +1296,6 @@ static char *code_generate_geometry(ListBase *nodes, const char *geom_code, cons
|
|||
BLI_dynstr_append(ds, "out vec3 worldNormal;\n");
|
||||
BLI_dynstr_append(ds, "out vec3 viewNormal;\n");
|
||||
|
||||
BLI_dynstr_append(ds, datatoc_common_view_lib_glsl);
|
||||
|
||||
BLI_dynstr_append(ds, "void main(){\n");
|
||||
|
||||
if (builtins & GPU_BARYCENTRIC_DIST) {
|
||||
|
@ -1363,13 +1340,9 @@ static char *code_generate_geometry(ListBase *nodes, const char *geom_code, cons
|
|||
BLI_dynstr_append(ds, "}\n");
|
||||
}
|
||||
|
||||
BLI_dynstr_append(ds, "RESOURCE_ID_VARYING\n");
|
||||
|
||||
/* Generate varying assignments. */
|
||||
BLI_dynstr_append(ds, "void pass_attr(in int vert) {\n");
|
||||
|
||||
BLI_dynstr_append(ds, "\tPASS_RESOURCE_ID(vert)\n");
|
||||
|
||||
/* XXX HACK: Eevee specific. */
|
||||
if (geom_code == NULL) {
|
||||
BLI_dynstr_append(ds, "\tworldPosition = worldPositiong[vert];\n");
|
||||
|
|
|
@ -248,9 +248,6 @@ static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH])
|
|||
/* a #version 400 feature, but we use #version 330 maximum so use extension */
|
||||
strcat(defines, "#extension GL_ARB_texture_query_lod: enable\n");
|
||||
}
|
||||
if (GLEW_ARB_shader_draw_parameters) {
|
||||
strcat(defines, "#extension GL_ARB_shader_draw_parameters : enable\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH])
|
||||
|
@ -258,9 +255,6 @@ static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH])
|
|||
/* some useful defines to detect GPU type */
|
||||
if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)) {
|
||||
strcat(defines, "#define GPU_ATI\n");
|
||||
if (GPU_crappy_amd_driver()) {
|
||||
strcat(defines, "#define GPU_CRAPPY_AMD_DRIVER\n");
|
||||
}
|
||||
}
|
||||
else if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY)) {
|
||||
strcat(defines, "#define GPU_NVIDIA\n");
|
||||
|
|
|
@ -65,8 +65,9 @@ static const char *BuiltinUniform_name(GPUUniformBuiltin u)
|
|||
[GPU_UNIFORM_CLIPPLANES] = "WorldClipPlanes",
|
||||
|
||||
[GPU_UNIFORM_COLOR] = "color",
|
||||
[GPU_UNIFORM_BASE_INSTANCE] = "baseInstance",
|
||||
[GPU_UNIFORM_RESOURCE_CHUNK] = "resourceChunk",
|
||||
[GPU_UNIFORM_CALLID] = "callId",
|
||||
[GPU_UNIFORM_OBJECT_INFO] = "unfobjectinfo",
|
||||
[GPU_UNIFORM_OBJECT_COLOR] = "unfobjectcolor",
|
||||
|
||||
[GPU_UNIFORM_CUSTOM] = NULL,
|
||||
[GPU_NUM_UNIFORMS] = NULL,
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
#include "GPU_immediate.h"
|
||||
#include "GPU_texture.h"
|
||||
#include "GPU_viewport.h"
|
||||
#include "GPU_uniformbuffer.h"
|
||||
|
||||
#include "DRW_engine.h"
|
||||
|
||||
|
@ -620,20 +619,11 @@ void GPU_viewport_free(GPUViewport *viewport)
|
|||
MEM_freeN(viewport->fbl);
|
||||
MEM_freeN(viewport->txl);
|
||||
|
||||
if (viewport->vmempool.commands != NULL) {
|
||||
BLI_memblock_destroy(viewport->vmempool.commands, NULL);
|
||||
if (viewport->vmempool.calls != NULL) {
|
||||
BLI_memblock_destroy(viewport->vmempool.calls, NULL);
|
||||
}
|
||||
if (viewport->vmempool.commands_small != NULL) {
|
||||
BLI_memblock_destroy(viewport->vmempool.commands_small, NULL);
|
||||
}
|
||||
if (viewport->vmempool.callbuffers != NULL) {
|
||||
BLI_memblock_destroy(viewport->vmempool.callbuffers, NULL);
|
||||
}
|
||||
if (viewport->vmempool.obmats != NULL) {
|
||||
BLI_memblock_destroy(viewport->vmempool.obmats, NULL);
|
||||
}
|
||||
if (viewport->vmempool.obinfos != NULL) {
|
||||
BLI_memblock_destroy(viewport->vmempool.obinfos, NULL);
|
||||
if (viewport->vmempool.states != NULL) {
|
||||
BLI_memblock_destroy(viewport->vmempool.states, NULL);
|
||||
}
|
||||
if (viewport->vmempool.cullstates != NULL) {
|
||||
BLI_memblock_destroy(viewport->vmempool.cullstates, NULL);
|
||||
|
@ -660,13 +650,6 @@ void GPU_viewport_free(GPUViewport *viewport)
|
|||
BLI_memblock_destroy(viewport->vmempool.images, NULL);
|
||||
}
|
||||
|
||||
for (int i = 0; i < viewport->vmempool.ubo_len; i++) {
|
||||
GPU_uniformbuffer_free(viewport->vmempool.matrices_ubo[i]);
|
||||
GPU_uniformbuffer_free(viewport->vmempool.obinfos_ubo[i]);
|
||||
}
|
||||
MEM_SAFE_FREE(viewport->vmempool.matrices_ubo);
|
||||
MEM_SAFE_FREE(viewport->vmempool.obinfos_ubo);
|
||||
|
||||
DRW_instance_data_list_free(viewport->idatalist);
|
||||
MEM_freeN(viewport->idatalist);
|
||||
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
|
||||
/* Need to be included after common_view_lib.glsl for resource_id. */
|
||||
#ifndef GPU_OBINFOS_UBO
|
||||
#define GPU_OBINFOS_UBO
|
||||
struct ObjectInfos {
|
||||
vec4 drw_OrcoTexCoFactors[2];
|
||||
vec4 drw_ObjectColor;
|
||||
vec4 drw_Infos;
|
||||
};
|
||||
|
||||
layout(std140) uniform infoBlock
|
||||
{
|
||||
/* DRW_RESOURCE_CHUNK_LEN = 512 */
|
||||
ObjectInfos drw_infos[512];
|
||||
};
|
||||
#define OrcoTexCoFactors (drw_infos[resource_id].drw_OrcoTexCoFactors)
|
||||
#define ObjectInfo (drw_infos[resource_id].drw_Infos)
|
||||
#define ObjectColor (drw_infos[resource_id].drw_ObjectColor)
|
||||
#endif
|
|
@ -1,5 +1,8 @@
|
|||
|
||||
uniform mat4 ViewProjectionMatrix;
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
uniform mat4 ModelMatrix;
|
||||
#endif
|
||||
|
||||
/* ---- Instantiated Attrs ---- */
|
||||
in float pos;
|
||||
|
@ -44,12 +47,11 @@ void main()
|
|||
pPos = vec3(0.0);
|
||||
}
|
||||
|
||||
vec4 wPos = InstanceModelMatrix * vec4(pPos, 1.0);
|
||||
gl_Position = ViewProjectionMatrix * wPos;
|
||||
gl_Position = ViewProjectionMatrix * InstanceModelMatrix * vec4(pPos, 1.0);
|
||||
|
||||
finalColor = vec4(color, 1.0);
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(wPos.xyz);
|
||||
world_clip_planes_calc_clip_distance((ModelMatrix * InstanceModelMatrix * vec4(pPos, 1.0)).xyz);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -18,14 +18,13 @@ void main()
|
|||
{
|
||||
float len = end - start;
|
||||
vec3 sta = vec3(0.0, 0.0, -start);
|
||||
vec4 pos_4d = vec4(pos * -len + sta, 1.0);
|
||||
|
||||
vec4 wPos = InstanceModelMatrix * vec4(pos * -len + sta, 1.0);
|
||||
|
||||
gl_Position = ViewProjectionMatrix * wPos;
|
||||
gl_Position = ViewProjectionMatrix * InstanceModelMatrix * pos_4d;
|
||||
gl_PointSize = size;
|
||||
finalColor = vec4(color, 1.0);
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(wPos.xyz);
|
||||
world_clip_planes_calc_clip_distance((InstanceModelMatrix * pos_4d).xyz);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
uniform mat4 ViewProjectionMatrix;
|
||||
uniform mat4 ModelMatrix;
|
||||
|
||||
/* ---- Instantiated Attrs ---- */
|
||||
in vec3 pos;
|
||||
|
@ -19,10 +20,10 @@ void main()
|
|||
{
|
||||
finalColor = color;
|
||||
|
||||
vec4 wPos = InstanceModelMatrix * vec4(pos * size, 1.0);
|
||||
gl_Position = ViewProjectionMatrix * wPos;
|
||||
vec4 pos_4d = vec4(pos * size, 1.0);
|
||||
gl_Position = ViewProjectionMatrix * InstanceModelMatrix * pos_4d;
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(wPos.xyz);
|
||||
world_clip_planes_calc_clip_distance((ModelMatrix * InstanceModelMatrix * pos_4d).xyz);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
|
||||
uniform mat4 ViewProjectionMatrix;
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
uniform mat4 ModelMatrix;
|
||||
#endif
|
||||
uniform int baseId;
|
||||
|
||||
/* ---- Instantiated Attrs ---- */
|
||||
|
@ -19,11 +21,11 @@ flat out uint finalId;
|
|||
|
||||
void main()
|
||||
{
|
||||
vec4 wPos = InstanceModelMatrix * vec4(pos * size, 1.0);
|
||||
gl_Position = ViewProjectionMatrix * wPos;
|
||||
vec4 pos_4d = vec4(pos * size, 1.0);
|
||||
gl_Position = ViewProjectionMatrix * InstanceModelMatrix * pos_4d;
|
||||
finalId = uint(baseId + callId);
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(wPos.xyz);
|
||||
world_clip_planes_calc_clip_distance((ModelMatrix * InstanceModelMatrix * pos_4d).xyz);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -9,5 +9,5 @@ in mat4 InstanceModelMatrix;
|
|||
|
||||
void main()
|
||||
{
|
||||
gl_Position = ViewProjectionMatrix * (InstanceModelMatrix * vec4(pos, 1.0));
|
||||
gl_Position = ViewProjectionMatrix * InstanceModelMatrix * vec4(pos, 1.0);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue