简体   繁体   English

Metal defaultLibrary 不加载.metal 函数

[英]Metal defaultLibrary does not load .metal functions

My metal default library does not contain the vertex and shader functions from the.metal file of the same directory.我的金属默认库不包含来自同一目录的 .metal 文件的顶点和着色器函数。

Then the library.makeFunction(name: ..) returns nil for both the vertex and shader functions that should be assigned to pipelineDescriptor vars.然后 library.makeFunction(name: ..) 为应该分配给 pipelineDescriptor 变量的顶点和着色器函数返回 nil。

The metal file & headers are copied from the Apple Sample App "BasicTexturing" ( Creating and Sampling Textures ).金属文件和标题是从 Apple 示例应用程序“BasicTexturing”( 创建和采样纹理)复制而来的。

The file APPLShaders.metal and APPLShaderTypes.h contain a vertexShader and samplingShader functions that are loaded by an AAPLRenderer.m文件 APPLShaders.metal 和 APPLShaderTypes.h 包含由 AAPLRenderer.m 加载的 vertexShader 和 samplingShader 函数

In the sample it's really straightforward在示例中它真的很简单

 id<MTLLibrary> defaultLibrary = [_device newDefaultLibrary];
    id<MTLFunction> vertexFunction = [defaultLibrary newFunctionWithName:@"vertexShader"];
    id<MTLFunction> fragmentFunction = [defaultLibrary newFunctionWithName:@"samplingShader"];

I have copied these files to a RayWenderlich Swift tutorial and used the swift version There is an init to set the library我已将这些文件复制到 RayWenderlich Swift 教程并使用 swift 版本 有一个 init 来设置库

Renderer.library = device.makeDefaultLibrary()

then然后

 let library = Renderer.library
    let importVertexFunction = library?.makeFunction(name: "vertexShader")
    let importShaderFunction = library?.makeFunction(name: "samplingShader")

This works just fine!这很好用!

Same thing in my app with the same files copied over and it does not load the functions.在我的应用程序中复制了相同的文件,但它没有加载功能。

I have checked compileSources in build settings - it lists the metal file.我已经检查了构建设置中的 compileSources - 它列出了金属文件。 Comparing everything in settings and don't see a difference between the working apps and my app.比较设置中的所有内容,看不到工作应用程序和我的应用程序之间的区别。

I don't see any error messages or log messages to indicate a syntax or path problem.我没有看到任何错误消息或日志消息来指示语法或路径问题。

Any ideas?有任何想法吗?

The Apple sample code AAPLShaders.metal Apple示例代码AAPLShaders.metal

/*
See LICENSE folder for this sample’s licensing information.

Abstract:
Metal shaders used for this sample
*/

#include <metal_stdlib>
#include <simd/simd.h>

using namespace metal;

// Include header shared between this Metal shader code and C code executing Metal API commands
#import "AAPLShaderTypes.h"

// Vertex shader outputs and per-fragment inputs. Includes clip-space position and vertex outputs
//  interpolated by rasterizer and fed to each fragment generated by clip-space primitives.
typedef struct
{
    // The [[position]] attribute qualifier of this member indicates this value is the clip space
    //   position of the vertex wen this structure is returned from the vertex shader
    float4 clipSpacePosition [[position]];

    // Since this member does not have a special attribute qualifier, the rasterizer will
    //   interpolate its value with values of other vertices making up the triangle and
    //   pass that interpolated value to the fragment shader for each fragment in that triangle;
    float2 textureCoordinate;

} RasterizerData;

// Vertex Function
vertex RasterizerData
vertexShader(uint vertexID [[ vertex_id ]],
             constant AAPLVertex *vertexArray [[ buffer(AAPLVertexInputIndexVertices) ]],
             constant vector_uint2 *viewportSizePointer  [[ buffer(AAPLVertexInputIndexViewportSize) ]])

{

    RasterizerData out;

    // Index into our array of positions to get the current vertex
    //   Our positions are specified in pixel dimensions (i.e. a value of 100 is 100 pixels from
    //   the origin)
    float2 pixelSpacePosition = vertexArray[vertexID].position.xy;

    // Get the size of the drawable so that we can convert to normalized device coordinates,
    float2 viewportSize = float2(*viewportSizePointer);

    // The output position of every vertex shader is in clip space (also known as normalized device
    //   coordinate space, or NDC). A value of (-1.0, -1.0) in clip-space represents the
    //   lower-left corner of the viewport whereas (1.0, 1.0) represents the upper-right corner of
    //   the viewport.

    // In order to convert from positions in pixel space to positions in clip space we divide the
    //   pixel coordinates by half the size of the viewport.
    out.clipSpacePosition.xy = pixelSpacePosition / (viewportSize / 2.0);

    // Set the z component of our clip space position 0 (since we're only rendering in
    //   2-Dimensions for this sample)
    out.clipSpacePosition.z = 0.0;

    // Set the w component to 1.0 since we don't need a perspective divide, which is also not
    //   necessary when rendering in 2-Dimensions
    out.clipSpacePosition.w = 1.0;

    // Pass our input textureCoordinate straight to our output RasterizerData. This value will be
    //   interpolated with the other textureCoordinate values in the vertices that make up the
    //   triangle.
    out.textureCoordinate = vertexArray[vertexID].textureCoordinate;
    
    return out;
}

