繁体   English   中英

Metal defaultLibrary 不加载.metal 函数

[英]Metal defaultLibrary does not load .metal functions

我的金属默认库不包含来自同一目录的 .metal 文件的顶点和着色器函数。

然后 library.makeFunction(name: ..) 为应该分配给 pipelineDescriptor 变量的顶点和着色器函数返回 nil。

金属文件和标题是从 Apple 示例应用程序“BasicTexturing”( 创建和采样纹理)复制而来的。

文件 APPLShaders.metal 和 APPLShaderTypes.h 包含由 AAPLRenderer.m 加载的 vertexShader 和 samplingShader 函数

在示例中它真的很简单

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

我已将这些文件复制到 RayWenderlich Swift 教程并使用 swift 版本 有一个 init 来设置库

Renderer.library = device.makeDefaultLibrary()

然后

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

这很好用!

在我的应用程序中复制了相同的文件,但它没有加载功能。

我已经检查了构建设置中的 compileSources - 它列出了金属文件。 比较设置中的所有内容,看不到工作应用程序和我的应用程序之间的区别。

我没有看到任何错误消息或日志消息来指示语法或路径问题。

有任何想法吗?

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);
}

苹果示例代码 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 */

我的图书馆的调试打印

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

来自 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

您是否检查了文件的目标成员资格? 您的代码没什么奇怪的,所以请检查目标。

在此处输入图像描述

答案 - 不将函数加载到金属库中的问题通过在项目目标的构建设置的其他金属编译器标志选项中删除剩余的 -fcikernel 标志来解决。 该标志是在测试 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