DRW: Put all view-only dependant uniform in a UBO.

This leads to less lookups to the GWNShaderInterface and less uniform upload.

We still keep a legacy path so that Builtin uniforms can still work. We might restrict this path to Builtin shader only in the future.
This commit is contained in:
Clément Foucault 2018-03-09 19:52:37 +01:00
parent 4540bd226d
commit 8444aaaa69
7 changed files with 76 additions and 37 deletions

View File

@ -203,6 +203,7 @@ data_to_c_simple(engines/eevee/shaders/volumetric_scatter_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/volumetric_integration_frag.glsl SRC)
data_to_c_simple(modes/shaders/common_globals_lib.glsl SRC)
data_to_c_simple(modes/shaders/common_view_lib.glsl SRC)
data_to_c_simple(modes/shaders/common_fxaa_lib.glsl SRC)
data_to_c_simple(modes/shaders/edit_mesh_overlay_frag.glsl SRC)
data_to_c_simple(modes/shaders/edit_mesh_overlay_vert.glsl SRC)

View File

@ -413,7 +413,7 @@ typedef enum {
DRW_MAT_COUNT, // Don't use this.
} DRWViewportMatrixType;
typedef struct DRWMatrixState{
typedef struct DRWMatrixState {
float mat[DRW_MAT_COUNT][4][4];
} DRWMatrixState;

View File

@ -90,6 +90,8 @@ DRWManager DST = {NULL};
ListBase DRW_engines = {NULL, NULL};
extern struct GPUUniformBuffer *view_ubo; /* draw_manager_exec.c */
/* -------------------------------------------------------------------- */
void DRW_draw_callbacks_pre_scene(void)
@ -437,8 +439,12 @@ static void drw_viewport_var_init(void)
DST.RST.bound_tex_slots = MEM_callocN(sizeof(bool) * GPU_max_textures(), "Bound Texture Slots");
}
if (view_ubo == NULL) {
view_ubo = DRW_uniformbuffer_create(sizeof(ViewUboStorage), NULL);
}
DST.override_mat = 0;
DST.dirty_mat = false;
DST.dirty_mat = true;
DST.state_cache_id = 1;
DST.clipping.updated = false;
@ -1936,6 +1942,7 @@ void DRW_engines_free(void)
}
DRW_UBO_FREE_SAFE(globals_ubo);
DRW_UBO_FREE_SAFE(view_ubo);
DRW_TEXTURE_FREE_SAFE(globals_ramp);
MEM_SAFE_FREE(g_pos_format);

View File

