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>2020-03-11 19:07:43 +0300
committerClément Foucault <foucault.clem@gmail.com>2020-03-11 19:12:16 +0300
commitc476c36e400883d929a7149def8dcb6ad6157a86 (patch)
treec19c43ad1ed82f333c08bee7d2096024fed812dd /source/blender/draw/intern
parentf01bc597a8e6bf5df19f1af0c422918c96b25e41 (diff)
Workbench Simplification Refactor
This patch is (almost) a complete rewrite of workbench engine. The features remain unchanged but the code quality is greatly improved. Hair shading is brighter but also more correct. This also introduce the concept of `DRWShaderLibrary` to make a simple include system inside the GLSL files. Differential Revision: https://developer.blender.org/D7060
Diffstat (limited to 'source/blender/draw/intern')
-rw-r--r--source/blender/draw/intern/DRW_render.h26
-rw-r--r--source/blender/draw/intern/draw_common.h5
-rw-r--r--source/blender/draw/intern/draw_hair.c29
-rw-r--r--source/blender/draw/intern/draw_manager.c38
-rw-r--r--source/blender/draw/intern/draw_manager_data.c20
-rw-r--r--source/blender/draw/intern/draw_manager_shader.c129
-rw-r--r--source/blender/draw/intern/draw_manager_texture.c7
7 files changed, 215 insertions, 39 deletions
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index c3e94fda4fc..5122b1ea1ac 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -81,6 +81,7 @@ typedef struct DRWPass DRWPass;
typedef struct DRWShadingGroup DRWShadingGroup;
typedef struct DRWUniform DRWUniform;
typedef struct DRWView DRWView;
+typedef struct DRWShaderLibrary DRWShaderLibrary;
/* TODO Put it somewhere else? */
typedef struct BoundSphere {
@@ -148,6 +149,8 @@ struct GPUTexture *DRW_texture_pool_query_2d(int w,
int h,
eGPUTextureFormat format,
DrawEngineType *engine_type);
+struct GPUTexture *DRW_texture_pool_query_fullscreen(eGPUTextureFormat format,
+ DrawEngineType *engine_type);
struct GPUTexture *DRW_texture_create_1d(int w,
eGPUTextureFormat format,
@@ -246,6 +249,24 @@ void DRW_shader_free(struct GPUShader *shader);
} \
} while (0)
+DRWShaderLibrary *DRW_shader_library_create(void);
+
+/* Warning: Each library must be added after all its dependencies. */
+void DRW_shader_library_add_file(DRWShaderLibrary *lib, char *lib_code, const char *lib_name);
+#define DRW_SHADER_LIB_ADD(lib, lib_name) \
+ DRW_shader_library_add_file(lib, datatoc_##lib_name##_glsl, STRINGIFY(lib_name) ".glsl")
+
+char *DRW_shader_library_create_shader_string(DRWShaderLibrary *lib, char *shader_code);
+
+void DRW_shader_library_free(DRWShaderLibrary *lib);
+#define DRW_SHADER_LIB_FREE_SAFE(lib) \
+ do { \
+ if (lib != NULL) { \
+ DRW_shader_library_free(lib); \
+ lib = NULL; \
+ } \
+ } while (0)
+
/* Batches */
typedef enum {
@@ -403,6 +424,9 @@ void DRW_buffer_add_entry_array(DRWCallBuffer *buffer, const void *attr[], uint
DRW_buffer_add_entry_array(buffer, array, (sizeof(array) / sizeof(*array))); \
} while (0)
+/* Can only be called during iter phase. */
+uint32_t DRW_object_resource_id_get(Object *UNUSED(ob));
+
void DRW_shgroup_state_enable(DRWShadingGroup *shgroup, DRWState state);
void DRW_shgroup_state_disable(DRWShadingGroup *shgroup, DRWState state);
@@ -414,7 +438,7 @@ void DRW_shgroup_state_disable(DRWShadingGroup *shgroup, DRWState state);
void DRW_shgroup_stencil_set(DRWShadingGroup *shgroup,
uint write_mask,
uint reference,
- uint comp_mask);
+ uint compare_mask);
/* TODO remove this function. Obsolete version. mask is actually reference value. */
void DRW_shgroup_stencil_mask(DRWShadingGroup *shgroup, uint mask);
diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h
index 24d3b7fa7b6..5818d84a7af 100644
--- a/source/blender/draw/intern/draw_common.h
+++ b/source/blender/draw/intern/draw_common.h
@@ -177,6 +177,11 @@ struct DRWShadingGroup *DRW_shgroup_hair_create(struct Object *object,
struct DRWPass *hair_pass,
struct GPUShader *shader);
+struct DRWShadingGroup *DRW_shgroup_hair_create_sub(struct Object *object,
+ struct ParticleSystem *psys,
+ struct ModifierData *md,
+ struct DRWShadingGroup *shgrp);
+
struct DRWShadingGroup *DRW_shgroup_material_hair_create(struct Object *object,
struct ParticleSystem *psys,
struct ModifierData *md,
diff --git a/source/blender/draw/intern/draw_hair.c b/source/blender/draw/intern/draw_hair.c
index 08256b931ba..847f5e7a224 100644
--- a/source/blender/draw/intern/draw_hair.c
+++ b/source/blender/draw/intern/draw_hair.c
@@ -108,6 +108,7 @@ static DRWShadingGroup *drw_shgroup_create_hair_procedural_ex(Object *object,
ParticleSystem *psys,
ModifierData *md,
DRWPass *hair_pass,
+ DRWShadingGroup *shgrp_parent,
struct GPUMaterial *gpu_mat,
GPUShader *gpu_shader)
{
@@ -127,7 +128,10 @@ static DRWShadingGroup *drw_shgroup_create_hair_procedural_ex(Object *object,
object, psys, md, &hair_cache, subdiv, thickness_res);
DRWShadingGroup *shgrp;
- if (gpu_mat) {
+ if (shgrp_parent) {
+ shgrp = DRW_shgroup_create_sub(shgrp_parent);
+ }
+ else if (gpu_mat) {
shgrp = DRW_shgroup_material_create(gpu_mat, hair_pass);
}
else if (gpu_shader) {
@@ -151,6 +155,17 @@ static DRWShadingGroup *drw_shgroup_create_hair_procedural_ex(Object *object,
}
}
+ /* Fix issue with certain driver not drawing anything if there is no texture bound to
+ * "ac", "au", "u" or "c". */
+ if (hair_cache->num_uv_layers == 0) {
+ DRW_shgroup_uniform_texture(shgrp, "u", hair_cache->final[subdiv].proc_tex);
+ DRW_shgroup_uniform_texture(shgrp, "au", hair_cache->final[subdiv].proc_tex);
+ }
+ if (hair_cache->num_col_layers == 0) {
+ DRW_shgroup_uniform_texture(shgrp, "c", hair_cache->final[subdiv].proc_tex);
+ DRW_shgroup_uniform_texture(shgrp, "ac", hair_cache->final[subdiv].proc_tex);
+ }
+
if ((dupli_parent != NULL) && (dupli_object != NULL)) {
if (dupli_object->type & OB_DUPLICOLLECTION) {
copy_m4_m4(dupli_mat, dupli_parent->obmat);
@@ -220,7 +235,15 @@ static DRWShadingGroup *drw_shgroup_create_hair_procedural_ex(Object *object,
DRWShadingGroup *DRW_shgroup_hair_create(
Object *object, ParticleSystem *psys, ModifierData *md, DRWPass *hair_pass, GPUShader *shader)
{
- return drw_shgroup_create_hair_procedural_ex(object, psys, md, hair_pass, NULL, shader);
+ return drw_shgroup_create_hair_procedural_ex(object, psys, md, hair_pass, NULL, NULL, shader);
+}
+
+DRWShadingGroup *DRW_shgroup_hair_create_sub(Object *object,
+ ParticleSystem *psys,
+ ModifierData *md,
+ DRWShadingGroup *shgrp)
+{
+ return drw_shgroup_create_hair_procedural_ex(object, psys, md, NULL, shgrp, NULL, NULL);
}
DRWShadingGroup *DRW_shgroup_material_hair_create(Object *object,
@@ -229,7 +252,7 @@ DRWShadingGroup *DRW_shgroup_material_hair_create(Object *object,
DRWPass *hair_pass,
struct GPUMaterial *material)
{
- return drw_shgroup_create_hair_procedural_ex(object, psys, md, hair_pass, material, NULL);
+ return drw_shgroup_create_hair_procedural_ex(object, psys, md, hair_pass, NULL, material, NULL);
}
void DRW_hair_update(void)
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 85b071f5c89..9553117c179 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -1118,45 +1118,23 @@ static void use_drw_engine(DrawEngineType *engine)
BLI_addtail(&DST.enabled_engines, ld);
}
-/**
- * Use for external render engines.
- */
-static void drw_engines_enable_external(void)
-{
- use_drw_engine(DRW_engine_viewport_external_type.draw_engine);
-}
-
-/* TODO revisit this when proper layering is implemented */
/* Gather all draw engines needed and store them in DST.enabled_engines
* That also define the rendering order of engines */
-static void drw_engines_enable_from_engine(RenderEngineType *engine_type,
- eDrawType drawtype,
- bool use_xray)
+static void drw_engines_enable_from_engine(RenderEngineType *engine_type, eDrawType drawtype)
{
switch (drawtype) {
case OB_WIRE:
- use_drw_engine(&draw_engine_workbench_transparent);
- break;
-
case OB_SOLID:
- if (use_xray) {
- use_drw_engine(&draw_engine_workbench_transparent);
- }
- else {
- use_drw_engine(&draw_engine_workbench_solid);
- }
+ use_drw_engine(DRW_engine_viewport_workbench_type.draw_engine);
break;
-
case OB_MATERIAL:
case OB_RENDER:
default:
- /* TODO layers */
if (engine_type->draw_engine != NULL) {
use_drw_engine(engine_type->draw_engine);
}
-
- if ((engine_type->flag & RE_INTERNAL) == 0) {
- drw_engines_enable_external();
+ else if ((engine_type->flag & RE_INTERNAL) == 0) {
+ use_drw_engine(DRW_engine_viewport_external_type.draw_engine);
}
break;
}
@@ -1182,7 +1160,7 @@ static void drw_engines_enable(ViewLayer *UNUSED(view_layer),
const eDrawType drawtype = v3d->shading.type;
const bool use_xray = XRAY_ENABLED(v3d);
- drw_engines_enable_from_engine(engine_type, drawtype, use_xray);
+ drw_engines_enable_from_engine(engine_type, drawtype);
if (gpencil_engine_needed && ((drawtype >= OB_SOLID) || !use_xray)) {
use_drw_engine(&draw_engine_gpencil_type);
}
@@ -1608,6 +1586,9 @@ void DRW_draw_render_loop_offscreen(struct Depsgraph *depsgraph,
GPU_blend(true);
}
+ GPU_matrix_identity_set();
+ GPU_matrix_identity_projection_set();
+
GPU_viewport_unbind_from_offscreen(render_viewport, ofs, do_color_management);
if (draw_background) {
@@ -2646,9 +2627,6 @@ void DRW_engines_register(void)
RE_engines_register(&DRW_engine_viewport_eevee_type);
RE_engines_register(&DRW_engine_viewport_workbench_type);
- DRW_engine_register(&draw_engine_workbench_solid);
- DRW_engine_register(&draw_engine_workbench_transparent);
-
DRW_engine_register(&draw_engine_gpencil_type);
DRW_engine_register(&draw_engine_overlay_type);
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index 83142da051a..be0dd7751ed 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -562,6 +562,16 @@ static DRWResourceHandle drw_resource_handle_new(float (*obmat)[4], Object *ob)
return handle;
}
+uint32_t DRW_object_resource_id_get(Object *UNUSED(ob))
+{
+ DRWResourceHandle handle = DST.ob_handle;
+ if (handle == 0) {
+ /* Handle not yet allocated. Return next handle. */
+ handle = DST.resource_handle;
+ }
+ return handle;
+}
+
static DRWResourceHandle drw_resource_handle(DRWShadingGroup *shgroup,
float (*obmat)[4],
Object *ob)
@@ -693,14 +703,14 @@ static void drw_command_set_select_id(DRWShadingGroup *shgroup, GPUVertBuf *buf,
static void drw_command_set_stencil_mask(DRWShadingGroup *shgroup,
uint write_mask,
uint reference,
- uint comp_mask)
+ uint compare_mask)
{
BLI_assert(write_mask <= 0xFF);
BLI_assert(reference <= 0xFF);
- BLI_assert(comp_mask <= 0xFF);
+ BLI_assert(compare_mask <= 0xFF);
DRWCommandSetStencil *cmd = drw_command_create(shgroup, DRW_CMD_STENCIL);
cmd->write_mask = write_mask;
- cmd->comp_mask = comp_mask;
+ cmd->comp_mask = compare_mask;
cmd->ref = reference;
}
@@ -1341,9 +1351,9 @@ void DRW_shgroup_state_disable(DRWShadingGroup *shgroup, DRWState state)
void DRW_shgroup_stencil_set(DRWShadingGroup *shgroup,
uint write_mask,
uint reference,
- uint comp_mask)
+ uint compare_mask)
{
- drw_command_set_stencil_mask(shgroup, write_mask, reference, comp_mask);
+ drw_command_set_stencil_mask(shgroup, write_mask, reference, compare_mask);
}
/* TODO remove this function. */
diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c
index ed05fb85dc9..7b08f44921f 100644
--- a/source/blender/draw/intern/draw_manager_shader.c
+++ b/source/blender/draw/intern/draw_manager_shader.c
@@ -24,6 +24,7 @@
#include "DNA_world_types.h"
#include "DNA_material_types.h"
+#include "BLI_dynstr.h"
#include "BLI_listbase.h"
#include "BLI_string_utils.h"
#include "BLI_threads.h"
@@ -282,6 +283,8 @@ void DRW_deferred_shader_remove(GPUMaterial *mat)
/* -------------------------------------------------------------------- */
+/** \{ */
+
GPUShader *DRW_shader_create(const char *vert,
const char *geom,
const char *frag,
@@ -468,3 +471,129 @@ void DRW_shader_free(GPUShader *shader)
{
GPU_shader_free(shader);
}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Shader Library
+ *
+ * Simple include system for glsl files.
+ *
+ * Usage: Create a DRWShaderLibrary and add the library in the right order.
+ * You can have nested dependencies but each new library needs to have all its dependencies already
+ * added to the DRWShaderLibrary.
+ * Finally you can use DRW_shader_library_create_shader_string to get a shader string that also
+ * contains the needed libraries for this shader.
+ * \{ */
+
+/* 32 because we use a 32bit bitmap. */
+#define MAX_LIB 32
+#define MAX_LIB_NAME 64
+#define MAX_LIB_DEPS 8
+
+struct DRWShaderLibrary {
+ char *libs[MAX_LIB];
+ char libs_name[MAX_LIB][MAX_LIB_NAME];
+ uint32_t libs_deps[MAX_LIB];
+};
+
+DRWShaderLibrary *DRW_shader_library_create(void)
+{
+ return MEM_callocN(sizeof(DRWShaderLibrary), "DRWShaderLibrary");
+}
+
+void DRW_shader_library_free(DRWShaderLibrary *lib)
+{
+ MEM_SAFE_FREE(lib);
+}
+
+static int drw_shader_library_search(DRWShaderLibrary *lib, const char *name)
+{
+ for (int i = 0; i < MAX_LIB; i++) {
+ if (lib->libs[i]) {
+ if (!strncmp(lib->libs_name[i], name, strlen(lib->libs_name[i]))) {
+ return i;
+ }
+ }
+ else {
+ break;
+ }
+ }
+ return -1;
+}
+
+/* Return bitmap of dependencies. */
+static uint32_t drw_shader_dependencies_get(DRWShaderLibrary *lib, char *lib_code)
+{
+ /* Search dependencies. */
+ uint32_t deps = 0;
+ char *haystack = lib_code;
+ while ((haystack = strstr(haystack, "BLENDER_REQUIRE("))) {
+ haystack += 16;
+ int dep = drw_shader_library_search(lib, haystack);
+ if (dep == -1) {
+ printf(
+ "Error: Dependency not found.\n"
+ "This might be due to bad lib ordering.\n");
+ BLI_assert(0);
+ }
+ else {
+ deps |= 1u << (uint32_t)dep;
+ }
+ }
+ return deps;
+}
+
+void DRW_shader_library_add_file(DRWShaderLibrary *lib, char *lib_code, const char *lib_name)
+{
+ int index = -1;
+ for (int i = 0; i < MAX_LIB; i++) {
+ if (lib->libs[i] == NULL) {
+ index = i;
+ break;
+ }
+ }
+
+ if (index > -1) {
+ lib->libs[index] = lib_code;
+ BLI_strncpy(lib->libs_name[index], lib_name, MAX_LIB_NAME);
+ }
+ else {
+ printf("Error: Too many libraries. Cannot add %s.\n", lib_name);
+ BLI_assert(0);
+ }
+
+ lib->libs_deps[index] = drw_shader_dependencies_get(lib, lib_code);
+}
+
+/* Return an allocN'ed string containing the shader code with its dependencies prepended.
+ * Caller must free the string with MEM_freeN after use. */
+char *DRW_shader_library_create_shader_string(DRWShaderLibrary *lib, char *shader_code)
+{
+ uint32_t deps = drw_shader_dependencies_get(lib, shader_code);
+
+ DynStr *ds = BLI_dynstr_new();
+ /* Add all dependencies recursively. */
+ for (int i = MAX_LIB - 1; i > -1; i--) {
+ if (lib->libs[i] && (deps & (1u << (uint32_t)i))) {
+ deps |= lib->libs_deps[i];
+ }
+ }
+ /* Concatenate all needed libs into one string. */
+ for (int i = 0; i < MAX_LIB; i++) {
+ if (deps & 1u) {
+ BLI_dynstr_append(ds, lib->libs[i]);
+ }
+ deps = deps >> 1;
+ }
+
+ BLI_dynstr_append(ds, shader_code);
+
+ char *str = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+
+ return str;
+}
+
+/** \} */
diff --git a/source/blender/draw/intern/draw_manager_texture.c b/source/blender/draw/intern/draw_manager_texture.c
index 373810b2f7f..c75299158a3 100644
--- a/source/blender/draw/intern/draw_manager_texture.c
+++ b/source/blender/draw/intern/draw_manager_texture.c
@@ -134,6 +134,13 @@ GPUTexture *DRW_texture_pool_query_2d(int w,
return tex;
}
+GPUTexture *DRW_texture_pool_query_fullscreen(eGPUTextureFormat format,
+ DrawEngineType *engine_type)
+{
+ const float *size = DRW_viewport_size_get();
+ return DRW_texture_pool_query_2d((int)size[0], (int)size[1], format, engine_type);
+}
+
void DRW_texture_ensure_fullscreen_2d(GPUTexture **tex,
eGPUTextureFormat format,
DRWTextureFlag flags)