Blender  V3.3
gl_texture.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2020 Blender Foundation. All rights reserved. */
3 
8 #include "DNA_userdef_types.h"
9 
10 #include "GPU_capabilities.h"
11 #include "GPU_framebuffer.h"
12 #include "GPU_platform.h"
13 
14 #include "gl_backend.hh"
15 #include "gl_debug.hh"
16 #include "gl_state.hh"
17 #include "gpu_vertex_buffer_private.hh" /* TODO: should be `gl_vertex_buffer.hh`. */
18 
19 #include "gl_texture.hh"
20 
21 namespace blender::gpu {
22 
23 /* -------------------------------------------------------------------- */
27 GLTexture::GLTexture(const char *name) : Texture(name)
28 {
29  BLI_assert(GLContext::get() != nullptr);
30 
31  glGenTextures(1, &tex_id_);
32 }
33 
35 {
36  if (framebuffer_) {
37  GPU_framebuffer_free(framebuffer_);
38  }
39  GLContext *ctx = GLContext::get();
40  if (ctx != nullptr && is_bound_) {
41  /* This avoid errors when the texture is still inside the bound texture array. */
42  ctx->state_manager->texture_unbind(this);
43  }
44  GLContext::tex_free(tex_id_);
45 }
46 
48 {
50  /* MacOS + Radeon Pro fails to blit depth on GPU_DEPTH24_STENCIL8
51  * but works on GPU_DEPTH32F_STENCIL8. */
53  }
54 
56  /* Silently fail and let the caller handle the error. */
57  // debug::raise_gl_error("Attempt to create a cubemap array without hardware support!");
58  return false;
59  }
60 
61  target_ = to_gl_target(type_);
62 
63  /* We need to bind once to define the texture type. */
65 
66  if (!this->proxy_check(0)) {
67  return false;
68  }
69 
70  GLenum internal_format = to_gl_internal_format(format_);
71  const bool is_cubemap = bool(type_ == GPU_TEXTURE_CUBE);
72  const bool is_layered = bool(type_ & GPU_TEXTURE_ARRAY);
73  const bool is_compressed = bool(format_flag_ & GPU_FORMAT_COMPRESSED);
74  const int dimensions = (is_cubemap) ? 2 : this->dimensions_count();
75  GLenum gl_format = to_gl_data_format(format_);
76  GLenum gl_type = to_gl(to_data_format(format_));
77 
78  auto mip_size = [&](int h, int w = 1, int d = 1) -> size_t {
79  return divide_ceil_u(w, 4) * divide_ceil_u(h, 4) * divide_ceil_u(d, 4) *
81  };
82  switch (dimensions) {
83  default:
84  case 1:
86  glTexStorage1D(target_, mipmaps_, internal_format, w_);
87  }
88  else {
89  for (int i = 0, w = w_; i < mipmaps_; i++) {
90  if (is_compressed) {
91  glCompressedTexImage1D(target_, i, internal_format, w, 0, mip_size(w), nullptr);
92  }
93  else {
94  glTexImage1D(target_, i, internal_format, w, 0, gl_format, gl_type, nullptr);
95  }
96  w = max_ii(1, (w / 2));
97  }
98  }
99  break;
100  case 2:
102  glTexStorage2D(target_, mipmaps_, internal_format, w_, h_);
103  }
104  else {
105  for (int i = 0, w = w_, h = h_; i < mipmaps_; i++) {
106  for (int f = 0; f < (is_cubemap ? 6 : 1); f++) {
107  GLenum target = (is_cubemap) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X + f : target_;
108  if (is_compressed) {
109  glCompressedTexImage2D(target, i, internal_format, w, h, 0, mip_size(w, h), nullptr);
110  }
111  else {
112  glTexImage2D(target, i, internal_format, w, h, 0, gl_format, gl_type, nullptr);
113  }
114  }
115  w = max_ii(1, (w / 2));
116  h = is_layered ? h_ : max_ii(1, (h / 2));
117  }
118  }
119  break;
120  case 3:
122  glTexStorage3D(target_, mipmaps_, internal_format, w_, h_, d_);
123  }
124  else {
125  for (int i = 0, w = w_, h = h_, d = d_; i < mipmaps_; i++) {
126  if (is_compressed) {
127  glCompressedTexImage3D(
128  target_, i, internal_format, w, h, d, 0, mip_size(w, h, d), nullptr);
129  }
130  else {
131  glTexImage3D(target_, i, internal_format, w, h, d, 0, gl_format, gl_type, nullptr);
132  }
133  w = max_ii(1, (w / 2));
134  h = max_ii(1, (h / 2));
135  d = is_layered ? d_ : max_ii(1, (d / 2));
136  }
137  }
138  break;
139  }
140  this->mip_range_set(0, mipmaps_ - 1);
141 
142  /* Avoid issue with formats not supporting filtering. Nearest by default. */
144  glTextureParameteri(tex_id_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
145  }
146  else {
147  glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
148  }
149 
150  debug::object_label(GL_TEXTURE, tex_id_, name_);
151  return true;
152 }
153 
155 {
156  GLVertBuf *gl_vbo = static_cast<GLVertBuf *>(unwrap(vbo));
157  target_ = to_gl_target(type_);
158 
159  /* We need to bind once to define the texture type. */
161 
162  GLenum internal_format = to_gl_internal_format(format_);
163 
165  glTextureBuffer(tex_id_, internal_format, gl_vbo->vbo_id_);
166  }
167  else {
168  glTexBuffer(target_, internal_format, gl_vbo->vbo_id_);
169  }
170 
171  debug::object_label(GL_TEXTURE, tex_id_, name_);
172 
173  return true;
174 }
175 
176 bool GLTexture::init_internal(const GPUTexture *src, int mip_offset, int layer_offset)
177 {
179 
180  const GLTexture *gl_src = static_cast<const GLTexture *>(unwrap(src));
181  GLenum internal_format = to_gl_internal_format(format_);
182  target_ = to_gl_target(type_);
183 
184  glTextureView(tex_id_,
185  target_,
186  gl_src->tex_id_,
187  internal_format,
188  mip_offset,
189  mipmaps_,
190  layer_offset,
191  this->layer_count());
192 
193  debug::object_label(GL_TEXTURE, tex_id_, name_);
194 
195  return true;
196 }
197 
200 /* -------------------------------------------------------------------- */
204 void GLTexture::update_sub_direct_state_access(
205  int mip, int offset[3], int extent[3], GLenum format, GLenum type, const void *data)
206 {
208  size_t size = ((extent[0] + 3) / 4) * ((extent[1] + 3) / 4) * to_block_size(format_);
209  switch (this->dimensions_count()) {
210  default:
211  case 1:
212  glCompressedTextureSubImage1D(tex_id_, mip, offset[0], extent[0], format, size, data);
213  break;
214  case 2:
215  glCompressedTextureSubImage2D(
216  tex_id_, mip, UNPACK2(offset), UNPACK2(extent), format, size, data);
217  break;
218  case 3:
219  glCompressedTextureSubImage3D(
220  tex_id_, mip, UNPACK3(offset), UNPACK3(extent), format, size, data);
221  break;
222  }
223  }
224  else {
225  switch (this->dimensions_count()) {
226  default:
227  case 1:
228  glTextureSubImage1D(tex_id_, mip, offset[0], extent[0], format, type, data);
229  break;
230  case 2:
231  glTextureSubImage2D(tex_id_, mip, UNPACK2(offset), UNPACK2(extent), format, type, data);
232  break;
233  case 3:
234  glTextureSubImage3D(tex_id_, mip, UNPACK3(offset), UNPACK3(extent), format, type, data);
235  break;
236  }
237  }
238 
239  has_pixels_ = true;
240 }
241 
243  int mip, int offset[3], int extent[3], eGPUDataFormat type, const void *data)
244 {
246  BLI_assert(data != nullptr);
247 
248  if (mip >= mipmaps_) {
249  debug::raise_gl_error("Updating a miplvl on a texture too small to have this many levels.");
250  return;
251  }
252 
253  const int dimensions = this->dimensions_count();
254  GLenum gl_format = to_gl_data_format(format_);
255  GLenum gl_type = to_gl(type);
256 
257  /* Some drivers have issues with cubemap & glTextureSubImage3D even if it is correct. */
259  this->update_sub_direct_state_access(mip, offset, extent, gl_format, gl_type, data);
260  return;
261  }
262 
264  if (type_ == GPU_TEXTURE_CUBE) {
265  for (int i = 0; i < extent[2]; i++) {
266  GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + offset[2] + i;
267  glTexSubImage2D(target, mip, UNPACK2(offset), UNPACK2(extent), gl_format, gl_type, data);
268  }
269  }
270  else if (format_flag_ & GPU_FORMAT_COMPRESSED) {
271  size_t size = ((extent[0] + 3) / 4) * ((extent[1] + 3) / 4) * to_block_size(format_);
272  switch (dimensions) {
273  default:
274  case 1:
275  glCompressedTexSubImage1D(target_, mip, offset[0], extent[0], gl_format, size, data);
276  break;
277  case 2:
278  glCompressedTexSubImage2D(
279  target_, mip, UNPACK2(offset), UNPACK2(extent), gl_format, size, data);
280  break;
281  case 3:
282  glCompressedTexSubImage3D(
283  target_, mip, UNPACK3(offset), UNPACK3(extent), gl_format, size, data);
284  break;
285  }
286  }
287  else {
288  switch (dimensions) {
289  default:
290  case 1:
291  glTexSubImage1D(target_, mip, offset[0], extent[0], gl_format, gl_type, data);
292  break;
293  case 2:
294  glTexSubImage2D(target_, mip, UNPACK2(offset), UNPACK2(extent), gl_format, gl_type, data);
295  break;
296  case 3:
297  glTexSubImage3D(target_, mip, UNPACK3(offset), UNPACK3(extent), gl_format, gl_type, data);
298  break;
299  }
300  }
301 
302  has_pixels_ = true;
303 }
304 
312 {
313  /* Allow users to provide mipmaps stored in compressed textures.
314  * Skip generating mipmaps to avoid overriding the existing ones. */
316  return;
317  }
318 
319  /* Some drivers have bugs when using #glGenerateMipmap with depth textures (see T56789).
320  * In this case we just create a complete texture with mipmaps manually without
321  * down-sampling. You must initialize the texture levels using other methods like
322  * #GPU_framebuffer_recursive_downsample(). */
324  return;
325  }
326 
328  /* Broken glGenerateMipmap, don't call it and render without mipmaps.
329  * If no top level pixels have been filled in, the levels will get filled by
330  * other means and there is no need to disable mipmapping. */
331  if (has_pixels_) {
332  this->mip_range_set(0, 0);
333  }
334  return;
335  }
336 
337  /* Down-sample from mip 0 using implementation. */
339  glGenerateTextureMipmap(tex_id_);
340  }
341  else {
343  glGenerateMipmap(target_);
344  }
345 }
346 
347 void GLTexture::clear(eGPUDataFormat data_format, const void *data)
348 {
349  BLI_assert(validate_data_format(format_, data_format));
350 
352  int mip = 0;
353  GLenum gl_format = to_gl_data_format(format_);
354  GLenum gl_type = to_gl(data_format);
355  glClearTexImage(tex_id_, mip, gl_format, gl_type, data);
356  }
357  else {
358  /* Fallback for older GL. */
360 
361  FrameBuffer *fb = reinterpret_cast<FrameBuffer *>(this->framebuffer_get());
362  fb->bind(true);
363  fb->clear_attachment(this->attachment_type(0), data_format, data);
364 
365  GPU_framebuffer_bind(prev_fb);
366  }
367 
368  has_pixels_ = true;
369 }
370 
372 {
373  GLTexture *dst = static_cast<GLTexture *>(dst_);
374  GLTexture *src = this;
375 
376  BLI_assert((dst->w_ == src->w_) && (dst->h_ == src->h_) && (dst->d_ == src->d_));
377  BLI_assert(dst->format_ == src->format_);
378  BLI_assert(dst->type_ == src->type_);
379  /* TODO: support array / 3D textures. */
380  BLI_assert(dst->d_ == 0);
381 
383  int mip = 0;
384  /* NOTE: mip_size_get() won't override any dimension that is equal to 0. */
385  int extent[3] = {1, 1, 1};
386  this->mip_size_get(mip, extent);
387  glCopyImageSubData(
388  src->tex_id_, target_, mip, 0, 0, 0, dst->tex_id_, target_, mip, 0, 0, 0, UNPACK3(extent));
389  }
390  else {
391  /* Fallback for older GL. */
393  src->framebuffer_get(), 0, dst->framebuffer_get(), 0, to_framebuffer_bits(format_));
394  }
395 
396  has_pixels_ = true;
397 }
398 
400 {
402  BLI_assert(mip <= mipmaps_ || mip == 0);
404 
405  /* NOTE: mip_size_get() won't override any dimension that is equal to 0. */
406  int extent[3] = {1, 1, 1};
407  this->mip_size_get(mip, extent);
408 
409  size_t sample_len = extent[0] * extent[1] * extent[2];
410  size_t sample_size = to_bytesize(format_, type);
411  size_t texture_size = sample_len * sample_size;
412 
413  /* AMD Pro driver have a bug that write 8 bytes past buffer size
414  * if the texture is big. (see T66573) */
415  void *data = MEM_mallocN(texture_size + 8, "GPU_texture_read");
416 
417  GLenum gl_format = to_gl_data_format(format_);
418  GLenum gl_type = to_gl(type);
419 
421  glGetTextureImage(tex_id_, mip, gl_format, gl_type, texture_size, data);
422  }
423  else {
425  if (type_ == GPU_TEXTURE_CUBE) {
426  size_t cube_face_size = texture_size / 6;
427  char *face_data = (char *)data;
428  for (int i = 0; i < 6; i++, face_data += cube_face_size) {
429  glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, mip, gl_format, gl_type, face_data);
430  }
431  }
432  else {
433  glGetTexImage(target_, mip, gl_format, gl_type, data);
434  }
435  }
436  return data;
437 }
438 
441 /* -------------------------------------------------------------------- */
445 void GLTexture::swizzle_set(const char swizzle[4])
446 {
447  GLint gl_swizzle[4] = {(GLint)swizzle_to_gl(swizzle[0]),
448  (GLint)swizzle_to_gl(swizzle[1]),
449  (GLint)swizzle_to_gl(swizzle[2]),
450  (GLint)swizzle_to_gl(swizzle[3])};
452  glTextureParameteriv(tex_id_, GL_TEXTURE_SWIZZLE_RGBA, gl_swizzle);
453  }
454  else {
456  glTexParameteriv(target_, GL_TEXTURE_SWIZZLE_RGBA, gl_swizzle);
457  }
458 }
459 
461 {
463  GLint value = use_stencil ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT;
465  glTextureParameteri(tex_id_, GL_DEPTH_STENCIL_TEXTURE_MODE, value);
466  }
467  else {
469  glTexParameteri(target_, GL_DEPTH_STENCIL_TEXTURE_MODE, value);
470  }
471 }
472 
474 {
475  BLI_assert(min <= max && min >= 0 && max <= mipmaps_);
476  mip_min_ = min;
477  mip_max_ = max;
479  glTextureParameteri(tex_id_, GL_TEXTURE_BASE_LEVEL, min);
480  glTextureParameteri(tex_id_, GL_TEXTURE_MAX_LEVEL, max);
481  }
482  else {
484  glTexParameteri(target_, GL_TEXTURE_BASE_LEVEL, min);
485  glTexParameteri(target_, GL_TEXTURE_MAX_LEVEL, max);
486  }
487 }
488 
489 struct GPUFrameBuffer *GLTexture::framebuffer_get()
490 {
491  if (framebuffer_) {
492  return framebuffer_;
493  }
495  /* TODO(fclem): cleanup this. Don't use GPU object but blender::gpu ones. */
496  GPUTexture *gputex = reinterpret_cast<GPUTexture *>(static_cast<Texture *>(this));
497  framebuffer_ = GPU_framebuffer_create(name_);
498  GPU_framebuffer_texture_attach(framebuffer_, gputex, 0, 0);
499  has_pixels_ = true;
500  return framebuffer_;
501 }
502 
505 /* -------------------------------------------------------------------- */
509 GLuint GLTexture::samplers_[GPU_SAMPLER_MAX] = {0};
510 
512 {
513  glGenSamplers(GPU_SAMPLER_MAX, samplers_);
514  for (int i = 0; i <= GPU_SAMPLER_ICON - 1; i++) {
515  eGPUSamplerState state = static_cast<eGPUSamplerState>(i);
516  GLenum clamp_type = (state & GPU_SAMPLER_CLAMP_BORDER) ? GL_CLAMP_TO_BORDER : GL_CLAMP_TO_EDGE;
517  GLenum wrap_s = (state & GPU_SAMPLER_REPEAT_S) ? GL_REPEAT : clamp_type;
518  GLenum wrap_t = (state & GPU_SAMPLER_REPEAT_T) ? GL_REPEAT : clamp_type;
519  GLenum wrap_r = (state & GPU_SAMPLER_REPEAT_R) ? GL_REPEAT : clamp_type;
520  GLenum mag_filter = (state & GPU_SAMPLER_FILTER) ? GL_LINEAR : GL_NEAREST;
521  GLenum min_filter = (state & GPU_SAMPLER_FILTER) ?
522  ((state & GPU_SAMPLER_MIPMAP) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR) :
523  ((state & GPU_SAMPLER_MIPMAP) ? GL_NEAREST_MIPMAP_LINEAR : GL_NEAREST);
524  GLenum compare_mode = (state & GPU_SAMPLER_COMPARE) ? GL_COMPARE_REF_TO_TEXTURE : GL_NONE;
525 
526  glSamplerParameteri(samplers_[i], GL_TEXTURE_WRAP_S, wrap_s);
527  glSamplerParameteri(samplers_[i], GL_TEXTURE_WRAP_T, wrap_t);
528  glSamplerParameteri(samplers_[i], GL_TEXTURE_WRAP_R, wrap_r);
529  glSamplerParameteri(samplers_[i], GL_TEXTURE_MIN_FILTER, min_filter);
530  glSamplerParameteri(samplers_[i], GL_TEXTURE_MAG_FILTER, mag_filter);
531  glSamplerParameteri(samplers_[i], GL_TEXTURE_COMPARE_MODE, compare_mode);
532  glSamplerParameteri(samplers_[i], GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
533 
541  char sampler_name[128] = "\0\0";
542  SNPRINTF(sampler_name,
543  "%s%s%s%s%s%s%s%s%s%s",
544  (state == GPU_SAMPLER_DEFAULT) ? "_default" : "",
545  (state & GPU_SAMPLER_FILTER) ? "_filter" : "",
546  (state & GPU_SAMPLER_MIPMAP) ? "_mipmap" : "",
547  (state & GPU_SAMPLER_REPEAT) ? "_repeat-" : "",
548  (state & GPU_SAMPLER_REPEAT_S) ? "S" : "",
549  (state & GPU_SAMPLER_REPEAT_T) ? "T" : "",
550  (state & GPU_SAMPLER_REPEAT_R) ? "R" : "",
551  (state & GPU_SAMPLER_CLAMP_BORDER) ? "_clamp_border" : "",
552  (state & GPU_SAMPLER_COMPARE) ? "_compare" : "",
553  (state & GPU_SAMPLER_ANISO) ? "_aniso" : "");
554  debug::object_label(GL_SAMPLER, samplers_[i], &sampler_name[1]);
555  }
556  samplers_update();
557 
558  /* Custom sampler for icons. */
559  GLuint icon_sampler = samplers_[GPU_SAMPLER_ICON];
560  glSamplerParameteri(icon_sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
561  glSamplerParameteri(icon_sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
562  glSamplerParameterf(icon_sampler, GL_TEXTURE_LOD_BIAS, -0.5f);
563 
564  debug::object_label(GL_SAMPLER, icon_sampler, "icons");
565 }
566 
568 {
570  return;
571  }
572 
573  float max_anisotropy = 1.0f;
574  glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy);
575 
576  float aniso_filter = min_ff(max_anisotropy, U.anisotropic_filter);
577 
578  for (int i = 0; i <= GPU_SAMPLER_ICON - 1; i++) {
579  eGPUSamplerState state = static_cast<eGPUSamplerState>(i);
581  glSamplerParameterf(samplers_[i], GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso_filter);
582  }
583  }
584 }
585 
587 {
588  glDeleteSamplers(GPU_SAMPLER_MAX, samplers_);
589 }
590 
593 /* -------------------------------------------------------------------- */
599 /* NOTE: This only checks if this mipmap is valid / supported.
600  * TODO(fclem): make the check cover the whole mipmap chain. */
601 bool GLTexture::proxy_check(int mip)
602 {
603  /* Manual validation first, since some implementation have issues with proxy creation. */
604  int max_size = GPU_max_texture_size();
605  int max_3d_size = GLContext::max_texture_3d_size;
606  int max_cube_size = GLContext::max_cubemap_size;
607  int size[3] = {1, 1, 1};
608  this->mip_size_get(mip, size);
609 
610  if (type_ & GPU_TEXTURE_ARRAY) {
611  if (this->layer_count() > GPU_max_texture_layers()) {
612  return false;
613  }
614  }
615 
616  if (type_ == GPU_TEXTURE_3D) {
617  if (size[0] > max_3d_size || size[1] > max_3d_size || size[2] > max_3d_size) {
618  return false;
619  }
620  }
621  else if ((type_ & ~GPU_TEXTURE_ARRAY) == GPU_TEXTURE_2D) {
622  if (size[0] > max_size || size[1] > max_size) {
623  return false;
624  }
625  }
626  else if ((type_ & ~GPU_TEXTURE_ARRAY) == GPU_TEXTURE_1D) {
627  if (size[0] > max_size) {
628  return false;
629  }
630  }
631  else if ((type_ & ~GPU_TEXTURE_ARRAY) == GPU_TEXTURE_CUBE) {
632  if (size[0] > max_cube_size) {
633  return false;
634  }
635  }
636 
640  /* Some AMD drivers have a faulty `GL_PROXY_TEXTURE_..` check.
641  * (see T55888, T56185, T59351).
642  * Checking with `GL_PROXY_TEXTURE_..` doesn't prevent `Out Of Memory` issue,
643  * it just states that the OGL implementation can support the texture.
644  * So we already manually check the maximum size and maximum number of layers.
645  * Same thing happens on Nvidia/macOS 10.15 (T78175). */
646  return true;
647  }
648 
649  if ((type_ == GPU_TEXTURE_CUBE_ARRAY) &&
651  /* Special fix for T79703. */
652  return true;
653  }
654 
655  GLenum gl_proxy = to_gl_proxy(type_);
656  GLenum internal_format = to_gl_internal_format(format_);
657  GLenum gl_format = to_gl_data_format(format_);
658  GLenum gl_type = to_gl(to_data_format(format_));
659  /* Small exception. */
660  int dimensions = (type_ == GPU_TEXTURE_CUBE) ? 2 : this->dimensions_count();
661 
662  if (format_flag_ & GPU_FORMAT_COMPRESSED) {
663  size_t img_size = ((size[0] + 3) / 4) * ((size[1] + 3) / 4) * to_block_size(format_);
664  switch (dimensions) {
665  default:
666  case 1:
667  glCompressedTexImage1D(gl_proxy, mip, size[0], 0, gl_format, img_size, nullptr);
668  break;
669  case 2:
670  glCompressedTexImage2D(gl_proxy, mip, UNPACK2(size), 0, gl_format, img_size, nullptr);
671  break;
672  case 3:
673  glCompressedTexImage3D(gl_proxy, mip, UNPACK3(size), 0, gl_format, img_size, nullptr);
674  break;
675  }
676  }
677  else {
678  switch (dimensions) {
679  default:
680  case 1:
681  glTexImage1D(gl_proxy, mip, internal_format, size[0], 0, gl_format, gl_type, nullptr);
682  break;
683  case 2:
684  glTexImage2D(
685  gl_proxy, mip, internal_format, UNPACK2(size), 0, gl_format, gl_type, nullptr);
686  break;
687  case 3:
688  glTexImage3D(
689  gl_proxy, mip, internal_format, UNPACK3(size), 0, gl_format, gl_type, nullptr);
690  break;
691  }
692  }
693 
694  int width = 0;
695  glGetTexLevelParameteriv(gl_proxy, 0, GL_TEXTURE_WIDTH, &width);
696  return (width > 0);
697 }
698 
702 {
703  /* Recursive down sample workaround break this check.
704  * See #recursive_downsample() for more information. */
706  return;
707  }
708  /* Do not check if using compute shader. */
709  GLShader *sh = dynamic_cast<GLShader *>(Context::get()->shader);
710  if (sh && sh->is_compute()) {
711  return;
712  }
713  GLFrameBuffer *fb = static_cast<GLFrameBuffer *>(GLContext::get()->active_fb);
714  for (int i = 0; i < ARRAY_SIZE(fb_); i++) {
715  if (fb_[i] == fb) {
717  GPUAttachment attachment = fb->attachments_[type];
718  if (attachment.mip <= mip_max_ && attachment.mip >= mip_min_) {
719  char msg[256];
720  SNPRINTF(msg,
721  "Feedback loop: Trying to bind a texture (%s) with mip range %d-%d but mip %d is "
722  "attached to the active framebuffer (%s)",
723  name_,
724  mip_min_,
725  mip_max_,
726  attachment.mip,
727  fb->name_);
729  }
730  return;
731  }
732  }
733 }
734 
735 /* TODO(fclem): Legacy. Should be removed at some point. */
737 {
738  return tex_id_;
739 }
740 
741 } // namespace blender::gpu
#define BLI_assert(a)
Definition: BLI_assert.h:46
MINLINE uint divide_ceil_u(uint a, uint b)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
#define SNPRINTF(dst, format,...)
Definition: BLI_string.h:485
unsigned int uint
Definition: BLI_sys_types.h:67
#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 type
_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
@ GPU_DRIVER_ANY
Definition: GPU_platform.h:47
@ GPU_DRIVER_OFFICIAL
Definition: GPU_platform.h:44
@ GPU_OS_WIN
Definition: GPU_platform.h:37
@ GPU_OS_UNIX
Definition: GPU_platform.h:39
@ GPU_OS_MAC
Definition: GPU_platform.h:38
@ GPU_DEVICE_ATI
Definition: GPU_platform.h:25
@ GPU_DEVICE_NVIDIA
Definition: GPU_platform.h:24
@ GPU_DEVICE_ANY
Definition: GPU_platform.h:31
bool GPU_type_matches(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver)
eGPUSamplerState
Definition: GPU_texture.h:25
@ GPU_SAMPLER_REPEAT_S
Definition: GPU_texture.h:29
@ GPU_SAMPLER_ANISO
Definition: GPU_texture.h:34
@ GPU_SAMPLER_REPEAT
Definition: GPU_texture.h:37
@ GPU_SAMPLER_MIPMAP
Definition: GPU_texture.h:28
@ GPU_SAMPLER_ICON
Definition: GPU_texture.h:35
@ GPU_SAMPLER_FILTER
Definition: GPU_texture.h:27
@ GPU_SAMPLER_COMPARE
Definition: GPU_texture.h:33
@ GPU_SAMPLER_REPEAT_T
Definition: GPU_texture.h:30
@ GPU_SAMPLER_CLAMP_BORDER
Definition: GPU_texture.h:32
@ GPU_SAMPLER_DEFAULT
Definition: GPU_texture.h:26
@ GPU_SAMPLER_REPEAT_R
Definition: GPU_texture.h:31
struct GPUTexture GPUTexture
Definition: GPU_texture.h:17
eGPUDataFormat
Definition: GPU_texture.h:170
static const int GPU_SAMPLER_MAX
Definition: GPU_texture.h:52
@ GPU_DEPTH32F_STENCIL8
Definition: GPU_texture.h:119
@ GPU_DEPTH24_STENCIL8
Definition: GPU_texture.h:120
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 Context * get()
Definition: gpu_context.cc:82
static bool stencil_texturing_support
Definition: gl_context.hh:66
static GLint max_texture_3d_size
Definition: gl_context.hh:45
static bool texture_storage_support
Definition: gl_context.hh:70
static bool copy_image_support
Definition: gl_context.hh:55
static bool direct_state_access_support
Definition: gl_context.hh:57
static GLContext * get()
Definition: gl_context.hh:117
static void tex_free(GLuint tex_id)
Definition: gl_context.cc:262
static bool texture_filter_anisotropic_support
Definition: gl_context.hh:68
static GLStateManager * state_manager_active_get()
Definition: gl_context.hh:122
static bool clear_texture_support
Definition: gl_context.hh:54
static GLint max_cubemap_size
Definition: gl_context.hh:44
static bool texture_cube_map_array_support
Definition: gl_context.hh:67
static bool generate_mipmap_workaround
Definition: gl_context.hh:77
void texture_bind_temp(GLTexture *tex)
Definition: gl_state.cc:466
GLTexture(const char *name)
Definition: gl_texture.cc:27
void copy_to(Texture *dst) override
Definition: gl_texture.cc:371
void swizzle_set(const char swizzle_mask[4]) override
Definition: gl_texture.cc:445
bool init_internal() override
Definition: gl_texture.cc:47
void clear(eGPUDataFormat format, const void *data) override
Definition: gl_texture.cc:347
static void samplers_free()
Definition: gl_texture.cc:586
uint gl_bindcode_get() const override
Definition: gl_texture.cc:736
void * read(int mip, eGPUDataFormat type) override
Definition: gl_texture.cc:399
static void samplers_update()
Definition: gl_texture.cc:567
static void samplers_init()
Definition: gl_texture.cc:511
void mip_range_set(int min, int max) override
Definition: gl_texture.cc:473
void stencil_texture_mode_set(bool use_stencil) override
Definition: gl_texture.cc:460
void generate_mipmap() override
Definition: gl_texture.cc:311
void update_sub(int mip, int offset[3], int extent[3], eGPUDataFormat type, const void *data) override
Definition: gl_texture.cc:242
virtual void texture_unbind(Texture *tex)=0
eGPUTextureFormat format_
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
void mip_size_get(int mip, int r_size[3]) const
Texture(const char *name)
Definition: gpu_texture.cc:25
SyclQueue void void * src
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)
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
const int state
ccl_gpu_kernel_postfix ccl_global float int int int int sh
format
Definition: logImageCore.h:38
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
void raise_gl_error(const char *info)
Definition: gl_debug.cc:275
void object_label(GLenum type, GLuint object, const char *name)
Definition: gl_debug.cc:328
GLenum to_gl_target(eGPUTextureType type)
Definition: gl_texture.hh:196
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:90
static Context * unwrap(GPUContext *ctx)
eGPUFrameBufferBits to_framebuffer_bits(eGPUTextureFormat tex_format)
GLenum to_gl_proxy(eGPUTextureType type)
Definition: gl_texture.hh:221
GLenum to_gl_data_format(eGPUTextureFormat format)
Definition: gl_texture.hh:294
eGPUDataFormat to_data_format(eGPUTextureFormat tex_format)
GLenum swizzle_to_gl(const char swizzle)
Definition: gl_texture.hh:245
static size_t to_bytesize(GPUIndexBufType type)
static GLenum to_gl(const GPUAttachmentType type)
#define min(a, b)
Definition: sort.c:35
float max