[Bf-blender-cvs] [cc8ea6ac67a] master: Metal: MTLShader and MTLShaderGenerator implementation.

Thomas Dinges noreply at git.blender.org
Thu Sep 1 22:30:15 CEST 2022


Commit: cc8ea6ac67a108fcb96e4a8373ac02faf9ccea3d
Author: Thomas Dinges
Date:   Thu Sep 1 22:22:32 2022 +0200
Branches: master
https://developer.blender.org/rBcc8ea6ac67a108fcb96e4a8373ac02faf9ccea3d

Metal: MTLShader and MTLShaderGenerator implementation.

Full support for translation and compilation of shaders in Metal, using
GPUShaderCreateInfo. Includes render pipeline state creation and management,
enabling all standard GPU viewport rendering features in Metal.

Authored by Apple: Michael Parkin-White, Marco Giordano

Ref T96261

Reviewed By: fclem

Maniphest Tasks: T96261

Differential Revision: https://developer.blender.org/D15563

===================================================================

M	source/blender/gpu/CMakeLists.txt
M	source/blender/gpu/GPU_capabilities.h
M	source/blender/gpu/GPU_shader_shared_utils.h
M	source/blender/gpu/intern/gpu_context.cc
M	source/blender/gpu/intern/gpu_context_private.hh
M	source/blender/gpu/intern/gpu_shader.cc
M	source/blender/gpu/intern/gpu_shader_create_info.hh
M	source/blender/gpu/metal/kernels/compute_texture_read.msl
M	source/blender/gpu/metal/kernels/compute_texture_update.msl
M	source/blender/gpu/metal/kernels/depth_2d_update_float_frag.glsl
A	source/blender/gpu/metal/kernels/depth_2d_update_info.hh
M	source/blender/gpu/metal/kernels/depth_2d_update_int24_frag.glsl
M	source/blender/gpu/metal/kernels/depth_2d_update_int32_frag.glsl
M	source/blender/gpu/metal/kernels/depth_2d_update_vert.glsl
M	source/blender/gpu/metal/kernels/gpu_shader_fullscreen_blit_frag.glsl
A	source/blender/gpu/metal/kernels/gpu_shader_fullscreen_blit_info.hh
M	source/blender/gpu/metal/kernels/gpu_shader_fullscreen_blit_vert.glsl
M	source/blender/gpu/metal/mtl_backend.mm
M	source/blender/gpu/metal/mtl_capabilities.hh
M	source/blender/gpu/metal/mtl_common.hh
M	source/blender/gpu/metal/mtl_context.hh
M	source/blender/gpu/metal/mtl_context.mm
M	source/blender/gpu/metal/mtl_memory.mm
A	source/blender/gpu/metal/mtl_primitive.hh
A	source/blender/gpu/metal/mtl_pso_descriptor_state.hh
A	source/blender/gpu/metal/mtl_shader.hh
A	source/blender/gpu/metal/mtl_shader.mm
A	source/blender/gpu/metal/mtl_shader_generator.hh
A	source/blender/gpu/metal/mtl_shader_generator.mm
A	source/blender/gpu/metal/mtl_shader_interface.hh
A	source/blender/gpu/metal/mtl_shader_interface.mm
A	source/blender/gpu/metal/mtl_shader_interface_type.hh
A	source/blender/gpu/metal/mtl_shader_shared.h
M	source/blender/gpu/metal/mtl_state.hh
M	source/blender/gpu/metal/mtl_state.mm
M	source/blender/gpu/metal/mtl_texture.hh
M	source/blender/gpu/metal/mtl_texture.mm
M	source/blender/gpu/metal/mtl_texture_util.mm
M	source/blender/gpu/opengl/gl_backend.cc
A	source/blender/gpu/shaders/metal/mtl_shader_common.msl
A	source/blender/gpu/shaders/metal/mtl_shader_defines.msl
M	source/blender/python/gpu/gpu_py_shader_create_info.cc

===================================================================

diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 6758b4b8794..979bfc63572 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -194,6 +194,9 @@ set(METAL_SRC
   metal/mtl_index_buffer.mm
   metal/mtl_memory.mm
   metal/mtl_query.mm
+  metal/mtl_shader.mm
+  metal/mtl_shader_generator.mm
+  metal/mtl_shader_interface.mm
   metal/mtl_state.mm
   metal/mtl_texture.mm
   metal/mtl_texture_util.mm
@@ -207,7 +210,14 @@ set(METAL_SRC
   metal/mtl_framebuffer.hh
   metal/mtl_index_buffer.hh
   metal/mtl_memory.hh
+  metal/mtl_pso_descriptor_state.hh
+  metal/mtl_primitive.hh
   metal/mtl_query.hh
+  metal/mtl_shader.hh
+  metal/mtl_shader_generator.hh
+  metal/mtl_shader_interface_type.hh
+  metal/mtl_shader_interface.hh
+  metal/mtl_shader_shared.h
   metal/mtl_state.hh
   metal/mtl_texture.hh
   metal/mtl_uniform_buffer.hh
@@ -227,6 +237,9 @@ set(LIB
 )
 
 set(MSL_SRC
+  shaders/metal/mtl_shader_defines.msl
+  shaders/metal/mtl_shader_common.msl
+
   metal/kernels/compute_texture_update.msl
   metal/kernels/compute_texture_read.msl
   metal/kernels/depth_2d_update_float_frag.glsl
@@ -458,21 +471,44 @@ set(GLSL_SRC
   GPU_shader_shared_utils.h
 )
 
-set(GLSL_C)
-foreach(GLSL_FILE ${GLSL_SRC})
-  data_to_c_simple(${GLSL_FILE} GLSL_C)
-endforeach()
+set(MTL_BACKEND_GLSL_SRC
+  metal/kernels/compute_texture_update.msl
+  metal/kernels/compute_texture_read.msl
+  metal/kernels/depth_2d_update_float_frag.glsl
+  metal/kernels/depth_2d_update_int24_frag.glsl
+  metal/kernels/depth_2d_update_int32_frag.glsl
+  metal/kernels/depth_2d_update_vert.glsl
+  metal/kernels/gpu_shader_fullscreen_blit_vert.glsl
+  metal/kernels/gpu_shader_fullscreen_blit_frag.glsl
+)
 
+set(MSL_SRC
+  shaders/metal/mtl_shader_defines.msl
+  shaders/metal/mtl_shader_common.msl
+  metal/mtl_shader_shared.h
+)
 
 if(WITH_METAL_BACKEND)
+  list(APPEND GLSL_SRC ${MTL_BACKEND_GLSL_SRC})
+
   set(MSL_C)
   foreach(MSL_FILE ${MSL_SRC})
     data_to_c_simple(${MSL_FILE} MSL_C)
   endforeach()
-  list(APPEND GLSL_C ${MSL_C})
 endif()
 
-blender_add_lib(bf_gpu_shaders "${GLSL_C}" "" "" "")
+set(GLSL_C)
+foreach(GLSL_FILE ${GLSL_SRC})
+  data_to_c_simple(${GLSL_FILE} GLSL_C)
+endforeach()
+
+set(SHADER_C)
+list(APPEND SHADER_C ${GLSL_C})
+if(WITH_METAL_BACKEND)
+  list(APPEND SHADER_C ${MSL_C})
+endif()
+
+blender_add_lib(bf_gpu_shaders "${SHADER_C}" "" "" "")
 
 list(APPEND LIB
   bf_gpu_shaders
@@ -587,6 +623,16 @@ set(SRC_SHADER_CREATE_INFOS
   shaders/compositor/infos/compositor_split_viewer_info.hh
 )
 
+set(SRC_SHADER_CREATE_INFOS_MTL
+  metal/kernels/depth_2d_update_info.hh
+  metal/kernels/gpu_shader_fullscreen_blit_info.hh
+)
+
+if(WITH_METAL_BACKEND)
+  list(APPEND SRC_SHADER_CREATE_INFOS ${SRC_SHADER_CREATE_INFOS_MTL})
+endif()
+
+
 set(SHADER_CREATE_INFOS_CONTENT "")
 foreach(DESCRIPTOR_FILE ${SRC_SHADER_CREATE_INFOS})
   string(APPEND SHADER_CREATE_INFOS_CONTENT "#include \"${DESCRIPTOR_FILE}\"\n")
@@ -629,6 +675,7 @@ if(WITH_GPU_BUILDTIME_SHADER_BUILDER)
   if(APPLE)
     add_executable(shader_builder
       intern/gpu_shader_builder.cc
+      intern/gpu_shader_builder_stubs.cc
       ${shader_create_info_list_file}
       )
 
diff --git a/source/blender/gpu/GPU_capabilities.h b/source/blender/gpu/GPU_capabilities.h
index 61c60f336e1..91cf14dc792 100644
--- a/source/blender/gpu/GPU_capabilities.h
+++ b/source/blender/gpu/GPU_capabilities.h
@@ -30,6 +30,7 @@ int GPU_max_batch_indices(void);
 int GPU_max_batch_vertices(void);
 int GPU_max_vertex_attribs(void);
 int GPU_max_varying_floats(void);
+int GPU_max_samplers(void);
 int GPU_max_shader_storage_buffer_bindings(void);
 int GPU_max_compute_shader_storage_blocks(void);
 int GPU_max_samplers(void);
diff --git a/source/blender/gpu/GPU_shader_shared_utils.h b/source/blender/gpu/GPU_shader_shared_utils.h
index 88bdad2bf76..1cfc4f8af31 100644
--- a/source/blender/gpu/GPU_shader_shared_utils.h
+++ b/source/blender/gpu/GPU_shader_shared_utils.h
@@ -43,20 +43,23 @@
 #  define sqrtf sqrt
 #  define expf exp
 
-#  define float2 vec2
-#  define float3 vec3
-#  define float4 vec4
-#  define float4x4 mat4
-#  define int2 ivec2
-#  define int3 ivec3
-#  define int4 ivec4
-#  define uint2 uvec2
-#  define uint3 uvec3
-#  define uint4 uvec4
 #  define bool1 bool
-#  define bool2 bvec2
-#  define bool3 bvec3
-#  define bool4 bvec4
+/* Type name collision with Metal shading language - These typenames are already defined. */
+#  ifndef GPU_METAL
+#    define float2 vec2
+#    define float3 vec3
+#    define float4 vec4
+#    define float4x4 mat4
+#    define int2 ivec2
+#    define int3 ivec3
+#    define int4 ivec4
+#    define uint2 uvec2
+#    define uint3 uvec3
+#    define uint4 uvec4
+#    define bool2 bvec2
+#    define bool3 bvec3
+#    define bool4 bvec4
+#  endif
 
 #else /* C / C++ */
 #  pragma once
diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc
index e29b0d5801d..bcc418169b7 100644
--- a/source/blender/gpu/intern/gpu_context.cc
+++ b/source/blender/gpu/intern/gpu_context.cc
@@ -56,11 +56,15 @@ static void gpu_backend_discard();
 
 namespace blender::gpu {
 
+int Context::context_counter = 0;
 Context::Context()
 {
   thread_ = pthread_self();
   is_active_ = false;
   matrix_state = GPU_matrix_state_create();
+
+  context_id = Context::context_counter;
+  Context::context_counter++;
 }
 
 Context::~Context()
diff --git a/source/blender/gpu/intern/gpu_context_private.hh b/source/blender/gpu/intern/gpu_context_private.hh
index f823a92893c..2217e5262ed 100644
--- a/source/blender/gpu/intern/gpu_context_private.hh
+++ b/source/blender/gpu/intern/gpu_context_private.hh
@@ -48,6 +48,14 @@ class Context {
 
   DebugStack debug_stack;
 
+  /* GPUContext counter used to assign a unique ID to each GPUContext.
+   * NOTE(Metal): This is required by the Metal Backend, as a bug exists in the global OS shader
+   * cache wherein compilation of identical source from two distinct threads can result in an
+   * invalid cache collision, result in a broken shader object. Appending the unique context ID
+   * onto compiled sources ensures the source hashes are different. */
+  static int context_counter;
+  int context_id = 0;
+
  protected:
   /** Thread on which this context is active. */
   pthread_t thread_;
diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc
index 2d1b3dc2dca..4d059ae495e 100644
--- a/source/blender/gpu/intern/gpu_shader.cc
+++ b/source/blender/gpu/intern/gpu_shader.cc
@@ -95,6 +95,9 @@ static void standard_defines(Vector<const char *> &sources)
     case GPU_BACKEND_OPENGL:
       sources.append("#define GPU_OPENGL\n");
       break;
+    case GPU_BACKEND_METAL:
+      sources.append("#define GPU_METAL\n");
+      break;
     default:
       BLI_assert(false && "Invalid GPU Backend Type");
       break;
diff --git a/source/blender/gpu/intern/gpu_shader_create_info.hh b/source/blender/gpu/intern/gpu_shader_create_info.hh
index 8236e669288..3884c067c83 100644
--- a/source/blender/gpu/intern/gpu_shader_create_info.hh
+++ b/source/blender/gpu/intern/gpu_shader_create_info.hh
@@ -32,6 +32,7 @@ namespace blender::gpu::shader {
 #endif
 
 enum class Type {
+  /* Types supported natively across all GPU backends. */
   FLOAT = 0,
   VEC2,
   VEC3,
@@ -47,6 +48,21 @@ enum class Type {
   IVEC3,
   IVEC4,
   BOOL,
+  /* Additionally supported types to enable data optimisation and native
+   * support in some GPUBackends.
+   * NOTE: These types must be representable in all APIs. E.g. VEC3_101010I2 is aliased as vec3 in
+   * the GL backend, as implicit type conversions from packed normal attribute data to vec3 is
+   * supported. UCHAR/CHAR types are natively supported in Metal and can be used to avoid
+   * additional data conversions for GPU_COMP_U8 vertex attributes. */
+  VEC3_101010I2,
+  UCHAR,
+  UCHAR2,
+  UCHAR3,
+  UCHAR4,
+  CHAR,
+  CHAR2,
+  CHAR3,
+  CHAR4
 };
 
 /* All of these functions is a bit out of place */
@@ -86,6 +102,40 @@ static inline std::ostream &operator<<(std::ostream &stream, const Type type)
       return stream << "mat3";
     case Type::MAT4:
       return stream << "mat4";
+    case Type::VEC3_101010I2:
+      return stream << "vec3_1010102_Inorm";
+    case Type::UCHAR:
+      return stream << "uchar";
+    case Type::UCHAR2:
+      return stream << "uchar2";
+    case Type::UCHAR3:
+      return stream << "uchar3";
+    case Type::UCHAR4:
+      return stream << "uchar4";
+    case Type::CHAR:
+      return stream << "char";
+    case Type::CHAR2:
+      return stream << "char2";
+    case Type::CHAR3:
+      return stream << "char3";
+    case Type::CHAR4:
+      return stream << "char4";
+    case Type::INT:
+      return stream << "int";
+    case Type::IVEC2:
+      return stream << "ivec2";
+    case Type::IVEC3:
+      return stream << "ivec3";
+    case Type::IVEC4:
+      return stream << "ivec4";
+    case Type::UINT:
+      return stream << "uint";
+    case Type::UVEC2:
+      return stream << "uvec2";
+    case Type::UVEC3:
+      return stream << "uvec3";
+    case Type::UVEC4:
+      return stream << "uvec4";
     default:
       BLI_assert(0);
       return stream;
@@ -228,6 +278,8 @@ enum class PrimitiveOut {
   POINTS = 0,
   LINE_STRIP,
   TRIANGLE_STRIP,
+  LINES,
+  TRIANGLES,
 };
 
 struct StageInterfaceInfo {
diff --git a/source/blender/gpu/metal/kernels/compute_texture_read.msl b/source/blender/gpu/metal/kernels/compute_texture_read.msl
index 4bfb48567f9..7b0760d7620 100644
--- a/source/blender/gpu/metal/kernels/compute_texture_read.msl
+++ b/source/blender/gpu/metal/kernels/compute_texture_read.msl
@@ -74,7 +74,7 @@ template<> uchar convert_type<uchar>(float val)
 
 template<> uint convert_type<uint>(float val)
 {
-  return uint(val * double(0xFFFFFFFFu));
+  return uint(val * float(0xFFFFFFFFu));
 }
 
 struct TextureReadParams {
diff --git a/source/blender/gpu/metal/kernels/compute_texture_update.msl b/source/blender/gpu/metal/kernels/compute_texture_update.msl
index 095c495ac54..43c746e0afa 100644
--- a/source/blender/gpu/metal/kernels/compute_texture_update.msl
+++ b/source/blender/gpu/metal/kernels/compute_texture

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list