Blender  V3.3
mtl_state.mm
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include "BLI_math_base.h"
8 #include "BLI_math_bits.h"
9 
10 #include "GPU_framebuffer.h"
11 
12 #include "mtl_context.hh"
13 #include "mtl_framebuffer.hh"
14 #include "mtl_state.hh"
15 
16 namespace blender::gpu {
17 
18 /* -------------------------------------------------------------------- */
22 void MTLStateManager::mtl_state_init()
23 {
24  BLI_assert(context_);
25  context_->pipeline_state_init();
26 }
27 
29 {
30  /* Initialize State. */
31  context_ = ctx;
32  mtl_state_init();
33 
34  /* Force update using default state. */
35  current_ = ~state;
36  current_mutable_ = ~mutable_state;
37  set_state(state);
38  set_mutable_state(mutable_state);
39 }
40 
42 {
43  this->set_state(this->state);
44  this->set_mutable_state(this->mutable_state);
45 
46  /* Apply active FrameBuffer state. */
47  static_cast<MTLFrameBuffer *>(context_->active_fb)->apply_state();
48 };
49 
51 {
52  /* Little exception for clip distances since they need to keep the old count correct. */
53  uint32_t clip_distances = current_.clip_distances;
54  current_ = ~this->state;
55  current_.clip_distances = clip_distances;
56  current_mutable_ = ~this->mutable_state;
57  this->set_state(this->state);
58  this->set_mutable_state(this->mutable_state);
59 };
60 
61 void MTLStateManager::set_state(const GPUState &state)
62 {
63  GPUState changed = state ^ current_;
64 
65  if (changed.blend != 0) {
66  set_blend((eGPUBlend)state.blend);
67  }
68  if (changed.write_mask != 0) {
69  set_write_mask((eGPUWriteMask)state.write_mask);
70  }
71  if (changed.depth_test != 0) {
72  set_depth_test((eGPUDepthTest)state.depth_test);
73  }
74  if (changed.stencil_test != 0 || changed.stencil_op != 0) {
76  set_stencil_mask((eGPUStencilTest)state.stencil_test, mutable_state);
77  }
78  if (changed.clip_distances != 0) {
79  set_clip_distances(state.clip_distances, current_.clip_distances);
80  }
81  if (changed.culling_test != 0) {
82  set_backface_culling((eGPUFaceCullTest)state.culling_test);
83  }
84  if (changed.logic_op_xor != 0) {
85  set_logic_op(state.logic_op_xor);
86  }
87  if (changed.invert_facing != 0) {
88  set_facing(state.invert_facing);
89  }
90  if (changed.provoking_vert != 0) {
91  set_provoking_vert((eGPUProvokingVertex)state.provoking_vert);
92  }
93  if (changed.shadow_bias != 0) {
94  set_shadow_bias(state.shadow_bias);
95  }
96 
97  /* TODO remove (Following GLState). */
98  if (changed.polygon_smooth) {
99  /* NOTE: Unsupported in Metal. */
100  }
101  if (changed.line_smooth) {
102  /* NOTE: Unsupported in Metal. */
103  }
104 
105  current_ = state;
106 }
107 
108 void MTLStateManager::mtl_depth_range(float near, float far)
109 {
110  BLI_assert(context_);
111  BLI_assert(near >= 0.0 && near < 1.0);
112  BLI_assert(far > 0.0 && far <= 1.0);
113  MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
114  MTLContextDepthStencilState &ds_state = pipeline_state.depth_stencil_state;
115 
116  ds_state.depth_range_near = near;
117  ds_state.depth_range_far = far;
118  pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_VIEWPORT_FLAG;
119 }
120 
121 void MTLStateManager::set_mutable_state(const GPUStateMutable &state)
122 {
123  GPUStateMutable changed = state ^ current_mutable_;
124  MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
125 
126  if (float_as_uint(changed.point_size) != 0) {
127  pipeline_state.point_size = state.point_size;
128  pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_PSO_FLAG;
129  }
130 
131  if (changed.line_width != 0) {
132  pipeline_state.line_width = state.line_width;
133  pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_PSO_FLAG;
134  }
135 
136  if (changed.depth_range[0] != 0 || changed.depth_range[1] != 0) {
137  /* TODO remove, should modify the projection matrix instead. */
138  mtl_depth_range(state.depth_range[0], state.depth_range[1]);
139  }
140 
141  if (changed.stencil_compare_mask != 0 || changed.stencil_reference != 0 ||
142  changed.stencil_write_mask != 0) {
143  set_stencil_mask((eGPUStencilTest)current_.stencil_test, state);
144  }
145 
146  current_mutable_ = state;
147 }
148 
151 /* -------------------------------------------------------------------- */
155 void MTLStateManager::set_write_mask(const eGPUWriteMask value)
156 {
157  BLI_assert(context_);
158  MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
159  pipeline_state.depth_stencil_state.depth_write_enable = ((value & GPU_WRITE_DEPTH) != 0);
160  pipeline_state.color_write_mask =
161  (((value & GPU_WRITE_RED) != 0) ? MTLColorWriteMaskRed : MTLColorWriteMaskNone) |
162  (((value & GPU_WRITE_GREEN) != 0) ? MTLColorWriteMaskGreen : MTLColorWriteMaskNone) |
163  (((value & GPU_WRITE_BLUE) != 0) ? MTLColorWriteMaskBlue : MTLColorWriteMaskNone) |
164  (((value & GPU_WRITE_ALPHA) != 0) ? MTLColorWriteMaskAlpha : MTLColorWriteMaskNone);
165  pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_PSO_FLAG;
166 }
167 
168 static MTLCompareFunction gpu_depth_function_to_metal(eGPUDepthTest depth_func)
169 {
170  switch (depth_func) {
171  case GPU_DEPTH_NONE:
172  return MTLCompareFunctionNever;
173  case GPU_DEPTH_LESS:
174  return MTLCompareFunctionLess;
175  case GPU_DEPTH_EQUAL:
176  return MTLCompareFunctionEqual;
178  return MTLCompareFunctionLessEqual;
179  case GPU_DEPTH_GREATER:
180  return MTLCompareFunctionGreater;
182  return MTLCompareFunctionGreaterEqual;
183  case GPU_DEPTH_ALWAYS:
184  return MTLCompareFunctionAlways;
185  default:
186  BLI_assert(false && "Invalid eGPUDepthTest");
187  break;
188  }
189  return MTLCompareFunctionAlways;
190 }
191 
192 static MTLCompareFunction gpu_stencil_func_to_metal(eGPUStencilTest stencil_func)
193 {
194  switch (stencil_func) {
195  case GPU_STENCIL_NONE:
196  return MTLCompareFunctionAlways;
197  case GPU_STENCIL_EQUAL:
198  return MTLCompareFunctionEqual;
199  case GPU_STENCIL_NEQUAL:
200  return MTLCompareFunctionNotEqual;
201  case GPU_STENCIL_ALWAYS:
202  return MTLCompareFunctionAlways;
203  default:
204  BLI_assert(false && "Unrecognised eGPUStencilTest function");
205  break;
206  }
207  return MTLCompareFunctionAlways;
208 }
209 
210 void MTLStateManager::set_depth_test(const eGPUDepthTest value)
211 {
212  BLI_assert(context_);
213  MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
214  MTLContextDepthStencilState &ds_state = pipeline_state.depth_stencil_state;
215 
216  ds_state.depth_test_enabled = (value != GPU_DEPTH_NONE);
217  ds_state.depth_function = gpu_depth_function_to_metal(value);
218  pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_DEPTHSTENCIL_FLAG;
219 }
220 
221 void MTLStateManager::mtl_stencil_mask(uint mask)
222 {
223  BLI_assert(context_);
224  MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
226  pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_DEPTHSTENCIL_FLAG;
227 }
228 
229 void MTLStateManager::mtl_stencil_set_func(eGPUStencilTest stencil_func, int ref, uint mask)
230 {
231  BLI_assert(context_);
232  MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
233  MTLContextDepthStencilState &ds_state = pipeline_state.depth_stencil_state;
234 
235  ds_state.stencil_func = gpu_stencil_func_to_metal(stencil_func);
236  ds_state.stencil_ref = ref;
237  ds_state.stencil_read_mask = mask;
238  pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_DEPTHSTENCIL_FLAG;
239 }
240 
242  eGPUFaceCullTest face,
243  MTLStencilOperation stencil_fail,
244  MTLStencilOperation depth_test_fail,
245  MTLStencilOperation depthstencil_pass)
246 {
248  MTLContextGlobalShaderPipelineState &pipeline_state = context->pipeline_state;
249  MTLContextDepthStencilState &ds_state = pipeline_state.depth_stencil_state;
250 
251  if (face == GPU_CULL_FRONT) {
252  ds_state.stencil_op_front_stencil_fail = stencil_fail;
253  ds_state.stencil_op_front_depth_fail = depth_test_fail;
254  ds_state.stencil_op_front_depthstencil_pass = depthstencil_pass;
255  }
256  else if (face == GPU_CULL_BACK) {
257  ds_state.stencil_op_back_stencil_fail = stencil_fail;
258  ds_state.stencil_op_back_depth_fail = depth_test_fail;
259  ds_state.stencil_op_back_depthstencil_pass = depthstencil_pass;
260  }
261 
263 }
264 
266  MTLStencilOperation stencil_fail,
267  MTLStencilOperation depth_test_fail,
268  MTLStencilOperation depthstencil_pass)
269 {
271  context, GPU_CULL_FRONT, stencil_fail, depth_test_fail, depthstencil_pass);
273  context, GPU_CULL_BACK, stencil_fail, depth_test_fail, depthstencil_pass);
274 }
275 
276 void MTLStateManager::set_stencil_test(const eGPUStencilTest test, const eGPUStencilOp operation)
277 {
278  switch (operation) {
281  context_, MTLStencilOperationKeep, MTLStencilOperationKeep, MTLStencilOperationReplace);
282  break;
284  /* Winding inversed due to flipped Y coordinate system in Metal. */
287  MTLStencilOperationKeep,
288  MTLStencilOperationKeep,
289  MTLStencilOperationIncrementWrap);
292  MTLStencilOperationKeep,
293  MTLStencilOperationKeep,
294  MTLStencilOperationDecrementWrap);
295  break;
297  /* Winding inversed due to flipped Y coordinate system in Metal. */
300  MTLStencilOperationKeep,
301  MTLStencilOperationDecrementWrap,
302  MTLStencilOperationKeep);
305  MTLStencilOperationKeep,
306  MTLStencilOperationIncrementWrap,
307  MTLStencilOperationKeep);
308  break;
309  case GPU_STENCIL_OP_NONE:
310  default:
312  context_, MTLStencilOperationKeep, MTLStencilOperationKeep, MTLStencilOperationKeep);
313  }
314 
315  BLI_assert(context_);
316  MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
317  pipeline_state.depth_stencil_state.stencil_test_enabled = (test != GPU_STENCIL_NONE);
318  pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_DEPTHSTENCIL_FLAG;
319 }
320 
321 void MTLStateManager::set_stencil_mask(const eGPUStencilTest test, const GPUStateMutable state)
322 {
323  if (test == GPU_STENCIL_NONE) {
324  mtl_stencil_mask(0x00);
325  mtl_stencil_set_func(GPU_STENCIL_ALWAYS, 0x00, 0x00);
326  }
327  else {
328  mtl_stencil_mask(state.stencil_write_mask);
329  mtl_stencil_set_func(test, state.stencil_reference, state.stencil_compare_mask);
330  }
331 }
332 
333 void MTLStateManager::set_clip_distances(const int new_dist_len, const int old_dist_len)
334 {
335  /* TODO(Metal): Support Clip distances in METAL. Clip distance
336  * assignment via shader is supported, but global clip-states require
337  * support. */
338 }
339 
340 void MTLStateManager::set_logic_op(const bool enable)
341 {
342  /* NOTE(Metal): Logic Operations not directly supported. */
343 }
344 
345 void MTLStateManager::set_facing(const bool invert)
346 {
347  /* Check Current Context. */
348  BLI_assert(context_);
349  MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
350 
351  /* Apply State -- opposite of GL, as METAL default is GPU_CLOCKWISE, GL default is
352  * COUNTERCLOCKWISE. This needs to be the inverse of the default. */
353  pipeline_state.front_face = (invert) ? GPU_COUNTERCLOCKWISE : GPU_CLOCKWISE;
354 
355  /* Mark Dirty - Ensure context updates state between draws. */
356  pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_FRONT_FACING_FLAG;
357  pipeline_state.dirty = true;
358 }
359 
360 void MTLStateManager::set_backface_culling(const eGPUFaceCullTest test)
361 {
362  /* Check Current Context. */
363  BLI_assert(context_);
364  MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
365 
366  /* Apply State. */
367  pipeline_state.culling_enabled = (test != GPU_CULL_NONE);
368  pipeline_state.cull_mode = test;
369 
370  /* Mark Dirty - Ensure context updates state between draws. */
371  pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_CULLMODE_FLAG;
372  pipeline_state.dirty = true;
373 }
374 
375 void MTLStateManager::set_provoking_vert(const eGPUProvokingVertex vert)
376 {
377  /* NOTE(Metal): Provoking vertex is not a feature in the Metal API.
378  * Shaders are handled on a case-by-case basis using a modified vertex shader.
379  * For example, wireframe rendering and edit-mesh shaders utilize an SSBO-based
380  * vertex fetching mechanism which considers the inverse convention for flat
381  * shading, to ensure consistent results with OpenGL. */
382 }
383 
384 void MTLStateManager::set_shadow_bias(const bool enable)
385 {
386  /* Check Current Context. */
387  BLI_assert(context_);
388  MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
389  MTLContextDepthStencilState &ds_state = pipeline_state.depth_stencil_state;
390 
391  /* Apply State. */
392  if (enable) {
393  ds_state.depth_bias_enabled_for_lines = true;
394  ds_state.depth_bias_enabled_for_tris = true;
395  ds_state.depth_bias = 2.0f;
396  ds_state.depth_slope_scale = 1.0f;
397  }
398  else {
399  ds_state.depth_bias_enabled_for_lines = false;
400  ds_state.depth_bias_enabled_for_tris = false;
401  ds_state.depth_bias = 0.0f;
402  ds_state.depth_slope_scale = 0.0f;
403  }
404 
405  /* Mark Dirty - Ensure context updates depth-stencil state between draws. */
406  pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_DEPTHSTENCIL_FLAG;
407  pipeline_state.dirty = true;
408 }
409 
410 void MTLStateManager::set_blend(const eGPUBlend value)
411 {
419  MTLBlendFactor src_rgb;
420  MTLBlendFactor dst_rgb;
421  MTLBlendFactor src_alpha;
422  MTLBlendFactor dst_alpha;
423  switch (value) {
424  default:
425  case GPU_BLEND_ALPHA: {
426  src_rgb = MTLBlendFactorSourceAlpha;
427  dst_rgb = MTLBlendFactorOneMinusSourceAlpha;
428  src_alpha = MTLBlendFactorOne;
429  dst_alpha = MTLBlendFactorOneMinusSourceAlpha;
430  break;
431  }
433  src_rgb = MTLBlendFactorOne;
434  dst_rgb = MTLBlendFactorOneMinusSourceAlpha;
435  src_alpha = MTLBlendFactorOne;
436  dst_alpha = MTLBlendFactorOneMinusSourceAlpha;
437  break;
438  }
439  case GPU_BLEND_ADDITIVE: {
440  /* Do not let alpha accumulate but pre-multiply the source RGB by it. */
441  src_rgb = MTLBlendFactorSourceAlpha;
442  dst_rgb = MTLBlendFactorOne;
443  src_alpha = MTLBlendFactorZero;
444  dst_alpha = MTLBlendFactorOne;
445  break;
446  }
447  case GPU_BLEND_SUBTRACT:
449  /* Let alpha accumulate. */
450  src_rgb = MTLBlendFactorOne;
451  dst_rgb = MTLBlendFactorOne;
452  src_alpha = MTLBlendFactorOne;
453  dst_alpha = MTLBlendFactorOne;
454  break;
455  }
456  case GPU_BLEND_MULTIPLY: {
457  src_rgb = MTLBlendFactorDestinationColor;
458  dst_rgb = MTLBlendFactorZero;
459  src_alpha = MTLBlendFactorDestinationAlpha;
460  dst_alpha = MTLBlendFactorZero;
461  break;
462  }
463  case GPU_BLEND_INVERT: {
464  src_rgb = MTLBlendFactorOneMinusDestinationColor;
465  dst_rgb = MTLBlendFactorZero;
466  src_alpha = MTLBlendFactorZero;
467  dst_alpha = MTLBlendFactorOne;
468  break;
469  }
470  case GPU_BLEND_OIT: {
471  src_rgb = MTLBlendFactorOne;
472  dst_rgb = MTLBlendFactorOne;
473  src_alpha = MTLBlendFactorZero;
474  dst_alpha = MTLBlendFactorOneMinusSourceAlpha;
475  break;
476  }
477  case GPU_BLEND_BACKGROUND: {
478  src_rgb = MTLBlendFactorOneMinusDestinationAlpha;
479  dst_rgb = MTLBlendFactorSourceAlpha;
480  src_alpha = MTLBlendFactorZero;
481  dst_alpha = MTLBlendFactorSourceAlpha;
482  break;
483  }
485  src_rgb = MTLBlendFactorOneMinusDestinationAlpha;
486  dst_rgb = MTLBlendFactorOne;
487  src_alpha = MTLBlendFactorOneMinusDestinationAlpha;
488  dst_alpha = MTLBlendFactorOne;
489  break;
490  }
491  case GPU_BLEND_CUSTOM: {
492  src_rgb = MTLBlendFactorOne;
493  dst_rgb = MTLBlendFactorSource1Color;
494  src_alpha = MTLBlendFactorOne;
495  dst_alpha = MTLBlendFactorSource1Alpha;
496  break;
497  }
498  }
499 
500  /* Check Current Context. */
501  BLI_assert(context_);
502  MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
503 
504  if (value == GPU_BLEND_SUBTRACT) {
505  pipeline_state.rgb_blend_op = MTLBlendOperationReverseSubtract;
506  pipeline_state.alpha_blend_op = MTLBlendOperationReverseSubtract;
507  }
508  else {
509  pipeline_state.rgb_blend_op = MTLBlendOperationAdd;
510  pipeline_state.alpha_blend_op = MTLBlendOperationAdd;
511  }
512 
513  /* Apply State. */
514  pipeline_state.blending_enabled = (value != GPU_BLEND_NONE);
515  pipeline_state.src_rgb_blend_factor = src_rgb;
516  pipeline_state.dest_rgb_blend_factor = dst_rgb;
517  pipeline_state.src_alpha_blend_factor = src_alpha;
518  pipeline_state.dest_alpha_blend_factor = dst_alpha;
519 
520  /* Mark Dirty - Ensure context updates PSOs between draws. */
521  pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_PSO_FLAG;
522  pipeline_state.dirty = true;
523 }
524 
527 /* -------------------------------------------------------------------- */
531 /* NOTE(Metal): Granular option for specifying before/after stages for a barrier
532  * Would be a useful feature. */
533 #if 0
535  eGPUStageBarrierBits before_stages,
536  eGPUStageBarrierBits after_stages)
537 #endif
539 {
540  /* NOTE(Metal): The Metal API implicitly tracks dependencies between resources.
541  * Memory barriers and execution barriers (Fences/Events) can be used to coordinate
542  * this explicitly, however, in most cases, the driver will be able to
543  * resolve these dependencies automatically.
544  * For untracked resources, such as MTLHeap's, explicit barriers are necessary. */
547 
548  MTLContext *ctx = reinterpret_cast<MTLContext *>(GPU_context_active_get());
549  BLI_assert(ctx);
550 
551  /* Apple Silicon does not support memory barriers.
552  * We do not currently need these due to implicit API guarantees.
553  * NOTE(Metal): MTLFence/MTLEvent may be required to synchronize work if
554  * untracked resources are ever used. */
555  if ([ctx->device hasUnifiedMemory]) {
556  return;
557  }
558 
559  ctx->main_command_buffer.insert_memory_barrier(barrier_bits, before_stages, after_stages);
560 }
561 
564 /* -------------------------------------------------------------------- */
569 {
570  /* Set source image row data stride when uploading image data to the GPU. */
571  MTLContext *ctx = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
573 }
574 
575 void MTLStateManager::texture_bind(Texture *tex_, eGPUSamplerState sampler_type, int unit)
576 {
577  BLI_assert(tex_);
578  gpu::MTLTexture *mtl_tex = static_cast<gpu::MTLTexture *>(tex_);
579  BLI_assert(mtl_tex);
580 
581  MTLContext *ctx = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
582  if (unit >= 0) {
583  ctx->texture_bind(mtl_tex, unit);
584 
585  /* Fetching textures default sampler configuration and applying
586  * eGPUSampler State on top. This path exists to support
587  * Any of the sampler state which is associated with the
588  * texture itself such as min/max mip levels. */
589  MTLSamplerState sampler = mtl_tex->get_sampler_state();
590  sampler.state = sampler_type;
591 
592  ctx->sampler_bind(sampler, unit);
593  }
594 }
595 
597 {
598  BLI_assert(tex_);
599  gpu::MTLTexture *mtl_tex = static_cast<gpu::MTLTexture *>(tex_);
600  BLI_assert(mtl_tex);
601  MTLContext *ctx = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
602  ctx->texture_unbind(mtl_tex);
603 }
604 
606 {
607  MTLContext *ctx = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
608  BLI_assert(ctx);
609  ctx->texture_unbind_all();
610 }
611 
614 /* -------------------------------------------------------------------- */
619 {
620  this->texture_bind(tex_, GPU_SAMPLER_DEFAULT, unit);
621 }
622 
624 {
625  this->texture_unbind(tex_);
626 }
627 
629 {
630  this->texture_unbind_all();
631 }
632 
635 } // blender::gpu
#define BLI_assert(a)
Definition: BLI_assert.h:46
MINLINE unsigned int float_as_uint(float f)
unsigned int uint
Definition: BLI_sys_types.h:67
@ GPU_COUNTERCLOCKWISE
@ GPU_CLOCKWISE
GPUContext * GPU_context_active_get(void)
Definition: gpu_context.cc:142
eGPUBlend
Definition: GPU_state.h:59
@ GPU_BLEND_ADDITIVE_PREMULT
Definition: GPU_state.h:65
@ GPU_BLEND_INVERT
Definition: GPU_state.h:70
@ GPU_BLEND_OIT
Definition: GPU_state.h:73
@ GPU_BLEND_MULTIPLY
Definition: GPU_state.h:66
@ GPU_BLEND_NONE
Definition: GPU_state.h:60
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:62
@ GPU_BLEND_CUSTOM
Definition: GPU_state.h:78
@ GPU_BLEND_ADDITIVE
Definition: GPU_state.h:64
@ GPU_BLEND_SUBTRACT
Definition: GPU_state.h:67
@ GPU_BLEND_ALPHA_UNDER_PREMUL
Definition: GPU_state.h:79
@ GPU_BLEND_BACKGROUND
Definition: GPU_state.h:75
@ GPU_BLEND_ALPHA_PREMULT
Definition: GPU_state.h:63
eGPUWriteMask
Definition: GPU_state.h:11
@ GPU_WRITE_RED
Definition: GPU_state.h:13
@ GPU_WRITE_GREEN
Definition: GPU_state.h:14
@ GPU_WRITE_BLUE
Definition: GPU_state.h:15
@ GPU_WRITE_DEPTH
Definition: GPU_state.h:17
@ GPU_WRITE_ALPHA
Definition: GPU_state.h:16
eGPUProvokingVertex
Definition: GPU_state.h:113
eGPUStageBarrierBits
Definition: GPU_state.h:40
@ GPU_BARRIER_STAGE_ANY
Definition: GPU_state.h:45
eGPUFaceCullTest
Definition: GPU_state.h:107
@ GPU_CULL_FRONT
Definition: GPU_state.h:109
@ GPU_CULL_NONE
Definition: GPU_state.h:108
@ GPU_CULL_BACK
Definition: GPU_state.h:110
eGPUBarrier
Definition: GPU_state.h:24
eGPUStencilOp
Definition: GPU_state.h:99
@ GPU_STENCIL_OP_COUNT_DEPTH_FAIL
Definition: GPU_state.h:104
@ GPU_STENCIL_OP_COUNT_DEPTH_PASS
Definition: GPU_state.h:103
@ GPU_STENCIL_OP_REPLACE
Definition: GPU_state.h:101
@ GPU_STENCIL_OP_NONE
Definition: GPU_state.h:100
eGPUDepthTest
Definition: GPU_state.h:82
@ GPU_DEPTH_GREATER
Definition: GPU_state.h:88
@ GPU_DEPTH_EQUAL
Definition: GPU_state.h:87
@ GPU_DEPTH_ALWAYS
Definition: GPU_state.h:84
@ GPU_DEPTH_GREATER_EQUAL
Definition: GPU_state.h:89
@ GPU_DEPTH_LESS
Definition: GPU_state.h:85
@ GPU_DEPTH_LESS_EQUAL
Definition: GPU_state.h:86
@ GPU_DEPTH_NONE
Definition: GPU_state.h:83
eGPUStencilTest
Definition: GPU_state.h:92
@ GPU_STENCIL_EQUAL
Definition: GPU_state.h:95
@ GPU_STENCIL_NEQUAL
Definition: GPU_state.h:96
@ GPU_STENCIL_ALWAYS
Definition: GPU_state.h:94
@ GPU_STENCIL_NONE
Definition: GPU_state.h:93
eGPUSamplerState
Definition: GPU_texture.h:25
@ GPU_SAMPLER_DEFAULT
Definition: GPU_texture.h:26
bool insert_memory_barrier(eGPUBarrier barrier_bits, eGPUStageBarrierBits before_stages, eGPUStageBarrierBits after_stages)
void texture_bind(gpu::MTLTexture *mtl_texture, uint texture_unit)
Definition: mtl_context.mm:418
MTLContextGlobalShaderPipelineState pipeline_state
Definition: mtl_context.hh:600
void texture_unbind(gpu::MTLTexture *mtl_texture)
Definition: mtl_context.mm:452
id< MTLDevice > device
Definition: mtl_context.hh:604
void sampler_bind(MTLSamplerState, uint sampler_unit)
Definition: mtl_context.mm:438
MTLCommandBufferManager main_command_buffer
Definition: mtl_context.hh:611
void image_unbind_all() override
Definition: mtl_state.mm:628
void texture_unbind(Texture *tex) override
Definition: mtl_state.mm:596
void image_unbind(Texture *tex) override
Definition: mtl_state.mm:623
void force_state() override
Definition: mtl_state.mm:50
void image_bind(Texture *tex, int unit) override
Definition: mtl_state.mm:618
void texture_bind(Texture *tex, eGPUSamplerState sampler, int unit) override
Definition: mtl_state.mm:575
void texture_unpack_row_length_set(uint len) override
Definition: mtl_state.mm:568
void apply_state() override
Definition: mtl_state.mm:41
MTLStateManager(MTLContext *ctx)
Definition: mtl_state.mm:28
void issue_barrier(eGPUBarrier barrier_bits) override
Definition: mtl_state.mm:538
void texture_unbind_all() override
Definition: mtl_state.mm:605
int len
Definition: draw_manager.c:108
depth_tx sampler(1, ImageType::FLOAT_2D, "combined_tx") .sampler(2
CCL_NAMESPACE_BEGIN ccl_device float invert(float color, float factor)
Definition: invert.h:8
const int state
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
static void mtl_stencil_set_op(MTLContext *context, MTLStencilOperation stencil_fail, MTLStencilOperation depth_test_fail, MTLStencilOperation depthstencil_pass)
Definition: mtl_state.mm:265
static MTLCompareFunction gpu_depth_function_to_metal(eGPUDepthTest depth_func)
Definition: mtl_state.mm:168
static Context * unwrap(GPUContext *ctx)
static MTLCompareFunction gpu_stencil_func_to_metal(eGPUStencilTest stencil_func)
Definition: mtl_state.mm:192
@ MTL_PIPELINE_STATE_CULLMODE_FLAG
Definition: mtl_context.hh:369
@ MTL_PIPELINE_STATE_PSO_FLAG
Definition: mtl_context.hh:365
@ MTL_PIPELINE_STATE_FRONT_FACING_FLAG
Definition: mtl_context.hh:367
@ MTL_PIPELINE_STATE_DEPTHSTENCIL_FLAG
Definition: mtl_context.hh:363
@ MTL_PIPELINE_STATE_VIEWPORT_FLAG
Definition: mtl_context.hh:359
static void mtl_stencil_set_op_separate(MTLContext *context, eGPUFaceCullTest face, MTLStencilOperation stencil_fail, MTLStencilOperation depth_test_fail, MTLStencilOperation depthstencil_pass)
Definition: mtl_state.mm:241
unsigned int uint32_t
Definition: stdint.h:80
MTLStencilOperation stencil_op_back_depthstencil_pass
Definition: mtl_context.hh:170
MTLStencilOperation stencil_op_back_stencil_fail
Definition: mtl_context.hh:168
MTLStencilOperation stencil_op_front_stencil_fail
Definition: mtl_context.hh:164
MTLStencilOperation stencil_op_front_depthstencil_pass
Definition: mtl_context.hh:166
MTLStencilOperation stencil_op_front_depth_fail
Definition: mtl_context.hh:165
MTLStencilOperation stencil_op_back_depth_fail
Definition: mtl_context.hh:169
MTLContextDepthStencilState depth_stencil_state
Definition: mtl_context.hh:432