| 
									
										
										
										
											2022-02-11 09:07:11 +11:00
										 |  |  | /* SPDX-License-Identifier: GPL-2.0-or-later
 | 
					
						
							|  |  |  |  * Copyright 2020 Blender Foundation. All rights reserved. */ | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup gpu | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-02-05 16:23:34 +11:00
										 |  |  |  * Encapsulation of Frame-buffer states (attached textures, viewport, scissors). | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "glew-mx.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "gpu_framebuffer_private.hh"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace blender::gpu { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-29 15:17:13 +02:00
										 |  |  | class GLStateManager; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Implementation of FrameBuffer object using OpenGL. | 
					
						
							| 
									
										
										
										
											2021-01-04 12:00:18 +11:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  | class GLFrameBuffer : public FrameBuffer { | 
					
						
							| 
									
										
										
										
											2020-09-05 17:36:13 +02:00
										 |  |  |   /* For debugging purpose. */ | 
					
						
							|  |  |  |   friend class GLTexture; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  |  private: | 
					
						
							|  |  |  |   /** OpenGL handle. */ | 
					
						
							|  |  |  |   GLuint fbo_id_ = 0; | 
					
						
							| 
									
										
										
										
											2021-02-05 16:23:34 +11:00
										 |  |  |   /** Context the handle is from. Frame-buffers are not shared across contexts. */ | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  |   GLContext *context_ = NULL; | 
					
						
							| 
									
										
										
										
											2020-08-29 15:17:13 +02:00
										 |  |  |   /** State Manager of the same contexts. */ | 
					
						
							|  |  |  |   GLStateManager *state_manager_ = NULL; | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  |   /** Copy of the GL state. Contains ONLY color attachments enums for slot binding. */ | 
					
						
							|  |  |  |   GLenum gl_attachments_[GPU_FB_MAX_COLOR_ATTACHMENT]; | 
					
						
							| 
									
										
										
										
											2021-02-05 16:23:34 +11:00
										 |  |  |   /** Internal frame-buffers are immutable. */ | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  |   bool immutable_; | 
					
						
							| 
									
										
										
										
											2021-02-05 16:23:34 +11:00
										 |  |  |   /** True is the frame-buffer has its first color target using the GPU_SRGB8_A8 format. */ | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  |   bool srgb_; | 
					
						
							| 
									
										
										
										
											2021-02-05 16:23:34 +11:00
										 |  |  |   /** True is the frame-buffer has been bound using the GL_FRAMEBUFFER_SRGB feature. */ | 
					
						
							| 
									
										
										
										
											2020-10-14 18:15:50 +02:00
										 |  |  |   bool enabled_srgb_ = false; | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   /**
 | 
					
						
							| 
									
										
										
										
											2021-02-05 16:23:34 +11:00
										 |  |  |    * Create a conventional frame-buffer to attach texture to. | 
					
						
							| 
									
										
										
										
											2021-01-04 12:00:18 +11:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  |   GLFrameBuffer(const char *name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							| 
									
										
										
										
											2020-09-08 09:10:17 +10:00
										 |  |  |    * Special frame-buffer encapsulating internal window frame-buffer. | 
					
						
							|  |  |  |    *  (i.e.: #GL_FRONT_LEFT, #GL_BACK_RIGHT, ...) | 
					
						
							| 
									
										
										
										
											2020-11-06 14:35:38 +11:00
										 |  |  |    * \param ctx: Context the handle is from. | 
					
						
							|  |  |  |    * \param target: The internal GL name (i.e: #GL_BACK_LEFT). | 
					
						
							|  |  |  |    * \param fbo: The (optional) already created object for some implementation. Default is 0. | 
					
						
							|  |  |  |    * \param w: Buffer width. | 
					
						
							|  |  |  |    * \param h: Buffer height. | 
					
						
							| 
									
										
										
										
											2021-01-04 12:00:18 +11:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  |   GLFrameBuffer(const char *name, GLContext *ctx, GLenum target, GLuint fbo, int w, int h); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ~GLFrameBuffer(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void bind(bool enabled_srgb) override; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-09 20:01:47 +11:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * This is a rather slow operation. Don't check in normal cases. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  |   bool check(char err_out[256]) override; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void clear(eGPUFrameBufferBits buffers, | 
					
						
							|  |  |  |              const float clear_col[4], | 
					
						
							|  |  |  |              float clear_depth, | 
					
						
							|  |  |  |              uint clear_stencil) override; | 
					
						
							|  |  |  |   void clear_multi(const float (*clear_cols)[4]) override; | 
					
						
							| 
									
										
										
										
											2020-09-03 21:52:30 +02:00
										 |  |  |   void clear_attachment(GPUAttachmentType type, | 
					
						
							|  |  |  |                         eGPUDataFormat data_format, | 
					
						
							|  |  |  |                         const void *clear_value) override; | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   void read(eGPUFrameBufferBits planes, | 
					
						
							|  |  |  |             eGPUDataFormat format, | 
					
						
							|  |  |  |             const int area[4], | 
					
						
							|  |  |  |             int channel_len, | 
					
						
							|  |  |  |             int slot, | 
					
						
							|  |  |  |             void *r_data) override; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-09 20:01:47 +11:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Copy \a src at the give offset inside \a dst. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  |   void blit_to(eGPUFrameBufferBits planes, | 
					
						
							|  |  |  |                int src_slot, | 
					
						
							|  |  |  |                FrameBuffer *dst, | 
					
						
							|  |  |  |                int dst_slot, | 
					
						
							|  |  |  |                int dst_offset_x, | 
					
						
							|  |  |  |                int dst_offset_y) override; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-05 21:44:03 -05:00
										 |  |  |   void apply_state(); | 
					
						
							| 
									
										
										
										
											2020-08-29 15:17:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  |  private: | 
					
						
							| 
									
										
										
										
											2022-01-05 21:44:03 -05:00
										 |  |  |   void init(); | 
					
						
							|  |  |  |   void update_attachments(); | 
					
						
							|  |  |  |   void update_drawbuffers(); | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   MEM_CXX_CLASS_ALLOC_FUNCS("GLFrameBuffer"); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name Enums Conversion
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline GLenum to_gl(const GPUAttachmentType type) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #define ATTACHMENT(X) \
 | 
					
						
							|  |  |  |   case GPU_FB_##X: { \ | 
					
						
							|  |  |  |     return GL_##X; \ | 
					
						
							|  |  |  |   } \ | 
					
						
							|  |  |  |     ((void)0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch (type) { | 
					
						
							|  |  |  |     ATTACHMENT(DEPTH_ATTACHMENT); | 
					
						
							|  |  |  |     ATTACHMENT(DEPTH_STENCIL_ATTACHMENT); | 
					
						
							|  |  |  |     ATTACHMENT(COLOR_ATTACHMENT0); | 
					
						
							|  |  |  |     ATTACHMENT(COLOR_ATTACHMENT1); | 
					
						
							|  |  |  |     ATTACHMENT(COLOR_ATTACHMENT2); | 
					
						
							|  |  |  |     ATTACHMENT(COLOR_ATTACHMENT3); | 
					
						
							|  |  |  |     ATTACHMENT(COLOR_ATTACHMENT4); | 
					
						
							|  |  |  |     ATTACHMENT(COLOR_ATTACHMENT5); | 
					
						
							| 
									
										
										
										
											2022-02-04 19:56:36 +01:00
										 |  |  |     ATTACHMENT(COLOR_ATTACHMENT6); | 
					
						
							|  |  |  |     ATTACHMENT(COLOR_ATTACHMENT7); | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  |     default: | 
					
						
							|  |  |  |       BLI_assert(0); | 
					
						
							|  |  |  |       return GL_COLOR_ATTACHMENT0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #undef ATTACHMENT
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline GLbitfield to_gl(const eGPUFrameBufferBits bits) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GLbitfield mask = 0; | 
					
						
							|  |  |  |   mask |= (bits & GPU_DEPTH_BIT) ? GL_DEPTH_BUFFER_BIT : 0; | 
					
						
							|  |  |  |   mask |= (bits & GPU_STENCIL_BIT) ? GL_STENCIL_BUFFER_BIT : 0; | 
					
						
							|  |  |  |   mask |= (bits & GPU_COLOR_BIT) ? GL_COLOR_BUFFER_BIT : 0; | 
					
						
							|  |  |  |   return mask; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }  // namespace blender::gpu
 |