Blender  V3.3
mtl_texture_util.mm
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include "BKE_global.h"
8 
9 #include "DNA_userdef_types.h"
10 
11 #include "GPU_batch.h"
12 #include "GPU_batch_presets.h"
13 #include "GPU_capabilities.h"
14 #include "GPU_framebuffer.h"
15 #include "GPU_platform.h"
16 #include "GPU_state.h"
17 
18 #include "mtl_backend.hh"
19 #include "mtl_context.hh"
20 #include "mtl_texture.hh"
21 
22 /* Utility file for secondary functionality which supports mtl_texture.mm. */
23 
32 
33 namespace blender::gpu {
34 
35 /* -------------------------------------------------------------------- */
40 {
41 
42  switch (tex_format) {
43  /* Formats texture & renderbuffer. */
44  case GPU_RGBA8UI:
45  return MTLPixelFormatRGBA8Uint;
46  case GPU_RGBA8I:
47  return MTLPixelFormatRGBA8Sint;
48  case GPU_RGBA8:
49  return MTLPixelFormatRGBA8Unorm;
50  case GPU_RGBA32UI:
51  return MTLPixelFormatRGBA32Uint;
52  case GPU_RGBA32I:
53  return MTLPixelFormatRGBA32Sint;
54  case GPU_RGBA32F:
55  return MTLPixelFormatRGBA32Float;
56  case GPU_RGBA16UI:
57  return MTLPixelFormatRGBA16Uint;
58  case GPU_RGBA16I:
59  return MTLPixelFormatRGBA16Sint;
60  case GPU_RGBA16F:
61  return MTLPixelFormatRGBA16Float;
62  case GPU_RGBA16:
63  return MTLPixelFormatRGBA16Unorm;
64  case GPU_RG8UI:
65  return MTLPixelFormatRG8Uint;
66  case GPU_RG8I:
67  return MTLPixelFormatRG8Sint;
68  case GPU_RG8:
69  return MTLPixelFormatRG8Unorm;
70  case GPU_RG32UI:
71  return MTLPixelFormatRG32Uint;
72  case GPU_RG32I:
73  return MTLPixelFormatRG32Sint;
74  case GPU_RG32F:
75  return MTLPixelFormatRG32Float;
76  case GPU_RG16UI:
77  return MTLPixelFormatRG16Uint;
78  case GPU_RG16I:
79  return MTLPixelFormatRG16Sint;
80  case GPU_RG16F:
81  return MTLPixelFormatRG16Float;
82  case GPU_RG16:
83  return MTLPixelFormatRG16Float;
84  case GPU_R8UI:
85  return MTLPixelFormatR8Uint;
86  case GPU_R8I:
87  return MTLPixelFormatR8Sint;
88  case GPU_R8:
89  return MTLPixelFormatR8Unorm;
90  case GPU_R32UI:
91  return MTLPixelFormatR32Uint;
92  case GPU_R32I:
93  return MTLPixelFormatR32Sint;
94  case GPU_R32F:
95  return MTLPixelFormatR32Float;
96  case GPU_R16UI:
97  return MTLPixelFormatR16Uint;
98  case GPU_R16I:
99  return MTLPixelFormatR16Sint;
100  case GPU_R16F:
101  return MTLPixelFormatR16Float;
102  case GPU_R16:
103  return MTLPixelFormatR16Snorm;
104 
105  /* Special formats texture & renderbuffer. */
106  case GPU_R11F_G11F_B10F:
107  return MTLPixelFormatRG11B10Float;
109  return MTLPixelFormatDepth32Float_Stencil8;
110  case GPU_DEPTH24_STENCIL8: {
111  BLI_assert(false && "GPU_DEPTH24_STENCIL8 not supported by Apple Silicon.");
112  return MTLPixelFormatDepth24Unorm_Stencil8;
113  }
114  case GPU_SRGB8_A8:
115  return MTLPixelFormatRGBA8Unorm_sRGB;
116  case GPU_RGB16F:
117  return MTLPixelFormatRGBA16Float;
118 
119  /* Depth Formats. */
122  return MTLPixelFormatDepth32Float;
124  return MTLPixelFormatDepth16Unorm;
125 
126  default:
127  BLI_assert(!"Unrecognised GPU pixel format!\n");
128  return MTLPixelFormatRGBA8Unorm;
129  }
130 }
131 
132 int get_mtl_format_bytesize(MTLPixelFormat tex_format)
133 {
134 
135  switch (tex_format) {
136  case MTLPixelFormatRGBA8Uint:
137  case MTLPixelFormatRGBA8Sint:
138  case MTLPixelFormatRGBA8Unorm:
139  return 4;
140  case MTLPixelFormatRGBA32Uint:
141  case MTLPixelFormatRGBA32Sint:
142  case MTLPixelFormatRGBA32Float:
143  return 16;
144  case MTLPixelFormatRGBA16Uint:
145  case MTLPixelFormatRGBA16Sint:
146  case MTLPixelFormatRGBA16Float:
147  case MTLPixelFormatRGBA16Unorm:
148  return 8;
149  case MTLPixelFormatRG8Uint:
150  case MTLPixelFormatRG8Sint:
151  case MTLPixelFormatRG8Unorm:
152  return 2;
153  case MTLPixelFormatRG32Uint:
154  case MTLPixelFormatRG32Sint:
155  case MTLPixelFormatRG32Float:
156  return 8;
157  case MTLPixelFormatRG16Uint:
158  case MTLPixelFormatRG16Sint:
159  case MTLPixelFormatRG16Float:
160  return 4;
161  case MTLPixelFormatR8Uint:
162  case MTLPixelFormatR8Sint:
163  case MTLPixelFormatR8Unorm:
164  return 1;
165  case MTLPixelFormatR32Uint:
166  case MTLPixelFormatR32Sint:
167  case MTLPixelFormatR32Float:
168  return 4;
169  case MTLPixelFormatR16Uint:
170  case MTLPixelFormatR16Sint:
171  case MTLPixelFormatR16Float:
172  case MTLPixelFormatR16Snorm:
173  return 2;
174  case MTLPixelFormatRG11B10Float:
175  return 4;
176  case MTLPixelFormatDepth32Float_Stencil8:
177  return 8;
178  case MTLPixelFormatRGBA8Unorm_sRGB:
179  case MTLPixelFormatDepth32Float:
180  case MTLPixelFormatDepth24Unorm_Stencil8:
181  return 4;
182  case MTLPixelFormatDepth16Unorm:
183  return 2;
184 
185  default:
186  BLI_assert(!"Unrecognised GPU pixel format!\n");
187  return 1;
188  }
189 }
190 
191 int get_mtl_format_num_components(MTLPixelFormat tex_format)
192 {
193 
194  switch (tex_format) {
195  case MTLPixelFormatRGBA8Uint:
196  case MTLPixelFormatRGBA8Sint:
197  case MTLPixelFormatRGBA8Unorm:
198  case MTLPixelFormatRGBA32Uint:
199  case MTLPixelFormatRGBA32Sint:
200  case MTLPixelFormatRGBA32Float:
201  case MTLPixelFormatRGBA16Uint:
202  case MTLPixelFormatRGBA16Sint:
203  case MTLPixelFormatRGBA16Float:
204  case MTLPixelFormatRGBA16Unorm:
205  case MTLPixelFormatRGBA8Unorm_sRGB:
206  return 4;
207 
208  case MTLPixelFormatRG11B10Float:
209  return 3;
210 
211  case MTLPixelFormatRG8Uint:
212  case MTLPixelFormatRG8Sint:
213  case MTLPixelFormatRG8Unorm:
214  case MTLPixelFormatRG32Uint:
215  case MTLPixelFormatRG32Sint:
216  case MTLPixelFormatRG32Float:
217  case MTLPixelFormatRG16Uint:
218  case MTLPixelFormatRG16Sint:
219  case MTLPixelFormatRG16Float:
220  case MTLPixelFormatDepth32Float_Stencil8:
221  return 2;
222 
223  case MTLPixelFormatR8Uint:
224  case MTLPixelFormatR8Sint:
225  case MTLPixelFormatR8Unorm:
226  case MTLPixelFormatR32Uint:
227  case MTLPixelFormatR32Sint:
228  case MTLPixelFormatR32Float:
229  case MTLPixelFormatR16Uint:
230  case MTLPixelFormatR16Sint:
231  case MTLPixelFormatR16Float:
232  case MTLPixelFormatR16Snorm:
233  case MTLPixelFormatDepth32Float:
234  case MTLPixelFormatDepth16Unorm:
235  case MTLPixelFormatDepth24Unorm_Stencil8:
236  /* Treating this format as single-channel for direct data copies -- Stencil component is not
237  * addressable. */
238  return 1;
239 
240  default:
241  BLI_assert(!"Unrecognised GPU pixel format!\n");
242  return 1;
243  }
244 }
245 
247 {
248  /* Add formats as needed -- Verify platforms. */
249  const MTLCapabilities &capabilities = MTLBackend::get_capabilities();
250 
251  if (capabilities.supports_family_mac1 || capabilities.supports_family_mac_catalyst1) {
252 
253  switch (format) {
254  case MTLPixelFormatA8Unorm:
255  case MTLPixelFormatR8Uint:
256  case MTLPixelFormatR8Sint:
257  case MTLPixelFormatR16Uint:
258  case MTLPixelFormatR16Sint:
259  case MTLPixelFormatRG32Uint:
260  case MTLPixelFormatRG32Sint:
261  case MTLPixelFormatRGBA8Uint:
262  case MTLPixelFormatRGBA8Sint:
263  case MTLPixelFormatRGBA32Uint:
264  case MTLPixelFormatRGBA32Sint:
265  case MTLPixelFormatDepth16Unorm:
266  case MTLPixelFormatDepth32Float:
267  case MTLPixelFormatInvalid:
268  case MTLPixelFormatBGR10A2Unorm:
269  case MTLPixelFormatRGB10A2Uint:
270  return false;
271  default:
272  return true;
273  }
274  }
275  else {
276  switch (format) {
277  case MTLPixelFormatA8Unorm:
278  case MTLPixelFormatR8Uint:
279  case MTLPixelFormatR8Sint:
280  case MTLPixelFormatR16Uint:
281  case MTLPixelFormatR16Sint:
282  case MTLPixelFormatRG32Uint:
283  case MTLPixelFormatRG32Sint:
284  case MTLPixelFormatRGBA8Uint:
285  case MTLPixelFormatRGBA8Sint:
286  case MTLPixelFormatRGBA32Uint:
287  case MTLPixelFormatRGBA32Sint:
288  case MTLPixelFormatRGBA32Float:
289  case MTLPixelFormatDepth16Unorm:
290  case MTLPixelFormatDepth32Float:
291  case MTLPixelFormatInvalid:
292  case MTLPixelFormatBGR10A2Unorm:
293  case MTLPixelFormatRGB10A2Uint:
294  return false;
295  default:
296  return true;
297  }
298  }
299 }
300 
303 /* -------------------------------------------------------------------- */
307 id<MTLComputePipelineState> gpu::MTLTexture::mtl_texture_update_impl(
308  TextureUpdateRoutineSpecialisation specialisation_params,
309  blender::Map<TextureUpdateRoutineSpecialisation, id<MTLComputePipelineState>>
310  &specialisation_cache,
311  eGPUTextureType texture_type)
312 {
313  /* Check whether the Kernel exists. */
314  id<MTLComputePipelineState> *result = specialisation_cache.lookup_ptr(specialisation_params);
315  if (result != nullptr) {
316  return *result;
317  }
318 
319  id<MTLComputePipelineState> return_pso = nil;
320  @autoreleasepool {
321 
322  /* Fetch active context. */
323  MTLContext *ctx = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
324  BLI_assert(ctx);
325 
327  NSString *tex_update_kernel_src = [NSString
328  stringWithUTF8String:datatoc_compute_texture_update_msl];
329 
330  /* Prepare options and specializations. */
331  MTLCompileOptions *options = [[[MTLCompileOptions alloc] init] autorelease];
332  options.languageVersion = MTLLanguageVersion2_2;
333  options.preprocessorMacros = @{
334  @"INPUT_DATA_TYPE" :
335  [NSString stringWithUTF8String:specialisation_params.input_data_type.c_str()],
336  @"OUTPUT_DATA_TYPE" :
337  [NSString stringWithUTF8String:specialisation_params.output_data_type.c_str()],
338  @"COMPONENT_COUNT_INPUT" :
339  [NSNumber numberWithInt:specialisation_params.component_count_input],
340  @"COMPONENT_COUNT_OUTPUT" :
341  [NSNumber numberWithInt:specialisation_params.component_count_output],
342  @"TEX_TYPE" : [NSNumber numberWithInt:((int)(texture_type))]
343  };
344 
345  /* Prepare shader library for conversion routine. */
346  NSError *error = NULL;
347  id<MTLLibrary> temp_lib = [[ctx->device newLibraryWithSource:tex_update_kernel_src
349  error:&error] autorelease];
350  if (error) {
351  NSLog(@"Compile Error - Metal Shader Library error %@ ", error);
352  BLI_assert(false);
353  return nullptr;
354  }
355 
356  /* Fetch compute function. */
357  BLI_assert(temp_lib != nil);
358  id<MTLFunction> temp_compute_function = [[temp_lib
359  newFunctionWithName:@"compute_texture_update"] autorelease];
360  BLI_assert(temp_compute_function);
361 
362  /* Otherwise, bake new Kernel. */
363  id<MTLComputePipelineState> compute_pso = [ctx->device
364  newComputePipelineStateWithFunction:temp_compute_function
365  error:&error];
366  if (error || compute_pso == nil) {
367  NSLog(@"Failed to prepare texture_update MTLComputePipelineState %@", error);
368  BLI_assert(false);
369  }
370 
371  /* Store PSO. */
372  [compute_pso retain];
373  specialisation_cache.add_new(specialisation_params, compute_pso);
374  return_pso = compute_pso;
375  }
376 
377  BLI_assert(return_pso != nil);
378  return return_pso;
379 }
380 
381 id<MTLComputePipelineState> gpu::MTLTexture::texture_update_1d_get_kernel(
382  TextureUpdateRoutineSpecialisation specialisation)
383 {
384  MTLContext *mtl_context = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
385  BLI_assert(mtl_context != nullptr);
386  return mtl_texture_update_impl(specialisation,
387  mtl_context->get_texture_utils().texture_1d_update_compute_psos,
389 }
390 
391 id<MTLComputePipelineState> gpu::MTLTexture::texture_update_1d_array_get_kernel(
392  TextureUpdateRoutineSpecialisation specialisation)
393 {
394  MTLContext *mtl_context = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
395  BLI_assert(mtl_context != nullptr);
396  return mtl_texture_update_impl(
397  specialisation,
398  mtl_context->get_texture_utils().texture_1d_array_update_compute_psos,
400 }
401 
402 id<MTLComputePipelineState> gpu::MTLTexture::texture_update_2d_get_kernel(
403  TextureUpdateRoutineSpecialisation specialisation)
404 {
405  MTLContext *mtl_context = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
406  BLI_assert(mtl_context != nullptr);
407  return mtl_texture_update_impl(specialisation,
408  mtl_context->get_texture_utils().texture_2d_update_compute_psos,
410 }
411 
412 id<MTLComputePipelineState> gpu::MTLTexture::texture_update_2d_array_get_kernel(
413  TextureUpdateRoutineSpecialisation specialisation)
414 {
415  MTLContext *mtl_context = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
416  BLI_assert(mtl_context != nullptr);
417  return mtl_texture_update_impl(
418  specialisation,
419  mtl_context->get_texture_utils().texture_2d_array_update_compute_psos,
421 }
422 
423 id<MTLComputePipelineState> gpu::MTLTexture::texture_update_3d_get_kernel(
424  TextureUpdateRoutineSpecialisation specialisation)
425 {
426  MTLContext *mtl_context = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
427  BLI_assert(mtl_context != nullptr);
428  return mtl_texture_update_impl(specialisation,
429  mtl_context->get_texture_utils().texture_3d_update_compute_psos,
431 }
432 
433 /* TODO(Metal): Data upload routine kernel for texture cube and texture cube array.
434  * Currently does not appear to be hit. */
435 
436 GPUShader *gpu::MTLTexture::depth_2d_update_sh_get(
438 {
439 
440  /* Check whether the Kernel exists. */
441  MTLContext *mtl_context = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
442  BLI_assert(mtl_context != nullptr);
443 
444  GPUShader **result = mtl_context->get_texture_utils().depth_2d_update_shaders.lookup_ptr(
445  specialisation);
446  if (result != nullptr) {
447  return *result;
448  }
449 
450  const char *fragment_source = nullptr;
451  switch (specialisation.data_mode) {
454  break;
457  break;
460  break;
461  default:
462  BLI_assert(false && "Invalid format mode\n");
463  return nullptr;
464  }
465 
468  nullptr,
469  nullptr,
470  nullptr,
471  "depth_2d_update_sh_get");
472  mtl_context->get_texture_utils().depth_2d_update_shaders.add_new(specialisation, shader);
473  return shader;
474 }
475 
476 GPUShader *gpu::MTLTexture::fullscreen_blit_sh_get()
477 {
478 
479  MTLContext *mtl_context = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
480  BLI_assert(mtl_context != nullptr);
481  if (mtl_context->get_texture_utils().fullscreen_blit_shader == nullptr) {
484  GPUShader *shader = GPU_shader_create(
485  vertex_source, fragment_source, nullptr, nullptr, nullptr, "fullscreen_blit");
486  mtl_context->get_texture_utils().fullscreen_blit_shader = shader;
487  }
488  return mtl_context->get_texture_utils().fullscreen_blit_shader;
489 }
490 
491 /* Special routine for updating 2D depth textures using the rendering pipeline. */
492 void gpu::MTLTexture::update_sub_depth_2d(
493  int mip, int offset[3], int extent[3], eGPUDataFormat type, const void *data)
494 {
495  /* Verify we are in a valid configuration. */
496  BLI_assert(ELEM(format_,
504 
505  /* Determine whether we are in GPU_DATA_UINT_24_8 or GPU_DATA_FLOAT mode. */
506  bool is_float = (type == GPU_DATA_FLOAT);
507  eGPUTextureFormat format = (is_float) ? GPU_R32F : GPU_R32I;
508 
509  /* Shader key - Add parameters here for different configurations. */
511  switch (type) {
512  case GPU_DATA_FLOAT:
513  specialisation.data_mode = MTL_DEPTH_UPDATE_MODE_FLOAT;
514  break;
515 
516  case GPU_DATA_UINT_24_8:
517  specialisation.data_mode = MTL_DEPTH_UPDATE_MODE_INT24;
518  break;
519 
520  case GPU_DATA_UINT:
521  specialisation.data_mode = MTL_DEPTH_UPDATE_MODE_INT32;
522  break;
523 
524  default:
525  BLI_assert(false && "Unsupported eGPUDataFormat being passed to depth texture update\n");
526  return;
527  }
528 
529  /* Push contents into an r32_tex and render contents to depth using a shader. */
530  GPUTexture *r32_tex_tmp = GPU_texture_create_2d(
531  "depth_intermediate_copy_tex", w_, h_, 1, format, nullptr);
532  GPU_texture_filter_mode(r32_tex_tmp, false);
533  GPU_texture_wrap_mode(r32_tex_tmp, false, true);
534  gpu::MTLTexture *mtl_tex = static_cast<gpu::MTLTexture *>(unwrap(r32_tex_tmp));
535  mtl_tex->update_sub(mip, offset, extent, type, data);
536 
538  GPUFrameBuffer *depth_fb_temp = GPU_framebuffer_create("depth_intermediate_copy_fb");
539  GPU_framebuffer_texture_attach(depth_fb_temp, wrap(static_cast<Texture *>(this)), 0, mip);
540  GPU_framebuffer_bind(depth_fb_temp);
541  if (extent[0] == w_ && extent[1] == h_) {
542  /* Skip load if the whole texture is being updated. */
543  GPU_framebuffer_clear_depth(depth_fb_temp, 0.0);
544  GPU_framebuffer_clear_stencil(depth_fb_temp, 0);
545  }
546 
547  GPUShader *depth_2d_update_sh = depth_2d_update_sh_get(specialisation);
548  BLI_assert(depth_2d_update_sh != nullptr);
550  GPU_batch_set_shader(quad, depth_2d_update_sh);
551 
552  GPU_batch_texture_bind(quad, "source_data", r32_tex_tmp);
553  GPU_batch_uniform_1i(quad, "mip", mip);
554  GPU_batch_uniform_2f(quad, "extent", (float)extent[0], (float)extent[1]);
555  GPU_batch_uniform_2f(quad, "offset", (float)offset[0], (float)offset[1]);
556  GPU_batch_uniform_2f(quad, "size", (float)w_, (float)h_);
557 
558  bool depth_write_prev = GPU_depth_mask_get();
559  uint stencil_mask_prev = GPU_stencil_mask_get();
560  eGPUDepthTest depth_test_prev = GPU_depth_test_get();
561  eGPUStencilTest stencil_test_prev = GPU_stencil_test_get();
562  GPU_scissor_test(true);
563  GPU_scissor(offset[0], offset[1], extent[0], extent[1]);
564 
568  GPU_depth_mask(true);
570 
572 
573  GPU_depth_mask(depth_write_prev);
574  GPU_stencil_write_mask_set(stencil_mask_prev);
575  GPU_stencil_test(stencil_test_prev);
576  GPU_depth_test(depth_test_prev);
577 
578  if (restore_fb != nullptr) {
579  GPU_framebuffer_bind(restore_fb);
580  }
581  else {
583  }
584  GPU_framebuffer_free(depth_fb_temp);
585  GPU_texture_free(r32_tex_tmp);
586 }
589 /* -------------------------------------------------------------------- */
593 id<MTLComputePipelineState> gpu::MTLTexture::mtl_texture_read_impl(
594  TextureReadRoutineSpecialisation specialisation_params,
595  blender::Map<TextureReadRoutineSpecialisation, id<MTLComputePipelineState>>
596  &specialisation_cache,
597  eGPUTextureType texture_type)
598 {
599  /* Check whether the Kernel exists. */
600  id<MTLComputePipelineState> *result = specialisation_cache.lookup_ptr(specialisation_params);
601  if (result != nullptr) {
602  return *result;
603  }
604 
605  id<MTLComputePipelineState> return_pso = nil;
606  @autoreleasepool {
607 
608  /* Fetch active context. */
609  MTLContext *ctx = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
610  BLI_assert(ctx);
611 
613  NSString *tex_update_kernel_src = [NSString
614  stringWithUTF8String:datatoc_compute_texture_read_msl];
615 
616  /* Defensive Debug Checks. */
617  long long int depth_scale_factor = 1;
618  if (specialisation_params.depth_format_mode > 0) {
619  BLI_assert(specialisation_params.component_count_input == 1);
620  BLI_assert(specialisation_params.component_count_output == 1);
621  switch (specialisation_params.depth_format_mode) {
622  case 1:
623  /* FLOAT */
624  depth_scale_factor = 1;
625  break;
626  case 2:
627  /* D24 uint */
628  depth_scale_factor = 0xFFFFFFu;
629  break;
630  case 4:
631  /* D32 uint */
632  depth_scale_factor = 0xFFFFFFFFu;
633  break;
634  default:
635  BLI_assert_msg(0, "Unrecognised mode");
636  break;
637  }
638  }
639 
640  /* Prepare options and specializations. */
641  MTLCompileOptions *options = [[[MTLCompileOptions alloc] init] autorelease];
642  options.languageVersion = MTLLanguageVersion2_2;
643  options.preprocessorMacros = @{
644  @"INPUT_DATA_TYPE" :
645  [NSString stringWithUTF8String:specialisation_params.input_data_type.c_str()],
646  @"OUTPUT_DATA_TYPE" :
647  [NSString stringWithUTF8String:specialisation_params.output_data_type.c_str()],
648  @"COMPONENT_COUNT_INPUT" :
649  [NSNumber numberWithInt:specialisation_params.component_count_input],
650  @"COMPONENT_COUNT_OUTPUT" :
651  [NSNumber numberWithInt:specialisation_params.component_count_output],
652  @"WRITE_COMPONENT_COUNT" :
653  [NSNumber numberWithInt:min_ii(specialisation_params.component_count_input,
654  specialisation_params.component_count_output)],
655  @"IS_DEPTH_FORMAT" :
656  [NSNumber numberWithInt:((specialisation_params.depth_format_mode > 0) ? 1 : 0)],
657  @"DEPTH_SCALE_FACTOR" : [NSNumber numberWithLongLong:depth_scale_factor],
658  @"TEX_TYPE" : [NSNumber numberWithInt:((int)(texture_type))]
659  };
660 
661  /* Prepare shader library for conversion routine. */
662  NSError *error = NULL;
663  id<MTLLibrary> temp_lib = [[ctx->device newLibraryWithSource:tex_update_kernel_src
665  error:&error] autorelease];
666  if (error) {
667  NSLog(@"Compile Error - Metal Shader Library error %@ ", error);
668  BLI_assert(false);
669  return nil;
670  }
671 
672  /* Fetch compute function. */
673  BLI_assert(temp_lib != nil);
674  id<MTLFunction> temp_compute_function = [[temp_lib newFunctionWithName:@"compute_texture_read"]
675  autorelease];
676  BLI_assert(temp_compute_function);
677 
678  /* Otherwise, bake new Kernel. */
679  id<MTLComputePipelineState> compute_pso = [ctx->device
680  newComputePipelineStateWithFunction:temp_compute_function
681  error:&error];
682  if (error || compute_pso == nil) {
683  NSLog(@"Failed to prepare texture_read MTLComputePipelineState %@", error);
684  BLI_assert(false);
685  return nil;
686  }
687 
688  /* Store PSO. */
689  [compute_pso retain];
690  specialisation_cache.add_new(specialisation_params, compute_pso);
691  return_pso = compute_pso;
692  }
693 
694  BLI_assert(return_pso != nil);
695  return return_pso;
696 }
697 
698 id<MTLComputePipelineState> gpu::MTLTexture::texture_read_2d_get_kernel(
699  TextureReadRoutineSpecialisation specialisation)
700 {
701  MTLContext *mtl_context = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
702  BLI_assert(mtl_context != nullptr);
703  return mtl_texture_read_impl(specialisation,
704  mtl_context->get_texture_utils().texture_2d_read_compute_psos,
706 }
707 
708 id<MTLComputePipelineState> gpu::MTLTexture::texture_read_2d_array_get_kernel(
709  TextureReadRoutineSpecialisation specialisation)
710 {
711  MTLContext *mtl_context = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
712  BLI_assert(mtl_context != nullptr);
713  return mtl_texture_read_impl(specialisation,
714  mtl_context->get_texture_utils().texture_2d_array_read_compute_psos,
716 }
717 
718 id<MTLComputePipelineState> gpu::MTLTexture::texture_read_1d_get_kernel(
719  TextureReadRoutineSpecialisation specialisation)
720 {
721  MTLContext *mtl_context = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
722  BLI_assert(mtl_context != nullptr);
723  return mtl_texture_read_impl(specialisation,
724  mtl_context->get_texture_utils().texture_1d_read_compute_psos,
726 }
727 
728 id<MTLComputePipelineState> gpu::MTLTexture::texture_read_1d_array_get_kernel(
729  TextureReadRoutineSpecialisation specialisation)
730 {
731  MTLContext *mtl_context = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
732  BLI_assert(mtl_context != nullptr);
733  return mtl_texture_read_impl(specialisation,
734  mtl_context->get_texture_utils().texture_1d_array_read_compute_psos,
736 }
737 
738 id<MTLComputePipelineState> gpu::MTLTexture::texture_read_3d_get_kernel(
739  TextureReadRoutineSpecialisation specialisation)
740 {
741  MTLContext *mtl_context = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
742  BLI_assert(mtl_context != nullptr);
743  return mtl_texture_read_impl(specialisation,
744  mtl_context->get_texture_utils().texture_3d_read_compute_psos,
746 }
747 
750 } // namespace blender::gpu
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition: BLI_assert.h:53
MINLINE int min_ii(int a, int b)
unsigned int uint
Definition: BLI_sys_types.h:67
#define ELEM(...)
GPUBatch
Definition: GPU_batch.h:78
void GPU_batch_set_shader(GPUBatch *batch, GPUShader *shader)
Definition: gpu_batch.cc:211
#define GPU_batch_texture_bind(batch, name, tex)
Definition: GPU_batch.h:161
void GPU_batch_draw(GPUBatch *batch)
Definition: gpu_batch.cc:223
#define GPU_batch_uniform_2f(batch, name, x, y)
Definition: GPU_batch.h:145
#define GPU_batch_uniform_1i(batch, name, x)
Definition: GPU_batch.h:142
struct GPUBatch * GPU_batch_preset_quad(void)
GPUContext * GPU_context_active_get(void)
Definition: gpu_context.cc:142
struct GPUFrameBuffer GPUFrameBuffer
void GPU_framebuffer_restore(void)
GPUFrameBuffer * GPU_framebuffer_active_get(void)
void GPU_framebuffer_free(GPUFrameBuffer *fb)
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
GPUFrameBuffer * GPU_framebuffer_create(const char *name)
_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
GPUShader * GPU_shader_create(const char *vertcode, const char *fragcode, const char *geomcode, const char *libcode, const char *defines, const char *shname)
Definition: gpu_shader.cc:211
struct GPUShader GPUShader
Definition: GPU_shader.h:20
void GPU_scissor_test(bool enable)
Definition: gpu_state.cc:180
uint GPU_stencil_mask_get(void)
Definition: gpu_state.cc:230
void GPU_depth_mask(bool depth)
Definition: gpu_state.cc:107
void GPU_stencil_test(eGPUStencilTest test)
Definition: gpu_state.cc:70
void GPU_stencil_write_mask_set(uint write_mask)
Definition: gpu_state.cc:202
void GPU_stencil_reference_set(uint reference)
Definition: gpu_state.cc:197
void GPU_scissor(int x, int y, int width, int height)
Definition: gpu_state.cc:185
eGPUStencilTest GPU_stencil_test_get(void)
Definition: gpu_state.cc:242
bool GPU_depth_mask_get(void)
Definition: gpu_state.cc:273
eGPUDepthTest
Definition: GPU_state.h:82
@ GPU_DEPTH_ALWAYS
Definition: GPU_state.h:84
eGPUDepthTest GPU_depth_test_get(void)
Definition: gpu_state.cc:236
eGPUStencilTest
Definition: GPU_state.h:92
@ GPU_STENCIL_ALWAYS
Definition: GPU_state.h:94
void GPU_depth_test(eGPUDepthTest test)
Definition: gpu_state.cc:65
void GPU_texture_wrap_mode(GPUTexture *tex, bool use_repeat, bool use_clamp)
Definition: gpu_texture.cc:546
struct GPUTexture GPUTexture
Definition: GPU_texture.h:17
eGPUDataFormat
Definition: GPU_texture.h:170
@ GPU_DATA_UINT_24_8
Definition: GPU_texture.h:175
@ GPU_DATA_UINT
Definition: GPU_texture.h:173
@ GPU_DATA_FLOAT
Definition: GPU_texture.h:171
void GPU_texture_free(GPUTexture *tex)
Definition: gpu_texture.cc:564
void GPU_texture_filter_mode(GPUTexture *tex, bool use_filter)
Definition: gpu_texture.cc:518
GPUTexture * GPU_texture_create_2d(const char *name, int w, int h, int mip_len, eGPUTextureFormat format, const float *data)
Definition: gpu_texture.cc:291
eGPUTextureFormat
Definition: GPU_texture.h:83
@ GPU_R16UI
Definition: GPU_texture.h:111
@ GPU_RG16F
Definition: GPU_texture.h:103
@ GPU_DEPTH32F_STENCIL8
Definition: GPU_texture.h:119
@ GPU_R16I
Definition: GPU_texture.h:112
@ GPU_SRGB8_A8
Definition: GPU_texture.h:121
@ GPU_DEPTH24_STENCIL8
Definition: GPU_texture.h:120
@ GPU_R32I
Definition: GPU_texture.h:109
@ GPU_RG8UI
Definition: GPU_texture.h:95
@ GPU_R16F
Definition: GPU_texture.h:113
@ GPU_RG8I
Definition: GPU_texture.h:96
@ GPU_RG16I
Definition: GPU_texture.h:102
@ GPU_RG32UI
Definition: GPU_texture.h:98
@ GPU_RGBA32F
Definition: GPU_texture.h:90
@ GPU_RG8
Definition: GPU_texture.h:97
@ GPU_RG32I
Definition: GPU_texture.h:99
@ GPU_RG16
Definition: GPU_texture.h:104
@ GPU_RGBA32UI
Definition: GPU_texture.h:88
@ GPU_R8I
Definition: GPU_texture.h:106
@ GPU_R16
Definition: GPU_texture.h:114
@ GPU_RG16UI
Definition: GPU_texture.h:101
@ GPU_RGBA8I
Definition: GPU_texture.h:86
@ GPU_RGBA8UI
Definition: GPU_texture.h:85
@ GPU_RGBA16UI
Definition: GPU_texture.h:91
@ GPU_RGBA16I
Definition: GPU_texture.h:92
@ GPU_R8UI
Definition: GPU_texture.h:105
@ GPU_RGBA16
Definition: GPU_texture.h:94
@ GPU_RG32F
Definition: GPU_texture.h:100
@ GPU_R8
Definition: GPU_texture.h:107
@ GPU_DEPTH_COMPONENT24
Definition: GPU_texture.h:166
@ GPU_RGB16F
Definition: GPU_texture.h:127
@ GPU_R32UI
Definition: GPU_texture.h:108
@ GPU_RGBA32I
Definition: GPU_texture.h:89
@ GPU_DEPTH_COMPONENT32F
Definition: GPU_texture.h:165
@ GPU_DEPTH_COMPONENT16
Definition: GPU_texture.h:167
@ GPU_R11F_G11F_B10F
Definition: GPU_texture.h:118
@ GPU_RGBA8
Definition: GPU_texture.h:87
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Texture
vertex_source("basic_depth_pointcloud_vert.glsl") .additional_info("draw_pointcloud")
static MTLCapabilities & get_capabilities()
Definition: mtl_backend.hh:33
CCL_NAMESPACE_BEGIN struct Options options
out_color fragment_source("eevee_film_frag.glsl") .additional_info("draw_fullscreen"
depth_tx normal_tx diffuse_light_tx specular_light_tx volume_light_tx environment_tx ambient_occlusion_tx aov_value_tx in_weight_img GPU_RGBA16F
depth_tx normal_tx diffuse_light_tx specular_light_tx volume_light_tx environment_tx ambient_occlusion_tx aov_value_tx GPU_R32F
GPUBatch * quad
void GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, int mip)
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
format
Definition: logImageCore.h:38
static void error(const char *str)
Definition: meshlaplacian.c:51
@ MTL_DEPTH_UPDATE_MODE_INT32
Definition: mtl_texture.hh:68
@ MTL_DEPTH_UPDATE_MODE_INT24
Definition: mtl_texture.hh:67
@ MTL_DEPTH_UPDATE_MODE_FLOAT
Definition: mtl_texture.hh:66
char datatoc_gpu_shader_fullscreen_blit_frag_glsl[]
char datatoc_gpu_shader_fullscreen_blit_vert_glsl[]
char datatoc_depth_2d_update_int32_frag_glsl[]
char datatoc_compute_texture_update_msl[]
char datatoc_depth_2d_update_int24_frag_glsl[]
char datatoc_depth_2d_update_vert_glsl[]
char datatoc_depth_2d_update_float_frag_glsl[]
char datatoc_compute_texture_read_msl[]
MTLPixelFormat gpu_texture_format_to_metal(eGPUTextureFormat tex_format)
bool validate_data_format_mtl(eGPUTextureFormat tex_format, eGPUDataFormat data_format)
static GPUContext * wrap(Context *ctx)
static Context * unwrap(GPUContext *ctx)
int get_mtl_format_num_components(MTLPixelFormat tex_format)
bool mtl_format_supports_blending(MTLPixelFormat format)
int get_mtl_format_bytesize(MTLPixelFormat tex_format)