Skip to content
Permalink
Browse files

play with creating a (minimal) library for Metal API

  • Loading branch information...
dmitshur committed Jun 6, 2018
1 parent 44eb072 commit ea8a996cc6283d1a9cf9a189676ef32bf101720d
Showing with 123 additions and 0 deletions.
  1. +12 −0 246/main.go
  2. +61 −0 246/mtl/mtl.go
  3. +18 −0 246/mtl/mtl.h
  4. +32 −0 246/mtl/mtl.m
@@ -0,0 +1,12 @@
// Play with creating a (minimal) library for Metal API.
package main

import (
"github.com/shurcooL/go-goon"
"github.com/shurcooL/play/246/mtl"
)

func main() {
goon.DumpExpr(mtl.CreateSystemDefaultDevice())
goon.DumpExpr(mtl.CopyAllDevices())
}
@@ -0,0 +1,61 @@
// Package mtl is a tiny subset of the Metal API.
package mtl

/*
#cgo darwin CFLAGS: -x objective-c
#cgo darwin LDFLAGS: -framework Metal
#include <stdlib.h>
#include "mtl.h"
*/
import "C"
import "unsafe"

// Device is abstract representation of the GPU that
// serves as the primary interface for a Metal app.
type Device struct {
// Headless indicates whether a device is configured as headless.
Headless bool

// LowPower indicates whether a device is low-power.
LowPower bool

// Removable determines whether or not a GPU is removable.
Removable bool

// RegistryID is the registry ID value for the device.
RegistryID uint64

// Name is the name of the device.
Name string
}

// CreateSystemDefaultDevice returns the preferred system default Metal device.
func CreateSystemDefaultDevice() Device {
d := C.CreateSystemDefaultDevice()

return Device{
Headless: d.headless != 0,
LowPower: d.lowPower != 0,
Removable: d.removable != 0,
RegistryID: uint64(d.registryID),
Name: C.GoString(d.name),
}
}

// CopyAllDevices returns all Metal devices in the system.
func CopyAllDevices() []Device {
d := C.CopyAllDevices()
defer C.free(unsafe.Pointer(d.devices))

ds := make([]Device, d.length)
for i := 0; i < len(ds); i++ {
d := (*C.struct_Device)(unsafe.Pointer(uintptr(unsafe.Pointer(d.devices)) + uintptr(i)*C.sizeof_struct_Device))

ds[i].Headless = d.headless != 0
ds[i].LowPower = d.lowPower != 0
ds[i].Removable = d.removable != 0
ds[i].RegistryID = uint64(d.registryID)
ds[i].Name = C.GoString(d.name)
}
return ds
}
@@ -0,0 +1,18 @@
typedef signed char BOOL;
typedef unsigned long long uint64_t;

struct Device {
BOOL headless;
BOOL lowPower;
BOOL removable;
uint64_t registryID;
const char * name;
};

struct Devices {
struct Device * devices;
int length;
};

struct Device CreateSystemDefaultDevice();
struct Devices CopyAllDevices();
@@ -0,0 +1,32 @@
#include <stdlib.h>
#import <Metal/Metal.h>
#include "mtl.h"

struct Device CreateSystemDefaultDevice() {
id<MTLDevice> device = MTLCreateSystemDefaultDevice();

struct Device d;
d.headless = device.headless;
d.lowPower = device.lowPower;
d.removable = device.removable;
d.registryID = device.registryID;
d.name = device.name.UTF8String;
return d;
}

// Caller must call free(d.devices).
struct Devices CopyAllDevices() {
NSArray<id<MTLDevice>> * devices = MTLCopyAllDevices();

struct Devices d;
d.devices = malloc(devices.count * sizeof(struct Device));
for (int i = 0; i < devices.count; i++) {
d.devices[i].headless = devices[i].headless;
d.devices[i].lowPower = devices[i].lowPower;
d.devices[i].removable = devices[i].removable;
d.devices[i].registryID = devices[i].registryID;
d.devices[i].name = devices[i].name.UTF8String;
}
d.length = devices.count;
return d;
}

0 comments on commit ea8a996

Please sign in to comment.
You can’t perform that action at this time.