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