dmitri.shuralyov.com/gpu/mtl

add GPUFamily and Device.SupportsFamily

This is a newer API to check whether a GPU device supports the feature
set of a specific GPU family. It's available on macOS since 10.15.
dmitshur committed 3 years ago commit 2a3c46a829b92964146abf7f6c2d649cd66cce97
Showing partial commit. Full Commit
Collapse all
mtl.go
@@ -25,10 +25,33 @@ struct Library Go_Device_MakeLibrary(void * device, _GoString_ source) {
	return Device_MakeLibrary(device, _GoStringPtr(source), _GoStringLen(source));
}
*/
import "C"

// GPUFamily is a family of GPUs.
//
// Reference: https://developer.apple.com/documentation/metal/mtlgpufamily.
type GPUFamily uint16

// Options for families of GPUs.
const (
	GPUFamilyApple1  GPUFamily = 1001 // Apple family 1 GPU features that correspond to the Apple A7 GPUs.
	GPUFamilyApple2  GPUFamily = 1002 // Apple family 2 GPU features that correspond to the Apple A8 GPUs.
	GPUFamilyApple3  GPUFamily = 1003 // Apple family 3 GPU features that correspond to the Apple A9 and A10 GPUs.
	GPUFamilyApple4  GPUFamily = 1004 // Apple family 4 GPU features that correspond to the Apple A11 GPUs.
	GPUFamilyApple5  GPUFamily = 1005 // Apple family 5 GPU features that correspond to the Apple A12 GPUs.
	GPUFamilyApple6  GPUFamily = 1006 // Apple family 6 GPU features that correspond to the Apple A13 GPUs.
	GPUFamilyApple7  GPUFamily = 1007 // Apple family 7 GPU features that correspond to the Apple A14 and M1 GPUs.
	GPUFamilyApple8  GPUFamily = 1008 // Apple family 8 GPU features that correspond to the Apple A15 and M2 GPUs.
	GPUFamilyMac1    GPUFamily = 2001 // Mac family 1 GPU features.
	GPUFamilyMac2    GPUFamily = 2002 // Mac family 2 GPU features.
	GPUFamilyCommon1 GPUFamily = 3001 // Common family 1 GPU features.
	GPUFamilyCommon2 GPUFamily = 3002 // Common family 2 GPU features.
	GPUFamilyCommon3 GPUFamily = 3003 // Common family 3 GPU features.
	GPUFamilyMetal3  GPUFamily = 5001 // Metal 3 features.
)

// FeatureSet defines a specific platform, hardware, and software configuration.
//
// Reference: https://developer.apple.com/documentation/metal/mtlfeatureset.
type FeatureSet uint16

@@ -332,10 +355,18 @@ func CopyAllDevices() []Device {
}

// Device returns the underlying id<MTLDevice> pointer.
func (d Device) Device() unsafe.Pointer { return d.device }

// SupportsFamily reports whether device d supports
// the feature set of GPU family gf.
//
// Reference: https://developer.apple.com/documentation/metal/mtldevice/3143473-supportsfamily.
func (d Device) SupportsFamily(gf GPUFamily) bool {
	return bool(C.Device_SupportsFamily(d.device, C.uint16_t(gf)))
}

// SupportsFeatureSet reports whether device d supports feature set fs.
//
// Reference: https://developer.apple.com/documentation/metal/mtldevice/1433418-supportsfeatureset.
func (d Device) SupportsFeatureSet(fs FeatureSet) bool {
	return bool(C.Device_SupportsFeatureSet(d.device, C.uint16_t(fs)))
mtl.h
@@ -74,10 +74,11 @@ struct Region {
};

struct Device CreateSystemDefaultDevice();
struct Devices CopyAllDevices();

bool                       Device_SupportsFamily(void * device, uint16_t gpuFamily);
bool                       Device_SupportsFeatureSet(void * device, uint16_t featureSet);
void *                     Device_MakeCommandQueue(void * device);
struct Library             Device_MakeLibrary(void * device, const char * source, size_t sourceLength);
struct RenderPipelineState Device_MakeRenderPipelineState(void * device, struct RenderPipelineDescriptor descriptor);
void *                     Device_MakeBuffer(void * device, const void * bytes, size_t length, uint16_t options);
mtl.m
@@ -37,10 +37,17 @@ struct Devices CopyAllDevices() {
	}
	d.Length = devices.count;
	return d;
}

bool Device_SupportsFamily(void * device, uint16_t gpuFamily) {
	if (@available(macOS 10.15, *)) {
		return [(id<MTLDevice>)device supportsFamily:gpuFamily];
	}
	@throw @"API not available";
}

bool Device_SupportsFeatureSet(void * device, uint16_t featureSet) {
	return [(id<MTLDevice>)device supportsFeatureSet:featureSet];
}

void * Device_MakeCommandQueue(void * device) {