MTLCommandBuffer.hpp
1 //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 // 3 // Metal/MTLCommandBuffer.hpp 4 // 5 // Copyright 2020-2024 Apple Inc. 6 // 7 // Licensed under the Apache License, Version 2.0 (the "License"); 8 // you may not use this file except in compliance with the License. 9 // You may obtain a copy of the License at 10 // 11 // http://www.apache.org/licenses/LICENSE-2.0 12 // 13 // Unless required by applicable law or agreed to in writing, software 14 // distributed under the License is distributed on an "AS IS" BASIS, 15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 // See the License for the specific language governing permissions and 17 // limitations under the License. 18 // 19 //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 21 #pragma once 22 23 #include "MTLDefines.hpp" 24 #include "MTLHeaderBridge.hpp" 25 #include "MTLPrivate.hpp" 26 27 #include <Foundation/Foundation.hpp> 28 29 #include "MTLCommandBuffer.hpp" 30 #include <functional> 31 32 namespace MTL 33 { 34 _MTL_ENUM(NS::UInteger, CommandBufferStatus) { 35 CommandBufferStatusNotEnqueued = 0, 36 CommandBufferStatusEnqueued = 1, 37 CommandBufferStatusCommitted = 2, 38 CommandBufferStatusScheduled = 3, 39 CommandBufferStatusCompleted = 4, 40 CommandBufferStatusError = 5, 41 }; 42 43 _MTL_ENUM(NS::UInteger, CommandBufferError) { 44 CommandBufferErrorNone = 0, 45 CommandBufferErrorInternal = 1, 46 CommandBufferErrorTimeout = 2, 47 CommandBufferErrorPageFault = 3, 48 CommandBufferErrorBlacklisted = 4, 49 CommandBufferErrorAccessRevoked = 4, 50 CommandBufferErrorNotPermitted = 7, 51 CommandBufferErrorOutOfMemory = 8, 52 CommandBufferErrorInvalidResource = 9, 53 CommandBufferErrorMemoryless = 10, 54 CommandBufferErrorDeviceRemoved = 11, 55 CommandBufferErrorStackOverflow = 12, 56 }; 57 58 _MTL_OPTIONS(NS::UInteger, CommandBufferErrorOption) { 59 CommandBufferErrorOptionNone = 0, 60 CommandBufferErrorOptionEncoderExecutionStatus = 1, 61 }; 62 63 _MTL_ENUM(NS::Integer, CommandEncoderErrorState) { 64 CommandEncoderErrorStateUnknown = 0, 65 CommandEncoderErrorStateCompleted = 1, 66 CommandEncoderErrorStateAffected = 2, 67 CommandEncoderErrorStatePending = 3, 68 CommandEncoderErrorStateFaulted = 4, 69 }; 70 71 class CommandBufferDescriptor : public NS::Copying<CommandBufferDescriptor> 72 { 73 public: 74 static class CommandBufferDescriptor* alloc(); 75 76 class CommandBufferDescriptor* init(); 77 78 bool retainedReferences() const; 79 void setRetainedReferences(bool retainedReferences); 80 81 MTL::CommandBufferErrorOption errorOptions() const; 82 void setErrorOptions(MTL::CommandBufferErrorOption errorOptions); 83 84 class LogState* logState() const; 85 void setLogState(const class LogState* logState); 86 }; 87 88 class CommandBufferEncoderInfo : public NS::Referencing<CommandBufferEncoderInfo> 89 { 90 public: 91 NS::String* label() const; 92 93 NS::Array* debugSignposts() const; 94 95 MTL::CommandEncoderErrorState errorState() const; 96 }; 97 98 _MTL_ENUM(NS::UInteger, DispatchType) { 99 DispatchTypeSerial = 0, 100 DispatchTypeConcurrent = 1, 101 }; 102 103 class CommandBuffer; 104 105 using CommandBufferHandler = void (^)(CommandBuffer*); 106 107 using HandlerFunction = std::function<void(CommandBuffer*)>; 108 109 class CommandBuffer : public NS::Referencing<CommandBuffer> 110 { 111 public: 112 void addScheduledHandler(const HandlerFunction& function); 113 114 void addCompletedHandler(const HandlerFunction& function); 115 116 class Device* device() const; 117 118 class CommandQueue* commandQueue() const; 119 120 bool retainedReferences() const; 121 122 MTL::CommandBufferErrorOption errorOptions() const; 123 124 NS::String* label() const; 125 void setLabel(const NS::String* label); 126 127 CFTimeInterval kernelStartTime() const; 128 129 CFTimeInterval kernelEndTime() const; 130 131 class LogContainer* logs() const; 132 133 CFTimeInterval GPUStartTime() const; 134 135 CFTimeInterval GPUEndTime() const; 136 137 void enqueue(); 138 139 void commit(); 140 141 void addScheduledHandler(const MTL::CommandBufferHandler block); 142 143 void presentDrawable(const class Drawable* drawable); 144 145 void presentDrawableAtTime(const class Drawable* drawable, CFTimeInterval presentationTime); 146 147 void presentDrawableAfterMinimumDuration(const class Drawable* drawable, CFTimeInterval duration); 148 149 void waitUntilScheduled(); 150 151 void addCompletedHandler(const MTL::CommandBufferHandler block); 152 153 void waitUntilCompleted(); 154 155 MTL::CommandBufferStatus status() const; 156 157 NS::Error* error() const; 158 159 class BlitCommandEncoder* blitCommandEncoder(); 160 161 class RenderCommandEncoder* renderCommandEncoder(const class RenderPassDescriptor* renderPassDescriptor); 162 163 class ComputeCommandEncoder* computeCommandEncoder(const class ComputePassDescriptor* computePassDescriptor); 164 165 class BlitCommandEncoder* blitCommandEncoder(const class BlitPassDescriptor* blitPassDescriptor); 166 167 class ComputeCommandEncoder* computeCommandEncoder(); 168 169 class ComputeCommandEncoder* computeCommandEncoder(MTL::DispatchType dispatchType); 170 171 void encodeWait(const class Event* event, uint64_t value); 172 173 void encodeSignalEvent(const class Event* event, uint64_t value); 174 175 class ParallelRenderCommandEncoder* parallelRenderCommandEncoder(const class RenderPassDescriptor* renderPassDescriptor); 176 177 class ResourceStateCommandEncoder* resourceStateCommandEncoder(); 178 179 class ResourceStateCommandEncoder* resourceStateCommandEncoder(const class ResourceStatePassDescriptor* resourceStatePassDescriptor); 180 181 class AccelerationStructureCommandEncoder* accelerationStructureCommandEncoder(); 182 183 class AccelerationStructureCommandEncoder* accelerationStructureCommandEncoder(const class AccelerationStructurePassDescriptor* descriptor); 184 185 void pushDebugGroup(const NS::String* string); 186 187 void popDebugGroup(); 188 189 void useResidencySet(const class ResidencySet* residencySet); 190 191 void useResidencySets(const class ResidencySet* const residencySets[], NS::UInteger count); 192 }; 193 194 } 195 196 // static method: alloc 197 _MTL_INLINE MTL::CommandBufferDescriptor* MTL::CommandBufferDescriptor::alloc() 198 { 199 return NS::Object::alloc<MTL::CommandBufferDescriptor>(_MTL_PRIVATE_CLS(MTLCommandBufferDescriptor)); 200 } 201 202 // method: init 203 _MTL_INLINE MTL::CommandBufferDescriptor* MTL::CommandBufferDescriptor::init() 204 { 205 return NS::Object::init<MTL::CommandBufferDescriptor>(); 206 } 207 208 // property: retainedReferences 209 _MTL_INLINE bool MTL::CommandBufferDescriptor::retainedReferences() const 210 { 211 return Object::sendMessage<bool>(this, _MTL_PRIVATE_SEL(retainedReferences)); 212 } 213 214 _MTL_INLINE void MTL::CommandBufferDescriptor::setRetainedReferences(bool retainedReferences) 215 { 216 Object::sendMessage<void>(this, _MTL_PRIVATE_SEL(setRetainedReferences_), retainedReferences); 217 } 218 219 // property: errorOptions 220 _MTL_INLINE MTL::CommandBufferErrorOption MTL::CommandBufferDescriptor::errorOptions() const 221 { 222 return Object::sendMessage<MTL::CommandBufferErrorOption>(this, _MTL_PRIVATE_SEL(errorOptions)); 223 } 224 225 _MTL_INLINE void MTL::CommandBufferDescriptor::setErrorOptions(MTL::CommandBufferErrorOption errorOptions) 226 { 227 Object::sendMessage<void>(this, _MTL_PRIVATE_SEL(setErrorOptions_), errorOptions); 228 } 229 230 // property: logState 231 _MTL_INLINE MTL::LogState* MTL::CommandBufferDescriptor::logState() const 232 { 233 return Object::sendMessage<MTL::LogState*>(this, _MTL_PRIVATE_SEL(logState)); 234 } 235 236 _MTL_INLINE void MTL::CommandBufferDescriptor::setLogState(const MTL::LogState* logState) 237 { 238 Object::sendMessage<void>(this, _MTL_PRIVATE_SEL(setLogState_), logState); 239 } 240 241 // property: label 242 _MTL_INLINE NS::String* MTL::CommandBufferEncoderInfo::label() const 243 { 244 return Object::sendMessage<NS::String*>(this, _MTL_PRIVATE_SEL(label)); 245 } 246 247 // property: debugSignposts 248 _MTL_INLINE NS::Array* MTL::CommandBufferEncoderInfo::debugSignposts() const 249 { 250 return Object::sendMessage<NS::Array*>(this, _MTL_PRIVATE_SEL(debugSignposts)); 251 } 252 253 // property: errorState 254 _MTL_INLINE MTL::CommandEncoderErrorState MTL::CommandBufferEncoderInfo::errorState() const 255 { 256 return Object::sendMessage<MTL::CommandEncoderErrorState>(this, _MTL_PRIVATE_SEL(errorState)); 257 } 258 259 _MTL_INLINE void MTL::CommandBuffer::addScheduledHandler(const HandlerFunction& function) 260 { 261 __block HandlerFunction blockFunction = function; 262 263 addScheduledHandler(^(MTL::CommandBuffer* pCommandBuffer) { blockFunction(pCommandBuffer); }); 264 } 265 266 _MTL_INLINE void MTL::CommandBuffer::addCompletedHandler(const HandlerFunction& function) 267 { 268 __block HandlerFunction blockFunction = function; 269 270 addCompletedHandler(^(MTL::CommandBuffer* pCommandBuffer) { blockFunction(pCommandBuffer); }); 271 } 272 273 // property: device 274 _MTL_INLINE MTL::Device* MTL::CommandBuffer::device() const 275 { 276 return Object::sendMessage<MTL::Device*>(this, _MTL_PRIVATE_SEL(device)); 277 } 278 279 // property: commandQueue 280 _MTL_INLINE MTL::CommandQueue* MTL::CommandBuffer::commandQueue() const 281 { 282 return Object::sendMessage<MTL::CommandQueue*>(this, _MTL_PRIVATE_SEL(commandQueue)); 283 } 284 285 // property: retainedReferences 286 _MTL_INLINE bool MTL::CommandBuffer::retainedReferences() const 287 { 288 return Object::sendMessage<bool>(this, _MTL_PRIVATE_SEL(retainedReferences)); 289 } 290 291 // property: errorOptions 292 _MTL_INLINE MTL::CommandBufferErrorOption MTL::CommandBuffer::errorOptions() const 293 { 294 return Object::sendMessage<MTL::CommandBufferErrorOption>(this, _MTL_PRIVATE_SEL(errorOptions)); 295 } 296 297 // property: label 298 _MTL_INLINE NS::String* MTL::CommandBuffer::label() const 299 { 300 return Object::sendMessage<NS::String*>(this, _MTL_PRIVATE_SEL(label)); 301 } 302 303 _MTL_INLINE void MTL::CommandBuffer::setLabel(const NS::String* label) 304 { 305 Object::sendMessage<void>(this, _MTL_PRIVATE_SEL(setLabel_), label); 306 } 307 308 // property: kernelStartTime 309 _MTL_INLINE CFTimeInterval MTL::CommandBuffer::kernelStartTime() const 310 { 311 return Object::sendMessage<CFTimeInterval>(this, _MTL_PRIVATE_SEL(kernelStartTime)); 312 } 313 314 // property: kernelEndTime 315 _MTL_INLINE CFTimeInterval MTL::CommandBuffer::kernelEndTime() const 316 { 317 return Object::sendMessage<CFTimeInterval>(this, _MTL_PRIVATE_SEL(kernelEndTime)); 318 } 319 320 // property: logs 321 _MTL_INLINE MTL::LogContainer* MTL::CommandBuffer::logs() const 322 { 323 return Object::sendMessage<MTL::LogContainer*>(this, _MTL_PRIVATE_SEL(logs)); 324 } 325 326 // property: GPUStartTime 327 _MTL_INLINE CFTimeInterval MTL::CommandBuffer::GPUStartTime() const 328 { 329 return Object::sendMessage<CFTimeInterval>(this, _MTL_PRIVATE_SEL(GPUStartTime)); 330 } 331 332 // property: GPUEndTime 333 _MTL_INLINE CFTimeInterval MTL::CommandBuffer::GPUEndTime() const 334 { 335 return Object::sendMessage<CFTimeInterval>(this, _MTL_PRIVATE_SEL(GPUEndTime)); 336 } 337 338 // method: enqueue 339 _MTL_INLINE void MTL::CommandBuffer::enqueue() 340 { 341 Object::sendMessage<void>(this, _MTL_PRIVATE_SEL(enqueue)); 342 } 343 344 // method: commit 345 _MTL_INLINE void MTL::CommandBuffer::commit() 346 { 347 Object::sendMessage<void>(this, _MTL_PRIVATE_SEL(commit)); 348 } 349 350 // method: addScheduledHandler: 351 _MTL_INLINE void MTL::CommandBuffer::addScheduledHandler(const MTL::CommandBufferHandler block) 352 { 353 Object::sendMessage<void>(this, _MTL_PRIVATE_SEL(addScheduledHandler_), block); 354 } 355 356 // method: presentDrawable: 357 _MTL_INLINE void MTL::CommandBuffer::presentDrawable(const MTL::Drawable* drawable) 358 { 359 Object::sendMessage<void>(this, _MTL_PRIVATE_SEL(presentDrawable_), drawable); 360 } 361 362 // method: presentDrawable:atTime: 363 _MTL_INLINE void MTL::CommandBuffer::presentDrawableAtTime(const MTL::Drawable* drawable, CFTimeInterval presentationTime) 364 { 365 Object::sendMessage<void>(this, _MTL_PRIVATE_SEL(presentDrawable_atTime_), drawable, presentationTime); 366 } 367 368 // method: presentDrawable:afterMinimumDuration: 369 _MTL_INLINE void MTL::CommandBuffer::presentDrawableAfterMinimumDuration(const MTL::Drawable* drawable, CFTimeInterval duration) 370 { 371 Object::sendMessage<void>(this, _MTL_PRIVATE_SEL(presentDrawable_afterMinimumDuration_), drawable, duration); 372 } 373 374 // method: waitUntilScheduled 375 _MTL_INLINE void MTL::CommandBuffer::waitUntilScheduled() 376 { 377 Object::sendMessage<void>(this, _MTL_PRIVATE_SEL(waitUntilScheduled)); 378 } 379 380 // method: addCompletedHandler: 381 _MTL_INLINE void MTL::CommandBuffer::addCompletedHandler(const MTL::CommandBufferHandler block) 382 { 383 Object::sendMessage<void>(this, _MTL_PRIVATE_SEL(addCompletedHandler_), block); 384 } 385 386 // method: waitUntilCompleted 387 _MTL_INLINE void MTL::CommandBuffer::waitUntilCompleted() 388 { 389 Object::sendMessage<void>(this, _MTL_PRIVATE_SEL(waitUntilCompleted)); 390 } 391 392 // property: status 393 _MTL_INLINE MTL::CommandBufferStatus MTL::CommandBuffer::status() const 394 { 395 return Object::sendMessage<MTL::CommandBufferStatus>(this, _MTL_PRIVATE_SEL(status)); 396 } 397 398 // property: error 399 _MTL_INLINE NS::Error* MTL::CommandBuffer::error() const 400 { 401 return Object::sendMessage<NS::Error*>(this, _MTL_PRIVATE_SEL(error)); 402 } 403 404 // method: blitCommandEncoder 405 _MTL_INLINE MTL::BlitCommandEncoder* MTL::CommandBuffer::blitCommandEncoder() 406 { 407 return Object::sendMessage<MTL::BlitCommandEncoder*>(this, _MTL_PRIVATE_SEL(blitCommandEncoder)); 408 } 409 410 // method: renderCommandEncoderWithDescriptor: 411 _MTL_INLINE MTL::RenderCommandEncoder* MTL::CommandBuffer::renderCommandEncoder(const MTL::RenderPassDescriptor* renderPassDescriptor) 412 { 413 return Object::sendMessage<MTL::RenderCommandEncoder*>(this, _MTL_PRIVATE_SEL(renderCommandEncoderWithDescriptor_), renderPassDescriptor); 414 } 415 416 // method: computeCommandEncoderWithDescriptor: 417 _MTL_INLINE MTL::ComputeCommandEncoder* MTL::CommandBuffer::computeCommandEncoder(const MTL::ComputePassDescriptor* computePassDescriptor) 418 { 419 return Object::sendMessage<MTL::ComputeCommandEncoder*>(this, _MTL_PRIVATE_SEL(computeCommandEncoderWithDescriptor_), computePassDescriptor); 420 } 421 422 // method: blitCommandEncoderWithDescriptor: 423 _MTL_INLINE MTL::BlitCommandEncoder* MTL::CommandBuffer::blitCommandEncoder(const MTL::BlitPassDescriptor* blitPassDescriptor) 424 { 425 return Object::sendMessage<MTL::BlitCommandEncoder*>(this, _MTL_PRIVATE_SEL(blitCommandEncoderWithDescriptor_), blitPassDescriptor); 426 } 427 428 // method: computeCommandEncoder 429 _MTL_INLINE MTL::ComputeCommandEncoder* MTL::CommandBuffer::computeCommandEncoder() 430 { 431 return Object::sendMessage<MTL::ComputeCommandEncoder*>(this, _MTL_PRIVATE_SEL(computeCommandEncoder)); 432 } 433 434 // method: computeCommandEncoderWithDispatchType: 435 _MTL_INLINE MTL::ComputeCommandEncoder* MTL::CommandBuffer::computeCommandEncoder(MTL::DispatchType dispatchType) 436 { 437 return Object::sendMessage<MTL::ComputeCommandEncoder*>(this, _MTL_PRIVATE_SEL(computeCommandEncoderWithDispatchType_), dispatchType); 438 } 439 440 // method: encodeWaitForEvent:value: 441 _MTL_INLINE void MTL::CommandBuffer::encodeWait(const MTL::Event* event, uint64_t value) 442 { 443 Object::sendMessage<void>(this, _MTL_PRIVATE_SEL(encodeWaitForEvent_value_), event, value); 444 } 445 446 // method: encodeSignalEvent:value: 447 _MTL_INLINE void MTL::CommandBuffer::encodeSignalEvent(const MTL::Event* event, uint64_t value) 448 { 449 Object::sendMessage<void>(this, _MTL_PRIVATE_SEL(encodeSignalEvent_value_), event, value); 450 } 451 452 // method: parallelRenderCommandEncoderWithDescriptor: 453 _MTL_INLINE MTL::ParallelRenderCommandEncoder* MTL::CommandBuffer::parallelRenderCommandEncoder(const MTL::RenderPassDescriptor* renderPassDescriptor) 454 { 455 return Object::sendMessage<MTL::ParallelRenderCommandEncoder*>(this, _MTL_PRIVATE_SEL(parallelRenderCommandEncoderWithDescriptor_), renderPassDescriptor); 456 } 457 458 // method: resourceStateCommandEncoder 459 _MTL_INLINE MTL::ResourceStateCommandEncoder* MTL::CommandBuffer::resourceStateCommandEncoder() 460 { 461 return Object::sendMessage<MTL::ResourceStateCommandEncoder*>(this, _MTL_PRIVATE_SEL(resourceStateCommandEncoder)); 462 } 463 464 // method: resourceStateCommandEncoderWithDescriptor: 465 _MTL_INLINE MTL::ResourceStateCommandEncoder* MTL::CommandBuffer::resourceStateCommandEncoder(const MTL::ResourceStatePassDescriptor* resourceStatePassDescriptor) 466 { 467 return Object::sendMessage<MTL::ResourceStateCommandEncoder*>(this, _MTL_PRIVATE_SEL(resourceStateCommandEncoderWithDescriptor_), resourceStatePassDescriptor); 468 } 469 470 // method: accelerationStructureCommandEncoder 471 _MTL_INLINE MTL::AccelerationStructureCommandEncoder* MTL::CommandBuffer::accelerationStructureCommandEncoder() 472 { 473 return Object::sendMessage<MTL::AccelerationStructureCommandEncoder*>(this, _MTL_PRIVATE_SEL(accelerationStructureCommandEncoder)); 474 } 475 476 // method: accelerationStructureCommandEncoderWithDescriptor: 477 _MTL_INLINE MTL::AccelerationStructureCommandEncoder* MTL::CommandBuffer::accelerationStructureCommandEncoder(const MTL::AccelerationStructurePassDescriptor* descriptor) 478 { 479 return Object::sendMessage<MTL::AccelerationStructureCommandEncoder*>(this, _MTL_PRIVATE_SEL(accelerationStructureCommandEncoderWithDescriptor_), descriptor); 480 } 481 482 // method: pushDebugGroup: 483 _MTL_INLINE void MTL::CommandBuffer::pushDebugGroup(const NS::String* string) 484 { 485 Object::sendMessage<void>(this, _MTL_PRIVATE_SEL(pushDebugGroup_), string); 486 } 487 488 // method: popDebugGroup 489 _MTL_INLINE void MTL::CommandBuffer::popDebugGroup() 490 { 491 Object::sendMessage<void>(this, _MTL_PRIVATE_SEL(popDebugGroup)); 492 } 493 494 // method: useResidencySet: 495 _MTL_INLINE void MTL::CommandBuffer::useResidencySet(const MTL::ResidencySet* residencySet) 496 { 497 Object::sendMessage<void>(this, _MTL_PRIVATE_SEL(useResidencySet_), residencySet); 498 } 499 500 // method: useResidencySets:count: 501 _MTL_INLINE void MTL::CommandBuffer::useResidencySets(const MTL::ResidencySet* const residencySets[], NS::UInteger count) 502 { 503 Object::sendMessage<void>(this, _MTL_PRIVATE_SEL(useResidencySets_count_), residencySets, count); 504 }