mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-27 12:18:55 +01:00
1282 lines
64 KiB
Go
1282 lines
64 KiB
Go
// Copyright 2018 The Ebiten Authors
|
||
//
|
||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||
// you may not use this file except in compliance with the License.
|
||
// You may obtain a copy of the License at
|
||
//
|
||
// http://www.apache.org/licenses/LICENSE-2.0
|
||
//
|
||
// Unless required by applicable law or agreed to in writing, software
|
||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
// See the License for the specific language governing permissions and
|
||
// limitations under the License.
|
||
|
||
// Package mtl provides access to Apple's Metal API (https://developer.apple.com/documentation/metal).
|
||
//
|
||
// Package mtl requires macOS version 10.12 or newer.
|
||
//
|
||
// This package is in very early stages of development.
|
||
// The API will change when opportunities for improvement are discovered; it is not yet frozen.
|
||
// Less than 20% of the Metal API surface is implemented.
|
||
// Current functionality is sufficient to render very basic geometry.
|
||
package mtl
|
||
|
||
import (
|
||
"errors"
|
||
"fmt"
|
||
"runtime"
|
||
"unsafe"
|
||
|
||
"github.com/ebitengine/purego"
|
||
"github.com/ebitengine/purego/objc"
|
||
|
||
"github.com/hajimehoshi/ebiten/v2/internal/cocoa"
|
||
)
|
||
|
||
// GPUFamily represents the functionality for families of GPUs.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlgpufamily?language=objc.
|
||
type GPUFamily int
|
||
|
||
const (
|
||
GPUFamilyApple1 GPUFamily = 1001
|
||
GPUFamilyApple2 GPUFamily = 1002
|
||
GPUFamilyApple3 GPUFamily = 1003
|
||
GPUFamilyApple4 GPUFamily = 1004
|
||
GPUFamilyApple5 GPUFamily = 1005
|
||
GPUFamilyApple6 GPUFamily = 1006
|
||
GPUFamilyApple7 GPUFamily = 1007
|
||
GPUFamilyApple8 GPUFamily = 1008
|
||
|
||
GPUFamilyMac2 GPUFamily = 2002
|
||
)
|
||
|
||
// FeatureSet defines a specific platform, hardware, and software configuration.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlfeatureset?language=objc.
|
||
type FeatureSet uint16
|
||
|
||
const (
|
||
FeatureSet_iOS_GPUFamily1_v1 FeatureSet = 0
|
||
FeatureSet_iOS_GPUFamily1_v2 FeatureSet = 2
|
||
FeatureSet_iOS_GPUFamily1_v3 FeatureSet = 5
|
||
FeatureSet_iOS_GPUFamily1_v4 FeatureSet = 8
|
||
FeatureSet_iOS_GPUFamily1_v5 FeatureSet = 12
|
||
FeatureSet_iOS_GPUFamily2_v1 FeatureSet = 1
|
||
FeatureSet_iOS_GPUFamily2_v2 FeatureSet = 3
|
||
FeatureSet_iOS_GPUFamily2_v3 FeatureSet = 6
|
||
FeatureSet_iOS_GPUFamily2_v4 FeatureSet = 9
|
||
FeatureSet_iOS_GPUFamily2_v5 FeatureSet = 13
|
||
FeatureSet_iOS_GPUFamily3_v1 FeatureSet = 4
|
||
FeatureSet_iOS_GPUFamily3_v2 FeatureSet = 7
|
||
FeatureSet_iOS_GPUFamily3_v3 FeatureSet = 10
|
||
FeatureSet_iOS_GPUFamily3_v4 FeatureSet = 14
|
||
FeatureSet_iOS_GPUFamily4_v1 FeatureSet = 11
|
||
FeatureSet_iOS_GPUFamily4_v2 FeatureSet = 15
|
||
FeatureSet_iOS_GPUFamily5_v1 FeatureSet = 16
|
||
FeatureSet_tvOS_GPUFamily1_v1 FeatureSet = 30000
|
||
FeatureSet_tvOS_GPUFamily1_v2 FeatureSet = 30001
|
||
FeatureSet_tvOS_GPUFamily1_v3 FeatureSet = 30002
|
||
FeatureSet_tvOS_GPUFamily1_v4 FeatureSet = 30004
|
||
FeatureSet_tvOS_GPUFamily2_v1 FeatureSet = 30003
|
||
FeatureSet_tvOS_GPUFamily2_v2 FeatureSet = 30005
|
||
FeatureSet_macOS_GPUFamily1_v1 FeatureSet = 10000
|
||
FeatureSet_macOS_GPUFamily1_v2 FeatureSet = 10001
|
||
FeatureSet_macOS_GPUFamily1_v3 FeatureSet = 10003
|
||
FeatureSet_macOS_GPUFamily1_v4 FeatureSet = 10004
|
||
FeatureSet_macOS_GPUFamily2_v1 FeatureSet = 10005
|
||
FeatureSet_macOS_ReadWriteTextureTier2 FeatureSet = 10002
|
||
)
|
||
|
||
// TextureType defines The dimension of each image, including whether multiple images are arranged into an array or
|
||
// a cube.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtltexturetype?language=objc.
|
||
type TextureType uint16
|
||
|
||
const (
|
||
TextureType2D TextureType = 2
|
||
)
|
||
|
||
// PixelFormat defines data formats that describe the organization
|
||
// and characteristics of individual pixels in a texture.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlpixelformat?language=objc.
|
||
type PixelFormat uint16
|
||
|
||
// The data formats that describe the organization and characteristics
|
||
// of individual pixels in a texture.
|
||
const (
|
||
PixelFormatRGBA8UNorm PixelFormat = 70 // Ordinary format with four 8-bit normalized unsigned integer components in RGBA order.
|
||
PixelFormatRGBA8UNormSRGB PixelFormat = 71 // Ordinary format with four 8-bit normalized unsigned integer components in RGBA order with conversion between sRGB and linear space.
|
||
PixelFormatBGRA8UNorm PixelFormat = 80 // Ordinary format with four 8-bit normalized unsigned integer components in BGRA order.
|
||
PixelFormatBGRA8UNormSRGB PixelFormat = 81 // Ordinary format with four 8-bit normalized unsigned integer components in BGRA order with conversion between sRGB and linear space.
|
||
PixelFormatStencil8 PixelFormat = 253 // A pixel format with an 8-bit unsigned integer component, used for a stencil render target.
|
||
)
|
||
|
||
// PrimitiveType defines geometric primitive types for drawing commands.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlprimitivetype?language=objc.
|
||
type PrimitiveType uint8
|
||
|
||
// Geometric primitive types for drawing commands.
|
||
const (
|
||
PrimitiveTypePoint PrimitiveType = 0
|
||
PrimitiveTypeLine PrimitiveType = 1
|
||
PrimitiveTypeLineStrip PrimitiveType = 2
|
||
PrimitiveTypeTriangle PrimitiveType = 3
|
||
PrimitiveTypeTriangleStrip PrimitiveType = 4
|
||
)
|
||
|
||
// LoadAction defines actions performed at the start of a rendering pass
|
||
// for a render command encoder.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlloadaction?language=objc.
|
||
type LoadAction uint8
|
||
|
||
// Actions performed at the start of a rendering pass for a render command encoder.
|
||
const (
|
||
LoadActionDontCare LoadAction = 0
|
||
LoadActionLoad LoadAction = 1
|
||
LoadActionClear LoadAction = 2
|
||
)
|
||
|
||
// StoreAction defines actions performed at the end of a rendering pass
|
||
// for a render command encoder.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlstoreaction?language=objc.
|
||
type StoreAction uint8
|
||
|
||
// Actions performed at the end of a rendering pass for a render command encoder.
|
||
const (
|
||
StoreActionDontCare StoreAction = 0
|
||
StoreActionStore StoreAction = 1
|
||
StoreActionMultisampleResolve StoreAction = 2
|
||
StoreActionStoreAndMultisampleResolve StoreAction = 3
|
||
StoreActionUnknown StoreAction = 4
|
||
StoreActionCustomSampleDepthStore StoreAction = 5
|
||
)
|
||
|
||
// StorageMode defines the memory location and access permissions of a resource.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlstoragemode?language=objc.
|
||
type StorageMode uint8
|
||
|
||
const (
|
||
// StorageModeShared indicates that the resource is stored in system memory
|
||
// accessible to both the CPU and the GPU.
|
||
StorageModeShared StorageMode = 0
|
||
|
||
// StorageModeManaged indicates that the resource exists as a synchronized
|
||
// memory pair with one copy stored in system memory accessible to the CPU
|
||
// and another copy stored in video memory accessible to the GPU.
|
||
StorageModeManaged StorageMode = 1
|
||
|
||
// StorageModePrivate indicates that the resource is stored in memory
|
||
// only accessible to the GPU. In iOS and tvOS, the resource is stored in
|
||
// system memory. In macOS, the resource is stored in video memory.
|
||
StorageModePrivate StorageMode = 2
|
||
|
||
// StorageModeMemoryless indicates that the resource is stored in on-tile memory,
|
||
// without CPU or GPU memory backing. The contents of the on-tile memory are undefined
|
||
// and do not persist; the only way to populate the resource is to render into it.
|
||
// Memoryless resources are limited to temporary render targets (i.e., Textures configured
|
||
// with a TextureDescriptor and used with a RenderPassAttachmentDescriptor).
|
||
StorageModeMemoryless StorageMode = 3
|
||
)
|
||
|
||
// ResourceOptions defines optional arguments used to create
|
||
// and influence behavior of buffer and texture objects.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlresourceoptions?language=objc.
|
||
type ResourceOptions uint16
|
||
|
||
const (
|
||
// ResourceCPUCacheModeDefaultCache is the default CPU cache mode for the resource.
|
||
// Guarantees that read and write operations are executed in the expected order.
|
||
ResourceCPUCacheModeDefaultCache ResourceOptions = ResourceOptions(CPUCacheModeDefaultCache) << resourceCPUCacheModeShift
|
||
|
||
// ResourceCPUCacheModeWriteCombined is a write-combined CPU cache mode for the resource.
|
||
// Optimized for resources that the CPU will write into, but never read.
|
||
ResourceCPUCacheModeWriteCombined ResourceOptions = ResourceOptions(CPUCacheModeWriteCombined) << resourceCPUCacheModeShift
|
||
|
||
// ResourceStorageModeShared indicates that the resource is stored in system memory
|
||
// accessible to both the CPU and the GPU.
|
||
ResourceStorageModeShared ResourceOptions = ResourceOptions(StorageModeShared) << resourceStorageModeShift
|
||
|
||
// ResourceStorageModeManaged indicates that the resource exists as a synchronized
|
||
// memory pair with one copy stored in system memory accessible to the CPU
|
||
// and another copy stored in video memory accessible to the GPU.
|
||
ResourceStorageModeManaged ResourceOptions = ResourceOptions(StorageModeManaged) << resourceStorageModeShift
|
||
|
||
// ResourceStorageModePrivate indicates that the resource is stored in memory
|
||
// only accessible to the GPU. In iOS and tvOS, the resource is stored
|
||
// in system memory. In macOS, the resource is stored in video memory.
|
||
ResourceStorageModePrivate ResourceOptions = ResourceOptions(StorageModePrivate) << resourceStorageModeShift
|
||
|
||
// ResourceStorageModeMemoryless indicates that the resource is stored in on-tile memory,
|
||
// without CPU or GPU memory backing. The contents of the on-tile memory are undefined
|
||
// and do not persist; the only way to populate the resource is to render into it.
|
||
// Memoryless resources are limited to temporary render targets (i.e., Textures configured
|
||
// with a TextureDescriptor and used with a RenderPassAttachmentDescriptor).
|
||
ResourceStorageModeMemoryless ResourceOptions = ResourceOptions(StorageModeMemoryless) << resourceStorageModeShift
|
||
|
||
// ResourceHazardTrackingModeUntracked indicates that the command encoder dependencies
|
||
// for this resource are tracked manually with Fence objects. This value is always set
|
||
// for resources sub-allocated from a Heap object and may optionally be specified for
|
||
// non-heap resources.
|
||
ResourceHazardTrackingModeUntracked ResourceOptions = 1 << resourceHazardTrackingModeShift
|
||
)
|
||
|
||
const (
|
||
resourceCPUCacheModeShift = 0
|
||
resourceStorageModeShift = 4
|
||
resourceHazardTrackingModeShift = 8
|
||
)
|
||
|
||
// CPUCacheMode is the CPU cache mode that defines the CPU mapping of a resource.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlcpucachemode?language=objc.
|
||
type CPUCacheMode uint8
|
||
|
||
const (
|
||
// CPUCacheModeDefaultCache is the default CPU cache mode for the resource.
|
||
// Guarantees that read and write operations are executed in the expected order.
|
||
CPUCacheModeDefaultCache CPUCacheMode = 0
|
||
|
||
// CPUCacheModeWriteCombined is a write-combined CPU cache mode for the resource.
|
||
// Optimized for resources that the CPU will write into, but never read.
|
||
CPUCacheModeWriteCombined CPUCacheMode = 1
|
||
)
|
||
|
||
// IndexType is the index type for an index buffer that references vertices of geometric primitives.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlstoragemode?language=objc
|
||
type IndexType uint8
|
||
|
||
const (
|
||
// IndexTypeUInt16 is a 16-bit unsigned integer used as a primitive index.
|
||
IndexTypeUInt16 IndexType = 0
|
||
|
||
// IndexTypeUInt32 is a 32-bit unsigned integer used as a primitive index.
|
||
IndexTypeUInt32 IndexType = 1
|
||
)
|
||
|
||
type TextureUsage uint8
|
||
|
||
const (
|
||
TextureUsageUnknown TextureUsage = 0x0000
|
||
TextureUsageShaderRead TextureUsage = 0x0001
|
||
TextureUsageShaderWrite TextureUsage = 0x0002
|
||
TextureUsageRenderTarget TextureUsage = 0x0004
|
||
TextureUsagePixelFormatView TextureUsage = 0x0008
|
||
)
|
||
|
||
type BlendFactor uint8
|
||
|
||
const (
|
||
BlendFactorZero BlendFactor = 0
|
||
BlendFactorOne BlendFactor = 1
|
||
BlendFactorSourceColor BlendFactor = 2
|
||
BlendFactorOneMinusSourceColor BlendFactor = 3
|
||
BlendFactorSourceAlpha BlendFactor = 4
|
||
BlendFactorOneMinusSourceAlpha BlendFactor = 5
|
||
BlendFactorDestinationColor BlendFactor = 6
|
||
BlendFactorOneMinusDestinationColor BlendFactor = 7
|
||
BlendFactorDestinationAlpha BlendFactor = 8
|
||
BlendFactorOneMinusDestinationAlpha BlendFactor = 9
|
||
BlendFactorSourceAlphaSaturated BlendFactor = 10
|
||
BlendFactorBlendColor BlendFactor = 11
|
||
BlendFactorOneMinusBlendColor BlendFactor = 12
|
||
BlendFactorBlendAlpha BlendFactor = 13
|
||
BlendFactorOneMinusBlendAlpha BlendFactor = 14
|
||
BlendFactorSource1Color BlendFactor = 15
|
||
BlendFactorOneMinusSource1Color BlendFactor = 16
|
||
BlendFactorSource1Alpha BlendFactor = 17
|
||
BlendFactorOneMinusSource1Alpha BlendFactor = 18
|
||
)
|
||
|
||
type BlendOperation uint8
|
||
|
||
const (
|
||
BlendOperationAdd BlendOperation = 0
|
||
BlendOperationSubtract BlendOperation = 1
|
||
BlendOperationReverseSubtract BlendOperation = 2
|
||
BlendOperationMin BlendOperation = 3
|
||
BlendOperationMax BlendOperation = 4
|
||
)
|
||
|
||
type ColorWriteMask uint8
|
||
|
||
const (
|
||
ColorWriteMaskNone ColorWriteMask = 0
|
||
ColorWriteMaskRed ColorWriteMask = 0x1 << 3
|
||
ColorWriteMaskGreen ColorWriteMask = 0x1 << 2
|
||
ColorWriteMaskBlue ColorWriteMask = 0x1 << 1
|
||
ColorWriteMaskAlpha ColorWriteMask = 0x1 << 0
|
||
ColorWriteMaskAll ColorWriteMask = 0xf
|
||
)
|
||
|
||
type StencilOperation uint8
|
||
|
||
const (
|
||
StencilOperationKeep StencilOperation = 0
|
||
StencilOperationZero StencilOperation = 1
|
||
StencilOperationReplace StencilOperation = 2
|
||
StencilOperationIncrementClamp StencilOperation = 3
|
||
StencilOperationDecrementClamp StencilOperation = 4
|
||
StencilOperationInvert StencilOperation = 5
|
||
StencilOperationIncrementWrap StencilOperation = 6
|
||
StencilOperationDecrementWrap StencilOperation = 7
|
||
)
|
||
|
||
type CompareFunction uint8
|
||
|
||
const (
|
||
CompareFunctionNever CompareFunction = 0
|
||
CompareFunctionLess CompareFunction = 1
|
||
CompareFunctionEqual CompareFunction = 2
|
||
CompareFunctionLessEqual CompareFunction = 3
|
||
CompareFunctionGreater CompareFunction = 4
|
||
CompareFunctionNotEqual CompareFunction = 5
|
||
CompareFunctionGreaterEqual CompareFunction = 6
|
||
CompareFunctionAlways CompareFunction = 7
|
||
)
|
||
|
||
type CommandBufferStatus uint8
|
||
|
||
const (
|
||
CommandBufferStatusNotEnqueued CommandBufferStatus = 0 //The command buffer is not enqueued yet.
|
||
CommandBufferStatusEnqueued CommandBufferStatus = 1 // The command buffer is enqueued.
|
||
CommandBufferStatusCommitted CommandBufferStatus = 2 // The command buffer is committed for execution.
|
||
CommandBufferStatusScheduled CommandBufferStatus = 3 // The command buffer is scheduled.
|
||
CommandBufferStatusCompleted CommandBufferStatus = 4 // The command buffer completed execution successfully.
|
||
CommandBufferStatusError CommandBufferStatus = 5 // Execution of the command buffer was aborted due to an error during execution.
|
||
)
|
||
|
||
// Resource represents a memory allocation for storing specialized data
|
||
// that is accessible to the GPU.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlresource?language=objc.
|
||
type Resource interface {
|
||
// resource returns the underlying id<MTLResource> pointer.
|
||
resource() unsafe.Pointer
|
||
}
|
||
|
||
// RenderPipelineDescriptor configures new RenderPipelineState objects.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlrenderpipelinedescriptor?language=objc.
|
||
type RenderPipelineDescriptor struct {
|
||
// VertexFunction is a programmable function that processes individual vertices in a rendering pass.
|
||
VertexFunction Function
|
||
|
||
// FragmentFunction is a programmable function that processes individual fragments in a rendering pass.
|
||
FragmentFunction Function
|
||
|
||
// ColorAttachments is an array of attachments that store color data.
|
||
ColorAttachments [1]RenderPipelineColorAttachmentDescriptor
|
||
|
||
// StencilAttachmentPixelFormat is the pixel format of the attachment that stores stencil data.
|
||
StencilAttachmentPixelFormat PixelFormat
|
||
}
|
||
|
||
// RenderPipelineColorAttachmentDescriptor describes a color render target that specifies
|
||
// the color configuration and color operations associated with a render pipeline.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlrenderpipelinecolorattachmentdescriptor?language=objc.
|
||
type RenderPipelineColorAttachmentDescriptor struct {
|
||
// PixelFormat is the pixel format of the color attachment's texture.
|
||
PixelFormat PixelFormat
|
||
|
||
BlendingEnabled bool
|
||
|
||
DestinationAlphaBlendFactor BlendFactor
|
||
DestinationRGBBlendFactor BlendFactor
|
||
SourceAlphaBlendFactor BlendFactor
|
||
SourceRGBBlendFactor BlendFactor
|
||
AlphaBlendOperation BlendOperation
|
||
RGBBlendOperation BlendOperation
|
||
|
||
WriteMask ColorWriteMask
|
||
}
|
||
|
||
// RenderPassDescriptor describes a group of render targets that serve as
|
||
// the output destination for pixels generated by a render pass.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlrenderpassdescriptor?language=objc.
|
||
type RenderPassDescriptor struct {
|
||
// ColorAttachments is array of state information for attachments that store color data.
|
||
ColorAttachments [1]RenderPassColorAttachmentDescriptor
|
||
|
||
// StencilAttachment is state information for an attachment that stores stencil data.
|
||
StencilAttachment RenderPassStencilAttachment
|
||
}
|
||
|
||
// RenderPassColorAttachmentDescriptor describes a color render target that serves
|
||
// as the output destination for color pixels generated by a render pass.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlrenderpasscolorattachmentdescriptor?language=objc.
|
||
type RenderPassColorAttachmentDescriptor struct {
|
||
RenderPassAttachmentDescriptor
|
||
ClearColor ClearColor
|
||
}
|
||
|
||
// RenderPassStencilAttachment describes a stencil render target that serves as the output
|
||
// destination for stencil pixels generated by a render pass.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlrenderpassstencilattachmentdescriptor?language=objc.
|
||
type RenderPassStencilAttachment struct {
|
||
RenderPassAttachmentDescriptor
|
||
}
|
||
|
||
// RenderPassAttachmentDescriptor describes a render target that serves
|
||
// as the output destination for pixels generated by a render pass.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlrenderpassattachmentdescriptor?language=objc.
|
||
type RenderPassAttachmentDescriptor struct {
|
||
LoadAction LoadAction
|
||
StoreAction StoreAction
|
||
Texture Texture
|
||
}
|
||
|
||
// ClearColor is an RGBA value used for a color pixel.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlclearcolor?language=objc.
|
||
type ClearColor struct {
|
||
Red, Green, Blue, Alpha float64
|
||
}
|
||
|
||
// TextureDescriptor configures new Texture objects.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtltexturedescriptor?language=objc.
|
||
type TextureDescriptor struct {
|
||
TextureType TextureType
|
||
PixelFormat PixelFormat
|
||
Width int
|
||
Height int
|
||
StorageMode StorageMode
|
||
Usage TextureUsage
|
||
}
|
||
|
||
// Device is abstract representation of the GPU that
|
||
// serves as the primary interface for a Metal app.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtldevice?language=objc.
|
||
type Device struct {
|
||
device objc.ID
|
||
|
||
// Headless indicates whether a device is configured as headless.
|
||
Headless bool
|
||
|
||
// LowPower indicates whether a device is low-power.
|
||
LowPower bool
|
||
|
||
// Name is the name of the device.
|
||
Name string
|
||
}
|
||
|
||
var (
|
||
class_MTLRenderPipelineDescriptor = objc.GetClass("MTLRenderPipelineDescriptor")
|
||
class_MTLTextureDescriptor = objc.GetClass("MTLTextureDescriptor")
|
||
class_MTLDepthStencilDescriptor = objc.GetClass("MTLDepthStencilDescriptor")
|
||
class_MTLRenderPassDescriptor = objc.GetClass("MTLRenderPassDescriptor")
|
||
)
|
||
|
||
var (
|
||
sel_class = objc.RegisterName("class")
|
||
sel_length = objc.RegisterName("length")
|
||
sel_isHeadless = objc.RegisterName("isHeadless")
|
||
sel_isLowPower = objc.RegisterName("isLowPower")
|
||
sel_name = objc.RegisterName("name")
|
||
sel_supportsFamily = objc.RegisterName("supportsFamily:")
|
||
sel_supportsFeatureSet = objc.RegisterName("supportsFeatureSet:")
|
||
sel_newCommandQueue = objc.RegisterName("newCommandQueue")
|
||
sel_newLibraryWithSource_options_error = objc.RegisterName("newLibraryWithSource:options:error:")
|
||
sel_newLibraryWithData_error = objc.RegisterName("newLibraryWithData:error:")
|
||
sel_release = objc.RegisterName("release")
|
||
sel_retain = objc.RegisterName("retain")
|
||
sel_new = objc.RegisterName("new")
|
||
sel_localizedDescription = objc.RegisterName("localizedDescription")
|
||
sel_setVertexFunction = objc.RegisterName("setVertexFunction:")
|
||
sel_setFragmentFunction = objc.RegisterName("setFragmentFunction:")
|
||
sel_colorAttachments = objc.RegisterName("colorAttachments")
|
||
sel_objectAtIndexedSubscript = objc.RegisterName("objectAtIndexedSubscript:")
|
||
sel_setPixelFormat = objc.RegisterName("setPixelFormat:")
|
||
sel_setBlendingEnabled = objc.RegisterName("setBlendingEnabled:")
|
||
sel_setDestinationAlphaBlendFactor = objc.RegisterName("setDestinationAlphaBlendFactor:")
|
||
sel_setDestinationRGBBlendFactor = objc.RegisterName("setDestinationRGBBlendFactor:")
|
||
sel_setSourceAlphaBlendFactor = objc.RegisterName("setSourceAlphaBlendFactor:")
|
||
sel_setSourceRGBBlendFactor = objc.RegisterName("setSourceRGBBlendFactor:")
|
||
sel_setAlphaBlendOperation = objc.RegisterName("setAlphaBlendOperation:")
|
||
sel_setRgbBlendOperation = objc.RegisterName("setRgbBlendOperation:")
|
||
sel_setWriteMask = objc.RegisterName("setWriteMask:")
|
||
sel_setStencilAttachmentPixelFormat = objc.RegisterName("setStencilAttachmentPixelFormat:")
|
||
sel_newRenderPipelineStateWithDescriptor_error = objc.RegisterName("newRenderPipelineStateWithDescriptor:error:")
|
||
sel_newBufferWithBytes_length_options = objc.RegisterName("newBufferWithBytes:length:options:")
|
||
sel_newBufferWithLength_options = objc.RegisterName("newBufferWithLength:options:")
|
||
sel_setTextureType = objc.RegisterName("setTextureType:")
|
||
sel_didModifyRange = objc.RegisterName("didModifyRange:")
|
||
sel_setWidth = objc.RegisterName("setWidth:")
|
||
sel_setHeight = objc.RegisterName("setHeight:")
|
||
sel_width = objc.RegisterName("width")
|
||
sel_height = objc.RegisterName("height")
|
||
sel_contents = objc.RegisterName("contents")
|
||
sel_setStorageMode = objc.RegisterName("setStorageMode:")
|
||
sel_setUsage = objc.RegisterName("setUsage:")
|
||
sel_newTextureWithDescriptor = objc.RegisterName("newTextureWithDescriptor:")
|
||
sel_commandBuffer = objc.RegisterName("commandBuffer")
|
||
sel_status = objc.RegisterName("status")
|
||
sel_presentDrawable = objc.RegisterName("presentDrawable:")
|
||
sel_commit = objc.RegisterName("commit")
|
||
sel_waitUntilCompleted = objc.RegisterName("waitUntilCompleted")
|
||
sel_waitUntilScheduled = objc.RegisterName("waitUntilScheduled")
|
||
sel_renderCommandEncoderWithDescriptor = objc.RegisterName("renderCommandEncoderWithDescriptor:")
|
||
sel_stencilAttachment = objc.RegisterName("stencilAttachment")
|
||
sel_setLoadAction = objc.RegisterName("setLoadAction:")
|
||
sel_setStoreAction = objc.RegisterName("setStoreAction:")
|
||
sel_setTexture = objc.RegisterName("setTexture:")
|
||
sel_setClearColor = objc.RegisterName("setClearColor:")
|
||
sel_blitCommandEncoder = objc.RegisterName("blitCommandEncoder")
|
||
sel_endEncoding = objc.RegisterName("endEncoding")
|
||
sel_setRenderPipelineState = objc.RegisterName("setRenderPipelineState:")
|
||
sel_setViewport = objc.RegisterName("setViewport:")
|
||
sel_setScissorRect = objc.RegisterName("setScissorRect:")
|
||
sel_setVertexBuffer_offset_atIndex = objc.RegisterName("setVertexBuffer:offset:atIndex:")
|
||
sel_setVertexBytes_length_atIndex = objc.RegisterName("setVertexBytes:length:atIndex:")
|
||
sel_setFragmentBytes_length_atIndex = objc.RegisterName("setFragmentBytes:length:atIndex:")
|
||
sel_setFragmentTexture_atIndex = objc.RegisterName("setFragmentTexture:atIndex:")
|
||
sel_setBlendColorRedGreenBlueAlpha = objc.RegisterName("setBlendColorRed:green:blue:alpha:")
|
||
sel_setDepthStencilState = objc.RegisterName("setDepthStencilState:")
|
||
sel_drawPrimitives_vertexStart_vertexCount = objc.RegisterName("drawPrimitives:vertexStart:vertexCount:")
|
||
sel_drawIndexedPrimitives_indexCount_indexType_indexBuffer_indexBufferOffset = objc.RegisterName("drawIndexedPrimitives:indexCount:indexType:indexBuffer:indexBufferOffset:")
|
||
sel_synchronizeResource = objc.RegisterName("synchronizeResource:")
|
||
sel_synchronizeTexture_slice_level = objc.RegisterName("synchronizeTexture:slice:level:")
|
||
sel_copyFromTexture_sourceSlice_sourceLevel_sourceOrigin_sourceSize_toTexture_destinationSlice_destinationLevel_destinationOrigin = objc.RegisterName("copyFromTexture:sourceSlice:sourceLevel:sourceOrigin:sourceSize:toTexture:destinationSlice:destinationLevel:destinationOrigin:")
|
||
sel_newFunctionWithName = objc.RegisterName("newFunctionWithName:")
|
||
sel_backFaceStencil = objc.RegisterName("backFaceStencil")
|
||
sel_frontFaceStencil = objc.RegisterName("frontFaceStencil")
|
||
sel_setStencilFailureOperation = objc.RegisterName("setStencilFailureOperation:")
|
||
sel_setDepthFailureOperation = objc.RegisterName("setDepthFailureOperation:")
|
||
sel_setDepthStencilPassOperation = objc.RegisterName("setDepthStencilPassOperation:")
|
||
sel_setStencilCompareFunction = objc.RegisterName("setStencilCompareFunction:")
|
||
sel_newDepthStencilStateWithDescriptor = objc.RegisterName("newDepthStencilStateWithDescriptor:")
|
||
sel_replaceRegion_mipmapLevel_withBytes_bytesPerRow = objc.RegisterName("replaceRegion:mipmapLevel:withBytes:bytesPerRow:")
|
||
sel_getBytes_bytesPerRow_fromRegion_mipmapLevel = objc.RegisterName("getBytes:bytesPerRow:fromRegion:mipmapLevel:")
|
||
sel_respondsToSelector = objc.RegisterName("respondsToSelector:")
|
||
)
|
||
|
||
// CreateSystemDefaultDevice returns the preferred system default Metal device.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/1433401-mtlcreatesystemdefaultdevice?language=objc.
|
||
func CreateSystemDefaultDevice() (Device, error) {
|
||
metal, err := purego.Dlopen("/System/Library/Frameworks/Metal.framework/Metal", purego.RTLD_LAZY|purego.RTLD_GLOBAL)
|
||
if err != nil {
|
||
return Device{}, err
|
||
}
|
||
|
||
mtlCreateSystemDefaultDevice, err := purego.Dlsym(metal, "MTLCreateSystemDefaultDevice")
|
||
if err != nil {
|
||
return Device{}, err
|
||
}
|
||
|
||
d, _, _ := purego.SyscallN(mtlCreateSystemDefaultDevice)
|
||
if d == 0 {
|
||
return Device{}, fmt.Errorf("mtl: MTLCreateSystemDefaultDevice returned 0")
|
||
}
|
||
var (
|
||
headless bool
|
||
lowPower bool
|
||
name string
|
||
)
|
||
if runtime.GOOS != "ios" {
|
||
headless = int(objc.ID(d).Send(sel_isHeadless)) != 0
|
||
lowPower = int(objc.ID(d).Send(sel_isLowPower)) != 0
|
||
}
|
||
name = cocoa.NSString{ID: objc.ID(d).Send(sel_name)}.String()
|
||
|
||
return Device{
|
||
device: objc.ID(d),
|
||
Headless: headless,
|
||
LowPower: lowPower,
|
||
Name: name,
|
||
}, nil
|
||
}
|
||
|
||
// Device returns the underlying id<MTLDevice> pointer.
|
||
func (d Device) Device() unsafe.Pointer { return *(*unsafe.Pointer)(unsafe.Pointer(&d.device)) }
|
||
|
||
// RespondsToSelector returns a Boolean value that indicates whether the receiver implements or inherits a method that can respond to a specified message.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/objectivec/1418956-nsobject/1418583-respondstoselector?language=objc.
|
||
func (d Device) RespondsToSelector(sel objc.SEL) bool {
|
||
return d.device.Send(sel_respondsToSelector, sel) != 0
|
||
}
|
||
|
||
// SupportsFamily returns a Boolean value that indicates whether the GPU device supports the feature set of a specific GPU family.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtldevice/3143473-supportsfamily?language=objc.
|
||
func (d Device) SupportsFamily(gpuFamily GPUFamily) bool {
|
||
return d.device.Send(sel_supportsFamily, uintptr(gpuFamily)) != 0
|
||
}
|
||
|
||
// SupportsFeatureSet reports whether device d supports feature set fs.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtldevice/1433418-supportsfeatureset?language=objc.
|
||
func (d Device) SupportsFeatureSet(fs FeatureSet) bool {
|
||
return d.device.Send(sel_supportsFeatureSet, uintptr(fs)) != 0
|
||
}
|
||
|
||
// NewCommandQueue creates a queue you use to submit rendering and computation commands to a GPU.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtldevice/1433388-newcommandqueue?language=objc.
|
||
func (d Device) NewCommandQueue() CommandQueue {
|
||
return CommandQueue{d.device.Send(sel_newCommandQueue)}
|
||
}
|
||
|
||
// NewLibraryWithSource synchronously creates a Metal library instance by compiling the functions in a source string.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtldevice/1433431-newlibrarywithsource?language=objc.
|
||
func (d Device) NewLibraryWithSource(source string, opt CompileOptions) (Library, error) {
|
||
var err cocoa.NSError
|
||
l := d.device.Send(
|
||
sel_newLibraryWithSource_options_error,
|
||
cocoa.NSString_alloc().InitWithUTF8String(source).ID,
|
||
0,
|
||
unsafe.Pointer(&err),
|
||
)
|
||
if l == 0 {
|
||
return Library{}, errors.New(cocoa.NSString{ID: err.Send(sel_localizedDescription)}.String())
|
||
}
|
||
|
||
return Library{l}, nil
|
||
}
|
||
|
||
// NewLibraryWithData Creates a Metal library instance that contains the functions in a precompiled Metal library.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtldevice/1433391-newlibrarywithdata?language=objc.
|
||
func (d Device) NewLibraryWithData(buffer []byte) (Library, error) {
|
||
defer runtime.KeepAlive(buffer)
|
||
|
||
data := dispatchDataCreate(unsafe.Pointer(&buffer[0]), uint(len(buffer)), 0, 0)
|
||
defer dispatchRelease(data)
|
||
|
||
var err cocoa.NSError
|
||
l := d.device.Send(
|
||
sel_newLibraryWithData_error,
|
||
data,
|
||
unsafe.Pointer(&err),
|
||
)
|
||
if l == 0 {
|
||
return Library{}, errors.New(cocoa.NSString{ID: err.Send(sel_localizedDescription)}.String())
|
||
}
|
||
return Library{l}, nil
|
||
}
|
||
|
||
// NewRenderPipelineStateWithDescriptor synchronously creates a render pipeline state.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtldevice/1433369-newrenderpipelinestatewithdescri?language=objc.
|
||
func (d Device) NewRenderPipelineStateWithDescriptor(rpd RenderPipelineDescriptor) (RenderPipelineState, error) {
|
||
renderPipelineDescriptor := objc.ID(class_MTLRenderPipelineDescriptor).Send(sel_new)
|
||
renderPipelineDescriptor.Send(sel_setVertexFunction, rpd.VertexFunction.function)
|
||
renderPipelineDescriptor.Send(sel_setFragmentFunction, rpd.FragmentFunction.function)
|
||
colorAttachments0 := renderPipelineDescriptor.Send(sel_colorAttachments).Send(sel_objectAtIndexedSubscript, 0)
|
||
colorAttachments0.Send(sel_setPixelFormat, uintptr(rpd.ColorAttachments[0].PixelFormat))
|
||
colorAttachments0.Send(sel_setBlendingEnabled, rpd.ColorAttachments[0].BlendingEnabled)
|
||
colorAttachments0.Send(sel_setDestinationAlphaBlendFactor, uintptr(rpd.ColorAttachments[0].DestinationAlphaBlendFactor))
|
||
colorAttachments0.Send(sel_setDestinationRGBBlendFactor, uintptr(rpd.ColorAttachments[0].DestinationRGBBlendFactor))
|
||
colorAttachments0.Send(sel_setSourceAlphaBlendFactor, uintptr(rpd.ColorAttachments[0].SourceAlphaBlendFactor))
|
||
colorAttachments0.Send(sel_setSourceRGBBlendFactor, uintptr(rpd.ColorAttachments[0].SourceRGBBlendFactor))
|
||
colorAttachments0.Send(sel_setAlphaBlendOperation, uintptr(rpd.ColorAttachments[0].AlphaBlendOperation))
|
||
colorAttachments0.Send(sel_setRgbBlendOperation, uintptr(rpd.ColorAttachments[0].RGBBlendOperation))
|
||
colorAttachments0.Send(sel_setWriteMask, uintptr(rpd.ColorAttachments[0].WriteMask))
|
||
renderPipelineDescriptor.Send(sel_setStencilAttachmentPixelFormat, uintptr(rpd.StencilAttachmentPixelFormat))
|
||
var err cocoa.NSError
|
||
renderPipelineState := d.device.Send(sel_newRenderPipelineStateWithDescriptor_error,
|
||
renderPipelineDescriptor,
|
||
unsafe.Pointer(&err),
|
||
)
|
||
renderPipelineDescriptor.Send(sel_release)
|
||
if renderPipelineState == 0 {
|
||
return RenderPipelineState{}, errors.New(cocoa.NSString{ID: err.Send(sel_localizedDescription)}.String())
|
||
}
|
||
|
||
return RenderPipelineState{renderPipelineState}, nil
|
||
}
|
||
|
||
// NewBufferWithBytes allocates a new buffer of a given length and initializes its contents by copying existing data into it.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtldevice/1433429-newbufferwithbytes?language=objc.
|
||
func (d Device) NewBufferWithBytes(bytes unsafe.Pointer, length uintptr, opt ResourceOptions) Buffer {
|
||
return Buffer{d.device.Send(sel_newBufferWithBytes_length_options, bytes, length, uintptr(opt))}
|
||
}
|
||
|
||
// NewBufferWithLength allocates a new zero-filled buffer of a given length.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtldevice/1433375-newbufferwithlength?language=objc.
|
||
func (d Device) NewBufferWithLength(length uintptr, opt ResourceOptions) Buffer {
|
||
return Buffer{d.device.Send(sel_newBufferWithLength_options, length, uintptr(opt))}
|
||
}
|
||
|
||
// NewTextureWithDescriptor creates a new texture instance.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtldevice/1433425-newtexturewithdescriptor?language=objc.
|
||
func (d Device) NewTextureWithDescriptor(td TextureDescriptor) Texture {
|
||
textureDescriptor := objc.ID(class_MTLTextureDescriptor).Send(sel_new)
|
||
textureDescriptor.Send(sel_setTextureType, uintptr(td.TextureType))
|
||
textureDescriptor.Send(sel_setPixelFormat, uintptr(td.PixelFormat))
|
||
textureDescriptor.Send(sel_setWidth, uintptr(td.Width))
|
||
textureDescriptor.Send(sel_setHeight, uintptr(td.Height))
|
||
textureDescriptor.Send(sel_setStorageMode, uintptr(td.StorageMode))
|
||
textureDescriptor.Send(sel_setUsage, uintptr(td.Usage))
|
||
texture := d.device.Send(sel_newTextureWithDescriptor, textureDescriptor)
|
||
textureDescriptor.Send(sel_release)
|
||
return Texture{
|
||
texture: texture,
|
||
}
|
||
}
|
||
|
||
// NewDepthStencilStateWithDescriptor creates a depth-stencil state instance.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtldevice/1433412-newdepthstencilstatewithdescript?language=objc.
|
||
func (d Device) NewDepthStencilStateWithDescriptor(dsd DepthStencilDescriptor) DepthStencilState {
|
||
depthStencilDescriptor := objc.ID(class_MTLDepthStencilDescriptor).Send(sel_new)
|
||
backFaceStencil := depthStencilDescriptor.Send(sel_backFaceStencil)
|
||
backFaceStencil.Send(sel_setStencilFailureOperation, uintptr(dsd.BackFaceStencil.StencilFailureOperation))
|
||
backFaceStencil.Send(sel_setDepthFailureOperation, uintptr(dsd.BackFaceStencil.DepthFailureOperation))
|
||
backFaceStencil.Send(sel_setDepthStencilPassOperation, uintptr(dsd.BackFaceStencil.DepthStencilPassOperation))
|
||
backFaceStencil.Send(sel_setStencilCompareFunction, uintptr(dsd.BackFaceStencil.StencilCompareFunction))
|
||
frontFaceStencil := depthStencilDescriptor.Send(sel_frontFaceStencil)
|
||
frontFaceStencil.Send(sel_setStencilFailureOperation, uintptr(dsd.FrontFaceStencil.StencilFailureOperation))
|
||
frontFaceStencil.Send(sel_setDepthFailureOperation, uintptr(dsd.FrontFaceStencil.DepthFailureOperation))
|
||
frontFaceStencil.Send(sel_setDepthStencilPassOperation, uintptr(dsd.FrontFaceStencil.DepthStencilPassOperation))
|
||
frontFaceStencil.Send(sel_setStencilCompareFunction, uintptr(dsd.FrontFaceStencil.StencilCompareFunction))
|
||
depthStencilState := d.device.Send(sel_newDepthStencilStateWithDescriptor, depthStencilDescriptor)
|
||
depthStencilDescriptor.Send(sel_release)
|
||
return DepthStencilState{
|
||
depthStencilState: depthStencilState,
|
||
}
|
||
}
|
||
|
||
// CompileOptions specifies optional compilation settings for
|
||
// the graphics or compute functions within a library.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlcompileoptions?language=objc.
|
||
type CompileOptions struct {
|
||
// TODO.
|
||
}
|
||
|
||
// Drawable is a displayable resource that can be rendered or written to.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtldrawable?language=objc.
|
||
type Drawable interface {
|
||
// Drawable returns the underlying id<MTLDrawable> pointer.
|
||
Drawable() unsafe.Pointer
|
||
}
|
||
|
||
// CommandQueue is a queue that organizes the order
|
||
// in which command buffers are executed by the GPU.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlcommandqueue?language=objc.
|
||
type CommandQueue struct {
|
||
commandQueue objc.ID
|
||
}
|
||
|
||
func (cq CommandQueue) Release() {
|
||
cq.commandQueue.Send(sel_release)
|
||
}
|
||
|
||
// CommandBuffer returns a command buffer from the command queue that maintains strong references to resources.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlcommandqueue/1508686-commandbuffer?language=objc.
|
||
func (cq CommandQueue) CommandBuffer() CommandBuffer {
|
||
return CommandBuffer{cq.commandQueue.Send(sel_commandBuffer)}
|
||
}
|
||
|
||
// CommandBuffer is a container that stores encoded commands
|
||
// that are committed to and executed by the GPU.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer?language=objc.
|
||
type CommandBuffer struct {
|
||
commandBuffer objc.ID
|
||
}
|
||
|
||
func (cb CommandBuffer) Retain() {
|
||
cb.commandBuffer.Send(sel_retain)
|
||
}
|
||
|
||
func (cb CommandBuffer) Release() {
|
||
cb.commandBuffer.Send(sel_release)
|
||
}
|
||
|
||
// Status returns the current stage in the lifetime of the command buffer.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer/1443048-status?language=objc.
|
||
func (cb CommandBuffer) Status() CommandBufferStatus {
|
||
return CommandBufferStatus(cb.commandBuffer.Send(sel_status))
|
||
}
|
||
|
||
// PresentDrawable registers a drawable presentation to occur as soon as possible.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer/1443029-presentdrawable?language=objc.
|
||
func (cb CommandBuffer) PresentDrawable(d Drawable) {
|
||
cb.commandBuffer.Send(sel_presentDrawable, d.Drawable())
|
||
}
|
||
|
||
// Commit commits this command buffer for execution as soon as possible.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer/1443003-commit?language=objc.
|
||
func (cb CommandBuffer) Commit() {
|
||
cb.commandBuffer.Send(sel_commit)
|
||
}
|
||
|
||
// WaitUntilCompleted waits for the execution of this command buffer to complete.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer/1443039-waituntilcompleted?language=objc.
|
||
func (cb CommandBuffer) WaitUntilCompleted() {
|
||
cb.commandBuffer.Send(sel_waitUntilCompleted)
|
||
}
|
||
|
||
// WaitUntilScheduled blocks execution of the current thread until the command buffer is scheduled.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer/1443036-waituntilscheduled?language=objc.
|
||
func (cb CommandBuffer) WaitUntilScheduled() {
|
||
cb.commandBuffer.Send(sel_waitUntilScheduled)
|
||
}
|
||
|
||
// RenderCommandEncoderWithDescriptor creates a render command encoder from a descriptor.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer/1442999-rendercommandencoderwithdescript?language=objc.
|
||
func (cb CommandBuffer) RenderCommandEncoderWithDescriptor(rpd RenderPassDescriptor) RenderCommandEncoder {
|
||
var renderPassDescriptor = objc.ID(class_MTLRenderPassDescriptor).Send(sel_new)
|
||
var colorAttachments0 = renderPassDescriptor.Send(sel_colorAttachments).Send(sel_objectAtIndexedSubscript, 0)
|
||
colorAttachments0.Send(sel_setLoadAction, int(rpd.ColorAttachments[0].LoadAction))
|
||
colorAttachments0.Send(sel_setStoreAction, int(rpd.ColorAttachments[0].StoreAction))
|
||
colorAttachments0.Send(sel_setTexture, rpd.ColorAttachments[0].Texture.texture)
|
||
sig := cocoa.NSMethodSignature_instanceMethodSignatureForSelector(colorAttachments0.Send(sel_class), sel_setClearColor)
|
||
inv := cocoa.NSInvocation_invocationWithMethodSignature(sig)
|
||
inv.SetTarget(colorAttachments0)
|
||
inv.SetSelector(sel_setClearColor)
|
||
inv.SetArgumentAtIndex(unsafe.Pointer(&rpd.ColorAttachments[0].ClearColor), 2)
|
||
inv.Invoke()
|
||
var stencilAttachment = renderPassDescriptor.Send(sel_stencilAttachment)
|
||
stencilAttachment.Send(sel_setLoadAction, int(rpd.StencilAttachment.LoadAction))
|
||
stencilAttachment.Send(sel_setStoreAction, int(rpd.StencilAttachment.StoreAction))
|
||
stencilAttachment.Send(sel_setTexture, rpd.StencilAttachment.Texture.texture)
|
||
var rce = cb.commandBuffer.Send(sel_renderCommandEncoderWithDescriptor, renderPassDescriptor)
|
||
renderPassDescriptor.Send(sel_release)
|
||
return RenderCommandEncoder{CommandEncoder{rce}}
|
||
}
|
||
|
||
// BlitCommandEncoder creates an encoder object that can encode
|
||
// memory operation (blit) commands into this command buffer.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer/1443001-makeblitcommandencoder?language=objc.
|
||
func (cb CommandBuffer) BlitCommandEncoder() BlitCommandEncoder {
|
||
ce := cb.commandBuffer.Send(sel_blitCommandEncoder)
|
||
return BlitCommandEncoder{CommandEncoder{ce}}
|
||
}
|
||
|
||
// CommandEncoder is an encoder that writes sequential GPU commands
|
||
// into a command buffer.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer/1443001-blitcommandencoder?language=objc.
|
||
type CommandEncoder struct {
|
||
commandEncoder objc.ID
|
||
}
|
||
|
||
// EndEncoding declares that all command generation from this encoder is completed.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlcommandencoder/1458038-endencoding?language=objc.
|
||
func (ce CommandEncoder) EndEncoding() {
|
||
ce.commandEncoder.Send(sel_endEncoding)
|
||
}
|
||
|
||
// RenderCommandEncoder is an encoder that specifies graphics-rendering commands
|
||
// and executes graphics functions.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder?language=objc.
|
||
type RenderCommandEncoder struct {
|
||
CommandEncoder
|
||
}
|
||
|
||
func (rce RenderCommandEncoder) Release() {
|
||
rce.commandEncoder.Send(sel_release)
|
||
}
|
||
|
||
// SetRenderPipelineState sets the current render pipeline state object.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515811-setrenderpipelinestate?language=objc.
|
||
func (rce RenderCommandEncoder) SetRenderPipelineState(rps RenderPipelineState) {
|
||
rce.commandEncoder.Send(sel_setRenderPipelineState, rps.renderPipelineState)
|
||
}
|
||
|
||
func (rce RenderCommandEncoder) SetViewport(viewport Viewport) {
|
||
inv := cocoa.NSInvocation_invocationWithMethodSignature(cocoa.NSMethodSignature_signatureWithObjCTypes("v@:{MTLViewport=dddddd}"))
|
||
inv.SetTarget(rce.commandEncoder)
|
||
inv.SetSelector(sel_setViewport)
|
||
inv.SetArgumentAtIndex(unsafe.Pointer(&viewport), 2)
|
||
inv.Invoke()
|
||
}
|
||
|
||
// SetScissorRect sets the scissor rectangle for a fragment scissor test.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515583-setscissorrect?language=objc.
|
||
func (rce RenderCommandEncoder) SetScissorRect(scissorRect ScissorRect) {
|
||
inv := cocoa.NSInvocation_invocationWithMethodSignature(cocoa.NSMethodSignature_signatureWithObjCTypes("v@:{MTLScissorRect=qqqq}"))
|
||
inv.SetTarget(rce.commandEncoder)
|
||
inv.SetSelector(sel_setScissorRect)
|
||
inv.SetArgumentAtIndex(unsafe.Pointer(&scissorRect), 2)
|
||
inv.Invoke()
|
||
}
|
||
|
||
// SetVertexBuffer sets a buffer for the vertex shader function at an index
|
||
// in the buffer argument table with an offset that specifies the start of the data.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515829-setvertexbuffer?language=objc.
|
||
func (rce RenderCommandEncoder) SetVertexBuffer(buf Buffer, offset, index int) {
|
||
rce.commandEncoder.Send(sel_setVertexBuffer_offset_atIndex, buf.buffer, offset, index)
|
||
}
|
||
|
||
// SetVertexBytes sets a block of data for the vertex function.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515846-setvertexbytes?language=objc.
|
||
func (rce RenderCommandEncoder) SetVertexBytes(bytes unsafe.Pointer, length uintptr, index int) {
|
||
rce.commandEncoder.Send(sel_setVertexBytes_length_atIndex, bytes, length, index)
|
||
}
|
||
|
||
func (rce RenderCommandEncoder) SetFragmentBytes(bytes unsafe.Pointer, length uintptr, index int) {
|
||
rce.commandEncoder.Send(sel_setFragmentBytes_length_atIndex, bytes, length, index)
|
||
}
|
||
|
||
// SetFragmentTexture sets a texture for the fragment function at an index in the texture argument table.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515390-setfragmenttexture?language=objc.
|
||
func (rce RenderCommandEncoder) SetFragmentTexture(texture Texture, index int) {
|
||
rce.commandEncoder.Send(sel_setFragmentTexture_atIndex, texture.texture, index)
|
||
}
|
||
|
||
func (rce RenderCommandEncoder) SetBlendColor(red, green, blue, alpha float32) {
|
||
rce.commandEncoder.Send(sel_setBlendColorRedGreenBlueAlpha, red, green, blue, alpha)
|
||
}
|
||
|
||
// SetDepthStencilState sets the depth and stencil test state.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1516119-setdepthstencilstate?language=objc.
|
||
func (rce RenderCommandEncoder) SetDepthStencilState(depthStencilState DepthStencilState) {
|
||
rce.commandEncoder.Send(sel_setDepthStencilState, depthStencilState.depthStencilState)
|
||
}
|
||
|
||
// DrawPrimitives renders one instance of primitives using vertex data
|
||
// in contiguous array elements.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1516326-drawprimitives?language=objc.
|
||
func (rce RenderCommandEncoder) DrawPrimitives(typ PrimitiveType, vertexStart, vertexCount int) {
|
||
rce.commandEncoder.Send(sel_drawPrimitives_vertexStart_vertexCount, uintptr(typ), vertexStart, vertexCount)
|
||
}
|
||
|
||
// DrawIndexedPrimitives encodes a command to render one instance of primitives using an index list specified in a buffer.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515542-drawindexedprimitives
|
||
func (rce RenderCommandEncoder) DrawIndexedPrimitives(typ PrimitiveType, indexCount int, indexType IndexType, indexBuffer Buffer, indexBufferOffset int) {
|
||
rce.commandEncoder.Send(
|
||
sel_drawIndexedPrimitives_indexCount_indexType_indexBuffer_indexBufferOffset,
|
||
uintptr(typ), indexCount, uintptr(indexType), indexBuffer.buffer, indexBufferOffset)
|
||
}
|
||
|
||
// BlitCommandEncoder is an encoder that specifies resource copy
|
||
// and resource synchronization commands.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlblitcommandencoder?language=objc.
|
||
type BlitCommandEncoder struct {
|
||
CommandEncoder
|
||
}
|
||
|
||
// Synchronize flushes any copy of the specified resource from its corresponding
|
||
// Device caches and, if needed, invalidates any CPU caches.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlblitcommandencoder/1400775-synchronize?language=objc.
|
||
func (bce BlitCommandEncoder) Synchronize(resource Resource) {
|
||
if runtime.GOOS == "ios" {
|
||
return
|
||
}
|
||
bce.commandEncoder.Send(sel_synchronizeResource, resource.resource())
|
||
}
|
||
|
||
// SynchronizeTexture encodes a command that synchronizes a part of the CPU’s copy of a texture so that it matches the GPU’s copy.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlblitcommandencoder/1400757-synchronizetexture?language=objc.
|
||
func (bce BlitCommandEncoder) SynchronizeTexture(texture Texture, slice int, level int) {
|
||
if runtime.GOOS == "ios" {
|
||
return
|
||
}
|
||
bce.commandEncoder.Send(sel_synchronizeTexture_slice_level, texture.texture, slice, level)
|
||
}
|
||
|
||
// CopyFromTexture encodes a command that copies image data from a texture’s slice into another slice.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlblitcommandencoder/1400754-copyfromtexture?language=objc.
|
||
func (bce BlitCommandEncoder) CopyFromTexture(sourceTexture Texture, sourceSlice int, sourceLevel int, sourceOrigin Origin, sourceSize Size, destinationTexture Texture, destinationSlice int, destinationLevel int, destinationOrigin Origin) {
|
||
inv := cocoa.NSInvocation_invocationWithMethodSignature(cocoa.NSMethodSignature_signatureWithObjCTypes("v@:@QQ{MTLOrigin=qqq}{MTLSize=qqq}@QQ{MTLOrigin=qqq}"))
|
||
inv.SetTarget(bce.commandEncoder)
|
||
inv.SetSelector(sel_copyFromTexture_sourceSlice_sourceLevel_sourceOrigin_sourceSize_toTexture_destinationSlice_destinationLevel_destinationOrigin)
|
||
inv.SetArgumentAtIndex(unsafe.Pointer(&sourceTexture), 2)
|
||
inv.SetArgumentAtIndex(unsafe.Pointer(&sourceSlice), 3)
|
||
inv.SetArgumentAtIndex(unsafe.Pointer(&sourceLevel), 4)
|
||
inv.SetArgumentAtIndex(unsafe.Pointer(&sourceOrigin), 5)
|
||
inv.SetArgumentAtIndex(unsafe.Pointer(&sourceSize), 6)
|
||
inv.SetArgumentAtIndex(unsafe.Pointer(&destinationTexture), 7)
|
||
inv.SetArgumentAtIndex(unsafe.Pointer(&destinationSlice), 8)
|
||
inv.SetArgumentAtIndex(unsafe.Pointer(&destinationLevel), 9)
|
||
inv.SetArgumentAtIndex(unsafe.Pointer(&destinationOrigin), 10)
|
||
inv.Invoke()
|
||
}
|
||
|
||
// Library is a collection of compiled graphics or compute functions.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtllibrary?language=objc.
|
||
type Library struct {
|
||
library objc.ID
|
||
}
|
||
|
||
// NewFunctionWithName returns a pre-compiled, non-specialized function.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtllibrary/1515524-newfunctionwithname?language=objc.
|
||
func (l Library) NewFunctionWithName(name string) (Function, error) {
|
||
f := l.library.Send(sel_newFunctionWithName,
|
||
cocoa.NSString_alloc().InitWithUTF8String(name).ID,
|
||
)
|
||
if f == 0 {
|
||
return Function{}, fmt.Errorf("function %q not found", name)
|
||
}
|
||
return Function{f}, nil
|
||
}
|
||
|
||
func (l Library) Release() {
|
||
l.library.Send(sel_release)
|
||
}
|
||
|
||
// Texture is a memory allocation for storing formatted
|
||
// image data that is accessible to the GPU.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtltexture?language=objc.
|
||
type Texture struct {
|
||
texture objc.ID
|
||
}
|
||
|
||
// NewTexture returns a Texture that wraps an existing id<MTLTexture> pointer.
|
||
func NewTexture(texture objc.ID) Texture {
|
||
return Texture{texture: texture}
|
||
}
|
||
|
||
// resource implements the Resource interface.
|
||
func (t Texture) resource() unsafe.Pointer {
|
||
return *(*unsafe.Pointer)(unsafe.Pointer(&t.texture))
|
||
}
|
||
|
||
func (t Texture) Release() {
|
||
t.texture.Send(sel_release)
|
||
}
|
||
|
||
// GetBytes copies a block of pixels from the storage allocation of texture
|
||
// slice zero into system memory at a specified address.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtltexture/1515751-getbytes?language=objc.
|
||
func (t Texture) GetBytes(pixelBytes *byte, bytesPerRow uintptr, region Region, level int) {
|
||
inv := cocoa.NSInvocation_invocationWithMethodSignature(cocoa.NSMethodSignature_signatureWithObjCTypes("v@:^vQ{MTLRegion={MTLOrigin=qqq}{MTLSize=qqq}}Q"))
|
||
inv.SetTarget(t.texture)
|
||
inv.SetSelector(sel_getBytes_bytesPerRow_fromRegion_mipmapLevel)
|
||
inv.SetArgumentAtIndex(unsafe.Pointer(&pixelBytes), 2)
|
||
inv.SetArgumentAtIndex(unsafe.Pointer(&bytesPerRow), 3)
|
||
inv.SetArgumentAtIndex(unsafe.Pointer(®ion), 4)
|
||
inv.SetArgumentAtIndex(unsafe.Pointer(&level), 5)
|
||
inv.Invoke()
|
||
}
|
||
|
||
// ReplaceRegion copies a block of pixels from the caller's pointer into the storage allocation for slice 0 of a texture.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtltexture/1515464-replaceregion?language=objc.
|
||
func (t Texture) ReplaceRegion(region Region, level int, pixelBytes unsafe.Pointer, bytesPerRow int) {
|
||
inv := cocoa.NSInvocation_invocationWithMethodSignature(cocoa.NSMethodSignature_signatureWithObjCTypes("v@:{MTLRegion={MTLOrigin=qqq}{MTLSize=qqq}}Q^vQ"))
|
||
inv.SetTarget(t.texture)
|
||
inv.SetSelector(sel_replaceRegion_mipmapLevel_withBytes_bytesPerRow)
|
||
inv.SetArgumentAtIndex(unsafe.Pointer(®ion), 2)
|
||
inv.SetArgumentAtIndex(unsafe.Pointer(&level), 3)
|
||
inv.SetArgumentAtIndex(unsafe.Pointer(&pixelBytes), 4)
|
||
inv.SetArgumentAtIndex(unsafe.Pointer(&bytesPerRow), 5)
|
||
inv.Invoke()
|
||
}
|
||
|
||
// Width is the width of the texture image for the base level mipmap, in pixels.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtltexture/1515339-width?language=objc.
|
||
func (t Texture) Width() int {
|
||
return int(t.texture.Send(sel_width))
|
||
}
|
||
|
||
// Height is the height of the texture image for the base level mipmap, in pixels.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtltexture/1515938-height?language=objc.
|
||
func (t Texture) Height() int {
|
||
return int(t.texture.Send(sel_height))
|
||
}
|
||
|
||
// Buffer is a memory allocation for storing unformatted data
|
||
// that is accessible to the GPU.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlbuffer?language=objc.
|
||
type Buffer struct {
|
||
buffer objc.ID
|
||
}
|
||
|
||
// resource implements the Resource interface.
|
||
func (b Buffer) resource() unsafe.Pointer {
|
||
return *(*unsafe.Pointer)(unsafe.Pointer(&b.buffer))
|
||
}
|
||
|
||
// Length returns the logical size of the buffer, in bytes.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlbuffer/1515373-length?language=objc.
|
||
func (b Buffer) Length() uintptr {
|
||
return uintptr(b.buffer.Send(sel_length))
|
||
}
|
||
|
||
func (b Buffer) CopyToContents(data unsafe.Pointer, lengthInBytes uintptr) {
|
||
contents := b.buffer.Send(sel_contents)
|
||
copy(unsafe.Slice((*byte)(unsafe.Pointer(contents)), lengthInBytes), unsafe.Slice((*byte)(data), lengthInBytes))
|
||
if runtime.GOOS != "ios" {
|
||
b.buffer.Send(sel_didModifyRange, 0, lengthInBytes)
|
||
}
|
||
}
|
||
|
||
func (b Buffer) Retain() {
|
||
b.buffer.Send(sel_retain)
|
||
}
|
||
|
||
func (b Buffer) Release() {
|
||
b.buffer.Send(sel_release)
|
||
}
|
||
|
||
// Function represents a programmable graphics or compute function executed by the GPU.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlfunction?language=objc.
|
||
type Function struct {
|
||
function objc.ID
|
||
}
|
||
|
||
func (f Function) Release() {
|
||
f.function.Send(sel_release)
|
||
}
|
||
|
||
// RenderPipelineState contains the graphics functions
|
||
// and configuration state used in a render pass.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlrenderpipelinestate?language=objc.
|
||
type RenderPipelineState struct {
|
||
renderPipelineState objc.ID
|
||
}
|
||
|
||
func (r RenderPipelineState) Release() {
|
||
r.renderPipelineState.Send(sel_release)
|
||
}
|
||
|
||
// Region is a rectangular block of pixels in an image or texture,
|
||
// defined by its upper-left corner and its size.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlregion?language=objc.
|
||
type Region struct {
|
||
Origin Origin // The location of the upper-left corner of the block.
|
||
Size Size // The size of the block.
|
||
}
|
||
|
||
// Origin represents the location of a pixel in an image or texture relative
|
||
// to the upper-left corner, whose coordinates are (0, 0).
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlorigin?language=objc.
|
||
type Origin struct {
|
||
X int
|
||
Y int
|
||
Z int
|
||
}
|
||
|
||
// Size represents the set of dimensions that declare the size of an object,
|
||
// such as an image, texture, threadgroup, or grid.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlsize?language=objc.
|
||
type Size struct {
|
||
Width int
|
||
Height int
|
||
Depth int
|
||
}
|
||
|
||
// RegionMake2D returns a 2D, rectangular region for image or texture data.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/1515675-mtlregionmake2d?language=objc.
|
||
func RegionMake2D(x, y, width, height int) Region {
|
||
return Region{
|
||
Origin: Origin{X: x, Y: y, Z: 0},
|
||
Size: Size{Width: width, Height: height, Depth: 1},
|
||
}
|
||
}
|
||
|
||
// Viewport is a 3D rectangular region for the viewport clipping.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlviewport?language=objc.
|
||
type Viewport struct {
|
||
OriginX float64
|
||
OriginY float64
|
||
Width float64
|
||
Height float64
|
||
ZNear float64
|
||
ZFar float64
|
||
}
|
||
|
||
// ScissorRect is a rectangle for the scissor fragment test.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlscissorrect?language=objc.
|
||
type ScissorRect struct {
|
||
X int
|
||
Y int
|
||
Width int
|
||
Height int
|
||
}
|
||
|
||
// DepthStencilState is a depth and stencil state object that specifies the depth and stencil configuration and operations used in a render pass.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtldepthstencilstate?language=objc.
|
||
type DepthStencilState struct {
|
||
depthStencilState objc.ID
|
||
}
|
||
|
||
func (d DepthStencilState) Release() {
|
||
d.depthStencilState.Send(sel_release)
|
||
}
|
||
|
||
// DepthStencilDescriptor is an object that configures new MTLDepthStencilState objects.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtldepthstencildescriptor?language=objc.
|
||
type DepthStencilDescriptor struct {
|
||
// BackFaceStencil is the stencil descriptor for back-facing primitives.
|
||
BackFaceStencil StencilDescriptor
|
||
|
||
// FrontFaceStencil is The stencil descriptor for front-facing primitives.
|
||
FrontFaceStencil StencilDescriptor
|
||
}
|
||
|
||
// StencilDescriptor is an object that defines the front-facing or back-facing stencil operations of a depth and stencil state object.
|
||
//
|
||
// Reference: https://developer.apple.com/documentation/metal/mtlstencildescriptor?language=objc.
|
||
type StencilDescriptor struct {
|
||
// StencilFailureOperation is the operation that is performed to update the values in the stencil attachment when the stencil test fails.
|
||
StencilFailureOperation StencilOperation
|
||
|
||
// DepthFailureOperation is the operation that is performed to update the values in the stencil attachment when the stencil test passes, but the depth test fails.
|
||
DepthFailureOperation StencilOperation
|
||
|
||
// DepthStencilPassOperation is the operation that is performed to update the values in the stencil attachment when both the stencil test and the depth test pass.
|
||
DepthStencilPassOperation StencilOperation
|
||
|
||
// StencilCompareFunction is the comparison that is performed between the masked reference value and a masked value in the stencil attachment.
|
||
StencilCompareFunction CompareFunction
|
||
}
|