diff options
author | Dalai Felinto <dfelinto@gmail.com> | 2017-05-09 16:09:39 +0300 |
---|---|---|
committer | Dalai Felinto <dfelinto@gmail.com> | 2017-05-09 16:23:33 +0300 |
commit | 65ebb668ec8d1fed282d59eea47da6dd47b699db (patch) | |
tree | 69fd13e5ae63bfd400112c8b954b586c8a5ae496 /source/blender/gpu | |
parent | 86c299c6a48036258096eb0c3447cad86369d4de (diff) |
glPushAttrib/Pop change implementation to use a stack
The original implementation (cbd78c81268f) broke depth of field.
Diffstat (limited to 'source/blender/gpu')
-rw-r--r-- | source/blender/gpu/GPU_draw.h | 50 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_compositing.c | 10 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_draw.c | 172 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_framebuffer.c | 14 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_select_pick.c | 6 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_select_sample_query.c | 6 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_viewport.c | 2 |
7 files changed, 137 insertions, 123 deletions
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h index cd305d5697f..52076c307df 100644 --- a/source/blender/gpu/GPU_draw.h +++ b/source/blender/gpu/GPU_draw.h @@ -174,58 +174,16 @@ void GPU_select_index_get(int index, int *r_col); int GPU_select_to_index(unsigned int col); void GPU_select_to_index_array(unsigned int *col, const unsigned int size); -typedef enum eGPUStateMask { +typedef enum eGPUAttribMask { GPU_DEPTH_BUFFER_BIT = (1 << 0), GPU_ENABLE_BIT = (1 << 1), GPU_SCISSOR_BIT = (1 << 2), GPU_VIEWPORT_BIT = (1 << 3), GPU_BLEND_BIT = (1 << 4), -} eGPUStateMask; - -typedef struct GPUStateValues -{ - eGPUStateMask mask; - - /* GL_ENABLE_BIT */ - unsigned int is_blend : 1; - unsigned int is_cull_face : 1; - unsigned int is_depth_test : 1; - unsigned int is_dither : 1; - unsigned int is_lighting : 1; - unsigned int is_line_smooth : 1; - unsigned int is_color_logic_op : 1; - unsigned int is_multisample : 1; - unsigned int is_polygon_offset_line : 1; - unsigned int is_polygon_offset_fill : 1; - unsigned int is_polygon_smooth : 1; - unsigned int is_sample_alpha_to_coverage : 1; - unsigned int is_scissor_test : 1; - unsigned int is_stencil_test : 1; - -#ifdef WITH_LEGACY_OPENGL - unsigned int is_alpha_test : 1; - bool is_light[8]; -#endif - - bool is_clip_plane[6]; - - /* GL_DEPTH_BUFFER_BIT */ - /* unsigned int is_depth_test : 1; */ - int depth_func; - double depth_clear_value; - bool depth_write_mask; - - /* GL_SCISSOR_BIT */ - int scissor_box[4]; - /* unsigned int is_scissor_test : 1; */ - - /* GL_VIEWPORT_BIT */ - int viewport[4]; - double near_far[2]; -} GPUStateValues; +} eGPUAttribMask; -void gpuSaveState(GPUStateValues *attribs, eGPUStateMask mask); -void gpuRestoreState(GPUStateValues *attribs); +void gpuPushAttrib(eGPUAttribMask mask); +void gpuPopAttrib(void); #ifdef __cplusplus } diff --git a/source/blender/gpu/intern/gpu_compositing.c b/source/blender/gpu/intern/gpu_compositing.c index f0692b91a80..6da71d17d33 100644 --- a/source/blender/gpu/intern/gpu_compositing.c +++ b/source/blender/gpu/intern/gpu_compositing.c @@ -197,8 +197,6 @@ struct GPUFX { Batch *quad_batch; Batch *point_batch; - - struct GPUStateValues attribs; }; #if 0 @@ -645,7 +643,7 @@ bool GPU_fx_compositor_initialize_passes( if (scissor_rect) { int w_sc = BLI_rcti_size_x(scissor_rect) + 1; int h_sc = BLI_rcti_size_y(scissor_rect) + 1; - gpuSaveState(&fx->attribs, GPU_SCISSOR_BIT); + gpuPushAttrib(GPU_SCISSOR_BIT); glEnable(GL_SCISSOR_TEST); glScissor(scissor_rect->xmin - rect->xmin, scissor_rect->ymin - rect->ymin, w_sc, h_sc); @@ -721,7 +719,7 @@ void GPU_fx_compositor_XRay_resolve(GPUFX *fx) GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer, 0, 0); /* full screen quad where we will always write to depth buffer */ - gpuSaveState(&fx->attribs, GPU_DEPTH_BUFFER_BIT | GPU_SCISSOR_BIT); + gpuPushAttrib(GPU_DEPTH_BUFFER_BIT | GPU_SCISSOR_BIT); glDepthFunc(GL_ALWAYS); /* disable scissor from sculpt if any */ glDisable(GL_SCISSOR_TEST); @@ -754,7 +752,7 @@ void GPU_fx_compositor_XRay_resolve(GPUFX *fx) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - gpuRestoreState(&fx->attribs); + gpuPopAttrib(); } @@ -785,7 +783,7 @@ bool GPU_fx_do_composite_pass( GPU_framebuffer_texture_detach(fx->depth_buffer); if (fx->restore_stencil) { - gpuRestoreState(&fx->attribs); + gpuPopAttrib(); } src = fx->color_buffer; diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 93b372336cb..0f4b105731d 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -2501,66 +2501,124 @@ void GPU_select_to_index_array(unsigned int *col, const unsigned int size) #undef INDEX_BUF_ARRAY } +#define STATE_STACK_DEPTH 16 + +typedef struct { + eGPUAttribMask mask; + + /* GL_ENABLE_BIT */ + unsigned int is_blend : 1; + unsigned int is_cull_face : 1; + unsigned int is_depth_test : 1; + unsigned int is_dither : 1; + unsigned int is_lighting : 1; + unsigned int is_line_smooth : 1; + unsigned int is_color_logic_op : 1; + unsigned int is_multisample : 1; + unsigned int is_polygon_offset_line : 1; + unsigned int is_polygon_offset_fill : 1; + unsigned int is_polygon_smooth : 1; + unsigned int is_sample_alpha_to_coverage : 1; + unsigned int is_scissor_test : 1; + unsigned int is_stencil_test : 1; + +#ifdef WITH_LEGACY_OPENGL + unsigned int is_alpha_test : 1; + bool is_light[8]; +#endif + + bool is_clip_plane[6]; + + /* GL_DEPTH_BUFFER_BIT */ + /* unsigned int is_depth_test : 1; */ + int depth_func; + double depth_clear_value; + bool depth_write_mask; + + /* GL_SCISSOR_BIT */ + int scissor_box[4]; + /* unsigned int is_scissor_test : 1; */ + + /* GL_VIEWPORT_BIT */ + int viewport[4]; + double near_far[2]; +} GPUAttribValues; + +typedef struct { + GPUAttribValues attrib_stack[STATE_STACK_DEPTH]; + unsigned int top; +} GPUAttribStack; + +static GPUAttribStack state = { + .top = 0 +}; + +#define AttribStack state +#define Attrib state.attrib_stack[state.top] + /** * Replacement for glPush/PopAttributes * * We don't need to cover all the options of legacy OpenGL * but simply the ones used by Blender. */ -void gpuSaveState(GPUStateValues *values, eGPUStateMask mask) +void gpuPushAttrib(eGPUAttribMask mask) { - values->mask = mask; + Attrib.mask = mask; if ((mask & GPU_DEPTH_BUFFER_BIT) != 0) { - values->is_depth_test = glIsEnabled(GL_DEPTH_TEST); - glGetIntegerv(GL_DEPTH_FUNC, &values->depth_func); - glGetDoublev(GL_DEPTH_CLEAR_VALUE, &values->depth_clear_value); - glGetBooleanv(GL_DEPTH_WRITEMASK, (GLboolean *)&values->depth_write_mask); + Attrib.is_depth_test = glIsEnabled(GL_DEPTH_TEST); + glGetIntegerv(GL_DEPTH_FUNC, &Attrib.depth_func); + glGetDoublev(GL_DEPTH_CLEAR_VALUE, &Attrib.depth_clear_value); + glGetBooleanv(GL_DEPTH_WRITEMASK, (GLboolean *)&Attrib.depth_write_mask); } if ((mask & GPU_ENABLE_BIT) != 0) { - values->is_blend = glIsEnabled(GL_BLEND); + Attrib.is_blend = glIsEnabled(GL_BLEND); for (int i = 0; i < 6; i++) { - values->is_clip_plane[i] = glIsEnabled(GL_CLIP_PLANE0 + i); + Attrib.is_clip_plane[i] = glIsEnabled(GL_CLIP_PLANE0 + i); } - values->is_cull_face = glIsEnabled(GL_CULL_FACE); - values->is_depth_test = glIsEnabled(GL_DEPTH_TEST); - values->is_dither = glIsEnabled(GL_DITHER); + Attrib.is_cull_face = glIsEnabled(GL_CULL_FACE); + Attrib.is_depth_test = glIsEnabled(GL_DEPTH_TEST); + Attrib.is_dither = glIsEnabled(GL_DITHER); #ifdef WITH_LEGACY_OPENGL - values->is_alpha_test = glIsEnabled(GL_ALPHA_TEST); + Attrib.is_alpha_test = glIsEnabled(GL_ALPHA_TEST); for (int i = 0; i < 8; i++) { - values->is_light[i] = glIsEnabled(GL_LIGHT0 + i); + Attrib.is_light[i] = glIsEnabled(GL_LIGHT0 + i); } #endif - values->is_line_smooth = glIsEnabled(GL_LINE_SMOOTH); - values->is_color_logic_op = glIsEnabled(GL_COLOR_LOGIC_OP); - values->is_multisample = glIsEnabled(GL_MULTISAMPLE); - values->is_polygon_offset_line = glIsEnabled(GL_POLYGON_OFFSET_LINE); - values->is_polygon_offset_fill = glIsEnabled(GL_POLYGON_OFFSET_FILL); - values->is_polygon_smooth = glIsEnabled(GL_POLYGON_SMOOTH); - values->is_sample_alpha_to_coverage = glIsEnabled(GL_SAMPLE_ALPHA_TO_COVERAGE); - values->is_scissor_test = glIsEnabled(GL_SCISSOR_TEST); - values->is_stencil_test = glIsEnabled(GL_STENCIL_TEST); + Attrib.is_line_smooth = glIsEnabled(GL_LINE_SMOOTH); + Attrib.is_color_logic_op = glIsEnabled(GL_COLOR_LOGIC_OP); + Attrib.is_multisample = glIsEnabled(GL_MULTISAMPLE); + Attrib.is_polygon_offset_line = glIsEnabled(GL_POLYGON_OFFSET_LINE); + Attrib.is_polygon_offset_fill = glIsEnabled(GL_POLYGON_OFFSET_FILL); + Attrib.is_polygon_smooth = glIsEnabled(GL_POLYGON_SMOOTH); + Attrib.is_sample_alpha_to_coverage = glIsEnabled(GL_SAMPLE_ALPHA_TO_COVERAGE); + Attrib.is_scissor_test = glIsEnabled(GL_SCISSOR_TEST); + Attrib.is_stencil_test = glIsEnabled(GL_STENCIL_TEST); } if ((mask & GPU_SCISSOR_BIT) != 0) { - values->is_scissor_test = glIsEnabled(GL_SCISSOR_TEST); - glGetIntegerv(GL_SCISSOR_BOX, (GLint *)&values->scissor_box); + Attrib.is_scissor_test = glIsEnabled(GL_SCISSOR_TEST); + glGetIntegerv(GL_SCISSOR_BOX, (GLint *)&Attrib.scissor_box); } if ((mask & GPU_VIEWPORT_BIT) != 0) { - glGetDoublev(GL_DEPTH_RANGE, (GLdouble *)&values->near_far); - glGetIntegerv(GL_VIEWPORT, (GLint *)&values->viewport); + glGetDoublev(GL_DEPTH_RANGE, (GLdouble *)&Attrib.near_far); + glGetIntegerv(GL_VIEWPORT, (GLint *)&Attrib.viewport); } if ((mask & GPU_BLEND_BIT) != 0) { - values->is_blend = glIsEnabled(GL_BLEND); + Attrib.is_blend = glIsEnabled(GL_BLEND); } + + BLI_assert(AttribStack.top < STATE_STACK_DEPTH); + AttribStack.top++; } static void restore_mask(GLenum cap, const bool value) { @@ -2572,60 +2630,66 @@ static void restore_mask(GLenum cap, const bool value) { } } -void gpuRestoreState(GPUStateValues *values) +void gpuPopAttrib() { - GLint mask = values->mask; + BLI_assert(AttribStack.top > 0); + AttribStack.top--; + + GLint mask = Attrib.mask; if ((mask & GPU_DEPTH_BUFFER_BIT) != 0) { - restore_mask(GL_DEPTH_TEST, values->is_depth_test); - glDepthFunc(values->depth_func); - glClearDepth(values->depth_clear_value); - glDepthMask(values->depth_write_mask); + restore_mask(GL_DEPTH_TEST, Attrib.is_depth_test); + glDepthFunc(Attrib.depth_func); + glClearDepth(Attrib.depth_clear_value); + glDepthMask(Attrib.depth_write_mask); } if ((mask & GPU_ENABLE_BIT) != 0) { - restore_mask(GL_BLEND, values->is_blend); + restore_mask(GL_BLEND, Attrib.is_blend); for (int i = 0; i < 6; i++) { - restore_mask(GL_CLIP_PLANE0 + i, values->is_clip_plane[i]); + restore_mask(GL_CLIP_PLANE0 + i, Attrib.is_clip_plane[i]); } - restore_mask(GL_CULL_FACE, values->is_cull_face); - restore_mask(GL_DEPTH_TEST, values->is_depth_test); - restore_mask(GL_DITHER, values->is_dither); + restore_mask(GL_CULL_FACE, Attrib.is_cull_face); + restore_mask(GL_DEPTH_TEST, Attrib.is_depth_test); + restore_mask(GL_DITHER, Attrib.is_dither); #ifdef WITH_LEGACY_OPENGL - restore_mask(GL_ALPHA_TEST, values->is_alpha_test); + restore_mask(GL_ALPHA_TEST, Attrib.is_alpha_test); for (int i = 0; i < 8; i++) { - restore_mask(GL_LIGHT0 + i, values->is_light[i]); + restore_mask(GL_LIGHT0 + i, Attrib.is_light[i]); } #endif - restore_mask(GL_LINE_SMOOTH, values->is_line_smooth); - restore_mask(GL_COLOR_LOGIC_OP, values->is_color_logic_op); - restore_mask(GL_MULTISAMPLE, values->is_multisample); - restore_mask(GL_POLYGON_OFFSET_LINE, values->is_polygon_offset_line); - restore_mask(GL_POLYGON_OFFSET_FILL, values->is_polygon_offset_fill); - restore_mask(GL_POLYGON_SMOOTH, values->is_polygon_smooth); - restore_mask(GL_SAMPLE_ALPHA_TO_COVERAGE, values->is_sample_alpha_to_coverage); - restore_mask(GL_SCISSOR_TEST, values->is_scissor_test); - restore_mask(GL_STENCIL_TEST, values->is_stencil_test); + restore_mask(GL_LINE_SMOOTH, Attrib.is_line_smooth); + restore_mask(GL_COLOR_LOGIC_OP, Attrib.is_color_logic_op); + restore_mask(GL_MULTISAMPLE, Attrib.is_multisample); + restore_mask(GL_POLYGON_OFFSET_LINE, Attrib.is_polygon_offset_line); + restore_mask(GL_POLYGON_OFFSET_FILL, Attrib.is_polygon_offset_fill); + restore_mask(GL_POLYGON_SMOOTH, Attrib.is_polygon_smooth); + restore_mask(GL_SAMPLE_ALPHA_TO_COVERAGE, Attrib.is_sample_alpha_to_coverage); + restore_mask(GL_SCISSOR_TEST, Attrib.is_scissor_test); + restore_mask(GL_STENCIL_TEST, Attrib.is_stencil_test); } if ((mask & GPU_VIEWPORT_BIT) != 0) { - glViewport(values->viewport[0], values->viewport[1], values->viewport[2], values->viewport[3]); - glDepthRange(values->near_far[0], values->near_far[1]); + glViewport(Attrib.viewport[0], Attrib.viewport[1], Attrib.viewport[2], Attrib.viewport[3]); + glDepthRange(Attrib.near_far[0], Attrib.near_far[1]); } if ((mask & GPU_SCISSOR_BIT) != 0) { - restore_mask(GL_SCISSOR_TEST, values->is_scissor_test); - glScissor(values->scissor_box[0], values->scissor_box[1], values->scissor_box[2], values->scissor_box[3]); + restore_mask(GL_SCISSOR_TEST, Attrib.is_scissor_test); + glScissor(Attrib.scissor_box[0], Attrib.scissor_box[1], Attrib.scissor_box[2], Attrib.scissor_box[3]); } if ((mask & GPU_BLEND_BIT) != 0) { - restore_mask(GL_BLEND, values->is_blend); + restore_mask(GL_BLEND, Attrib.is_blend); } } +#undef Attrib +#undef AttribStack + /** \} */ diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c index 09e80eeac9e..dd23eaceaff 100644 --- a/source/blender/gpu/intern/gpu_framebuffer.c +++ b/source/blender/gpu/intern/gpu_framebuffer.c @@ -51,7 +51,6 @@ struct GPUFrameBuffer { GLuint object; GPUTexture *colortex[GPU_FB_MAX_SLOTS]; GPUTexture *depthtex; - struct GPUStateValues attribs; }; static void gpu_print_framebuffer_error(GLenum status, char err_out[256]) @@ -217,7 +216,7 @@ void GPU_texture_bind_as_framebuffer(GPUTexture *tex) } /* push attributes */ - gpuSaveState(&fb->attribs, GPU_ENABLE_BIT | GPU_VIEWPORT_BIT); + gpuPushAttrib(GPU_ENABLE_BIT | GPU_VIEWPORT_BIT); glDisable(GL_SCISSOR_TEST); /* bind framebuffer */ @@ -260,7 +259,7 @@ void GPU_framebuffer_slots_bind(GPUFrameBuffer *fb, int slot) } /* push attributes */ - gpuSaveState(&fb->attribs, GPU_ENABLE_BIT | GPU_VIEWPORT_BIT); + gpuPushAttrib(GPU_ENABLE_BIT | GPU_VIEWPORT_BIT); glDisable(GL_SCISSOR_TEST); /* bind framebuffer */ @@ -312,11 +311,10 @@ void GPU_framebuffer_bind(GPUFrameBuffer *fb) GG.currentfb = fb->object; } - -void GPU_framebuffer_texture_unbind(GPUFrameBuffer *fb, GPUTexture *UNUSED(tex)) +void GPU_framebuffer_texture_unbind(GPUFrameBuffer *UNUSED(fb), GPUTexture *UNUSED(tex)) { - /* restore attributes */ - gpuRestoreState(&fb->attribs); + /* Restore attributes. */ + gpuPopAttrib(); } void GPU_framebuffer_bind_no_save(GPUFrameBuffer *fb, int slot) @@ -690,4 +688,4 @@ void GPU_offscreen_viewport_data_get( *r_fb = ofs->fb; *r_color = ofs->color; *r_depth = ofs->depth; -}
\ No newline at end of file +} diff --git a/source/blender/gpu/intern/gpu_select_pick.c b/source/blender/gpu/intern/gpu_select_pick.c index da75925fe66..f1d311890e6 100644 --- a/source/blender/gpu/intern/gpu_select_pick.c +++ b/source/blender/gpu/intern/gpu_select_pick.c @@ -293,8 +293,6 @@ typedef struct GPUPickState { unsigned int *rect_id; } nearest; }; - - struct GPUStateValues attribs; } GPUPickState; @@ -320,7 +318,7 @@ void gpu_select_pick_begin( /* Restrict OpenGL operations for when we don't have cache */ if (ps->is_cached == false) { - gpuSaveState(&ps->attribs, GPU_DEPTH_BUFFER_BIT | GPU_VIEWPORT_BIT); + gpuPushAttrib(GPU_DEPTH_BUFFER_BIT | GPU_VIEWPORT_BIT); /* disable writing to the framebuffer */ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); @@ -540,7 +538,7 @@ unsigned int gpu_select_pick_end(void) gpu_select_pick_load_id(ps->gl.prev_id); } - gpuRestoreState(&ps->attribs); + gpuPopAttrib(); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } diff --git a/source/blender/gpu/intern/gpu_select_sample_query.c b/source/blender/gpu/intern/gpu_select_sample_query.c index 96fd2595584..a7374604379 100644 --- a/source/blender/gpu/intern/gpu_select_sample_query.c +++ b/source/blender/gpu/intern/gpu_select_sample_query.c @@ -69,8 +69,6 @@ typedef struct GPUQueryState { char mode; unsigned int index; int oldhits; - /* OpenGL attrib bits */ - struct GPUStateValues attribs; } GPUQueryState; static GPUQueryState g_query_state = {0}; @@ -98,7 +96,7 @@ void gpu_select_query_begin( g_query_state.id = MEM_mallocN(g_query_state.num_of_queries * sizeof(*g_query_state.id), "gpu selection ids"); glGenQueries(g_query_state.num_of_queries, g_query_state.queries); - gpuSaveState(&g_query_state.attribs, GPU_DEPTH_BUFFER_BIT | GPU_VIEWPORT_BIT); + gpuPushAttrib(GPU_DEPTH_BUFFER_BIT | GPU_VIEWPORT_BIT); /* disable writing to the framebuffer */ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); @@ -206,7 +204,7 @@ unsigned int gpu_select_query_end(void) glDeleteQueries(g_query_state.num_of_queries, g_query_state.queries); MEM_freeN(g_query_state.queries); MEM_freeN(g_query_state.id); - gpuRestoreState(&g_query_state.attribs); + gpuPopAttrib(); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); return hits; diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c index c116d035f60..c87b5099f0e 100644 --- a/source/blender/gpu/intern/gpu_viewport.c +++ b/source/blender/gpu/intern/gpu_viewport.c @@ -346,7 +346,7 @@ void GPU_viewport_unbind(GPUViewport *viewport) DefaultFramebufferList *dfbl = viewport->fbl; if (dfbl->default_fb) { - GPU_framebuffer_texture_unbind(dfbl->default_fb, NULL); + GPU_framebuffer_texture_unbind(NULL, NULL); GPU_framebuffer_restore(); glEnable(GL_SCISSOR_TEST); |