Blender V4.3
gl_state.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2020 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "BKE_global.hh"
10
11#include "BLI_math_base.h"
12#include "BLI_math_bits.h"
13
14#include "GPU_capabilities.hh"
15
16#include "gl_context.hh"
17#include "gl_framebuffer.hh"
18#include "gl_texture.hh"
19
20#include "gl_state.hh"
21
22namespace blender::gpu {
23
24/* -------------------------------------------------------------------- */
29{
30 /* Set other states that never change. */
31 glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
32 glEnable(GL_MULTISAMPLE);
33
34 glDisable(GL_DITHER);
35
36 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
37 glPixelStorei(GL_PACK_ALIGNMENT, 1);
38 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
39
40 /* Takes precedence over #GL_PRIMITIVE_RESTART.
41 * Sets restart index correctly following the IBO type. */
42 glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
43
44 /* Limits. */
45 glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, line_width_range_);
46
47 /* Force update using default state. */
48 current_ = ~state;
49 current_mutable_ = ~mutable_state;
50 set_state(state);
51 set_mutable_state(mutable_state);
52}
53
55{
56 if (!this->use_bgl) {
57 this->set_state(this->state);
58 this->set_mutable_state(this->mutable_state);
59 this->texture_bind_apply();
60 this->image_bind_apply();
61 }
62 /* This is needed by gpu_py_offscreen. */
64};
65
67{
68 /* Little exception for clip distances since they need to keep the old count correct. */
69 uint32_t clip_distances = current_.clip_distances;
70 current_ = ~this->state;
71 current_.clip_distances = clip_distances;
72 current_mutable_ = ~this->mutable_state;
73 this->set_state(this->state);
74 this->set_mutable_state(this->mutable_state);
75};
76
77void GLStateManager::set_state(const GPUState &state)
78{
79 GPUState changed = state ^ current_;
80
81 if (changed.blend != 0) {
82 set_blend((eGPUBlend)state.blend);
83 }
84 if (changed.write_mask != 0) {
85 set_write_mask((eGPUWriteMask)state.write_mask);
86 }
87 if (changed.depth_test != 0) {
88 set_depth_test((eGPUDepthTest)state.depth_test);
89 }
90 if (changed.stencil_test != 0 || changed.stencil_op != 0) {
93 }
94 if (changed.clip_distances != 0) {
95 set_clip_distances(state.clip_distances, current_.clip_distances);
96 }
97 if (changed.culling_test != 0) {
98 set_backface_culling((eGPUFaceCullTest)state.culling_test);
99 }
100 if (changed.logic_op_xor != 0) {
101 set_logic_op(state.logic_op_xor);
102 }
103 if (changed.invert_facing != 0) {
104 set_facing(state.invert_facing);
105 }
106 if (changed.provoking_vert != 0) {
107 set_provoking_vert((eGPUProvokingVertex)state.provoking_vert);
108 }
109 if (changed.shadow_bias != 0) {
110 set_shadow_bias(state.shadow_bias);
111 }
112
113 /* TODO: remove. */
114 if (changed.polygon_smooth) {
115 if (state.polygon_smooth) {
116 glEnable(GL_POLYGON_SMOOTH);
117 }
118 else {
119 glDisable(GL_POLYGON_SMOOTH);
120 }
121 }
122 if (changed.line_smooth) {
123 if (state.line_smooth) {
124 glEnable(GL_LINE_SMOOTH);
125 }
126 else {
127 glDisable(GL_LINE_SMOOTH);
128 }
129 }
130
131 current_ = state;
132}
133
134void GLStateManager::set_mutable_state(const GPUStateMutable &state)
135{
136 GPUStateMutable changed = state ^ current_mutable_;
137
138 /* TODO: remove, should be uniform. */
139 if (float_as_uint(changed.point_size) != 0) {
140 if (state.point_size > 0.0f) {
141 glEnable(GL_PROGRAM_POINT_SIZE);
142 }
143 else {
144 glDisable(GL_PROGRAM_POINT_SIZE);
145 glPointSize(fabsf(state.point_size));
146 }
147 }
148
149 if (float_as_uint(changed.line_width) != 0) {
150 /* TODO: remove, should use wide line shader. */
151 glLineWidth(clamp_f(state.line_width, line_width_range_[0], line_width_range_[1]));
152 }
153
154 if (float_as_uint(changed.depth_range[0]) != 0 || float_as_uint(changed.depth_range[1]) != 0) {
155 /* TODO: remove, should modify the projection matrix instead. */
156 glDepthRange(UNPACK2(state.depth_range));
157 }
158
159 if (changed.stencil_compare_mask != 0 || changed.stencil_reference != 0 ||
160 changed.stencil_write_mask != 0)
161 {
162 set_stencil_mask((eGPUStencilTest)current_.stencil_test, state);
163 }
164
165 current_mutable_ = state;
166}
167
170/* -------------------------------------------------------------------- */
174void GLStateManager::set_write_mask(const eGPUWriteMask value)
175{
176 glDepthMask((value & GPU_WRITE_DEPTH) != 0);
177 glColorMask((value & GPU_WRITE_RED) != 0,
178 (value & GPU_WRITE_GREEN) != 0,
179 (value & GPU_WRITE_BLUE) != 0,
180 (value & GPU_WRITE_ALPHA) != 0);
181
182 if (value == GPU_WRITE_NONE) {
183 glEnable(GL_RASTERIZER_DISCARD);
184 }
185 else {
186 glDisable(GL_RASTERIZER_DISCARD);
187 }
188}
189
190void GLStateManager::set_depth_test(const eGPUDepthTest value)
191{
192 GLenum func;
193 switch (value) {
194 case GPU_DEPTH_LESS:
195 func = GL_LESS;
196 break;
198 func = GL_LEQUAL;
199 break;
200 case GPU_DEPTH_EQUAL:
201 func = GL_EQUAL;
202 break;
204 func = GL_GREATER;
205 break;
207 func = GL_GEQUAL;
208 break;
209 case GPU_DEPTH_ALWAYS:
210 default:
211 func = GL_ALWAYS;
212 break;
213 }
214
215 if (value != GPU_DEPTH_NONE) {
216 glEnable(GL_DEPTH_TEST);
217 glDepthFunc(func);
218 }
219 else {
220 glDisable(GL_DEPTH_TEST);
221 }
222}
223
224void GLStateManager::set_stencil_test(const eGPUStencilTest test, const eGPUStencilOp operation)
225{
226 switch (operation) {
228 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
229 break;
231 glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR_WRAP);
232 glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR_WRAP);
233 break;
235 glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_KEEP);
236 glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_KEEP);
237 break;
239 default:
240 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
241 }
242
243 if (test != GPU_STENCIL_NONE) {
244 glEnable(GL_STENCIL_TEST);
245 }
246 else {
247 glDisable(GL_STENCIL_TEST);
248 }
249}
250
251void GLStateManager::set_stencil_mask(const eGPUStencilTest test, const GPUStateMutable &state)
252{
253 GLenum func;
254 switch (test) {
256 func = GL_NOTEQUAL;
257 break;
259 func = GL_EQUAL;
260 break;
262 func = GL_ALWAYS;
263 break;
264 case GPU_STENCIL_NONE:
265 default:
266 glStencilMask(0x00);
267 glStencilFunc(GL_ALWAYS, 0x00, 0x00);
268 return;
269 }
270
271 glStencilMask(state.stencil_write_mask);
272 glStencilFunc(func, state.stencil_reference, state.stencil_compare_mask);
273}
274
275void GLStateManager::set_clip_distances(const int new_dist_len, const int old_dist_len)
276{
277 for (int i = 0; i < new_dist_len; i++) {
278 glEnable(GL_CLIP_DISTANCE0 + i);
279 }
280 for (int i = new_dist_len; i < old_dist_len; i++) {
281 glDisable(GL_CLIP_DISTANCE0 + i);
282 }
283}
284
285void GLStateManager::set_logic_op(const bool enable)
286{
287 if (enable) {
288 glEnable(GL_COLOR_LOGIC_OP);
289 glLogicOp(GL_XOR);
290 }
291 else {
292 glDisable(GL_COLOR_LOGIC_OP);
293 }
294}
295
296void GLStateManager::set_facing(const bool invert)
297{
298 glFrontFace((invert) ? GL_CW : GL_CCW);
299}
300
301void GLStateManager::set_backface_culling(const eGPUFaceCullTest test)
302{
303 if (test != GPU_CULL_NONE) {
304 glEnable(GL_CULL_FACE);
305 glCullFace((test == GPU_CULL_FRONT) ? GL_FRONT : GL_BACK);
306 }
307 else {
308 glDisable(GL_CULL_FACE);
309 }
310}
311
312void GLStateManager::set_provoking_vert(const eGPUProvokingVertex vert)
313{
314 GLenum value = (vert == GPU_VERTEX_FIRST) ? GL_FIRST_VERTEX_CONVENTION :
315 GL_LAST_VERTEX_CONVENTION;
316 glProvokingVertex(value);
317}
318
319void GLStateManager::set_shadow_bias(const bool enable)
320{
321 if (enable) {
322 glEnable(GL_POLYGON_OFFSET_FILL);
323 glEnable(GL_POLYGON_OFFSET_LINE);
324 /* 2.0 Seems to be the lowest possible slope bias that works in every case. */
325 glPolygonOffset(2.0f, 1.0f);
326 }
327 else {
328 glDisable(GL_POLYGON_OFFSET_FILL);
329 glDisable(GL_POLYGON_OFFSET_LINE);
330 }
331}
332
333void GLStateManager::set_blend(const eGPUBlend value)
334{
342 GLenum src_rgb, src_alpha, dst_rgb, dst_alpha;
343 switch (value) {
344 default:
345 case GPU_BLEND_ALPHA: {
346 src_rgb = GL_SRC_ALPHA;
347 dst_rgb = GL_ONE_MINUS_SRC_ALPHA;
348 src_alpha = GL_ONE;
349 dst_alpha = GL_ONE_MINUS_SRC_ALPHA;
350 break;
351 }
353 src_rgb = GL_ONE;
354 dst_rgb = GL_ONE_MINUS_SRC_ALPHA;
355 src_alpha = GL_ONE;
356 dst_alpha = GL_ONE_MINUS_SRC_ALPHA;
357 break;
358 }
359 case GPU_BLEND_ADDITIVE: {
360 /* Do not let alpha accumulate but pre-multiply the source RGB by it. */
361 src_rgb = GL_SRC_ALPHA;
362 dst_rgb = GL_ONE;
363 src_alpha = GL_ZERO;
364 dst_alpha = GL_ONE;
365 break;
366 }
369 /* Let alpha accumulate. */
370 src_rgb = GL_ONE;
371 dst_rgb = GL_ONE;
372 src_alpha = GL_ONE;
373 dst_alpha = GL_ONE;
374 break;
375 }
376 case GPU_BLEND_MULTIPLY: {
377 src_rgb = GL_DST_COLOR;
378 dst_rgb = GL_ZERO;
379 src_alpha = GL_DST_ALPHA;
380 dst_alpha = GL_ZERO;
381 break;
382 }
383 case GPU_BLEND_INVERT: {
384 src_rgb = GL_ONE_MINUS_DST_COLOR;
385 dst_rgb = GL_ZERO;
386 src_alpha = GL_ZERO;
387 dst_alpha = GL_ONE;
388 break;
389 }
390 case GPU_BLEND_OIT: {
391 src_rgb = GL_ONE;
392 dst_rgb = GL_ONE;
393 src_alpha = GL_ZERO;
394 dst_alpha = GL_ONE_MINUS_SRC_ALPHA;
395 break;
396 }
398 src_rgb = GL_ONE_MINUS_DST_ALPHA;
399 dst_rgb = GL_SRC_ALPHA;
400 src_alpha = GL_ZERO;
401 dst_alpha = GL_SRC_ALPHA;
402 break;
403 }
405 src_rgb = GL_ONE_MINUS_DST_ALPHA;
406 dst_rgb = GL_ONE;
407 src_alpha = GL_ONE_MINUS_DST_ALPHA;
408 dst_alpha = GL_ONE;
409 break;
410 }
411 case GPU_BLEND_CUSTOM: {
412 src_rgb = GL_ONE;
413 dst_rgb = GL_SRC1_COLOR;
414 src_alpha = GL_ONE;
415 dst_alpha = GL_SRC1_ALPHA;
416 break;
417 }
418 }
419
420 if (value == GPU_BLEND_SUBTRACT) {
421 glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
422 }
423 else {
424 glBlendEquation(GL_FUNC_ADD);
425 }
426
427 /* Always set the blend function. This avoid a rendering error when blending is disabled but
428 * GPU_BLEND_CUSTOM was used just before and the frame-buffer is using more than 1 color target.
429 */
430 glBlendFuncSeparate(src_rgb, dst_rgb, src_alpha, dst_alpha);
431 if (value != GPU_BLEND_NONE) {
432 glEnable(GL_BLEND);
433 }
434 else {
435 glDisable(GL_BLEND);
436 }
437}
438
441/* -------------------------------------------------------------------- */
445void GLStateManager::texture_bind(Texture *tex_, GPUSamplerState sampler_state, int unit)
446{
448 GLTexture *tex = static_cast<GLTexture *>(tex_);
449 if (G.debug & G_DEBUG_GPU) {
450 tex->check_feedback_loop();
451 }
452 /* Eliminate redundant binds. */
453 if ((textures_[unit] == tex->tex_id_) &&
454 (samplers_[unit] == GLTexture::get_sampler(sampler_state)))
455 {
456 return;
457 }
458 targets_[unit] = tex->target_;
459 textures_[unit] = tex->tex_id_;
460 samplers_[unit] = GLTexture::get_sampler(sampler_state);
461 tex->is_bound_ = true;
462 dirty_texture_binds_ |= 1ULL << unit;
463}
464
466{
467 glActiveTexture(GL_TEXTURE0);
468 glBindTexture(tex->target_, tex->tex_id_);
469 /* Will reset the first texture that was originally bound to slot 0 back before drawing. */
470 dirty_texture_binds_ |= 1ULL;
471 /* NOTE: This might leave this texture attached to this target even after update.
472 * In practice it is not causing problems as we have incorrect binding detection
473 * at higher level. */
474}
475
477{
478 GLTexture *tex = static_cast<GLTexture *>(tex_);
479 if (!tex->is_bound_) {
480 return;
481 }
482
483 GLuint tex_id = tex->tex_id_;
484 for (int i = 0; i < ARRAY_SIZE(textures_); i++) {
485 if (textures_[i] == tex_id) {
486 textures_[i] = 0;
487 samplers_[i] = 0;
488 dirty_texture_binds_ |= 1ULL << i;
489 }
490 }
491 tex->is_bound_ = false;
492}
493
495{
496 for (int i = 0; i < ARRAY_SIZE(textures_); i++) {
497 if (textures_[i] != 0) {
498 textures_[i] = 0;
499 samplers_[i] = 0;
500 dirty_texture_binds_ |= 1ULL << i;
501 }
502 }
503 this->texture_bind_apply();
504}
505
506void GLStateManager::texture_bind_apply()
507{
508 if (dirty_texture_binds_ == 0) {
509 return;
510 }
511 uint64_t dirty_bind = dirty_texture_binds_;
512 dirty_texture_binds_ = 0;
513
514 int first = bitscan_forward_uint64(dirty_bind);
515 int last = 64 - bitscan_reverse_uint64(dirty_bind);
516 int count = last - first;
517
519 glBindTextures(first, count, textures_ + first);
520 glBindSamplers(first, count, samplers_ + first);
521 }
522 else {
523 for (int unit = first; unit < last; unit++) {
524 if ((dirty_bind >> unit) & 1UL) {
525 glActiveTexture(GL_TEXTURE0 + unit);
526 glBindTexture(targets_[unit], textures_[unit]);
527 glBindSampler(unit, samplers_[unit]);
528 }
529 }
530 }
531}
532
534{
535 glPixelStorei(GL_UNPACK_ROW_LENGTH, len);
536}
537
539{
540 uint64_t bound_slots = 0;
541 for (int i = 0; i < ARRAY_SIZE(textures_); i++) {
542 if (textures_[i] != 0) {
543 bound_slots |= 1ULL << i;
544 }
545 }
546 return bound_slots;
547}
548
551/* -------------------------------------------------------------------- */
556{
557 /* Minimum support is 8 image in the fragment shader. No image for other stages. */
558 BLI_assert(unit < 8);
559 GLTexture *tex = static_cast<GLTexture *>(tex_);
560 if (G.debug & G_DEBUG_GPU) {
561 tex->check_feedback_loop();
562 }
563 images_[unit] = tex->tex_id_;
564 formats_[unit] = to_gl_internal_format(tex->format_);
565 tex->is_bound_image_ = true;
566 dirty_image_binds_ |= 1ULL << unit;
567}
568
570{
571 GLTexture *tex = static_cast<GLTexture *>(tex_);
572 if (!tex->is_bound_image_) {
573 return;
574 }
575
576 GLuint tex_id = tex->tex_id_;
577 for (int i = 0; i < ARRAY_SIZE(images_); i++) {
578 if (images_[i] == tex_id) {
579 images_[i] = 0;
580 dirty_image_binds_ |= 1ULL << i;
581 }
582 }
583 tex->is_bound_image_ = false;
584}
585
587{
588 for (int i = 0; i < ARRAY_SIZE(images_); i++) {
589 if (images_[i] != 0) {
590 images_[i] = 0;
591 dirty_image_binds_ |= 1ULL << i;
592 }
593 }
594 this->image_bind_apply();
595}
596
597void GLStateManager::image_bind_apply()
598{
599 if (dirty_image_binds_ == 0) {
600 return;
601 }
602 uint32_t dirty_bind = dirty_image_binds_;
603 dirty_image_binds_ = 0;
604
605 int first = bitscan_forward_uint(dirty_bind);
606 int last = 32 - bitscan_reverse_uint(dirty_bind);
607 int count = last - first;
608
610 glBindImageTextures(first, count, images_ + first);
611 }
612 else {
613 for (int unit = first; unit < last; unit++) {
614 if ((dirty_bind >> unit) & 1UL) {
615 glBindImageTexture(unit, images_[unit], 0, GL_TRUE, 0, GL_READ_WRITE, formats_[unit]);
616 }
617 }
618 }
619}
620
622{
623 uint8_t bound_slots = 0;
624 for (int i = 0; i < ARRAY_SIZE(images_); i++) {
625 if (images_[i] != 0) {
626 bound_slots |= 1ULL << i;
627 }
628 }
629 return bound_slots;
630}
631
634/* -------------------------------------------------------------------- */
639{
640 glMemoryBarrier(to_gl(barrier_bits));
641}
642
644{
645 if (gl_sync_ != nullptr) {
646 glDeleteSync(gl_sync_);
647 gl_sync_ = nullptr;
648 }
649}
650
652{
653 /* If fence is already signalled, create a newly signalled fence primitive. */
654 if (gl_sync_) {
655 glDeleteSync(gl_sync_);
656 }
657
658 gl_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
659 signalled_ = true;
660}
661
663{
664 /* Do not wait if fence does not yet exist. */
665 if (gl_sync_ == nullptr) {
666 return;
667 }
668 glWaitSync(gl_sync_, 0, GL_TIMEOUT_IGNORED);
669 signalled_ = false;
670}
673} // namespace blender::gpu
@ G_DEBUG_GPU
#define BLI_assert(a)
Definition BLI_assert.h:50
MINLINE float clamp_f(float value, float min, float max)
MINLINE unsigned int bitscan_forward_uint(unsigned int a)
MINLINE unsigned int float_as_uint(float f)
MINLINE unsigned int bitscan_reverse_uint(unsigned int a)
MINLINE unsigned int bitscan_forward_uint64(unsigned long long a)
MINLINE unsigned int bitscan_reverse_uint64(unsigned long long a)
unsigned int uint
#define UNPACK2(a)
#define ARRAY_SIZE(arr)
int GPU_max_textures()
eGPUBlend
Definition GPU_state.hh:84
@ GPU_BLEND_ADDITIVE_PREMULT
Definition GPU_state.hh:90
@ GPU_BLEND_INVERT
Definition GPU_state.hh:95
@ GPU_BLEND_OIT
Definition GPU_state.hh:98
@ GPU_BLEND_MULTIPLY
Definition GPU_state.hh:91
@ GPU_BLEND_NONE
Definition GPU_state.hh:85
@ GPU_BLEND_ALPHA
Definition GPU_state.hh:87
@ GPU_BLEND_CUSTOM
Definition GPU_state.hh:103
@ GPU_BLEND_ADDITIVE
Definition GPU_state.hh:89
@ GPU_BLEND_SUBTRACT
Definition GPU_state.hh:92
@ GPU_BLEND_ALPHA_UNDER_PREMUL
Definition GPU_state.hh:104
@ GPU_BLEND_BACKGROUND
Definition GPU_state.hh:100
@ GPU_BLEND_ALPHA_PREMULT
Definition GPU_state.hh:88
eGPUWriteMask
Definition GPU_state.hh:16
@ GPU_WRITE_RED
Definition GPU_state.hh:18
@ GPU_WRITE_NONE
Definition GPU_state.hh:17
@ 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_ALPHA
Definition GPU_state.hh:21
eGPUProvokingVertex
Definition GPU_state.hh:138
@ GPU_VERTEX_FIRST
Definition GPU_state.hh:140
eGPUFaceCullTest
Definition GPU_state.hh:132
@ GPU_CULL_FRONT
Definition GPU_state.hh:134
@ GPU_CULL_NONE
Definition GPU_state.hh:133
eGPUBarrier
Definition GPU_state.hh:29
eGPUStencilOp
Definition GPU_state.hh:124
@ GPU_STENCIL_OP_COUNT_DEPTH_FAIL
Definition GPU_state.hh:129
@ GPU_STENCIL_OP_COUNT_DEPTH_PASS
Definition GPU_state.hh:128
@ GPU_STENCIL_OP_REPLACE
Definition GPU_state.hh:126
@ GPU_STENCIL_OP_NONE
Definition GPU_state.hh:125
eGPUDepthTest
Definition GPU_state.hh:107
@ GPU_DEPTH_GREATER
Definition GPU_state.hh:113
@ GPU_DEPTH_EQUAL
Definition GPU_state.hh:112
@ GPU_DEPTH_ALWAYS
Definition GPU_state.hh:109
@ GPU_DEPTH_GREATER_EQUAL
Definition GPU_state.hh:114
@ GPU_DEPTH_LESS
Definition GPU_state.hh:110
@ 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_EQUAL
Definition GPU_state.hh:120
@ GPU_STENCIL_NEQUAL
Definition GPU_state.hh:121
@ GPU_STENCIL_ALWAYS
Definition GPU_state.hh:119
@ GPU_STENCIL_NONE
Definition GPU_state.hh:118
static bool multi_bind_support
Definition gl_context.hh:57
static bool multi_bind_image_support
Definition gl_context.hh:58
void signal() override
Definition gl_state.cc:651
void wait() override
Definition gl_state.cc:662
void texture_bind_temp(GLTexture *tex)
Definition gl_state.cc:465
GLFrameBuffer * active_fb
Definition gl_state.hh:32
void image_unbind(Texture *tex) override
Definition gl_state.cc:569
void image_bind(Texture *tex, int unit) override
Definition gl_state.cc:555
void apply_state() override
Definition gl_state.cc:54
void texture_unpack_row_length_set(uint len) override
Definition gl_state.cc:533
void issue_barrier(eGPUBarrier barrier_bits) override
Definition gl_state.cc:638
void texture_unbind_all() override
Definition gl_state.cc:494
void force_state() override
Definition gl_state.cc:66
void texture_bind(Texture *tex, GPUSamplerState sampler, int unit) override
Definition gl_state.cc:445
void image_unbind_all() override
Definition gl_state.cc:586
void texture_unbind(Texture *tex) override
Definition gl_state.cc:476
static GLuint get_sampler(const GPUSamplerState &sampler_state)
#define fabsf(x)
int len
int count
CCL_NAMESPACE_BEGIN ccl_device float invert(float color, float factor)
Definition invert.h:9
static ulong state[N]
#define G(x, y, z)
GLenum to_gl_internal_format(eGPUTextureFormat format)
static GLenum to_gl(const GPUAttachmentType type)
unsigned int uint32_t
Definition stdint.h:80
unsigned char uint8_t
Definition stdint.h:78
unsigned __int64 uint64_t
Definition stdint.h:90