34 const char *name,
GLContext *ctx, GLenum target, GLuint fbo,
int w,
int h)
41 gl_attachments_[0] = target;
60 if (context_ ==
nullptr) {
66 glDeleteFramebuffers(1, &fbo_id_);
80void GLFrameBuffer::init()
84 glGenFramebuffers(1, &fbo_id_);
87 glBindFramebuffer(GL_FRAMEBUFFER, fbo_id_);
102 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
104#define FORMAT_STATUS(X) \
120 case GL_FRAMEBUFFER_COMPLETE:
129 const char *
format =
"GPUFrameBuffer: %s status %s\n";
141void GLFrameBuffer::update_attachments()
152 GLenum gl_attachment =
to_gl(type);
156 first_attachment = (attach.
tex) ? type : first_attachment;
160 first_attachment = (attach.
tex) ? type : first_attachment;
163 if (attach.
tex ==
nullptr) {
164 glFramebufferTexture(GL_FRAMEBUFFER, gl_attachment, 0, 0);
172 GLenum gl_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + attach.
layer;
173 glFramebufferTexture2D(GL_FRAMEBUFFER, gl_attachment, gl_target, gl_tex, attach.
mip);
175 else if (attach.
layer > -1) {
176 glFramebufferTextureLayer(GL_FRAMEBUFFER, gl_attachment, gl_tex, attach.
mip, attach.
layer);
180 glFramebufferTexture(GL_FRAMEBUFFER, gl_attachment, gl_tex, attach.
mip);
193 for (
int i =
ARRAY_SIZE(gl_attachments_) - 1; i >= 0; --i) {
196 if (attach.
tex !=
nullptr) {
199 else if (gl_tex != 0) {
200 GLenum gl_attachment =
to_gl(type);
201 gl_attachments_[i] = gl_attachment;
202 glFramebufferTexture(GL_FRAMEBUFFER, gl_attachment, gl_tex, 0);
216 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH,
width_);
217 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT,
height_);
222 glDrawBuffers(
ARRAY_SIZE(gl_attachments_), gl_attachments_);
234 bool any_read =
false;
235 for (
auto attachment : color_attachment_states.
index_range()) {
244 glFramebufferFetchBarrierEXT();
253 for (
int i : color_attachment_states.
index_range()) {
264 attachments[i] = (attach_tex && attach_write) ?
to_gl(type) : GL_NONE;
269 glDrawBuffers(
ARRAY_SIZE(attachments), attachments);
277 for (
int i : color_attachment_states.
index_range()) {
281 if (tmp_detached_[type].
tex !=
nullptr) {
289 unwrap(tmp_detached_[type].
tex)->detach_from(
this);
294 this->update_attachments();
305 if (tmp_detached_[type].
tex !=
nullptr) {
318 glDrawBuffers(
ARRAY_SIZE(gl_attachments_), gl_attachments_);
323 this->update_attachments();
344 for (
int j = 0; j < 4; j++) {
353 glEnable(GL_SCISSOR_TEST);
356 glDisable(GL_SCISSOR_TEST);
370 if (!immutable_ && fbo_id_ == 0) {
375 BLI_assert_msg(0,
"Trying to use the same frame-buffer in multiple context");
380 glBindFramebuffer(GL_FRAMEBUFFER, fbo_id_);
382 if (immutable_ && fbo_id_ == 0) {
383 glDrawBuffer(gl_attachments_[0]);
394 this->update_attachments();
399 if (context_->
active_fb !=
this || enabled_srgb_ != enabled_srgb) {
400 enabled_srgb_ = enabled_srgb;
401 if (enabled_srgb && srgb_) {
402 glEnable(GL_FRAMEBUFFER_SRGB);
405 glDisable(GL_FRAMEBUFFER_SRGB);
424 const float clear_col[4],
438 glClearColor(clear_col[0], clear_col[1], clear_col[2], clear_col[3]);
442 glClearDepth(clear_depth);
447 glClearStencil(clear_stencil);
466 const void *clear_value)
481 float depth = ((*(
uint32_t *)clear_value) & 0x00FFFFFFu) /
float(0x00FFFFFFu);
482 int stencil = ((*(
uint32_t *)clear_value) >> 24);
483 glClearBufferfi(GL_DEPTH_STENCIL, 0, depth, stencil);
487 glClearBufferfv(GL_DEPTH, 0, (GLfloat *)clear_value);
490 float depth = *(
uint32_t *)clear_value /
float(0xFFFFFFFFu);
491 glClearBufferfv(GL_DEPTH, 0, &depth);
499 switch (data_format) {
501 glClearBufferfv(GL_COLOR, slot, (GLfloat *)clear_value);
504 glClearBufferuiv(GL_COLOR, slot, (GLuint *)clear_value);
507 glClearBufferiv(GL_COLOR, slot, (GLint *)clear_value);
539 GLenum
format, type, mode;
540 mode = gl_attachments_[slot];
541 type =
to_gl(data_format);
545 format = GL_DEPTH_COMPONENT;
549 "GPUFramebuffer: Error: Trying to read depth without a depth buffer attached.");
554 "GPUFramebuffer: Error: Trying to read a color slot without valid attachment.");
557 if (
format == GL_RED && type == GL_UNSIGNED_INT) {
562 fprintf(stderr,
"GPUFramebuffer: Error: Trying to read stencil bit. Unsupported.");
565 fprintf(stderr,
"GPUFramebuffer: Error: Trying to read more than one frame-buffer plane.");
569 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_id_);
588 glBindFramebuffer(GL_READ_FRAMEBUFFER, src->fbo_id_);
589 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst->fbo_id_);
592 BLI_assert(src->immutable_ ==
false || src_slot == 0);
593 BLI_assert(dst->immutable_ ==
false || dst_slot == 0);
594 BLI_assert(src->gl_attachments_[src_slot] != GL_NONE);
595 BLI_assert(dst->gl_attachments_[dst_slot] != GL_NONE);
596 glReadBuffer(src->gl_attachments_[src_slot]);
597 glDrawBuffer(dst->gl_attachments_[dst_slot]);
604 GLbitfield mask =
to_gl(planes);
605 glBlitFramebuffer(0, 0,
w, h, x, y, x +
w, y + h, mask, GL_NEAREST);
607 if (!dst->immutable_) {
609 glDrawBuffers(
ARRAY_SIZE(dst->gl_attachments_), dst->gl_attachments_);
#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()
#define GPU_ATTACHMENT_NONE
#define GPU_MAX_VIEWPORTS
void GPU_write_mask(eGPUWriteMask mask)
void GPU_depth_mask(bool depth)
void GPU_stencil_test(eGPUStencilTest test)
void GPU_stencil_write_mask_set(uint write_mask)
void GPU_color_mask(bool r, bool g, bool b, bool a)
eGPUWriteMask GPU_write_mask_get()
eGPUStencilTest GPU_stencil_test_get()
uint GPU_stencil_mask_get()
bool GPU_depth_mask_get()
void GPU_texture_bind_ex(GPUTexture *texture, GPUSamplerState state, int unit)
bool GPU_texture_is_cube(const GPUTexture *texture)
bool GPU_texture_is_array(const GPUTexture *texture)
void GPU_texture_get_mipmap_size(GPUTexture *texture, int mip_level, int *r_size)
eGPUTextureFormat GPU_texture_format(const GPUTexture *texture)
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)
char name_[DEBUG_NAME_LEN]
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
void fbo_free(GLuint fbo_id)
void clear(eGPUFrameBufferBits buffers, const float clear_col[4], float clear_depth, uint clear_stencil) override
bool check(char err_out[256]) override
void attachment_set_loadstore_op(GPUAttachmentType type, GPULoadStore ls) override
void read(eGPUFrameBufferBits planes, eGPUDataFormat format, const int area[4], int channel_len, int slot, void *r_data) 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 blit_to(eGPUFrameBufferBits planes, int src_slot, FrameBuffer *dst, int dst_slot, int dst_offset_x, int dst_offset_y) override
GLFrameBuffer * active_fb
static void set_framebuffer_srgb_target(int use_srgb_to_linear)
virtual void apply_state()=0
@ GPU_FB_DEPTH_STENCIL_ATTACHMENT
@ GPU_FB_COLOR_ATTACHMENT0
@ GPU_FB_DEPTH_ATTACHMENT
#define GPU_FB_MAX_COLOR_ATTACHMENT
void object_label(GLenum type, GLuint object, const char *name)
static Context * unwrap(GPUContext *ctx)
GLenum channel_len_to_gl(int channel_len)
static GLenum to_gl(const GPUAttachmentType type)
static constexpr GPUSamplerState default_sampler()