34 const char *
name,
GLContext *ctx, GLenum target, GLuint fbo,
int w,
int h)
41 gl_attachments_[0] = target;
61 if (context_ ==
nullptr) {
67 glDeleteFramebuffers(1, &fbo_id_);
70 context_->fbo_free(fbo_id_);
73 if (context_->active_fb ==
this && context_->back_left !=
this) {
81void GLFrameBuffer::init()
85 glGenFramebuffers(1, &fbo_id_);
88 glBindFramebuffer(GL_FRAMEBUFFER, fbo_id_);
103 GLenum
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
105#define FORMAT_STATUS(X) \
121 case GL_FRAMEBUFFER_COMPLETE:
130 const char *
format =
"gpu::FrameBuffer: %s status %s\n";
142void GLFrameBuffer::update_attachments()
153 GLenum gl_attachment =
to_gl(type);
157 first_attachment = (attach.
tex) ? type : first_attachment;
161 first_attachment = (attach.
tex) ? type : first_attachment;
164 if (attach.
tex ==
nullptr) {
165 glFramebufferTexture(GL_FRAMEBUFFER, gl_attachment, 0, 0);
168 GLuint gl_tex =
static_cast<GLTexture *
>(attach.
tex)->tex_id_;
173 GLenum gl_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + attach.
layer;
174 glFramebufferTexture2D(GL_FRAMEBUFFER, gl_attachment, gl_target, gl_tex, attach.
mip);
176 else if (attach.
layer > -1) {
177 glFramebufferTextureLayer(GL_FRAMEBUFFER, gl_attachment, gl_tex, attach.
mip, attach.
layer);
181 glFramebufferTexture(GL_FRAMEBUFFER, gl_attachment, gl_tex, attach.
mip);
197 if (attach.
tex !=
nullptr) {
200 else if (gl_tex != 0) {
201 GLenum gl_attachment =
to_gl(type);
202 gl_attachments_[
i] = gl_attachment;
203 glFramebufferTexture(GL_FRAMEBUFFER, gl_attachment, gl_tex, 0);
217 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH,
width_);
218 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT,
height_);
223 glDrawBuffers(
ARRAY_SIZE(gl_attachments_), gl_attachments_);
235 bool any_read =
false;
236 for (
auto attachment : color_attachment_states.
index_range()) {
245 glFramebufferFetchBarrierEXT();
265 attachments[
i] = (attach_tex && attach_write) ?
to_gl(type) : GL_NONE;
270 glDrawBuffers(
ARRAY_SIZE(attachments), attachments);
282 if (tmp_detached_[type].tex !=
nullptr) {
290 tmp_detached_[type].tex->detach_from(
this);
295 this->update_attachments();
306 if (tmp_detached_[type].tex !=
nullptr) {
319 glDrawBuffers(
ARRAY_SIZE(gl_attachments_), gl_attachments_);
324 this->update_attachments();
345 for (
int j = 0; j < 4; j++) {
354 glEnable(GL_SCISSOR_TEST);
357 glDisable(GL_SCISSOR_TEST);
371 if (!immutable_ && fbo_id_ == 0) {
376 BLI_assert_msg(0,
"Trying to use the same frame-buffer in multiple context");
380 if (context_->active_fb !=
this) {
381 glBindFramebuffer(GL_FRAMEBUFFER, fbo_id_);
383 if (immutable_ && fbo_id_ == 0) {
384 glDrawBuffer(gl_attachments_[0]);
395 this->update_attachments();
400 if (context_->active_fb !=
this || enabled_srgb_ != enabled_srgb) {
401 enabled_srgb_ = enabled_srgb;
402 if (enabled_srgb && srgb_) {
403 glEnable(GL_FRAMEBUFFER_SRGB);
406 glDisable(GL_FRAMEBUFFER_SRGB);
411 if (context_->active_fb !=
this) {
412 context_->active_fb =
this;
413 state_manager_->active_fb =
this;
425 const float clear_col[4],
439 glClearColor(clear_col[0], clear_col[1], clear_col[2], clear_col[3]);
443 glClearDepth(clear_depth);
448 glClearStencil(clear_stencil);
451 context_->state_manager->apply_state();
467 const void *clear_value)
478 context_->state_manager->apply_state();
482 float depth = ((*(uint32_t *)clear_value) & 0x00FFFFFFu) /
float(0x00FFFFFFu);
483 int stencil = ((*(uint32_t *)clear_value) >> 24);
484 glClearBufferfi(GL_DEPTH_STENCIL, 0, depth, stencil);
488 glClearBufferfv(GL_DEPTH, 0, (GLfloat *)clear_value);
491 float depth = *(uint32_t *)clear_value /
float(0xFFFFFFFFu);
492 glClearBufferfv(GL_DEPTH, 0, &depth);
500 switch (data_format) {
502 glClearBufferfv(GL_COLOR, slot, (GLfloat *)clear_value);
505 glClearBufferuiv(GL_COLOR, slot, (GLuint *)clear_value);
508 glClearBufferiv(GL_COLOR, slot, (GLint *)clear_value);
540 GLenum
format, type, mode;
541 mode = gl_attachments_[slot];
542 type =
to_gl(data_format);
546 format = GL_DEPTH_COMPONENT;
550 "GPUFramebuffer: Error: Trying to read depth without a depth buffer attached.");
555 "GPUFramebuffer: Error: Trying to read a color slot without valid attachment.");
558 if (
format == GL_RED && type == GL_UNSIGNED_INT) {
563 fprintf(stderr,
"GPUFramebuffer: Error: Trying to read stencil bit. Unsupported.");
566 fprintf(stderr,
"GPUFramebuffer: Error: Trying to read more than one frame-buffer plane.");
570 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_id_);
589 glBindFramebuffer(GL_READ_FRAMEBUFFER, src->fbo_id_);
590 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst->fbo_id_);
593 BLI_assert(src->immutable_ ==
false || src_slot == 0);
594 BLI_assert(dst->immutable_ ==
false || dst_slot == 0);
595 BLI_assert(src->gl_attachments_[src_slot] != GL_NONE);
596 BLI_assert(dst->gl_attachments_[dst_slot] != GL_NONE);
597 glReadBuffer(src->gl_attachments_[src_slot]);
598 glDrawBuffer(dst->gl_attachments_[dst_slot]);
601 context_->state_manager->apply_state();
606 glBlitFramebuffer(0, 0,
w, h,
x,
y,
x +
w,
y + h,
mask, GL_NEAREST);
608 if (!dst->immutable_) {
610 glDrawBuffers(
ARRAY_SIZE(dst->gl_attachments_), dst->gl_attachments_);
613 context_->active_fb = dst;
#define BLI_assert_msg(a, msg)
size_t BLI_snprintf(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
void GPU_framebuffer_restore()
static constexpr int GPU_MAX_VIEWPORTS
#define GPU_ATTACHMENT_NONE
GPUStencilTest GPU_stencil_test_get()
void GPU_depth_mask(bool depth)
void GPU_stencil_write_mask_set(uint write_mask)
void GPU_stencil_test(GPUStencilTest test)
void GPU_color_mask(bool r, bool g, bool b, bool a)
void GPU_write_mask(GPUWriteMask mask)
GPUWriteMask GPU_write_mask_get()
uint GPU_stencil_mask_get()
bool GPU_depth_mask_get()
void GPU_texture_get_mipmap_size(blender::gpu::Texture *texture, int mip_level, int *r_size)
blender::gpu::TextureFormat GPU_texture_format(const blender::gpu::Texture *texture)
@ GPU_DATA_UINT_24_8_DEPRECATED
void GPU_texture_bind_ex(blender::gpu::Texture *texture, GPUSamplerState state, int unit)
bool GPU_texture_is_cube(const blender::gpu::Texture *texture)
bool GPU_texture_is_array(const blender::gpu::Texture *texture)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
constexpr IndexRange index_range() const
StateManager * state_manager
void size_set(int width, int height)
void set_color_attachment_bit(GPUAttachmentType type, bool value)
char name_[DEBUG_NAME_LEN]
FrameBuffer(const char *name)
GPUAttachment attachments_[GPU_FB_MAX_ATTACHMENT]
int viewport_[GPU_MAX_VIEWPORTS][4]
void attachment_set(GPUAttachmentType type, const GPUAttachment &new_attachment)
static bool framebuffer_fetch_support
static bool unused_fb_slot_workaround
static bool texture_barrier_support
bool check(char err_out[256]) override
void attachment_set_loadstore_op(GPUAttachmentType type, GPULoadStore ls) override
void clear(GPUFrameBufferBits buffers, const float clear_col[4], float clear_depth, uint clear_stencil) override
void blit_to(GPUFrameBufferBits planes, int src_slot, FrameBuffer *dst, int dst_slot, int dst_offset_x, int dst_offset_y) override
void clear_multi(const float(*clear_cols)[4]) override
void subpass_transition_impl(const GPUAttachmentState depth_attachment_state, Span< GPUAttachmentState > color_attachment_states) override
GLFrameBuffer(const char *name)
void bind(bool enabled_srgb) override
void clear_attachment(GPUAttachmentType type, eGPUDataFormat data_format, const void *clear_value) override
void read(GPUFrameBufferBits planes, eGPUDataFormat format, const int area[4], int channel_len, int slot, void *r_data) override
static void set_framebuffer_srgb_target(int use_srgb_to_linear)
@ GPU_FB_DEPTH_STENCIL_ATTACHMENT
@ GPU_FB_COLOR_ATTACHMENT0
@ GPU_FB_DEPTH_ATTACHMENT
#define GPU_FB_MAX_COLOR_ATTACHMENT
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
void object_label(GLenum type, GLuint object, const char *name)
GLenum channel_len_to_gl(int channel_len)
static GLenum to_gl(const GPUAttachmentType type)
blender::gpu::Texture * tex
static constexpr GPUSamplerState default_sampler()