@ -246,6 +246,12 @@ struct DRWPass {
char name[MAX_PASS_NAME];
};
typedef struct ViewUboStorage {
DRWMatrixState matstate;
float viewcamtexcofac[4];
float clipplanes[2][4];
} ViewUboStorage;
/* ------------- DRAW MANAGER ------------ */
#define MAX_CLIP_PLANES 6 /* GL_MAX_CLIP_PLANES is at least 6 */
@ -304,11 +310,8 @@ typedef struct DRWManager {
int num_clip_planes; /* Number of active clipplanes. */
bool dirty_mat;
struct {
DRWMatrixState matstate;
float viewcamtexcofac[4];
float clip_planes_eq[MAX_CLIP_PLANES][4];
} view_data;
/* keep in sync with viewBlock */
ViewUboStorage view_data;
struct {
float frustum_planes[6][4];

View File

@ -43,6 +43,8 @@
struct Gwn_VertFormat *g_pos_format = NULL;
extern struct GPUUniformBuffer *view_ubo; /* draw_manager_exec.c */
/* -------------------------------------------------------------------- */
/** \name Uniform Buffer Object (DRW_uniformbuffer)
@ -70,17 +72,12 @@ void DRW_uniformbuffer_free(GPUUniformBuffer *ubo)
/** \name Uniforms (DRW_shgroup_uniform)
* \{ */
static void drw_interface_builtin_uniform(
DRWShadingGroup *shgroup, int builtin, const void *value, int length, int arraysize)
static void drw_interface_uniform_create_ex(DRWShadingGroup *shgroup, int loc,
DRWUniformType type, const void *value, int length, int arraysize)
{
int loc = GPU_shader_get_builtin_uniform(shgroup->shader, builtin);
if (loc == -1)
return;
DRWUniform *uni = BLI_mempool_alloc(DST.vmempool->uniforms);
uni->location = loc;
uni->type = DRW_UNIFORM_FLOAT;
uni->type = type;
uni->value = value;
uni->length = length;
uni->arraysize = arraysize;
@ -88,6 +85,16 @@ static void drw_interface_builtin_uniform(
BLI_LINKS_PREPEND(shgroup->uniforms, uni);
}
static void drw_interface_builtin_uniform(
DRWShadingGroup *shgroup, int builtin, const void *value, int length, int arraysize)
{
int loc = GPU_shader_get_builtin_uniform(shgroup->shader, builtin);
if (loc != -1) {
drw_interface_uniform_create_ex(shgroup, loc, DRW_UNIFORM_FLOAT, value, length, arraysize);
}
}
static void drw_interface_uniform(DRWShadingGroup *shgroup, const char *name,
DRWUniformType type, const void *value, int length, int arraysize)
{
@ -107,18 +114,10 @@ static void drw_interface_uniform(DRWShadingGroup *shgroup, const char *name,
return;
}
DRWUniform *uni = BLI_mempool_alloc(DST.vmempool->uniforms);
BLI_assert(arraysize > 0 && arraysize <= 16);
BLI_assert(length >= 0 && length <= 16);
uni->location = location;
uni->type = type;
uni->value = value;
uni->length = length;
uni->arraysize = arraysize;
BLI_LINKS_PREPEND(shgroup->uniforms, uni);
drw_interface_uniform_create_ex(shgroup, location, type, value, length, arraysize);
}
void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex)
@ -457,15 +456,21 @@ static void drw_interface_init(DRWShadingGroup *shgroup, GPUShader *shader)
shgroup->attribs_count = 0;
#endif
/* TODO : They should be grouped inside a UBO updated once per redraw. */
drw_interface_builtin_uniform(shgroup, GWN_UNIFORM_VIEW, DST.view_data.matstate.mat[DRW_MAT_VIEW], 16, 1);
drw_interface_builtin_uniform(shgroup, GWN_UNIFORM_VIEW_INV, DST.view_data.matstate.mat[DRW_MAT_VIEWINV], 16, 1);
drw_interface_builtin_uniform(shgroup, GWN_UNIFORM_VIEWPROJECTION, DST.view_data.matstate.mat[DRW_MAT_PERS], 16, 1);
drw_interface_builtin_uniform(shgroup, GWN_UNIFORM_VIEWPROJECTION_INV, DST.view_data.matstate.mat[DRW_MAT_PERSINV], 16, 1);
drw_interface_builtin_uniform(shgroup, GWN_UNIFORM_PROJECTION, DST.view_data.matstate.mat[DRW_MAT_WIN], 16, 1);
drw_interface_builtin_uniform(shgroup, GWN_UNIFORM_PROJECTION_INV, DST.view_data.matstate.mat[DRW_MAT_WININV], 16, 1);
drw_interface_builtin_uniform(shgroup, GWN_UNIFORM_CAMERATEXCO, DST.view_data.viewcamtexcofac, 3, 2);
drw_interface_builtin_uniform(shgroup, GWN_UNIFORM_CLIPPLANES, DST.view_data.clip_planes_eq, 4, DST.num_clip_planes); /* TO REMOVE */
int view_ubo_location = GPU_shader_get_uniform_block(shader, "viewBlock");
if (view_ubo_location != -1) {
drw_interface_uniform_create_ex(shgroup, view_ubo_location, DRW_UNIFORM_BLOCK, view_ubo, 0, 1);
}
else {
/* Only here to support builtin shaders. This should not be used by engines. */
drw_interface_builtin_uniform(shgroup, GWN_UNIFORM_VIEW, DST.view_data.matstate.mat[DRW_MAT_VIEW], 16, 1);
drw_interface_builtin_uniform(shgroup, GWN_UNIFORM_VIEW_INV, DST.view_data.matstate.mat[DRW_MAT_VIEWINV], 16, 1);
drw_interface_builtin_uniform(shgroup, GWN_UNIFORM_VIEWPROJECTION, DST.view_data.matstate.mat[DRW_MAT_PERS], 16, 1);
drw_interface_builtin_uniform(shgroup, GWN_UNIFORM_VIEWPROJECTION_INV, DST.view_data.matstate.mat[DRW_MAT_PERSINV], 16, 1);
drw_interface_builtin_uniform(shgroup, GWN_UNIFORM_PROJECTION, DST.view_data.matstate.mat[DRW_MAT_WIN], 16, 1);
drw_interface_builtin_uniform(shgroup, GWN_UNIFORM_PROJECTION_INV, DST.view_data.matstate.mat[DRW_MAT_WININV], 16, 1);
drw_interface_builtin_uniform(shgroup, GWN_UNIFORM_CAMERATEXCO, DST.view_data.viewcamtexcofac, 3, 2);
}
shgroup->model = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_MODEL);
shgroup->modelinverse = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_MODEL_INV);

