Blender  V2.93
gl_texture.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2020 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "BKE_global.h"
25 
26 #include "DNA_userdef_types.h"
27 
28 #include "GPU_capabilities.h"
29 #include "GPU_framebuffer.h"
30 #include "GPU_platform.h"
31 
32 #include "gl_backend.hh"
33 #include "gl_debug.hh"
34 #include "gl_state.hh"
35 #include "gpu_vertex_buffer_private.hh" /* TODO should be `gl_vertex_buffer.hh` */
36 
37 #include "gl_texture.hh"
38 
39 namespace blender::gpu {
40 
41 /* -------------------------------------------------------------------- */
45 GLTexture::GLTexture(const char *name) : Texture(name)
46 {
47  BLI_assert(GLContext::get() != nullptr);
48 
49  glGenTextures(1, &tex_id_);
50 }
51 
53 {
54  if (framebuffer_) {
55  GPU_framebuffer_free(framebuffer_);
56  }
57  GLContext *ctx = GLContext::get();
58  if (ctx != nullptr && is_bound_) {
59  /* This avoid errors when the texture is still inside the bound texture array. */
60  ctx->state_manager->texture_unbind(this);
61  }
62  GLContext::tex_free(tex_id_);
63 }
64 
65 /* Return true on success. */
67 {
69  /* MacOS + Radeon Pro fails to blit depth on GPU_DEPTH24_STENCIL8
70  * but works on GPU_DEPTH32F_STENCIL8. */
72  }
73 
75  /* Silently fail and let the caller handle the error. */
76  // debug::raise_gl_error("Attempt to create a cubemap array without hardware support!");
77  return false;
78  }
79 
80  target_ = to_gl_target(type_);
81 
82  /* We need to bind once to define the texture type. */
84 
85  if (!this->proxy_check(0)) {
86  return false;
87  }
88 
89  this->ensure_mipmaps(0);
90 
91  /* Avoid issue with incomplete textures. */
93  glTextureParameteri(tex_id_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
94  }
95  else {
96  glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
97  }
98 
99  debug::object_label(GL_TEXTURE, tex_id_, name_);
100  return true;
101 }
102 
103 /* Return true on success. */
105 {
106  GLVertBuf *gl_vbo = static_cast<GLVertBuf *>(unwrap(vbo));
107  target_ = to_gl_target(type_);
108 
109  /* We need to bind once to define the texture type. */
111 
112  GLenum internal_format = to_gl_internal_format(format_);
113 
115  glTextureBuffer(tex_id_, internal_format, gl_vbo->vbo_id_);
116  }
117  else {
118  glTexBuffer(target_, internal_format, gl_vbo->vbo_id_);
119  }
120 
121  debug::object_label(GL_TEXTURE, tex_id_, name_);
122 
123  return true;
124 }
125 
126 /* Will create enough mipmaps up to get to the given level. */
127 void GLTexture::ensure_mipmaps(int miplvl)
128 {
129  int effective_h = (type_ == GPU_TEXTURE_1D_ARRAY) ? 0 : h_;
130  int effective_d = (type_ != GPU_TEXTURE_3D) ? 0 : d_;
131  int max_dimension = max_iii(w_, effective_h, effective_d);
132  int max_miplvl = floor(log2(max_dimension));
133  miplvl = min_ii(miplvl, max_miplvl);
134 
135  while (mipmaps_ < miplvl) {
136  int mip = ++mipmaps_;
137  const int dimensions = this->dimensions_count();
138 
139  int w = mip_width_get(mip);
140  int h = mip_height_get(mip);
141  int d = mip_depth_get(mip);
142  GLenum internal_format = to_gl_internal_format(format_);
143  GLenum gl_format = to_gl_data_format(format_);
144  GLenum gl_type = to_gl(to_data_format(format_));
145 
147 
148  if (type_ == GPU_TEXTURE_CUBE) {
149  for (int i = 0; i < d; i++) {
150  GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
151  glTexImage2D(target, mip, internal_format, w, h, 0, gl_format, gl_type, nullptr);
152  }
153  }
154  else if (format_flag_ & GPU_FORMAT_COMPRESSED) {
155  size_t size = ((w + 3) / 4) * ((h + 3) / 4) * to_block_size(format_);
156  switch (dimensions) {
157  default:
158  case 1:
159  glCompressedTexImage1D(target_, mip, internal_format, w, 0, size, nullptr);
160  break;
161  case 2:
162  glCompressedTexImage2D(target_, mip, internal_format, w, h, 0, size, nullptr);
163  break;
164  case 3:
165  glCompressedTexImage3D(target_, mip, internal_format, w, h, d, 0, size, nullptr);
166  break;
167  }
168  }
169  else {
170  switch (dimensions) {
171  default:
172  case 1:
173  glTexImage1D(target_, mip, internal_format, w, 0, gl_format, gl_type, nullptr);
174  break;
175  case 2:
176  glTexImage2D(target_, mip, internal_format, w, h, 0, gl_format, gl_type, nullptr);
177  break;
178  case 3:
179  glTexImage3D(target_, mip, internal_format, w, h, d, 0, gl_format, gl_type, nullptr);
180  break;
181  }
182  }
183  }
184 
185  this->mip_range_set(0, mipmaps_);
186 }
187 
190 /* -------------------------------------------------------------------- */
194 void GLTexture::update_sub_direct_state_access(
195  int mip, int offset[3], int extent[3], GLenum format, GLenum type, const void *data)
196 {
198  size_t size = ((extent[0] + 3) / 4) * ((extent[1] + 3) / 4) * to_block_size(format_);
199  switch (this->dimensions_count()) {
200  default:
201  case 1:
202  glCompressedTextureSubImage1D(tex_id_, mip, offset[0], extent[0], format, size, data);
203  break;
204  case 2:
205  glCompressedTextureSubImage2D(
206  tex_id_, mip, UNPACK2(offset), UNPACK2(extent), format, size, data);
207  break;
208  case 3:
209  glCompressedTextureSubImage3D(
210  tex_id_, mip, UNPACK3(offset), UNPACK3(extent), format, size, data);
211  break;
212  }
213  }
214  else {
215  switch (this->dimensions_count()) {
216  default:
217  case 1:
218  glTextureSubImage1D(tex_id_, mip, offset[0], extent[0], format, type, data);
219  break;
220  case 2:
221  glTextureSubImage2D(tex_id_, mip, UNPACK2(offset), UNPACK2(extent), format, type, data);
222  break;
223  case 3:
224  glTextureSubImage3D(tex_id_, mip, UNPACK3(offset), UNPACK3(extent), format, type, data);
225  break;
226  }
227  }
228 
229  has_pixels_ = true;
230 }
231 
233  int mip, int offset[3], int extent[3], eGPUDataFormat type, const void *data)
234 {
236  BLI_assert(data != nullptr);
237 
238  this->ensure_mipmaps(mip);
239 
240  if (mip > mipmaps_) {
241  debug::raise_gl_error("Updating a miplvl on a texture too small to have this many levels.");
242  return;
243  }
244 
245  const int dimensions = this->dimensions_count();
246  GLenum gl_format = to_gl_data_format(format_);
247  GLenum gl_type = to_gl(type);
248 
249  /* Some drivers have issues with cubemap & glTextureSubImage3D even if it is correct. */
251  this->update_sub_direct_state_access(mip, offset, extent, gl_format, gl_type, data);
252  return;
253  }
254 
256  if (type_ == GPU_TEXTURE_CUBE) {
257  for (int i = 0; i < extent[2]; i++) {
258  GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + offset[2] + i;
259  glTexSubImage2D(target, mip, UNPACK2(offset), UNPACK2(extent), gl_format, gl_type, data);
260  }
261  }
262  else if (format_flag_ & GPU_FORMAT_COMPRESSED) {
263  size_t size = ((extent[0] + 3) / 4) * ((extent[1] + 3) / 4) * to_block_size(format_);
264  switch (dimensions) {
265  default:
266  case 1:
267  glCompressedTexSubImage1D(target_, mip, offset[0], extent[0], gl_format, size, data);
268  break;
269  case 2:
270  glCompressedTexSubImage2D(
271  target_, mip, UNPACK2(offset), UNPACK2(extent), gl_format, size, data);
272  break;
273  case 3:
274  glCompressedTexSubImage3D(
275  target_, mip, UNPACK3(offset), UNPACK3(extent), gl_format, size, data);
276  break;
277  }
278  }
279  else {
280  switch (dimensions) {
281  default:
282  case 1:
283  glTexSubImage1D(target_, mip, offset[0], extent[0], gl_format, gl_type, data);
284  break;
285  case 2:
286  glTexSubImage2D(target_, mip, UNPACK2(offset), UNPACK2(extent), gl_format, gl_type, data);
287  break;
288  case 3:
289  glTexSubImage3D(target_, mip, UNPACK3(offset), UNPACK3(extent), gl_format, gl_type, data);
290  break;
291  }
292  }
293 
294  has_pixels_ = true;
295 }
296 
304 {
305  this->ensure_mipmaps(9999);
306  /* Some drivers have bugs when using #glGenerateMipmap with depth textures (see T56789).
307  * In this case we just create a complete texture with mipmaps manually without
308  * down-sampling. You must initialize the texture levels using other methods like
309  * #GPU_framebuffer_recursive_downsample(). */
311  return;
312  }
313 
315  /* Broken glGenerateMipmap, don't call it and render without mipmaps.
316  * If no top level pixels have been filled in, the levels will get filled by
317  * other means and there is no need to disable mipmapping. */
318  if (has_pixels_) {
319  this->mip_range_set(0, 0);
320  }
321  return;
322  }
323 
324  /* Down-sample from mip 0 using implementation. */
326  glGenerateTextureMipmap(tex_id_);
327  }
328  else {
330  glGenerateMipmap(target_);
331  }
332 }
333 
334 void GLTexture::clear(eGPUDataFormat data_format, const void *data)
335 {
336  BLI_assert(validate_data_format(format_, data_format));
337 
339  int mip = 0;
340  GLenum gl_format = to_gl_data_format(format_);
341  GLenum gl_type = to_gl(data_format);
342  glClearTexImage(tex_id_, mip, gl_format, gl_type, data);
343  }
344  else {
345  /* Fallback for older GL. */
347 
348  FrameBuffer *fb = reinterpret_cast<FrameBuffer *>(this->framebuffer_get());
349  fb->bind(true);
350  fb->clear_attachment(this->attachment_type(0), data_format, data);
351 
352  GPU_framebuffer_bind(prev_fb);
353  }
354 
355  has_pixels_ = true;
356 }
357 
359 {
360  GLTexture *dst = static_cast<GLTexture *>(dst_);
361  GLTexture *src = this;
362 
363  BLI_assert((dst->w_ == src->w_) && (dst->h_ == src->h_) && (dst->d_ == src->d_));
364  BLI_assert(dst->format_ == src->format_);
365  BLI_assert(dst->type_ == src->type_);
366  /* TODO support array / 3D textures. */
367  BLI_assert(dst->d_ == 0);
368 
370  int mip = 0;
371  /* NOTE: mip_size_get() won't override any dimension that is equal to 0. */
372  int extent[3] = {1, 1, 1};
373  this->mip_size_get(mip, extent);
374  glCopyImageSubData(
375  src->tex_id_, target_, mip, 0, 0, 0, dst->tex_id_, target_, mip, 0, 0, 0, UNPACK3(extent));
376  }
377  else {
378  /* Fallback for older GL. */
380  src->framebuffer_get(), 0, dst->framebuffer_get(), 0, to_framebuffer_bits(format_));
381  }
382 
383  has_pixels_ = true;
384 }
385 
387 {
389  BLI_assert(mip <= mipmaps_);
391 
392  /* NOTE: mip_size_get() won't override any dimension that is equal to 0. */
393  int extent[3] = {1, 1, 1};
394  this->mip_size_get(mip, extent);
395 
396  size_t sample_len = extent[0] * extent[1] * extent[2];
397  size_t sample_size = to_bytesize(format_, type);
398  size_t texture_size = sample_len * sample_size;
399 
400  /* AMD Pro driver have a bug that write 8 bytes past buffer size
401  * if the texture is big. (see T66573) */
402  void *data = MEM_mallocN(texture_size + 8, "GPU_texture_read");
403 
404  GLenum gl_format = to_gl_data_format(format_);
405  GLenum gl_type = to_gl(type);
406 
408  glGetTextureImage(tex_id_, mip, gl_format, gl_type, texture_size, data);
409  }
410  else {
412  if (type_ == GPU_TEXTURE_CUBE) {
413  size_t cube_face_size = texture_size / 6;
414  char *face_data = (char *)data;
415  for (int i = 0; i < 6; i++, face_data += cube_face_size) {
416  glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, mip, gl_format, gl_type, face_data);
417  }
418  }
419  else {
420  glGetTexImage(target_, mip, gl_format, gl_type, data);
421  }
422  }
423  return data;
424 }
425 
428 /* -------------------------------------------------------------------- */
432 void GLTexture::swizzle_set(const char swizzle[4])
433 {
434  GLint gl_swizzle[4] = {(GLint)swizzle_to_gl(swizzle[0]),
435  (GLint)swizzle_to_gl(swizzle[1]),
436  (GLint)swizzle_to_gl(swizzle[2]),
437  (GLint)swizzle_to_gl(swizzle[3])};
439  glTextureParameteriv(tex_id_, GL_TEXTURE_SWIZZLE_RGBA, gl_swizzle);
440  }
441  else {
443  glTexParameteriv(target_, GL_TEXTURE_SWIZZLE_RGBA, gl_swizzle);
444  }
445 }
446 
448 {
449  BLI_assert(min <= max && min >= 0 && max <= mipmaps_);
450  mip_min_ = min;
451  mip_max_ = max;
453  glTextureParameteri(tex_id_, GL_TEXTURE_BASE_LEVEL, min);
454  glTextureParameteri(tex_id_, GL_TEXTURE_MAX_LEVEL, max);
455  }
456  else {
458  glTexParameteri(target_, GL_TEXTURE_BASE_LEVEL, min);
459  glTexParameteri(target_, GL_TEXTURE_MAX_LEVEL, max);
460  }
461 }
462 
463 struct GPUFrameBuffer *GLTexture::framebuffer_get()
464 {
465  if (framebuffer_) {
466  return framebuffer_;
467  }
469  /* TODO(fclem): cleanup this. Don't use GPU object but blender::gpu ones. */
470  GPUTexture *gputex = reinterpret_cast<GPUTexture *>(static_cast<Texture *>(this));
471  framebuffer_ = GPU_framebuffer_create(name_);
472  GPU_framebuffer_texture_attach(framebuffer_, gputex, 0, 0);
473  has_pixels_ = true;
474  return framebuffer_;
475 }
476 
479 /* -------------------------------------------------------------------- */
483 GLuint GLTexture::samplers_[GPU_SAMPLER_MAX] = {0};
484 
486 {
487  glGenSamplers(GPU_SAMPLER_MAX, samplers_);
488  for (int i = 0; i <= GPU_SAMPLER_ICON - 1; i++) {
489  eGPUSamplerState state = static_cast<eGPUSamplerState>(i);
490  GLenum clamp_type = (state & GPU_SAMPLER_CLAMP_BORDER) ? GL_CLAMP_TO_BORDER : GL_CLAMP_TO_EDGE;
491  GLenum wrap_s = (state & GPU_SAMPLER_REPEAT_S) ? GL_REPEAT : clamp_type;
492  GLenum wrap_t = (state & GPU_SAMPLER_REPEAT_T) ? GL_REPEAT : clamp_type;
493  GLenum wrap_r = (state & GPU_SAMPLER_REPEAT_R) ? GL_REPEAT : clamp_type;
494  GLenum mag_filter = (state & GPU_SAMPLER_FILTER) ? GL_LINEAR : GL_NEAREST;
495  GLenum min_filter = (state & GPU_SAMPLER_FILTER) ?
496  ((state & GPU_SAMPLER_MIPMAP) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR) :
497  ((state & GPU_SAMPLER_MIPMAP) ? GL_NEAREST_MIPMAP_LINEAR : GL_NEAREST);
498  GLenum compare_mode = (state & GPU_SAMPLER_COMPARE) ? GL_COMPARE_REF_TO_TEXTURE : GL_NONE;
499 
500  glSamplerParameteri(samplers_[i], GL_TEXTURE_WRAP_S, wrap_s);
501  glSamplerParameteri(samplers_[i], GL_TEXTURE_WRAP_T, wrap_t);
502  glSamplerParameteri(samplers_[i], GL_TEXTURE_WRAP_R, wrap_r);
503  glSamplerParameteri(samplers_[i], GL_TEXTURE_MIN_FILTER, min_filter);
504  glSamplerParameteri(samplers_[i], GL_TEXTURE_MAG_FILTER, mag_filter);
505  glSamplerParameteri(samplers_[i], GL_TEXTURE_COMPARE_MODE, compare_mode);
506  glSamplerParameteri(samplers_[i], GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
507 
515  char sampler_name[128] = "\0\0";
516  SNPRINTF(sampler_name,
517  "%s%s%s%s%s%s%s%s%s%s",
518  (state == GPU_SAMPLER_DEFAULT) ? "_default" : "",
519  (state & GPU_SAMPLER_FILTER) ? "_filter" : "",
520  (state & GPU_SAMPLER_MIPMAP) ? "_mipmap" : "",
521  (state & GPU_SAMPLER_REPEAT) ? "_repeat-" : "",
522  (state & GPU_SAMPLER_REPEAT_S) ? "S" : "",
523  (state & GPU_SAMPLER_REPEAT_T) ? "T" : "",
524  (state & GPU_SAMPLER_REPEAT_R) ? "R" : "",
525  (state & GPU_SAMPLER_CLAMP_BORDER) ? "_clamp_border" : "",
526  (state & GPU_SAMPLER_COMPARE) ? "_compare" : "",
527  (state & GPU_SAMPLER_ANISO) ? "_aniso" : "");
528  debug::object_label(GL_SAMPLER, samplers_[i], &sampler_name[1]);
529  }
530  samplers_update();
531 
532  /* Custom sampler for icons. */
533  GLuint icon_sampler = samplers_[GPU_SAMPLER_ICON];
534  glSamplerParameteri(icon_sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
535  glSamplerParameteri(icon_sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
536  glSamplerParameterf(icon_sampler, GL_TEXTURE_LOD_BIAS, -0.5f);
537 
538  debug::object_label(GL_SAMPLER, icon_sampler, "icons");
539 }
540 
542 {
544  return;
545  }
546 
547  float max_anisotropy = 1.0f;
548  glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy);
549 
550  float aniso_filter = min_ff(max_anisotropy, U.anisotropic_filter);
551 
552  for (int i = 0; i <= GPU_SAMPLER_ICON - 1; i++) {
553  eGPUSamplerState state = static_cast<eGPUSamplerState>(i);
555  glSamplerParameterf(samplers_[i], GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso_filter);
556  }
557  }
558 }
559 
561 {
562  glDeleteSamplers(GPU_SAMPLER_MAX, samplers_);
563 }
564 
567 /* -------------------------------------------------------------------- */
573 /* NOTE: This only checks if this mipmap is valid / supported.
574  * TODO(fclem): make the check cover the whole mipmap chain. */
575 bool GLTexture::proxy_check(int mip)
576 {
577  /* Manual validation first, since some implementation have issues with proxy creation. */
578  int max_size = GPU_max_texture_size();
579  int max_3d_size = GLContext::max_texture_3d_size;
580  int max_cube_size = GLContext::max_cubemap_size;
581  int size[3] = {1, 1, 1};
582  this->mip_size_get(mip, size);
583 
584  if (type_ & GPU_TEXTURE_ARRAY) {
585  if (this->layer_count() > GPU_max_texture_layers()) {
586  return false;
587  }
588  }
589 
590  if (type_ == GPU_TEXTURE_3D) {
591  if (size[0] > max_3d_size || size[1] > max_3d_size || size[2] > max_3d_size) {
592  return false;
593  }
594  }
595  else if ((type_ & ~GPU_TEXTURE_ARRAY) == GPU_TEXTURE_2D) {
596  if (size[0] > max_size || size[1] > max_size) {
597  return false;
598  }
599  }
600  else if ((type_ & ~GPU_TEXTURE_ARRAY) == GPU_TEXTURE_1D) {
601  if (size[0] > max_size) {
602  return false;
603  }
604  }
605  else if ((type_ & ~GPU_TEXTURE_ARRAY) == GPU_TEXTURE_CUBE) {
606  if (size[0] > max_cube_size) {
607  return false;
608  }
609  }
610 
614  /* Some AMD drivers have a faulty `GL_PROXY_TEXTURE_..` check.
615  * (see T55888, T56185, T59351).
616  * Checking with `GL_PROXY_TEXTURE_..` doesn't prevent `Out Of Memory` issue,
617  * it just states that the OGL implementation can support the texture.
618  * So we already manually check the maximum size and maximum number of layers.
619  * Same thing happens on Nvidia/macOS 10.15 (T78175). */
620  return true;
621  }
622 
623  if ((type_ == GPU_TEXTURE_CUBE_ARRAY) &&
625  /* Special fix for T79703. */
626  return true;
627  }
628 
629  GLenum gl_proxy = to_gl_proxy(type_);
630  GLenum internal_format = to_gl_internal_format(format_);
631  GLenum gl_format = to_gl_data_format(format_);
632  GLenum gl_type = to_gl(to_data_format(format_));
633  /* Small exception. */
634  int dimensions = (type_ == GPU_TEXTURE_CUBE) ? 2 : this->dimensions_count();
635 
636  if (format_flag_ & GPU_FORMAT_COMPRESSED) {
637  size_t img_size = ((size[0] + 3) / 4) * ((size[1] + 3) / 4) * to_block_size(format_);
638  switch (dimensions) {
639  default:
640  case 1:
641  glCompressedTexImage1D(gl_proxy, mip, size[0], 0, gl_format, img_size, nullptr);
642  break;
643  case 2:
644  glCompressedTexImage2D(gl_proxy, mip, UNPACK2(size), 0, gl_format, img_size, nullptr);
645  break;
646  case 3:
647  glCompressedTexImage3D(gl_proxy, mip, UNPACK3(size), 0, gl_format, img_size, nullptr);
648  break;
649  }
650  }
651  else {
652  switch (dimensions) {
653  default:
654  case 1:
655  glTexImage1D(gl_proxy, mip, internal_format, size[0], 0, gl_format, gl_type, nullptr);
656  break;
657  case 2:
658  glTexImage2D(
659  gl_proxy, mip, internal_format, UNPACK2(size), 0, gl_format, gl_type, nullptr);
660  break;
661  case 3:
662  glTexImage3D(
663  gl_proxy, mip, internal_format, UNPACK3(size), 0, gl_format, gl_type, nullptr);
664  break;
665  }
666  }
667 
668  int width = 0;
669  glGetTexLevelParameteriv(gl_proxy, 0, GL_TEXTURE_WIDTH, &width);
670  return (width > 0);
671 }
672 
676 {
677  /* Recursive down sample workaround break this check.
678  * See #recursive_downsample() for more information. */
680  return;
681  }
682  GLFrameBuffer *fb = static_cast<GLFrameBuffer *>(GLContext::get()->active_fb);
683  for (int i = 0; i < ARRAY_SIZE(fb_); i++) {
684  if (fb_[i] == fb) {
686  GPUAttachment attachment = fb->attachments_[type];
687  if (attachment.mip <= mip_max_ && attachment.mip >= mip_min_) {
688  char msg[256];
689  SNPRINTF(msg,
690  "Feedback loop: Trying to bind a texture (%s) with mip range %d-%d but mip %d is "
691  "attached to the active framebuffer (%s)",
692  name_,
693  mip_min_,
694  mip_max_,
695  attachment.mip,
696  fb->name_);
698  }
699  return;
700  }
701  }
702 }
703 
704 /* TODO(fclem): Legacy. Should be removed at some point. */
706 {
707  return tex_id_;
708 }
709 
710 } // namespace blender::gpu
#define BLI_assert(a)
Definition: BLI_assert.h:58
MINLINE int min_ii(int a, int b)
MINLINE float min_ff(float a, float b)
MINLINE int max_iii(int a, int b, int c)
#define SNPRINTF(dst, format,...)
Definition: BLI_string.h:165
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNPACK2(a)
#define ARRAY_SIZE(arr)
#define UNPACK3(a)
int GPU_max_texture_size(void)
bool GPU_depth_blitting_workaround(void)
int GPU_max_texture_layers(void)
bool GPU_mip_render_workaround(void)
struct GPUFrameBuffer GPUFrameBuffer
GPUFrameBuffer * GPU_framebuffer_active_get(void)
void GPU_framebuffer_free(GPUFrameBuffer *fb)
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
GPUFrameBuffer * GPU_framebuffer_create(const char *name)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
@ GPU_DRIVER_ANY
Definition: GPU_platform.h:56
@ GPU_DRIVER_OFFICIAL
Definition: GPU_platform.h:53
@ GPU_OS_WIN
Definition: GPU_platform.h:46
@ GPU_OS_UNIX
Definition: GPU_platform.h:48
@ GPU_OS_MAC
Definition: GPU_platform.h:47
@ GPU_DEVICE_ATI
Definition: GPU_platform.h:34
@ GPU_DEVICE_NVIDIA
Definition: GPU_platform.h:33
@ GPU_DEVICE_ANY
Definition: GPU_platform.h:40
bool GPU_type_matches(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver)
eGPUSamplerState
Definition: GPU_texture.h:40
@ GPU_SAMPLER_REPEAT_S
Definition: GPU_texture.h:44
@ GPU_SAMPLER_ANISO
Definition: GPU_texture.h:49
@ GPU_SAMPLER_REPEAT
Definition: GPU_texture.h:52
@ GPU_SAMPLER_MIPMAP
Definition: GPU_texture.h:43
@ GPU_SAMPLER_ICON
Definition: GPU_texture.h:50
@ GPU_SAMPLER_FILTER
Definition: GPU_texture.h:42
@ GPU_SAMPLER_COMPARE
Definition: GPU_texture.h:48
@ GPU_SAMPLER_REPEAT_T
Definition: GPU_texture.h:45
@ GPU_SAMPLER_CLAMP_BORDER
Definition: GPU_texture.h:47
@ GPU_SAMPLER_DEFAULT
Definition: GPU_texture.h:41
@ GPU_SAMPLER_REPEAT_R
Definition: GPU_texture.h:46
struct GPUTexture GPUTexture
Definition: GPU_texture.h:33
eGPUDataFormat
Definition: GPU_texture.h:171
static const int GPU_SAMPLER_MAX
Definition: GPU_texture.h:58
@ GPU_DEPTH32F_STENCIL8
Definition: GPU_texture.h:120
@ GPU_DEPTH24_STENCIL8
Definition: GPU_texture.h:121
struct GPUVertBuf GPUVertBuf
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
unsigned int U
Definition: btGjkEpa3.h:78
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
static GLint max_texture_3d_size
Definition: gl_context.hh:60
static bool copy_image_support
Definition: gl_context.hh:66
static bool direct_state_access_support
Definition: gl_context.hh:68
static GLContext * get()
Definition: gl_context.hh:118
static void tex_free(GLuint tex_id)
Definition: gl_context.cc:269
static bool texture_filter_anisotropic_support
Definition: gl_context.hh:74
static GLStateManager * state_manager_active_get()
Definition: gl_context.hh:123
static bool clear_texture_support
Definition: gl_context.hh:65
static GLint max_cubemap_size
Definition: gl_context.hh:59
static bool texture_cube_map_array_support
Definition: gl_context.hh:73
static bool generate_mipmap_workaround
Definition: gl_context.hh:80
void texture_bind_temp(GLTexture *tex)
Definition: gl_state.cc:485
GLTexture(const char *name)
Definition: gl_texture.cc:45
static void samplers_free(void)
Definition: gl_texture.cc:560
void copy_to(Texture *dst) override
Definition: gl_texture.cc:358
void mip_range_set(int min, int max) override
Definition: gl_texture.cc:447
void check_feedback_loop(void)
Definition: gl_texture.cc:675
uint gl_bindcode_get(void) const override
Definition: gl_texture.cc:705
void generate_mipmap(void) override
Definition: gl_texture.cc:303
void * read(int mip, eGPUDataFormat type) override
Definition: gl_texture.cc:386
static void samplers_update(void)
Definition: gl_texture.cc:541
bool init_internal(void) override
Definition: gl_texture.cc:66
static void samplers_init(void)
Definition: gl_texture.cc:485
void update_sub(int mip, int offset[3], int extent[3], eGPUDataFormat type, const void *data) override
Definition: gl_texture.cc:232
void clear(eGPUDataFormat format, const void *data) override
Definition: gl_texture.cc:334
void swizzle_set(const char swizzle_mask[4]) override
Definition: gl_texture.cc:432
virtual void texture_unbind(Texture *tex)=0
int mip_width_get(int mip) const
eGPUTextureFormat format_
int mip_depth_get(int mip) const
eGPUTextureFormatFlag format_flag_
char name_[DEBUG_NAME_LEN]
FrameBuffer * fb_[GPU_TEX_MAX_FBO_ATTACHED]
GPUAttachmentType fb_attachment_[GPU_TEX_MAX_FBO_ATTACHED]
GPUAttachmentType attachment_type(int slot) const
int mip_height_get(int mip) const
int dimensions_count(void) const
void mip_size_get(int mip, int r_size[3]) const
Texture(const char *name)
Definition: gpu_texture.cc:42
void GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, int mip)
void GPU_framebuffer_blit(GPUFrameBuffer *gpufb_read, int read_slot, GPUFrameBuffer *gpufb_write, int write_slot, eGPUFrameBufferBits blit_buffers)
BLI_INLINE float fb(float length, float L)
format
Definition: logImageCore.h:47
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static ulong state[N]
void raise_gl_error(const char *info)
Definition: gl_debug.cc:282
void object_label(GLenum type, GLuint object, const char *name)
Definition: gl_debug.cc:335
GLenum to_gl_target(eGPUTextureType type)
Definition: gl_texture.hh:202
bool validate_data_format(eGPUTextureFormat tex_format, eGPUDataFormat data_format)
size_t to_block_size(eGPUTextureFormat data_type)
GLenum to_gl_internal_format(eGPUTextureFormat format)
Definition: gl_texture.hh:96
static Context * unwrap(GPUContext *ctx)
eGPUFrameBufferBits to_framebuffer_bits(eGPUTextureFormat tex_format)
GLenum to_gl_proxy(eGPUTextureType type)
Definition: gl_texture.hh:227
GLenum to_gl_data_format(eGPUTextureFormat format)
Definition: gl_texture.hh:298
eGPUDataFormat to_data_format(eGPUTextureFormat tex_format)
GLenum swizzle_to_gl(const char swizzle)
Definition: gl_texture.hh:251
static size_t to_bytesize(GPUIndexBufType type)
static GLenum to_gl(const GPUAttachmentType type)
#define min(a, b)
Definition: sort.c:51
float max
ccl_device_inline float2 floor(const float2 &a)