如何编译两个版本的金属文件 [英] How to compile two versions of metal files
问题描述
我想同时支持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.
- 将新的构建目标添加到您的项目中.
- 在编译源中添加金属文件
- 如果您使用Core Image,请添加这些链接器标志.更改部署目标(ios12 +)并检查快速数学运算.
-
在原始项目目标中添加新的依赖关系并复制脚本
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屋!