Blender V4.3
gpu_state.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#ifndef GPU_STANDALONE
10# include "DNA_userdef_types.h"
11# define PIXELSIZE (U.pixelsize)
12#else
13# define PIXELSIZE (1.0f)
14#endif
15
16#include "BLI_math_vector.h"
17#include "BLI_utildefines.h"
18
19#include "GPU_state.hh"
20
21#include "gpu_backend.hh"
23
24#include "gpu_state_private.hh"
25
26using namespace blender::gpu;
27
28#define SET_STATE(_prefix, _state, _value) \
29 do { \
30 StateManager *stack = Context::get()->state_manager; \
31 auto &state_object = stack->_prefix##state; \
32 state_object._state = (_value); \
33 } while (0)
34
35#define SET_IMMUTABLE_STATE(_state, _value) SET_STATE(, _state, _value)
36#define SET_MUTABLE_STATE(_state, _value) SET_STATE(mutable_, _state, _value)
37
38/* -------------------------------------------------------------------- */
46
48{
49 SET_IMMUTABLE_STATE(culling_test, culling);
50}
51
57
59{
60 SET_IMMUTABLE_STATE(invert_facing, invert);
61}
62
64{
65 SET_IMMUTABLE_STATE(provoking_vert, vert);
66}
67
69{
70 SET_IMMUTABLE_STATE(depth_test, test);
71}
72
74{
75 SET_IMMUTABLE_STATE(stencil_test, test);
76}
77
78void GPU_line_smooth(bool enable)
79{
80 SET_IMMUTABLE_STATE(line_smooth, enable);
81}
82
83void GPU_polygon_smooth(bool enable)
84{
85 SET_IMMUTABLE_STATE(polygon_smooth, enable);
86}
87
88void GPU_logic_op_xor_set(bool enable)
89{
90 SET_IMMUTABLE_STATE(logic_op_xor, enable);
91}
92
94{
95 SET_IMMUTABLE_STATE(write_mask, mask);
96}
97
98void GPU_color_mask(bool r, bool g, bool b, bool a)
99{
101 auto &state = stack->state;
102 uint32_t write_mask = state.write_mask;
107 state.write_mask = write_mask;
108}
109
110void GPU_depth_mask(bool depth)
111{
113 auto &state = stack->state;
114 uint32_t write_mask = state.write_mask;
115 SET_FLAG_FROM_TEST(write_mask, depth, uint32_t(GPU_WRITE_DEPTH));
116 state.write_mask = write_mask;
117}
118
119void GPU_shadow_offset(bool enable)
120{
121 SET_IMMUTABLE_STATE(shadow_bias, enable);
122}
123
124void GPU_clip_distances(int distances_enabled)
125{
126 SET_IMMUTABLE_STATE(clip_distances, distances_enabled);
127}
128
131 eGPUFaceCullTest culling_test,
132 eGPUDepthTest depth_test,
133 eGPUStencilTest stencil_test,
134 eGPUStencilOp stencil_op,
135 eGPUProvokingVertex provoking_vert)
136{
138 auto &state = stack->state;
139 state.write_mask = uint32_t(write_mask);
140 state.blend = uint32_t(blend);
141 state.culling_test = uint32_t(culling_test);
142 state.depth_test = uint32_t(depth_test);
143 state.stencil_test = uint32_t(stencil_test);
144 state.stencil_op = uint32_t(stencil_op);
145 state.provoking_vert = uint32_t(provoking_vert);
146}
147
150/* -------------------------------------------------------------------- */
154void GPU_depth_range(float near, float far)
155{
157 auto &state = stack->mutable_state;
158 copy_v2_fl2(state.depth_range, near, far);
159}
160
161void GPU_line_width(float width)
162{
163 width = max_ff(1.0f, width * PIXELSIZE);
164 SET_MUTABLE_STATE(line_width, width);
165}
166
167void GPU_point_size(float size)
168{
170 auto &state = stack->mutable_state;
171 /* Keep the sign of point_size since it represents the enable state. */
172 state.point_size = size * ((state.point_size > 0.0) ? 1.0f : -1.0f);
173}
174
175void GPU_program_point_size(bool enable)
176{
178 auto &state = stack->mutable_state;
179 /* Set point size sign negative to disable. */
180 state.point_size = fabsf(state.point_size) * (enable ? 1 : -1);
181}
182
183void GPU_scissor_test(bool enable)
184{
186}
187
188void GPU_scissor(int x, int y, int width, int height)
189{
190 int scissor_rect[4] = {x, y, width, height};
191 Context::get()->active_fb->scissor_set(scissor_rect);
192}
193
194void GPU_viewport(int x, int y, int width, int height)
195{
196 int viewport_rect[4] = {x, y, width, height};
197 Context::get()->active_fb->viewport_set(viewport_rect);
198}
199
201{
202 SET_MUTABLE_STATE(stencil_reference, uint8_t(reference));
203}
204
206{
207 SET_MUTABLE_STATE(stencil_write_mask, uint8_t(write_mask));
208}
209
211{
212 SET_MUTABLE_STATE(stencil_compare_mask, uint8_t(compare_mask));
213}
214
217/* -------------------------------------------------------------------- */
226
232
238
244
250
256
257void GPU_scissor_get(int coords[4])
258{
260}
261
262void GPU_viewport_size_get_f(float coords[4])
263{
264 int viewport[4];
265 Context::get()->active_fb->viewport_get(viewport);
266 for (int i = 0; i < 4; i++) {
267 coords[i] = viewport[i];
268 }
269}
270
271void GPU_viewport_size_get_i(int coords[4])
272{
274}
275
277{
279 return (state.write_mask & GPU_WRITE_DEPTH) != 0;
280}
281
283{
284 /* TODO(fclem): this used to be a userdef option. */
285 return true;
286}
287
290/* -------------------------------------------------------------------- */
295{
296 Context::get()->flush();
297}
298
300{
301 Context::get()->finish();
302}
303
308
311/* -------------------------------------------------------------------- */
320{
321 Context *ctx = Context::get();
322 if (!(ctx && ctx->state_manager)) {
323 return;
324 }
325 StateManager &state_manager = *(Context::get()->state_manager);
326 if (state_manager.use_bgl == false) {
327 /* Expected by many addons (see #80169, #81289).
328 * This will reset the blend function. */
330
331 /* Equivalent of setting the depth func `glDepthFunc(GL_LEQUAL)`
332 * Needed since Python scripts may enable depth test.
333 * Without this block the depth test function is undefined. */
334 {
335 eGPUDepthTest depth_test_real = GPU_depth_test_get();
336 eGPUDepthTest depth_test_temp = GPU_DEPTH_LESS_EQUAL;
337 if (depth_test_real != depth_test_temp) {
338 GPU_depth_test(depth_test_temp);
339 state_manager.apply_state();
340 GPU_depth_test(depth_test_real);
341 }
342 }
343
344 state_manager.apply_state();
345 state_manager.use_bgl = true;
346 }
347}
348
350{
351 Context *ctx = Context::get();
352 if (!(ctx && ctx->state_manager)) {
353 return;
354 }
355 StateManager &state_manager = *ctx->state_manager;
356 if (state_manager.use_bgl == true) {
357 state_manager.use_bgl = false;
358 /* Resync state tracking. */
359 state_manager.force_state();
360 }
361}
362
364{
366}
367
370/* -------------------------------------------------------------------- */
378
380{
381 Fence *fence = GPUBackend::get()->fence_alloc();
382 return wrap(fence);
383}
384
386{
387 delete unwrap(fence);
388}
389
391{
392 unwrap(fence)->signal();
393}
394
396{
397 unwrap(fence)->wait();
398}
399
402/* -------------------------------------------------------------------- */
431
MINLINE float max_ff(float a, float b)
MINLINE void copy_v2_fl2(float v[2], float x, float y)
unsigned int uint
#define SET_FLAG_FROM_TEST(value, test, flag)
eGPUBlend
Definition GPU_state.hh:84
@ GPU_BLEND_NONE
Definition GPU_state.hh:85
eGPUWriteMask
Definition GPU_state.hh:16
@ GPU_WRITE_RED
Definition GPU_state.hh:18
@ GPU_WRITE_GREEN
Definition GPU_state.hh:19
@ GPU_WRITE_BLUE
Definition GPU_state.hh:20
@ GPU_WRITE_DEPTH
Definition GPU_state.hh:22
@ GPU_WRITE_COLOR
Definition GPU_state.hh:24
@ GPU_WRITE_ALPHA
Definition GPU_state.hh:21
eGPUProvokingVertex
Definition GPU_state.hh:138
@ GPU_VERTEX_LAST
Definition GPU_state.hh:139
eGPUFaceCullTest
Definition GPU_state.hh:132
@ GPU_CULL_NONE
Definition GPU_state.hh:133
eGPUBarrier
Definition GPU_state.hh:29
eGPUStencilOp
Definition GPU_state.hh:124
@ GPU_STENCIL_OP_NONE
Definition GPU_state.hh:125
eGPUDepthTest
Definition GPU_state.hh:107
@ GPU_DEPTH_LESS_EQUAL
Definition GPU_state.hh:111
@ GPU_DEPTH_NONE
Definition GPU_state.hh:108
eGPUStencilTest
Definition GPU_state.hh:117
@ GPU_STENCIL_NONE
Definition GPU_state.hh:118
struct GPUFence GPUFence
static Context * get()
virtual void finish()=0
virtual void flush()=0
void viewport_set(const int viewport[4])
void scissor_set(const int scissor[4])
void scissor_get(int r_scissor[4]) const
void viewport_get(int r_viewport[4]) const
static GPUBackend * get()
virtual Fence * fence_alloc()=0
virtual void issue_barrier(eGPUBarrier barrier_bits)=0
virtual void apply_state()=0
virtual void force_state()=0
local_group_size(16, 16) .push_constant(Type b
#define fabsf(x)
void GPU_memory_barrier(eGPUBarrier barrier)
Definition gpu_state.cc:374
void GPU_program_point_size(bool enable)
Definition gpu_state.cc:175
void GPU_face_culling(eGPUFaceCullTest culling)
Definition gpu_state.cc:47
eGPUFaceCullTest GPU_face_culling_get()
Definition gpu_state.cc:52
void GPU_flush()
Definition gpu_state.cc:294
void GPU_blend(eGPUBlend blend)
Definition gpu_state.cc:42
void GPU_write_mask(eGPUWriteMask mask)
Definition gpu_state.cc:93
void GPU_scissor_test(bool enable)
Definition gpu_state.cc:183
void GPU_line_width(float width)
Definition gpu_state.cc:161
eGPUBlend GPU_blend_get()
Definition gpu_state.cc:221
void GPU_finish()
Definition gpu_state.cc:299
void GPU_line_smooth(bool enable)
Definition gpu_state.cc:78
void GPU_logic_op_xor_set(bool enable)
Definition gpu_state.cc:88
void GPU_depth_mask(bool depth)
Definition gpu_state.cc:110
eGPUDepthTest GPU_depth_test_get()
Definition gpu_state.cc:239
void GPU_bgl_start()
Definition gpu_state.cc:319
void GPU_stencil_test(eGPUStencilTest test)
Definition gpu_state.cc:73
void GPU_stencil_write_mask_set(uint write_mask)
Definition gpu_state.cc:205
bool GPU_mipmap_enabled()
Definition gpu_state.cc:282
void GPU_color_mask(bool r, bool g, bool b, bool a)
Definition gpu_state.cc:98
GPUFence * GPU_fence_create()
Definition gpu_state.cc:379
void GPU_depth_range(float near, float far)
Definition gpu_state.cc:154
void GPU_viewport_size_get_i(int coords[4])
Definition gpu_state.cc:271
eGPUWriteMask GPU_write_mask_get()
Definition gpu_state.cc:227
void GPU_stencil_reference_set(uint reference)
Definition gpu_state.cc:200
void GPU_scissor(int x, int y, int width, int height)
Definition gpu_state.cc:188
float GPU_line_width_get()
Definition gpu_state.cc:251
void GPU_stencil_compare_mask_set(uint compare_mask)
Definition gpu_state.cc:210
eGPUStencilTest GPU_stencil_test_get()
Definition gpu_state.cc:245
#define SET_MUTABLE_STATE(_state, _value)
Definition gpu_state.cc:36
void GPU_front_facing(bool invert)
Definition gpu_state.cc:58
void GPU_viewport(int x, int y, int width, int height)
Definition gpu_state.cc:194
void GPU_fence_wait(GPUFence *fence)
Definition gpu_state.cc:395
#define PIXELSIZE
Definition gpu_state.cc:11
void GPU_point_size(float size)
Definition gpu_state.cc:167
uint GPU_stencil_mask_get()
Definition gpu_state.cc:233
void GPU_bgl_end()
Definition gpu_state.cc:349
bool GPU_bgl_get()
Definition gpu_state.cc:363
void GPU_state_set(eGPUWriteMask write_mask, eGPUBlend blend, eGPUFaceCullTest culling_test, eGPUDepthTest depth_test, eGPUStencilTest stencil_test, eGPUStencilOp stencil_op, eGPUProvokingVertex provoking_vert)
Definition gpu_state.cc:129
#define SET_IMMUTABLE_STATE(_state, _value)
Definition gpu_state.cc:35
void GPU_fence_signal(GPUFence *fence)
Definition gpu_state.cc:390
void GPU_depth_test(eGPUDepthTest test)
Definition gpu_state.cc:68
void GPU_viewport_size_get_f(float coords[4])
Definition gpu_state.cc:262
void GPU_apply_state()
Definition gpu_state.cc:304
bool GPU_depth_mask_get()
Definition gpu_state.cc:276
void GPU_scissor_get(int coords[4])
Definition gpu_state.cc:257
void GPU_clip_distances(int distances_enabled)
Definition gpu_state.cc:124
void GPU_fence_free(GPUFence *fence)
Definition gpu_state.cc:385
void GPU_provoking_vertex(eGPUProvokingVertex vert)
Definition gpu_state.cc:63
void GPU_polygon_smooth(bool enable)
Definition gpu_state.cc:83
void GPU_shadow_offset(bool enable)
Definition gpu_state.cc:119
CCL_NAMESPACE_BEGIN ccl_device float invert(float color, float factor)
Definition invert.h:9
static ulong state[N]
static Context * unwrap(GPUContext *ctx)
static GPUContext * wrap(Context *ctx)
unsigned int uint32_t
Definition stdint.h:80
unsigned char uint8_t
Definition stdint.h:78