mtl.go (36674B)
1 // Copyright 2018 The Ebiten Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // +build darwin 16 17 // Package mtl provides access to Apple's Metal API (https://developer.apple.com/documentation/metal). 18 // 19 // Package mtl requires macOS version 10.13 or newer. 20 // 21 // This package is in very early stages of development. 22 // The API will change when opportunities for improvement are discovered; it is not yet frozen. 23 // Less than 20% of the Metal API surface is implemented. 24 // Current functionality is sufficient to render very basic geometry. 25 package mtl 26 27 import ( 28 "errors" 29 "fmt" 30 "unsafe" 31 ) 32 33 // #cgo !ios CFLAGS: -mmacosx-version-min=10.12 34 // #cgo LDFLAGS: -framework Metal -framework CoreGraphics -framework Foundation 35 // 36 // #include "mtl.h" 37 // #include <stdlib.h> 38 import "C" 39 40 // FeatureSet defines a specific platform, hardware, and software configuration. 41 // 42 // Reference: https://developer.apple.com/documentation/metal/mtlfeatureset. 43 type FeatureSet uint16 44 45 // The device feature sets that define specific platform, hardware, and software configurations. 46 const ( 47 MacOSGPUFamily1V1 FeatureSet = 10000 // The GPU family 1, version 1 feature set for macOS. 48 MacOSGPUFamily1V2 FeatureSet = 10001 // The GPU family 1, version 2 feature set for macOS. 49 MacOSReadWriteTextureTier2 FeatureSet = 10002 // The read-write texture, tier 2 feature set for macOS. 50 MacOSGPUFamily1V3 FeatureSet = 10003 // The GPU family 1, version 3 feature set for macOS. 51 MacOSGPUFamily1V4 FeatureSet = 10004 // The GPU family 1, version 4 feature set for macOS. 52 MacOSGPUFamily2V1 FeatureSet = 10005 // The GPU family 2, version 1 feature set for macOS. 53 ) 54 55 const ( 56 FeatureSet_iOS_GPUFamily1_v1 FeatureSet = 0 57 FeatureSet_iOS_GPUFamily1_v2 FeatureSet = 2 58 FeatureSet_iOS_GPUFamily1_v3 FeatureSet = 5 59 FeatureSet_iOS_GPUFamily1_v4 FeatureSet = 8 60 FeatureSet_iOS_GPUFamily1_v5 FeatureSet = 12 61 FeatureSet_iOS_GPUFamily2_v1 FeatureSet = 1 62 FeatureSet_iOS_GPUFamily2_v2 FeatureSet = 3 63 FeatureSet_iOS_GPUFamily2_v3 FeatureSet = 6 64 FeatureSet_iOS_GPUFamily2_v4 FeatureSet = 9 65 FeatureSet_iOS_GPUFamily2_v5 FeatureSet = 13 66 FeatureSet_iOS_GPUFamily3_v1 FeatureSet = 4 67 FeatureSet_iOS_GPUFamily3_v2 FeatureSet = 7 68 FeatureSet_iOS_GPUFamily3_v3 FeatureSet = 10 69 FeatureSet_iOS_GPUFamily3_v4 FeatureSet = 14 70 FeatureSet_iOS_GPUFamily4_v1 FeatureSet = 11 71 FeatureSet_iOS_GPUFamily4_v2 FeatureSet = 15 72 FeatureSet_iOS_GPUFamily5_v1 FeatureSet = 16 73 FeatureSet_tvOS_GPUFamily1_v1 FeatureSet = 30000 74 FeatureSet_tvOS_GPUFamily1_v2 FeatureSet = 30001 75 FeatureSet_tvOS_GPUFamily1_v3 FeatureSet = 30002 76 FeatureSet_tvOS_GPUFamily1_v4 FeatureSet = 30004 77 FeatureSet_tvOS_GPUFamily2_v1 FeatureSet = 30003 78 FeatureSet_tvOS_GPUFamily2_v2 FeatureSet = 30005 79 FeatureSet_macOS_GPUFamily1_v1 FeatureSet = 10000 80 FeatureSet_macOS_GPUFamily1_v2 FeatureSet = 10001 81 FeatureSet_macOS_GPUFamily1_v3 FeatureSet = 10003 82 FeatureSet_macOS_GPUFamily1_v4 FeatureSet = 10004 83 FeatureSet_macOS_GPUFamily2_v1 FeatureSet = 10005 84 FeatureSet_macOS_ReadWriteTextureTier2 FeatureSet = 10002 85 ) 86 87 // TextureType defines The dimension of each image, including whether multiple images are arranged into an array or 88 // a cube. 89 // 90 // Reference: https://developer.apple.com/documentation/metal/mtltexturetype 91 type TextureType uint16 92 93 const ( 94 TextureType2D TextureType = 2 95 ) 96 97 // PixelFormat defines data formats that describe the organization 98 // and characteristics of individual pixels in a texture. 99 // 100 // Reference: https://developer.apple.com/documentation/metal/mtlpixelformat. 101 type PixelFormat uint16 102 103 // The data formats that describe the organization and characteristics 104 // of individual pixels in a texture. 105 const ( 106 PixelFormatRGBA8UNorm PixelFormat = 70 // Ordinary format with four 8-bit normalized unsigned integer components in RGBA order. 107 PixelFormatRGBA8UNormSRGB PixelFormat = 71 // Ordinary format with four 8-bit normalized unsigned integer components in RGBA order with conversion between sRGB and linear space. 108 PixelFormatBGRA8UNorm PixelFormat = 80 // Ordinary format with four 8-bit normalized unsigned integer components in BGRA order. 109 PixelFormatBGRA8UNormSRGB PixelFormat = 81 // Ordinary format with four 8-bit normalized unsigned integer components in BGRA order with conversion between sRGB and linear space. 110 ) 111 112 // PrimitiveType defines geometric primitive types for drawing commands. 113 // 114 // Reference: https://developer.apple.com/documentation/metal/mtlprimitivetype. 115 type PrimitiveType uint8 116 117 // Geometric primitive types for drawing commands. 118 const ( 119 PrimitiveTypePoint PrimitiveType = 0 120 PrimitiveTypeLine PrimitiveType = 1 121 PrimitiveTypeLineStrip PrimitiveType = 2 122 PrimitiveTypeTriangle PrimitiveType = 3 123 PrimitiveTypeTriangleStrip PrimitiveType = 4 124 ) 125 126 // LoadAction defines actions performed at the start of a rendering pass 127 // for a render command encoder. 128 // 129 // Reference: https://developer.apple.com/documentation/metal/mtlloadaction. 130 type LoadAction uint8 131 132 // Actions performed at the start of a rendering pass for a render command encoder. 133 const ( 134 LoadActionDontCare LoadAction = 0 135 LoadActionLoad LoadAction = 1 136 LoadActionClear LoadAction = 2 137 ) 138 139 // StoreAction defines actions performed at the end of a rendering pass 140 // for a render command encoder. 141 // 142 // Reference: https://developer.apple.com/documentation/metal/mtlstoreaction. 143 type StoreAction uint8 144 145 // Actions performed at the end of a rendering pass for a render command encoder. 146 const ( 147 StoreActionDontCare StoreAction = 0 148 StoreActionStore StoreAction = 1 149 StoreActionMultisampleResolve StoreAction = 2 150 StoreActionStoreAndMultisampleResolve StoreAction = 3 151 StoreActionUnknown StoreAction = 4 152 StoreActionCustomSampleDepthStore StoreAction = 5 153 ) 154 155 // StorageMode defines defines the memory location and access permissions of a resource. 156 // 157 // Reference: https://developer.apple.com/documentation/metal/mtlstoragemode. 158 type StorageMode uint8 159 160 const ( 161 // StorageModeShared indicates that the resource is stored in system memory 162 // accessible to both the CPU and the GPU. 163 StorageModeShared StorageMode = 0 164 165 // StorageModeManaged indicates that the resource exists as a synchronized 166 // memory pair with one copy stored in system memory accessible to the CPU 167 // and another copy stored in video memory accessible to the GPU. 168 StorageModeManaged StorageMode = 1 169 170 // StorageModePrivate indicates that the resource is stored in memory 171 // only accessible to the GPU. In iOS and tvOS, the resource is stored in 172 // system memory. In macOS, the resource is stored in video memory. 173 StorageModePrivate StorageMode = 2 174 175 // StorageModeMemoryless indicates that the resource is stored in on-tile memory, 176 // without CPU or GPU memory backing. The contents of the on-tile memory are undefined 177 // and do not persist; the only way to populate the resource is to render into it. 178 // Memoryless resources are limited to temporary render targets (i.e., Textures configured 179 // with a TextureDescriptor and used with a RenderPassAttachmentDescriptor). 180 StorageModeMemoryless StorageMode = 3 181 ) 182 183 // ResourceOptions defines optional arguments used to create 184 // and influence behavior of buffer and texture objects. 185 // 186 // Reference: https://developer.apple.com/documentation/metal/mtlresourceoptions. 187 type ResourceOptions uint16 188 189 const ( 190 // ResourceCPUCacheModeDefaultCache is the default CPU cache mode for the resource. 191 // Guarantees that read and write operations are executed in the expected order. 192 ResourceCPUCacheModeDefaultCache ResourceOptions = ResourceOptions(CPUCacheModeDefaultCache) << resourceCPUCacheModeShift 193 194 // ResourceCPUCacheModeWriteCombined is a write-combined CPU cache mode for the resource. 195 // Optimized for resources that the CPU will write into, but never read. 196 ResourceCPUCacheModeWriteCombined ResourceOptions = ResourceOptions(CPUCacheModeWriteCombined) << resourceCPUCacheModeShift 197 198 // ResourceStorageModeShared indicates that the resource is stored in system memory 199 // accessible to both the CPU and the GPU. 200 ResourceStorageModeShared ResourceOptions = ResourceOptions(StorageModeShared) << resourceStorageModeShift 201 202 // ResourceStorageModeManaged indicates that the resource exists as a synchronized 203 // memory pair with one copy stored in system memory accessible to the CPU 204 // and another copy stored in video memory accessible to the GPU. 205 ResourceStorageModeManaged ResourceOptions = ResourceOptions(StorageModeManaged) << resourceStorageModeShift 206 207 // ResourceStorageModePrivate indicates that the resource is stored in memory 208 // only accessible to the GPU. In iOS and tvOS, the resource is stored 209 // in system memory. In macOS, the resource is stored in video memory. 210 ResourceStorageModePrivate ResourceOptions = ResourceOptions(StorageModePrivate) << resourceStorageModeShift 211 212 // ResourceStorageModeMemoryless indicates that the resource is stored in on-tile memory, 213 // without CPU or GPU memory backing. The contents of the on-tile memory are undefined 214 // and do not persist; the only way to populate the resource is to render into it. 215 // Memoryless resources are limited to temporary render targets (i.e., Textures configured 216 // with a TextureDescriptor and used with a RenderPassAttachmentDescriptor). 217 ResourceStorageModeMemoryless ResourceOptions = ResourceOptions(StorageModeMemoryless) << resourceStorageModeShift 218 219 // ResourceHazardTrackingModeUntracked indicates that the command encoder dependencies 220 // for this resource are tracked manually with Fence objects. This value is always set 221 // for resources sub-allocated from a Heap object and may optionally be specified for 222 // non-heap resources. 223 ResourceHazardTrackingModeUntracked ResourceOptions = 1 << resourceHazardTrackingModeShift 224 ) 225 226 const ( 227 resourceCPUCacheModeShift = 0 228 resourceStorageModeShift = 4 229 resourceHazardTrackingModeShift = 8 230 ) 231 232 // CPUCacheMode is the CPU cache mode that defines the CPU mapping of a resource. 233 // 234 // Reference: https://developer.apple.com/documentation/metal/mtlcpucachemode. 235 type CPUCacheMode uint8 236 237 const ( 238 // CPUCacheModeDefaultCache is the default CPU cache mode for the resource. 239 // Guarantees that read and write operations are executed in the expected order. 240 CPUCacheModeDefaultCache CPUCacheMode = 0 241 242 // CPUCacheModeWriteCombined is a write-combined CPU cache mode for the resource. 243 // Optimized for resources that the CPU will write into, but never read. 244 CPUCacheModeWriteCombined CPUCacheMode = 1 245 ) 246 247 // IndexType is the index type for an index buffer that references vertices of geometric primitives. 248 // 249 // Reference: https://developer.apple.com/documentation/metal/mtlstoragemode 250 type IndexType uint8 251 252 const ( 253 // IndexTypeUInt16 is a 16-bit unsigned integer used as a primitive index. 254 IndexTypeUInt16 IndexType = 0 255 256 // IndexTypeUInt32 is a 32-bit unsigned integer used as a primitive index. 257 IndexTypeUInt32 IndexType = 1 258 ) 259 260 type TextureUsage uint8 261 262 const ( 263 TextureUsageUnknown TextureUsage = 0x0000 264 TextureUsageShaderRead TextureUsage = 0x0001 265 TextureUsageShaderWrite TextureUsage = 0x0002 266 TextureUsageRenderTarget TextureUsage = 0x0004 267 TextureUsagePixelFormatView TextureUsage = 0x0008 268 ) 269 270 type BlendFactor uint8 271 272 const ( 273 BlendFactorZero BlendFactor = 0 274 BlendFactorOne BlendFactor = 1 275 BlendFactorSourceColor BlendFactor = 2 276 BlendFactorOneMinusSourceColor BlendFactor = 3 277 BlendFactorSourceAlpha BlendFactor = 4 278 BlendFactorOneMinusSourceAlpha BlendFactor = 5 279 BlendFactorDestinationColor BlendFactor = 6 280 BlendFactorOneMinusDestinationColor BlendFactor = 7 281 BlendFactorDestinationAlpha BlendFactor = 8 282 BlendFactorOneMinusDestinationAlpha BlendFactor = 9 283 BlendFactorSourceAlphaSaturated BlendFactor = 10 284 BlendFactorBlendColor BlendFactor = 11 285 BlendFactorOneMinusBlendColor BlendFactor = 12 286 BlendFactorBlendAlpha BlendFactor = 13 287 BlendFactorOneMinusBlendAlpha BlendFactor = 14 288 BlendFactorSource1Color BlendFactor = 15 289 BlendFactorOneMinusSource1Color BlendFactor = 16 290 BlendFactorSource1Alpha BlendFactor = 17 291 BlendFactorOneMinusSource1Alpha BlendFactor = 18 292 ) 293 294 // Resource represents a memory allocation for storing specialized data 295 // that is accessible to the GPU. 296 // 297 // Reference: https://developer.apple.com/documentation/metal/mtlresource. 298 type Resource interface { 299 // resource returns the underlying id<MTLResource> pointer. 300 resource() unsafe.Pointer 301 } 302 303 // RenderPipelineDescriptor configures new RenderPipelineState objects. 304 // 305 // Reference: https://developer.apple.com/documentation/metal/mtlrenderpipelinedescriptor. 306 type RenderPipelineDescriptor struct { 307 // VertexFunction is a programmable function that processes individual vertices in a rendering pass. 308 VertexFunction Function 309 310 // FragmentFunction is a programmable function that processes individual fragments in a rendering pass. 311 FragmentFunction Function 312 313 // ColorAttachments is an array of attachments that store color data. 314 ColorAttachments [1]RenderPipelineColorAttachmentDescriptor 315 } 316 317 // RenderPipelineColorAttachmentDescriptor describes a color render target that specifies 318 // the color configuration and color operations associated with a render pipeline. 319 // 320 // Reference: https://developer.apple.com/documentation/metal/mtlrenderpipelinecolorattachmentdescriptor. 321 type RenderPipelineColorAttachmentDescriptor struct { 322 // PixelFormat is the pixel format of the color attachment's texture. 323 PixelFormat PixelFormat 324 325 BlendingEnabled bool 326 327 DestinationAlphaBlendFactor BlendFactor 328 DestinationRGBBlendFactor BlendFactor 329 SourceAlphaBlendFactor BlendFactor 330 SourceRGBBlendFactor BlendFactor 331 } 332 333 // RenderPassDescriptor describes a group of render targets that serve as 334 // the output destination for pixels generated by a render pass. 335 // 336 // Reference: https://developer.apple.com/documentation/metal/mtlrenderpassdescriptor. 337 type RenderPassDescriptor struct { 338 // ColorAttachments is array of state information for attachments that store color data. 339 ColorAttachments [1]RenderPassColorAttachmentDescriptor 340 } 341 342 // RenderPassColorAttachmentDescriptor describes a color render target that serves 343 // as the output destination for color pixels generated by a render pass. 344 // 345 // Reference: https://developer.apple.com/documentation/metal/mtlrenderpasscolorattachmentdescriptor. 346 type RenderPassColorAttachmentDescriptor struct { 347 RenderPassAttachmentDescriptor 348 ClearColor ClearColor 349 } 350 351 // RenderPassAttachmentDescriptor describes a render target that serves 352 // as the output destination for pixels generated by a render pass. 353 // 354 // Reference: https://developer.apple.com/documentation/metal/mtlrenderpassattachmentdescriptor. 355 type RenderPassAttachmentDescriptor struct { 356 LoadAction LoadAction 357 StoreAction StoreAction 358 Texture Texture 359 } 360 361 // ClearColor is an RGBA value used for a color pixel. 362 // 363 // Reference: https://developer.apple.com/documentation/metal/mtlclearcolor. 364 type ClearColor struct { 365 Red, Green, Blue, Alpha float64 366 } 367 368 // TextureDescriptor configures new Texture objects. 369 // 370 // Reference: https://developer.apple.com/documentation/metal/mtltexturedescriptor. 371 type TextureDescriptor struct { 372 TextureType TextureType 373 PixelFormat PixelFormat 374 Width int 375 Height int 376 StorageMode StorageMode 377 Usage TextureUsage 378 } 379 380 // Device is abstract representation of the GPU that 381 // serves as the primary interface for a Metal app. 382 // 383 // Reference: https://developer.apple.com/documentation/metal/mtldevice. 384 type Device struct { 385 device unsafe.Pointer 386 387 // Headless indicates whether a device is configured as headless. 388 Headless bool 389 390 // LowPower indicates whether a device is low-power. 391 LowPower bool 392 393 // Name is the name of the device. 394 Name string 395 } 396 397 // CreateSystemDefaultDevice returns the preferred system default Metal device. 398 // 399 // Reference: https://developer.apple.com/documentation/metal/1433401-mtlcreatesystemdefaultdevice. 400 func CreateSystemDefaultDevice() (Device, error) { 401 d := C.CreateSystemDefaultDevice() 402 if d.Device == nil { 403 return Device{}, errors.New("Metal is not supported on this system") 404 } 405 406 return Device{ 407 device: d.Device, 408 Headless: d.Headless != 0, 409 LowPower: d.LowPower != 0, 410 Name: C.GoString(d.Name), 411 }, nil 412 } 413 414 // Device returns the underlying id<MTLDevice> pointer. 415 func (d Device) Device() unsafe.Pointer { return d.device } 416 417 // SupportsFeatureSet reports whether device d supports feature set fs. 418 // 419 // Reference: https://developer.apple.com/documentation/metal/mtldevice/1433418-supportsfeatureset. 420 func (d Device) SupportsFeatureSet(fs FeatureSet) bool { 421 return C.Device_SupportsFeatureSet(d.device, C.uint16_t(fs)) != 0 422 } 423 424 // MakeCommandQueue creates a serial command submission queue. 425 // 426 // Reference: https://developer.apple.com/documentation/metal/mtldevice/1433388-makecommandqueue. 427 func (d Device) MakeCommandQueue() CommandQueue { 428 return CommandQueue{C.Device_MakeCommandQueue(d.device)} 429 } 430 431 // MakeLibrary creates a new library that contains 432 // the functions stored in the specified source string. 433 // 434 // Reference: https://developer.apple.com/documentation/metal/mtldevice/1433431-makelibrary. 435 func (d Device) MakeLibrary(source string, opt CompileOptions) (Library, error) { 436 cs := C.CString(source) 437 defer C.free(unsafe.Pointer(cs)) 438 439 l := C.Device_MakeLibrary(d.device, cs, C.size_t(len(source))) 440 if l.Library == nil { 441 return Library{}, errors.New(C.GoString(l.Error)) 442 } 443 444 return Library{l.Library}, nil 445 } 446 447 // MakeRenderPipelineState creates a render pipeline state object. 448 // 449 // Reference: https://developer.apple.com/documentation/metal/mtldevice/1433369-makerenderpipelinestate. 450 func (d Device) MakeRenderPipelineState(rpd RenderPipelineDescriptor) (RenderPipelineState, error) { 451 blendingEnabled := 0 452 if rpd.ColorAttachments[0].BlendingEnabled { 453 blendingEnabled = 1 454 } 455 c := &rpd.ColorAttachments[0] 456 descriptor := C.struct_RenderPipelineDescriptor{ 457 VertexFunction: rpd.VertexFunction.function, 458 FragmentFunction: rpd.FragmentFunction.function, 459 ColorAttachment0PixelFormat: C.uint16_t(c.PixelFormat), 460 ColorAttachment0BlendingEnabled: C.uint8_t(blendingEnabled), 461 ColorAttachment0DestinationAlphaBlendFactor: C.uint8_t(c.DestinationAlphaBlendFactor), 462 ColorAttachment0DestinationRGBBlendFactor: C.uint8_t(c.DestinationRGBBlendFactor), 463 ColorAttachment0SourceAlphaBlendFactor: C.uint8_t(c.SourceAlphaBlendFactor), 464 ColorAttachment0SourceRGBBlendFactor: C.uint8_t(c.SourceRGBBlendFactor), 465 } 466 rps := C.Device_MakeRenderPipelineState(d.device, descriptor) 467 if rps.RenderPipelineState == nil { 468 return RenderPipelineState{}, errors.New(C.GoString(rps.Error)) 469 } 470 471 return RenderPipelineState{rps.RenderPipelineState}, nil 472 } 473 474 // MakeBufferWithBytes allocates a new buffer of a given length 475 // and initializes its contents by copying existing data into it. 476 // 477 // Reference: https://developer.apple.com/documentation/metal/mtldevice/1433429-makebuffer. 478 func (d Device) MakeBufferWithBytes(bytes unsafe.Pointer, length uintptr, opt ResourceOptions) Buffer { 479 return Buffer{C.Device_MakeBufferWithBytes(d.device, bytes, C.size_t(length), C.uint16_t(opt))} 480 } 481 482 // MakeBufferWithLength allocates a new zero-filled buffer of a given length. 483 // 484 // Reference: https://developer.apple.com/documentation/metal/mtldevice/1433375-newbufferwithlength 485 func (d Device) MakeBufferWithLength(length uintptr, opt ResourceOptions) Buffer { 486 return Buffer{C.Device_MakeBufferWithLength(d.device, C.size_t(length), C.uint16_t(opt))} 487 } 488 489 // MakeTexture creates a texture object with privately owned storage 490 // that contains texture state. 491 // 492 // Reference: https://developer.apple.com/documentation/metal/mtldevice/1433425-maketexture. 493 func (d Device) MakeTexture(td TextureDescriptor) Texture { 494 descriptor := C.struct_TextureDescriptor{ 495 TextureType: C.uint16_t(td.TextureType), 496 PixelFormat: C.uint16_t(td.PixelFormat), 497 Width: C.uint_t(td.Width), 498 Height: C.uint_t(td.Height), 499 StorageMode: C.uint8_t(td.StorageMode), 500 Usage: C.uint8_t(td.Usage), 501 } 502 return Texture{ 503 texture: C.Device_MakeTexture(d.device, descriptor), 504 } 505 } 506 507 // CompileOptions specifies optional compilation settings for 508 // the graphics or compute functions within a library. 509 // 510 // Reference: https://developer.apple.com/documentation/metal/mtlcompileoptions. 511 type CompileOptions struct { 512 // TODO. 513 } 514 515 // Drawable is a displayable resource that can be rendered or written to. 516 // 517 // Reference: https://developer.apple.com/documentation/metal/mtldrawable. 518 type Drawable interface { 519 // Drawable returns the underlying id<MTLDrawable> pointer. 520 Drawable() unsafe.Pointer 521 } 522 523 // CommandQueue is a queue that organizes the order 524 // in which command buffers are executed by the GPU. 525 // 526 // Reference: https://developer.apple.com/documentation/metal/mtlcommandqueue. 527 type CommandQueue struct { 528 commandQueue unsafe.Pointer 529 } 530 531 func (c CommandQueue) Release() { 532 C.CommandQueue_Release(c.commandQueue) 533 } 534 535 // MakeCommandBuffer creates a command buffer. 536 // 537 // Reference: https://developer.apple.com/documentation/metal/mtlcommandqueue/1508686-makecommandbuffer. 538 func (cq CommandQueue) MakeCommandBuffer() CommandBuffer { 539 return CommandBuffer{C.CommandQueue_MakeCommandBuffer(cq.commandQueue)} 540 } 541 542 // CommandBuffer is a container that stores encoded commands 543 // that are committed to and executed by the GPU. 544 // 545 // Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer. 546 type CommandBuffer struct { 547 commandBuffer unsafe.Pointer 548 } 549 550 // PresentDrawable registers a drawable presentation to occur as soon as possible. 551 // 552 // Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer/1443029-presentdrawable. 553 func (cb CommandBuffer) PresentDrawable(d Drawable) { 554 C.CommandBuffer_PresentDrawable(cb.commandBuffer, d.Drawable()) 555 } 556 557 // Commit commits this command buffer for execution as soon as possible. 558 // 559 // Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer/1443003-commit. 560 func (cb CommandBuffer) Commit() { 561 C.CommandBuffer_Commit(cb.commandBuffer) 562 } 563 564 // WaitUntilCompleted waits for the execution of this command buffer to complete. 565 // 566 // Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer/1443039-waituntilcompleted. 567 func (cb CommandBuffer) WaitUntilCompleted() { 568 C.CommandBuffer_WaitUntilCompleted(cb.commandBuffer) 569 } 570 571 // MakeRenderCommandEncoder creates an encoder object that can 572 // encode graphics rendering commands into this command buffer. 573 // 574 // Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer/1442999-makerendercommandencoder. 575 func (cb CommandBuffer) MakeRenderCommandEncoder(rpd RenderPassDescriptor) RenderCommandEncoder { 576 descriptor := C.struct_RenderPassDescriptor{ 577 ColorAttachment0LoadAction: C.uint8_t(rpd.ColorAttachments[0].LoadAction), 578 ColorAttachment0StoreAction: C.uint8_t(rpd.ColorAttachments[0].StoreAction), 579 ColorAttachment0ClearColor: C.struct_ClearColor{ 580 Red: C.double(rpd.ColorAttachments[0].ClearColor.Red), 581 Green: C.double(rpd.ColorAttachments[0].ClearColor.Green), 582 Blue: C.double(rpd.ColorAttachments[0].ClearColor.Blue), 583 Alpha: C.double(rpd.ColorAttachments[0].ClearColor.Alpha), 584 }, 585 ColorAttachment0Texture: rpd.ColorAttachments[0].Texture.texture, 586 } 587 return RenderCommandEncoder{CommandEncoder{C.CommandBuffer_MakeRenderCommandEncoder(cb.commandBuffer, descriptor)}} 588 } 589 590 // MakeBlitCommandEncoder creates an encoder object that can encode 591 // memory operation (blit) commands into this command buffer. 592 // 593 // Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer/1443001-makeblitcommandencoder. 594 func (cb CommandBuffer) MakeBlitCommandEncoder() BlitCommandEncoder { 595 return BlitCommandEncoder{CommandEncoder{C.CommandBuffer_MakeBlitCommandEncoder(cb.commandBuffer)}} 596 } 597 598 // CommandEncoder is an encoder that writes sequential GPU commands 599 // into a command buffer. 600 // 601 // Reference: https://developer.apple.com/documentation/metal/mtlcommandencoder. 602 type CommandEncoder struct { 603 commandEncoder unsafe.Pointer 604 } 605 606 // EndEncoding declares that all command generation from this encoder is completed. 607 // 608 // Reference: https://developer.apple.com/documentation/metal/mtlcommandencoder/1458038-endencoding. 609 func (ce CommandEncoder) EndEncoding() { 610 C.CommandEncoder_EndEncoding(ce.commandEncoder) 611 } 612 613 // RenderCommandEncoder is an encoder that specifies graphics-rendering commands 614 // and executes graphics functions. 615 // 616 // Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder. 617 type RenderCommandEncoder struct { 618 CommandEncoder 619 } 620 621 func (rce RenderCommandEncoder) Release() { 622 C.RenderCommandEncoder_Release(rce.commandEncoder) 623 } 624 625 // SetRenderPipelineState sets the current render pipeline state object. 626 // 627 // Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515811-setrenderpipelinestate. 628 func (rce RenderCommandEncoder) SetRenderPipelineState(rps RenderPipelineState) { 629 C.RenderCommandEncoder_SetRenderPipelineState(rce.commandEncoder, rps.renderPipelineState) 630 } 631 632 func (rce RenderCommandEncoder) SetViewport(viewport Viewport) { 633 C.RenderCommandEncoder_SetViewport(rce.commandEncoder, viewport.c()) 634 } 635 636 // SetScissorRect sets the scissor rectangle for a fragment scissor test. 637 // 638 // Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515583-setscissorrect 639 func (rce RenderCommandEncoder) SetScissorRect(scissorRect ScissorRect) { 640 C.RenderCommandEncoder_SetScissorRect(rce.commandEncoder, scissorRect.c()) 641 } 642 643 // SetVertexBuffer sets a buffer for the vertex shader function at an index 644 // in the buffer argument table with an offset that specifies the start of the data. 645 // 646 // Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515829-setvertexbuffer. 647 func (rce RenderCommandEncoder) SetVertexBuffer(buf Buffer, offset, index int) { 648 C.RenderCommandEncoder_SetVertexBuffer(rce.commandEncoder, buf.buffer, C.uint_t(offset), C.uint_t(index)) 649 } 650 651 // SetVertexBytes sets a block of data for the vertex function. 652 // 653 // Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515846-setvertexbytes. 654 func (rce RenderCommandEncoder) SetVertexBytes(bytes unsafe.Pointer, length uintptr, index int) { 655 C.RenderCommandEncoder_SetVertexBytes(rce.commandEncoder, bytes, C.size_t(length), C.uint_t(index)) 656 } 657 658 func (rce RenderCommandEncoder) SetFragmentBytes(bytes unsafe.Pointer, length uintptr, index int) { 659 C.RenderCommandEncoder_SetFragmentBytes(rce.commandEncoder, bytes, C.size_t(length), C.uint_t(index)) 660 } 661 662 // SetFragmentTexture sets a texture for the fragment function at an index in the texture argument table. 663 // 664 // Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515390-setfragmenttexture 665 func (rce RenderCommandEncoder) SetFragmentTexture(texture Texture, index int) { 666 C.RenderCommandEncoder_SetFragmentTexture(rce.commandEncoder, texture.texture, C.uint_t(index)) 667 } 668 669 func (rce RenderCommandEncoder) SetBlendColor(red, green, blue, alpha float32) { 670 C.RenderCommandEncoder_SetBlendColor(rce.commandEncoder, C.float(red), C.float(green), C.float(blue), C.float(alpha)) 671 } 672 673 // DrawPrimitives renders one instance of primitives using vertex data 674 // in contiguous array elements. 675 // 676 // Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1516326-drawprimitives. 677 func (rce RenderCommandEncoder) DrawPrimitives(typ PrimitiveType, vertexStart, vertexCount int) { 678 C.RenderCommandEncoder_DrawPrimitives(rce.commandEncoder, C.uint8_t(typ), C.uint_t(vertexStart), C.uint_t(vertexCount)) 679 } 680 681 // DrawIndexedPrimitives encodes a command to render one instance of primitives using an index list specified in a buffer. 682 // 683 // Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515542-drawindexedprimitives 684 func (rce RenderCommandEncoder) DrawIndexedPrimitives(typ PrimitiveType, indexCount int, indexType IndexType, indexBuffer Buffer, indexBufferOffset int) { 685 C.RenderCommandEncoder_DrawIndexedPrimitives(rce.commandEncoder, C.uint8_t(typ), C.uint_t(indexCount), C.uint8_t(indexType), indexBuffer.buffer, C.uint_t(indexBufferOffset)) 686 } 687 688 // BlitCommandEncoder is an encoder that specifies resource copy 689 // and resource synchronization commands. 690 // 691 // Reference: https://developer.apple.com/documentation/metal/mtlblitcommandencoder. 692 type BlitCommandEncoder struct { 693 CommandEncoder 694 } 695 696 // Synchronize flushes any copy of the specified resource from its corresponding 697 // Device caches and, if needed, invalidates any CPU caches. 698 // 699 // Reference: https://developer.apple.com/documentation/metal/mtlblitcommandencoder/1400775-synchronize. 700 func (bce BlitCommandEncoder) Synchronize(resource Resource) { 701 C.BlitCommandEncoder_Synchronize(bce.commandEncoder, resource.resource()) 702 } 703 704 func (bce BlitCommandEncoder) SynchronizeTexture(texture Texture, slice int, level int) { 705 C.BlitCommandEncoder_SynchronizeTexture(bce.commandEncoder, texture.texture, C.uint_t(slice), C.uint_t(level)) 706 } 707 708 func (bce BlitCommandEncoder) CopyFromTexture(sourceTexture Texture, sourceSlice int, sourceLevel int, sourceOrigin Origin, sourceSize Size, destinationTexture Texture, destinationSlice int, destinationLevel int, destinationOrigin Origin) { 709 C.BlitCommandEncoder_CopyFromTexture(bce.commandEncoder, sourceTexture.texture, C.uint_t(sourceSlice), C.uint_t(sourceLevel), sourceOrigin.c(), sourceSize.c(), destinationTexture.texture, C.uint_t(destinationSlice), C.uint_t(destinationLevel), destinationOrigin.c()) 710 } 711 712 // Library is a collection of compiled graphics or compute functions. 713 // 714 // Reference: https://developer.apple.com/documentation/metal/mtllibrary. 715 type Library struct { 716 library unsafe.Pointer 717 } 718 719 // MakeFunction returns a pre-compiled, non-specialized function. 720 // 721 // Reference: https://developer.apple.com/documentation/metal/mtllibrary/1515524-makefunction. 722 func (l Library) MakeFunction(name string) (Function, error) { 723 f := C.Library_MakeFunction(l.library, C.CString(name)) 724 if f == nil { 725 return Function{}, fmt.Errorf("function %q not found", name) 726 } 727 728 return Function{f}, nil 729 } 730 731 // Texture is a memory allocation for storing formatted 732 // image data that is accessible to the GPU. 733 // 734 // Reference: https://developer.apple.com/documentation/metal/mtltexture. 735 type Texture struct { 736 texture unsafe.Pointer 737 } 738 739 // NewTexture returns a Texture that wraps an existing id<MTLTexture> pointer. 740 func NewTexture(texture unsafe.Pointer) Texture { 741 return Texture{texture: texture} 742 } 743 744 // resource implements the Resource interface. 745 func (t Texture) resource() unsafe.Pointer { return t.texture } 746 747 func (t Texture) Release() { 748 C.Texture_Release(t.texture) 749 } 750 751 // GetBytes copies a block of pixels from the storage allocation of texture 752 // slice zero into system memory at a specified address. 753 // 754 // Reference: https://developer.apple.com/documentation/metal/mtltexture/1515751-getbytes. 755 func (t Texture) GetBytes(pixelBytes *byte, bytesPerRow uintptr, region Region, level int) { 756 r := region.c() 757 C.Texture_GetBytes(t.texture, unsafe.Pointer(pixelBytes), C.size_t(bytesPerRow), r, C.uint_t(level)) 758 } 759 760 // ReplaceRegion copies a block of pixels from the caller's pointer into the storage allocation for slice 0 of a texture. 761 // 762 // Reference: https://developer.apple.com/documentation/metal/mtltexture/1515464-replaceregion 763 func (t Texture) ReplaceRegion(region Region, level int, pixelBytes unsafe.Pointer, bytesPerRow int) { 764 r := region.c() 765 C.Texture_ReplaceRegion(t.texture, r, C.uint_t(level), pixelBytes, C.uint_t(bytesPerRow)) 766 } 767 768 // Width is the width of the texture image for the base level mipmap, in pixels. 769 // 770 // Reference: https://developer.apple.com/documentation/metal/mtltexture/1515339-width 771 func (t Texture) Width() int { 772 return int(C.Texture_Width(t.texture)) 773 } 774 775 // Height is the height of the texture image for the base level mipmap, in pixels. 776 // 777 // Reference: https://developer.apple.com/documentation/metal/mtltexture/1515938-height 778 func (t Texture) Height() int { 779 return int(C.Texture_Height(t.texture)) 780 } 781 782 // Buffer is a memory allocation for storing unformatted data 783 // that is accessible to the GPU. 784 // 785 // Reference: https://developer.apple.com/documentation/metal/mtlbuffer. 786 type Buffer struct { 787 buffer unsafe.Pointer 788 } 789 790 func (b Buffer) CopyToContents(data unsafe.Pointer, lengthInBytes uintptr) { 791 C.Buffer_CopyToContents(b.buffer, data, C.size_t(lengthInBytes)) 792 } 793 794 func (b Buffer) Retain() { 795 C.Buffer_Retain(b.buffer) 796 } 797 798 func (b Buffer) Release() { 799 C.Buffer_Release(b.buffer) 800 } 801 802 func (b Buffer) Native() unsafe.Pointer { 803 return b.buffer 804 } 805 806 // Function represents a programmable graphics or compute function executed by the GPU. 807 // 808 // Reference: https://developer.apple.com/documentation/metal/mtlfunction. 809 type Function struct { 810 function unsafe.Pointer 811 } 812 813 func (f Function) Release() { 814 C.Function_Release(f.function) 815 } 816 817 // RenderPipelineState contains the graphics functions 818 // and configuration state used in a render pass. 819 // 820 // Reference: https://developer.apple.com/documentation/metal/mtlrenderpipelinestate. 821 type RenderPipelineState struct { 822 renderPipelineState unsafe.Pointer 823 } 824 825 func (r RenderPipelineState) Release() { 826 C.RenderPipelineState_Release(r.renderPipelineState) 827 } 828 829 // Region is a rectangular block of pixels in an image or texture, 830 // defined by its upper-left corner and its size. 831 // 832 // Reference: https://developer.apple.com/documentation/metal/mtlregion. 833 type Region struct { 834 Origin Origin // The location of the upper-left corner of the block. 835 Size Size // The size of the block. 836 } 837 838 func (r *Region) c() C.struct_Region { 839 return C.struct_Region{ 840 Origin: r.Origin.c(), 841 Size: r.Size.c(), 842 } 843 } 844 845 // Origin represents the location of a pixel in an image or texture relative 846 // to the upper-left corner, whose coordinates are (0, 0). 847 // 848 // Reference: https://developer.apple.com/documentation/metal/mtlorigin. 849 type Origin struct{ X, Y, Z int } 850 851 func (o *Origin) c() C.struct_Origin { 852 return C.struct_Origin{ 853 X: C.uint_t(o.X), 854 Y: C.uint_t(o.Y), 855 Z: C.uint_t(o.Z), 856 } 857 } 858 859 // Size represents the set of dimensions that declare the size of an object, 860 // such as an image, texture, threadgroup, or grid. 861 // 862 // Reference: https://developer.apple.com/documentation/metal/mtlsize. 863 type Size struct{ Width, Height, Depth int } 864 865 func (s *Size) c() C.struct_Size { 866 return C.struct_Size{ 867 Width: C.uint_t(s.Width), 868 Height: C.uint_t(s.Height), 869 Depth: C.uint_t(s.Depth), 870 } 871 } 872 873 // RegionMake2D returns a 2D, rectangular region for image or texture data. 874 // 875 // Reference: https://developer.apple.com/documentation/metal/1515675-mtlregionmake2d. 876 func RegionMake2D(x, y, width, height int) Region { 877 return Region{ 878 Origin: Origin{x, y, 0}, 879 Size: Size{width, height, 1}, 880 } 881 } 882 883 type Viewport struct { 884 OriginX float64 885 OriginY float64 886 Width float64 887 Height float64 888 ZNear float64 889 ZFar float64 890 } 891 892 func (v *Viewport) c() C.struct_Viewport { 893 return C.struct_Viewport{ 894 OriginX: C.double(v.OriginX), 895 OriginY: C.double(v.OriginY), 896 Width: C.double(v.Width), 897 Height: C.double(v.Height), 898 ZNear: C.double(v.ZNear), 899 ZFar: C.double(v.ZFar), 900 } 901 } 902 903 // ScissorRect represents a rectangle for the scissor fragment test. 904 // 905 // Reference: https://developer.apple.com/documentation/metal/mtlscissorrect 906 type ScissorRect struct { 907 X int 908 Y int 909 Width int 910 Height int 911 } 912 913 func (s *ScissorRect) c() C.struct_ScissorRect { 914 return C.struct_ScissorRect{ 915 X: C.uint_t(s.X), 916 Y: C.uint_t(s.Y), 917 Width: C.uint_t(s.Width), 918 Height: C.uint_t(s.Height), 919 } 920 }