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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2018-07-10 15:40:28 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-07-10 16:31:34 +0300
commitc90a0d5dda535a42697503e130b0c2fc123fe491 (patch)
tree0791abda94c63b54c2255b77ba9fbfee17edbe67 /source/blender/draw
parent873d7f7e14e080f75e75ed7c6c07f326e588cecb (diff)
DRW: Add new features from lightcache branch
- Change gl_context_mutex to a ticket mutex ensuring interactivity even when rendering. - Add DRW_custom_pipeline for using DRW outside of the viewport and render pipeline. - DRW_opengl_render_context_*** and DRW_gawain_render_context_*** to use with DRW_custom_pipeline. - Add possibility to bypass deferred compilation on demand (not User demand). - Add union to access DRWMatrixState members more easily.
Diffstat (limited to 'source/blender/draw')
-rw-r--r--source/blender/draw/DRW_engine.h5
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c29
-rw-r--r--source/blender/draw/intern/DRW_render.h28
-rw-r--r--source/blender/draw/intern/draw_manager.c115
-rw-r--r--source/blender/draw/intern/draw_manager.h2
-rw-r--r--source/blender/draw/intern/draw_manager_shader.c20
6 files changed, 150 insertions, 49 deletions
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index d2a3bab9b20..ab2001dcb6a 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -136,6 +136,11 @@ void DRW_opengl_context_destroy(void);
void DRW_opengl_context_enable(void);
void DRW_opengl_context_disable(void);
+void DRW_opengl_render_context_enable(void *re_gl_context);
+void DRW_opengl_render_context_disable(void *re_gl_context);
+void DRW_gawain_render_context_enable(void *re_gwn_context);
+void DRW_gawain_render_context_disable(void *re_gwn_context);
+
void DRW_deferred_shader_remove(struct GPUMaterial *mat);
struct DrawDataList *DRW_drawdatalist_from_id(struct ID *id);
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 4161d11e0c1..4a7e97756a9 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -654,14 +654,14 @@ struct GPUMaterial *EEVEE_material_world_lightprobe_get(struct Scene *scene, Wor
const void *engine = &DRW_engine_viewport_eevee_type;
const int options = VAR_WORLD_PROBE;
- GPUMaterial *mat = DRW_shader_find_from_world(wo, engine, options);
+ GPUMaterial *mat = DRW_shader_find_from_world(wo, engine, options, false);
if (mat != NULL) {
return mat;
}
return DRW_shader_create_from_world(
scene, wo, engine, options,
datatoc_background_vert_glsl, NULL, e_data.frag_shader_lib,
- SHADER_DEFINES "#define PROBE_CAPTURE\n");
+ SHADER_DEFINES "#define PROBE_CAPTURE\n", false);
}
struct GPUMaterial *EEVEE_material_world_background_get(struct Scene *scene, World *wo)
@@ -669,14 +669,14 @@ struct GPUMaterial *EEVEE_material_world_background_get(struct Scene *scene, Wor
const void *engine = &DRW_engine_viewport_eevee_type;
int options = VAR_WORLD_BACKGROUND;
- GPUMaterial *mat = DRW_shader_find_from_world(wo, engine, options);
+ GPUMaterial *mat = DRW_shader_find_from_world(wo, engine, options, true);
if (mat != NULL) {
return mat;
}
return DRW_shader_create_from_world(
scene, wo, engine, options,
datatoc_background_vert_glsl, NULL, e_data.frag_shader_lib,
- SHADER_DEFINES "#define WORLD_BACKGROUND\n");
+ SHADER_DEFINES "#define WORLD_BACKGROUND\n", true);
}
struct GPUMaterial *EEVEE_material_world_volume_get(struct Scene *scene, World *wo)
@@ -684,7 +684,7 @@ struct GPUMaterial *EEVEE_material_world_volume_get(struct Scene *scene, World *
const void *engine = &DRW_engine_viewport_eevee_type;
int options = VAR_WORLD_VOLUME;
- GPUMaterial *mat = DRW_shader_find_from_world(wo, engine, options);
+ GPUMaterial *mat = DRW_shader_find_from_world(wo, engine, options, true);
if (mat != NULL) {
return mat;
}
@@ -694,7 +694,7 @@ struct GPUMaterial *EEVEE_material_world_volume_get(struct Scene *scene, World *
mat = DRW_shader_create_from_world(
scene, wo, engine, options,
datatoc_volumetric_vert_glsl, datatoc_volumetric_geom_glsl, e_data.volume_shader_lib,
- defines);
+ defines, true);
MEM_freeN(defines);
@@ -719,7 +719,7 @@ struct GPUMaterial *EEVEE_material_mesh_get(
options |= eevee_material_shadow_option(shadow_method);
- GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options);
+ GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options, true);
if (mat) {
return mat;
}
@@ -729,7 +729,7 @@ struct GPUMaterial *EEVEE_material_mesh_get(
mat = DRW_shader_create_from_material(
scene, ma, engine, options,
e_data.vert_shader_str, NULL, e_data.frag_shader_lib,
- defines);
+ defines, true);
MEM_freeN(defines);
@@ -741,7 +741,7 @@ struct GPUMaterial *EEVEE_material_mesh_volume_get(struct Scene *scene, Material
const void *engine = &DRW_engine_viewport_eevee_type;
int options = VAR_MAT_VOLUME;
- GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options);
+ GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options, true);
if (mat != NULL) {
return mat;
}
@@ -751,7 +751,7 @@ struct GPUMaterial *EEVEE_material_mesh_volume_get(struct Scene *scene, Material
mat = DRW_shader_create_from_material(
scene, ma, engine, options,
datatoc_volumetric_vert_glsl, datatoc_volumetric_geom_glsl, e_data.volume_shader_lib,
- defines);
+ defines, true);
MEM_freeN(defines);
@@ -775,7 +775,7 @@ struct GPUMaterial *EEVEE_material_mesh_depth_get(
if (is_shadow)
options |= VAR_MAT_SHADOW;
- GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options);
+ GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options, true);
if (mat) {
return mat;
}
@@ -791,7 +791,8 @@ struct GPUMaterial *EEVEE_material_mesh_depth_get(
(is_shadow) ? datatoc_shadow_vert_glsl : e_data.vert_shader_str,
NULL,
frag_str,
- defines);
+ defines,
+ true);
MEM_freeN(frag_str);
MEM_freeN(defines);
@@ -807,7 +808,7 @@ struct GPUMaterial *EEVEE_material_hair_get(
options |= eevee_material_shadow_option(shadow_method);
- GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options);
+ GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options, true);
if (mat) {
return mat;
}
@@ -817,7 +818,7 @@ struct GPUMaterial *EEVEE_material_hair_get(
mat = DRW_shader_create_from_material(
scene, ma, engine, options,
e_data.vert_shader_str, NULL, e_data.frag_shader_lib,
- defines);
+ defines, true);
MEM_freeN(defines);
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index e0c8cb36e2f..4d1b8269494 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -240,14 +240,14 @@ struct GPUShader *DRW_shader_create_2D(const char *frag, const char *defines);
struct GPUShader *DRW_shader_create_3D(const char *frag, const char *defines);
struct GPUShader *DRW_shader_create_fullscreen(const char *frag, const char *defines);
struct GPUShader *DRW_shader_create_3D_depth_only(void);
-struct GPUMaterial *DRW_shader_find_from_world(struct World *wo, const void *engine_type, int options);
-struct GPUMaterial *DRW_shader_find_from_material(struct Material *ma, const void *engine_type, int options);
+struct GPUMaterial *DRW_shader_find_from_world(struct World *wo, const void *engine_type, int options, bool no_deferred);
+struct GPUMaterial *DRW_shader_find_from_material(struct Material *ma, const void *engine_type, int options, bool no_deferred);
struct GPUMaterial *DRW_shader_create_from_world(
struct Scene *scene, struct World *wo, const void *engine_type, int options,
- const char *vert, const char *geom, const char *frag_lib, const char *defines);
+ const char *vert, const char *geom, const char *frag_lib, const char *defines, bool no_deferred);
struct GPUMaterial *DRW_shader_create_from_material(
struct Scene *scene, struct Material *ma, const void *engine_type, int options,
- const char *vert, const char *geom, const char *frag_lib, const char *defines);
+ const char *vert, const char *geom, const char *frag_lib, const char *defines, bool no_deferred);
void DRW_shader_free(struct GPUShader *shader);
#define DRW_SHADER_FREE_SAFE(shader) do { \
if (shader != NULL) { \
@@ -410,6 +410,7 @@ void DRW_pass_sort_shgroup_z(DRWPass *pass);
/* Viewport */
typedef enum {
+ /* keep in sync with the union struct DRWMatrixState. */
DRW_MAT_PERS = 0,
DRW_MAT_PERSINV,
DRW_MAT_VIEW,
@@ -421,7 +422,18 @@ typedef enum {
} DRWViewportMatrixType;
typedef struct DRWMatrixState {
- float mat[DRW_MAT_COUNT][4][4];
+ union {
+ float mat[DRW_MAT_COUNT][4][4];
+ struct {
+ /* keep in sync with the enum DRWViewportMatrixType. */
+ float persmat[4][4];
+ float persinv[4][4];
+ float viewmat[4][4];
+ float viewinv[4][4];
+ float winmat[4][4];
+ float wininv[4][4];
+ };
+ };
} DRWMatrixState;
void DRW_viewport_init(const bContext *C);
@@ -454,6 +466,12 @@ void DRW_render_object_iter(
void (*callback)(void *vedata, struct Object *ob, struct RenderEngine *engine, struct Depsgraph *depsgraph));
void DRW_render_instance_buffer_finish(void);
+void DRW_custom_pipeline(
+ DrawEngineType *draw_engine_type,
+ struct Depsgraph *depsgraph,
+ void (*callback)(void *vedata, void *user_data),
+ void *user_data);
+
/* ViewLayers */
void *DRW_view_layer_engine_data_get(DrawEngineType *engine_type);
void **DRW_view_layer_engine_data_ensure_ex(
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 311a223dcdd..30f7742fd35 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -1256,7 +1256,7 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
/* XXX Really nasty locking. But else this could
* be executed by the material previews thread
* while rendering a viewport. */
- BLI_mutex_lock(&DST.gl_context_mutex);
+ BLI_ticket_mutex_lock(DST.gl_context_mutex);
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
@@ -1284,7 +1284,7 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
drw_engines_disable();
- BLI_mutex_unlock(&DST.gl_context_mutex);
+ BLI_ticket_mutex_unlock(DST.gl_context_mutex);
}
}
@@ -1554,14 +1554,10 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
/* Changing Context */
if (re_gl_context != NULL) {
- /* TODO get rid of the blocking. Only here because of the static global DST. */
- BLI_mutex_lock(&DST.gl_context_mutex);
- WM_opengl_context_activate(re_gl_context);
+ DRW_opengl_render_context_enable(re_gl_context);
+ /* We need to query gwn context after a gl context has been bound. */
re_gwn_context = RE_gwn_context_get(render);
- if (GWN_context_active_get() == NULL) {
- GWN_context_active_set(re_gwn_context);
- }
- DRW_shape_cache_reset(); /* XXX fix that too. */
+ DRW_gawain_render_context_enable(re_gwn_context);
}
else {
DRW_opengl_context_enable();
@@ -1640,12 +1636,8 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
/* Changing Context */
if (re_gl_context != NULL) {
- DRW_shape_cache_reset(); /* XXX fix that too. */
- glFlush();
- GWN_context_active_set(NULL);
- WM_opengl_context_release(re_gl_context);
- /* TODO get rid of the blocking. */
- BLI_mutex_unlock(&DST.gl_context_mutex);
+ DRW_gawain_render_context_disable(re_gwn_context);
+ DRW_opengl_render_context_disable(re_gl_context);
}
else {
DRW_opengl_context_disable();
@@ -1671,6 +1663,56 @@ void DRW_render_object_iter(
DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END
}
+/* Assume a valid gl context is bound (and that the gl_context_mutex has been aquired).
+ * This function only setup DST and execute the given function.
+ * Warning: similar to DRW_render_to_image you cannot use default lists (dfbl & dtxl). */
+void DRW_custom_pipeline(
+ DrawEngineType *draw_engine_type,
+ struct Depsgraph *depsgraph,
+ void (*callback)(void *vedata, void *user_data),
+ void *user_data)
+{
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+ ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
+
+ /* Reset before using it. */
+ drw_state_prepare_clean_for_draw(&DST);
+ DST.options.is_image_render = true;
+ DST.options.is_scene_render = true;
+ DST.options.draw_background = false;
+
+ DST.draw_ctx = (DRWContextState){
+ .scene = scene,
+ .view_layer = view_layer,
+ .engine_type = NULL,
+ .depsgraph = depsgraph,
+ .object_mode = OB_MODE_OBJECT,
+ };
+ drw_context_state_init();
+
+ DST.viewport = GPU_viewport_create();
+ const int size[2] = {1, 1};
+ GPU_viewport_size_set(DST.viewport, size);
+
+ drw_viewport_var_init();
+
+ DRW_hair_init();
+
+ ViewportEngineData *data = drw_viewport_engine_data_ensure(draw_engine_type);
+
+ /* Execute the callback */
+ callback(data, user_data);
+ DST.buffer_finish_called = false;
+
+ GPU_viewport_free(DST.viewport);
+ GPU_framebuffer_restore();
+
+#ifdef DEBUG
+ /* Avoid accidental reuse. */
+ drw_state_ensure_not_reused(&DST);
+#endif
+}
+
static struct DRWSelectBuffer {
struct GPUFrameBuffer *framebuffer;
struct GPUTexture *texture_depth;
@@ -2280,7 +2322,7 @@ void DRW_opengl_context_create(void)
{
BLI_assert(DST.gl_context == NULL); /* Ensure it's called once */
- BLI_mutex_init(&DST.gl_context_mutex);
+ DST.gl_context_mutex = BLI_ticket_mutex_alloc();
if (!G.background) {
immDeactivate();
}
@@ -2305,7 +2347,7 @@ void DRW_opengl_context_destroy(void)
GWN_context_active_set(DST.gwn_context);
GWN_context_discard(DST.gwn_context);
WM_opengl_context_dispose(DST.gl_context);
- BLI_mutex_end(&DST.gl_context_mutex);
+ BLI_ticket_mutex_free(DST.gl_context_mutex);
}
}
@@ -2315,7 +2357,7 @@ void DRW_opengl_context_enable(void)
/* IMPORTANT: We dont support immediate mode in render mode!
* This shall remain in effect until immediate mode supports
* multiple threads. */
- BLI_mutex_lock(&DST.gl_context_mutex);
+ BLI_ticket_mutex_lock(DST.gl_context_mutex);
if (BLI_thread_is_main()) {
if (!G.background) {
immDeactivate();
@@ -2349,8 +2391,43 @@ void DRW_opengl_context_disable(void)
GWN_context_active_set(NULL);
}
- BLI_mutex_unlock(&DST.gl_context_mutex);
+ BLI_ticket_mutex_unlock(DST.gl_context_mutex);
}
}
+void DRW_opengl_render_context_enable(void *re_gl_context)
+{
+ /* If thread is main you should use DRW_opengl_context_enable(). */
+ BLI_assert(!BLI_thread_is_main());
+
+ /* TODO get rid of the blocking. Only here because of the static global DST. */
+ BLI_ticket_mutex_lock(DST.gl_context_mutex);
+ WM_opengl_context_activate(re_gl_context);
+}
+
+void DRW_opengl_render_context_disable(void *re_gl_context)
+{
+ glFlush();
+ WM_opengl_context_release(re_gl_context);
+ /* TODO get rid of the blocking. */
+ BLI_ticket_mutex_unlock(DST.gl_context_mutex);
+}
+
+/* Needs to be called AFTER DRW_opengl_render_context_enable() */
+void DRW_gawain_render_context_enable(void *re_gwn_context)
+{
+ /* If thread is main you should use DRW_opengl_context_enable(). */
+ BLI_assert(!BLI_thread_is_main());
+
+ GWN_context_active_set(re_gwn_context);
+ DRW_shape_cache_reset(); /* XXX fix that too. */
+}
+
+/* Needs to be called BEFORE DRW_opengl_render_context_disable() */
+void DRW_gawain_render_context_disable(void *UNUSED(re_gwn_context))
+{
+ DRW_shape_cache_reset(); /* XXX fix that too. */
+ GWN_context_active_set(NULL);
+}
+
/** \} */
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index 91a30fa45ae..6eae3459c2b 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -373,7 +373,7 @@ typedef struct DRWManager {
* the top portion of the struct so DO NOT MOVE IT! */
void *gl_context; /* Unique ghost context used by the draw manager. */
Gwn_Context *gwn_context;
- ThreadMutex gl_context_mutex; /* Mutex to lock the drw manager and avoid concurent context usage. */
+ TicketMutex *gl_context_mutex; /* Mutex to lock the drw manager and avoid concurent context usage. */
/** GPU Resource State: Memory storage between drawing. */
struct {
diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c
index 435c6c77e59..b0aec4a7600 100644
--- a/source/blender/draw/intern/draw_manager_shader.c
+++ b/source/blender/draw/intern/draw_manager_shader.c
@@ -154,10 +154,10 @@ static void drw_deferred_shader_compilation_free(void *custom_data)
MEM_freeN(comp);
}
-static void drw_deferred_shader_add(GPUMaterial *mat)
+static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred)
{
/* Do not deferre the compilation if we are rendering for image. */
- if (DRW_state_is_image_render() || !USE_DEFERRED_COMPILATION) {
+ if (DRW_state_is_image_render() || !USE_DEFERRED_COMPILATION || !deferred) {
/* Double checking that this GPUMaterial is not going to be
* compiled by another thread. */
DRW_deferred_shader_remove(mat);
@@ -308,10 +308,10 @@ GPUShader *DRW_shader_create_3D_depth_only(void)
return GPU_shader_get_builtin_shader(GPU_SHADER_3D_DEPTH_ONLY);
}
-GPUMaterial *DRW_shader_find_from_world(World *wo, const void *engine_type, int options)
+GPUMaterial *DRW_shader_find_from_world(World *wo, const void *engine_type, int options, bool deferred)
{
GPUMaterial *mat = GPU_material_from_nodetree_find(&wo->gpumaterial, engine_type, options);
- if (DRW_state_is_image_render()) {
+ if (DRW_state_is_image_render() || !deferred) {
if (mat != NULL && GPU_material_status(mat) == GPU_MAT_QUEUED) {
/* XXX Hack : we return NULL so that the engine will call DRW_shader_create_from_XXX
* with the shader code and we will resume the compilation from there. */
@@ -321,10 +321,10 @@ GPUMaterial *DRW_shader_find_from_world(World *wo, const void *engine_type, int
return mat;
}
-GPUMaterial *DRW_shader_find_from_material(Material *ma, const void *engine_type, int options)
+GPUMaterial *DRW_shader_find_from_material(Material *ma, const void *engine_type, int options, bool deferred)
{
GPUMaterial *mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine_type, options);
- if (DRW_state_is_image_render()) {
+ if (DRW_state_is_image_render() || !deferred) {
if (mat != NULL && GPU_material_status(mat) == GPU_MAT_QUEUED) {
/* XXX Hack : we return NULL so that the engine will call DRW_shader_create_from_XXX
* with the shader code and we will resume the compilation from there. */
@@ -336,7 +336,7 @@ GPUMaterial *DRW_shader_find_from_material(Material *ma, const void *engine_type
GPUMaterial *DRW_shader_create_from_world(
struct Scene *scene, World *wo, const void *engine_type, int options,
- const char *vert, const char *geom, const char *frag_lib, const char *defines)
+ const char *vert, const char *geom, const char *frag_lib, const char *defines, bool deferred)
{
GPUMaterial *mat = NULL;
if (DRW_state_is_image_render()) {
@@ -350,7 +350,7 @@ GPUMaterial *DRW_shader_create_from_world(
}
if (GPU_material_status(mat) == GPU_MAT_QUEUED) {
- drw_deferred_shader_add(mat);
+ drw_deferred_shader_add(mat, deferred);
}
return mat;
@@ -358,7 +358,7 @@ GPUMaterial *DRW_shader_create_from_world(
GPUMaterial *DRW_shader_create_from_material(
struct Scene *scene, Material *ma, const void *engine_type, int options,
- const char *vert, const char *geom, const char *frag_lib, const char *defines)
+ const char *vert, const char *geom, const char *frag_lib, const char *defines, bool deferred)
{
GPUMaterial *mat = NULL;
if (DRW_state_is_image_render()) {
@@ -372,7 +372,7 @@ GPUMaterial *DRW_shader_create_from_material(
}
if (GPU_material_status(mat) == GPU_MAT_QUEUED) {
- drw_deferred_shader_add(mat);
+ drw_deferred_shader_add(mat, deferred);
}
return mat;