Blender  V3.3
mtl_framebuffer.hh
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
9 #pragma once
10 
11 #include "GPU_common_types.h"
12 #include "MEM_guardedalloc.h"
13 
15 #include "mtl_texture.hh"
16 #include <Metal/Metal.h>
17 
18 namespace blender::gpu {
19 
20 class MTLContext;
21 
22 struct MTLAttachment {
23  bool used;
25  union {
26  float color[4];
27  float depth;
30 
36 
37  /* If Array Length is larger than zero, use multilayered rendering. */
39 };
40 
44 class MTLFrameBuffer : public FrameBuffer {
45  private:
46  /* Context Handle. */
47  MTLContext *context_;
48 
49  /* Metal Attachment properties. */
50  uint colour_attachment_count_;
51  MTLAttachment mtl_color_attachments_[GPU_FB_MAX_COLOR_ATTACHMENT];
52  MTLAttachment mtl_depth_attachment_;
53  MTLAttachment mtl_stencil_attachment_;
54  bool use_multilayered_rendering_ = false;
55 
56  /* State. */
57  /* Whether global framebuffer properties have changed and require
58  * re-generation of MTLRenderPassDescriptor/RenderCommandEncoders. */
59  bool is_dirty_;
60 
61  /* Whether loadstore properties have changed (only affects certain cached configs). */
62  bool is_loadstore_dirty_;
63 
64  /* Context that the latest modified state was last applied to.
65  * If this does not match current ctx, re-apply state. */
66  MTLContext *dirty_state_ctx_;
67 
68  /* Whether a clear is pending -- Used to toggle between clear and load FB configurations
69  * (without dirtying the state) - Frame-buffer load config is used if no `GPU_clear_*` command
70  * was issued after binding the FrameBuffer. */
71  bool has_pending_clear_;
72 
73  /* Render Pass Descriptors:
74  * There are 3 MTLRenderPassDescriptors for different ways in which a frame-buffer
75  * can be configured:
76  * [0] = CLEAR CONFIG -- Used when a GPU_framebuffer_clear_* command has been issued.
77  * [1] = LOAD CONFIG -- Used if bound, but no clear is required.
78  * [2] = CUSTOM CONFIG -- When using GPU_framebuffer_bind_ex to manually specify
79  * load-store configuration for optimal bandwidth utilization.
80  * -- We cache these different configs to avoid re-generation --
81  */
82  typedef enum {
83  MTL_FB_CONFIG_CLEAR = 0,
84  MTL_FB_CONFIG_LOAD = 1,
85  MTL_FB_CONFIG_CUSTOM = 2
86  } MTL_FB_CONFIG;
87 #define MTL_FB_CONFIG_MAX (MTL_FB_CONFIG_CUSTOM + 1)
88 
89  MTLRenderPassDescriptor *framebuffer_descriptor_[MTL_FB_CONFIG_MAX];
90  MTLRenderPassColorAttachmentDescriptor
91  *colour_attachment_descriptors_[GPU_FB_MAX_COLOR_ATTACHMENT];
92  /* Whether MTLRenderPassDescriptor[N] requires updating with latest state. */
93  bool descriptor_dirty_[MTL_FB_CONFIG_MAX];
94  /* Whether SRGB is enabled for this framebuffer configuration. */
95  bool srgb_enabled_;
96  /* Whether the primary Frame-buffer attachment is an SRGB target or not. */
97  bool is_srgb_;
98 
99  public:
103  MTLFrameBuffer(MTLContext *ctx, const char *name);
104 
105  ~MTLFrameBuffer();
106 
107  void bind(bool enabled_srgb) override;
108 
109  bool check(char err_out[256]) override;
110 
111  void clear(eGPUFrameBufferBits buffers,
112  const float clear_col[4],
113  float clear_depth,
114  uint clear_stencil) override;
115  void clear_multi(const float (*clear_cols)[4]) override;
117  eGPUDataFormat data_format,
118  const void *clear_value) override;
119 
121  eGPULoadOp load_action,
122  eGPUStoreOp store_action) override;
123 
124  void read(eGPUFrameBufferBits planes,
126  const int area[4],
127  int channel_len,
128  int slot,
129  void *r_data) override;
130 
131  void blit_to(eGPUFrameBufferBits planes,
132  int src_slot,
133  FrameBuffer *dst,
134  int dst_slot,
135  int dst_offset_x,
136  int dst_offset_y) override;
137 
138  void apply_state();
139 
140  /* State. */
141  /* Flag MTLFramebuffer configuration as having changed. */
142  void mark_dirty();
143  void mark_loadstore_dirty();
144  /* Mark that a pending clear has been performed. */
145  void mark_cleared();
146  /* Mark that we have a pending clear. */
147  void mark_do_clear();
148 
149  /* Attachment management. */
150  /* When dirty_attachments_ is true, we need to reprocess attachments to extract Metal
151  * information. */
152  void update_attachments(bool update_viewport);
153  bool add_color_attachment(gpu::MTLTexture *texture, uint slot, int miplevel, int layer);
154  bool add_depth_attachment(gpu::MTLTexture *texture, int miplevel, int layer);
155  bool add_stencil_attachment(gpu::MTLTexture *texture, int miplevel, int layer);
156  bool remove_color_attachment(uint slot);
159  void remove_all_attachments();
161 
162  /* Clear values -> Load/store actions. */
163  bool set_color_attachment_clear_color(uint slot, const float clear_color[4]);
164  bool set_depth_attachment_clear_value(float depth_clear);
165  bool set_stencil_attachment_clear_value(uint stencil_clear);
166  bool set_color_loadstore_op(uint slot, eGPULoadOp load_action, eGPUStoreOp store_action);
167  bool set_depth_loadstore_op(eGPULoadOp load_action, eGPUStoreOp store_action);
168  bool set_stencil_loadstore_op(eGPULoadOp load_action, eGPUStoreOp store_action);
169 
170  /* Remove any pending clears - Ensure "load" configuration is used. */
171  bool reset_clear_state();
172 
173  /* Fetch values */
174  bool has_attachment_at_slot(uint slot);
175  bool has_color_attachment_with_texture(gpu::MTLTexture *texture);
176  bool has_depth_attachment();
177  bool has_stencil_attachment();
178  int get_color_attachment_slot_from_texture(gpu::MTLTexture *texture);
181  {
183  };
187 
188  /* Metal API resources and validation. */
189  bool validate_render_pass();
190  MTLRenderPassDescriptor *bake_render_pass_descriptor(bool load_contents);
191 
192  /* Blitting. */
193  void blit(uint read_slot,
194  uint src_x_offset,
195  uint src_y_offset,
196  MTLFrameBuffer *metal_fb_write,
197  uint write_slot,
198  uint dst_x_offset,
199  uint dst_y_offset,
200  uint width,
201  uint height,
202  eGPUFrameBufferBits blit_buffers);
203 
204  int get_width();
205  int get_height();
206  bool get_dirty()
207  {
208  return is_dirty_ || is_loadstore_dirty_;
209  }
210 
212  {
213  return has_pending_clear_;
214  }
215 
217  {
218  return srgb_enabled_;
219  }
220 
221  bool get_is_srgb()
222  {
223  return is_srgb_;
224  }
225 
226  private:
227  /* Clears a render target by force-opening a render pass. */
228  void force_clear();
229 
230  MEM_CXX_CLASS_ALLOC_FUNCS("MTLFrameBuffer");
231 };
232 
233 } // namespace blender::gpu
unsigned int uint
Definition: BLI_sys_types.h:67
eGPULoadOp
eGPUStoreOp
eGPUFrameBufferBits
_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 type
_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
eGPUDataFormat
Definition: GPU_texture.h:170
Read Guarded memory(de)allocation.
FrameBuffer(const char *name)
bool set_depth_loadstore_op(eGPULoadOp load_action, eGPUStoreOp store_action)
MTLAttachment get_color_attachment(uint slot)
bool remove_color_attachment(uint slot)
void blit(uint read_slot, uint src_x_offset, uint src_y_offset, MTLFrameBuffer *metal_fb_write, uint write_slot, uint dst_x_offset, uint dst_y_offset, uint width, uint height, eGPUFrameBufferBits blit_buffers)
void read(eGPUFrameBufferBits planes, eGPUDataFormat format, const int area[4], int channel_len, int slot, void *r_data) override
int get_color_attachment_slot_from_texture(gpu::MTLTexture *texture)
void blit_to(eGPUFrameBufferBits planes, int src_slot, FrameBuffer *dst, int dst_slot, int dst_offset_x, int dst_offset_y) override
bool check(char err_out[256]) override
bool add_color_attachment(gpu::MTLTexture *texture, uint slot, int miplevel, int layer)
bool set_color_attachment_clear_color(uint slot, const float clear_color[4])
MTLFrameBuffer(MTLContext *ctx, const char *name)
bool set_depth_attachment_clear_value(float depth_clear)
void update_attachments(bool update_viewport)
MTLAttachment get_stencil_attachment()
MTLRenderPassDescriptor * bake_render_pass_descriptor(bool load_contents)
bool has_color_attachment_with_texture(gpu::MTLTexture *texture)
void clear_multi(const float(*clear_cols)[4]) override
bool set_stencil_loadstore_op(eGPULoadOp load_action, eGPUStoreOp store_action)
bool set_color_loadstore_op(uint slot, eGPULoadOp load_action, eGPUStoreOp store_action)
bool add_depth_attachment(gpu::MTLTexture *texture, int miplevel, int layer)
void attachment_set_loadstore_op(GPUAttachmentType type, eGPULoadOp load_action, eGPUStoreOp store_action) override
bool set_stencil_attachment_clear_value(uint stencil_clear)
bool add_stencil_attachment(gpu::MTLTexture *texture, int miplevel, int layer)
bool has_attachment_at_slot(uint slot)
void clear_attachment(GPUAttachmentType type, eGPUDataFormat data_format, const void *clear_value) override
void clear(eGPUFrameBufferBits buffers, const float clear_col[4], float clear_depth, uint clear_stencil) override
void bind(bool enabled_srgb) override
#define GPU_FB_MAX_COLOR_ATTACHMENT
format
Definition: logImageCore.h:38
#define MTL_FB_CONFIG_MAX
static void area(int d1, int d2, int e1, int e2, float weights[2])
union blender::gpu::MTLAttachment::@685 clear_value