Как скомпилировать две версии металлических файлов - PullRequest
1 голос
/ 18 октября 2019

Я хочу поддерживать и 10.13, и 10.14, но я хочу поддержать быструю математику в 10.14. Я могу скомпилировать проект, только если форсировать #define __CIKERNEL_METAL_VERSION__ 200, но это означает, что в 10.13 он потерпит крах. Как мне настроить проект, чтобы он создавал 2 металлические библиотеки? Пока что файл результатов - default.metallib (компилируется с использованием 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);
    }
}}

1 Ответ

2 голосов
/ 19 октября 2019

XCode 11 поддерживает библиотеки металлов.

  1. Добавьте новую цель сборки в ваш проект.

enter image description here

Добавление металлических файлов в исходники компиляции

enter image description here

Если вы используете Core Image, добавьте эти флаги компоновщика. Измените цели развертывания (ios12 +) и проверьте наличие быстрой математики.

enter image description here

К исходной цели проекта добавьте новые зависимости и скопируйте скрипт

cp "$ {BUILT_PRODUCTS_DIR}" / *. Metallib "$ {METAL_LIBRARY_OUTPUT_DIR}" enter image description here

Дополнительно:

Избегайте жестко закодированных строк везде в проекте. Добавить файл xconfig в проект

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 в качестве конфигурации (не устанавливайте его для проекта, потому что в итоге вы получите двойной импорт) enter image description here

Измените переменную PRODUCT_NAME каждой библиотеки металлов на переменную

enter image description here

Используйте переменные препроцессора в коде

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";
}
...