如何编译两个版本的金属文件 [英] How to compile two versions of metal files

查看:65
本文介绍了如何编译两个版本的金属文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想同时支持10.13和10.14,但是我想在10.14上支持快速数学运算.如果我强制使用#define __CIKERNEL_METAL_VERSION__ 200,则仅能编译项目,但这意味着在10.13上它将崩溃.如何配置项目,以便创建2个金属库?到目前为止,结果文件为default.metallib(使用Xcode编译)

I want to support both 10.13 and 10.14 however I want to support fast math on 10.14. I am only able to compile project if I force #define __CIKERNEL_METAL_VERSION__ 200 but this means on 10.13 it will crash. How do I configure the project so it creates 2 metal libraries? So far the result file is default.metallib (compiling using Xcode)

        BOOL supportsMetal;

#if TARGET_OS_IOS
        supportsMetal = MTLCreateSystemDefaultDevice() != nil; //this forces GPU on macbook to switch immediatelly
#else
        supportsMetal = [MTLCopyAllDevices() count] >= 1;
#endif

        if (@available(macOS 10.13, *)) {

            //only 10.14 fully supports metal with fast math, however there are hackintoshes etc...
            if (supportsMetal) {
                _kernel = [self metalKernel];
            } else {
                _kernel = [self GLSLKernel];
            }

        } else {
            _kernel = [self GLSLKernel];
        }

        if (_kernel == nil) return nil;

METAL文件

#include <metal_stdlib>
using namespace metal;

//https://en.wikipedia.org/wiki/List_of_monochrome_and_RGB_palettes

//https://en.wikipedia.org/wiki/Relative_luminance
//https://en.wikipedia.org/wiki/Grayscale

//<CoreImage/CIKernelMetalLib.h>
//only if you enable fast math (macOS10.14 or iOS12) otherwise fall back to float4 instead of half4

//forcing compilation for macOS 10.14+//iOS12+
#define __CIKERNEL_METAL_VERSION__ 200

constant half3 kRec709Luma  = half3(0.2126, 0.7152, 0.0722);
constant half3 kRec601Luma  = half3(0.299 , 0.587 , 0.114);
//constant float3 kRec2100Luma = float3(0.2627, 0.6780, 0.0593);

#include <CoreImage/CoreImage.h>

extern "C" { namespace coreimage {

    float lumin601(half3 p)
    {
        return dot(p.rgb, kRec601Luma);
    }

    float lumin709(half3 p)
    {
        return dot(p.rgb, kRec709Luma);
    }

    half4 thresholdFilter(sample_h image, float threshold)
    {
        half4 pix = unpremultiply(image);
        float luma = lumin601(pix.rgb);
        pix.rgb = half3(step(threshold, luma));
        return premultiply(pix);
    }
}}

推荐答案

XCode 11支持Metal库.

XCode 11 supports Metal libraries.

  1. 将新的构建目标添加到您的项目中.

  1. 在编译源中添加金属文件

  1. 如果您使用Core Image,请添加这些链接器标志.更改部署目标(ios12 +)并检查快速数学运算.

  1. 在原始项目目标中添加新的依赖关系并复制脚本

  1. To your original project target add new dependencies and copy script

cp"$ {BUILT_PRODUCTS_DIR}"/*.metallib"$ {METAL_LIBRARY_OUTPUT_DIR}"

cp "${BUILT_PRODUCTS_DIR}"/*.metallib "${METAL_LIBRARY_OUTPUT_DIR}"

可选:

避免在项目中的任何地方使用硬编码字符串.将xconfig文件添加到项目

Avoiding hard coded strings everywhere in project. Add xconfig file to project

MY_METAL_LIBRARY_NAME_10_13 = Metal_10_13_aaa
MY_METAL_LIBRARY_NAME_10_14 = Metal_10_14_bbb
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) MY_METAL_LIBRARY_NAME_10_13='@"$(MY_METAL_LIBRARY_NAME_10_13)"' MY_METAL_LIBRARY_NAME_10_14='@"$(MY_METAL_LIBRARY_NAME_10_14)"'

添加xconfig作为配置(不要为项目设置它,因为最终将导致两次导入)

Add xconfig as configuration (don't set it for project cause you will end up with double import)

将每个金属库的PRODUCT_NAME变量更改为一个变量

Change PRODUCT_NAME variable of each metal library to a variable

在代码中使用预处理变量

Use preprocesor variables in code

static NSString *const kMetallibExtension = @"metallib";
NSString *const kMetalLibraryOldTarget = MY_METAL_LIBRARY_NAME_10_13; //@"Metal_10_13";
NSString *const kMetalLibraryFastMathTarget = MY_METAL_LIBRARY_NAME_10_14; //@"Metal_10_14";

+ (NSString *)metalLibraryName
{
    if (@available(macOS 10.14, *)) {
        return kMetalLibraryFastMathTarget;
    } else {
        return kMetalLibraryOldTarget;
    }
    //use default
    //return @"default";
}

这篇关于如何编译两个版本的金属文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