mtl.go (36020B)
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 <stdlib.h> 37 // #include "mtl.h" 38 // struct Library Go_Device_MakeLibrary(void * device, _GoString_ source) { 39 // return Device_MakeLibrary(device, _GoStringPtr(source), _GoStringLen(source)); 40 // } 41 import "C" 42 43 // FeatureSet defines a specific platform, hardware, and software configuration. 44 // 45 // Reference: https://developer.apple.com/documentation/metal/mtlfeatureset. 46 type FeatureSet uint16 47 48 // The device feature sets that define specific platform, hardware, and software configurations. 49 const ( 50 MacOSGPUFamily1V1 FeatureSet = 10000 // The GPU family 1, version 1 feature set for macOS. 51 MacOSGPUFamily1V2 FeatureSet = 10001 // The GPU family 1, version 2 feature set for macOS. 52 MacOSReadWriteTextureTier2 FeatureSet = 10002 // The read-write texture, tier 2 feature set for macOS. 53 MacOSGPUFamily1V3 FeatureSet = 10003 // The GPU family 1, version 3 feature set for macOS. 54 MacOSGPUFamily1V4 FeatureSet = 10004 // The GPU family 1, version 4 feature set for macOS. 55 MacOSGPUFamily2V1 FeatureSet = 10005 // The GPU family 2, version 1 feature set for macOS. 56 ) 57 58 const ( 59 FeatureSet_iOS_GPUFamily1_v1 FeatureSet = 0 60 FeatureSet_iOS_GPUFamily1_v2 FeatureSet = 2 61 FeatureSet_iOS_GPUFamily1_v3 FeatureSet = 5 62 FeatureSet_iOS_GPUFamily1_v4 FeatureSet = 8 63 FeatureSet_iOS_GPUFamily1_v5 FeatureSet = 12 64 FeatureSet_iOS_GPUFamily2_v1 FeatureSet = 1 65 FeatureSet_iOS_GPUFamily2_v2 FeatureSet = 3 66 FeatureSet_iOS_GPUFamily2_v3 FeatureSet = 6 67 FeatureSet_iOS_GPUFamily2_v4 FeatureSet = 9 68 FeatureSet_iOS_GPUFamily2_v5 FeatureSet = 13 69 FeatureSet_iOS_GPUFamily3_v1 FeatureSet = 4 70 FeatureSet_iOS_GPUFamily3_v2 FeatureSet = 7 71 FeatureSet_iOS_GPUFamily3_v3 FeatureSet = 10 72 FeatureSet_iOS_GPUFamily3_v4 FeatureSet = 14 73 FeatureSet_iOS_GPUFamily4_v1 FeatureSet = 11 74 FeatureSet_iOS_GPUFamily4_v2 FeatureSet = 15 75 FeatureSet_iOS_GPUFamily5_v1 FeatureSet = 16 76 FeatureSet_tvOS_GPUFamily1_v1 FeatureSet = 30000 77 FeatureSet_tvOS_GPUFamily1_v2 FeatureSet = 30001 78 FeatureSet_tvOS_GPUFamily1_v3 FeatureSet = 30002 79 FeatureSet_tvOS_GPUFamily1_v4 FeatureSet = 30004 80 FeatureSet_tvOS_GPUFamily2_v1 FeatureSet = 30003 81 FeatureSet_tvOS_GPUFamily2_v2 FeatureSet = 30005 82 FeatureSet_macOS_GPUFamily1_v1 FeatureSet = 10000 83 FeatureSet_macOS_GPUFamily1_v2 FeatureSet = 10001 84 FeatureSet_macOS_GPUFamily1_v3 FeatureSet = 10003 85 FeatureSet_macOS_GPUFamily1_v4 FeatureSet = 10004 86 FeatureSet_macOS_GPUFamily2_v1 FeatureSet = 10005 87 FeatureSet_macOS_ReadWriteTextureTier2 FeatureSet = 10002 88 ) 89 90 // TextureType defines The dimension of each image, including whether multiple images are arranged into an array or 91 // a cube. 92 // 93 // Reference: https://developer.apple.com/documentation/metal/mtltexturetype 94 type TextureType uint16 95 96 const ( 97 TextureType2D TextureType = 2 98 ) 99 100 // PixelFormat defines data formats that describe the organization 101 // and characteristics of individual pixels in a texture. 102 // 103 // Reference: https://developer.apple.com/documentation/metal/mtlpixelformat. 104 type PixelFormat uint16 105 106 // The data formats that describe the organization and characteristics 107 // of individual pixels in a texture. 108 const ( 109 PixelFormatRGBA8UNorm PixelFormat = 70 // Ordinary format with four 8-bit normalized unsigned integer components in RGBA order. 110 PixelFormatRGBA8UNormSRGB PixelFormat = 71 // Ordinary format with four 8-bit normalized unsigned integer components in RGBA order with conversion between sRGB and linear space. 111 PixelFormatBGRA8UNorm PixelFormat = 80 // Ordinary format with four 8-bit normalized unsigned integer components in BGRA order. 112 PixelFormatBGRA8UNormSRGB PixelFormat = 81 // Ordinary format with four 8-bit normalized unsigned integer components in BGRA order with conversion between sRGB and linear space. 113 ) 114 115 // PrimitiveType defines geometric primitive types for drawing commands. 116 // 117 // Reference: https://developer.apple.com/documentation/metal/mtlprimitivetype. 118 type PrimitiveType uint8 119 120 // Geometric primitive types for drawing commands. 121 const ( 122 PrimitiveTypePoint PrimitiveType = 0 123 PrimitiveTypeLine PrimitiveType = 1 124 PrimitiveTypeLineStrip PrimitiveType = 2 125 PrimitiveTypeTriangle PrimitiveType = 3 126 PrimitiveTypeTriangleStrip PrimitiveType = 4 127 ) 128 129 // LoadAction defines actions performed at the start of a rendering pass 130 // for a render command encoder. 131 // 132 // Reference: https://developer.apple.com/documentation/metal/mtlloadaction. 133 type LoadAction uint8 134 135 // Actions performed at the start of a rendering pass for a render command encoder. 136 const ( 137 LoadActionDontCare LoadAction = 0 138 LoadActionLoad LoadAction = 1 139 LoadActionClear LoadAction = 2 140 ) 141 142 // StoreAction defines actions performed at the end of a rendering pass 143 // for a render command encoder. 144 // 145 // Reference: https://developer.apple.com/documentation/metal/mtlstoreaction. 146 type StoreAction uint8 147 148 // Actions performed at the end of a rendering pass for a render command encoder. 149 const ( 150 StoreActionDontCare StoreAction = 0 151 StoreActionStore StoreAction = 1 152 StoreActionMultisampleResolve StoreAction = 2 153 StoreActionStoreAndMultisampleResolve StoreAction = 3 154 StoreActionUnknown StoreAction = 4 155 StoreActionCustomSampleDepthStore StoreAction = 5 156 ) 157 158 // StorageMode defines defines the memory location and access permissions of a resource. 159 // 160 // Reference: https://developer.apple.com/documentation/metal/mtlstoragemode. 161 type StorageMode uint8 162 163 const ( 164 // StorageModeShared indicates that the resource is stored in system memory 165 // accessible to both the CPU and the GPU. 166 StorageModeShared StorageMode = 0 167 168 // StorageModeManaged indicates that the resource exists as a synchronized 169 // memory pair with one copy stored in system memory accessible to the CPU 170 // and another copy stored in video memory accessible to the GPU. 171 StorageModeManaged StorageMode = 1 172 173 // StorageModePrivate indicates that the resource is stored in memory 174 // only accessible to the GPU. In iOS and tvOS, the resource is stored in 175 // system memory. In macOS, the resource is stored in video memory. 176 StorageModePrivate StorageMode = 2 177 178 // StorageModeMemoryless indicates that the resource is stored in on-tile memory, 179 // without CPU or GPU memory backing. The contents of the on-tile memory are undefined 180 // and do not persist; the only way to populate the resource is to render into it. 181 // Memoryless resources are limited to temporary render targets (i.e., Textures configured 182 // with a TextureDescriptor and used with a RenderPassAttachmentDescriptor). 183 StorageModeMemoryless StorageMode = 3 184 ) 185 186 // ResourceOptions defines optional arguments used to create 187 // and influence behavior of buffer and texture objects. 188 // 189 // Reference: https://developer.apple.com/documentation/metal/mtlresourceoptions. 190 type ResourceOptions uint16 191 192 const ( 193 // ResourceCPUCacheModeDefaultCache is the default CPU cache mode for the resource. 194 // Guarantees that read and write operations are executed in the expected order. 195 ResourceCPUCacheModeDefaultCache ResourceOptions = ResourceOptions(CPUCacheModeDefaultCache) << resourceCPUCacheModeShift 196 197 // ResourceCPUCacheModeWriteCombined is a write-combined CPU cache mode for the resource. 198 // Optimized for resources that the CPU will write into, but never read. 199 ResourceCPUCacheModeWriteCombined ResourceOptions = ResourceOptions(CPUCacheModeWriteCombined) << resourceCPUCacheModeShift 200 201 // ResourceStorageModeShared indicates that the resource is stored in system memory 202 // accessible to both the CPU and the GPU. 203 ResourceStorageModeShared ResourceOptions = ResourceOptions(StorageModeShared) << resourceStorageModeShift 204 205 // ResourceStorageModeManaged indicates that the resource exists as a synchronized 206 // memory pair with one copy stored in system memory accessible to the CPU 207 // and another copy stored in video memory accessible to the GPU. 208 ResourceStorageModeManaged ResourceOptions = ResourceOptions(StorageModeManaged) << resourceStorageModeShift 209 210 // ResourceStorageModePrivate indicates that the resource is stored in memory 211 // only accessible to the GPU. In iOS and tvOS, the resource is stored 212 // in system memory. In macOS, the resource is stored in video memory. 213 ResourceStorageModePrivate ResourceOptions = ResourceOptions(StorageModePrivate) << resourceStorageModeShift 214 215 // ResourceStorageModeMemoryless indicates that the resource is stored in on-tile memory, 216 // without CPU or GPU memory backing. The contents of the on-tile memory are undefined 217 // and do not persist; the only way to populate the resource is to render into it. 218 // Memoryless resources are limited to temporary render targets (i.e., Textures configured 219 // with a TextureDescriptor and used with a RenderPassAttachmentDescriptor). 220 ResourceStorageModeMemoryless ResourceOptions = ResourceOptions(StorageModeMemoryless) << resourceStorageModeShift 221 222 // ResourceHazardTrackingModeUntracked indicates that the command encoder dependencies 223 // for this resource are tracked manually with Fence objects. This value is always set 224 // for resources sub-allocated from a Heap object and may optionally be specified for 225 // non-heap resources. 226 ResourceHazardTrackingModeUntracked ResourceOptions = 1 << resourceHazardTrackingModeShift 227 ) 228 229 const ( 230 resourceCPUCacheModeShift = 0 231 resourceStorageModeShift = 4 232 resourceHazardTrackingModeShift = 8 233 ) 234 235 // CPUCacheMode is the CPU cache mode that defines the CPU mapping of a resource. 236 // 237 // Reference: https://developer.apple.com/documentation/metal/mtlcpucachemode. 238 type CPUCacheMode uint8 239 240 const ( 241 // CPUCacheModeDefaultCache is the default CPU cache mode for the resource. 242 // Guarantees that read and write operations are executed in the expected order. 243 CPUCacheModeDefaultCache CPUCacheMode = 0 244 245 // CPUCacheModeWriteCombined is a write-combined CPU cache mode for the resource. 246 // Optimized for resources that the CPU will write into, but never read. 247 CPUCacheModeWriteCombined CPUCacheMode = 1 248 ) 249 250 // IndexType is the index type for an index buffer that references vertices of geometric primitives. 251 // 252 // Reference: https://developer.apple.com/documentation/metal/mtlstoragemode 253 type IndexType uint8 254 255 const ( 256 // IndexTypeUInt16 is a 16-bit unsigned integer used as a primitive index. 257 IndexTypeUInt16 IndexType = 0 258 259 // IndexTypeUInt32 is a 32-bit unsigned integer used as a primitive index. 260 IndexTypeUInt32 IndexType = 1 261 ) 262 263 type TextureUsage uint8 264 265 const ( 266 TextureUsageUnknown TextureUsage = 0x0000 267 TextureUsageShaderRead TextureUsage = 0x0001 268 TextureUsageShaderWrite TextureUsage = 0x0002 269 TextureUsageRenderTarget TextureUsage = 0x0004 270 TextureUsagePixelFormatView TextureUsage = 0x0008 271 ) 272 273 type BlendFactor uint8 274 275 const ( 276 BlendFactorZero BlendFactor = 0 277 BlendFactorOne BlendFactor = 1 278 BlendFactorSourceColor BlendFactor = 2 279 BlendFactorOneMinusSourceColor BlendFactor = 3 280 BlendFactorSourceAlpha BlendFactor = 4 281 BlendFactorOneMinusSourceAlpha BlendFactor = 5 282 BlendFactorDestinationColor BlendFactor = 6 283 BlendFactorOneMinusDestinationColor BlendFactor = 7 284 BlendFactorDestinationAlpha BlendFactor = 8 285 BlendFactorOneMinusDestinationAlpha BlendFactor = 9 286 BlendFactorSourceAlphaSaturated BlendFactor = 10 287 BlendFactorBlendColor BlendFactor = 11 288 BlendFactorOneMinusBlendColor BlendFactor = 12 289 BlendFactorBlendAlpha BlendFactor = 13 290 BlendFactorOneMinusBlendAlpha BlendFactor = 14 291 BlendFactorSource1Color BlendFactor = 15 292 BlendFactorOneMinusSource1Color BlendFactor = 16 293 BlendFactorSource1Alpha BlendFactor = 17 294 BlendFactorOneMinusSource1Alpha BlendFactor = 18 295 ) 296 297 // Resource represents a memory allocation for storing specialized data 298 // that is accessible to the GPU. 299 // 300 // Reference: https://developer.apple.com/documentation/metal/mtlresource. 301 type Resource interface { 302 // resource returns the underlying id<MTLResource> pointer. 303 resource() unsafe.Pointer 304 } 305 306 // RenderPipelineDescriptor configures new RenderPipelineState objects. 307 // 308 // Reference: https://developer.apple.com/documentation/metal/mtlrenderpipelinedescriptor. 309 type RenderPipelineDescriptor struct { 310 // VertexFunction is a programmable function that processes individual vertices in a rendering pass. 311 VertexFunction Function 312 313 // FragmentFunction is a programmable function that processes individual fragments in a rendering pass. 314 FragmentFunction Function 315 316 // ColorAttachments is an array of attachments that store color data. 317 ColorAttachments [1]RenderPipelineColorAttachmentDescriptor 318 } 319 320 // RenderPipelineColorAttachmentDescriptor describes a color render target that specifies 321 // the color configuration and color operations associated with a render pipeline. 322 // 323 // Reference: https://developer.apple.com/documentation/metal/mtlrenderpipelinecolorattachmentdescriptor. 324 type RenderPipelineColorAttachmentDescriptor struct { 325 // PixelFormat is the pixel format of the color attachment's texture. 326 PixelFormat PixelFormat 327 328 BlendingEnabled bool 329 330 DestinationAlphaBlendFactor BlendFactor 331 DestinationRGBBlendFactor BlendFactor 332 SourceAlphaBlendFactor BlendFactor 333 SourceRGBBlendFactor BlendFactor 334 } 335 336 // RenderPassDescriptor describes a group of render targets that serve as 337 // the output destination for pixels generated by a render pass. 338 // 339 // Reference: https://developer.apple.com/documentation/metal/mtlrenderpassdescriptor. 340 type RenderPassDescriptor struct { 341 // ColorAttachments is array of state information for attachments that store color data. 342 ColorAttachments [1]RenderPassColorAttachmentDescriptor 343 } 344 345 // RenderPassColorAttachmentDescriptor describes a color render target that serves 346 // as the output destination for color pixels generated by a render pass. 347 // 348 // Reference: https://developer.apple.com/documentation/metal/mtlrenderpasscolorattachmentdescriptor. 349 type RenderPassColorAttachmentDescriptor struct { 350 RenderPassAttachmentDescriptor 351 ClearColor ClearColor 352 } 353 354 // RenderPassAttachmentDescriptor describes a render target that serves 355 // as the output destination for pixels generated by a render pass. 356 // 357 // Reference: https://developer.apple.com/documentation/metal/mtlrenderpassattachmentdescriptor. 358 type RenderPassAttachmentDescriptor struct { 359 LoadAction LoadAction 360 StoreAction StoreAction 361 Texture Texture 362 } 363 364 // ClearColor is an RGBA value used for a color pixel. 365 // 366 // Reference: https://developer.apple.com/documentation/metal/mtlclearcolor. 367 type ClearColor struct { 368 Red, Green, Blue, Alpha float64 369 } 370 371 // TextureDescriptor configures new Texture objects. 372 // 373 // Reference: https://developer.apple.com/documentation/metal/mtltexturedescriptor. 374 type TextureDescriptor struct { 375 TextureType TextureType 376 PixelFormat PixelFormat 377 Width int 378 Height int 379 StorageMode StorageMode 380 Usage TextureUsage 381 } 382 383 // Device is abstract representation of the GPU that 384 // serves as the primary interface for a Metal app. 385 // 386 // Reference: https://developer.apple.com/documentation/metal/mtldevice. 387 type Device struct { 388 device unsafe.Pointer 389 390 // Headless indicates whether a device is configured as headless. 391 Headless bool 392 393 // LowPower indicates whether a device is low-power. 394 LowPower bool 395 396 // Name is the name of the device. 397 Name string 398 } 399 400 // CreateSystemDefaultDevice returns the preferred system default Metal device. 401 // 402 // Reference: https://developer.apple.com/documentation/metal/1433401-mtlcreatesystemdefaultdevice. 403 func CreateSystemDefaultDevice() (Device, error) { 404 d := C.CreateSystemDefaultDevice() 405 if d.Device == nil { 406 return Device{}, errors.New("Metal is not supported on this system") 407 } 408 409 return Device{ 410 device: d.Device, 411 Headless: d.Headless != 0, 412 LowPower: d.LowPower != 0, 413 Name: C.GoString(d.Name), 414 }, nil 415 } 416 417 // Device returns the underlying id<MTLDevice> pointer. 418 func (d Device) Device() unsafe.Pointer { return d.device } 419 420 // SupportsFeatureSet reports whether device d supports feature set fs. 421 // 422 // Reference: https://developer.apple.com/documentation/metal/mtldevice/1433418-supportsfeatureset. 423 func (d Device) SupportsFeatureSet(fs FeatureSet) bool { 424 return C.Device_SupportsFeatureSet(d.device, C.uint16_t(fs)) != 0 425 } 426 427 // MakeCommandQueue creates a serial command submission queue. 428 // 429 // Reference: https://developer.apple.com/documentation/metal/mtldevice/1433388-makecommandqueue. 430 func (d Device) MakeCommandQueue() CommandQueue { 431 return CommandQueue{C.Device_MakeCommandQueue(d.device)} 432 } 433 434 // MakeLibrary creates a new library that contains 435 // the functions stored in the specified source string. 436 // 437 // Reference: https://developer.apple.com/documentation/metal/mtldevice/1433431-makelibrary. 438 func (d Device) MakeLibrary(source string, opt CompileOptions) (Library, error) { 439 l := C.Go_Device_MakeLibrary(d.device, source) // TODO: opt. 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 // SetVertexBuffer sets a buffer for the vertex shader function at an index 637 // in the buffer argument table with an offset that specifies the start of the data. 638 // 639 // Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515829-setvertexbuffer. 640 func (rce RenderCommandEncoder) SetVertexBuffer(buf Buffer, offset, index int) { 641 C.RenderCommandEncoder_SetVertexBuffer(rce.commandEncoder, buf.buffer, C.uint_t(offset), C.uint_t(index)) 642 } 643 644 // SetVertexBytes sets a block of data for the vertex function. 645 // 646 // Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515846-setvertexbytes. 647 func (rce RenderCommandEncoder) SetVertexBytes(bytes unsafe.Pointer, length uintptr, index int) { 648 C.RenderCommandEncoder_SetVertexBytes(rce.commandEncoder, bytes, C.size_t(length), C.uint_t(index)) 649 } 650 651 func (rce RenderCommandEncoder) SetFragmentBytes(bytes unsafe.Pointer, length uintptr, index int) { 652 C.RenderCommandEncoder_SetFragmentBytes(rce.commandEncoder, bytes, C.size_t(length), C.uint_t(index)) 653 } 654 655 // SetFragmentTexture sets a texture for the fragment function at an index in the texture argument table. 656 // 657 // Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515390-setfragmenttexture 658 func (rce RenderCommandEncoder) SetFragmentTexture(texture Texture, index int) { 659 C.RenderCommandEncoder_SetFragmentTexture(rce.commandEncoder, texture.texture, C.uint_t(index)) 660 } 661 662 func (rce RenderCommandEncoder) SetBlendColor(red, green, blue, alpha float32) { 663 C.RenderCommandEncoder_SetBlendColor(rce.commandEncoder, C.float(red), C.float(green), C.float(blue), C.float(alpha)) 664 } 665 666 // DrawPrimitives renders one instance of primitives using vertex data 667 // in contiguous array elements. 668 // 669 // Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1516326-drawprimitives. 670 func (rce RenderCommandEncoder) DrawPrimitives(typ PrimitiveType, vertexStart, vertexCount int) { 671 C.RenderCommandEncoder_DrawPrimitives(rce.commandEncoder, C.uint8_t(typ), C.uint_t(vertexStart), C.uint_t(vertexCount)) 672 } 673 674 // DrawIndexedPrimitives encodes a command to render one instance of primitives using an index list specified in a buffer. 675 // 676 // Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515542-drawindexedprimitives 677 func (rce RenderCommandEncoder) DrawIndexedPrimitives(typ PrimitiveType, indexCount int, indexType IndexType, indexBuffer Buffer, indexBufferOffset int) { 678 C.RenderCommandEncoder_DrawIndexedPrimitives(rce.commandEncoder, C.uint8_t(typ), C.uint_t(indexCount), C.uint8_t(indexType), indexBuffer.buffer, C.uint_t(indexBufferOffset)) 679 } 680 681 // BlitCommandEncoder is an encoder that specifies resource copy 682 // and resource synchronization commands. 683 // 684 // Reference: https://developer.apple.com/documentation/metal/mtlblitcommandencoder. 685 type BlitCommandEncoder struct { 686 CommandEncoder 687 } 688 689 // Synchronize flushes any copy of the specified resource from its corresponding 690 // Device caches and, if needed, invalidates any CPU caches. 691 // 692 // Reference: https://developer.apple.com/documentation/metal/mtlblitcommandencoder/1400775-synchronize. 693 func (bce BlitCommandEncoder) Synchronize(resource Resource) { 694 C.BlitCommandEncoder_Synchronize(bce.commandEncoder, resource.resource()) 695 } 696 697 func (bce BlitCommandEncoder) SynchronizeTexture(texture Texture, slice int, level int) { 698 C.BlitCommandEncoder_SynchronizeTexture(bce.commandEncoder, texture.texture, C.uint_t(slice), C.uint_t(level)) 699 } 700 701 func (bce BlitCommandEncoder) CopyFromTexture(sourceTexture Texture, sourceSlice int, sourceLevel int, sourceOrigin Origin, sourceSize Size, destinationTexture Texture, destinationSlice int, destinationLevel int, destinationOrigin Origin) { 702 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()) 703 } 704 705 // Library is a collection of compiled graphics or compute functions. 706 // 707 // Reference: https://developer.apple.com/documentation/metal/mtllibrary. 708 type Library struct { 709 library unsafe.Pointer 710 } 711 712 // MakeFunction returns a pre-compiled, non-specialized function. 713 // 714 // Reference: https://developer.apple.com/documentation/metal/mtllibrary/1515524-makefunction. 715 func (l Library) MakeFunction(name string) (Function, error) { 716 f := C.Library_MakeFunction(l.library, C.CString(name)) 717 if f == nil { 718 return Function{}, fmt.Errorf("function %q not found", name) 719 } 720 721 return Function{f}, nil 722 } 723 724 // Texture is a memory allocation for storing formatted 725 // image data that is accessible to the GPU. 726 // 727 // Reference: https://developer.apple.com/documentation/metal/mtltexture. 728 type Texture struct { 729 texture unsafe.Pointer 730 } 731 732 // NewTexture returns a Texture that wraps an existing id<MTLTexture> pointer. 733 func NewTexture(texture unsafe.Pointer) Texture { 734 return Texture{texture: texture} 735 } 736 737 // resource implements the Resource interface. 738 func (t Texture) resource() unsafe.Pointer { return t.texture } 739 740 func (t Texture) Release() { 741 C.Texture_Release(t.texture) 742 } 743 744 // GetBytes copies a block of pixels from the storage allocation of texture 745 // slice zero into system memory at a specified address. 746 // 747 // Reference: https://developer.apple.com/documentation/metal/mtltexture/1515751-getbytes. 748 func (t Texture) GetBytes(pixelBytes *byte, bytesPerRow uintptr, region Region, level int) { 749 r := region.c() 750 C.Texture_GetBytes(t.texture, unsafe.Pointer(pixelBytes), C.size_t(bytesPerRow), r, C.uint_t(level)) 751 } 752 753 // ReplaceRegion copies a block of pixels from the caller's pointer into the storage allocation for slice 0 of a texture. 754 // 755 // Reference: https://developer.apple.com/documentation/metal/mtltexture/1515464-replaceregion 756 func (t Texture) ReplaceRegion(region Region, level int, pixelBytes unsafe.Pointer, bytesPerRow int) { 757 r := region.c() 758 C.Texture_ReplaceRegion(t.texture, r, C.uint_t(level), pixelBytes, C.uint_t(bytesPerRow)) 759 } 760 761 // Width is the width of the texture image for the base level mipmap, in pixels. 762 // 763 // Reference: https://developer.apple.com/documentation/metal/mtltexture/1515339-width 764 func (t Texture) Width() int { 765 return int(C.Texture_Width(t.texture)) 766 } 767 768 // Height is the height of the texture image for the base level mipmap, in pixels. 769 // 770 // Reference: https://developer.apple.com/documentation/metal/mtltexture/1515938-height 771 func (t Texture) Height() int { 772 return int(C.Texture_Height(t.texture)) 773 } 774 775 // Buffer is a memory allocation for storing unformatted data 776 // that is accessible to the GPU. 777 // 778 // Reference: https://developer.apple.com/documentation/metal/mtlbuffer. 779 type Buffer struct { 780 buffer unsafe.Pointer 781 } 782 783 func (b Buffer) CopyToContents(data unsafe.Pointer, lengthInBytes uintptr) { 784 C.Buffer_CopyToContents(b.buffer, data, C.size_t(lengthInBytes)) 785 } 786 787 func (b Buffer) Retain() { 788 C.Buffer_Retain(b.buffer) 789 } 790 791 func (b Buffer) Release() { 792 C.Buffer_Release(b.buffer) 793 } 794 795 func (b Buffer) Native() unsafe.Pointer { 796 return b.buffer 797 } 798 799 // Function represents a programmable graphics or compute function executed by the GPU. 800 // 801 // Reference: https://developer.apple.com/documentation/metal/mtlfunction. 802 type Function struct { 803 function unsafe.Pointer 804 } 805 806 func (f Function) Release() { 807 C.Function_Release(f.function) 808 } 809 810 // RenderPipelineState contains the graphics functions 811 // and configuration state used in a render pass. 812 // 813 // Reference: https://developer.apple.com/documentation/metal/mtlrenderpipelinestate. 814 type RenderPipelineState struct { 815 renderPipelineState unsafe.Pointer 816 } 817 818 func (r RenderPipelineState) Release() { 819 C.RenderPipelineState_Release(r.renderPipelineState) 820 } 821 822 // Region is a rectangular block of pixels in an image or texture, 823 // defined by its upper-left corner and its size. 824 // 825 // Reference: https://developer.apple.com/documentation/metal/mtlregion. 826 type Region struct { 827 Origin Origin // The location of the upper-left corner of the block. 828 Size Size // The size of the block. 829 } 830 831 func (r *Region) c() C.struct_Region { 832 return C.struct_Region{ 833 Origin: r.Origin.c(), 834 Size: r.Size.c(), 835 } 836 } 837 838 // Origin represents the location of a pixel in an image or texture relative 839 // to the upper-left corner, whose coordinates are (0, 0). 840 // 841 // Reference: https://developer.apple.com/documentation/metal/mtlorigin. 842 type Origin struct{ X, Y, Z int } 843 844 func (o *Origin) c() C.struct_Origin { 845 return C.struct_Origin{ 846 X: C.uint_t(o.X), 847 Y: C.uint_t(o.Y), 848 Z: C.uint_t(o.Z), 849 } 850 } 851 852 // Size represents the set of dimensions that declare the size of an object, 853 // such as an image, texture, threadgroup, or grid. 854 // 855 // Reference: https://developer.apple.com/documentation/metal/mtlsize. 856 type Size struct{ Width, Height, Depth int } 857 858 func (s *Size) c() C.struct_Size { 859 return C.struct_Size{ 860 Width: C.uint_t(s.Width), 861 Height: C.uint_t(s.Height), 862 Depth: C.uint_t(s.Depth), 863 } 864 } 865 866 // RegionMake2D returns a 2D, rectangular region for image or texture data. 867 // 868 // Reference: https://developer.apple.com/documentation/metal/1515675-mtlregionmake2d. 869 func RegionMake2D(x, y, width, height int) Region { 870 return Region{ 871 Origin: Origin{x, y, 0}, 872 Size: Size{width, height, 1}, 873 } 874 } 875 876 type Viewport struct { 877 OriginX float64 878 OriginY float64 879 Width float64 880 Height float64 881 ZNear float64 882 ZFar float64 883 } 884 885 func (v *Viewport) c() C.struct_Viewport { 886 return C.struct_Viewport{ 887 OriginX: C.double(v.OriginX), 888 OriginY: C.double(v.OriginY), 889 Width: C.double(v.Width), 890 Height: C.double(v.Height), 891 ZNear: C.double(v.ZNear), 892 ZFar: C.double(v.ZFar), 893 } 894 }