Blender  V2.93
gpu_framebuffer.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2005 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "MEM_guardedalloc.h"
25 
26 #include "BLI_blenlib.h"
27 #include "BLI_math_base.h"
28 #include "BLI_utildefines.h"
29 
30 #include "GPU_batch.h"
31 #include "GPU_capabilities.h"
32 #include "GPU_shader.h"
33 #include "GPU_texture.h"
34 
35 #include "gpu_backend.hh"
36 #include "gpu_context_private.hh"
37 #include "gpu_private.h"
38 #include "gpu_texture_private.hh"
39 
41 
42 namespace blender::gpu {
43 
44 /* -------------------------------------------------------------------- */
48 FrameBuffer::FrameBuffer(const char *name)
49 {
50  if (name) {
51  BLI_strncpy(name_, name, sizeof(name_));
52  }
53  else {
54  name_[0] = '\0';
55  }
56  /* Force config on first use. */
57  dirty_attachments_ = true;
58  dirty_state_ = true;
59 
60  for (GPUAttachment &attachment : attachments_) {
61  attachment.tex = nullptr;
62  attachment.mip = -1;
63  attachment.layer = -1;
64  }
65 }
66 
68 {
69  for (GPUAttachment &attachment : attachments_) {
70  if (attachment.tex != nullptr) {
71  reinterpret_cast<Texture *>(attachment.tex)->detach_from(this);
72  }
73  }
74 }
75 
78 /* -------------------------------------------------------------------- */
83 {
84  if (new_attachment.mip == -1) {
85  return; /* GPU_ATTACHMENT_LEAVE */
86  }
87 
88  if (type >= GPU_FB_MAX_ATTACHMENT) {
89  fprintf(stderr,
90  "GPUFramebuffer: Error: Trying to attach texture to type %d but maximum slot is %d.\n",
93  return;
94  }
95 
96  if (new_attachment.tex) {
97  if (new_attachment.layer > 0) {
98  BLI_assert(GPU_texture_cube(new_attachment.tex) || GPU_texture_array(new_attachment.tex));
99  }
100  if (GPU_texture_stencil(new_attachment.tex)) {
102  }
103  else if (GPU_texture_depth(new_attachment.tex)) {
105  }
106  }
107 
108  GPUAttachment &attachment = attachments_[type];
109 
110  if (attachment.tex == new_attachment.tex && attachment.layer == new_attachment.layer &&
111  attachment.mip == new_attachment.mip) {
112  return; /* Exact same texture already bound here. */
113  }
114  /* Unbind previous and bind new. */
115  /* TODO(fclem): cleanup the casts. */
116  if (attachment.tex) {
117  reinterpret_cast<Texture *>(attachment.tex)->detach_from(this);
118  }
119 
120  attachment = new_attachment;
121 
122  /* Might be null if this is for unbinding. */
123  if (attachment.tex) {
124  reinterpret_cast<Texture *>(attachment.tex)->attach_to(this, type);
125  }
126  else {
127  /* GPU_ATTACHMENT_NONE */
128  }
129 
130  dirty_attachments_ = true;
131 }
132 
134 {
135  attachments_[type] = GPU_ATTACHMENT_NONE;
136  dirty_attachments_ = true;
137 }
138 
140  void (*callback)(void *userData, int level),
141  void *userData)
142 {
143  /* Bind to make sure the frame-buffer is up to date. */
144  this->bind(true);
145 
146  /* FIXME(fclem): This assumes all mips are defined which may not be the case. */
147  max_lvl = min_ii(max_lvl, floor(log2(max_ii(width_, height_))));
148 
149  for (int mip_lvl = 1; mip_lvl <= max_lvl; mip_lvl++) {
150  /* Replace attached mip-level for each attachment. */
151  for (GPUAttachment &attachment : attachments_) {
152  Texture *tex = reinterpret_cast<Texture *>(attachment.tex);
153  if (tex != nullptr) {
154  /* Some Intel HDXXX have issue with rendering to a mipmap that is below
155  * the texture GL_TEXTURE_MAX_LEVEL. So even if it not correct, in this case
156  * we allow GL_TEXTURE_MAX_LEVEL to be one level lower. In practice it does work! */
157  int mip_max = (GPU_mip_render_workaround()) ? mip_lvl : (mip_lvl - 1);
158  /* Restrict fetches only to previous level. */
159  tex->mip_range_set(mip_lvl - 1, mip_max);
160  /* Bind next level. */
161  attachment.mip = mip_lvl;
162  }
163  }
164  /* Update the internal attachments and viewport size. */
165  dirty_attachments_ = true;
166  this->bind(true);
167 
168  callback(userData, mip_lvl);
169  }
170 
171  for (GPUAttachment &attachment : attachments_) {
172  if (attachment.tex != nullptr) {
173  /* Reset mipmap level range. */
174  reinterpret_cast<Texture *>(attachment.tex)->mip_range_set(0, max_lvl);
175  /* Reset base level. NOTE: might not be the one bound at the start of this function. */
176  attachment.mip = 0;
177  }
178  }
179  dirty_attachments_ = true;
180 }
181 
184 } // namespace blender::gpu
185 
186 /* -------------------------------------------------------------------- */
190 using namespace blender;
191 using namespace blender::gpu;
192 
194 {
195  /* We generate the FB object later at first use in order to
196  * create the frame-buffer in the right opengl context. */
197  return wrap(GPUBackend::get()->framebuffer_alloc(name));
198 }
199 
201 {
202  delete unwrap(gpu_fb);
203 }
204 
205 /* ---------- Binding ----------- */
206 
208 {
209  const bool enable_srgb = true;
210  unwrap(gpu_fb)->bind(enable_srgb);
211 }
212 
217 {
218  const bool enable_srgb = false;
219  unwrap(gpu_fb)->bind(enable_srgb);
220 }
221 
226 {
227  Context *ctx = Context::get();
228 
229  if (buffer == GPU_BACKBUFFER_LEFT) {
230  ctx->back_left->bind(false);
231  }
232  else {
233  ctx->back_right->bind(false);
234  }
235 }
236 
238 {
239  Context::get()->back_left->bind(false);
240 }
241 
243 {
244  Context *ctx = Context::get();
245  return wrap(ctx ? ctx->active_fb : nullptr);
246 }
247 
248 /* Returns the default frame-buffer. Will always exists even if it's just a dummy. */
250 {
251  Context *ctx = Context::get();
252  return wrap(ctx ? ctx->back_left : nullptr);
253 }
254 
256 {
257  return (gpu_fb == GPU_framebuffer_active_get());
258 }
259 
260 /* ---------- Attachment Management ----------- */
261 
262 bool GPU_framebuffer_check_valid(GPUFrameBuffer *gpu_fb, char err_out[256])
263 {
264  return unwrap(gpu_fb)->check(err_out);
265 }
266 
268 {
269  Texture *tex = reinterpret_cast<Texture *>(attachment.tex);
270  GPUAttachmentType type = tex->attachment_type(slot);
271  unwrap(gpu_fb)->attachment_set(type, attachment);
272 }
273 
275 {
276  GPUAttachment attachment = GPU_ATTACHMENT_TEXTURE_MIP(tex, mip);
277  GPU_framebuffer_texture_attach_ex(fb, attachment, slot);
278 }
279 
281  GPUFrameBuffer *fb, GPUTexture *tex, int slot, int layer, int mip)
282 {
283  GPUAttachment attachment = GPU_ATTACHMENT_TEXTURE_LAYER_MIP(tex, layer, mip);
284  GPU_framebuffer_texture_attach_ex(fb, attachment, slot);
285 }
286 
288  GPUFrameBuffer *fb, GPUTexture *tex, int slot, int face, int mip)
289 {
290  GPUAttachment attachment = GPU_ATTACHMENT_TEXTURE_CUBEFACE_MIP(tex, face, mip);
291  GPU_framebuffer_texture_attach_ex(fb, attachment, slot);
292 }
293 
295 {
296  unwrap(tex)->detach_from(unwrap(fb));
297 }
298 
306  const GPUAttachment *config,
307  int config_len)
308 {
309  FrameBuffer *fb = unwrap(gpu_fb);
310 
311  const GPUAttachment &depth_attachment = config[0];
312  Span<GPUAttachment> color_attachments(config + 1, config_len - 1);
313 
314  if (depth_attachment.mip == -1) {
315  /* GPU_ATTACHMENT_LEAVE */
316  }
317  else if (depth_attachment.tex == nullptr) {
318  /* GPU_ATTACHMENT_NONE: Need to clear both targets. */
319  fb->attachment_set(GPU_FB_DEPTH_STENCIL_ATTACHMENT, depth_attachment);
320  fb->attachment_set(GPU_FB_DEPTH_ATTACHMENT, depth_attachment);
321  }
322  else {
323  GPUAttachmentType type = GPU_texture_stencil(depth_attachment.tex) ?
326  fb->attachment_set(type, depth_attachment);
327  }
328 
330  for (const GPUAttachment &attachment : color_attachments) {
331  fb->attachment_set(type, attachment);
332  ++type;
333  }
334 }
335 
336 /* ---------- Viewport & Scissor Region ----------- */
337 
343 void GPU_framebuffer_viewport_set(GPUFrameBuffer *gpu_fb, int x, int y, int width, int height)
344 {
345  int viewport_rect[4] = {x, y, width, height};
346  unwrap(gpu_fb)->viewport_set(viewport_rect);
347 }
348 
349 void GPU_framebuffer_viewport_get(GPUFrameBuffer *gpu_fb, int r_viewport[4])
350 {
351  unwrap(gpu_fb)->viewport_get(r_viewport);
352 }
353 
358 {
359  unwrap(gpu_fb)->viewport_reset();
360 }
361 
362 /* ---------- Frame-buffer Operations ----------- */
363 
365  eGPUFrameBufferBits buffers,
366  const float clear_col[4],
367  float clear_depth,
368  uint clear_stencil)
369 {
370  unwrap(gpu_fb)->clear(buffers, clear_col, clear_depth, clear_stencil);
371 }
372 
376 void GPU_framebuffer_multi_clear(GPUFrameBuffer *gpu_fb, const float (*clear_cols)[4])
377 {
378  unwrap(gpu_fb)->clear_multi(clear_cols);
379 }
380 
381 void GPU_clear_color(float red, float green, float blue, float alpha)
382 {
383  float clear_col[4] = {red, green, blue, alpha};
384  Context::get()->active_fb->clear(GPU_COLOR_BIT, clear_col, 0.0f, 0x0);
385 }
386 
387 void GPU_clear_depth(float depth)
388 {
389  float clear_col[4] = {0};
390  Context::get()->active_fb->clear(GPU_DEPTH_BIT, clear_col, depth, 0x0);
391 }
392 
394  GPUFrameBuffer *gpu_fb, int x, int y, int w, int h, eGPUDataFormat format, void *data)
395 {
396  int rect[4] = {x, y, w, h};
397  unwrap(gpu_fb)->read(GPU_DEPTH_BIT, format, rect, 1, 1, data);
398 }
399 
401  int x,
402  int y,
403  int w,
404  int h,
405  int channels,
406  int slot,
408  void *data)
409 {
410  int rect[4] = {x, y, w, h};
411  unwrap(gpu_fb)->read(GPU_COLOR_BIT, format, rect, channels, slot, data);
412 }
413 
414 /* TODO(fclem): rename to read_color. */
416  int x, int y, int w, int h, int channels, eGPUDataFormat format, void *data)
417 {
418  int rect[4] = {x, y, w, h};
419  Context::get()->front_left->read(GPU_COLOR_BIT, format, rect, channels, 0, data);
420 }
421 
422 /* read_slot and write_slot are only used for color buffers. */
423 /* TODO(fclem): port as texture operation. */
425  int read_slot,
426  GPUFrameBuffer *gpufb_write,
427  int write_slot,
428  eGPUFrameBufferBits blit_buffers)
429 {
430  FrameBuffer *fb_read = unwrap(gpufb_read);
431  FrameBuffer *fb_write = unwrap(gpufb_write);
432  BLI_assert(blit_buffers != 0);
433 
434  FrameBuffer *prev_fb = Context::get()->active_fb;
435 
436 #ifndef NDEBUG
437  GPUTexture *read_tex, *write_tex;
438  if (blit_buffers & (GPU_DEPTH_BIT | GPU_STENCIL_BIT)) {
439  read_tex = fb_read->depth_tex();
440  write_tex = fb_write->depth_tex();
441  }
442  else {
443  read_tex = fb_read->color_tex(read_slot);
444  write_tex = fb_write->color_tex(write_slot);
445  }
446 
447  if (blit_buffers & GPU_DEPTH_BIT) {
448  BLI_assert(GPU_texture_depth(read_tex) && GPU_texture_depth(write_tex));
449  BLI_assert(GPU_texture_format(read_tex) == GPU_texture_format(write_tex));
450  }
451  if (blit_buffers & GPU_STENCIL_BIT) {
452  BLI_assert(GPU_texture_stencil(read_tex) && GPU_texture_stencil(write_tex));
453  BLI_assert(GPU_texture_format(read_tex) == GPU_texture_format(write_tex));
454  }
455 #endif
456 
457  fb_read->blit_to(blit_buffers, read_slot, fb_write, write_slot, 0, 0);
458 
459  /* FIXME(fclem) sRGB is not saved. */
460  prev_fb->bind(true);
461 }
462 
469  int max_lvl,
470  void (*callback)(void *userData, int level),
471  void *userData)
472 {
473  unwrap(gpu_fb)->recursive_downsample(max_lvl, callback, userData);
474 }
475 
478 /* -------------------------------------------------------------------- */
484 #define FRAMEBUFFER_STACK_DEPTH 16
485 
486 static struct {
489 } FrameBufferStack = {{nullptr}};
490 
492 {
494  FrameBufferStack.framebuffers[FrameBufferStack.top] = fb;
495  FrameBufferStack.top++;
496 }
497 
499 {
500  BLI_assert(FrameBufferStack.top > 0);
501  FrameBufferStack.top--;
502  return FrameBufferStack.framebuffers[FrameBufferStack.top];
503 }
504 
506 {
507  return FrameBufferStack.top;
508 }
509 
510 #undef FRAMEBUFFER_STACK_DEPTH
511 
514 /* -------------------------------------------------------------------- */
521 #define MAX_CTX_FB_LEN 3
522 
523 struct GPUOffScreen {
524  struct {
528 
531 };
532 
537 {
538  Context *ctx = Context::get();
539  BLI_assert(ctx);
540 
541  for (auto &framebuffer : ofs->framebuffers) {
542  if (framebuffer.fb == nullptr) {
543  framebuffer.ctx = ctx;
544  GPU_framebuffer_ensure_config(&framebuffer.fb,
545  {
546  GPU_ATTACHMENT_TEXTURE(ofs->depth),
547  GPU_ATTACHMENT_TEXTURE(ofs->color),
548  });
549  }
550 
551  if (framebuffer.ctx == ctx) {
552  return framebuffer.fb;
553  }
554  }
555 
556  /* List is full, this should never happen or
557  * it might just slow things down if it happens
558  * regularly. In this case we just empty the list
559  * and start over. This is most likely never going
560  * to happen under normal usage. */
561  BLI_assert(0);
562  printf(
563  "Warning: GPUOffscreen used in more than 3 GPUContext. "
564  "This may create performance drop.\n");
565 
566  for (auto &framebuffer : ofs->framebuffers) {
567  GPU_framebuffer_free(framebuffer.fb);
568  framebuffer.fb = nullptr;
569  }
570 
571  return gpu_offscreen_fb_get(ofs);
572 }
573 
575  int width, int height, bool depth, bool high_bitdepth, char err_out[256])
576 {
577  GPUOffScreen *ofs = (GPUOffScreen *)MEM_callocN(sizeof(GPUOffScreen), __func__);
578 
579  /* Sometimes areas can have 0 height or width and this will
580  * create a 1D texture which we don't want. */
581  height = max_ii(1, height);
582  width = max_ii(1, width);
583 
585  "ofs_color", width, height, 1, (high_bitdepth) ? GPU_RGBA16F : GPU_RGBA8, nullptr);
586 
587  if (depth) {
589  "ofs_depth", width, height, 1, GPU_DEPTH24_STENCIL8, nullptr);
590  }
591 
592  if ((depth && !ofs->depth) || !ofs->color) {
593  BLI_snprintf(err_out, 256, "GPUTexture: Texture allocation failed.");
594  GPU_offscreen_free(ofs);
595  return nullptr;
596  }
597 
599 
600  /* check validity at the very end! */
601  if (!GPU_framebuffer_check_valid(fb, err_out)) {
602  GPU_offscreen_free(ofs);
603  return nullptr;
604  }
606  return ofs;
607 }
608 
610 {
611  for (auto &framebuffer : ofs->framebuffers) {
612  if (framebuffer.fb) {
613  GPU_framebuffer_free(framebuffer.fb);
614  }
615  }
616  if (ofs->color) {
617  GPU_texture_free(ofs->color);
618  }
619  if (ofs->depth) {
620  GPU_texture_free(ofs->depth);
621  }
622 
623  MEM_freeN(ofs);
624 }
625 
627 {
628  if (save) {
631  }
632  unwrap(gpu_offscreen_fb_get(ofs))->bind(false);
633 }
634 
635 void GPU_offscreen_unbind(GPUOffScreen *UNUSED(ofs), bool restore)
636 {
637  GPUFrameBuffer *fb = nullptr;
638  if (restore) {
640  }
641 
642  if (fb) {
644  }
645  else {
647  }
648 }
649 
651 {
652  Context *ctx = Context::get();
653  FrameBuffer *ofs_fb = unwrap(gpu_offscreen_fb_get(ofs));
654  ofs_fb->blit_to(GPU_COLOR_BIT, 0, ctx->active_fb, 0, x, y);
655 }
656 
658 {
660 
661  const int w = GPU_texture_width(ofs->color);
662  const int h = GPU_texture_height(ofs->color);
663 
664  GPUFrameBuffer *ofs_fb = gpu_offscreen_fb_get(ofs);
665  GPU_framebuffer_read_color(ofs_fb, 0, 0, w, h, 4, 0, format, pixels);
666 }
667 
669 {
670  return GPU_texture_width(ofs->color);
671 }
672 
674 {
675  return GPU_texture_height(ofs->color);
676 }
677 
679 {
680  return ofs->color;
681 }
682 
687  GPUFrameBuffer **r_fb,
688  GPUTexture **r_color,
689  GPUTexture **r_depth)
690 {
691  *r_fb = gpu_offscreen_fb_get(ofs);
692  *r_color = ofs->color;
693  *r_depth = ofs->depth;
694 }
695 
#define BLI_assert(a)
Definition: BLI_assert.h:58
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNUSED(x)
#define ELEM(...)
bool GPU_mip_render_workaround(void)
struct GPUFrameBuffer GPUFrameBuffer
eGPUFrameBufferBits
@ GPU_DEPTH_BIT
@ GPU_STENCIL_BIT
@ GPU_COLOR_BIT
eGPUBackBuffer
@ GPU_BACKBUFFER_LEFT
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte blue
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble green
bool GPU_texture_cube(const GPUTexture *tex)
Definition: gpu_texture.cc:574
int GPU_texture_height(const GPUTexture *tex)
Definition: gpu_texture.cc:532
struct GPUTexture GPUTexture
Definition: GPU_texture.h:33
int GPU_texture_width(const GPUTexture *tex)
Definition: gpu_texture.cc:527
eGPUDataFormat
Definition: GPU_texture.h:171
@ GPU_DATA_UBYTE
Definition: GPU_texture.h:175
@ GPU_DATA_FLOAT
Definition: GPU_texture.h:172
bool GPU_texture_array(const GPUTexture *tex)
Definition: gpu_texture.cc:579
void GPU_texture_free(GPUTexture *tex)
Definition: gpu_texture.cc:508
GPUTexture * GPU_texture_create_2d(const char *name, int w, int h, int mip_len, eGPUTextureFormat format, const float *data)
Definition: gpu_texture.cc:250
@ GPU_DEPTH24_STENCIL8
Definition: GPU_texture.h:121
@ GPU_RGBA16F
Definition: GPU_texture.h:94
@ GPU_RGBA8
Definition: GPU_texture.h:88
bool GPU_texture_stencil(const GPUTexture *tex)
Definition: gpu_texture.cc:564
eGPUTextureFormat GPU_texture_format(const GPUTexture *tex)
Definition: gpu_texture.cc:554
bool GPU_texture_depth(const GPUTexture *tex)
Definition: gpu_texture.cc:559
Read Guarded memory(de)allocation.
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
static Context * get(void)
Definition: gpu_context.cc:88
void attachment_remove(GPUAttachmentType type)
GPUTexture * depth_tex(void) const
virtual void read(eGPUFrameBufferBits planes, eGPUDataFormat format, const int area[4], int channel_len, int slot, void *r_data)=0
virtual void bind(bool enabled_srgb)=0
FrameBuffer(const char *name)
GPUTexture * color_tex(int slot) const
virtual void clear(eGPUFrameBufferBits buffers, const float clear_col[4], float clear_depth, uint clear_stencil)=0
void recursive_downsample(int max_lvl, void(*callback)(void *userData, int level), void *userData)
GPUAttachment attachments_[GPU_FB_MAX_ATTACHMENT]
virtual void blit_to(eGPUFrameBufferBits planes, int src_slot, FrameBuffer *dst, int dst_slot, int dst_offset_x, int dst_offset_y)=0
void attachment_set(GPUAttachmentType type, const GPUAttachment &new_attachment)
static GPUBackend * get(void)
Definition: gpu_context.cc:191
DEGForeachIDComponentCallback callback
static CCL_NAMESPACE_BEGIN const double alpha
#define FRAMEBUFFER_STACK_DEPTH
GPUFrameBuffer * GPU_framebuffer_back_get(void)
#define MAX_CTX_FB_LEN
void GPU_framebuffer_clear(GPUFrameBuffer *gpu_fb, eGPUFrameBufferBits buffers, const float clear_col[4], float clear_depth, uint clear_stencil)
static GPUFrameBuffer * gpu_offscreen_fb_get(GPUOffScreen *ofs)
void GPU_framebuffer_bind(GPUFrameBuffer *gpu_fb)
void GPU_framebuffer_texture_attach_ex(GPUFrameBuffer *gpu_fb, GPUAttachment attachment, int slot)
uint GPU_framebuffer_stack_level_get(void)
void GPU_framebuffer_texture_layer_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, int layer, int mip)
void GPU_framebuffer_config_array(GPUFrameBuffer *gpu_fb, const GPUAttachment *config, int config_len)
void GPU_framebuffer_bind_no_srgb(GPUFrameBuffer *gpu_fb)
void GPU_framebuffer_multi_clear(GPUFrameBuffer *gpu_fb, const float(*clear_cols)[4])
void GPU_framebuffer_texture_cubeface_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, int face, int mip)
void GPU_framebuffer_restore(void)
void GPU_framebuffer_free(GPUFrameBuffer *gpu_fb)
void GPU_offscreen_free(GPUOffScreen *ofs)
static struct @619 FrameBufferStack
GPUFrameBuffer * GPU_framebuffer_pop(void)
void GPU_framebuffer_read_color(GPUFrameBuffer *gpu_fb, int x, int y, int w, int h, int channels, int slot, eGPUDataFormat format, void *data)
void GPU_offscreen_unbind(GPUOffScreen *UNUSED(ofs), bool restore)
GPUFrameBuffer * GPU_framebuffer_active_get(void)
GPUFrameBuffer * framebuffers[FRAMEBUFFER_STACK_DEPTH]
void GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, int mip)
void GPU_offscreen_read_pixels(GPUOffScreen *ofs, eGPUDataFormat format, void *pixels)
bool GPU_framebuffer_bound(GPUFrameBuffer *gpu_fb)
void GPU_framebuffer_viewport_get(GPUFrameBuffer *gpu_fb, int r_viewport[4])
void GPU_framebuffer_recursive_downsample(GPUFrameBuffer *gpu_fb, int max_lvl, void(*callback)(void *userData, int level), void *userData)
void GPU_backbuffer_bind(eGPUBackBuffer buffer)
void GPU_clear_color(float red, float green, float blue, float alpha)
GPUOffScreen * GPU_offscreen_create(int width, int height, bool depth, bool high_bitdepth, char err_out[256])
bool GPU_framebuffer_check_valid(GPUFrameBuffer *gpu_fb, char err_out[256])
void GPU_offscreen_viewport_data_get(GPUOffScreen *ofs, GPUFrameBuffer **r_fb, GPUTexture **r_color, GPUTexture **r_depth)
void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex)
void GPU_offscreen_draw_to_screen(GPUOffScreen *ofs, int x, int y)
void GPU_frontbuffer_read_pixels(int x, int y, int w, int h, int channels, eGPUDataFormat format, void *data)
void GPU_framebuffer_push(GPUFrameBuffer *fb)
int GPU_offscreen_width(const GPUOffScreen *ofs)
void GPU_framebuffer_viewport_reset(GPUFrameBuffer *gpu_fb)
void GPU_framebuffer_blit(GPUFrameBuffer *gpufb_read, int read_slot, GPUFrameBuffer *gpufb_write, int write_slot, eGPUFrameBufferBits blit_buffers)
void GPU_clear_depth(float depth)
void GPU_offscreen_bind(GPUOffScreen *ofs, bool save)
GPUTexture * GPU_offscreen_color_texture(const GPUOffScreen *ofs)
void GPU_framebuffer_viewport_set(GPUFrameBuffer *gpu_fb, int x, int y, int width, int height)
uint top
int GPU_offscreen_height(const GPUOffScreen *ofs)
void GPU_framebuffer_read_depth(GPUFrameBuffer *gpu_fb, int x, int y, int w, int h, eGPUDataFormat format, void *data)
GPUFrameBuffer * GPU_framebuffer_create(const char *name)
@ GPU_FB_DEPTH_STENCIL_ATTACHMENT
@ GPU_FB_MAX_ATTACHMENT
@ GPU_FB_COLOR_ATTACHMENT0
@ GPU_FB_DEPTH_ATTACHMENT
#define GPU_FB_MAX_COLOR_ATTACHMENT
BLI_INLINE float fb(float length, float L)
__kernel void ccl_constant KernelData ccl_global void ccl_global char ccl_global int ccl_global char ccl_global unsigned int ccl_global float * buffer
format
Definition: logImageCore.h:47
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
int save(ostream &out, const Vec3r &v)
Definition: ViewMapIO.cpp:542
static GPUContext * wrap(Context *ctx)
static Context * unwrap(GPUContext *ctx)
struct GPUTexture * tex
GPUTexture * color
GPUTexture * depth
GPUFrameBuffer * fb
struct GPUOffScreen::@620 framebuffers[MAX_CTX_FB_LEN]
ccl_device_inline float2 floor(const float2 &a)