Blender V4.3
mtl_state.mm
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2022-2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "BLI_math_base.h"
10#include "BLI_math_bits.h"
11
12#include "GPU_framebuffer.hh"
13
14#include "mtl_context.hh"
15#include "mtl_framebuffer.hh"
17#include "mtl_state.hh"
18
19namespace blender::gpu {
20
21/* -------------------------------------------------------------------- */
25void MTLStateManager::mtl_state_init()
26{
27 BLI_assert(context_);
28 context_->pipeline_state_init();
29}
30
32{
33 /* Initialize State. */
34 context_ = ctx;
35 mtl_state_init();
36
37 /* Force update using default state. */
38 current_ = ~state;
39 current_mutable_ = ~mutable_state;
40
41 /* Clip distances initial mask forces to 0x111, which exceeds
42 * max clip plane count of 6, so limit to ensure all clipping
43 * planes get disabled. */
44 current_.clip_distances = 6;
45
46 set_state(state);
47 set_mutable_state(mutable_state);
48}
49
51{
52 this->set_state(this->state);
53 this->set_mutable_state(this->mutable_state);
54
55 /* Apply active FrameBuffer state. */
56 static_cast<MTLFrameBuffer *>(context_->active_fb)->apply_state();
57};
58
60{
61 /* Little exception for clip distances since they need to keep the old count correct. */
62 uint32_t clip_distances = current_.clip_distances;
63 BLI_assert(clip_distances <= 6);
64 current_ = ~this->state;
65 current_.clip_distances = clip_distances;
66 current_mutable_ = ~this->mutable_state;
67 this->set_state(this->state);
68 this->set_mutable_state(this->mutable_state);
69};
70
71void MTLStateManager::set_state(const GPUState &state)
72{
73 GPUState changed = state ^ current_;
74
75 if (changed.blend != 0) {
76 set_blend((eGPUBlend)state.blend);
77 }
78 if (changed.write_mask != 0) {
79 set_write_mask((eGPUWriteMask)state.write_mask);
80 }
81 if (changed.depth_test != 0) {
82 set_depth_test((eGPUDepthTest)state.depth_test);
83 }
84 if (changed.stencil_test != 0 || changed.stencil_op != 0) {
87 }
88 if (changed.clip_distances != 0) {
89 set_clip_distances(state.clip_distances, current_.clip_distances);
90 }
91 if (changed.culling_test != 0) {
92 set_backface_culling((eGPUFaceCullTest)state.culling_test);
93 }
94 if (changed.logic_op_xor != 0) {
95 set_logic_op(state.logic_op_xor);
96 }
97 if (changed.invert_facing != 0) {
98 set_facing(state.invert_facing);
99 }
100 if (changed.provoking_vert != 0) {
101 set_provoking_vert((eGPUProvokingVertex)state.provoking_vert);
102 }
103 if (changed.shadow_bias != 0) {
104 set_shadow_bias(state.shadow_bias);
105 }
106
107 /* TODO remove (Following GLState). */
108 if (changed.polygon_smooth) {
109 /* NOTE: Unsupported in Metal. */
110 }
111 if (changed.line_smooth) {
112 /* NOTE: Unsupported in Metal. */
113 }
114
115 current_ = state;
116}
117
118void MTLStateManager::mtl_depth_range(float near, float far)
119{
120 BLI_assert(context_);
121 BLI_assert(near >= 0.0 && near < 1.0);
122 BLI_assert(far > 0.0 && far <= 1.0);
123 MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
124 MTLContextDepthStencilState &ds_state = pipeline_state.depth_stencil_state;
125
126 ds_state.depth_range_near = near;
127 ds_state.depth_range_far = far;
128 pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_VIEWPORT_FLAG;
129}
130
131void MTLStateManager::set_mutable_state(const GPUStateMutable &state)
132{
133 GPUStateMutable changed = state ^ current_mutable_;
134 MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
135
136 if (float_as_uint(changed.point_size) != 0) {
137 pipeline_state.point_size = state.point_size;
138 pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_PSO_FLAG;
139 }
140
141 if (changed.line_width != 0) {
142 pipeline_state.line_width = state.line_width;
143 pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_PSO_FLAG;
144 }
145
146 if (float_as_uint(changed.depth_range[0]) != 0 || float_as_uint(changed.depth_range[1]) != 0) {
147 /* TODO remove, should modify the projection matrix instead. */
148 mtl_depth_range(state.depth_range[0], state.depth_range[1]);
149 }
150
151 if (changed.stencil_compare_mask != 0 || changed.stencil_reference != 0 ||
152 changed.stencil_write_mask != 0)
153 {
154 set_stencil_mask((eGPUStencilTest)current_.stencil_test, state);
155 }
156
157 current_mutable_ = state;
158}
159
162/* -------------------------------------------------------------------- */
166void MTLStateManager::set_write_mask(const eGPUWriteMask value)
167{
168 BLI_assert(context_);
169 MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
170 pipeline_state.depth_stencil_state.depth_write_enable = ((value & GPU_WRITE_DEPTH) != 0);
171 pipeline_state.color_write_mask =
172 (((value & GPU_WRITE_RED) != 0) ? MTLColorWriteMaskRed : MTLColorWriteMaskNone) |
173 (((value & GPU_WRITE_GREEN) != 0) ? MTLColorWriteMaskGreen : MTLColorWriteMaskNone) |
174 (((value & GPU_WRITE_BLUE) != 0) ? MTLColorWriteMaskBlue : MTLColorWriteMaskNone) |
175 (((value & GPU_WRITE_ALPHA) != 0) ? MTLColorWriteMaskAlpha : MTLColorWriteMaskNone);
176 pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_PSO_FLAG;
177}
178
179static MTLCompareFunction gpu_depth_function_to_metal(eGPUDepthTest depth_func)
180{
181 switch (depth_func) {
182 case GPU_DEPTH_NONE:
183 return MTLCompareFunctionNever;
184 case GPU_DEPTH_LESS:
185 return MTLCompareFunctionLess;
186 case GPU_DEPTH_EQUAL:
187 return MTLCompareFunctionEqual;
189 return MTLCompareFunctionLessEqual;
191 return MTLCompareFunctionGreater;
193 return MTLCompareFunctionGreaterEqual;
194 case GPU_DEPTH_ALWAYS:
195 return MTLCompareFunctionAlways;
196 default:
197 BLI_assert(false && "Invalid eGPUDepthTest");
198 break;
199 }
200 return MTLCompareFunctionAlways;
201}
202
203static MTLCompareFunction gpu_stencil_func_to_metal(eGPUStencilTest stencil_func)
204{
205 switch (stencil_func) {
206 case GPU_STENCIL_NONE:
207 return MTLCompareFunctionAlways;
209 return MTLCompareFunctionEqual;
211 return MTLCompareFunctionNotEqual;
213 return MTLCompareFunctionAlways;
214 default:
215 BLI_assert(false && "Unrecognized eGPUStencilTest function");
216 break;
217 }
218 return MTLCompareFunctionAlways;
219}
220
221void MTLStateManager::set_depth_test(const eGPUDepthTest value)
222{
223 BLI_assert(context_);
224 MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
225 MTLContextDepthStencilState &ds_state = pipeline_state.depth_stencil_state;
226
227 ds_state.depth_test_enabled = (value != GPU_DEPTH_NONE);
228 ds_state.depth_function = gpu_depth_function_to_metal(value);
229 pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_DEPTHSTENCIL_FLAG;
230}
231
232void MTLStateManager::mtl_stencil_mask(uint mask)
233{
234 BLI_assert(context_);
235 MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
237 pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_DEPTHSTENCIL_FLAG;
238}
239
240void MTLStateManager::mtl_stencil_set_func(eGPUStencilTest stencil_func, int ref, uint mask)
241{
242 BLI_assert(context_);
243 MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
244 MTLContextDepthStencilState &ds_state = pipeline_state.depth_stencil_state;
245
246 ds_state.stencil_func = gpu_stencil_func_to_metal(stencil_func);
247 ds_state.stencil_ref = ref;
248 ds_state.stencil_read_mask = mask;
249 pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_DEPTHSTENCIL_FLAG;
250}
251
253 eGPUFaceCullTest face,
254 MTLStencilOperation stencil_fail,
255 MTLStencilOperation depth_test_fail,
256 MTLStencilOperation depthstencil_pass)
257{
258 BLI_assert(context);
259 MTLContextGlobalShaderPipelineState &pipeline_state = context->pipeline_state;
260 MTLContextDepthStencilState &ds_state = pipeline_state.depth_stencil_state;
261
262 if (face == GPU_CULL_FRONT) {
263 ds_state.stencil_op_front_stencil_fail = stencil_fail;
264 ds_state.stencil_op_front_depth_fail = depth_test_fail;
265 ds_state.stencil_op_front_depthstencil_pass = depthstencil_pass;
266 }
267 else if (face == GPU_CULL_BACK) {
268 ds_state.stencil_op_back_stencil_fail = stencil_fail;
269 ds_state.stencil_op_back_depth_fail = depth_test_fail;
270 ds_state.stencil_op_back_depthstencil_pass = depthstencil_pass;
271 }
272
274}
275
276static void mtl_stencil_set_op(MTLContext *context,
277 MTLStencilOperation stencil_fail,
278 MTLStencilOperation depth_test_fail,
279 MTLStencilOperation depthstencil_pass)
280{
282 context, GPU_CULL_FRONT, stencil_fail, depth_test_fail, depthstencil_pass);
284 context, GPU_CULL_BACK, stencil_fail, depth_test_fail, depthstencil_pass);
285}
286
287void MTLStateManager::set_stencil_test(const eGPUStencilTest test, const eGPUStencilOp operation)
288{
289 switch (operation) {
292 context_, MTLStencilOperationKeep, MTLStencilOperationKeep, MTLStencilOperationReplace);
293 break;
297 MTLStencilOperationKeep,
298 MTLStencilOperationKeep,
299 MTLStencilOperationIncrementWrap);
302 MTLStencilOperationKeep,
303 MTLStencilOperationKeep,
304 MTLStencilOperationDecrementWrap);
305 break;
309 MTLStencilOperationKeep,
310 MTLStencilOperationDecrementWrap,
311 MTLStencilOperationKeep);
314 MTLStencilOperationKeep,
315 MTLStencilOperationIncrementWrap,
316 MTLStencilOperationKeep);
317 break;
319 default:
321 context_, MTLStencilOperationKeep, MTLStencilOperationKeep, MTLStencilOperationKeep);
322 }
323
324 BLI_assert(context_);
325 MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
327 pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_DEPTHSTENCIL_FLAG;
328}
329
330void MTLStateManager::set_stencil_mask(const eGPUStencilTest test, const GPUStateMutable &state)
331{
332 if (test == GPU_STENCIL_NONE) {
333 mtl_stencil_mask(0x00);
334 mtl_stencil_set_func(GPU_STENCIL_ALWAYS, 0x00, 0x00);
335 }
336 else {
337 mtl_stencil_mask(state.stencil_write_mask);
338 mtl_stencil_set_func(test, state.stencil_reference, state.stencil_compare_mask);
339 }
340}
341
342void MTLStateManager::mtl_clip_plane_enable(uint i)
343{
344 BLI_assert(context_);
345 MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
346 pipeline_state.clip_distance_enabled[i] = true;
347 pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_PSO_FLAG;
348}
349
350void MTLStateManager::mtl_clip_plane_disable(uint i)
351{
352 BLI_assert(context_);
353 MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
354 pipeline_state.clip_distance_enabled[i] = false;
355 pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_PSO_FLAG;
356}
357
358void MTLStateManager::set_clip_distances(const int new_dist_len, const int old_dist_len)
359{
360 BLI_assert(new_dist_len <= 6);
361 BLI_assert(old_dist_len <= 6);
362 for (uint i = 0; i < new_dist_len; i++) {
363 mtl_clip_plane_enable(i);
364 }
365 for (uint i = new_dist_len; i < old_dist_len; i++) {
366 mtl_clip_plane_disable(i);
367 }
368}
369
370void MTLStateManager::set_logic_op(const bool /*enable*/)
371{
372 /* NOTE(Metal): Logic Operations not directly supported. */
373}
374
375void MTLStateManager::set_facing(const bool invert)
376{
377 /* Check Current Context. */
378 BLI_assert(context_);
379 MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
380
381 /* Apply State -- opposite of GL, as METAL default is GPU_CLOCKWISE, GL default is
382 * COUNTERCLOCKWISE. This needs to be the inverse of the default. */
384
385 /* Mark Dirty - Ensure context updates state between draws. */
386 pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_FRONT_FACING_FLAG;
387 pipeline_state.dirty = true;
388}
389
390void MTLStateManager::set_backface_culling(const eGPUFaceCullTest test)
391{
392 /* Check Current Context. */
393 BLI_assert(context_);
394 MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
395
396 /* Apply State. */
397 pipeline_state.culling_enabled = (test != GPU_CULL_NONE);
398 pipeline_state.cull_mode = test;
399
400 /* Mark Dirty - Ensure context updates state between draws. */
401 pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_CULLMODE_FLAG;
402 pipeline_state.dirty = true;
403}
404
405void MTLStateManager::set_provoking_vert(const eGPUProvokingVertex /*vert*/)
406{
407 /* NOTE(Metal): Provoking vertex is not a feature in the Metal API.
408 * Shaders are handled on a case-by-case basis using a modified vertex shader.
409 * For example, wireframe rendering and edit-mesh shaders utilize an SSBO-based
410 * vertex fetching mechanism which considers the inverse convention for flat
411 * shading, to ensure consistent results with OpenGL. */
412}
413
414void MTLStateManager::set_shadow_bias(const bool enable)
415{
416 /* Check Current Context. */
417 BLI_assert(context_);
418 MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
419 MTLContextDepthStencilState &ds_state = pipeline_state.depth_stencil_state;
420
421 /* Apply State. */
422 if (enable) {
423 ds_state.depth_bias_enabled_for_lines = true;
424 ds_state.depth_bias_enabled_for_tris = true;
425 ds_state.depth_bias = 2.0f;
426 ds_state.depth_slope_scale = 1.0f;
427 }
428 else {
429 ds_state.depth_bias_enabled_for_lines = false;
430 ds_state.depth_bias_enabled_for_tris = false;
431 ds_state.depth_bias = 0.0f;
432 ds_state.depth_slope_scale = 0.0f;
433 }
434
435 /* Mark Dirty - Ensure context updates depth-stencil state between draws. */
436 pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_DEPTHSTENCIL_FLAG;
437 pipeline_state.dirty = true;
438}
439
440void MTLStateManager::set_blend(const eGPUBlend value)
441{
449 MTLBlendFactor src_rgb;
450 MTLBlendFactor dst_rgb;
451 MTLBlendFactor src_alpha;
452 MTLBlendFactor dst_alpha;
453 switch (value) {
454 default:
455 case GPU_BLEND_ALPHA: {
456 src_rgb = MTLBlendFactorSourceAlpha;
457 dst_rgb = MTLBlendFactorOneMinusSourceAlpha;
458 src_alpha = MTLBlendFactorOne;
459 dst_alpha = MTLBlendFactorOneMinusSourceAlpha;
460 break;
461 }
463 src_rgb = MTLBlendFactorOne;
464 dst_rgb = MTLBlendFactorOneMinusSourceAlpha;
465 src_alpha = MTLBlendFactorOne;
466 dst_alpha = MTLBlendFactorOneMinusSourceAlpha;
467 break;
468 }
469 case GPU_BLEND_ADDITIVE: {
470 /* Do not let alpha accumulate but pre-multiply the source RGB by it. */
471 src_rgb = MTLBlendFactorSourceAlpha;
472 dst_rgb = MTLBlendFactorOne;
473 src_alpha = MTLBlendFactorZero;
474 dst_alpha = MTLBlendFactorOne;
475 break;
476 }
479 /* Let alpha accumulate. */
480 src_rgb = MTLBlendFactorOne;
481 dst_rgb = MTLBlendFactorOne;
482 src_alpha = MTLBlendFactorOne;
483 dst_alpha = MTLBlendFactorOne;
484 break;
485 }
486 case GPU_BLEND_MULTIPLY: {
487 src_rgb = MTLBlendFactorDestinationColor;
488 dst_rgb = MTLBlendFactorZero;
489 src_alpha = MTLBlendFactorDestinationAlpha;
490 dst_alpha = MTLBlendFactorZero;
491 break;
492 }
493 case GPU_BLEND_INVERT: {
494 src_rgb = MTLBlendFactorOneMinusDestinationColor;
495 dst_rgb = MTLBlendFactorZero;
496 src_alpha = MTLBlendFactorZero;
497 dst_alpha = MTLBlendFactorOne;
498 break;
499 }
500 case GPU_BLEND_OIT: {
501 src_rgb = MTLBlendFactorOne;
502 dst_rgb = MTLBlendFactorOne;
503 src_alpha = MTLBlendFactorZero;
504 dst_alpha = MTLBlendFactorOneMinusSourceAlpha;
505 break;
506 }
508 src_rgb = MTLBlendFactorOneMinusDestinationAlpha;
509 dst_rgb = MTLBlendFactorSourceAlpha;
510 src_alpha = MTLBlendFactorZero;
511 dst_alpha = MTLBlendFactorSourceAlpha;
512 break;
513 }
515 src_rgb = MTLBlendFactorOneMinusDestinationAlpha;
516 dst_rgb = MTLBlendFactorOne;
517 src_alpha = MTLBlendFactorOneMinusDestinationAlpha;
518 dst_alpha = MTLBlendFactorOne;
519 break;
520 }
521 case GPU_BLEND_CUSTOM: {
522 src_rgb = MTLBlendFactorOne;
523 dst_rgb = MTLBlendFactorSource1Color;
524 src_alpha = MTLBlendFactorOne;
525 dst_alpha = MTLBlendFactorSource1Alpha;
526 break;
527 }
528 }
529
530 /* Check Current Context. */
531 BLI_assert(context_);
532 MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
533
534 if (value == GPU_BLEND_SUBTRACT) {
535 pipeline_state.rgb_blend_op = MTLBlendOperationReverseSubtract;
536 pipeline_state.alpha_blend_op = MTLBlendOperationReverseSubtract;
537 }
538 else {
539 pipeline_state.rgb_blend_op = MTLBlendOperationAdd;
540 pipeline_state.alpha_blend_op = MTLBlendOperationAdd;
541 }
542
543 /* Apply State. */
544 pipeline_state.blending_enabled = (value != GPU_BLEND_NONE);
545 pipeline_state.src_rgb_blend_factor = src_rgb;
546 pipeline_state.dest_rgb_blend_factor = dst_rgb;
547 pipeline_state.src_alpha_blend_factor = src_alpha;
548 pipeline_state.dest_alpha_blend_factor = dst_alpha;
549
550 /* Mark Dirty - Ensure context updates PSOs between draws. */
551 pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_PSO_FLAG;
552 pipeline_state.dirty = true;
553}
554
557/* -------------------------------------------------------------------- */
561/* NOTE(Metal): Granular option for specifying before/after stages for a barrier
562 * Would be a useful feature. */
563#if 0
565 eGPUStageBarrierBits before_stages,
566 eGPUStageBarrierBits after_stages)
567#endif
569{
570 /* NOTE(Metal): The Metal API implicitly tracks dependencies between resources.
571 * Memory barriers and execution barriers (Fences/Events) can be used to coordinate
572 * this explicitly, however, in most cases, the driver will be able to
573 * resolve these dependencies automatically.
574 * For untracked resources, such as MTLHeap's, explicit barriers are necessary. */
577
579 BLI_assert(ctx);
580
581 ctx->main_command_buffer.insert_memory_barrier(barrier_bits, before_stages, after_stages);
582}
583
585{
586 if (mtl_event_) {
587 [mtl_event_ release];
588 mtl_event_ = nil;
589 }
590}
591
593{
594 if (mtl_event_ == nil) {
596 BLI_assert(ctx);
597 mtl_event_ = [ctx->device newEvent];
598 }
600 BLI_assert(ctx);
601 ctx->main_command_buffer.encode_signal_event(mtl_event_, ++last_signalled_value_);
602
603 signalled_ = true;
604}
605
607{
608 /* do not attempt to wait if event has not yet been signalled for the first time. */
609 if (mtl_event_ == nil) {
610 return;
611 }
612
613 if (signalled_) {
615 BLI_assert(ctx);
616
617 ctx->main_command_buffer.encode_wait_for_event(mtl_event_, last_signalled_value_);
618 signalled_ = false;
619 }
620}
621
624/* -------------------------------------------------------------------- */
629{
630 /* Set source image row data stride when uploading image data to the GPU. */
633}
634
635void MTLStateManager::texture_bind(Texture *tex_, GPUSamplerState sampler_type, int unit)
636{
637 BLI_assert(tex_);
638 gpu::MTLTexture *mtl_tex = static_cast<gpu::MTLTexture *>(tex_);
639 BLI_assert(mtl_tex);
640
642 if (unit >= 0) {
643 ctx->texture_bind(mtl_tex, unit, false);
644
645 /* Fetching textures default sampler configuration and applying
646 * eGPUSampler State on top. This path exists to support
647 * Any of the sampler state which is associated with the
648 * texture itself such as min/max mip levels. */
649 MTLSamplerState sampler = mtl_tex->get_sampler_state();
650 sampler.state = sampler_type;
651
652 ctx->sampler_bind(sampler, unit);
653 }
654}
655
657{
658 BLI_assert(tex_);
659 gpu::MTLTexture *mtl_tex = static_cast<gpu::MTLTexture *>(tex_);
660 BLI_assert(mtl_tex);
662 ctx->texture_unbind(mtl_tex, false);
663}
664
666{
668 BLI_assert(ctx);
669 ctx->texture_unbind_all(false);
670}
671
674/* -------------------------------------------------------------------- */
679{
680 BLI_assert(tex_);
681 gpu::MTLTexture *mtl_tex = static_cast<gpu::MTLTexture *>(tex_);
682 BLI_assert(mtl_tex);
683
685 if (unit >= 0) {
686 ctx->texture_bind(mtl_tex, unit, true);
687 }
688}
689
691{
692 BLI_assert(tex_);
693 gpu::MTLTexture *mtl_tex = static_cast<gpu::MTLTexture *>(tex_);
694 BLI_assert(mtl_tex);
696 ctx->texture_unbind(mtl_tex, true);
697}
698
700{
702 BLI_assert(ctx);
703 ctx->texture_unbind_all(true);
704}
705
708} // namespace blender::gpu
#define BLI_assert(a)
Definition BLI_assert.h:50
MINLINE unsigned int float_as_uint(float f)
unsigned int uint
@ GPU_COUNTERCLOCKWISE
@ GPU_CLOCKWISE
eGPUBlend
Definition GPU_state.hh:84
@ GPU_BLEND_ADDITIVE_PREMULT
Definition GPU_state.hh:90
@ GPU_BLEND_INVERT
Definition GPU_state.hh:95
@ GPU_BLEND_OIT
Definition GPU_state.hh:98
@ GPU_BLEND_MULTIPLY
Definition GPU_state.hh:91
@ GPU_BLEND_NONE
Definition GPU_state.hh:85
@ GPU_BLEND_ALPHA
Definition GPU_state.hh:87
@ GPU_BLEND_CUSTOM
Definition GPU_state.hh:103
@ GPU_BLEND_ADDITIVE
Definition GPU_state.hh:89
@ GPU_BLEND_SUBTRACT
Definition GPU_state.hh:92
@ GPU_BLEND_ALPHA_UNDER_PREMUL
Definition GPU_state.hh:104
@ GPU_BLEND_BACKGROUND
Definition GPU_state.hh:100
@ GPU_BLEND_ALPHA_PREMULT
Definition GPU_state.hh:88
eGPUWriteMask
Definition GPU_state.hh:16
@ GPU_WRITE_RED
Definition GPU_state.hh:18
@ GPU_WRITE_GREEN
Definition GPU_state.hh:19
@ GPU_WRITE_BLUE
Definition GPU_state.hh:20
@ GPU_WRITE_DEPTH
Definition GPU_state.hh:22
@ GPU_WRITE_ALPHA
Definition GPU_state.hh:21
eGPUProvokingVertex
Definition GPU_state.hh:138
eGPUStageBarrierBits
Definition GPU_state.hh:65
@ GPU_BARRIER_STAGE_ANY
Definition GPU_state.hh:70
eGPUFaceCullTest
Definition GPU_state.hh:132
@ GPU_CULL_FRONT
Definition GPU_state.hh:134
@ GPU_CULL_NONE
Definition GPU_state.hh:133
@ GPU_CULL_BACK
Definition GPU_state.hh:135
eGPUBarrier
Definition GPU_state.hh:29
eGPUStencilOp
Definition GPU_state.hh:124
@ GPU_STENCIL_OP_COUNT_DEPTH_FAIL
Definition GPU_state.hh:129
@ GPU_STENCIL_OP_COUNT_DEPTH_PASS
Definition GPU_state.hh:128
@ GPU_STENCIL_OP_REPLACE
Definition GPU_state.hh:126
@ GPU_STENCIL_OP_NONE
Definition GPU_state.hh:125
eGPUDepthTest
Definition GPU_state.hh:107
@ GPU_DEPTH_GREATER
Definition GPU_state.hh:113
@ GPU_DEPTH_EQUAL
Definition GPU_state.hh:112
@ GPU_DEPTH_ALWAYS
Definition GPU_state.hh:109
@ GPU_DEPTH_GREATER_EQUAL
Definition GPU_state.hh:114
@ GPU_DEPTH_LESS
Definition GPU_state.hh:110
@ GPU_DEPTH_LESS_EQUAL
Definition GPU_state.hh:111
@ GPU_DEPTH_NONE
Definition GPU_state.hh:108
eGPUStencilTest
Definition GPU_state.hh:117
@ GPU_STENCIL_EQUAL
Definition GPU_state.hh:120
@ GPU_STENCIL_NEQUAL
Definition GPU_state.hh:121
@ GPU_STENCIL_ALWAYS
Definition GPU_state.hh:119
@ GPU_STENCIL_NONE
Definition GPU_state.hh:118
void encode_signal_event(id< MTLEvent > event, uint64_t value)
bool insert_memory_barrier(eGPUBarrier barrier_bits, eGPUStageBarrierBits before_stages, eGPUStageBarrierBits after_stages)
void encode_wait_for_event(id< MTLEvent > event, uint64_t value)
static MTLContext * get()
MTLContextGlobalShaderPipelineState pipeline_state
void sampler_bind(MTLSamplerState, uint sampler_unit)
void texture_bind(gpu::MTLTexture *mtl_texture, uint texture_unit, bool is_image)
void texture_unbind(gpu::MTLTexture *mtl_texture, bool is_image)
MTLCommandBufferManager main_command_buffer
void texture_unbind_all(bool is_image)
void signal() override
Definition mtl_state.mm:592
void wait() override
Definition mtl_state.mm:606
void image_unbind_all() override
Definition mtl_state.mm:699
void texture_unbind(Texture *tex) override
Definition mtl_state.mm:656
void image_unbind(Texture *tex) override
Definition mtl_state.mm:690
void force_state() override
Definition mtl_state.mm:59
void image_bind(Texture *tex, int unit) override
Definition mtl_state.mm:678
void texture_unpack_row_length_set(uint len) override
Definition mtl_state.mm:628
void texture_bind(Texture *tex, GPUSamplerState sampler, int unit) override
Definition mtl_state.mm:635
void apply_state() override
Definition mtl_state.mm:50
MTLStateManager(MTLContext *ctx)
Definition mtl_state.mm:31
void issue_barrier(eGPUBarrier barrier_bits) override
Definition mtl_state.mm:568
void texture_unbind_all() override
Definition mtl_state.mm:665
local_group_size(16, 16) .push_constant(Type local_group_size(16, 16) .push_constant(Type input_tx sampler(1, ImageType::FLOAT_2D, "matte_tx") .image(0
int len
CCL_NAMESPACE_BEGIN ccl_device float invert(float color, float factor)
Definition invert.h:9
ccl_device_inline float4 mask(const int4 mask, const float4 a)
static ulong state[N]
static void mtl_stencil_set_op(MTLContext *context, MTLStencilOperation stencil_fail, MTLStencilOperation depth_test_fail, MTLStencilOperation depthstencil_pass)
Definition mtl_state.mm:276
static MTLCompareFunction gpu_depth_function_to_metal(eGPUDepthTest depth_func)
Definition mtl_state.mm:179
static MTLCompareFunction gpu_stencil_func_to_metal(eGPUStencilTest stencil_func)
Definition mtl_state.mm:203
@ MTL_PIPELINE_STATE_CULLMODE_FLAG
@ MTL_PIPELINE_STATE_PSO_FLAG
@ MTL_PIPELINE_STATE_FRONT_FACING_FLAG
@ MTL_PIPELINE_STATE_DEPTHSTENCIL_FLAG
@ MTL_PIPELINE_STATE_VIEWPORT_FLAG
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:252
unsigned int uint32_t
Definition stdint.h:80
MTLStencilOperation stencil_op_back_depthstencil_pass
MTLStencilOperation stencil_op_front_stencil_fail
MTLStencilOperation stencil_op_front_depthstencil_pass