| 
									
										
										
										
											2020-08-25 23:27:40 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2020 Blender Foundation. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup gpu | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-02-05 21:32:31 +11:00
										 |  |  |  * Private frame buffer API. | 
					
						
							| 
									
										
										
										
											2020-08-25 23:27:40 +02:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-29 15:17:13 +02:00
										 |  |  | #include "BLI_math_vector.h"
 | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  | #include "BLI_span.hh"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-25 23:27:40 +02:00
										 |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "GPU_framebuffer.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct GPUTexture; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  | typedef enum GPUAttachmentType : int { | 
					
						
							| 
									
										
										
										
											2020-08-25 23:27:40 +02:00
										 |  |  |   GPU_FB_DEPTH_ATTACHMENT = 0, | 
					
						
							|  |  |  |   GPU_FB_DEPTH_STENCIL_ATTACHMENT, | 
					
						
							|  |  |  |   GPU_FB_COLOR_ATTACHMENT0, | 
					
						
							|  |  |  |   GPU_FB_COLOR_ATTACHMENT1, | 
					
						
							|  |  |  |   GPU_FB_COLOR_ATTACHMENT2, | 
					
						
							|  |  |  |   GPU_FB_COLOR_ATTACHMENT3, | 
					
						
							|  |  |  |   GPU_FB_COLOR_ATTACHMENT4, | 
					
						
							|  |  |  |   GPU_FB_COLOR_ATTACHMENT5, | 
					
						
							|  |  |  |   /* Number of maximum output slots.
 | 
					
						
							|  |  |  |    * We support 6 outputs for now (usually we wouldn't need more to preserve fill rate). */ | 
					
						
							|  |  |  |   /* Keep in mind that GL max is GL_MAX_DRAW_BUFFERS and is at least 8, corresponding to
 | 
					
						
							|  |  |  |    * the maximum number of COLOR attachments specified by glDrawBuffers. */ | 
					
						
							| 
									
										
										
										
											2020-09-02 10:04:50 +10:00
										 |  |  |   GPU_FB_MAX_ATTACHMENT, | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-25 23:27:40 +02:00
										 |  |  | } GPUAttachmentType; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-02 11:39:27 +10:00
										 |  |  | #define GPU_FB_MAX_COLOR_ATTACHMENT (GPU_FB_MAX_ATTACHMENT - GPU_FB_COLOR_ATTACHMENT0)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  | inline constexpr GPUAttachmentType operator-(GPUAttachmentType a, int b) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return static_cast<GPUAttachmentType>(static_cast<int>(a) - b); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-08-25 23:27:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  | inline constexpr GPUAttachmentType operator+(GPUAttachmentType a, int b) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return static_cast<GPUAttachmentType>(static_cast<int>(a) + b); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-08-25 23:27:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  | inline GPUAttachmentType &operator++(GPUAttachmentType &a) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   a = a + 1; | 
					
						
							|  |  |  |   return a; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-08-25 23:27:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  | inline GPUAttachmentType &operator--(GPUAttachmentType &a) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   a = a - 1; | 
					
						
							|  |  |  |   return a; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-08-25 23:27:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  | namespace blender { | 
					
						
							|  |  |  | namespace gpu { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef DEBUG
 | 
					
						
							|  |  |  | #  define DEBUG_NAME_LEN 64
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #  define DEBUG_NAME_LEN 16
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2020-08-25 23:27:40 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | class FrameBuffer { | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  |  protected: | 
					
						
							| 
									
										
										
										
											2020-09-02 09:58:26 +10:00
										 |  |  |   /** Set of texture attachments to render to. DEPTH and DEPTH_STENCIL are mutually exclusive. */ | 
					
						
							| 
									
										
										
										
											2020-09-02 10:04:50 +10:00
										 |  |  |   GPUAttachment attachments_[GPU_FB_MAX_ATTACHMENT]; | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  |   /** Is true if internal representation need to be updated. */ | 
					
						
							|  |  |  |   bool dirty_attachments_; | 
					
						
							| 
									
										
										
										
											2020-09-02 09:58:26 +10:00
										 |  |  |   /** Size of attachment textures. */ | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  |   int width_, height_; | 
					
						
							|  |  |  |   /** Debug name. */ | 
					
						
							|  |  |  |   char name_[DEBUG_NAME_LEN]; | 
					
						
							| 
									
										
										
										
											2020-09-02 09:58:26 +10:00
										 |  |  |   /** Frame-buffer state. */ | 
					
						
							| 
									
										
										
										
											2020-11-05 17:59:07 +01:00
										 |  |  |   int viewport_[4] = {0}; | 
					
						
							|  |  |  |   int scissor_[4] = {0}; | 
					
						
							| 
									
										
										
										
											2020-08-29 15:17:13 +02:00
										 |  |  |   bool scissor_test_ = false; | 
					
						
							| 
									
										
										
										
											2020-11-05 17:59:07 +01:00
										 |  |  |   bool dirty_state_ = true; | 
					
						
							| 
									
										
										
										
											2020-08-25 23:27:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-30 11:20:39 -03:00
										 |  |  | #ifndef GPU_NO_USE_PY_REFERENCES
 | 
					
						
							| 
									
										
										
										
											2021-04-29 14:48:59 -03:00
										 |  |  |  public: | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Reference of a pointer that needs to be cleaned when deallocating the frame-buffer. | 
					
						
							|  |  |  |    * Points to #BPyGPUFrameBuffer.fb | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   void **py_ref = nullptr; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-30 10:48:55 -03:00
										 |  |  |  public: | 
					
						
							|  |  |  |   /* Reference of a pointer that needs to be cleaned when deallocating the frame-buffer.
 | 
					
						
							| 
									
										
										
										
											2021-05-04 00:42:34 +10:00
										 |  |  |    * Points to #BPyGPUFrameBuffer::fb */ | 
					
						
							| 
									
										
										
										
											2021-04-30 10:48:55 -03:00
										 |  |  |   void **ref = nullptr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-25 23:27:40 +02:00
										 |  |  |  public: | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  |   FrameBuffer(const char *name); | 
					
						
							|  |  |  |   virtual ~FrameBuffer(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   virtual void bind(bool enabled_srgb) = 0; | 
					
						
							|  |  |  |   virtual bool check(char err_out[256]) = 0; | 
					
						
							|  |  |  |   virtual void clear(eGPUFrameBufferBits buffers, | 
					
						
							|  |  |  |                      const float clear_col[4], | 
					
						
							|  |  |  |                      float clear_depth, | 
					
						
							|  |  |  |                      uint clear_stencil) = 0; | 
					
						
							|  |  |  |   virtual void clear_multi(const float (*clear_col)[4]) = 0; | 
					
						
							| 
									
										
										
										
											2020-09-03 21:52:30 +02:00
										 |  |  |   virtual void clear_attachment(GPUAttachmentType type, | 
					
						
							|  |  |  |                                 eGPUDataFormat data_format, | 
					
						
							|  |  |  |                                 const void *clear_value) = 0; | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   virtual void read(eGPUFrameBufferBits planes, | 
					
						
							|  |  |  |                     eGPUDataFormat format, | 
					
						
							|  |  |  |                     const int area[4], | 
					
						
							|  |  |  |                     int channel_len, | 
					
						
							|  |  |  |                     int slot, | 
					
						
							|  |  |  |                     void *r_data) = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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); | 
					
						
							| 
									
										
										
										
											2020-09-05 17:37:01 +02:00
										 |  |  |   void attachment_remove(GPUAttachmentType type); | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   void recursive_downsample(int max_lvl, | 
					
						
							|  |  |  |                             void (*callback)(void *userData, int level), | 
					
						
							|  |  |  |                             void *userData); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-29 14:03:15 +02:00
										 |  |  |   inline void size_set(int width, int height) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     width_ = width; | 
					
						
							|  |  |  |     height_ = height; | 
					
						
							| 
									
										
										
										
											2020-08-29 15:17:13 +02:00
										 |  |  |     dirty_state_ = true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   inline void viewport_set(const int viewport[4]) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if (!equals_v4v4_int(viewport_, viewport)) { | 
					
						
							|  |  |  |       copy_v4_v4_int(viewport_, viewport); | 
					
						
							|  |  |  |       dirty_state_ = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   inline void scissor_set(const int scissor[4]) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if (!equals_v4v4_int(scissor_, scissor)) { | 
					
						
							|  |  |  |       copy_v4_v4_int(scissor_, scissor); | 
					
						
							|  |  |  |       dirty_state_ = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   inline void scissor_test_set(bool test) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     scissor_test_ = test; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   inline void viewport_get(int r_viewport[4]) const | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     copy_v4_v4_int(r_viewport, viewport_); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   inline void scissor_get(int r_scissor[4]) const | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     copy_v4_v4_int(r_scissor, scissor_); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   inline bool scissor_test_get(void) const | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     return scissor_test_; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   inline void viewport_reset(void) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     int viewport_rect[4] = {0, 0, width_, height_}; | 
					
						
							|  |  |  |     viewport_set(viewport_rect); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   inline void scissor_reset(void) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     int scissor_rect[4] = {0, 0, width_, height_}; | 
					
						
							|  |  |  |     scissor_set(scissor_rect); | 
					
						
							| 
									
										
										
										
											2020-08-29 14:03:15 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  |   inline GPUTexture *depth_tex(void) const | 
					
						
							| 
									
										
										
										
											2020-08-25 23:27:40 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  |     if (attachments_[GPU_FB_DEPTH_ATTACHMENT].tex) { | 
					
						
							|  |  |  |       return attachments_[GPU_FB_DEPTH_ATTACHMENT].tex; | 
					
						
							| 
									
										
										
										
											2020-08-25 23:27:40 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  |     return attachments_[GPU_FB_DEPTH_STENCIL_ATTACHMENT].tex; | 
					
						
							| 
									
										
										
										
											2020-08-25 23:27:40 +02:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  |   inline GPUTexture *color_tex(int slot) const | 
					
						
							| 
									
										
										
										
											2020-08-25 23:27:40 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  |     return attachments_[GPU_FB_COLOR_ATTACHMENT0 + slot].tex; | 
					
						
							| 
									
										
										
										
											2020-08-25 23:27:40 +02:00
										 |  |  |   }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-05 16:23:34 +11:00
										 |  |  | /* Syntactic sugar. */ | 
					
						
							| 
									
										
										
										
											2020-09-08 03:34:47 +02:00
										 |  |  | static inline GPUFrameBuffer *wrap(FrameBuffer *vert) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return reinterpret_cast<GPUFrameBuffer *>(vert); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | static inline FrameBuffer *unwrap(GPUFrameBuffer *vert) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return reinterpret_cast<FrameBuffer *>(vert); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | static inline const FrameBuffer *unwrap(const GPUFrameBuffer *vert) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return reinterpret_cast<const FrameBuffer *>(vert); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-29 01:13:54 +02:00
										 |  |  | #undef DEBUG_NAME_LEN
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-25 23:27:40 +02:00
										 |  |  | }  // namespace gpu
 | 
					
						
							|  |  |  | }  // namespace blender
 |