Blender V5.0
gpu_framebuffer.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 "MEM_guardedalloc.h"
10
11#include "BLI_math_base.h"
12#include "BLI_string.h"
13#include "BLI_utildefines.h"
14
15#include "GPU_capabilities.hh"
16#include "GPU_texture.hh"
17
18#include "gpu_backend.hh"
21
23
24namespace blender::gpu {
25
26/* -------------------------------------------------------------------- */
29
31{
32 if (name) {
34 }
35 else {
36 name_[0] = '\0';
37 }
38 /* Force config on first use. */
39 dirty_attachments_ = true;
40 dirty_state_ = true;
41
42 for (GPUAttachment &attachment : attachments_) {
43 attachment.tex = nullptr;
44 attachment.mip = -1;
45 attachment.layer = -1;
46 }
47}
48
50{
51 for (GPUAttachment &attachment : attachments_) {
52 if (attachment.tex != nullptr) {
53 reinterpret_cast<Texture *>(attachment.tex)->detach_from(this);
54 }
55 }
56
57#ifndef GPU_NO_USE_PY_REFERENCES
58 if (this->py_ref) {
59 *this->py_ref = nullptr;
60 }
61#endif
62}
63
65
66/* -------------------------------------------------------------------- */
69
71{
72 if (new_attachment.mip == -1) {
73 return; /* GPU_ATTACHMENT_LEAVE */
74 }
75
76 if (type >= GPU_FB_MAX_ATTACHMENT) {
77 fprintf(stderr,
78 "GPUFramebuffer: Error: Trying to attach texture to type %d but maximum slot is %d.\n",
81 return;
82 }
83
84 if (new_attachment.tex) {
85 if (new_attachment.layer > 0) {
86 BLI_assert(GPU_texture_is_cube(new_attachment.tex) ||
87 GPU_texture_is_array(new_attachment.tex));
88 }
89 if (GPU_texture_has_stencil_format(new_attachment.tex)) {
91 }
92 else if (GPU_texture_has_depth_format(new_attachment.tex)) {
94 }
95 }
96
97 GPUAttachment &attachment = attachments_[type];
98
99 set_color_attachment_bit(type, new_attachment.tex != nullptr);
100
101 if (attachment.tex == new_attachment.tex && attachment.layer == new_attachment.layer &&
102 attachment.mip == new_attachment.mip)
103 {
104 return; /* Exact same texture already bound here. */
105 }
106 /* Unbind previous and bind new. */
107 /* TODO(fclem): cleanup the casts. */
108 if (attachment.tex) {
109 reinterpret_cast<Texture *>(attachment.tex)->detach_from(this);
110 }
111
112 /* Might be null if this is for unbinding. */
113 if (new_attachment.tex) {
114 reinterpret_cast<Texture *>(new_attachment.tex)->attach_to(this, type);
115 }
116 else {
117 /* GPU_ATTACHMENT_NONE */
118 }
119
120 attachment = new_attachment;
121 dirty_attachments_ = true;
122}
123
130
131void FrameBuffer::subpass_transition(const GPUAttachmentState depth_attachment_state,
132 Span<GPUAttachmentState> color_attachment_states)
133{
134 /* NOTE: Depth is not supported as input attachment because the Metal API doesn't support it and
135 * because depth is not compatible with the framebuffer fetch implementation. */
136 BLI_assert(depth_attachment_state != GPU_ATTACHMENT_READ);
137
140 {
141 BLI_assert(depth_attachment_state == GPU_ATTACHMENT_IGNORE);
142 }
143
144 BLI_assert(color_attachment_states.size() <= GPU_FB_MAX_COLOR_ATTACHMENT);
147 if (this->attachments_[type].tex) {
148 BLI_assert(i < color_attachment_states.size());
149 set_color_attachment_bit(type, color_attachment_states[i] == GPU_ATTACHMENT_WRITE);
150 }
151 else {
152 BLI_assert(i >= color_attachment_states.size() ||
153 color_attachment_states[i] == GPU_ATTACHMENT_IGNORE);
154 }
155 }
156
157 subpass_transition_impl(depth_attachment_state, color_attachment_states);
158}
159
160void FrameBuffer::load_store_config_array(const GPULoadStore *load_store_actions, uint actions_len)
161{
162 /* Follows attachment structure of GPU_framebuffer_config_array/GPU_framebuffer_ensure_config */
163 const GPULoadStore &depth_action = load_store_actions[0];
164 Span<GPULoadStore> color_attachment_actions(load_store_actions + 1, actions_len - 1);
165 BLI_assert(color_attachment_actions.size() <= GPU_FB_MAX_COLOR_ATTACHMENT);
166
169 {
172 }
173
176 }
177
178 if (this->attachments_[GPU_FB_DEPTH_ATTACHMENT].tex) {
180 }
181
184 if (this->attachments_[type].tex) {
185 BLI_assert(i < color_attachment_actions.size());
186 this->attachment_set_loadstore_op(type, color_attachment_actions[i]);
187 }
188 else {
189 BLI_assert(i >= color_attachment_actions.size() ||
190 (color_attachment_actions[i].load_action == GPU_LOADACTION_DONT_CARE &&
191 color_attachment_actions[i].store_action == GPU_STOREACTION_DONT_CARE));
192 }
193 }
194}
195
197{
198 uint total_bits = 0;
199 for (GPUAttachment &attachment : attachments_) {
200 Texture *tex = reinterpret_cast<Texture *>(attachment.tex);
201 if (tex != nullptr) {
202 int bits = to_bytesize(tex->format_get()) * to_component_len(tex->format_get());
203 total_bits += bits;
204 }
205 }
206 return total_bits;
207}
208
210
211} // namespace blender::gpu
212
213/* -------------------------------------------------------------------- */
216
217using namespace blender;
218using namespace blender::gpu;
219
221{
222 /* We generate the FB object later at first use in order to
223 * create the frame-buffer in the right opengl context. */
225}
226
228{
229 delete fb;
230}
231
233{
234 return fb->name_get();
235}
236
237/* ---------- Binding ----------- */
238
240{
241 const bool enable_srgb = true;
242 /* Disable custom loadstore and bind. */
243 fb->set_use_explicit_loadstore(false);
244 fb->bind(enable_srgb);
245}
246
248 const GPULoadStore *load_store_actions,
249 uint actions_len)
250{
251 const bool enable_srgb = true;
252 /* Bind with explicit loadstore state */
253 fb->set_use_explicit_loadstore(true);
254 fb->bind(enable_srgb);
255
256 /* Update load store */
257 fb->load_store_config_array(load_store_actions, actions_len);
258}
259
261 const GPUAttachmentState *attachment_states,
262 uint attachment_len)
263{
264 fb->subpass_transition(attachment_states[0],
265 Span<GPUAttachmentState>(attachment_states + 1, attachment_len - 1));
266}
267
269{
270 const bool enable_srgb = false;
271 fb->bind(enable_srgb);
272}
273
274void GPU_backbuffer_bind(GPUBackBuffer back_buffer_type)
275{
276 Context *ctx = Context::get();
277
278 if (back_buffer_type == GPU_BACKBUFFER_LEFT) {
279 ctx->back_left->bind(false);
280 }
281 else {
282 ctx->back_right->bind(false);
283 }
284}
285
287{
288 Context::get()->back_left->bind(false);
289}
290
292{
293 Context *ctx = Context::get();
294 return ctx ? ctx->active_fb : nullptr;
295}
296
298{
299 Context *ctx = Context::get();
300 return ctx ? ctx->back_left : nullptr;
301}
302
304{
305 return (gpu_fb == GPU_framebuffer_active_get());
306}
307
308/* ---------- Attachment Management ----------- */
309
310bool GPU_framebuffer_check_valid(gpu::FrameBuffer *gpu_fb, char err_out[256])
311{
312 return gpu_fb->check(err_out);
313}
314
316 GPUAttachment attachment,
317 int slot)
318{
319 Texture *tex = reinterpret_cast<Texture *>(attachment.tex);
320 GPUAttachmentType type = tex->attachment_type(slot);
321 gpu_fb->attachment_set(type, attachment);
322}
323
326 int slot,
327 int mip)
328{
329 GPUAttachment attachment = GPU_ATTACHMENT_TEXTURE_MIP(tex, mip);
330 gpu_framebuffer_texture_attach_ex(fb, attachment, slot);
331}
332
334 gpu::FrameBuffer *fb, blender::gpu::Texture *tex, int slot, int layer, int mip)
335{
336 GPUAttachment attachment = GPU_ATTACHMENT_TEXTURE_LAYER_MIP(tex, layer, mip);
337 gpu_framebuffer_texture_attach_ex(fb, attachment, slot);
338}
339
341 gpu::FrameBuffer *fb, blender::gpu::Texture *tex, int slot, int face, int mip)
342{
343 GPUAttachment attachment = GPU_ATTACHMENT_TEXTURE_CUBEFACE_MIP(tex, face, mip);
344 gpu_framebuffer_texture_attach_ex(fb, attachment, slot);
345}
346
351
353 const GPUAttachment *config,
354 int config_len)
355{
356 const GPUAttachment &depth_attachment = config[0];
357 Span<GPUAttachment> color_attachments(config + 1, config_len - 1);
358
359 if (depth_attachment.mip == -1) {
360 /* GPU_ATTACHMENT_LEAVE */
361 }
362 else if (depth_attachment.tex == nullptr) {
363 /* GPU_ATTACHMENT_NONE: Need to clear both targets. */
364 fb->attachment_set(GPU_FB_DEPTH_STENCIL_ATTACHMENT, depth_attachment);
365 fb->attachment_set(GPU_FB_DEPTH_ATTACHMENT, depth_attachment);
366 }
367 else {
368 GPUAttachmentType type = GPU_texture_has_stencil_format(depth_attachment.tex) ?
371 fb->attachment_set(type, depth_attachment);
372 }
373
375 for (const GPUAttachment &attachment : color_attachments) {
376 fb->attachment_set(type, attachment);
377 ++type;
378 }
379}
380
381void GPU_framebuffer_default_size(gpu::FrameBuffer *gpu_fb, int width, int height)
382{
383 gpu_fb->default_size_set(width, height);
384}
385
386/* ---------- Viewport & Scissor Region ----------- */
387
388void GPU_framebuffer_viewport_set(gpu::FrameBuffer *gpu_fb, int x, int y, int width, int height)
389{
390 int viewport_rect[4] = {x, y, width, height};
391 gpu_fb->viewport_set(viewport_rect);
392}
393
395 const int viewport_rects[GPU_MAX_VIEWPORTS][4])
396{
397 gpu_fb->viewport_multi_set(viewport_rects);
398}
399
400void GPU_framebuffer_viewport_get(gpu::FrameBuffer *gpu_fb, int r_viewport[4])
401{
402 gpu_fb->viewport_get(r_viewport);
403}
404
409
410/* ---------- Frame-buffer Operations ----------- */
411
414 const float clear_col[4],
415 float clear_depth,
416 uint clear_stencil)
417{
419 "Using GPU_framebuffer_clear_* functions in conjunction with custom load-store "
420 "state via GPU_framebuffer_bind_ex is invalid.");
421 gpu_fb->clear(buffers, clear_col, clear_depth, clear_stencil);
422}
423
424void GPU_framebuffer_clear_color(gpu::FrameBuffer *fb, const float clear_col[4])
425{
426 GPU_framebuffer_clear(fb, GPU_COLOR_BIT, clear_col, 0.0f, 0x00);
427}
428
430{
431 GPU_framebuffer_clear(fb, GPU_DEPTH_BIT, nullptr, clear_depth, 0x00);
432}
433
435 const float clear_col[4],
436 float clear_depth)
437{
438 GPU_framebuffer_clear(fb, GPU_COLOR_BIT | GPU_DEPTH_BIT, clear_col, clear_depth, 0x00);
439}
440
442{
443 GPU_framebuffer_clear(fb, GPU_STENCIL_BIT, nullptr, 0.0f, clear_stencil);
444}
445
447 float clear_depth,
448 uint clear_stencil)
449{
450 GPU_framebuffer_clear(fb, GPU_DEPTH_BIT | GPU_STENCIL_BIT, nullptr, clear_depth, clear_stencil);
451}
452
454 const float clear_col[4],
455 float clear_depth,
456 uint clear_stencil)
457{
459 fb, GPU_COLOR_BIT | GPU_DEPTH_BIT | GPU_STENCIL_BIT, clear_col, clear_depth, clear_stencil);
460}
461
462void GPU_framebuffer_multi_clear(gpu::FrameBuffer *fb, const float (*clear_colors)[4])
463{
464 BLI_assert_msg(fb->get_use_explicit_loadstore() == false,
465 "Using GPU_framebuffer_clear_* functions in conjunction with custom load-store "
466 "state via GPU_framebuffer_bind_ex is invalid.");
467 fb->clear_multi(clear_colors);
468}
469
470void GPU_clear_color(float red, float green, float blue, float alpha)
471{
472 BLI_assert_msg(Context::get()->active_fb->get_use_explicit_loadstore() == false,
473 "Using GPU_framebuffer_clear_* functions in conjunction with custom load-store "
474 "state via GPU_framebuffer_bind_ex is invalid.");
475 float clear_col[4] = {red, green, blue, alpha};
476 Context::get()->active_fb->clear(GPU_COLOR_BIT, clear_col, 0.0f, 0x0);
477}
478
479void GPU_clear_depth(float depth)
480{
481 BLI_assert_msg(Context::get()->active_fb->get_use_explicit_loadstore() == false,
482 "Using GPU_framebuffer_clear_* functions in conjunction with custom load-store "
483 "state via GPU_framebuffer_bind_ex is invalid.");
484 float clear_col[4] = {0};
485 Context::get()->active_fb->clear(GPU_DEPTH_BIT, clear_col, depth, 0x0);
486}
487
489 gpu::FrameBuffer *fb, int x, int y, int w, int h, eGPUDataFormat format, void *data)
490{
491 int rect[4] = {x, y, w, h};
492 fb->read(GPU_DEPTH_BIT, format, rect, 1, 1, data);
493}
494
496 int x,
497 int y,
498 int w,
499 int h,
500 int channels,
501 int slot,
503 void *data)
504{
505 int rect[4] = {x, y, w, h};
506 fb->read(GPU_COLOR_BIT, format, rect, channels, slot, data);
507}
508
510 int x, int y, int w, int h, int channels, eGPUDataFormat format, void *data)
511{
512 int rect[4] = {x, y, w, h};
513 Context::get()->front_left->read(GPU_COLOR_BIT, format, rect, channels, 0, data);
514}
515
516/* TODO(fclem): port as texture operation. */
518 int read_slot,
519 gpu::FrameBuffer *fb_write,
520 int write_slot,
521 GPUFrameBufferBits blit_buffers)
522{
523 BLI_assert(blit_buffers != 0);
524
525 FrameBuffer *prev_fb = Context::get()->active_fb;
526
527#ifndef NDEBUG
528 blender::gpu::Texture *read_tex, *write_tex;
529 if (blit_buffers & (GPU_DEPTH_BIT | GPU_STENCIL_BIT)) {
530 read_tex = fb_read->depth_tex();
531 write_tex = fb_write->depth_tex();
532 }
533 else {
534 read_tex = fb_read->color_tex(read_slot);
535 write_tex = fb_write->color_tex(write_slot);
536 }
537
538 if (blit_buffers & GPU_DEPTH_BIT) {
540 BLI_assert(GPU_texture_format(read_tex) == GPU_texture_format(write_tex));
541 }
542 if (blit_buffers & GPU_STENCIL_BIT) {
545 BLI_assert(GPU_texture_format(read_tex) == GPU_texture_format(write_tex));
546 }
547#endif
548
549 fb_read->blit_to(blit_buffers, read_slot, fb_write, write_slot, 0, 0);
550
551 /* FIXME(@fclem): sRGB is not saved. */
552 prev_fb->bind(true);
553}
554
555#ifndef GPU_NO_USE_PY_REFERENCES
557{
558 return fb->py_ref;
559}
560
562{
563 BLI_assert(py_ref == nullptr || fb->py_ref == nullptr);
564 fb->py_ref = py_ref;
565}
566#endif
567
569
570/* -------------------------------------------------------------------- */
575
576#define FRAMEBUFFER_STACK_DEPTH 16
577
578static struct {
581} FrameBufferStack = {{nullptr}};
582
589
596
601
602#undef FRAMEBUFFER_STACK_DEPTH
603
605
606/* -------------------------------------------------------------------- */
612
614 constexpr static int MAX_CTX_FB_LEN = 3;
615
616 struct {
619 } framebuffers[MAX_CTX_FB_LEN];
620
623};
624
629{
630 Context *ctx = Context::get();
631 BLI_assert(ctx);
632
633 for (auto &framebuffer : ofs->framebuffers) {
634 if (framebuffer.fb == nullptr) {
635 framebuffer.ctx = ctx;
636 GPU_framebuffer_ensure_config(&framebuffer.fb,
637 {
638 GPU_ATTACHMENT_TEXTURE(ofs->depth),
639 GPU_ATTACHMENT_TEXTURE(ofs->color),
640 });
641 }
642
643 if (framebuffer.ctx == ctx) {
644 return framebuffer.fb;
645 }
646 }
647
648 /* List is full, this should never happen or
649 * it might just slow things down if it happens
650 * regularly. In this case we just empty the list
651 * and start over. This is most likely never going
652 * to happen under normal usage. */
653 BLI_assert(0);
654 printf(
655 "Warning: GPUOffscreen used in more than 3 GPUContext. "
656 "This may create performance drop.\n");
657
658 for (auto &framebuffer : ofs->framebuffers) {
659 GPU_framebuffer_free(framebuffer.fb);
660 framebuffer.fb = nullptr;
661 }
662
663 return gpu_offscreen_fb_get(ofs);
664}
665
667 int height,
668 bool with_depth_buffer,
670 eGPUTextureUsage usage,
671 bool clear,
672 char err_out[256])
673{
675
676 /* Sometimes areas can have 0 height or width and this will
677 * create a 1D texture which we don't want. */
678 height = max_ii(1, height);
679 width = max_ii(1, width);
680
681 /* Always add GPU_TEXTURE_USAGE_ATTACHMENT for convenience. */
683
684 ofs->color = GPU_texture_create_2d("ofs_color", width, height, 1, format, usage, nullptr);
685
686 if (with_depth_buffer) {
687 /* Format view flag is needed by Workbench Volumes to read the stencil view. */
689 ofs->depth = GPU_texture_create_2d("ofs_depth",
690 width,
691 height,
692 1,
693 blender::gpu::TextureFormat::SFLOAT_32_DEPTH_UINT_8,
694 depth_usage,
695 nullptr);
696 }
697
698 if ((with_depth_buffer && !ofs->depth) || !ofs->color) {
699 const char error[] = "blender::gpu::Texture: Texture allocation failed.";
700 if (err_out) {
701 BLI_strncpy(err_out, error, 256);
702 }
703 else {
704 fprintf(stderr, "%s", error);
705 }
707 return nullptr;
708 }
709
711
712 /* check validity at the very end! */
713 if (!GPU_framebuffer_check_valid(fb, err_out)) {
715 return nullptr;
716 }
717
718 if (clear) {
719 float const clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
720 float clear_depth = 0.0f;
722 if (with_depth_buffer) {
723 GPU_framebuffer_clear_color_depth(fb, clear_color, clear_depth);
724 }
725 else {
726 GPU_framebuffer_clear_color(fb, clear_color);
727 }
728 }
729
731 return ofs;
732}
733
735{
736 for (auto &framebuffer : offscreen->framebuffers) {
737 if (framebuffer.fb) {
738 GPU_framebuffer_free(framebuffer.fb);
739 }
740 }
741 if (offscreen->color) {
742 GPU_texture_free(offscreen->color);
743 }
744 if (offscreen->depth) {
745 GPU_texture_free(offscreen->depth);
746 }
747
748 MEM_freeN(offscreen);
749}
750
751void GPU_offscreen_bind(GPUOffScreen *offscreen, bool save)
752{
753 if (save) {
756 }
757 gpu_offscreen_fb_get(offscreen)->bind(false);
758}
759
760void GPU_offscreen_unbind(GPUOffScreen * /*offscreen*/, bool restore)
761{
762 gpu::FrameBuffer *fb = nullptr;
763 if (restore) {
765 }
766
767 if (fb) {
769 }
770 else {
772 }
773}
774
776{
777 Context *ctx = Context::get();
778 FrameBuffer *ofs_fb = gpu_offscreen_fb_get(offscreen);
779 ofs_fb->blit_to(GPU_COLOR_BIT, 0, ctx->active_fb, 0, x, y);
780}
781
783 GPUOffScreen *offscreen, eGPUDataFormat format, int x, int y, int w, int h, void *r_data)
784{
786 BLI_assert(x >= 0 && y >= 0 && w > 0 && h > 0);
787 BLI_assert(x + w <= GPU_texture_width(offscreen->color));
788 BLI_assert(y + h <= GPU_texture_height(offscreen->color));
789
790 gpu::FrameBuffer *ofs_fb = gpu_offscreen_fb_get(offscreen);
791 GPU_framebuffer_read_color(ofs_fb, x, y, w, h, 4, 0, format, r_data);
792}
793
795{
797
798 const int w = GPU_texture_width(offscreen->color);
799 const int h = GPU_texture_height(offscreen->color);
800
801 GPU_offscreen_read_color_region(offscreen, format, 0, 0, w, h, r_data);
802}
803
805{
806 return GPU_texture_width(offscreen->color);
807}
808
810{
811 return GPU_texture_height(offscreen->color);
812}
813
815{
816 return offscreen->color;
817}
818
823
825 gpu::FrameBuffer **r_fb,
826 blender::gpu::Texture **r_color,
827 blender::gpu::Texture **r_depth)
828{
829 *r_fb = gpu_offscreen_fb_get(offscreen);
830 *r_color = offscreen->color;
831 *r_depth = offscreen->depth;
832}
833
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
MINLINE int max_ii(int a, int b)
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:693
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
unsigned int uint
#define ELEM(...)
@ GPU_LOADACTION_DONT_CARE
@ GPU_STOREACTION_DONT_CARE
GPUAttachmentState
@ GPU_ATTACHMENT_WRITE
@ GPU_ATTACHMENT_READ
@ GPU_ATTACHMENT_IGNORE
blender::gpu::FrameBuffer * GPU_framebuffer_create(const char *name)
void GPU_framebuffer_subpass_transition_array(blender::gpu::FrameBuffer *fb, const GPUAttachmentState *attachment_states, uint attachment_len)
blender::gpu::Texture * GPU_offscreen_color_texture(const GPUOffScreen *offscreen)
void GPU_framebuffer_default_size(blender::gpu::FrameBuffer *fb, int width, int height)
void GPU_framebuffer_texture_detach(blender::gpu::FrameBuffer *fb, blender::gpu::Texture *texture)
void GPU_offscreen_draw_to_screen(GPUOffScreen *offscreen, int x, int y)
GPUFrameBufferBits
@ GPU_DEPTH_BIT
@ GPU_STENCIL_BIT
@ GPU_COLOR_BIT
void GPU_framebuffer_viewport_reset(blender::gpu::FrameBuffer *fb)
void GPU_framebuffer_clear_stencil(blender::gpu::FrameBuffer *fb, uint clear_stencil)
int GPU_offscreen_width(const GPUOffScreen *offscreen)
void GPU_offscreen_bind(GPUOffScreen *offscreen, bool save)
void GPU_framebuffer_restore()
GPUBackBuffer
@ GPU_BACKBUFFER_LEFT
void GPU_backbuffer_bind(GPUBackBuffer back_buffer_type)
void GPU_framebuffer_bind_loadstore(blender::gpu::FrameBuffer *fb, const GPULoadStore *load_store_actions, uint load_store_actions_len)
void GPU_framebuffer_clear_depth_stencil(blender::gpu::FrameBuffer *fb, float clear_depth, uint clear_stencil)
blender::gpu::FrameBuffer * GPU_framebuffer_back_get()
void GPU_framebuffer_read_color(blender::gpu::FrameBuffer *fb, int x, int y, int width, int height, int channels, int slot, eGPUDataFormat data_format, void *r_data)
blender::gpu::TextureFormat GPU_offscreen_format(const GPUOffScreen *offscreen)
void GPU_framebuffer_multi_clear(blender::gpu::FrameBuffer *fb, const float(*clear_colors)[4])
static constexpr int GPU_MAX_VIEWPORTS
void ** GPU_framebuffer_py_reference_get(blender::gpu::FrameBuffer *fb)
void GPU_framebuffer_py_reference_set(blender::gpu::FrameBuffer *fb, void **py_ref)
void GPU_frontbuffer_read_color(int x, int y, int width, int height, int channels, eGPUDataFormat data_format, void *r_data)
#define GPU_ATTACHMENT_NONE
void GPU_framebuffer_free(blender::gpu::FrameBuffer *fb)
uint GPU_framebuffer_stack_level_get()
void GPU_framebuffer_texture_layer_attach(blender::gpu::FrameBuffer *fb, blender::gpu::Texture *texture, int slot, int layer, int mip)
void GPU_framebuffer_texture_attach(blender::gpu::FrameBuffer *fb, blender::gpu::Texture *texture, int slot, int mip)
void GPU_framebuffer_viewport_set(blender::gpu::FrameBuffer *fb, int x, int y, int width, int height)
#define GPU_ATTACHMENT_TEXTURE_MIP(_texture, _mip)
int GPU_offscreen_height(const GPUOffScreen *offscreen)
blender::gpu::FrameBuffer * GPU_framebuffer_pop()
GPUOffScreen * GPU_offscreen_create(int width, int height, bool with_depth_buffer, blender::gpu::TextureFormat format, eGPUTextureUsage usage, bool clear, char err_out[256])
void GPU_clear_color(float red, float green, float blue, float alpha)
bool GPU_framebuffer_check_valid(blender::gpu::FrameBuffer *fb, char err_out[256])
void GPU_framebuffer_blit(blender::gpu::FrameBuffer *fb_read, int read_slot, blender::gpu::FrameBuffer *fb_write, int write_slot, GPUFrameBufferBits blit_buffers)
void GPU_offscreen_read_color_region(GPUOffScreen *offscreen, eGPUDataFormat data_format, int x, int y, int w, int h, void *r_data)
void GPU_offscreen_free(GPUOffScreen *offscreen)
void GPU_offscreen_viewport_data_get(GPUOffScreen *offscreen, blender::gpu::FrameBuffer **r_fb, blender::gpu::Texture **r_color, blender::gpu::Texture **r_depth)
const char * GPU_framebuffer_get_name(blender::gpu::FrameBuffer *fb)
void GPU_framebuffer_bind_no_srgb(blender::gpu::FrameBuffer *fb)
void GPU_framebuffer_clear_depth(blender::gpu::FrameBuffer *fb, float clear_depth)
void GPU_framebuffer_clear_color_depth_stencil(blender::gpu::FrameBuffer *fb, const float clear_col[4], float clear_depth, uint clear_stencil)
void GPU_clear_depth(float depth)
bool GPU_framebuffer_bound(blender::gpu::FrameBuffer *fb)
void GPU_framebuffer_clear_color(blender::gpu::FrameBuffer *fb, const float clear_col[4])
void GPU_framebuffer_read_depth(blender::gpu::FrameBuffer *fb, int x, int y, int width, int height, eGPUDataFormat data_format, void *r_data)
#define GPU_framebuffer_ensure_config(_fb,...)
void GPU_framebuffer_push(blender::gpu::FrameBuffer *fb)
void GPU_framebuffer_config_array(blender::gpu::FrameBuffer *fb, const GPUAttachment *config, int config_len)
void GPU_offscreen_read_color(GPUOffScreen *offscreen, eGPUDataFormat data_format, void *r_data)
#define GPU_ATTACHMENT_TEXTURE_LAYER_MIP(_texture, _layer, _mip)
void GPU_framebuffer_multi_viewports_set(blender::gpu::FrameBuffer *gpu_fb, const int viewport_rects[GPU_MAX_VIEWPORTS][4])
void GPU_framebuffer_texture_cubeface_attach(blender::gpu::FrameBuffer *fb, blender::gpu::Texture *texture, int slot, int face, int mip)
void GPU_framebuffer_clear_color_depth(blender::gpu::FrameBuffer *fb, const float clear_col[4], float clear_depth)
void GPU_framebuffer_clear(blender::gpu::FrameBuffer *fb, GPUFrameBufferBits buffers, const float clear_col[4], float clear_depth, unsigned int clear_stencil)
void GPU_framebuffer_bind(blender::gpu::FrameBuffer *fb)
void GPU_offscreen_unbind(GPUOffScreen *offscreen, bool restore)
#define GPU_ATTACHMENT_TEXTURE_CUBEFACE_MIP(_texture, _face, _mip)
void GPU_framebuffer_viewport_get(blender::gpu::FrameBuffer *fb, int r_viewport[4])
blender::gpu::FrameBuffer * GPU_framebuffer_active_get()
int GPU_texture_height(const blender::gpu::Texture *texture)
bool GPU_texture_has_depth_format(const blender::gpu::Texture *texture)
blender::gpu::TextureFormat GPU_texture_format(const blender::gpu::Texture *texture)
bool GPU_texture_has_stencil_format(const blender::gpu::Texture *texture)
int GPU_texture_width(const blender::gpu::Texture *texture)
eGPUDataFormat
@ GPU_DATA_UBYTE
@ GPU_DATA_FLOAT
eGPUTextureUsage
@ GPU_TEXTURE_USAGE_ATTACHMENT
@ GPU_TEXTURE_USAGE_FORMAT_VIEW
bool GPU_texture_is_cube(const blender::gpu::Texture *texture)
blender::gpu::Texture * GPU_texture_create_2d(const char *name, int width, int height, int mip_len, blender::gpu::TextureFormat format, eGPUTextureUsage usage, const float *data)
void GPU_texture_free(blender::gpu::Texture *texture)
bool GPU_texture_is_array(const blender::gpu::Texture *texture)
Read Guarded memory(de)allocation.
BMesh const char void * data
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
constexpr int64_t size() const
Definition BLI_span.hh:252
static Context * get()
void attachment_remove(GPUAttachmentType type)
virtual void subpass_transition_impl(const GPUAttachmentState depth_attachment_state, Span< GPUAttachmentState > color_attachment_states)=0
virtual void clear(GPUFrameBufferBits buffers, const float clear_col[4], float clear_depth, uint clear_stencil)=0
virtual void read(GPUFrameBufferBits planes, eGPUDataFormat format, const int area[4], int channel_len, int slot, void *r_data)=0
virtual void attachment_set_loadstore_op(GPUAttachmentType type, GPULoadStore ls)=0
void viewport_set(const int viewport[4])
void set_color_attachment_bit(GPUAttachmentType type, bool value)
virtual void bind(bool enabled_srgb)=0
void default_size_set(int width, int height)
blender::gpu::Texture * depth_tex() const
blender::gpu::Texture * color_tex(int slot) const
void subpass_transition(const GPUAttachmentState depth_attachment_state, Span< GPUAttachmentState > color_attachment_states)
FrameBuffer(const char *name)
virtual bool check(char err_out[256])=0
virtual void blit_to(GPUFrameBufferBits planes, int src_slot, FrameBuffer *dst, int dst_slot, int dst_offset_x, int dst_offset_y)=0
void viewport_multi_set(const int viewports[GPU_MAX_VIEWPORTS][4])
void viewport_get(int r_viewport[4]) const
GPUAttachment attachments_[GPU_FB_MAX_ATTACHMENT]
void load_store_config_array(const GPULoadStore *load_store_actions, uint actions_len)
void attachment_set(GPUAttachmentType type, const GPUAttachment &new_attachment)
static GPUBackend * get()
virtual FrameBuffer * framebuffer_alloc(const char *name)=0
GPUAttachmentType attachment_type(int slot) const
TextureFormat format_get() const
void detach_from(FrameBuffer *fb)
#define FRAMEBUFFER_STACK_DEPTH
static void gpu_framebuffer_texture_attach_ex(gpu::FrameBuffer *gpu_fb, GPUAttachment attachment, int slot)
gpu::FrameBuffer * framebuffers[FRAMEBUFFER_STACK_DEPTH]
uint top
static gpu::FrameBuffer * gpu_offscreen_fb_get(GPUOffScreen *ofs)
static struct @141033310223244255046200227055353175217006175233 FrameBufferStack
@ GPU_FB_DEPTH_STENCIL_ATTACHMENT
@ GPU_FB_MAX_ATTACHMENT
@ GPU_FB_COLOR_ATTACHMENT0
@ GPU_FB_DEPTH_ATTACHMENT
#define GPU_FB_MAX_COLOR_ATTACHMENT
#define printf(...)
BLI_INLINE float fb(float length, float L)
format
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
static void error(const char *str)
static void clear(Message &msg)
Definition msgfmt.cc:213
int to_bytesize(const DataFormat format)
int to_component_len(TextureFormat format)
const char * name
blender::gpu::Texture * tex
GPUStoreOp store_action
GPULoadOp load_action
static constexpr int MAX_CTX_FB_LEN
blender::gpu::Texture * color
gpu::FrameBuffer * fb
struct GPUOffScreen::@167257126263316171025200246244026236355107071163 framebuffers[MAX_CTX_FB_LEN]
blender::gpu::Texture * depth
i
Definition text_draw.cc:230
char * buffers[2]