1 // 2 // Copyright 2019 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 // mtl_command_buffer.h: 7 // Defines the wrapper classes for Metal's MTLCommandEncoder, MTLCommandQueue and 8 // MTLCommandBuffer. 9 // 10 11 #ifndef LIBANGLE_RENDERER_METAL_COMMANDENBUFFERMTL_H_ 12 #define LIBANGLE_RENDERER_METAL_COMMANDENBUFFERMTL_H_ 13 14 #import <Metal/Metal.h> 15 #import <QuartzCore/CAMetalLayer.h> 16 #include <cstdint> 17 18 #include <deque> 19 #include <memory> 20 #include <mutex> 21 #include <thread> 22 #include <unordered_set> 23 #include <vector> 24 25 #include "common/FixedVector.h" 26 #include "common/angleutils.h" 27 #include "libANGLE/renderer/metal/mtl_common.h" 28 #include "libANGLE/renderer/metal/mtl_resources.h" 29 #include "libANGLE/renderer/metal/mtl_state_cache.h" 30 31 namespace rx 32 { 33 namespace mtl 34 { 35 36 enum CommandBufferFinishOperation 37 { 38 NoWait, 39 WaitUntilScheduled, 40 WaitUntilFinished 41 }; 42 43 class CommandBuffer; 44 class CommandEncoder; 45 class RenderCommandEncoder; 46 class OcclusionQueryPool; 47 48 class CommandQueue final : public WrappedObject<id<MTLCommandQueue>>, angle::NonCopyable 49 { 50 public: 51 void reset(); 52 void set(id<MTLCommandQueue> metalQueue); 53 54 void finishAllCommands(); 55 56 // This method will ensure that every GPU command buffer using this resource will finish before 57 // returning. Note: this doesn't include the "in-progress" command buffer, i.e. the one hasn't 58 // been commmitted yet. It's the responsibility of caller to make sure that command buffer is 59 // commited/flushed first before calling this method. 60 void ensureResourceReadyForCPU(const ResourceRef &resource); 61 void ensureResourceReadyForCPU(Resource *resource); 62 63 // Check whether the resource is being used by any command buffer still running on GPU. 64 // This must be called before attempting to read the content of resource on CPU side. isResourceBeingUsedByGPU(const ResourceRef & resource)65 bool isResourceBeingUsedByGPU(const ResourceRef &resource) const 66 { 67 return isResourceBeingUsedByGPU(resource.get()); 68 } 69 bool isResourceBeingUsedByGPU(const Resource *resource) const; 70 71 // Checks whether the last command buffer that uses the given resource has been committed or not 72 bool resourceHasPendingWorks(const Resource *resource) const; 73 74 CommandQueue &operator=(id<MTLCommandQueue> metalQueue) 75 { 76 set(metalQueue); 77 return *this; 78 } 79 80 AutoObjCPtr<id<MTLCommandBuffer>> makeMetalCommandBuffer(uint64_t *queueSerialOut); 81 void onCommandBufferCommitted(id<MTLCommandBuffer> buf, uint64_t serial); 82 83 private: 84 void onCommandBufferCompleted(id<MTLCommandBuffer> buf, uint64_t serial); 85 using ParentClass = WrappedObject<id<MTLCommandQueue>>; 86 87 struct CmdBufferQueueEntry 88 { 89 AutoObjCPtr<id<MTLCommandBuffer>> buffer; 90 uint64_t serial; 91 }; 92 std::deque<CmdBufferQueueEntry> mMetalCmdBuffers; 93 94 uint64_t mQueueSerialCounter = 1; 95 uint64_t mLastCommittedSerial = 0; 96 std::atomic<uint64_t> mCommittedBufferSerial{0}; 97 std::atomic<uint64_t> mCompletedBufferSerial{0}; 98 99 mutable std::mutex mLock; 100 }; 101 102 class CommandBuffer final : public WrappedObject<id<MTLCommandBuffer>>, angle::NonCopyable 103 { 104 public: 105 CommandBuffer(CommandQueue *cmdQueue); 106 ~CommandBuffer(); 107 108 // This method must be called so that command encoder can be used. 109 void restart(); 110 111 // Return true if command buffer can be encoded into. Return false if it has been committed 112 // and hasn't been restarted. 113 bool ready() const; 114 void commit(CommandBufferFinishOperation operation); 115 116 void present(id<CAMetalDrawable> presentationDrawable); 117 118 void setWriteDependency(const ResourceRef &resource); 119 void setReadDependency(const ResourceRef &resource); 120 void setReadDependency(Resource *resourcePtr); 121 122 void queueEventSignal(const mtl::SharedEventRef &event, uint64_t value); 123 void serverWaitEvent(const mtl::SharedEventRef &event, uint64_t value); 124 125 void insertDebugSign(const std::string &marker); 126 void pushDebugGroup(const std::string &marker); 127 void popDebugGroup(); 128 cmdQueue()129 CommandQueue &cmdQueue() { return mCmdQueue; } 130 131 // Private use only 132 void setActiveCommandEncoder(CommandEncoder *encoder); 133 void invalidateActiveCommandEncoder(CommandEncoder *encoder); 134 135 bool needsFlushForDrawCallLimits() const; 136 137 private: 138 void set(id<MTLCommandBuffer> metalBuffer); 139 void cleanup(); 140 141 bool readyImpl() const; 142 bool commitImpl(); 143 void forceEndingCurrentEncoder(); 144 145 void setPendingEvents(); 146 void setEventImpl(const mtl::SharedEventRef &event, uint64_t value); 147 void waitEventImpl(const mtl::SharedEventRef &event, uint64_t value); 148 149 void pushDebugGroupImpl(const std::string &marker); 150 void popDebugGroupImpl(); 151 152 void setResourceUsedByCommandBuffer(const ResourceRef &resource); 153 void clearResourceListAndSize(); 154 155 using ParentClass = WrappedObject<id<MTLCommandBuffer>>; 156 157 CommandQueue &mCmdQueue; 158 159 CommandEncoder *mActiveCommandEncoder = nullptr; 160 161 uint64_t mQueueSerial = 0; 162 163 mutable std::mutex mLock; 164 165 std::vector<std::string> mPendingDebugSigns; 166 std::vector<std::pair<mtl::SharedEventRef, uint64_t>> mPendingSignalEvents; 167 std::vector<std::string> mDebugGroups; 168 169 std::unordered_set<id> mResourceList; 170 size_t mWorkingResourceSize = 0; 171 bool mCommitted = false; 172 }; 173 174 class CommandEncoder : public WrappedObject<id<MTLCommandEncoder>>, angle::NonCopyable 175 { 176 public: 177 enum Type 178 { 179 RENDER, 180 BLIT, 181 COMPUTE, 182 }; 183 184 virtual ~CommandEncoder(); 185 186 virtual void endEncoding(); 187 188 virtual void reset(); getType()189 Type getType() const { return mType; } 190 191 CommandEncoder &markResourceBeingWrittenByGPU(const BufferRef &buffer); 192 CommandEncoder &markResourceBeingWrittenByGPU(const TextureRef &texture); 193 194 void insertDebugSign(NSString *label); 195 196 virtual void pushDebugGroup(NSString *label); 197 virtual void popDebugGroup(); 198 199 protected: 200 using ParentClass = WrappedObject<id<MTLCommandEncoder>>; 201 202 CommandEncoder(CommandBuffer *cmdBuffer, Type type); 203 cmdBuffer()204 CommandBuffer &cmdBuffer() { return mCmdBuffer; } cmdQueue()205 CommandQueue &cmdQueue() { return mCmdBuffer.cmdQueue(); } 206 207 void set(id<MTLCommandEncoder> metalCmdEncoder); 208 209 virtual void insertDebugSignImpl(NSString *marker); 210 211 private: 212 const Type mType; 213 CommandBuffer &mCmdBuffer; 214 }; 215 216 // Stream to store commands before encoding them into the real MTLCommandEncoder 217 class IntermediateCommandStream 218 { 219 public: 220 template <typename T> push(const T & val)221 inline IntermediateCommandStream &push(const T &val) 222 { 223 auto ptr = reinterpret_cast<const uint8_t *>(&val); 224 mBuffer.insert(mBuffer.end(), ptr, ptr + sizeof(T)); 225 return *this; 226 } 227 push(const uint8_t * bytes,size_t len)228 inline IntermediateCommandStream &push(const uint8_t *bytes, size_t len) 229 { 230 mBuffer.insert(mBuffer.end(), bytes, bytes + len); 231 return *this; 232 } 233 234 template <typename T> peek()235 inline T peek() 236 { 237 ASSERT(mReadPtr <= mBuffer.size() - sizeof(T)); 238 T re; 239 auto ptr = reinterpret_cast<uint8_t *>(&re); 240 std::copy(mBuffer.data() + mReadPtr, mBuffer.data() + mReadPtr + sizeof(T), ptr); 241 return re; 242 } 243 244 template <typename T> fetch()245 inline T fetch() 246 { 247 auto re = peek<T>(); 248 mReadPtr += sizeof(T); 249 return re; 250 } 251 fetch(size_t bytes)252 inline const uint8_t *fetch(size_t bytes) 253 { 254 ASSERT(mReadPtr <= mBuffer.size() - bytes); 255 auto cur = mReadPtr; 256 mReadPtr += bytes; 257 return mBuffer.data() + cur; 258 } 259 clear()260 inline void clear() 261 { 262 mBuffer.clear(); 263 mReadPtr = 0; 264 } 265 resetReadPtr(size_t readPtr)266 inline void resetReadPtr(size_t readPtr) 267 { 268 ASSERT(readPtr <= mBuffer.size()); 269 mReadPtr = readPtr; 270 } 271 good()272 inline bool good() const { return mReadPtr < mBuffer.size(); } 273 274 private: 275 std::vector<uint8_t> mBuffer; 276 size_t mReadPtr = 0; 277 }; 278 279 // Per shader stage's states 280 struct RenderCommandEncoderShaderStates 281 { 282 RenderCommandEncoderShaderStates(); 283 284 void reset(); 285 286 std::array<id<MTLBuffer>, kMaxShaderBuffers> buffers; 287 std::array<uint32_t, kMaxShaderBuffers> bufferOffsets; 288 std::array<id<MTLSamplerState>, kMaxShaderSamplers> samplers; 289 std::array<Optional<std::pair<float, float>>, kMaxShaderSamplers> samplerLodClamps; 290 std::array<id<MTLTexture>, kMaxShaderSamplers> textures; 291 }; 292 293 // Per render pass's states 294 struct RenderCommandEncoderStates 295 { 296 RenderCommandEncoderStates(); 297 298 void reset(); 299 300 id<MTLRenderPipelineState> renderPipeline; 301 302 MTLTriangleFillMode triangleFillMode; 303 MTLWinding winding; 304 MTLCullMode cullMode; 305 306 id<MTLDepthStencilState> depthStencilState; 307 float depthBias, depthSlopeScale, depthClamp; 308 309 uint32_t stencilFrontRef, stencilBackRef; 310 311 Optional<MTLViewport> viewport; 312 Optional<MTLScissorRect> scissorRect; 313 314 std::array<float, 4> blendColor; 315 316 gl::ShaderMap<RenderCommandEncoderShaderStates> perShaderStates; 317 318 MTLVisibilityResultMode visibilityResultMode; 319 size_t visibilityResultBufferOffset; 320 }; 321 322 // Encoder for encoding render commands 323 class RenderCommandEncoder final : public CommandEncoder 324 { 325 public: 326 RenderCommandEncoder(CommandBuffer *cmdBuffer, const OcclusionQueryPool &queryPool); 327 ~RenderCommandEncoder() override; 328 329 // override CommandEncoder valid()330 bool valid() const { return mRecording; } 331 void reset() override; 332 void endEncoding() override; 333 334 // Restart the encoder so that new commands can be encoded. 335 // NOTE: parent CommandBuffer's restart() must be called before this. 336 RenderCommandEncoder &restart(const RenderPassDesc &desc); 337 338 RenderCommandEncoder &setRenderPipelineState(id<MTLRenderPipelineState> state); 339 RenderCommandEncoder &setTriangleFillMode(MTLTriangleFillMode mode); 340 RenderCommandEncoder &setFrontFacingWinding(MTLWinding winding); 341 RenderCommandEncoder &setCullMode(MTLCullMode mode); 342 343 RenderCommandEncoder &setDepthStencilState(id<MTLDepthStencilState> state); 344 RenderCommandEncoder &setDepthBias(float depthBias, float slopeScale, float clamp); 345 RenderCommandEncoder &setStencilRefVals(uint32_t frontRef, uint32_t backRef); 346 RenderCommandEncoder &setStencilRefVal(uint32_t ref); 347 348 RenderCommandEncoder &setViewport(const MTLViewport &viewport); 349 RenderCommandEncoder &setScissorRect(const MTLScissorRect &rect); 350 351 RenderCommandEncoder &setBlendColor(float r, float g, float b, float a); 352 setVertexBuffer(const BufferRef & buffer,uint32_t offset,uint32_t index)353 RenderCommandEncoder &setVertexBuffer(const BufferRef &buffer, uint32_t offset, uint32_t index) 354 { 355 return setBuffer(gl::ShaderType::Vertex, buffer, offset, index); 356 } setVertexBytes(const uint8_t * bytes,size_t size,uint32_t index)357 RenderCommandEncoder &setVertexBytes(const uint8_t *bytes, size_t size, uint32_t index) 358 { 359 return setBytes(gl::ShaderType::Vertex, bytes, size, index); 360 } 361 template <typename T> setVertexData(const T & data,uint32_t index)362 RenderCommandEncoder &setVertexData(const T &data, uint32_t index) 363 { 364 return setVertexBytes(reinterpret_cast<const uint8_t *>(&data), sizeof(T), index); 365 } setVertexSamplerState(id<MTLSamplerState> state,float lodMinClamp,float lodMaxClamp,uint32_t index)366 RenderCommandEncoder &setVertexSamplerState(id<MTLSamplerState> state, 367 float lodMinClamp, 368 float lodMaxClamp, 369 uint32_t index) 370 { 371 return setSamplerState(gl::ShaderType::Vertex, state, lodMinClamp, lodMaxClamp, index); 372 } setVertexTexture(const TextureRef & texture,uint32_t index)373 RenderCommandEncoder &setVertexTexture(const TextureRef &texture, uint32_t index) 374 { 375 return setTexture(gl::ShaderType::Vertex, texture, index); 376 } 377 setFragmentBuffer(const BufferRef & buffer,uint32_t offset,uint32_t index)378 RenderCommandEncoder &setFragmentBuffer(const BufferRef &buffer, 379 uint32_t offset, 380 uint32_t index) 381 { 382 return setBuffer(gl::ShaderType::Fragment, buffer, offset, index); 383 } setFragmentBytes(const uint8_t * bytes,size_t size,uint32_t index)384 RenderCommandEncoder &setFragmentBytes(const uint8_t *bytes, size_t size, uint32_t index) 385 { 386 return setBytes(gl::ShaderType::Fragment, bytes, size, index); 387 } 388 template <typename T> setFragmentData(const T & data,uint32_t index)389 RenderCommandEncoder &setFragmentData(const T &data, uint32_t index) 390 { 391 return setFragmentBytes(reinterpret_cast<const uint8_t *>(&data), sizeof(T), index); 392 } setFragmentSamplerState(id<MTLSamplerState> state,float lodMinClamp,float lodMaxClamp,uint32_t index)393 RenderCommandEncoder &setFragmentSamplerState(id<MTLSamplerState> state, 394 float lodMinClamp, 395 float lodMaxClamp, 396 uint32_t index) 397 { 398 return setSamplerState(gl::ShaderType::Fragment, state, lodMinClamp, lodMaxClamp, index); 399 } setFragmentTexture(const TextureRef & texture,uint32_t index)400 RenderCommandEncoder &setFragmentTexture(const TextureRef &texture, uint32_t index) 401 { 402 return setTexture(gl::ShaderType::Fragment, texture, index); 403 } 404 405 RenderCommandEncoder &setBuffer(gl::ShaderType shaderType, 406 const BufferRef &buffer, 407 uint32_t offset, 408 uint32_t index); 409 RenderCommandEncoder &setBufferForWrite(gl::ShaderType shaderType, 410 const BufferRef &buffer, 411 uint32_t offset, 412 uint32_t index); 413 RenderCommandEncoder &setBytes(gl::ShaderType shaderType, 414 const uint8_t *bytes, 415 size_t size, 416 uint32_t index); 417 template <typename T> setData(gl::ShaderType shaderType,const T & data,uint32_t index)418 RenderCommandEncoder &setData(gl::ShaderType shaderType, const T &data, uint32_t index) 419 { 420 return setBytes(shaderType, reinterpret_cast<const uint8_t *>(&data), sizeof(T), index); 421 } 422 RenderCommandEncoder &setSamplerState(gl::ShaderType shaderType, 423 id<MTLSamplerState> state, 424 float lodMinClamp, 425 float lodMaxClamp, 426 uint32_t index); 427 RenderCommandEncoder &setTexture(gl::ShaderType shaderType, 428 const TextureRef &texture, 429 uint32_t index); 430 431 RenderCommandEncoder &draw(MTLPrimitiveType primitiveType, 432 uint32_t vertexStart, 433 uint32_t vertexCount); 434 RenderCommandEncoder &drawInstanced(MTLPrimitiveType primitiveType, 435 uint32_t vertexStart, 436 uint32_t vertexCount, 437 uint32_t instances); 438 RenderCommandEncoder &drawInstancedBaseInstance(MTLPrimitiveType primitiveType, 439 uint32_t vertexStart, 440 uint32_t vertexCount, 441 uint32_t instances, 442 uint32_t baseInstance); 443 RenderCommandEncoder &drawIndexed(MTLPrimitiveType primitiveType, 444 uint32_t indexCount, 445 MTLIndexType indexType, 446 const BufferRef &indexBuffer, 447 size_t bufferOffset); 448 RenderCommandEncoder &drawIndexedInstanced(MTLPrimitiveType primitiveType, 449 uint32_t indexCount, 450 MTLIndexType indexType, 451 const BufferRef &indexBuffer, 452 size_t bufferOffset, 453 uint32_t instances); 454 RenderCommandEncoder &drawIndexedInstancedBaseVertexBaseInstance(MTLPrimitiveType primitiveType, 455 uint32_t indexCount, 456 MTLIndexType indexType, 457 const BufferRef &indexBuffer, 458 size_t bufferOffset, 459 uint32_t instances, 460 uint32_t baseVertex, 461 uint32_t baseInstance); 462 463 RenderCommandEncoder &setVisibilityResultMode(MTLVisibilityResultMode mode, size_t offset); 464 465 RenderCommandEncoder &useResource(const BufferRef &resource, 466 MTLResourceUsage usage, 467 mtl::RenderStages states); 468 469 RenderCommandEncoder &memoryBarrierWithResource(const BufferRef &resource, 470 mtl::RenderStages after, 471 mtl::RenderStages before); 472 473 RenderCommandEncoder &setColorStoreAction(MTLStoreAction action, uint32_t colorAttachmentIndex); 474 // Set store action for every color attachment. 475 RenderCommandEncoder &setColorStoreAction(MTLStoreAction action); 476 477 RenderCommandEncoder &setDepthStencilStoreAction(MTLStoreAction depthStoreAction, 478 MTLStoreAction stencilStoreAction); 479 RenderCommandEncoder &setDepthStoreAction(MTLStoreAction action); 480 RenderCommandEncoder &setStencilStoreAction(MTLStoreAction action); 481 482 // Set storeaction for every color & depth & stencil attachment. 483 RenderCommandEncoder &setStoreAction(MTLStoreAction action); 484 485 // Change the render pass's loadAction. Note that this operation is only allowed when there 486 // is no draw call recorded yet. 487 RenderCommandEncoder &setColorLoadAction(MTLLoadAction action, 488 const MTLClearColor &clearValue, 489 uint32_t colorAttachmentIndex); 490 RenderCommandEncoder &setDepthLoadAction(MTLLoadAction action, double clearValue); 491 RenderCommandEncoder &setStencilLoadAction(MTLLoadAction action, uint32_t clearValue); 492 493 void setLabel(NSString *label); 494 495 void pushDebugGroup(NSString *label) override; 496 void popDebugGroup() override; 497 renderPassDesc()498 const RenderPassDesc &renderPassDesc() const { return mRenderPassDesc; } hasDrawCalls()499 bool hasDrawCalls() const { return mHasDrawCalls; } 500 501 private: 502 // Override CommandEncoder get()503 id<MTLRenderCommandEncoder> get() 504 { 505 return static_cast<id<MTLRenderCommandEncoder>>(CommandEncoder::get()); 506 } 507 void insertDebugSignImpl(NSString *label) override; 508 509 void initAttachmentWriteDependencyAndScissorRect(const RenderPassAttachmentDesc &attachment); 510 void initWriteDependency(const TextureRef &texture); 511 512 void finalizeLoadStoreAction(MTLRenderPassAttachmentDescriptor *objCRenderPassAttachment); 513 514 void encodeMetalEncoder(); 515 void simulateDiscardFramebuffer(); 516 void endEncodingImpl(bool considerDiscardSimulation); 517 518 RenderCommandEncoder &commonSetBuffer(gl::ShaderType shaderType, 519 id<MTLBuffer> mtlBuffer, 520 uint32_t offset, 521 uint32_t index); 522 523 RenderPassDesc mRenderPassDesc; 524 // Cached Objective-C render pass desc to avoid re-allocate every frame. 525 mtl::AutoObjCObj<MTLRenderPassDescriptor> mCachedRenderPassDescObjC; 526 527 mtl::AutoObjCObj<NSString> mLabel; 528 529 MTLScissorRect mRenderPassMaxScissorRect; 530 531 const OcclusionQueryPool &mOcclusionQueryPool; 532 bool mRecording = false; 533 bool mHasDrawCalls = false; 534 IntermediateCommandStream mCommands; 535 536 gl::ShaderMap<uint8_t> mSetBufferCmds; 537 gl::ShaderMap<uint8_t> mSetBufferOffsetCmds; 538 gl::ShaderMap<uint8_t> mSetBytesCmds; 539 gl::ShaderMap<uint8_t> mSetTextureCmds; 540 gl::ShaderMap<uint8_t> mSetSamplerCmds; 541 542 RenderCommandEncoderStates mStateCache = {}; 543 544 bool mPipelineStateSet = false; 545 }; 546 547 class BlitCommandEncoder final : public CommandEncoder 548 { 549 public: 550 BlitCommandEncoder(CommandBuffer *cmdBuffer); 551 ~BlitCommandEncoder() override; 552 553 // Restart the encoder so that new commands can be encoded. 554 // NOTE: parent CommandBuffer's restart() must be called before this. 555 BlitCommandEncoder &restart(); 556 557 BlitCommandEncoder ©Buffer(const BufferRef &src, 558 size_t srcOffset, 559 const BufferRef &dst, 560 size_t dstOffset, 561 size_t size); 562 563 BlitCommandEncoder ©BufferToTexture(const BufferRef &src, 564 size_t srcOffset, 565 size_t srcBytesPerRow, 566 size_t srcBytesPerImage, 567 MTLSize srcSize, 568 const TextureRef &dst, 569 uint32_t dstSlice, 570 MipmapNativeLevel dstLevel, 571 MTLOrigin dstOrigin, 572 MTLBlitOption blitOption); 573 574 BlitCommandEncoder ©TextureToBuffer(const TextureRef &src, 575 uint32_t srcSlice, 576 MipmapNativeLevel srcLevel, 577 MTLOrigin srcOrigin, 578 MTLSize srcSize, 579 const BufferRef &dst, 580 size_t dstOffset, 581 size_t dstBytesPerRow, 582 size_t dstBytesPerImage, 583 MTLBlitOption blitOption); 584 585 BlitCommandEncoder ©Texture(const TextureRef &src, 586 uint32_t srcSlice, 587 MipmapNativeLevel srcLevel, 588 const TextureRef &dst, 589 uint32_t dstSlice, 590 MipmapNativeLevel dstLevel, 591 uint32_t sliceCount, 592 uint32_t levelCount); 593 594 BlitCommandEncoder &fillBuffer(const BufferRef &buffer, NSRange range, uint8_t value); 595 596 BlitCommandEncoder &generateMipmapsForTexture(const TextureRef &texture); 597 BlitCommandEncoder &synchronizeResource(Buffer *bufferPtr); 598 BlitCommandEncoder &synchronizeResource(Texture *texturePtr); 599 600 private: get()601 id<MTLBlitCommandEncoder> get() 602 { 603 return static_cast<id<MTLBlitCommandEncoder>>(CommandEncoder::get()); 604 } 605 }; 606 607 class ComputeCommandEncoder final : public CommandEncoder 608 { 609 public: 610 ComputeCommandEncoder(CommandBuffer *cmdBuffer); 611 ~ComputeCommandEncoder() override; 612 613 // Restart the encoder so that new commands can be encoded. 614 // NOTE: parent CommandBuffer's restart() must be called before this. 615 ComputeCommandEncoder &restart(); 616 617 ComputeCommandEncoder &setComputePipelineState(id<MTLComputePipelineState> state); 618 619 ComputeCommandEncoder &setBuffer(const BufferRef &buffer, uint32_t offset, uint32_t index); 620 ComputeCommandEncoder &setBufferForWrite(const BufferRef &buffer, 621 uint32_t offset, 622 uint32_t index); 623 ComputeCommandEncoder &setBytes(const uint8_t *bytes, size_t size, uint32_t index); 624 template <typename T> setData(const T & data,uint32_t index)625 ComputeCommandEncoder &setData(const T &data, uint32_t index) 626 { 627 return setBytes(reinterpret_cast<const uint8_t *>(&data), sizeof(T), index); 628 } 629 ComputeCommandEncoder &setSamplerState(id<MTLSamplerState> state, 630 float lodMinClamp, 631 float lodMaxClamp, 632 uint32_t index); 633 ComputeCommandEncoder &setTexture(const TextureRef &texture, uint32_t index); 634 ComputeCommandEncoder &setTextureForWrite(const TextureRef &texture, uint32_t index); 635 636 ComputeCommandEncoder &dispatch(const MTLSize &threadGroupsPerGrid, 637 const MTLSize &threadsPerGroup); 638 639 ComputeCommandEncoder &dispatchNonUniform(const MTLSize &threadsPerGrid, 640 const MTLSize &threadsPerGroup); 641 642 private: get()643 id<MTLComputeCommandEncoder> get() 644 { 645 return static_cast<id<MTLComputeCommandEncoder>>(CommandEncoder::get()); 646 } 647 }; 648 649 } // namespace mtl 650 } // namespace rx 651 652 #endif /* LIBANGLE_RENDERER_METAL_COMMANDENBUFFERMTL_H_ */ 653