diff options
author | Jeroen Bakker <jeroen@blender.org> | 2020-03-09 18:49:56 +0300 |
---|---|---|
committer | Jeroen Bakker <jeroen@blender.org> | 2020-03-12 11:35:27 +0300 |
commit | 21f016f01062a26c4de18d4b775d71a8bf1d84ce (patch) | |
tree | 1575e470ed97f989ea41f7cfff8187b4137145a2 /source | |
parent | 456595fd39c2db59be9de4652c7232a04d2322b6 (diff) |
DrawManager: Pack Draw State Bits
Some draw state bits are mutual exclusive. This patch will free some
draw state bits by packing the mutual exclusive bits in a mask.
Reviewed By: fclem
Differential Revision: https://developer.blender.org/D7088
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/draw/intern/DRW_render.h | 69 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_exec.c | 185 |
2 files changed, 130 insertions, 124 deletions
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index 6a6cdd8f51c..8ed7bb25336 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -270,50 +270,53 @@ void DRW_shader_library_free(DRWShaderLibrary *lib); } while (0) /* Batches */ - +/* DRWState is a bitmask that stores the current render state and the desired render state. Based + * on the differences the minimum state changes can be invoked to setup the desired render state. + * + * The Write Stencil, Stencil test, Depth test and Blend state options are mutual exclusive + * therefore they aren't ordered as a bit mask.*/ typedef enum { /** Write mask */ DRW_STATE_WRITE_DEPTH = (1 << 0), DRW_STATE_WRITE_COLOR = (1 << 1), + /* Write Stencil. These options are mutual exclusive and packed into 2 bits */ DRW_STATE_WRITE_STENCIL = (1 << 2), - DRW_STATE_WRITE_STENCIL_SHADOW_PASS = (1 << 3), - DRW_STATE_WRITE_STENCIL_SHADOW_FAIL = (1 << 4), - - /** Depth test */ - DRW_STATE_DEPTH_ALWAYS = (1 << 5), - DRW_STATE_DEPTH_LESS = (1 << 6), - DRW_STATE_DEPTH_LESS_EQUAL = (1 << 7), - DRW_STATE_DEPTH_EQUAL = (1 << 8), - DRW_STATE_DEPTH_GREATER = (1 << 9), - DRW_STATE_DEPTH_GREATER_EQUAL = (1 << 10), + DRW_STATE_WRITE_STENCIL_SHADOW_PASS = (2 << 2), + DRW_STATE_WRITE_STENCIL_SHADOW_FAIL = (3 << 2), + /** Depth test. These options are mutual exclusive and packed into 3 bits */ + DRW_STATE_DEPTH_ALWAYS = (1 << 4), + DRW_STATE_DEPTH_LESS = (2 << 4), + DRW_STATE_DEPTH_LESS_EQUAL = (3 << 4), + DRW_STATE_DEPTH_EQUAL = (4 << 4), + DRW_STATE_DEPTH_GREATER = (5 << 4), + DRW_STATE_DEPTH_GREATER_EQUAL = (6 << 4), /** Culling test */ - DRW_STATE_CULL_BACK = (1 << 11), - DRW_STATE_CULL_FRONT = (1 << 12), - /** Stencil test */ - DRW_STATE_STENCIL_ALWAYS = (1 << 13), - DRW_STATE_STENCIL_EQUAL = (1 << 14), - DRW_STATE_STENCIL_NEQUAL = (1 << 15), - - /** Blend state */ - DRW_STATE_BLEND_ADD = (1 << 16), + DRW_STATE_CULL_BACK = (1 << 7), + DRW_STATE_CULL_FRONT = (1 << 8), + /** Stencil test . These options are mutal exclusive and packed into 2 bits*/ + DRW_STATE_STENCIL_ALWAYS = (1 << 9), + DRW_STATE_STENCIL_EQUAL = (2 << 9), + DRW_STATE_STENCIL_NEQUAL = (3 << 9), + + /** Blend state. These options are mutual exclusive and packed into 4 bits */ + DRW_STATE_BLEND_ADD = (1 << 11), /** Same as additive but let alpha accumulate without premult. */ - DRW_STATE_BLEND_ADD_FULL = (1 << 17), + DRW_STATE_BLEND_ADD_FULL = (2 << 11), /** Standard alpha blending. */ - DRW_STATE_BLEND_ALPHA = (1 << 18), + DRW_STATE_BLEND_ALPHA = (3 << 11), /** Use that if color is already premult by alpha. */ - DRW_STATE_BLEND_ALPHA_PREMUL = (1 << 19), - DRW_STATE_BLEND_BACKGROUND = (1 << 20), - DRW_STATE_BLEND_OIT = (1 << 21), - DRW_STATE_BLEND_MUL = (1 << 22), - DRW_STATE_BLEND_SUB = (1 << 23), + DRW_STATE_BLEND_ALPHA_PREMUL = (4 << 11), + DRW_STATE_BLEND_BACKGROUND = (5 << 11), + DRW_STATE_BLEND_OIT = (6 << 11), + DRW_STATE_BLEND_MUL = (7 << 11), + DRW_STATE_BLEND_SUB = (8 << 11), /** Use dual source blending. WARNING: Only one color buffer allowed. */ - DRW_STATE_BLEND_CUSTOM = (1 << 24), + DRW_STATE_BLEND_CUSTOM = (9 << 11), + DRW_STATE_LOGIC_INVERT = (10 << 11), - DRW_STATE_IN_FRONT_SELECT = (1 << 25), - DRW_STATE_LOGIC_INVERT = (1 << 26), - DRW_STATE_SHADOW_OFFSET = (1 << 27), - DRW_STATE_CLIP_PLANES = (1 << 28), - // DRW_STATE_WIRE_SMOOTH = (1 << 29), /* UNUSED */ + DRW_STATE_IN_FRONT_SELECT = (1 << 27), + DRW_STATE_SHADOW_OFFSET = (1 << 28), + DRW_STATE_CLIP_PLANES = (1 << 29), DRW_STATE_FIRST_VERTEX_CONVENTION = (1 << 30), /** DO NOT USE. Assumed always enabled. Only used internally. */ DRW_STATE_PROGRAM_POINT_SIZE = (1u << 31), diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index 87a475cb134..3d1b43537b7 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -114,19 +114,20 @@ void drw_state_set(DRWState state) /* Stencil Write */ if (test) { glStencilMask(0xFF); - if (test & DRW_STATE_WRITE_STENCIL) { - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - } - else if (test & DRW_STATE_WRITE_STENCIL_SHADOW_PASS) { - glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR_WRAP); - glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR_WRAP); - } - else if (test & DRW_STATE_WRITE_STENCIL_SHADOW_FAIL) { - glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_KEEP); - glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_KEEP); - } - else { - BLI_assert(0); + switch (test) { + case DRW_STATE_WRITE_STENCIL: + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + break; + case DRW_STATE_WRITE_STENCIL_SHADOW_PASS: + glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR_WRAP); + glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR_WRAP); + break; + case DRW_STATE_WRITE_STENCIL_SHADOW_FAIL: + glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_KEEP); + glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_KEEP); + break; + default: + BLI_assert(0); } } else { @@ -191,26 +192,27 @@ void drw_state_set(DRWState state) if (test) { glEnable(GL_DEPTH_TEST); - if (state & DRW_STATE_DEPTH_LESS) { - glDepthFunc(GL_LESS); - } - else if (state & DRW_STATE_DEPTH_LESS_EQUAL) { - glDepthFunc(GL_LEQUAL); - } - else if (state & DRW_STATE_DEPTH_EQUAL) { - glDepthFunc(GL_EQUAL); - } - else if (state & DRW_STATE_DEPTH_GREATER) { - glDepthFunc(GL_GREATER); - } - else if (state & DRW_STATE_DEPTH_GREATER_EQUAL) { - glDepthFunc(GL_GEQUAL); - } - else if (state & DRW_STATE_DEPTH_ALWAYS) { - glDepthFunc(GL_ALWAYS); - } - else { - BLI_assert(0); + switch (test) { + case DRW_STATE_DEPTH_LESS: + glDepthFunc(GL_LESS); + break; + case DRW_STATE_DEPTH_LESS_EQUAL: + glDepthFunc(GL_LEQUAL); + break; + case DRW_STATE_DEPTH_EQUAL: + glDepthFunc(GL_EQUAL); + break; + case DRW_STATE_DEPTH_GREATER: + glDepthFunc(GL_GREATER); + break; + case DRW_STATE_DEPTH_GREATER_EQUAL: + glDepthFunc(GL_GEQUAL); + break; + case DRW_STATE_DEPTH_ALWAYS: + glDepthFunc(GL_ALWAYS); + break; + default: + BLI_assert(0); } } else { @@ -244,62 +246,63 @@ void drw_state_set(DRWState state) if (test) { glEnable(GL_BLEND); - if ((state & DRW_STATE_BLEND_ALPHA) != 0) { - glBlendFuncSeparate(GL_SRC_ALPHA, - GL_ONE_MINUS_SRC_ALPHA, /* RGB */ - GL_ONE, - GL_ONE_MINUS_SRC_ALPHA); /* Alpha */ - } - else if ((state & DRW_STATE_BLEND_BACKGROUND) != 0) { - /* Special blend to add color under and multiply dst by alpha. */ - glBlendFuncSeparate(GL_ONE_MINUS_DST_ALPHA, - GL_SRC_ALPHA, /* RGB */ - GL_ZERO, - GL_SRC_ALPHA); /* Alpha */ - } - else if ((state & DRW_STATE_BLEND_ALPHA_PREMUL) != 0) { - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - } - else if ((state & DRW_STATE_BLEND_MUL) != 0) { - glBlendFunc(GL_DST_COLOR, GL_ZERO); - } - else if ((state & DRW_STATE_BLEND_OIT) != 0) { - glBlendFuncSeparate(GL_ONE, - GL_ONE, /* RGB */ - GL_ZERO, - GL_ONE_MINUS_SRC_ALPHA); /* Alpha */ - } - else if ((state & DRW_STATE_BLEND_ADD) != 0) { - /* Do not let alpha accumulate but premult the source RGB by it. */ - glBlendFuncSeparate(GL_SRC_ALPHA, - GL_ONE, /* RGB */ - GL_ZERO, - GL_ONE); /* Alpha */ - } - else if ((state & DRW_STATE_BLEND_ADD_FULL) != 0) { - /* Let alpha accumulate. */ - glBlendFunc(GL_ONE, GL_ONE); - } - else if ((state & DRW_STATE_BLEND_SUB) != 0) { - glBlendFunc(GL_ONE, GL_ONE); - } - else if ((state & DRW_STATE_BLEND_CUSTOM) != 0) { - /* Custom blend parameters using dual source blending. - * Can only be used with one Draw Buffer. */ - glBlendFunc(GL_ONE, GL_SRC1_COLOR); - } - else if ((state & DRW_STATE_LOGIC_INVERT) != 0) { - /* Replace logic op by blend func to support floating point framebuffer. */ - glBlendFuncSeparate(GL_ONE_MINUS_DST_COLOR, - GL_ZERO, /* RGB */ - GL_ZERO, - GL_ONE); /* Alpha */ - } - else { - BLI_assert(0); + switch (test) { + case DRW_STATE_BLEND_ALPHA: + glBlendFuncSeparate(GL_SRC_ALPHA, + GL_ONE_MINUS_SRC_ALPHA, /* RGB */ + GL_ONE, + GL_ONE_MINUS_SRC_ALPHA); /* Alpha */ + break; + case DRW_STATE_BLEND_BACKGROUND: + /* Special blend to add color under and multiply dst by alpha. */ + glBlendFuncSeparate(GL_ONE_MINUS_DST_ALPHA, + GL_SRC_ALPHA, /* RGB */ + GL_ZERO, + GL_SRC_ALPHA); /* Alpha */ + break; + case DRW_STATE_BLEND_ALPHA_PREMUL: + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + break; + case DRW_STATE_BLEND_MUL: + glBlendFunc(GL_DST_COLOR, GL_ZERO); + break; + case DRW_STATE_BLEND_OIT: + glBlendFuncSeparate(GL_ONE, + GL_ONE, /* RGB */ + GL_ZERO, + GL_ONE_MINUS_SRC_ALPHA); /* Alpha */ + break; + case DRW_STATE_BLEND_ADD: + /* Do not let alpha accumulate but premult the source RGB by it. */ + glBlendFuncSeparate(GL_SRC_ALPHA, + GL_ONE, /* RGB */ + GL_ZERO, + GL_ONE); /* Alpha */ + break; + case DRW_STATE_BLEND_ADD_FULL: + /* Let alpha accumulate. */ + glBlendFunc(GL_ONE, GL_ONE); + break; + case DRW_STATE_BLEND_SUB: + glBlendFunc(GL_ONE, GL_ONE); + break; + case DRW_STATE_BLEND_CUSTOM: + /* Custom blend parameters using dual source blending. + * Can only be used with one Draw Buffer. */ + glBlendFunc(GL_ONE, GL_SRC1_COLOR); + break; + case DRW_STATE_LOGIC_INVERT: + /* Replace logic op by blend func to support floating point framebuffer. */ + glBlendFuncSeparate(GL_ONE_MINUS_DST_COLOR, + GL_ZERO, /* RGB */ + GL_ZERO, + GL_ONE); /* Alpha */ + break; + default: + BLI_assert(0); } - if ((state & DRW_STATE_BLEND_SUB) != 0) { + if (test == DRW_STATE_BLEND_SUB) { glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); } else { @@ -405,14 +408,14 @@ static void drw_stencil_state_set(uint write_mask, uint reference, uint compare_ * - (write-mask & reference) is what gets written if the test condition is fulfilled. **/ glStencilMask(write_mask); - - if ((DST.state & DRW_STATE_STENCIL_ALWAYS) != 0) { + DRWState stencil_test = DST.state & DRW_STATE_STENCIL_TEST_ENABLED; + if (stencil_test == DRW_STATE_STENCIL_ALWAYS) { glStencilFunc(GL_ALWAYS, reference, compare_mask); } - else if ((DST.state & DRW_STATE_STENCIL_EQUAL) != 0) { + else if (stencil_test == DRW_STATE_STENCIL_EQUAL) { glStencilFunc(GL_EQUAL, reference, compare_mask); } - else if ((DST.state & DRW_STATE_STENCIL_NEQUAL) != 0) { + else if (stencil_test == DRW_STATE_STENCIL_NEQUAL) { glStencilFunc(GL_NOTEQUAL, reference, compare_mask); } } |