mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
internal/graphicsdriver/metal: support macOS 10.12 by removing packed types
From the Metal shading language specification [1] Table 2.2.3, attribute variables in Ebitengine's vertices don't have to be packed. Then, we can remove `packed` types. [1] https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf Closes #2107
This commit is contained in:
parent
ac922742bf
commit
5c63c4a4aa
@ -30,7 +30,7 @@ import (
|
|||||||
// It is because old Xcode (8 or older?) does not accept @available syntax.
|
// It is because old Xcode (8 or older?) does not accept @available syntax.
|
||||||
|
|
||||||
// #cgo CFLAGS: -Wno-unguarded-availability-new
|
// #cgo CFLAGS: -Wno-unguarded-availability-new
|
||||||
// #cgo !ios CFLAGS: -mmacosx-version-min=10.14
|
// #cgo !ios CFLAGS: -mmacosx-version-min=10.12
|
||||||
// #cgo LDFLAGS: -framework QuartzCore -framework Foundation -framework CoreGraphics
|
// #cgo LDFLAGS: -framework QuartzCore -framework Foundation -framework CoreGraphics
|
||||||
//
|
//
|
||||||
// #include "ca_darwin.h"
|
// #include "ca_darwin.h"
|
||||||
|
@ -29,7 +29,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// #cgo CFLAGS: -x objective-c
|
// #cgo CFLAGS: -x objective-c
|
||||||
// #cgo !ios CFLAGS: -mmacosx-version-min=10.14
|
// #cgo !ios CFLAGS: -mmacosx-version-min=10.12
|
||||||
// #cgo LDFLAGS: -framework Foundation
|
// #cgo LDFLAGS: -framework Foundation
|
||||||
//
|
//
|
||||||
// #import <Foundation/Foundation.h>
|
// #import <Foundation/Foundation.h>
|
||||||
@ -56,9 +56,9 @@ const source = `#include <metal_stdlib>
|
|||||||
using namespace metal;
|
using namespace metal;
|
||||||
|
|
||||||
struct VertexIn {
|
struct VertexIn {
|
||||||
packed_float2 position;
|
float2 position;
|
||||||
packed_float2 tex;
|
float2 tex;
|
||||||
packed_float4 color;
|
float4 color;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VertexOut {
|
struct VertexOut {
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
// Package mtl provides access to Apple's Metal API (https://developer.apple.com/documentation/metal).
|
// Package mtl provides access to Apple's Metal API (https://developer.apple.com/documentation/metal).
|
||||||
//
|
//
|
||||||
// Package mtl requires macOS version 10.14 or newer.
|
// Package mtl requires macOS version 10.12 or newer.
|
||||||
//
|
//
|
||||||
// This package is in very early stages of development.
|
// This package is in very early stages of development.
|
||||||
// The API will change when opportunities for improvement are discovered; it is not yet frozen.
|
// The API will change when opportunities for improvement are discovered; it is not yet frozen.
|
||||||
@ -28,7 +28,7 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
// #cgo !ios CFLAGS: -mmacosx-version-min=10.14
|
// #cgo !ios CFLAGS: -mmacosx-version-min=10.12
|
||||||
// #cgo LDFLAGS: -framework Metal -framework CoreGraphics -framework Foundation
|
// #cgo LDFLAGS: -framework Metal -framework CoreGraphics -framework Foundation
|
||||||
//
|
//
|
||||||
// #include "mtl_darwin.h"
|
// #include "mtl_darwin.h"
|
||||||
|
@ -48,15 +48,11 @@ void *Device_MakeCommandQueue(void *device) {
|
|||||||
struct Library Device_MakeLibrary(void *device, const char *source,
|
struct Library Device_MakeLibrary(void *device, const char *source,
|
||||||
size_t sourceLength) {
|
size_t sourceLength) {
|
||||||
NSError *error;
|
NSError *error;
|
||||||
MTLCompileOptions* options = [[MTLCompileOptions alloc] init];
|
|
||||||
if (@available(macOS 10.14, iOS 12.0, *)) {
|
|
||||||
options.languageVersion = MTLLanguageVersion2_1;
|
|
||||||
}
|
|
||||||
id<MTLLibrary> library = [(id<MTLDevice>)device
|
id<MTLLibrary> library = [(id<MTLDevice>)device
|
||||||
newLibraryWithSource:[[NSString alloc] initWithBytes:source
|
newLibraryWithSource:[[NSString alloc] initWithBytes:source
|
||||||
length:sourceLength
|
length:sourceLength
|
||||||
encoding:NSUTF8StringEncoding]
|
encoding:NSUTF8StringEncoding]
|
||||||
options:options
|
options:NULL
|
||||||
error:&error];
|
error:&error];
|
||||||
|
|
||||||
struct Library l;
|
struct Library l;
|
||||||
|
@ -25,7 +25,7 @@ import (
|
|||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/metal/ca"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/metal/ca"
|
||||||
)
|
)
|
||||||
|
|
||||||
// #cgo !ios CFLAGS: -mmacosx-version-min=10.14
|
// #cgo !ios CFLAGS: -mmacosx-version-min=10.12
|
||||||
//
|
//
|
||||||
// #include "ns_darwin.h"
|
// #include "ns_darwin.h"
|
||||||
import "C"
|
import "C"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
struct Attributes {
|
struct Attributes {
|
||||||
packed_float2 M0;
|
float2 M0;
|
||||||
packed_float2 M1;
|
float2 M1;
|
||||||
packed_float4 M2;
|
float4 M2;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Varyings {
|
struct Varyings {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
struct Attributes {
|
struct Attributes {
|
||||||
packed_float2 M0;
|
float2 M0;
|
||||||
packed_float2 M1;
|
float2 M1;
|
||||||
packed_float4 M2;
|
float4 M2;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Varyings {
|
struct Varyings {
|
||||||
|
@ -72,7 +72,7 @@ func Compile(p *shaderir.Program, vertex, fragment string) (shader string) {
|
|||||||
lines = append(lines, "")
|
lines = append(lines, "")
|
||||||
lines = append(lines, "struct Attributes {")
|
lines = append(lines, "struct Attributes {")
|
||||||
for i, a := range p.Attributes {
|
for i, a := range p.Attributes {
|
||||||
lines = append(lines, fmt.Sprintf("\t%s;", c.varDecl(p, &a, fmt.Sprintf("M%d", i), true, false)))
|
lines = append(lines, fmt.Sprintf("\t%s;", c.varDecl(p, &a, fmt.Sprintf("M%d", i), false)))
|
||||||
}
|
}
|
||||||
lines = append(lines, "};")
|
lines = append(lines, "};")
|
||||||
}
|
}
|
||||||
@ -82,7 +82,7 @@ func Compile(p *shaderir.Program, vertex, fragment string) (shader string) {
|
|||||||
lines = append(lines, "struct Varyings {")
|
lines = append(lines, "struct Varyings {")
|
||||||
lines = append(lines, "\tfloat4 Position [[position]];")
|
lines = append(lines, "\tfloat4 Position [[position]];")
|
||||||
for i, v := range p.Varyings {
|
for i, v := range p.Varyings {
|
||||||
lines = append(lines, fmt.Sprintf("\t%s;", c.varDecl(p, &v, fmt.Sprintf("M%d", i), false, false)))
|
lines = append(lines, fmt.Sprintf("\t%s;", c.varDecl(p, &v, fmt.Sprintf("M%d", i), false)))
|
||||||
}
|
}
|
||||||
lines = append(lines, "};")
|
lines = append(lines, "};")
|
||||||
}
|
}
|
||||||
@ -108,7 +108,7 @@ func Compile(p *shaderir.Program, vertex, fragment string) (shader string) {
|
|||||||
"\tconst device Attributes* attributes [[buffer(0)]]")
|
"\tconst device Attributes* attributes [[buffer(0)]]")
|
||||||
for i, u := range p.Uniforms {
|
for i, u := range p.Uniforms {
|
||||||
lines[len(lines)-1] += ","
|
lines[len(lines)-1] += ","
|
||||||
lines = append(lines, fmt.Sprintf("\tconstant %s [[buffer(%d)]]", c.varDecl(p, &u, fmt.Sprintf("U%d", i), false, true), i+1))
|
lines = append(lines, fmt.Sprintf("\tconstant %s [[buffer(%d)]]", c.varDecl(p, &u, fmt.Sprintf("U%d", i), true), i+1))
|
||||||
}
|
}
|
||||||
for i := 0; i < p.TextureNum; i++ {
|
for i := 0; i < p.TextureNum; i++ {
|
||||||
lines[len(lines)-1] += ","
|
lines[len(lines)-1] += ","
|
||||||
@ -130,7 +130,7 @@ func Compile(p *shaderir.Program, vertex, fragment string) (shader string) {
|
|||||||
"\tVaryings varyings [[stage_in]]")
|
"\tVaryings varyings [[stage_in]]")
|
||||||
for i, u := range p.Uniforms {
|
for i, u := range p.Uniforms {
|
||||||
lines[len(lines)-1] += ","
|
lines[len(lines)-1] += ","
|
||||||
lines = append(lines, fmt.Sprintf("\tconstant %s [[buffer(%d)]]", c.varDecl(p, &u, fmt.Sprintf("U%d", i), false, true), i+1))
|
lines = append(lines, fmt.Sprintf("\tconstant %s [[buffer(%d)]]", c.varDecl(p, &u, fmt.Sprintf("U%d", i), true), i+1))
|
||||||
}
|
}
|
||||||
for i := 0; i < p.TextureNum; i++ {
|
for i := 0; i < p.TextureNum; i++ {
|
||||||
lines[len(lines)-1] += ","
|
lines[len(lines)-1] += ","
|
||||||
@ -153,7 +153,7 @@ func Compile(p *shaderir.Program, vertex, fragment string) (shader string) {
|
|||||||
for i, t := range c.structTypes {
|
for i, t := range c.structTypes {
|
||||||
stlines = append(stlines, fmt.Sprintf("struct S%d {", i))
|
stlines = append(stlines, fmt.Sprintf("struct S%d {", i))
|
||||||
for j, st := range t.Sub {
|
for j, st := range t.Sub {
|
||||||
stlines = append(stlines, fmt.Sprintf("\t%s;", c.varDecl(p, &st, fmt.Sprintf("M%d", j), false, false)))
|
stlines = append(stlines, fmt.Sprintf("\t%s;", c.varDecl(p, &st, fmt.Sprintf("M%d", j), false)))
|
||||||
}
|
}
|
||||||
stlines = append(stlines, "};")
|
stlines = append(stlines, "};")
|
||||||
}
|
}
|
||||||
@ -169,18 +169,18 @@ func Compile(p *shaderir.Program, vertex, fragment string) (shader string) {
|
|||||||
return ls
|
return ls
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *compileContext) typ(p *shaderir.Program, t *shaderir.Type, packed bool, ref bool) string {
|
func (c *compileContext) typ(p *shaderir.Program, t *shaderir.Type) string {
|
||||||
switch t.Main {
|
switch t.Main {
|
||||||
case shaderir.None:
|
case shaderir.None:
|
||||||
return "void"
|
return "void"
|
||||||
case shaderir.Struct:
|
case shaderir.Struct:
|
||||||
return c.structName(p, t)
|
return c.structName(p, t)
|
||||||
default:
|
default:
|
||||||
return typeString(t, packed, ref)
|
return typeString(t, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *compileContext) varDecl(p *shaderir.Program, t *shaderir.Type, varname string, packed bool, ref bool) string {
|
func (c *compileContext) varDecl(p *shaderir.Program, t *shaderir.Type, varname string, ref bool) string {
|
||||||
switch t.Main {
|
switch t.Main {
|
||||||
case shaderir.None:
|
case shaderir.None:
|
||||||
return "?(none)"
|
return "?(none)"
|
||||||
@ -191,7 +191,7 @@ func (c *compileContext) varDecl(p *shaderir.Program, t *shaderir.Type, varname
|
|||||||
}
|
}
|
||||||
return fmt.Sprintf("%s %s", s, varname)
|
return fmt.Sprintf("%s %s", s, varname)
|
||||||
default:
|
default:
|
||||||
t := typeString(t, packed, ref)
|
t := typeString(t, ref)
|
||||||
return fmt.Sprintf("%s %s", t, varname)
|
return fmt.Sprintf("%s %s", t, varname)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -209,9 +209,9 @@ func (c *compileContext) varInit(p *shaderir.Program, t *shaderir.Type) string {
|
|||||||
case shaderir.Int:
|
case shaderir.Int:
|
||||||
return "0"
|
return "0"
|
||||||
case shaderir.Float, shaderir.Vec2, shaderir.Vec3, shaderir.Vec4, shaderir.Mat2, shaderir.Mat3, shaderir.Mat4:
|
case shaderir.Float, shaderir.Vec2, shaderir.Vec3, shaderir.Vec4, shaderir.Mat2, shaderir.Mat3, shaderir.Mat4:
|
||||||
return fmt.Sprintf("%s(0)", basicTypeString(t.Main, false))
|
return fmt.Sprintf("%s(0)", basicTypeString(t.Main))
|
||||||
default:
|
default:
|
||||||
t := c.typ(p, t, false, false)
|
t := c.typ(p, t)
|
||||||
panic(fmt.Sprintf("?(unexpected type: %s)", t))
|
panic(fmt.Sprintf("?(unexpected type: %s)", t))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -221,7 +221,7 @@ func (c *compileContext) function(p *shaderir.Program, f *shaderir.Func, prototy
|
|||||||
|
|
||||||
// Uniform variables and texture variables. In Metal, non-const global variables are not available.
|
// Uniform variables and texture variables. In Metal, non-const global variables are not available.
|
||||||
for i, u := range p.Uniforms {
|
for i, u := range p.Uniforms {
|
||||||
args = append(args, "constant "+c.varDecl(p, &u, fmt.Sprintf("U%d", i), false, true))
|
args = append(args, "constant "+c.varDecl(p, &u, fmt.Sprintf("U%d", i), true))
|
||||||
}
|
}
|
||||||
for i := 0; i < p.TextureNum; i++ {
|
for i := 0; i < p.TextureNum; i++ {
|
||||||
args = append(args, fmt.Sprintf("texture2d<float> T%d", i))
|
args = append(args, fmt.Sprintf("texture2d<float> T%d", i))
|
||||||
@ -229,11 +229,11 @@ func (c *compileContext) function(p *shaderir.Program, f *shaderir.Func, prototy
|
|||||||
|
|
||||||
var idx int
|
var idx int
|
||||||
for _, t := range f.InParams {
|
for _, t := range f.InParams {
|
||||||
args = append(args, c.varDecl(p, &t, fmt.Sprintf("l%d", idx), false, false))
|
args = append(args, c.varDecl(p, &t, fmt.Sprintf("l%d", idx), false))
|
||||||
idx++
|
idx++
|
||||||
}
|
}
|
||||||
for _, t := range f.OutParams {
|
for _, t := range f.OutParams {
|
||||||
args = append(args, "thread "+c.varDecl(p, &t, fmt.Sprintf("l%d", idx), false, true))
|
args = append(args, "thread "+c.varDecl(p, &t, fmt.Sprintf("l%d", idx), true))
|
||||||
idx++
|
idx++
|
||||||
}
|
}
|
||||||
argsstr := "void"
|
argsstr := "void"
|
||||||
@ -241,7 +241,7 @@ func (c *compileContext) function(p *shaderir.Program, f *shaderir.Func, prototy
|
|||||||
argsstr = strings.Join(args, ", ")
|
argsstr = strings.Join(args, ", ")
|
||||||
}
|
}
|
||||||
|
|
||||||
t := c.typ(p, &f.Return, false, false)
|
t := c.typ(p, &f.Return)
|
||||||
sig := fmt.Sprintf("%s F%d(%s)", t, f.Index, argsstr)
|
sig := fmt.Sprintf("%s F%d(%s)", t, f.Index, argsstr)
|
||||||
|
|
||||||
var lines []string
|
var lines []string
|
||||||
@ -323,7 +323,7 @@ func (c *compileContext) initVariable(p *shaderir.Program, topBlock, block *shad
|
|||||||
|
|
||||||
var lines []string
|
var lines []string
|
||||||
if decl {
|
if decl {
|
||||||
lines = append(lines, fmt.Sprintf("%s%s = %s;", idt, c.varDecl(p, &t, name, false, false), c.varInit(p, &t)))
|
lines = append(lines, fmt.Sprintf("%s%s = %s;", idt, c.varDecl(p, &t, name, false), c.varInit(p, &t)))
|
||||||
} else {
|
} else {
|
||||||
lines = append(lines, fmt.Sprintf("%s%s = %s;", idt, name, c.varInit(p, &t)))
|
lines = append(lines, fmt.Sprintf("%s%s = %s;", idt, name, c.varInit(p, &t)))
|
||||||
}
|
}
|
||||||
@ -477,7 +477,7 @@ func (c *compileContext) block(p *shaderir.Program, topBlock, block *shaderir.Bl
|
|||||||
t := s.ForVarType
|
t := s.ForVarType
|
||||||
init := constantToNumberLiteral(ct, s.ForInit)
|
init := constantToNumberLiteral(ct, s.ForInit)
|
||||||
end := constantToNumberLiteral(ct, s.ForEnd)
|
end := constantToNumberLiteral(ct, s.ForEnd)
|
||||||
ts := typeString(&t, false, false)
|
ts := typeString(&t, false)
|
||||||
lines = append(lines, fmt.Sprintf("%sfor (%s %s = %s; %s %s %s; %s) {", idt, ts, v, init, v, op, end, delta))
|
lines = append(lines, fmt.Sprintf("%sfor (%s %s = %s; %s %s %s; %s) {", idt, ts, v, init, v, op, end, delta))
|
||||||
lines = append(lines, c.block(p, topBlock, s.Blocks[0], level+1)...)
|
lines = append(lines, c.block(p, topBlock, s.Blocks[0], level+1)...)
|
||||||
lines = append(lines, fmt.Sprintf("%s}", idt))
|
lines = append(lines, fmt.Sprintf("%s}", idt))
|
||||||
|
@ -64,10 +64,10 @@ func opString(op shaderir.Op) string {
|
|||||||
return fmt.Sprintf("?(unexpected operator: %d)", op)
|
return fmt.Sprintf("?(unexpected operator: %d)", op)
|
||||||
}
|
}
|
||||||
|
|
||||||
func typeString(t *shaderir.Type, packed bool, ref bool) string {
|
func typeString(t *shaderir.Type, ref bool) string {
|
||||||
switch t.Main {
|
switch t.Main {
|
||||||
case shaderir.Array:
|
case shaderir.Array:
|
||||||
st := typeString(&t.Sub[0], packed, false)
|
st := typeString(&t.Sub[0], false)
|
||||||
t := fmt.Sprintf("array<%s, %d>", st, t.Length)
|
t := fmt.Sprintf("array<%s, %d>", st, t.Length)
|
||||||
if ref {
|
if ref {
|
||||||
t += "&"
|
t += "&"
|
||||||
@ -76,7 +76,7 @@ func typeString(t *shaderir.Type, packed bool, ref bool) string {
|
|||||||
case shaderir.Struct:
|
case shaderir.Struct:
|
||||||
panic("msl: a struct is not implemented")
|
panic("msl: a struct is not implemented")
|
||||||
default:
|
default:
|
||||||
t := basicTypeString(t.Main, packed)
|
t := basicTypeString(t.Main)
|
||||||
if ref {
|
if ref {
|
||||||
t += "&"
|
t += "&"
|
||||||
}
|
}
|
||||||
@ -84,7 +84,7 @@ func typeString(t *shaderir.Type, packed bool, ref bool) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func basicTypeString(t shaderir.BasicType, packed bool) string {
|
func basicTypeString(t shaderir.BasicType) string {
|
||||||
switch t {
|
switch t {
|
||||||
case shaderir.None:
|
case shaderir.None:
|
||||||
return "?(none)"
|
return "?(none)"
|
||||||
@ -95,19 +95,10 @@ func basicTypeString(t shaderir.BasicType, packed bool) string {
|
|||||||
case shaderir.Float:
|
case shaderir.Float:
|
||||||
return "float"
|
return "float"
|
||||||
case shaderir.Vec2:
|
case shaderir.Vec2:
|
||||||
if packed {
|
|
||||||
return "packed_float2"
|
|
||||||
}
|
|
||||||
return "float2"
|
return "float2"
|
||||||
case shaderir.Vec3:
|
case shaderir.Vec3:
|
||||||
if packed {
|
|
||||||
return "packed_float3"
|
|
||||||
}
|
|
||||||
return "float3"
|
return "float3"
|
||||||
case shaderir.Vec4:
|
case shaderir.Vec4:
|
||||||
if packed {
|
|
||||||
return "packed_float4"
|
|
||||||
}
|
|
||||||
return "float4"
|
return "float4"
|
||||||
case shaderir.Mat2:
|
case shaderir.Mat2:
|
||||||
return "float2x2"
|
return "float2x2"
|
||||||
|
Loading…
Reference in New Issue
Block a user