Blender V4.5
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
8
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/* -------------------------------------------------------------------- */
25
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) {
46 fb_[i]->attachment_remove(fb_attachment_[i]);
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) {
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
186
187/* -------------------------------------------------------------------- */
190
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. */
198 fb_[i]->attachment_remove(fb_attachment_[i]);
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) {
218 fb_[i]->attachment_remove(fb_attachment_[i]);
219 fb_[i] = nullptr;
220 return;
221 }
222 }
223 BLI_assert_msg(0, "GPU: Error: Texture: Framebuffer is not attached");
224}
225
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
236
237} // namespace blender::gpu
238
239/* -------------------------------------------------------------------- */
242
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 eGPUTextureUsage usage,
264 const void *pixels,
265 eGPUDataFormat data_format = GPU_DATA_FLOAT)
266{
267 BLI_assert(mip_len > 0);
268 Texture *tex = GPUBackend::get()->texture_alloc(name);
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 width,
304 int mip_len,
306 eGPUTextureUsage usage,
307 const float *data)
308{
309 return gpu_texture_create(name, width, 0, 0, GPU_TEXTURE_1D, mip_len, format, usage, data);
310}
311
312GPUTexture *GPU_texture_create_1d_array(const char *name,
313 int width,
314 int layer_len,
315 int mip_len,
317 eGPUTextureUsage usage,
318 const float *data)
319{
320 return gpu_texture_create(
321 name, width, layer_len, 0, GPU_TEXTURE_1D_ARRAY, mip_len, format, usage, data);
322}
323
324GPUTexture *GPU_texture_create_2d(const char *name,
325 int width,
326 int height,
327 int mip_len,
329 eGPUTextureUsage usage,
330 const float *data)
331{
332 return gpu_texture_create(name, width, height, 0, GPU_TEXTURE_2D, mip_len, format, usage, data);
333}
334
335GPUTexture *GPU_texture_create_2d_array(const char *name,
336 int width,
337 int height,
338 int layer_len,
339 int mip_len,
341 eGPUTextureUsage usage,
342 const float *data)
343{
344 return gpu_texture_create(
345 name, width, height, layer_len, GPU_TEXTURE_2D_ARRAY, mip_len, format, usage, data);
346}
347
348GPUTexture *GPU_texture_create_3d(const char *name,
349 int width,
350 int height,
351 int depth,
352 int mip_len,
353 eGPUTextureFormat texture_format,
354 eGPUTextureUsage usage,
355 const void *data)
356{
357 return gpu_texture_create(
358 name, width, height, depth, GPU_TEXTURE_3D, mip_len, texture_format, usage, data);
359}
360
361GPUTexture *GPU_texture_create_cube(const char *name,
362 int width,
363 int mip_len,
365 eGPUTextureUsage usage,
366 const float *data)
367{
368 return gpu_texture_create(name, width, width, 0, GPU_TEXTURE_CUBE, mip_len, format, usage, data);
369}
370
371GPUTexture *GPU_texture_create_cube_array(const char *name,
372 int width,
373 int layer_len,
374 int mip_len,
376 eGPUTextureUsage usage,
377 const float *data)
378{
379 return gpu_texture_create(
380 name, width, width, layer_len, GPU_TEXTURE_CUBE_ARRAY, mip_len, format, usage, data);
381}
382
383GPUTexture *GPU_texture_create_compressed_2d(const char *name,
384 int width,
385 int height,
386 int mip_len,
387 eGPUTextureFormat tex_format,
388 eGPUTextureUsage usage,
389 const void *data)
390{
391 Texture *tex = GPUBackend::get()->texture_alloc(name);
392 tex->usage_set(usage);
393 bool success = tex->init_2D(width, height, 0, mip_len, tex_format);
394
395 if (!success) {
396 delete tex;
397 return nullptr;
398 }
399 if (data) {
400 size_t ofs = 0;
401 for (int mip = 0; mip < mip_len; mip++) {
402 int extent[3], offset[3] = {0, 0, 0};
403 tex->mip_size_get(mip, extent);
404
405 size_t size = ((extent[0] + 3) / 4) * ((extent[1] + 3) / 4) * to_block_size(tex_format);
406 tex->update_sub(mip, offset, extent, to_data_format(tex_format), (uchar *)data + ofs);
407
408 ofs += size;
409 }
410 }
411 return reinterpret_cast<GPUTexture *>(tex);
412}
413
414GPUTexture *GPU_texture_create_from_vertbuf(const char *name, blender::gpu::VertBuf *vert)
415{
416#ifndef NDEBUG
417 /* Vertex buffers used for texture buffers must be flagged with:
418 * GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY. */
420 "Vertex Buffers used for textures should have usage flag "
421 "GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY.");
422#endif
424 Texture *tex = GPUBackend::get()->texture_alloc(name);
425
426 bool success = tex->init_buffer(vert, tex_format);
427 if (!success) {
428 delete tex;
429 return nullptr;
430 }
431 return reinterpret_cast<GPUTexture *>(tex);
432}
433
434GPUTexture *GPU_texture_create_error(int dimension, bool is_array)
435{
436 const float pixel[4] = {1.0f, 0.0f, 1.0f, 1.0f};
437 int w = 1;
438 int h = (dimension < 2 && !is_array) ? 0 : 1;
439 int d = (dimension < 3 && !is_array) ? 0 : 1;
440
442 type = (dimension == 2) ? (is_array ? GPU_TEXTURE_2D_ARRAY : GPU_TEXTURE_2D) : type;
443 type = (dimension == 1) ? (is_array ? GPU_TEXTURE_1D_ARRAY : GPU_TEXTURE_1D) : type;
444
445 return gpu_texture_create(
446 "invalid_tex", w, h, d, type, 1, GPU_RGBA8, GPU_TEXTURE_USAGE_GENERAL, pixel);
447}
448
449GPUTexture *GPU_texture_create_view(const char *name,
450 GPUTexture *source_texture,
451 eGPUTextureFormat view_format,
452 int mip_start,
453 int mip_len,
454 int layer_start,
455 int layer_len,
456 bool cube_as_array,
457 bool use_stencil)
458{
459 BLI_assert(mip_len > 0);
460 BLI_assert(layer_len > 0);
461 BLI_assert_msg(use_stencil == false ||
463 "Source texture of TextureView must have GPU_TEXTURE_USAGE_FORMAT_VIEW usage "
464 "flag if view texture uses stencil texturing.");
465 BLI_assert_msg((view_format == GPU_texture_format(source_texture)) ||
467 "Source texture of TextureView must have GPU_TEXTURE_USAGE_FORMAT_VIEW usage "
468 "flag if view texture format is different.");
470 view->init_view(source_texture,
471 view_format,
472 unwrap(source_texture)->type_get(),
473 mip_start,
474 mip_len,
475 layer_start,
476 layer_len,
477 cube_as_array,
478 use_stencil);
479 return wrap(view);
480}
481
482/* ------ Usage ------ */
483eGPUTextureUsage GPU_texture_usage(const GPUTexture *texture_)
484{
485 const Texture *tex = reinterpret_cast<const Texture *>(texture_);
486 return tex->usage_get();
487}
488
489/* ------ Update ------ */
490
492 int mip_level,
493 eGPUDataFormat data_format,
494 const void *pixels)
495{
496 int extent[3] = {1, 1, 1}, offset[3] = {0, 0, 0};
497 unwrap(texture)->mip_size_get(mip_level, extent);
498 unwrap(texture)->update_sub(mip_level, offset, extent, data_format, pixels);
499}
500
501void GPU_texture_update_sub(GPUTexture *tex,
502 eGPUDataFormat data_format,
503 const void *pixels,
504 int offset_x,
505 int offset_y,
506 int offset_z,
507 int width,
508 int height,
509 int depth)
510{
511 int offset[3] = {offset_x, offset_y, offset_z};
512 int extent[3] = {width, height, depth};
513 unwrap(tex)->update_sub(0, offset, extent, data_format, pixels);
514}
515
517 eGPUDataFormat data_format,
518 GPUPixelBuffer *pixel_buf,
519 int offset_x,
520 int offset_y,
521 int offset_z,
522 int width,
523 int height,
524 int depth)
525{
526 int offset[3] = {offset_x, offset_y, offset_z};
527 int extent[3] = {width, height, depth};
528 unwrap(texture)->update_sub(offset, extent, data_format, pixel_buf);
529}
530
531void *GPU_texture_read(GPUTexture *texture, eGPUDataFormat data_format, int mip_level)
532{
535 "The host-read usage flag must be specified up-front. Only textures which require data "
536 "reads should be flagged, allowing the backend to make certain optimizations.");
537 return unwrap(texture)->read(mip_level, data_format);
538}
539
540void GPU_texture_clear(GPUTexture *tex, eGPUDataFormat data_format, const void *data)
541{
542 BLI_assert(data != nullptr); /* Do not accept nullptr as parameter. */
543 unwrap(tex)->clear(data_format, data);
544}
545
546void GPU_texture_update(GPUTexture *tex, eGPUDataFormat data_format, const void *data)
547{
548 unwrap(tex)->update(data_format, data);
549}
550
555
556/* ------ Binding ------ */
557
559{
560 Texture *tex = unwrap(texture);
563}
564
565void GPU_texture_bind(GPUTexture *texture, int unit)
566{
567 Texture *tex = unwrap(texture);
569}
570
572{
573 Texture *tex = unwrap(texture);
575}
576
581
582void GPU_texture_image_bind(GPUTexture *tex, int unit)
583{
585}
586
587void GPU_texture_image_unbind(GPUTexture *tex)
588{
590}
591
596
598{
599 unwrap(tex)->generate_mipmap();
600}
601
602void GPU_texture_copy(GPUTexture *dst_, GPUTexture *src_)
603{
604 Texture *src = unwrap(src_);
605 Texture *dst = unwrap(dst_);
606 src->copy_to(dst);
607}
608
609void GPU_texture_compare_mode(GPUTexture *texture, bool use_compare)
610{
611 Texture *tex = unwrap(texture);
612 /* Only depth formats does support compare mode. */
613 BLI_assert(!(use_compare) || (tex->format_flag_get() & GPU_FORMAT_DEPTH));
614
618}
619
620void GPU_texture_filter_mode(GPUTexture *texture, bool use_filter)
621{
622 Texture *tex = unwrap(texture);
623 /* Stencil and integer format does not support filtering. */
624 BLI_assert(!(use_filter) ||
627}
628
629void GPU_texture_mipmap_mode(GPUTexture *texture, bool use_mipmap, bool use_filter)
630{
631 Texture *tex = unwrap(texture);
632 /* Stencil and integer format does not support filtering. */
633 BLI_assert(!(use_filter || use_mipmap) ||
637}
638
639void GPU_texture_anisotropic_filter(GPUTexture *texture, bool use_aniso)
640{
641 Texture *tex = unwrap(texture);
642 /* Stencil and integer format does not support filtering. */
643 BLI_assert(!(use_aniso) ||
646}
647
649{
650 unwrap(texture)->sampler_state.extend_x = extend_mode;
651}
652
654{
655 unwrap(texture)->sampler_state.extend_yz = extend_mode;
656}
657
659{
660 unwrap(texture)->sampler_state.extend_x = extend_mode;
661 unwrap(texture)->sampler_state.extend_yz = extend_mode;
662}
663
664void GPU_texture_swizzle_set(GPUTexture *texture, const char swizzle[4])
665{
666 unwrap(texture)->swizzle_set(swizzle);
667}
668
669void GPU_texture_free(GPUTexture *texture)
670{
671 Texture *tex = unwrap(texture);
672 tex->refcount--;
673
674 if (tex->refcount < 0) {
675 fprintf(stderr, "GPUTexture: negative refcount\n");
676 }
677
678 if (tex->refcount == 0) {
679 delete tex;
680 }
681}
682
683void GPU_texture_ref(GPUTexture *texture)
684{
685 unwrap(texture)->refcount++;
686}
687
688int GPU_texture_dimensions(const GPUTexture *texture)
689{
690 eGPUTextureType type = unwrap(texture)->type_get();
691 if (type & GPU_TEXTURE_1D) {
692 return 1;
693 }
694 if (type & GPU_TEXTURE_2D) {
695 return 2;
696 }
697 if (type & GPU_TEXTURE_3D) {
698 return 3;
699 }
700 if (type & GPU_TEXTURE_CUBE) {
701 return 2;
702 }
703 /* GPU_TEXTURE_BUFFER */
704 return 1;
705}
706
707int GPU_texture_width(const GPUTexture *texture)
708{
709 return unwrap(texture)->width_get();
710}
711
712int GPU_texture_height(const GPUTexture *texture)
713{
714 return unwrap(texture)->height_get();
715}
716
717int GPU_texture_depth(const GPUTexture *texture)
718{
719 return unwrap(texture)->depth_get();
720}
721
722int GPU_texture_layer_count(const GPUTexture *texture)
723{
724 return unwrap(texture)->layer_count();
725}
726
727int GPU_texture_mip_count(const GPUTexture *texture)
728{
729 return unwrap(texture)->mip_count();
730}
731
733{
734 return unwrap(texture)->src_w;
735}
736
738{
739 return unwrap(texture)->src_h;
740}
741
742void GPU_texture_original_size_set(GPUTexture *texture, int w, int h)
743{
744 unwrap(texture)->src_w = w;
745 unwrap(texture)->src_h = h;
746}
747
749{
750 return unwrap(texture)->format_get();
751}
752
754{
755 switch (texture_format) {
756 /* Formats texture & render-buffer */
757 case GPU_RGBA8UI:
758 return "RGBA8UI";
759 case GPU_RGBA8I:
760 return "RGBA8I";
761 case GPU_RGBA8:
762 return "RGBA8";
763 case GPU_RGBA32UI:
764 return "RGBA32UI";
765 case GPU_RGBA32I:
766 return "RGBA32I";
767 case GPU_RGBA32F:
768 return "RGBA32F";
769 case GPU_RGBA16UI:
770 return "RGBA16UI";
771 case GPU_RGBA16I:
772 return "RGBA16I";
773 case GPU_RGBA16F:
774 return "RGBA16F";
775 case GPU_RGBA16:
776 return "RGBA16";
777 case GPU_RG8UI:
778 return "RG8UI";
779 case GPU_RG8I:
780 return "RG8I";
781 case GPU_RG8:
782 return "RG8";
783 case GPU_RG32UI:
784 return "RG32UI";
785 case GPU_RG32I:
786 return "RG32I";
787 case GPU_RG32F:
788 return "RG32F";
789 case GPU_RG16UI:
790 return "RG16UI";
791 case GPU_RG16I:
792 return "RG16I";
793 case GPU_RG16F:
794 return "RG16F";
795 case GPU_RG16:
796 return "RG16";
797 case GPU_R8UI:
798 return "R8UI";
799 case GPU_R8I:
800 return "R8I";
801 case GPU_R8:
802 return "R8";
803 case GPU_R32UI:
804 return "R32UI";
805 case GPU_R32I:
806 return "R32I";
807 case GPU_R32F:
808 return "R32F";
809 case GPU_R16UI:
810 return "R16UI";
811 case GPU_R16I:
812 return "R16I";
813 case GPU_R16F:
814 return "R16F";
815 case GPU_R16:
816 return "R16";
817 /* Special formats texture & render-buffer */
818 case GPU_RGB10_A2:
819 return "RGB10_A2";
820 case GPU_RGB10_A2UI:
821 return "RGB10_A2UI";
823 return "R11F_G11F_B10F";
825 return "DEPTH32F_STENCIL8";
827 return "DEPTH24_STENCIL8";
828 case GPU_SRGB8_A8:
829 return "SRGB8_A8";
830 /* Texture only formats. */
831 case GPU_RGB16F:
832 return "RGB16F";
833 case GPU_RGB16_SNORM:
834 return "RGB16_SNORM";
835 case GPU_RGB16I:
836 return "RGB16I";
837 case GPU_RGB16UI:
838 return "RGB16UI";
839 case GPU_RGB16:
840 return "RGB16";
841 case GPU_RGBA16_SNORM:
842 return "RGBA16_SNORM";
843 case GPU_RGBA8_SNORM:
844 return "RGBA8_SNORM";
845 case GPU_RGB32F:
846 return "RGB32F";
847 case GPU_RGB32I:
848 return "RGB32I";
849 case GPU_RGB32UI:
850 return "RGB32UI";
851 case GPU_RGB8_SNORM:
852 return "RGB8_SNORM";
853 case GPU_RGB8:
854 return "RGB8";
855 case GPU_RGB8I:
856 return "RGB8I";
857 case GPU_RGB8UI:
858 return "RGB8UI";
859 case GPU_RG16_SNORM:
860 return "RG16_SNORM";
861 case GPU_RG8_SNORM:
862 return "RG8_SNORM";
863 case GPU_R16_SNORM:
864 return "R16_SNORM";
865 case GPU_R8_SNORM:
866 return "R8_SNORM";
867 /* Special formats, texture only. */
869 return "SRGB8_A8_DXT1";
871 return "SRGB8_A8_DXT3";
873 return "SRGB8_A8_DXT5";
874 case GPU_RGBA8_DXT1:
875 return "RGBA8_DXT1";
876 case GPU_RGBA8_DXT3:
877 return "RGBA8_DXT3";
878 case GPU_RGBA8_DXT5:
879 return "RGBA8_DXT5";
880 case GPU_SRGB8:
881 return "SRGB8";
882 case GPU_RGB9_E5:
883 return "RGB9_E5";
884 /* Depth Formats. */
886 return "DEPTH_COMPONENT32F";
888 return "DEPTH_COMPONENT24";
890 return "DEPTH_COMPONENT16";
891 }
893 return "";
894}
895
897{
898 return (unwrap(texture)->format_flag_get() & GPU_FORMAT_DEPTH) != 0;
899}
900
902{
903 return (unwrap(texture)->format_flag_get() & GPU_FORMAT_STENCIL) != 0;
904}
905
907{
908 return (unwrap(texture)->format_flag_get() & GPU_FORMAT_INTEGER) != 0;
909}
910
912{
913 return (unwrap(texture)->format_flag_get() & GPU_FORMAT_FLOAT) != 0;
914}
915
917{
918 return (unwrap(texture)->format_flag_get() & GPU_FORMAT_NORMALIZED_INTEGER) != 0;
919}
920
922{
923 return (unwrap(texture)->format_flag_get() & GPU_FORMAT_SIGNED) != 0;
924}
925
926bool GPU_texture_is_cube(const GPUTexture *texture)
927{
928 return (unwrap(texture)->type_get() & GPU_TEXTURE_CUBE) != 0;
929}
930
931bool GPU_texture_is_array(const GPUTexture *texture)
932{
933 return (unwrap(texture)->type_get() & GPU_TEXTURE_ARRAY) != 0;
934}
935
936#ifndef GPU_NO_USE_PY_REFERENCES
938{
939 return unwrap(texture)->py_ref;
940}
941
942void GPU_texture_py_reference_set(GPUTexture *texture, void **py_ref)
943{
944 BLI_assert(py_ref == nullptr || unwrap(texture)->py_ref == nullptr);
945 unwrap(texture)->py_ref = py_ref;
946}
947#endif
948
949/* TODO: remove. */
951{
952 return unwrap(texture)->gl_bindcode_get();
953}
954
955void GPU_texture_get_mipmap_size(GPUTexture *texture, int mip_level, int *r_size)
956{
957 unwrap(texture)->mip_size_get(mip_level, r_size);
958}
959
961
962/* -------------------------------------------------------------------- */
967
968GPUPixelBuffer *GPU_pixel_buffer_create(size_t size)
969{
970 /* Ensure buffer satisfies the alignment of 256 bytes for copying
971 * data between buffers and textures. As specified in:
972 * https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf
973 *
974 * Ensuring minimal size across all platforms handles cases for small-sized
975 * textures and avoids issues with zero-sized buffers. */
978 return wrap(pixbuf);
979}
980
981void GPU_pixel_buffer_free(GPUPixelBuffer *pixel_buf)
982{
983 PixelBuffer *handle = unwrap(pixel_buf);
984 delete handle;
985}
986
987void *GPU_pixel_buffer_map(GPUPixelBuffer *pixel_buf)
988{
989 return unwrap(pixel_buf)->map();
990}
991
992void GPU_pixel_buffer_unmap(GPUPixelBuffer *pixel_buf)
993{
994 unwrap(pixel_buf)->unmap();
995}
996
997size_t GPU_pixel_buffer_size(GPUPixelBuffer *pixel_buf)
998{
999 return unwrap(pixel_buf)->get_size();
1000}
1001
1003{
1004 return unwrap(pixel_buf)->get_native_handle();
1005}
1006
1008
1009/* -------------------------------------------------------------------- */
1015
1017{
1018 /* Backend may not exist when we are updating preferences from background mode. */
1019 GPUBackend *backend = GPUBackend::get();
1020 if (backend) {
1021 backend->samplers_update();
1022 }
1023}
1024
1026
1027/* -------------------------------------------------------------------- */
1030
1032{
1033 return to_component_len(tex_format);
1034}
1035
1037{
1038 return to_bytesize(data_format);
1039}
1040
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
#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)
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
unsigned char uchar
unsigned int uint
#define ARRAY_SIZE(arr)
static AppView * view
@ 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)
size_t GPU_texture_dataformat_size(eGPUDataFormat data_format)
void * GPU_texture_read(GPUTexture *texture, eGPUDataFormat data_format, int mip_level)
bool GPU_texture_has_float_format(const GPUTexture *texture)
bool GPU_texture_is_cube(const GPUTexture *texture)
void GPU_texture_image_unbind_all()
int GPU_texture_depth(const GPUTexture *texture)
GPUPixelBufferNativeHandle GPU_pixel_buffer_get_native_handle(GPUPixelBuffer *pixel_buf)
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)
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)
bool GPU_texture_has_normalized_format(const GPUTexture *texture)
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)
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)
void GPU_texture_filter_mode(GPUTexture *texture, bool use_filter)
eGPUTextureFormat
@ GPU_RGB16
@ GPU_R16UI
@ GPU_RGB8
@ GPU_RG16F
@ GPU_DEPTH32F_STENCIL8
@ GPU_R32F
@ 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_R16F
@ GPU_RGB16I
@ GPU_RGBA16_SNORM
@ GPU_RGB9_E5
@ GPU_SRGB8_A8_DXT5
@ GPU_RG8I
@ GPU_RG16I
@ GPU_RG32UI
@ GPU_RGB32I
@ GPU_RGBA32F
@ GPU_RGBA16F
@ GPU_RG8
@ GPU_RG32I
@ GPU_SRGB8_A8_DXT1
@ GPU_RG16
@ 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_R32UI
@ GPU_RGBA32I
@ GPU_RGBA8_DXT5
@ GPU_DEPTH_COMPONENT32F
@ GPU_R16_SNORM
@ GPU_DEPTH_COMPONENT16
@ GPU_R11F_G11F_B10F
@ GPU_RGBA8
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)
bool GPU_texture_has_signed_format(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
BMesh const char void * data
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()
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_get() const
eGPUTextureFormatFlag format_flag_
void update(eGPUDataFormat format, const void *data)
eGPUTextureUsage gpu_image_usage_flags_
eGPUTextureUsage usage_get() const
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)
#define floorf(x)
TEX_TEMPLATE DataVec texture(T, FltCoord, float=0.0f) RET
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, eGPUTextureUsage usage, const void *pixels, eGPUDataFormat data_format=GPU_DATA_FLOAT)
BLI_INLINE float fb(float length, float L)
format
static ulong state[N]
static Context * unwrap(GPUContext *ctx)
size_t to_block_size(eGPUTextureFormat data_type)
static GPUContext * wrap(Context *ctx)
int to_bytesize(const DataFormat format)
eGPUTextureFormatFlag to_format_flag(eGPUTextureFormat format)
int to_component_len(eGPUTextureFormat format)
constexpr DataFormat to_data_format(TextureFormat format)
constexpr TextureFormat to_texture_format(TextureTargetFormat format)
GPUSamplerCustomType custom_type
GPUSamplerStateType type
void set_filtering_flag_from_test(GPUSamplerFiltering filtering_flags, bool test)
i
Definition text_draw.cc:230
uint len