View File

@ -49,6 +49,8 @@ void DRW_select_load_id(unsigned int id)
}
#endif
struct GPUUniformBuffer *view_ubo;
/* -------------------------------------------------------------------- */
/** \name Draw State (DRW_state)
@ -367,7 +369,7 @@ void DRW_state_invert_facing(void)
void DRW_state_clip_planes_add(float plane_eq[4])
{
BLI_assert(DST.num_clip_planes < MAX_CLIP_PLANES-1);
copy_v4_v4(DST.view_data.clip_planes_eq[DST.num_clip_planes++], plane_eq);
// copy_v4_v4(DST.view_data.clip_planes_eq[DST.num_clip_planes++], plane_eq);
}
void DRW_state_clip_planes_reset(void)
@ -943,14 +945,14 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
DRW_state_reset();
}
static void drw_draw_pass_ex(DRWPass *pass, DRWShadingGroup *start_group, DRWShadingGroup *end_group)
static void drw_update_view(void)
{
DST.shader = NULL;
if (DST.dirty_mat) {
DST.state_cache_id++;
DST.dirty_mat = false;
DRW_uniformbuffer_update(view_ubo, &DST.view_data);
/* Catch integer wrap around. */
if (UNLIKELY(DST.state_cache_id == 0)) {
DST.state_cache_id = 1;
@ -968,9 +970,16 @@ static void drw_draw_pass_ex(DRWPass *pass, DRWShadingGroup *start_group, DRWSha
}
draw_clipping_setup_from_view();
}
static void drw_draw_pass_ex(DRWPass *pass, DRWShadingGroup *start_group, DRWShadingGroup *end_group)
{
DST.shader = NULL;
BLI_assert(DST.buffer_finish_called && "DRW_render_instance_buffer_finish had not been called before drawing");
drw_update_view();
drw_state_set(pass->state);
DRW_stats_query_start(pass->name);

View File

@ -0,0 +1,14 @@
/* keep in sync with DRWManager.view_data */
layout(std140) uniform viewBlock {
/* Same order as DRWViewportMatrixType */
mat4 ViewProjectionMatrix;
mat4 ViewProjectionMatrixInverse;
mat4 ViewMatrix;
mat4 ViewMatrixInverse;
mat4 ProjectionMatrix;
mat4 ProjectionMatrixInverse;
vec4 CameraTexCoFactors;
vec4 clipPlanes[2];
};