// Fragment function
fragment float4
samplingShader(RasterizerData in [[stage_in]],
               texture2d<half> colorTexture [[ texture(AAPLTextureIndexBaseColor) ]])
{
    constexpr sampler textureSampler (mag_filter::linear,
                                      min_filter::linear);

    // Sample the texture to obtain a color
    const half4 colorSample = colorTexture.sample(textureSampler, in.textureCoordinate);

    // We return the color of the texture
    return float4(colorSample);
}

The Apple Sample code header AAPLShaderTypes.h苹果示例代码 header AAPLShaderTypes.h

/*
See LICENSE folder for this sample’s licensing information.

Abstract:
Header containing types and enum constants shared between Metal shaders and C/ObjC source
*/

#ifndef AAPLShaderTypes_h
#define AAPLShaderTypes_h

#include <simd/simd.h>

// Buffer index values shared between shader and C code to ensure Metal shader buffer inputs match
//   Metal API buffer set calls
typedef enum AAPLVertexInputIndex
{
    AAPLVertexInputIndexVertices     = 0,
    AAPLVertexInputIndexViewportSize = 1,
} AAPLVertexInputIndex;

// Texture index values shared between shader and C code to ensure Metal shader buffer inputs match
//   Metal API texture set calls
typedef enum AAPLTextureIndex
{
    AAPLTextureIndexBaseColor = 0,
} AAPLTextureIndex;

//  This structure defines the layout of each vertex in the array of vertices set as an input to our
//    Metal vertex shader.  Since this header is shared between our .metal shader and C code,
//    we can be sure that the layout of the vertex array in the code matches the layout that
//    our vertex shader expects
typedef struct
{
    // Positions in pixel space (i.e. a value of 100 indicates 100 pixels from the origin/center)
    vector_float2 position;

    // 2D texture coordinate
    vector_float2 textureCoordinate;
} AAPLVertex;

#endif /* AAPLShaderTypes_h */

Debug print of my library我的图书馆的调试打印

Printing description of self.library:
(MTLLibrary?) library = (object = 0x00006000004af7b0) {
  object = 0x00006000004af7b0 {
    baseNSObject@0 = {
      isa = CaptureMTLLibrary
    }

Debug print of working library from RayWenderlich sample app The new added sampleShader and vertexShader are shown in the library along with the existing fragment and vertex functions.来自 RayWenderlich 示例应用程序的工作库的调试打印新添加的 sampleShader 和 vertexShader 与现有的片段和顶点函数一起显示在库中。

▿ Optional<MTLLibrary>
  - some : <CaptureMTLLibrary: 0x600000f54210> -> <MTLDebugLibrary: 0x600002204050> -> <_MTLLibrary: 0x600001460280>
    label = <none> 
    device = <MTLSimDevice: 0x15a5069d0>
        name = Apple iOS simulator GPU 
    functionNames: fragment_main vertex_main samplingShader vertexShader

Did you check the target membership of file?您是否检查了文件的目标成员资格? Your code is nothing to weird so please check the target.您的代码没什么奇怪的,所以请检查目标。

在此处输入图像描述

Answer - issue of not loading functions into the metal library is resolved by removing a leftover -fcikernel flag in the Other Metal Compiler Flags option of Build Settings of the project target.答案 - 不将函数加载到金属库中的问题通过在项目目标的构建设置的其他金属编译器标志选项中删除剩余的 -fcikernel 标志来解决。 The flag was set when testing a CoreImageKernel.metal as documented in https://developer.apple.com/documentation/coreimage/cikernel/2880194-init I removed the kernel definition file from the app but missed the compiler flag.. and missed it when visually comparing build settings.该标志是在测试 CoreImageKernel.metal 时设置的,如https 中所述://developer.apple.com/documentation/coreimage/cikernel/2880194-init我从应用程序中删除了 kernel 定义文件,但错过了编译器标志......并且错过了它在视觉上比较构建设置时。

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM