Blender V4.3
gpu_texture.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2005 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "BLI_string.h"
10
11#include "GPU_framebuffer.hh"
12#include "GPU_texture.hh"
13
14#include "gpu_backend.hh"
17
19
20namespace blender::gpu {
21
22/* -------------------------------------------------------------------- */
26Texture::Texture(const char *name)
27{
28 if (name) {
29 STRNCPY(name_, name);
30 }
31 else {
32 name_[0] = '\0';
33 }
34
35 for (int i = 0; i < ARRAY_SIZE(fb_); i++) {
36 fb_[i] = nullptr;
37 }
38
40}
41
43{
44 for (int i = 0; i < ARRAY_SIZE(fb_); i++) {
45 if (fb_[i] != nullptr) {
47 }
48 }
49
50#ifndef GPU_NO_USE_PY_REFERENCES
51 if (this->py_ref) {
52 *this->py_ref = nullptr;
53 }
54#endif
55}
56
57bool Texture::init_1D(int w, int layers, int mip_len, eGPUTextureFormat format)
58{
59 w_ = w;
60 h_ = layers;
61 d_ = 0;
62 int mip_len_max = 1 + floorf(log2f(w));
63 mipmaps_ = min_ii(mip_len, mip_len_max);
66 type_ = (layers > 0) ? GPU_TEXTURE_1D_ARRAY : GPU_TEXTURE_1D;
69 }
70 return this->init_internal();
71}
72
73bool Texture::init_2D(int w, int h, int layers, int mip_len, eGPUTextureFormat format)
74{
75 w_ = w;
76 h_ = h;
77 d_ = layers;
78 int mip_len_max = 1 + floorf(log2f(max_ii(w, h)));
79 mipmaps_ = min_ii(mip_len, mip_len_max);
82 type_ = (layers > 0) ? GPU_TEXTURE_2D_ARRAY : GPU_TEXTURE_2D;
85 }
86 return this->init_internal();
87}
88
89bool Texture::init_3D(int w, int h, int d, int mip_len, eGPUTextureFormat format)
90{
91 w_ = w;
92 h_ = h;
93 d_ = d;
94 int mip_len_max = 1 + floorf(log2f(max_iii(w, h, d)));
95 mipmaps_ = min_ii(mip_len, mip_len_max);
101 }
102 return this->init_internal();
103}
104
105bool Texture::init_cubemap(int w, int layers, int mip_len, eGPUTextureFormat format)
106{
107 w_ = w;
108 h_ = w;
109 d_ = max_ii(1, layers) * 6;
110 int mip_len_max = 1 + floorf(log2f(w));
111 mipmaps_ = min_ii(mip_len, mip_len_max);
112 format_ = format;
117 }
118 return this->init_internal();
119}
120
122{
123 /* See to_texture_format(). */
125 return false;
126 }
128 h_ = 0;
129 d_ = 0;
130 format_ = format;
133 return this->init_internal(vbo);
134}
135
136bool Texture::init_view(GPUTexture *src_,
138 eGPUTextureType type,
139 int mip_start,
140 int mip_len,
141 int layer_start,
142 int layer_len,
143 bool cube_as_array,
144 bool use_stencil)
145{
146 const Texture *src = unwrap(src_);
147 w_ = src->w_;
148 h_ = src->h_;
149 d_ = src->d_;
150 layer_start = min_ii(layer_start, src->layer_count() - 1);
151 layer_len = min_ii(layer_len, (src->layer_count() - layer_start));
152 switch (type) {
154 h_ = layer_len;
155 break;
157 BLI_assert(layer_len % 6 == 0);
160 d_ = layer_len;
161 break;
162 default:
163 BLI_assert(layer_len == 1 && layer_start == 0);
164 break;
165 }
166 mip_start = min_ii(mip_start, src->mipmaps_ - 1);
167 mip_len = min_ii(mip_len, (src->mipmaps_ - mip_start));
168 mipmaps_ = mip_len;
169 format_ = format;
171 type_ = type;
172 if (cube_as_array) {
174 type_ = (type_ & ~GPU_TEXTURE_CUBE) | GPU_TEXTURE_2D_ARRAY;
175 }
177 return this->init_internal(src_, mip_start, layer_start, use_stencil);
178}
179
181{
182 gpu_image_usage_flags_ = usage_flags;
183}
184
187/* -------------------------------------------------------------------- */
192{
193 for (int i = 0; i < ARRAY_SIZE(fb_); i++) {
194 if (fb_[i] == fb) {
195 /* Already stores a reference */
196 if (fb_attachment_[i] != type) {
197 /* Ensure it's not attached twice to the same FrameBuffer. */
199 fb_attachment_[i] = type;
200 }
201 return;
202 }
203 }
204 for (int i = 0; i < ARRAY_SIZE(fb_); i++) {
205 if (fb_[i] == nullptr) {
206 fb_attachment_[i] = type;
207 fb_[i] = fb;
208 return;
209 }
210 }
211 BLI_assert_msg(0, "GPU: Error: Texture: Not enough attachment");
212}
213
215{
216 for (int i = 0; i < ARRAY_SIZE(fb_); i++) {
217 if (fb_[i] == fb) {
219 fb_[i] = nullptr;
220 return;
221 }
222 }
223 BLI_assert_msg(0, "GPU: Error: Texture: Framebuffer is not attached");
224}
225
226void Texture::update(eGPUDataFormat format, const void *data)
227{
228 int mip = 0;
229 int extent[3] = {1, 1, 1};
230 int offset[3] = {0, 0, 0};
231 this->mip_size_get(mip, extent);
232 this->update_sub(mip, offset, extent, format, data);
233}
234
237} // namespace blender::gpu
238
239/* -------------------------------------------------------------------- */
243using namespace blender;
244using namespace blender::gpu;
245
246/* ------ Memory Management ------ */
247
249{
250 /* TODO(fclem): Do that inside the new Texture class. */
251 return 0;
252}
253
254/* ------ Creation ------ */
255
256static inline GPUTexture *gpu_texture_create(const char *name,
257 const int w,
258 const int h,
259 const int d,
260 const eGPUTextureType type,
261 int mip_len,
262 eGPUTextureFormat tex_format,
263 eGPUDataFormat data_format,
264 eGPUTextureUsage usage,
265 const void *pixels)
266{
267 BLI_assert(mip_len > 0);
269 tex->usage_set(usage);
270
271 bool success = false;
272 switch (type) {
273 case GPU_TEXTURE_1D:
275 success = tex->init_1D(w, h, mip_len, tex_format);
276 break;
277 case GPU_TEXTURE_2D:
279 success = tex->init_2D(w, h, d, mip_len, tex_format);
280 break;
281 case GPU_TEXTURE_3D:
282 success = tex->init_3D(w, h, d, mip_len, tex_format);
283 break;
284 case GPU_TEXTURE_CUBE:
286 success = tex->init_cubemap(w, d, mip_len, tex_format);
287 break;
288 default:
289 break;
290 }
291
292 if (!success) {
293 delete tex;
294 return nullptr;
295 }
296 if (pixels) {
297 tex->update(data_format, pixels);
298 }
299 return reinterpret_cast<GPUTexture *>(tex);
300}
301
302GPUTexture *GPU_texture_create_1d(const char *name,
303 int w,
304 int mip_len,
306 eGPUTextureUsage usage,
307 const float *data)
308{
309 return gpu_texture_create(
310 name, w, 0, 0, GPU_TEXTURE_1D, mip_len, format, GPU_DATA_FLOAT, usage, data);
311}
312
313GPUTexture *GPU_texture_create_1d_array(const char *name,
314 int w,
315 int h,
316 int mip_len,
318 eGPUTextureUsage usage,
319 const float *data)
320{
321 return gpu_texture_create(
322 name, w, h, 0, GPU_TEXTURE_1D_ARRAY, mip_len, format, GPU_DATA_FLOAT, usage, data);
323}
324
325GPUTexture *GPU_texture_create_2d(const char *name,
326 int w,
327 int h,
328 int mip_len,
330 eGPUTextureUsage usage,
331 const float *data)
332{
333 return gpu_texture_create(
334 name, w, h, 0, GPU_TEXTURE_2D, mip_len, format, GPU_DATA_FLOAT, usage, data);
335}
336
337GPUTexture *GPU_texture_create_2d_array(const char *name,
338 int w,
339 int h,
340 int d,
341 int mip_len,
343 eGPUTextureUsage usage,
344 const float *data)
345{
346 return gpu_texture_create(
347 name, w, h, d, GPU_TEXTURE_2D_ARRAY, mip_len, format, GPU_DATA_FLOAT, usage, data);
348}
349
350GPUTexture *GPU_texture_create_3d(const char *name,
351 int w,
352 int h,
353 int d,
354 int mip_len,
355 eGPUTextureFormat texture_format,
356 eGPUTextureUsage usage,
357 const void *data)
358{
359 return gpu_texture_create(
360 name, w, h, d, GPU_TEXTURE_3D, mip_len, texture_format, GPU_DATA_FLOAT, usage, data);
361}
362
363GPUTexture *GPU_texture_create_cube(const char *name,
364 int w,
365 int mip_len,
367 eGPUTextureUsage usage,
368 const float *data)
369{
370 return gpu_texture_create(
371 name, w, w, 0, GPU_TEXTURE_CUBE, mip_len, format, GPU_DATA_FLOAT, usage, data);
372}
373
374GPUTexture *GPU_texture_create_cube_array(const char *name,
375 int w,
376 int d,
377 int mip_len,
379 eGPUTextureUsage usage,
380 const float *data)
381{
382 return gpu_texture_create(
383 name, w, w, d, GPU_TEXTURE_CUBE_ARRAY, mip_len, format, GPU_DATA_FLOAT, usage, data);
384}
385
386GPUTexture *GPU_texture_create_compressed_2d(const char *name,
387 int w,
388 int h,
389 int miplen,
390 eGPUTextureFormat tex_format,
391 eGPUTextureUsage usage,
392 const void *data)
393{
395 tex->usage_set(usage);
396 bool success = tex->init_2D(w, h, 0, miplen, tex_format);
397
398 if (!success) {
399 delete tex;
400 return nullptr;
401 }
402 if (data) {
403 size_t ofs = 0;
404 for (int mip = 0; mip < miplen; mip++) {
405 int extent[3], offset[3] = {0, 0, 0};
406 tex->mip_size_get(mip, extent);
407
408 size_t size = ((extent[0] + 3) / 4) * ((extent[1] + 3) / 4) * to_block_size(tex_format);
409 tex->update_sub(mip, offset, extent, to_data_format(tex_format), (uchar *)data + ofs);
410
411 ofs += size;
412 }
413 }
414 return reinterpret_cast<GPUTexture *>(tex);
415}
416
417GPUTexture *GPU_texture_create_from_vertbuf(const char *name, blender::gpu::VertBuf *vert)
418{
419#ifndef NDEBUG
420 /* Vertex buffers used for texture buffers must be flagged with:
421 * GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY. */
423 "Vertex Buffers used for textures should have usage flag "
424 "GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY.");
425#endif
428
429 bool success = tex->init_buffer(vert, tex_format);
430 if (!success) {
431 delete tex;
432 return nullptr;
433 }
434 return reinterpret_cast<GPUTexture *>(tex);
435}
436
437GPUTexture *GPU_texture_create_error(int dimension, bool is_array)
438{
439 const float pixel[4] = {1.0f, 0.0f, 1.0f, 1.0f};
440 int w = 1;
441 int h = (dimension < 2 && !is_array) ? 0 : 1;
442 int d = (dimension < 3 && !is_array) ? 0 : 1;
443
445 type = (dimension == 2) ? (is_array ? GPU_TEXTURE_2D_ARRAY : GPU_TEXTURE_2D) : type;
446 type = (dimension == 1) ? (is_array ? GPU_TEXTURE_1D_ARRAY : GPU_TEXTURE_1D) : type;
447
448 return gpu_texture_create("invalid_tex",
449 w,
450 h,
451 d,
452 type,
453 1,
454 GPU_RGBA8,
457 pixel);
458}
459
460GPUTexture *GPU_texture_create_view(const char *name,
461 GPUTexture *src,
463 int mip_start,
464 int mip_len,
465 int layer_start,
466 int layer_len,
467 bool cube_as_array,
468 bool use_stencil)
469{
470 BLI_assert(mip_len > 0);
471 BLI_assert(layer_len > 0);
472 BLI_assert_msg(use_stencil == false || (GPU_texture_usage(src) & GPU_TEXTURE_USAGE_FORMAT_VIEW),
473 "Source texture of TextureView must have GPU_TEXTURE_USAGE_FORMAT_VIEW usage "
474 "flag if view texture uses stencil texturing.");
477 "Source texture of TextureView must have GPU_TEXTURE_USAGE_FORMAT_VIEW usage "
478 "flag if view texture format is different.");
479 Texture *view = GPUBackend::get()->texture_alloc(name);
480 view->init_view(src,
481 format,
482 unwrap(src)->type_get(),
483 mip_start,
484 mip_len,
485 layer_start,
486 layer_len,
487 cube_as_array,
488 use_stencil);
489 return wrap(view);
490}
491
492/* ------ Usage ------ */
493eGPUTextureUsage GPU_texture_usage(const GPUTexture *texture_)
494{
495 const Texture *tex = reinterpret_cast<const Texture *>(texture_);
496 return tex->usage_get();
497}
498
499/* ------ Update ------ */
500
501void GPU_texture_update_mipmap(GPUTexture *tex_,
502 int miplvl,
503 eGPUDataFormat data_format,
504 const void *pixels)
505{
506 Texture *tex = reinterpret_cast<Texture *>(tex_);
507 int extent[3] = {1, 1, 1}, offset[3] = {0, 0, 0};
508 tex->mip_size_get(miplvl, extent);
509 reinterpret_cast<Texture *>(tex)->update_sub(miplvl, offset, extent, data_format, pixels);
510}
511
513 eGPUDataFormat data_format,
514 const void *pixels,
515 int offset_x,
516 int offset_y,
517 int offset_z,
518 int width,
519 int height,
520 int depth)
521{
522 int offset[3] = {offset_x, offset_y, offset_z};
523 int extent[3] = {width, height, depth};
524 reinterpret_cast<Texture *>(tex)->update_sub(0, offset, extent, data_format, pixels);
525}
526
528 eGPUDataFormat data_format,
529 GPUPixelBuffer *pix_buf,
530 int offset_x,
531 int offset_y,
532 int offset_z,
533 int width,
534 int height,
535 int depth)
536{
537 int offset[3] = {offset_x, offset_y, offset_z};
538 int extent[3] = {width, height, depth};
539 reinterpret_cast<Texture *>(tex)->update_sub(offset, extent, data_format, pix_buf);
540}
541
542void *GPU_texture_read(GPUTexture *tex_, eGPUDataFormat data_format, int miplvl)
543{
544 Texture *tex = reinterpret_cast<Texture *>(tex_);
547 "The host-read usage flag must be specified up-front. Only textures which require data "
548 "reads should be flagged, allowing the backend to make certain optimisations.");
549 return tex->read(miplvl, data_format);
550}
551
552void GPU_texture_clear(GPUTexture *tex, eGPUDataFormat data_format, const void *data)
553{
554 BLI_assert(data != nullptr); /* Do not accept nullptr as parameter. */
555 reinterpret_cast<Texture *>(tex)->clear(data_format, data);
556}
557
558void GPU_texture_update(GPUTexture *tex, eGPUDataFormat data_format, const void *data)
559{
560 reinterpret_cast<Texture *>(tex)->update(data_format, data);
561}
562
567
568/* ------ Binding ------ */
569
570void GPU_texture_bind_ex(GPUTexture *tex_, GPUSamplerState state, int unit)
571{
572 Texture *tex = reinterpret_cast<Texture *>(tex_);
573 state = (state.type == GPU_SAMPLER_STATE_TYPE_INTERNAL) ? tex->sampler_state : state;
575}
576
577void GPU_texture_bind(GPUTexture *tex_, int unit)
578{
579 Texture *tex = reinterpret_cast<Texture *>(tex_);
580 Context::get()->state_manager->texture_bind(tex, tex->sampler_state, unit);
581}
582
583void GPU_texture_unbind(GPUTexture *tex_)
584{
585 Texture *tex = reinterpret_cast<Texture *>(tex_);
587}
588
593
594void GPU_texture_image_bind(GPUTexture *tex, int unit)
595{
597}
598
603
608
610{
611 reinterpret_cast<Texture *>(tex)->generate_mipmap();
612}
613
614void GPU_texture_copy(GPUTexture *dst_, GPUTexture *src_)
615{
616 Texture *src = reinterpret_cast<Texture *>(src_);
617 Texture *dst = reinterpret_cast<Texture *>(dst_);
618 src->copy_to(dst);
619}
620
621void GPU_texture_compare_mode(GPUTexture *tex_, bool use_compare)
622{
623 Texture *tex = reinterpret_cast<Texture *>(tex_);
624 /* Only depth formats does support compare mode. */
625 BLI_assert(!(use_compare) || (tex->format_flag_get() & GPU_FORMAT_DEPTH));
626
627 tex->sampler_state.type = use_compare ? GPU_SAMPLER_STATE_TYPE_CUSTOM :
629 tex->sampler_state.custom_type = GPU_SAMPLER_CUSTOM_COMPARE;
630}
631
632void GPU_texture_filter_mode(GPUTexture *tex_, bool use_filter)
633{
634 Texture *tex = reinterpret_cast<Texture *>(tex_);
635 /* Stencil and integer format does not support filtering. */
636 BLI_assert(!(use_filter) ||
637 !(tex->format_flag_get() & (GPU_FORMAT_STENCIL | GPU_FORMAT_INTEGER)));
638 tex->sampler_state.set_filtering_flag_from_test(GPU_SAMPLER_FILTERING_LINEAR, use_filter);
639}
640
641void GPU_texture_mipmap_mode(GPUTexture *tex_, bool use_mipmap, bool use_filter)
642{
643 Texture *tex = reinterpret_cast<Texture *>(tex_);
644 /* Stencil and integer format does not support filtering. */
645 BLI_assert(!(use_filter || use_mipmap) ||
646 !(tex->format_flag_get() & (GPU_FORMAT_STENCIL | GPU_FORMAT_INTEGER)));
647 tex->sampler_state.set_filtering_flag_from_test(GPU_SAMPLER_FILTERING_MIPMAP, use_mipmap);
648 tex->sampler_state.set_filtering_flag_from_test(GPU_SAMPLER_FILTERING_LINEAR, use_filter);
649}
650
651void GPU_texture_anisotropic_filter(GPUTexture *tex_, bool use_aniso)
652{
653 Texture *tex = reinterpret_cast<Texture *>(tex_);
654 /* Stencil and integer format does not support filtering. */
655 BLI_assert(!(use_aniso) ||
656 !(tex->format_flag_get() & (GPU_FORMAT_STENCIL | GPU_FORMAT_INTEGER)));
657 tex->sampler_state.set_filtering_flag_from_test(GPU_SAMPLER_FILTERING_ANISOTROPIC, use_aniso);
658}
659
660void GPU_texture_extend_mode_x(GPUTexture *tex_, GPUSamplerExtendMode extend_mode)
661{
662 Texture *tex = reinterpret_cast<Texture *>(tex_);
663 tex->sampler_state.extend_x = extend_mode;
664}
665
666void GPU_texture_extend_mode_y(GPUTexture *tex_, GPUSamplerExtendMode extend_mode)
667{
668 Texture *tex = reinterpret_cast<Texture *>(tex_);
669 tex->sampler_state.extend_yz = extend_mode;
670}
671
672void GPU_texture_extend_mode(GPUTexture *tex_, GPUSamplerExtendMode extend_mode)
673{
674 Texture *tex = reinterpret_cast<Texture *>(tex_);
675 tex->sampler_state.extend_x = extend_mode;
676 tex->sampler_state.extend_yz = extend_mode;
677}
678
679void GPU_texture_swizzle_set(GPUTexture *tex, const char swizzle[4])
680{
681 reinterpret_cast<Texture *>(tex)->swizzle_set(swizzle);
682}
683
684void GPU_texture_free(GPUTexture *tex_)
685{
686 Texture *tex = reinterpret_cast<Texture *>(tex_);
687 tex->refcount--;
688
689 if (tex->refcount < 0) {
690 fprintf(stderr, "GPUTexture: negative refcount\n");
691 }
692
693 if (tex->refcount == 0) {
694 delete tex;
695 }
696}
697
698void GPU_texture_ref(GPUTexture *tex)
699{
700 reinterpret_cast<Texture *>(tex)->refcount++;
701}
702
703int GPU_texture_dimensions(const GPUTexture *tex_)
704{
705 eGPUTextureType type = reinterpret_cast<const Texture *>(tex_)->type_get();
706 if (type & GPU_TEXTURE_1D) {
707 return 1;
708 }
709 if (type & GPU_TEXTURE_2D) {
710 return 2;
711 }
712 if (type & GPU_TEXTURE_3D) {
713 return 3;
714 }
715 if (type & GPU_TEXTURE_CUBE) {
716 return 2;
717 }
718 /* GPU_TEXTURE_BUFFER */
719 return 1;
720}
721
722int GPU_texture_width(const GPUTexture *tex)
723{
724 return reinterpret_cast<const Texture *>(tex)->width_get();
725}
726
727int GPU_texture_height(const GPUTexture *tex)
728{
729 return reinterpret_cast<const Texture *>(tex)->height_get();
730}
731
732int GPU_texture_depth(const GPUTexture *tex)
733{
734 return reinterpret_cast<const Texture *>(tex)->depth_get();
735}
736
737int GPU_texture_layer_count(const GPUTexture *tex)
738{
739 return reinterpret_cast<const Texture *>(tex)->layer_count();
740}
741
742int GPU_texture_mip_count(const GPUTexture *tex)
743{
744 return reinterpret_cast<const Texture *>(tex)->mip_count();
745}
746
747int GPU_texture_original_width(const GPUTexture *tex)
748{
749 return reinterpret_cast<const Texture *>(tex)->src_w;
750}
751
752int GPU_texture_original_height(const GPUTexture *tex)
753{
754 return reinterpret_cast<const Texture *>(tex)->src_h;
755}
756
757void GPU_texture_original_size_set(GPUTexture *tex_, int w, int h)
758{
759 Texture *tex = reinterpret_cast<Texture *>(tex_);
760 tex->src_w = w;
761 tex->src_h = h;
762}
763
765{
766 return reinterpret_cast<const Texture *>(tex)->format_get();
767}
768
770{
771 switch (texture_format) {
772 /* Formats texture & render-buffer */
773 case GPU_RGBA8UI:
774 return "RGBA8UI";
775 case GPU_RGBA8I:
776 return "RGBA8I";
777 case GPU_RGBA8:
778 return "RGBA8";
779 case GPU_RGBA32UI:
780 return "RGBA32UI";
781 case GPU_RGBA32I:
782 return "RGBA32I";
783 case GPU_RGBA32F:
784 return "RGBA32F";
785 case GPU_RGBA16UI:
786 return "RGBA16UI";
787 case GPU_RGBA16I:
788 return "RGBA16I";
789 case GPU_RGBA16F:
790 return "RGBA16F";
791 case GPU_RGBA16:
792 return "RGBA16";
793 case GPU_RG8UI:
794 return "RG8UI";
795 case GPU_RG8I:
796 return "RG8I";
797 case GPU_RG8:
798 return "RG8";
799 case GPU_RG32UI:
800 return "RG32UI";
801 case GPU_RG32I:
802 return "RG32I";
803 case GPU_RG32F:
804 return "RG32F";
805 case GPU_RG16UI:
806 return "RG16UI";
807 case GPU_RG16I:
808 return "RG16I";
809 case GPU_RG16F:
810 return "RG16F";
811 case GPU_RG16:
812 return "RG16";
813 case GPU_R8UI:
814 return "R8UI";
815 case GPU_R8I:
816 return "R8I";
817 case GPU_R8:
818 return "R8";
819 case GPU_R32UI:
820 return "R32UI";
821 case GPU_R32I:
822 return "R32I";
823 case GPU_R32F:
824 return "R32F";
825 case GPU_R16UI:
826 return "R16UI";
827 case GPU_R16I:
828 return "R16I";
829 case GPU_R16F:
830 return "R16F";
831 case GPU_R16:
832 return "R16";
833 /* Special formats texture & render-buffer */
834 case GPU_RGB10_A2:
835 return "RGB10_A2";
836 case GPU_RGB10_A2UI:
837 return "RGB10_A2UI";
839 return "R11F_G11F_B10F";
841 return "DEPTH32F_STENCIL8";
843 return "DEPTH24_STENCIL8";
844 case GPU_SRGB8_A8:
845 return "SRGB8_A8";
846 /* Texture only formats. */
847 case GPU_RGB16F:
848 return "RGB16F";
849 case GPU_RGB16_SNORM:
850 return "RGB16_SNORM";
851 case GPU_RGB16I:
852 return "RGB16I";
853 case GPU_RGB16UI:
854 return "RGB16UI";
855 case GPU_RGB16:
856 return "RGB16";
857 case GPU_RGBA16_SNORM:
858 return "RGBA16_SNORM";
859 case GPU_RGBA8_SNORM:
860 return "RGBA8_SNORM";
861 case GPU_RGB32F:
862 return "RGB32F";
863 case GPU_RGB32I:
864 return "RGB32I";
865 case GPU_RGB32UI:
866 return "RGB32UI";
867 case GPU_RGB8_SNORM:
868 return "RGB8_SNORM";
869 case GPU_RGB8:
870 return "RGB8";
871 case GPU_RGB8I:
872 return "RGB8I";
873 case GPU_RGB8UI:
874 return "RGB8UI";
875 case GPU_RG16_SNORM:
876 return "RG16_SNORM";
877 case GPU_RG8_SNORM:
878 return "RG8_SNORM";
879 case GPU_R16_SNORM:
880 return "R16_SNORM";
881 case GPU_R8_SNORM:
882 return "R8_SNORM";
883 /* Special formats, texture only. */
885 return "SRGB8_A8_DXT1";
887 return "SRGB8_A8_DXT3";
889 return "SRGB8_A8_DXT5";
890 case GPU_RGBA8_DXT1:
891 return "RGBA8_DXT1";
892 case GPU_RGBA8_DXT3:
893 return "RGBA8_DXT3";
894 case GPU_RGBA8_DXT5:
895 return "RGBA8_DXT5";
896 case GPU_SRGB8:
897 return "SRGB8";
898 case GPU_RGB9_E5:
899 return "RGB9_E5";
900 /* Depth Formats. */
902 return "DEPTH_COMPONENT32F";
904 return "DEPTH_COMPONENT24";
906 return "DEPTH_COMPONENT16";
907 }
909 return "";
910}
911
912bool GPU_texture_has_depth_format(const GPUTexture *tex)
913{
914 return (reinterpret_cast<const Texture *>(tex)->format_flag_get() & GPU_FORMAT_DEPTH) != 0;
915}
916
917bool GPU_texture_has_stencil_format(const GPUTexture *tex)
918{
919 return (reinterpret_cast<const Texture *>(tex)->format_flag_get() & GPU_FORMAT_STENCIL) != 0;
920}
921
922bool GPU_texture_has_integer_format(const GPUTexture *tex)
923{
924 return (reinterpret_cast<const Texture *>(tex)->format_flag_get() & GPU_FORMAT_INTEGER) != 0;
925}
926
927bool GPU_texture_has_float_format(const GPUTexture *tex)
928{
929 return (reinterpret_cast<const Texture *>(tex)->format_flag_get() & GPU_FORMAT_FLOAT) != 0;
930}
931
933{
934 return (reinterpret_cast<const Texture *>(tex)->format_flag_get() &
936}
937
938bool GPU_texture_has_signed_format(const GPUTexture *tex)
939{
940 return (reinterpret_cast<const Texture *>(tex)->format_flag_get() & GPU_FORMAT_SIGNED) != 0;
941}
942
943bool GPU_texture_is_cube(const GPUTexture *tex)
944{
945 return (reinterpret_cast<const Texture *>(tex)->type_get() & GPU_TEXTURE_CUBE) != 0;
946}
947
948bool GPU_texture_is_array(const GPUTexture *tex)
949{
950 return (reinterpret_cast<const Texture *>(tex)->type_get() & GPU_TEXTURE_ARRAY) != 0;
951}
952
953#ifndef GPU_NO_USE_PY_REFERENCES
955{
956 return unwrap(tex)->py_ref;
957}
958
959void GPU_texture_py_reference_set(GPUTexture *tex, void **py_ref)
960{
961 BLI_assert(py_ref == nullptr || unwrap(tex)->py_ref == nullptr);
962 unwrap(tex)->py_ref = py_ref;
963}
964#endif
965
966/* TODO: remove. */
967int GPU_texture_opengl_bindcode(const GPUTexture *tex)
968{
969 return reinterpret_cast<const Texture *>(tex)->gl_bindcode_get();
970}
971
972void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *r_size)
973{
974 return reinterpret_cast<Texture *>(tex)->mip_size_get(lvl, r_size);
975}
976
979/* -------------------------------------------------------------------- */
985GPUPixelBuffer *GPU_pixel_buffer_create(size_t size)
986{
987 /* Ensure buffer satisfies the alignment of 256 bytes for copying
988 * data between buffers and textures. As specified in:
989 * https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf
990 *
991 * Ensuring minimal size across all platforms handles cases for small-sized
992 * textures and avoids issues with zero-sized buffers. */
993 size = ceil_to_multiple_ul(size, 256);
994 PixelBuffer *pixbuf = GPUBackend::get()->pixelbuf_alloc(size);
995 return wrap(pixbuf);
996}
997
998void GPU_pixel_buffer_free(GPUPixelBuffer *pix_buf)
999{
1000 PixelBuffer *handle = unwrap(pix_buf);
1001 delete handle;
1002}
1003
1004void *GPU_pixel_buffer_map(GPUPixelBuffer *pix_buf)
1005{
1006 return reinterpret_cast<PixelBuffer *>(pix_buf)->map();
1007}
1008
1009void GPU_pixel_buffer_unmap(GPUPixelBuffer *pix_buf)
1010{
1011 reinterpret_cast<PixelBuffer *>(pix_buf)->unmap();
1012}
1013
1014size_t GPU_pixel_buffer_size(GPUPixelBuffer *pix_buf)
1015{
1016 return reinterpret_cast<PixelBuffer *>(pix_buf)->get_size();
1017}
1018
1020{
1021 return reinterpret_cast<PixelBuffer *>(pix_buf)->get_native_handle();
1022}
1023
1026/* -------------------------------------------------------------------- */
1034{
1035 /* Backend may not exist when we are updating preferences from background mode. */
1036 GPUBackend *backend = GPUBackend::get();
1037 if (backend) {
1038 backend->samplers_update();
1039 }
1040}
1041
1044/* -------------------------------------------------------------------- */
1049{
1050 return to_component_len(tex_format);
1051}
1052
1054{
1055 return to_bytesize(data_format);
1056}
1057
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
#define ATTR_FALLTHROUGH
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
MINLINE int max_iii(int a, int b, int c)
MINLINE uint64_t ceil_to_multiple_ul(uint64_t a, uint64_t b)
#define STRNCPY(dst, src)
Definition BLI_string.h:593
unsigned char uchar
unsigned int uint
#define ARRAY_SIZE(arr)
@ GPU_SAMPLER_CUSTOM_COMPARE
int GPU_texture_height(const GPUTexture *texture)
GPUTexture * GPU_texture_create_compressed_2d(const char *name, int width, int height, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const void *data)
void GPU_texture_bind(GPUTexture *texture, int unit)
int GPU_texture_original_height(const GPUTexture *texture)
GPUTexture * GPU_texture_create_2d(const char *name, int width, int height, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
void GPU_texture_extend_mode_y(GPUTexture *texture, GPUSamplerExtendMode extend_mode)
GPUTexture * GPU_texture_create_1d(const char *name, int width, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
const char * GPU_texture_format_name(eGPUTextureFormat format)
void GPU_texture_free(GPUTexture *texture)
void GPU_pixel_buffer_unmap(GPUPixelBuffer *pixel_buf)
int GPU_texture_width(const GPUTexture *texture)
void GPU_texture_clear(GPUTexture *texture, eGPUDataFormat data_format, const void *data)
void GPU_texture_ref(GPUTexture *texture)
void ** GPU_texture_py_reference_get(GPUTexture *texture)
void GPU_texture_bind_ex(GPUTexture *texture, GPUSamplerState state, int unit)
int GPU_texture_dimensions(const GPUTexture *texture)
void GPU_texture_copy(GPUTexture *dst, GPUTexture *src)
bool GPU_texture_has_float_format(const GPUTexture *tex)
size_t GPU_texture_dataformat_size(eGPUDataFormat data_format)
void * GPU_texture_read(GPUTexture *texture, eGPUDataFormat data_format, int mip_level)
bool GPU_texture_is_cube(const GPUTexture *texture)
void GPU_texture_image_unbind_all()
int GPU_texture_depth(const GPUTexture *texture)
void GPU_texture_unbind(GPUTexture *texture)
size_t GPU_pixel_buffer_size(GPUPixelBuffer *pixel_buf)
int GPU_texture_mip_count(const GPUTexture *texture)
int GPU_texture_original_width(const GPUTexture *texture)
@ GPU_SAMPLER_STATE_TYPE_CUSTOM
@ GPU_SAMPLER_STATE_TYPE_PARAMETERS
@ GPU_SAMPLER_STATE_TYPE_INTERNAL
void GPU_texture_py_reference_set(GPUTexture *texture, void **py_ref)
void * GPU_pixel_buffer_map(GPUPixelBuffer *pixel_buf)
void GPU_pixel_buffer_free(GPUPixelBuffer *pixel_buf)
void GPU_texture_update_sub_from_pixel_buffer(GPUTexture *texture, eGPUDataFormat data_format, GPUPixelBuffer *pixel_buf, int offset_x, int offset_y, int offset_z, int width, int height, int depth)
void GPU_texture_anisotropic_filter(GPUTexture *texture, bool use_aniso)
GPUTexture * GPU_texture_create_error(int dimension, bool array)
int64_t GPU_pixel_buffer_get_native_handle(GPUPixelBuffer *pixel_buf)
GPUTexture * GPU_texture_create_cube_array(const char *name, int width, int layer_len, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
eGPUDataFormat
@ GPU_DATA_FLOAT
void GPU_texture_compare_mode(GPUTexture *texture, bool use_compare)
void GPU_texture_extend_mode_x(GPUTexture *texture, GPUSamplerExtendMode extend_mode)
void GPU_texture_extend_mode(GPUTexture *texture, GPUSamplerExtendMode extend_mode)
bool GPU_texture_has_integer_format(const GPUTexture *texture)
GPUTexture * GPU_texture_create_from_vertbuf(const char *name, blender::gpu::VertBuf *vertex_buf)
GPUTexture * GPU_texture_create_view(const char *name, GPUTexture *source_texture, eGPUTextureFormat view_format, int mip_start, int mip_len, int layer_start, int layer_len, bool cube_as_array, bool use_stencil)
bool GPU_texture_is_array(const GPUTexture *texture)
int GPU_texture_opengl_bindcode(const GPUTexture *texture)
eGPUTextureUsage
@ GPU_TEXTURE_USAGE_HOST_READ
@ GPU_TEXTURE_USAGE_GENERAL
@ GPU_TEXTURE_USAGE_FORMAT_VIEW
bool GPU_texture_has_stencil_format(const GPUTexture *texture)
GPUSamplerExtendMode
void GPU_texture_update_sub(GPUTexture *texture, eGPUDataFormat data_format, const void *pixels, int offset_x, int offset_y, int offset_z, int width, int height, int depth)
void GPU_texture_update_mipmap(GPUTexture *texture, int mip_level, eGPUDataFormat data_format, const void *pixels)
GPUTexture * GPU_texture_create_2d_array(const char *name, int width, int height, int layer_len, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
bool GPU_texture_has_signed_format(const GPUTexture *tex)
void GPU_texture_mipmap_mode(GPUTexture *texture, bool use_mipmap, bool use_filter)
void GPU_texture_image_unbind(GPUTexture *texture)
GPUTexture * GPU_texture_create_3d(const char *name, int width, int height, int depth, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const void *data)
void GPU_texture_image_bind(GPUTexture *texture, int unit)
bool GPU_texture_has_normalized_format(const GPUTexture *tex)
void GPU_texture_filter_mode(GPUTexture *texture, bool use_filter)
eGPUTextureFormat
@ GPU_RGB16
@ GPU_R16UI
@ GPU_RGB8
@ GPU_DEPTH32F_STENCIL8
@ GPU_SRGB8
@ GPU_R16I
@ GPU_SRGB8_A8
@ GPU_RG8_SNORM
@ GPU_DEPTH24_STENCIL8
@ GPU_RGB10_A2
@ GPU_RGB8I
@ GPU_R32I
@ GPU_RGBA8_SNORM
@ GPU_RGB10_A2UI
@ GPU_RG8UI
@ GPU_RGB16I
@ GPU_RGBA16_SNORM
@ GPU_RGB9_E5
@ GPU_SRGB8_A8_DXT5
@ GPU_RG8I
@ GPU_RG16I
@ GPU_RG32UI
@ GPU_RGB32I
@ GPU_RG8
@ GPU_RG32I
@ GPU_SRGB8_A8_DXT1
@ GPU_RGBA32UI
@ GPU_R8I
@ GPU_R16
@ GPU_RG16UI
@ GPU_RGBA8I
@ GPU_RGBA8_DXT1
@ GPU_RGBA8UI
@ GPU_RGB32F
@ GPU_RGBA16UI
@ GPU_RGBA16I
@ GPU_R8UI
@ GPU_RGBA16
@ GPU_SRGB8_A8_DXT3
@ GPU_RGB8_SNORM
@ GPU_RGBA8_DXT3
@ GPU_RGB32UI
@ GPU_R8_SNORM
@ GPU_RG32F
@ GPU_R8
@ GPU_RGB16_SNORM
@ GPU_DEPTH_COMPONENT24
@ GPU_RG16_SNORM
@ GPU_RGB8UI
@ GPU_RGB16F
@ GPU_RGB16UI
@ GPU_RGBA32I
@ GPU_RGBA8_DXT5
@ GPU_DEPTH_COMPONENT32F
@ GPU_R16_SNORM
@ GPU_DEPTH_COMPONENT16
void GPU_texture_unbind_all()
GPUTexture * GPU_texture_create_cube(const char *name, int width, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
void GPU_texture_update_mipmap_chain(GPUTexture *texture)
eGPUTextureUsage GPU_texture_usage(const GPUTexture *texture)
GPUPixelBuffer * GPU_pixel_buffer_create(size_t byte_size)
GPUTexture * GPU_texture_create_1d_array(const char *name, int width, int layer_len, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
void GPU_unpack_row_length_set(uint len)
@ GPU_SAMPLER_FILTERING_MIPMAP
@ GPU_SAMPLER_FILTERING_ANISOTROPIC
@ GPU_SAMPLER_FILTERING_LINEAR
void GPU_texture_original_size_set(GPUTexture *texture, int width, int height)
int GPU_texture_layer_count(const GPUTexture *texture)
bool GPU_texture_has_depth_format(const GPUTexture *texture)
void GPU_samplers_update()
size_t GPU_texture_component_len(eGPUTextureFormat format)
void GPU_texture_update(GPUTexture *texture, eGPUDataFormat data_format, const void *data)
void GPU_texture_get_mipmap_size(GPUTexture *texture, int mip_level, int *r_size)
unsigned int GPU_texture_memory_usage_get()
eGPUTextureFormat GPU_texture_format(const GPUTexture *texture)
void GPU_texture_swizzle_set(GPUTexture *texture, const char swizzle[4])
const GPUVertFormat * GPU_vertbuf_get_format(const blender::gpu::VertBuf *verts)
uint GPU_vertbuf_get_vertex_len(const blender::gpu::VertBuf *verts)
@ GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
static Context * get()
void attachment_remove(GPUAttachmentType type)
static GPUBackend * get()
virtual void samplers_update()=0
virtual PixelBuffer * pixelbuf_alloc(size_t size)=0
virtual Texture * texture_alloc(const char *name)=0
virtual void texture_unbind_all()=0
virtual void texture_unbind(Texture *tex)=0
virtual void image_unbind_all()=0
virtual void image_unbind(Texture *tex)=0
virtual void image_bind(Texture *tex, int unit)=0
virtual void texture_bind(Texture *tex, GPUSamplerState sampler, int unit)=0
virtual void texture_unpack_row_length_set(uint len)=0
void attach_to(FrameBuffer *fb, GPUAttachmentType type)
bool init_view(GPUTexture *src, eGPUTextureFormat format, eGPUTextureType type, int mip_start, int mip_len, int layer_start, int layer_len, bool cube_as_array, bool use_stencil)
eGPUTextureFormatFlag format_flag_
void update(eGPUDataFormat format, const void *data)
eGPUTextureUsage gpu_image_usage_flags_
char name_[DEBUG_NAME_LEN]
FrameBuffer * fb_[GPU_TEX_MAX_FBO_ATTACHED]
GPUAttachmentType fb_attachment_[GPU_TEX_MAX_FBO_ATTACHED]
bool init_1D(int w, int layers, int mip_len, eGPUTextureFormat format)
bool init_buffer(VertBuf *vbo, eGPUTextureFormat format)
virtual bool init_internal()=0
bool init_cubemap(int w, int layers, int mip_len, eGPUTextureFormat format)
virtual void update_sub(int mip, int offset[3], int extent[3], eGPUDataFormat format, const void *data)=0
void mip_size_get(int mip, int r_size[3]) const
virtual void copy_to(Texture *tex)=0
void usage_set(eGPUTextureUsage usage_flags)
bool init_3D(int w, int h, int d, int mip_len, eGPUTextureFormat format)
Texture(const char *name)
void detach_from(FrameBuffer *fb)
bool init_2D(int w, int h, int layers, int mip_len, eGPUTextureFormat format)
additional_info("compositor_sum_float_shared") .push_constant(Type additional_info("compositor_sum_float_shared") .push_constant(Type GPU_RGBA32F
#define floorf(x)
int len
DOF_TILES_FLATTEN_GROUP_SIZE coc_tx GPU_R11F_G11F_B10F
out_radiance out_gbuf_normal out_gbuf_closure2 GPU_RG16
SHADOW_TILEMAP_RES tiles_buf[] statistics_buf render_view_buf[SHADOW_VIEW_MAX] GPU_R32UI
RAYTRACE_GROUP_SIZE additional_info("eevee_shared", "eevee_gbuffer_data", "eevee_global_ubo", "eevee_sampling_data", "eevee_utility_texture", "eevee_hiz_data", "draw_view") .specialization_constant(Type RAYTRACE_GROUP_SIZE in_sh_0_tx in_sh_2_tx screen_normal_tx GPU_RGBA8
static GPUTexture * gpu_texture_create(const char *name, const int w, const int h, const int d, const eGPUTextureType type, int mip_len, eGPUTextureFormat tex_format, eGPUDataFormat data_format, eGPUTextureUsage usage, const void *pixels)
BLI_INLINE float fb(float length, float L)
format
static ulong state[N]
static void clear(Message &msg)
Definition msgfmt.cc:218
static Context * unwrap(GPUContext *ctx)
size_t to_block_size(eGPUTextureFormat data_type)
static GPUContext * wrap(Context *ctx)
size_t to_bytesize(GPUIndexBufType type)
eGPUDataFormat to_data_format(eGPUTextureFormat tex_format)
static eGPUTextureFormat to_texture_format(const GPUVertFormat *format)
eGPUTextureFormatFlag to_format_flag(eGPUTextureFormat format)
int to_component_len(eGPUTextureFormat format)
static void update(bNodeTree *ntree)
__int64 int64_t
Definition stdint.h:89
GPUSamplerFiltering filtering