| 
									
										
										
										
											2018-06-26 15:17:31 -06:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup gpu | 
					
						
							| 
									
										
										
										
											2018-06-26 15:17:31 -06:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-11 14:52:57 +11:00
										 |  |  | #ifndef GPU_STANDALONE
 | 
					
						
							|  |  |  | #  include "DNA_userdef_types.h"
 | 
					
						
							|  |  |  | #  define PIXELSIZE (U.pixelsize)
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #  define PIXELSIZE (1.0f)
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-10-30 16:21:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | #include "BLI_math_vector.h"
 | 
					
						
							| 
									
										
										
										
											2019-06-06 10:06:54 +10:00
										 |  |  | #include "BLI_utildefines.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-23 23:47:12 +01:00
										 |  |  | #include "BKE_global.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-26 15:17:31 -06:00
										 |  |  | #include "GPU_state.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | #include "gpu_context_private.hh"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 14:01:07 +02:00
										 |  |  | #include "gpu_state_private.hh"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using namespace blender::gpu; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | #define SET_STATE(_prefix, _state, _value) \
 | 
					
						
							|  |  |  |   do { \ | 
					
						
							| 
									
										
										
										
											2020-09-12 16:22:34 +02:00
										 |  |  |     StateManager *stack = Context::get()->state_manager; \ | 
					
						
							| 
									
										
										
										
											2020-08-17 00:34:06 +02:00
										 |  |  |     auto &state_object = stack->_prefix##state; \ | 
					
						
							| 
									
										
										
										
											2020-08-19 17:10:18 +02:00
										 |  |  |     state_object._state = (_value); \ | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  |   } while (0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define SET_IMMUTABLE_STATE(_state, _value) SET_STATE(, _state, _value)
 | 
					
						
							|  |  |  | #define SET_MUTABLE_STATE(_state, _value) SET_STATE(mutable_, _state, _value)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name Immutable state Setters
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 15:38:34 +02:00
										 |  |  | void GPU_blend(eGPUBlend blend) | 
					
						
							| 
									
										
										
										
											2018-06-26 15:17:31 -06:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  |   SET_IMMUTABLE_STATE(blend, blend); | 
					
						
							| 
									
										
										
										
											2018-06-26 15:17:31 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 14:01:07 +02:00
										 |  |  | void GPU_face_culling(eGPUFaceCullTest culling) | 
					
						
							| 
									
										
										
										
											2020-07-17 20:04:37 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  |   SET_IMMUTABLE_STATE(culling_test, culling); | 
					
						
							| 
									
										
										
										
											2020-07-17 20:04:37 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-17 20:13:11 +02:00
										 |  |  | void GPU_front_facing(bool invert) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  |   SET_IMMUTABLE_STATE(invert_facing, invert); | 
					
						
							| 
									
										
										
										
											2020-07-17 20:13:11 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-17 20:26:12 +02:00
										 |  |  | void GPU_provoking_vertex(eGPUProvokingVertex vert) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  |   SET_IMMUTABLE_STATE(provoking_vert, vert); | 
					
						
							| 
									
										
										
										
											2018-10-30 15:31:32 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-20 16:38:34 +02:00
										 |  |  | void GPU_depth_test(eGPUDepthTest test) | 
					
						
							| 
									
										
										
										
											2018-06-26 15:17:31 -06:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-20 16:38:34 +02:00
										 |  |  |   SET_IMMUTABLE_STATE(depth_test, test); | 
					
						
							| 
									
										
										
										
											2018-06-26 15:17:31 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-23 11:06:52 +02:00
										 |  |  | void GPU_stencil_test(eGPUStencilTest test) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   SET_IMMUTABLE_STATE(stencil_test, test); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-26 15:17:31 -06:00
										 |  |  | void GPU_line_smooth(bool enable) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  |   SET_IMMUTABLE_STATE(line_smooth, enable); | 
					
						
							| 
									
										
										
										
											2018-06-26 15:17:31 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | void GPU_polygon_smooth(bool enable) | 
					
						
							| 
									
										
										
										
											2018-06-26 15:17:31 -06:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  |   SET_IMMUTABLE_STATE(polygon_smooth, enable); | 
					
						
							| 
									
										
										
										
											2018-06-26 15:17:31 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | void GPU_logic_op_xor_set(bool enable) | 
					
						
							| 
									
										
										
										
											2018-06-26 15:17:31 -06:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  |   SET_IMMUTABLE_STATE(logic_op_xor, enable); | 
					
						
							| 
									
										
										
										
											2018-06-26 15:17:31 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 23:20:59 +02:00
										 |  |  | void GPU_write_mask(eGPUWriteMask mask) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   SET_IMMUTABLE_STATE(write_mask, mask); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | void GPU_color_mask(bool r, bool g, bool b, bool a) | 
					
						
							| 
									
										
										
										
											2018-06-26 15:17:31 -06:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-12 16:22:34 +02:00
										 |  |  |   StateManager *stack = Context::get()->state_manager; | 
					
						
							| 
									
										
										
										
											2020-08-17 00:34:06 +02:00
										 |  |  |   auto &state = stack->state; | 
					
						
							| 
									
										
										
										
											2020-08-19 17:10:18 +02:00
										 |  |  |   uint32_t write_mask = state.write_mask; | 
					
						
							|  |  |  |   SET_FLAG_FROM_TEST(write_mask, r, (uint32_t)GPU_WRITE_RED); | 
					
						
							|  |  |  |   SET_FLAG_FROM_TEST(write_mask, g, (uint32_t)GPU_WRITE_GREEN); | 
					
						
							|  |  |  |   SET_FLAG_FROM_TEST(write_mask, b, (uint32_t)GPU_WRITE_BLUE); | 
					
						
							|  |  |  |   SET_FLAG_FROM_TEST(write_mask, a, (uint32_t)GPU_WRITE_ALPHA); | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  |   state.write_mask = write_mask; | 
					
						
							| 
									
										
										
										
											2018-06-26 15:17:31 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | void GPU_depth_mask(bool depth) | 
					
						
							| 
									
										
										
										
											2019-05-28 17:14:22 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-12 16:22:34 +02:00
										 |  |  |   StateManager *stack = Context::get()->state_manager; | 
					
						
							| 
									
										
										
										
											2020-08-17 00:34:06 +02:00
										 |  |  |   auto &state = stack->state; | 
					
						
							| 
									
										
										
										
											2020-08-19 17:10:18 +02:00
										 |  |  |   uint32_t write_mask = state.write_mask; | 
					
						
							|  |  |  |   SET_FLAG_FROM_TEST(write_mask, depth, (uint32_t)GPU_WRITE_DEPTH); | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  |   state.write_mask = write_mask; | 
					
						
							| 
									
										
										
										
											2019-05-28 17:14:22 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-17 18:11:09 +02:00
										 |  |  | void GPU_shadow_offset(bool enable) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   SET_IMMUTABLE_STATE(shadow_bias, enable); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | void GPU_clip_distances(int distances_enabled) | 
					
						
							| 
									
										
										
										
											2020-07-17 19:21:33 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  |   SET_IMMUTABLE_STATE(clip_distances, distances_enabled); | 
					
						
							| 
									
										
										
										
											2020-07-17 19:21:33 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-17 18:11:09 +02:00
										 |  |  | void GPU_state_set(eGPUWriteMask write_mask, | 
					
						
							|  |  |  |                    eGPUBlend blend, | 
					
						
							|  |  |  |                    eGPUFaceCullTest culling_test, | 
					
						
							|  |  |  |                    eGPUDepthTest depth_test, | 
					
						
							|  |  |  |                    eGPUStencilTest stencil_test, | 
					
						
							|  |  |  |                    eGPUStencilOp stencil_op, | 
					
						
							|  |  |  |                    eGPUProvokingVertex provoking_vert) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-12 16:22:34 +02:00
										 |  |  |   StateManager *stack = Context::get()->state_manager; | 
					
						
							| 
									
										
										
										
											2020-08-17 18:11:09 +02:00
										 |  |  |   auto &state = stack->state; | 
					
						
							| 
									
										
										
										
											2020-08-19 17:10:18 +02:00
										 |  |  |   state.write_mask = (uint32_t)write_mask; | 
					
						
							|  |  |  |   state.blend = (uint32_t)blend; | 
					
						
							|  |  |  |   state.culling_test = (uint32_t)culling_test; | 
					
						
							|  |  |  |   state.depth_test = (uint32_t)depth_test; | 
					
						
							|  |  |  |   state.stencil_test = (uint32_t)stencil_test; | 
					
						
							|  |  |  |   state.stencil_op = (uint32_t)stencil_op; | 
					
						
							|  |  |  |   state.provoking_vert = (uint32_t)provoking_vert; | 
					
						
							| 
									
										
										
										
											2020-08-17 18:11:09 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | /** \} */ | 
					
						
							| 
									
										
										
										
											2018-06-26 15:17:31 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name Mutable State Setters
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							| 
									
										
										
										
											2020-07-17 19:03:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | void GPU_depth_range(float near, float far) | 
					
						
							| 
									
										
										
										
											2018-06-26 15:17:31 -06:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-12 16:22:34 +02:00
										 |  |  |   StateManager *stack = Context::get()->state_manager; | 
					
						
							| 
									
										
										
										
											2020-08-17 00:34:06 +02:00
										 |  |  |   auto &state = stack->mutable_state; | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  |   copy_v2_fl2(state.depth_range, near, far); | 
					
						
							| 
									
										
										
										
											2018-06-26 15:17:31 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-21 11:12:11 +11:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * \note By convention, this is set as needed and not reset back to 1.0. | 
					
						
							|  |  |  |  * This means code that draws lines must always set the line width beforehand, | 
					
						
							|  |  |  |  * but is not expected to restore it's previous value. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | void GPU_line_width(float width) | 
					
						
							| 
									
										
										
										
											2018-06-26 15:17:31 -06:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-10-22 21:09:11 +02:00
										 |  |  |   width = max_ff(1.0f, width * PIXELSIZE); | 
					
						
							|  |  |  |   SET_MUTABLE_STATE(line_width, width); | 
					
						
							| 
									
										
										
										
											2018-06-26 15:17:31 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | void GPU_point_size(float size) | 
					
						
							| 
									
										
										
										
											2018-06-26 15:17:31 -06:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-12 16:22:34 +02:00
										 |  |  |   StateManager *stack = Context::get()->state_manager; | 
					
						
							| 
									
										
										
										
											2020-09-10 15:51:20 +02:00
										 |  |  |   auto &state = stack->mutable_state; | 
					
						
							| 
									
										
										
										
											2020-09-10 23:55:22 +02:00
										 |  |  |   /* Keep the sign of point_size since it represents the enable state. */ | 
					
						
							|  |  |  |   state.point_size = size * ((state.point_size > 0.0) ? 1.0f : -1.0f); | 
					
						
							| 
									
										
										
										
											2018-06-26 15:17:31 -06:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-10-31 12:28:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | /* Programmable point size
 | 
					
						
							|  |  |  |  * - shaders set their own point size when enabled | 
					
						
							| 
									
										
										
										
											2020-09-10 15:51:20 +02:00
										 |  |  |  * - use GPU_point_size when disabled */ | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | /* TODO remove and use program point size everywhere */ | 
					
						
							|  |  |  | void GPU_program_point_size(bool enable) | 
					
						
							| 
									
										
										
										
											2018-10-31 12:28:59 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-12 16:22:34 +02:00
										 |  |  |   StateManager *stack = Context::get()->state_manager; | 
					
						
							| 
									
										
										
										
											2020-08-17 00:34:06 +02:00
										 |  |  |   auto &state = stack->mutable_state; | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  |   /* Set point size sign negative to disable. */ | 
					
						
							|  |  |  |   state.point_size = fabsf(state.point_size) * (enable ? 1 : -1); | 
					
						
							| 
									
										
										
										
											2018-10-31 12:28:59 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | void GPU_scissor_test(bool enable) | 
					
						
							| 
									
										
										
										
											2018-10-31 12:28:59 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  |   Context::get()->active_fb->scissor_test_set(enable); | 
					
						
							| 
									
										
										
										
											2018-11-04 10:08:55 +11:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-07-02 12:30:55 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | void GPU_scissor(int x, int y, int width, int height) | 
					
						
							| 
									
										
										
										
											2020-07-17 18:51:26 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-29 15:17:13 +02:00
										 |  |  |   int scissor_rect[4] = {x, y, width, height}; | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  |   Context::get()->active_fb->scissor_set(scissor_rect); | 
					
						
							| 
									
										
										
										
											2020-07-17 18:51:26 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | void GPU_viewport(int x, int y, int width, int height) | 
					
						
							| 
									
										
										
										
											2019-07-02 12:30:55 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  |   int viewport_rect[4] = {x, y, width, height}; | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  |   Context::get()->active_fb->viewport_set(viewport_rect); | 
					
						
							| 
									
										
										
										
											2019-07-02 12:30:55 +10:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-03-11 14:52:57 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-17 18:11:09 +02:00
										 |  |  | void GPU_stencil_reference_set(uint reference) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   SET_MUTABLE_STATE(stencil_reference, (uint8_t)reference); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-08-23 11:06:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-17 18:11:09 +02:00
										 |  |  | void GPU_stencil_write_mask_set(uint write_mask) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   SET_MUTABLE_STATE(stencil_write_mask, (uint8_t)write_mask); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-08-23 11:06:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-17 18:11:09 +02:00
										 |  |  | void GPU_stencil_compare_mask_set(uint compare_mask) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   SET_MUTABLE_STATE(stencil_compare_mask, (uint8_t)compare_mask); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name State Getters
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 23:20:59 +02:00
										 |  |  | eGPUBlend GPU_blend_get() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  |   GPUState &state = Context::get()->state_manager->state; | 
					
						
							| 
									
										
										
										
											2020-08-19 17:10:18 +02:00
										 |  |  |   return (eGPUBlend)state.blend; | 
					
						
							| 
									
										
										
										
											2020-08-16 23:20:59 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | eGPUWriteMask GPU_write_mask_get() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  |   GPUState &state = Context::get()->state_manager->state; | 
					
						
							| 
									
										
										
										
											2020-08-19 17:10:18 +02:00
										 |  |  |   return (eGPUWriteMask)state.write_mask; | 
					
						
							| 
									
										
										
										
											2020-08-16 23:20:59 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-23 11:06:52 +02:00
										 |  |  | uint GPU_stencil_mask_get() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-04-30 15:24:46 +10:00
										 |  |  |   const GPUStateMutable &state = Context::get()->state_manager->mutable_state; | 
					
						
							| 
									
										
										
										
											2020-08-23 11:06:52 +02:00
										 |  |  |   return state.stencil_write_mask; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-20 16:38:34 +02:00
										 |  |  | eGPUDepthTest GPU_depth_test_get() | 
					
						
							| 
									
										
										
										
											2020-07-16 04:16:10 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  |   GPUState &state = Context::get()->state_manager->state; | 
					
						
							| 
									
										
										
										
											2020-08-20 16:38:34 +02:00
										 |  |  |   return (eGPUDepthTest)state.depth_test; | 
					
						
							| 
									
										
										
										
											2020-07-16 04:16:10 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-23 11:06:52 +02:00
										 |  |  | eGPUStencilTest GPU_stencil_test_get() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  |   GPUState &state = Context::get()->state_manager->state; | 
					
						
							| 
									
										
										
										
											2020-08-23 11:06:52 +02:00
										 |  |  |   return (eGPUStencilTest)state.stencil_test; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-18 19:59:51 +02:00
										 |  |  | /* NOTE: Already premultiplied by U.pixelsize. */ | 
					
						
							| 
									
										
										
										
											2020-11-06 13:18:48 +01:00
										 |  |  | float GPU_line_width_get() | 
					
						
							| 
									
										
										
										
											2020-09-18 19:59:51 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-04-30 15:24:46 +10:00
										 |  |  |   const GPUStateMutable &state = Context::get()->state_manager->mutable_state; | 
					
						
							| 
									
										
										
										
											2020-09-18 19:59:51 +02:00
										 |  |  |   return state.line_width; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | void GPU_scissor_get(int coords[4]) | 
					
						
							| 
									
										
										
										
											2020-07-16 04:16:10 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  |   Context::get()->active_fb->scissor_get(coords); | 
					
						
							| 
									
										
										
										
											2020-07-16 04:16:10 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | void GPU_viewport_size_get_f(float coords[4]) | 
					
						
							| 
									
										
										
										
											2020-07-16 04:16:10 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-29 15:17:13 +02:00
										 |  |  |   int viewport[4]; | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  |   Context::get()->active_fb->viewport_get(viewport); | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  |   for (int i = 0; i < 4; i++) { | 
					
						
							| 
									
										
										
										
											2020-08-29 15:17:13 +02:00
										 |  |  |     coords[i] = viewport[i]; | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-07-16 04:16:10 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | void GPU_viewport_size_get_i(int coords[4]) | 
					
						
							| 
									
										
										
										
											2020-07-16 04:16:10 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  |   Context::get()->active_fb->viewport_get(coords); | 
					
						
							| 
									
										
										
										
											2020-07-16 04:16:10 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-06 13:18:48 +01:00
										 |  |  | bool GPU_depth_mask_get() | 
					
						
							| 
									
										
										
										
											2020-07-17 23:00:55 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-04-30 15:24:46 +10:00
										 |  |  |   const GPUState &state = Context::get()->state_manager->state; | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  |   return (state.write_mask & GPU_WRITE_DEPTH) != 0; | 
					
						
							| 
									
										
										
										
											2020-07-17 23:00:55 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-06 13:18:48 +01:00
										 |  |  | bool GPU_mipmap_enabled() | 
					
						
							| 
									
										
										
										
											2020-07-29 18:13:19 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-19 14:32:41 +10:00
										 |  |  |   /* TODO(fclem): this used to be a userdef option. */ | 
					
						
							| 
									
										
										
										
											2020-07-29 18:13:19 +02:00
										 |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name Context Utils
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-06 13:18:48 +01:00
										 |  |  | void GPU_flush() | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  |   Context::get()->flush(); | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-06 13:18:48 +01:00
										 |  |  | void GPU_finish() | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  |   Context::get()->finish(); | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-06 13:18:48 +01:00
										 |  |  | void GPU_apply_state() | 
					
						
							| 
									
										
										
										
											2020-09-12 17:29:37 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   Context::get()->state_manager->apply_state(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-09 15:12:28 +02:00
										 |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name BGL workaround
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * bgl makes direct GL calls that makes our state tracking out of date. | 
					
						
							|  |  |  |  * This flag make it so that the pyGPU calls will not override the state set by | 
					
						
							|  |  |  |  * bgl functions. | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-06 13:18:48 +01:00
										 |  |  | void GPU_bgl_start() | 
					
						
							| 
									
										
										
										
											2020-10-09 15:12:28 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-10-09 16:33:24 +02:00
										 |  |  |   Context *ctx = Context::get(); | 
					
						
							| 
									
										
										
										
											2020-10-09 17:00:00 +02:00
										 |  |  |   if (!(ctx && ctx->state_manager)) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   StateManager &state_manager = *(Context::get()->state_manager); | 
					
						
							|  |  |  |   if (state_manager.use_bgl == false) { | 
					
						
							|  |  |  |     /* Expected by many addons (see T80169, T81289).
 | 
					
						
							|  |  |  |      * This will reset the blend function. */ | 
					
						
							|  |  |  |     GPU_blend(GPU_BLEND_NONE); | 
					
						
							| 
									
										
										
										
											2021-01-28 21:16:17 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Equivalent of setting the depth func `glDepthFunc(GL_LEQUAL)`
 | 
					
						
							|  |  |  |      * Needed since Python scripts may enable depth test. | 
					
						
							|  |  |  |      * Without this block the depth test function is undefined. */ | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       eGPUDepthTest depth_test_real = GPU_depth_test_get(); | 
					
						
							|  |  |  |       eGPUDepthTest depth_test_temp = GPU_DEPTH_LESS_EQUAL; | 
					
						
							|  |  |  |       if (depth_test_real != depth_test_temp) { | 
					
						
							|  |  |  |         GPU_depth_test(depth_test_temp); | 
					
						
							|  |  |  |         state_manager.apply_state(); | 
					
						
							|  |  |  |         GPU_depth_test(depth_test_real); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-09 17:00:00 +02:00
										 |  |  |     state_manager.apply_state(); | 
					
						
							|  |  |  |     state_manager.use_bgl = true; | 
					
						
							| 
									
										
										
										
											2020-10-09 15:12:28 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-09 17:00:00 +02:00
										 |  |  | /* Just turn off the bgl safeguard system. Can be called even without GPU_bgl_start. */ | 
					
						
							| 
									
										
										
										
											2020-11-06 13:18:48 +01:00
										 |  |  | void GPU_bgl_end() | 
					
						
							| 
									
										
										
										
											2020-10-09 15:12:28 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-10-09 16:33:24 +02:00
										 |  |  |   Context *ctx = Context::get(); | 
					
						
							| 
									
										
										
										
											2020-10-09 17:00:00 +02:00
										 |  |  |   if (!(ctx && ctx->state_manager)) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   StateManager &state_manager = *ctx->state_manager; | 
					
						
							|  |  |  |   if (state_manager.use_bgl == true) { | 
					
						
							| 
									
										
										
										
											2020-10-09 16:33:24 +02:00
										 |  |  |     state_manager.use_bgl = false; | 
					
						
							|  |  |  |     /* Resync state tracking. */ | 
					
						
							|  |  |  |     state_manager.force_state(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-10-09 15:12:28 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-06 13:18:48 +01:00
										 |  |  | bool GPU_bgl_get() | 
					
						
							| 
									
										
										
										
											2020-09-12 17:29:37 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-10-09 15:12:28 +02:00
										 |  |  |   return Context::get()->state_manager->use_bgl; | 
					
						
							| 
									
										
										
										
											2020-09-12 17:29:37 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 20:56:39 +02:00
										 |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-12 06:10:11 +02:00
										 |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							| 
									
										
										
										
											2020-09-13 15:00:52 +10:00
										 |  |  | /** \name Synchronization Utils
 | 
					
						
							| 
									
										
										
										
											2020-09-12 06:10:11 +02:00
										 |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GPU_memory_barrier(eGPUBarrier barrier) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Context::get()->state_manager->issue_barrier(barrier); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 14:01:07 +02:00
										 |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							| 
									
										
										
										
											2020-09-12 17:29:37 +02:00
										 |  |  | /** \name Default State
 | 
					
						
							| 
									
										
										
										
											2020-08-16 23:20:59 +02:00
										 |  |  |  * \{ */ | 
					
						
							| 
									
										
										
										
											2020-05-15 14:29:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-06 13:18:48 +01:00
										 |  |  | StateManager::StateManager() | 
					
						
							| 
									
										
										
										
											2020-08-17 20:32:20 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   /* Set default state. */ | 
					
						
							|  |  |  |   state.write_mask = GPU_WRITE_COLOR; | 
					
						
							|  |  |  |   state.blend = GPU_BLEND_NONE; | 
					
						
							|  |  |  |   state.culling_test = GPU_CULL_NONE; | 
					
						
							|  |  |  |   state.depth_test = GPU_DEPTH_NONE; | 
					
						
							|  |  |  |   state.stencil_test = GPU_STENCIL_NONE; | 
					
						
							|  |  |  |   state.stencil_op = GPU_STENCIL_OP_NONE; | 
					
						
							|  |  |  |   state.provoking_vert = GPU_VERTEX_LAST; | 
					
						
							|  |  |  |   state.logic_op_xor = false; | 
					
						
							|  |  |  |   state.invert_facing = false; | 
					
						
							|  |  |  |   state.shadow_bias = false; | 
					
						
							|  |  |  |   state.clip_distances = 0; | 
					
						
							| 
									
										
										
										
											2020-10-23 16:32:10 +02:00
										 |  |  |   state.polygon_smooth = false; | 
					
						
							|  |  |  |   state.line_smooth = false; | 
					
						
							| 
									
										
										
										
											2020-08-17 20:32:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   mutable_state.depth_range[0] = 0.0f; | 
					
						
							|  |  |  |   mutable_state.depth_range[1] = 1.0f; | 
					
						
							| 
									
										
										
										
											2020-09-14 20:52:45 +02:00
										 |  |  |   mutable_state.point_size = -1.0f; /* Negative is not using point size. */ | 
					
						
							| 
									
										
										
										
											2020-08-17 20:32:20 +02:00
										 |  |  |   mutable_state.line_width = 1.0f; | 
					
						
							|  |  |  |   mutable_state.stencil_write_mask = 0x00; | 
					
						
							|  |  |  |   mutable_state.stencil_compare_mask = 0x00; | 
					
						
							|  |  |  |   mutable_state.stencil_reference = 0x00; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-11 14:52:57 +11:00
										 |  |  | /** \} */ |