diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdRendering.h b/MoltenVK/MoltenVK/Commands/MVKCmdRendering.h index 16e4863bf..a26141001 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdRendering.h +++ b/MoltenVK/MoltenVK/Commands/MVKCmdRendering.h @@ -6,9 +6,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -27,7 +27,6 @@ class MVKRenderPass; class MVKFramebuffer; - #pragma mark - #pragma mark MVKCmdBeginRenderPassBase @@ -35,24 +34,23 @@ class MVKFramebuffer; * Abstract base class of MVKCmdBeginRenderPass. * Contains all pieces that are independent of the templated portions. */ -class MVKCmdBeginRenderPassBase : public MVKCommand { +class MVKCmdBeginRenderPassBase : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, - const VkRenderPassBeginInfo* pRenderPassBegin, - const VkSubpassBeginInfo* pSubpassBeginInfo); + VkResult setContent(MVKCommandBuffer *cmdBuff, + const VkRenderPassBeginInfo *pRenderPassBegin, + const VkSubpassBeginInfo *pSubpassBeginInfo); - inline MVKRenderPass* getRenderPass() { return _renderPass; } + inline MVKRenderPass *getRenderPass() { return _renderPass; } protected: - - MVKRenderPass* _renderPass; - MVKFramebuffer* _framebuffer; + MVKRenderPass *_renderPass; + MVKFramebuffer *_framebuffer; VkRect2D _renderArea; VkSubpassContents _contents; }; - #pragma mark - #pragma mark MVKCmdBeginRenderPass @@ -61,21 +59,22 @@ class MVKCmdBeginRenderPassBase : public MVKCommand { * Template class to balance vector pre-allocations between very common low counts and fewer larger counts. */ template -class MVKCmdBeginRenderPass : public MVKCmdBeginRenderPassBase { +class MVKCmdBeginRenderPass : public MVKCmdBeginRenderPassBase +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, - const VkRenderPassBeginInfo* pRenderPassBegin, - const VkSubpassBeginInfo* pSubpassBeginInfo, - MVKArrayRef attachments); + VkResult setContent(MVKCommandBuffer *cmdBuff, + const VkRenderPassBeginInfo *pRenderPassBegin, + const VkSubpassBeginInfo *pSubpassBeginInfo, + MVKArrayRef attachments); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; MVKSmallVector _clearValues; - MVKSmallVector _attachments; + MVKSmallVector _attachments; }; // Concrete template class implementations. @@ -95,48 +94,46 @@ typedef MVKCmdBeginRenderPass<1, 9> MVKCmdBeginRenderPass1Multi; typedef MVKCmdBeginRenderPass<2, 9> MVKCmdBeginRenderPass2Multi; typedef MVKCmdBeginRenderPass<9, 9> MVKCmdBeginRenderPassMultiMulti; - #pragma mark - #pragma mark MVKCmdNextSubpass /** Vulkan command to begin a render pass. */ -class MVKCmdNextSubpass : public MVKCommand { +class MVKCmdNextSubpass : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, + VkResult setContent(MVKCommandBuffer *cmdBuff, VkSubpassContents contents); - VkResult setContent(MVKCommandBuffer* cmdBuff, - const VkSubpassBeginInfo* pSubpassBeginInfo, - const VkSubpassEndInfo* pSubpassEndInfo); + VkResult setContent(MVKCommandBuffer *cmdBuff, + const VkSubpassBeginInfo *pSubpassBeginInfo, + const VkSubpassEndInfo *pSubpassEndInfo); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; VkSubpassContents _contents; }; - #pragma mark - #pragma mark MVKCmdEndRenderPass /** Vulkan command to end the current render pass. */ -class MVKCmdEndRenderPass : public MVKCommand { +class MVKCmdEndRenderPass : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff); - VkResult setContent(MVKCommandBuffer* cmdBuff, - const VkSubpassEndInfo* pSubpassEndInfo); + VkResult setContent(MVKCommandBuffer *cmdBuff); + VkResult setContent(MVKCommandBuffer *cmdBuff, + const VkSubpassEndInfo *pSubpassEndInfo); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; - + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; }; - #pragma mark - #pragma mark MVKCmdBeginRendering @@ -145,17 +142,18 @@ class MVKCmdEndRenderPass : public MVKCommand { * Template class to balance vector pre-allocations between very common low counts and fewer larger counts. */ template -class MVKCmdBeginRendering : public MVKCommand { +class MVKCmdBeginRendering : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* - cmdBuff, const VkRenderingInfo* pRenderingInfo); - - void encode(MVKCommandEncoder* cmdEncoder) override; + VkResult setContent(MVKCommandBuffer * + cmdBuff, + const VkRenderingInfo *pRenderingInfo); + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; VkRenderingInfo _renderingInfo; MVKSmallVector _colorAttachments; @@ -169,62 +167,60 @@ typedef MVKCmdBeginRendering<2> MVKCmdBeginRendering2; typedef MVKCmdBeginRendering<4> MVKCmdBeginRendering4; typedef MVKCmdBeginRendering<8> MVKCmdBeginRenderingMulti; - #pragma mark - #pragma mark MVKCmdEndRendering /** Vulkan command to end the current dynamic rendering. */ -class MVKCmdEndRendering : public MVKCommand { +class MVKCmdEndRendering : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff); + VkResult setContent(MVKCommandBuffer *cmdBuff); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; - + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; }; - #pragma mark - #pragma mark MVKCmdSetSampleLocations /** Vulkan command to dynamically set custom sample locations. */ -class MVKCmdSetSampleLocations : public MVKCommand { +class MVKCmdSetSampleLocations : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, - const VkSampleLocationsInfoEXT* pSampleLocationsInfo); + VkResult setContent(MVKCommandBuffer *cmdBuff, + const VkSampleLocationsInfoEXT *pSampleLocationsInfo); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; MVKSmallVector _sampleLocations; }; - #pragma mark - #pragma mark MVKCmdSetSampleLocationsEnable /** Vulkan command to dynamically enable custom sample locations. */ -class MVKCmdSetSampleLocationsEnable : public MVKCommand { +class MVKCmdSetSampleLocationsEnable : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, + VkResult setContent(MVKCommandBuffer *cmdBuff, VkBool32 sampleLocationsEnable); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; VkBool32 _sampleLocationsEnable; }; - #pragma mark - #pragma mark MVKCmdSetViewport @@ -233,18 +229,19 @@ class MVKCmdSetSampleLocationsEnable : public MVKCommand { * Template class to balance vector pre-allocations between very common low counts and fewer larger counts. */ template -class MVKCmdSetViewport : public MVKCommand { +class MVKCmdSetViewport : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, + VkResult setContent(MVKCommandBuffer *cmdBuff, uint32_t firstViewport, uint32_t viewportCount, - const VkViewport* pViewports); + const VkViewport *pViewports); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; MVKSmallVector _viewports; uint32_t _firstViewport; @@ -254,7 +251,6 @@ class MVKCmdSetViewport : public MVKCommand { typedef MVKCmdSetViewport<1> MVKCmdSetViewport1; typedef MVKCmdSetViewport MVKCmdSetViewportMulti; - #pragma mark - #pragma mark MVKCmdSetScissor @@ -263,18 +259,19 @@ typedef MVKCmdSetViewport MVKCmdSetViewportMulti; * Template class to balance vector pre-allocations between very common low counts and fewer larger counts. */ template -class MVKCmdSetScissor : public MVKCommand { +class MVKCmdSetScissor : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, + VkResult setContent(MVKCommandBuffer *cmdBuff, uint32_t firstScissor, uint32_t scissorCount, - const VkRect2D* pScissors); + const VkRect2D *pScissors); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; MVKSmallVector _scissors; uint32_t _firstScissor; @@ -284,181 +281,181 @@ class MVKCmdSetScissor : public MVKCommand { typedef MVKCmdSetScissor<1> MVKCmdSetScissor1; typedef MVKCmdSetScissor MVKCmdSetScissorMulti; - #pragma mark - #pragma mark MVKCmdSetDepthBias /** Vulkan command to set the depth bias. */ -class MVKCmdSetDepthBias : public MVKCommand { +class MVKCmdSetDepthBias : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, + VkResult setContent(MVKCommandBuffer *cmdBuff, float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; - float _depthBiasConstantFactor; - float _depthBiasClamp; - float _depthBiasSlopeFactor; + float _depthBiasConstantFactor; + float _depthBiasClamp; + float _depthBiasSlopeFactor; }; - #pragma mark - #pragma mark MVKCmdSetDepthBiasEnable /** Vulkan command to dynamically enable or disable depth bias. */ -class MVKCmdSetDepthBiasEnable : public MVKCommand { +class MVKCmdSetDepthBiasEnable : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, + VkResult setContent(MVKCommandBuffer *cmdBuff, VkBool32 depthBiasEnable); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; VkBool32 _depthBiasEnable; }; - #pragma mark - #pragma mark MVKCmdSetBlendConstants /** Vulkan command to set the blend constants. */ -class MVKCmdSetBlendConstants : public MVKCommand { +class MVKCmdSetBlendConstants : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, + VkResult setContent(MVKCommandBuffer *cmdBuff, const float blendConst[4]); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; float _blendConstants[4] = {}; }; - #pragma mark - #pragma mark MVKCmdSetDepthTestEnable /** Vulkan command to dynamically enable depth testing. */ -class MVKCmdSetDepthTestEnable : public MVKCommand { +class MVKCmdSetDepthTestEnable : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, + VkResult setContent(MVKCommandBuffer *cmdBuff, VkBool32 depthTestEnable); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; VkBool32 _depthTestEnable; }; - #pragma mark - #pragma mark MVKCmdSetDepthWriteEnable /** Vulkan command to dynamically enable depth writing. */ -class MVKCmdSetDepthWriteEnable : public MVKCommand { +class MVKCmdSetDepthWriteEnable : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, + VkResult setContent(MVKCommandBuffer *cmdBuff, VkBool32 depthWriteEnable); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; VkBool32 _depthWriteEnable; }; - #pragma mark - #pragma mark MVKCmdSetDepthClipEnable /** Vulkan command to dynamically enable depth clip. */ -class MVKCmdSetDepthClipEnable : public MVKCommand { +class MVKCmdSetDepthClipEnable : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, + VkResult setContent(MVKCommandBuffer *cmdBuff, VkBool32 depthClipEnable); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; VkBool32 _depthClipEnable; }; - #pragma mark - #pragma mark MVKCmdSetDepthCompareOp /** Vulkan command to dynamically set the depth compare operation. */ -class MVKCmdSetDepthCompareOp : public MVKCommand { +class MVKCmdSetDepthCompareOp : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, + VkResult setContent(MVKCommandBuffer *cmdBuff, VkCompareOp depthCompareOp); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; VkCompareOp _depthCompareOp; }; - #pragma mark - #pragma mark MVKCmdSetStencilTestEnable /** Vulkan command to dynamically enable stencil testing. */ -class MVKCmdSetStencilTestEnable : public MVKCommand { +class MVKCmdSetStencilTestEnable : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, + VkResult setContent(MVKCommandBuffer *cmdBuff, VkBool32 stencilTestEnable); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; VkBool32 _stencilTestEnable; }; - #pragma mark - #pragma mark MVKCmdSetStencilOp /** Vulkan command to dynamically set the stencil operations. */ -class MVKCmdSetStencilOp : public MVKCommand { +class MVKCmdSetStencilOp : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, + VkResult setContent(MVKCommandBuffer *cmdBuff, VkStencilFaceFlags faceMask, VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp, VkCompareOp compareOp); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; VkStencilFaceFlags _faceMask; VkStencilOp _failOp; @@ -467,199 +464,217 @@ class MVKCmdSetStencilOp : public MVKCommand { VkCompareOp _compareOp; }; - #pragma mark - #pragma mark MVKCmdSetStencilCompareMask /** Vulkan command to set the stencil compare mask. */ -class MVKCmdSetStencilCompareMask : public MVKCommand { +class MVKCmdSetStencilCompareMask : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, + VkResult setContent(MVKCommandBuffer *cmdBuff, VkStencilFaceFlags faceMask, uint32_t stencilCompareMask); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; - VkStencilFaceFlags _faceMask; - uint32_t _stencilCompareMask; + VkStencilFaceFlags _faceMask; + uint32_t _stencilCompareMask; }; - #pragma mark - #pragma mark MVKCmdSetStencilWriteMask /** Vulkan command to set the stencil write mask. */ -class MVKCmdSetStencilWriteMask : public MVKCommand { +class MVKCmdSetStencilWriteMask : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, + VkResult setContent(MVKCommandBuffer *cmdBuff, VkStencilFaceFlags faceMask, uint32_t stencilWriteMask); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; - VkStencilFaceFlags _faceMask; - uint32_t _stencilWriteMask; + VkStencilFaceFlags _faceMask; + uint32_t _stencilWriteMask; }; - #pragma mark - #pragma mark MVKCmdSetStencilReference /** Vulkan command to set the stencil reference value. */ -class MVKCmdSetStencilReference : public MVKCommand { +class MVKCmdSetStencilReference : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, + VkResult setContent(MVKCommandBuffer *cmdBuff, VkStencilFaceFlags faceMask, uint32_t stencilReference); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; - VkStencilFaceFlags _faceMask; - uint32_t _stencilReference; + VkStencilFaceFlags _faceMask; + uint32_t _stencilReference; }; - #pragma mark - #pragma mark MVKCmdSetCullMode /** Vulkan command to dynamically set the cull mode. */ -class MVKCmdSetCullMode : public MVKCommand { +class MVKCmdSetCullMode : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, - VkCullModeFlags cullMode); + VkResult setContent(MVKCommandBuffer *cmdBuff, + VkCullModeFlags cullMode); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; VkCullModeFlags _cullMode; }; - #pragma mark - #pragma mark MVKCmdSetFrontFace /** Vulkan command to dynamically set the front facing winding order. */ -class MVKCmdSetFrontFace : public MVKCommand { +class MVKCmdSetFrontFace : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, - VkFrontFace frontFace); + VkResult setContent(MVKCommandBuffer *cmdBuff, + VkFrontFace frontFace); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; VkFrontFace _frontFace; }; - #pragma mark - #pragma mark MVKCmdSetPatchControlPoints /** Vulkan command to dynamically set the number of patch control points. */ -class MVKCmdSetPatchControlPoints : public MVKCommand { +class MVKCmdSetPatchControlPoints : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, + VkResult setContent(MVKCommandBuffer *cmdBuff, uint32_t patchControlPoints); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; uint32_t _patchControlPoints; }; - #pragma mark - #pragma mark MVKCmdSetPolygonMode /** Vulkan command to dynamically set the polygon mode. */ -class MVKCmdSetPolygonMode : public MVKCommand { +class MVKCmdSetPolygonMode : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, + VkResult setContent(MVKCommandBuffer *cmdBuff, VkPolygonMode polygonMode); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; VkPolygonMode _polygonMode; }; - #pragma mark - #pragma mark MVKCmdSetPrimitiveTopology /** Vulkan command to dynamically set the primitive topology. */ -class MVKCmdSetPrimitiveTopology : public MVKCommand { +class MVKCmdSetPrimitiveTopology : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, + VkResult setContent(MVKCommandBuffer *cmdBuff, VkPrimitiveTopology primitiveTopology); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; VkPrimitiveTopology _primitiveTopology; }; - #pragma mark - #pragma mark MVKCmdSetPrimitiveRestartEnable /** Vulkan command to dynamically enable or disable primitive restart functionality. */ -class MVKCmdSetPrimitiveRestartEnable : public MVKCommand { +class MVKCmdSetPrimitiveRestartEnable : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, + VkResult setContent(MVKCommandBuffer *cmdBuff, VkBool32 primitiveRestartEnable); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; VkBool32 _primitiveRestartEnable; }; - #pragma mark - #pragma mark MVKCmdSetRasterizerDiscardEnable /** Vulkan command to dynamically enable or disable rasterization. */ -class MVKCmdSetRasterizerDiscardEnable : public MVKCommand { +class MVKCmdSetRasterizerDiscardEnable : public MVKCommand +{ public: - VkResult setContent(MVKCommandBuffer* cmdBuff, + VkResult setContent(MVKCommandBuffer *cmdBuff, VkBool32 rasterizerDiscardEnable); - void encode(MVKCommandEncoder* cmdEncoder) override; + void encode(MVKCommandEncoder *cmdEncoder) override; protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; VkBool32 _rasterizerDiscardEnable; }; +#pragma mark - +#pragma mark MVKCmdSetLineWidth + +/** TODO: (jarrodnorwell) */ +class MVKCmdSetLineWidth : public MVKCommand +{ + +public: + VkResult setContent(MVKCommandBuffer *cmdBuff, + float lineWidth); + + void encode(MVKCommandEncoder *cmdEncoder) override; + +protected: + MVKCommandTypePool *getTypePool(MVKCommandPool *cmdPool) override; + + float _lineWidth; +}; diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdRendering.mm b/MoltenVK/MoltenVK/Commands/MVKCmdRendering.mm index a2492acec..8dc1371d7 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdRendering.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdRendering.mm @@ -552,3 +552,17 @@ void MVKCmdSetRasterizerDiscardEnable::encode(MVKCommandEncoder* cmdEncoder) { cmdEncoder->_renderingState.setRasterizerDiscardEnable(_rasterizerDiscardEnable, true); } + + +#pragma mark - +#pragma mark MVKCmdSetLineWidth + +VkResult MVKCmdSetLineWidth::setContent(MVKCommandBuffer* cmdBuff, + float lineWidth) { + _lineWidth = lineWidth; + return VK_SUCCESS; +} + +void MVKCmdSetLineWidth::encode(MVKCommandEncoder* cmdEncoder) { + cmdEncoder->_lineWidthState.setLineWidth(_lineWidth, true); +} diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h index 92d02e772..d5959f0c5 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h +++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h @@ -6,9 +6,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -44,37 +44,37 @@ class MVKComputePipeline; typedef uint64_t MVKMTLCommandBufferID; - #pragma mark - #pragma mark MVKCommandEncodingContext /** Context for tracking information across multiple encodings. */ -typedef struct MVKCommandEncodingContext { +typedef struct MVKCommandEncodingContext +{ NSUInteger mtlVisibilityResultOffset = 0; - const MVKMTLBufferAllocation* visibilityResultBuffer = nullptr; + const MVKMTLBufferAllocation *visibilityResultBuffer = nullptr; - MVKRenderPass* getRenderPass() { return _renderPass; } - MVKFramebuffer* getFramebuffer() { return _framebuffer; } - void setRenderingContext(MVKRenderPass* renderPass, MVKFramebuffer* framebuffer); + MVKRenderPass *getRenderPass() { return _renderPass; } + MVKFramebuffer *getFramebuffer() { return _framebuffer; } + void setRenderingContext(MVKRenderPass *renderPass, MVKFramebuffer *framebuffer); VkRenderingFlags getRenderingFlags() { return _renderPass ? _renderPass->getRenderingFlags() : 0; } ~MVKCommandEncodingContext(); private: - MVKRenderPass* _renderPass = nullptr; - MVKFramebuffer* _framebuffer = nullptr; + MVKRenderPass *_renderPass = nullptr; + MVKFramebuffer *_framebuffer = nullptr; } MVKCommandEncodingContext; - #pragma mark - #pragma mark MVKCurrentSubpassInfo /** Tracks current render subpass information. */ -typedef struct MVKCurrentSubpassInfo { - MVKRenderPass* renderpass; +typedef struct MVKCurrentSubpassInfo +{ + MVKRenderPass *renderpass; uint32_t subpassIndex; uint32_t subpassViewMask; - void beginRenderpass(MVKRenderPass* rp); + void beginRenderpass(MVKRenderPass *rp); void nextSubpass(); void beginRendering(uint32_t viewMask); @@ -82,16 +82,15 @@ typedef struct MVKCurrentSubpassInfo { void updateViewMask(); } MVKCurrentSubpassInfo; - #pragma mark - #pragma mark MVKCommandBuffer /** Represents a Vulkan command pool. */ class MVKCommandBuffer : public MVKDispatchableVulkanAPIObject, public MVKDeviceTrackingMixin, - public MVKLinkableMixin { + public MVKLinkableMixin +{ public: - /** Returns the Vulkan type of this object. */ VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_COMMAND_BUFFER; } @@ -99,10 +98,10 @@ class MVKCommandBuffer : public MVKDispatchableVulkanAPIObject, VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT; } /** Returns a pointer to the Vulkan instance. */ - MVKInstance* getInstance() override { return _device->getInstance(); } + MVKInstance *getInstance() override { return _device->getInstance(); } /** Prepares this instance to receive commands. */ - VkResult begin(const VkCommandBufferBeginInfo* pBeginInfo); + VkResult begin(const VkCommandBufferBeginInfo *pBeginInfo); /** Resets this instance to allow it to receive new commands. */ VkResult reset(VkCommandBufferResetFlags flags); @@ -111,19 +110,19 @@ class MVKCommandBuffer : public MVKDispatchableVulkanAPIObject, VkResult end(); /** Adds the specified execution command at the end of this command buffer. */ - void addCommand(MVKCommand* command); + void addCommand(MVKCommand *command); /** Returns the number of commands currently in this command buffer. */ uint32_t getCommandCount() { return _commandCount; } /** Returns the command pool backing this command buffer. */ - MVKCommandPool* getCommandPool() { return _commandPool; } + MVKCommandPool *getCommandPool() { return _commandPool; } /** Submit the commands in this buffer as part of the queue submission. */ - void submit(MVKQueueCommandBufferSubmission* cmdBuffSubmit, MVKCommandEncodingContext* pEncodingContext); + void submit(MVKQueueCommandBufferSubmission *cmdBuffSubmit, MVKCommandEncodingContext *pEncodingContext); - /** Returns whether this command buffer can be submitted to a queue more than once. */ - bool getIsReusable() { return _isReusable; } + /** Returns whether this command buffer can be submitted to a queue more than once. */ + bool getIsReusable() { return _isReusable; } /** * If this is a secondary command buffer, returns the number of views inherited @@ -134,72 +133,71 @@ class MVKCommandBuffer : public MVKDispatchableVulkanAPIObject, /** Updated as renderpass commands are added. */ MVKCurrentSubpassInfo _currentSubpassInfo; - /** - * Metal requires that a visibility buffer is established when a render pass is created, - * but Vulkan permits it to be set during a render pass. When the first occlusion query - * command is added, it sets this value so that it can be applied when the first renderpass - * is begun. - */ - bool _needsVisibilityResultMTLBuffer; + /** + * Metal requires that a visibility buffer is established when a render pass is created, + * but Vulkan permits it to be set during a render pass. When the first occlusion query + * command is added, it sets this value so that it can be applied when the first renderpass + * is begun. + */ + bool _needsVisibilityResultMTLBuffer; /** Called when a MVKCmdExecuteCommands is added to this command buffer. */ - void recordExecuteCommands(MVKArrayRef secondaryCommandBuffers); + void recordExecuteCommands(MVKArrayRef secondaryCommandBuffers); /** Called when a timestamp command is added. */ void recordTimestampCommand(); - #pragma mark Tessellation constituent command management /** Update the last recorded pipeline with tessellation shaders */ - void recordBindPipeline(MVKCmdBindPipeline* mvkBindPipeline); + void recordBindPipeline(MVKCmdBindPipeline *mvkBindPipeline); /** The most recent recorded tessellation pipeline */ - MVKCmdBindPipeline* _lastTessellationPipeline; - + MVKCmdBindPipeline *_lastTessellationPipeline; #pragma mark Construction - MVKCommandBuffer(MVKDevice* device) : MVKDeviceTrackingMixin(device) {} + MVKCommandBuffer(MVKDevice *device) : MVKDeviceTrackingMixin(device) {} ~MVKCommandBuffer() override; - /** - * Returns a reference to this object suitable for use as a Vulkan API handle. - * This is the compliment of the getMVKCommandBuffer() method. - */ + /** + * Returns a reference to this object suitable for use as a Vulkan API handle. + * This is the compliment of the getMVKCommandBuffer() method. + */ VkCommandBuffer getVkCommandBuffer() { return (VkCommandBuffer)getVkHandle(); } - /** - * Retrieves the MVKCommandBuffer instance referenced by the VkCommandBuffer handle. - * This is the compliment of the getVkCommandBuffer() method. - */ - static MVKCommandBuffer* getMVKCommandBuffer(VkCommandBuffer vkCommandBuffer) { - return (MVKCommandBuffer*)getDispatchableObject(vkCommandBuffer); - } + /** + * Retrieves the MVKCommandBuffer instance referenced by the VkCommandBuffer handle. + * This is the compliment of the getVkCommandBuffer() method. + */ + static MVKCommandBuffer *getMVKCommandBuffer(VkCommandBuffer vkCommandBuffer) + { + return (MVKCommandBuffer *)getDispatchableObject(vkCommandBuffer); + } protected: friend class MVKCommandEncoder; friend class MVKCommandPool; void propagateDebugName() override {} - void init(const VkCommandBufferAllocateInfo* pAllocateInfo); + void init(const VkCommandBufferAllocateInfo *pAllocateInfo); bool canExecute(); void clearPrefilledMTLCommandBuffer(); - void releaseCommands(MVKCommand* command); + void releaseCommands(MVKCommand *command); void releaseRecordedCommands(); void flushImmediateCmdEncoder(); void checkDeferredEncoding(); - MVKCommand* _head = nullptr; - MVKCommand* _tail = nullptr; + MVKCommand *_head = nullptr; + MVKCommand *_tail = nullptr; MVKSmallVector _colorAttachmentFormats; - MVKCommandPool* _commandPool; + MVKCommandPool *_commandPool; VkCommandBufferInheritanceInfo _secondaryInheritanceInfo; VkCommandBufferInheritanceRenderingInfo _secondaryInheritanceRenderingInfo; id _prefilledMTLCmdBuffer = nil; - MVKCommandEncodingContext* _immediateCmdEncodingContext = nullptr; - MVKCommandEncoder* _immediateCmdEncoder = nullptr; + MVKCommandEncodingContext *_immediateCmdEncodingContext = nullptr; + MVKCommandEncoder *_immediateCmdEncoder = nullptr; uint32_t _commandCount; std::atomic_flag _isExecutingNonConcurrently; bool _isSecondary; @@ -211,57 +209,56 @@ class MVKCommandBuffer : public MVKDispatchableVulkanAPIObject, bool _hasStageCounterTimestampCommand; }; - #pragma mark - #pragma mark MVKCommandEncoder /*** Holds a collection of active queries for each query pool. */ -typedef std::unordered_map> MVKActivatedQueries; +typedef std::unordered_map> MVKActivatedQueries; -/** - * MVKCommandEncoder uses a visitor design pattern iterate the commands in a MVKCommandBuffer, +/** + * MVKCommandEncoder uses a visitor design pattern iterate the commands in a MVKCommandBuffer, * tracking and caching dynamic encoding state, and encoding the commands onto Metal MTLCommandBuffers. * * Much of the dynamic cached encoding state has public access and is accessed directly * from the commands in the command buffer. */ -class MVKCommandEncoder : public MVKBaseDeviceObject { +class MVKCommandEncoder : public MVKBaseDeviceObject +{ public: - /** Returns the Vulkan API opaque object controlling this object. */ - MVKVulkanAPIObject* getVulkanAPIObject() override { return _cmdBuffer->getVulkanAPIObject(); }; + MVKVulkanAPIObject *getVulkanAPIObject() override { return _cmdBuffer->getVulkanAPIObject(); }; /** Encode commands from the command buffer onto the Metal command buffer. */ - void encode(id mtlCmdBuff, MVKCommandEncodingContext* pEncodingContext); - - void beginEncoding(id mtlCmdBuff, MVKCommandEncodingContext* pEncodingContext); - void encodeCommands(MVKCommand* command); - void endEncoding(); + void encode(id mtlCmdBuff, MVKCommandEncodingContext *pEncodingContext); + + void beginEncoding(id mtlCmdBuff, MVKCommandEncodingContext *pEncodingContext); + void encodeCommands(MVKCommand *command); + void endEncoding(); /** Encode commands from the specified secondary command buffer onto the Metal command buffer. */ - void encodeSecondary(MVKCommandBuffer* secondaryCmdBuffer); + void encodeSecondary(MVKCommandBuffer *secondaryCmdBuffer); /** Begins a render pass and establishes initial draw state. */ - void beginRenderpass(MVKCommand* passCmd, + void beginRenderpass(MVKCommand *passCmd, VkSubpassContents subpassContents, - MVKRenderPass* renderPass, - MVKFramebuffer* framebuffer, - const VkRect2D& renderArea, + MVKRenderPass *renderPass, + MVKFramebuffer *framebuffer, + const VkRect2D &renderArea, MVKArrayRef clearValues, - MVKArrayRef attachments, + MVKArrayRef attachments, MVKCommandUse cmdUse); /** Begins the next render subpass. */ - void beginNextSubpass(MVKCommand* subpassCmd, VkSubpassContents renderpassContents); + void beginNextSubpass(MVKCommand *subpassCmd, VkSubpassContents renderpassContents); /** Begins dynamic rendering. */ - void beginRendering(MVKCommand* rendCmd, const VkRenderingInfo* pRenderingInfo); + void beginRendering(MVKCommand *rendCmd, const VkRenderingInfo *pRenderingInfo); /** Begins a Metal render pass for the current render subpass. */ void beginMetalRenderPass(MVKCommandUse cmdUse); - /** + /** * If a Metal render pass has started, and it needs to be restarted, * then end the existing Metal render pass, and start a new one. */ @@ -274,7 +271,7 @@ class MVKCommandEncoder : public MVKBaseDeviceObject { bool isInRenderPass() { return _pEncodingContext->getRenderPass() != nullptr; } /** Returns the render subpass that is currently active. */ - MVKRenderSubpass* getSubpass(); + MVKRenderSubpass *getSubpass(); /** The extent of current framebuffer.*/ VkExtent2D getFramebufferExtent(); @@ -288,19 +285,19 @@ class MVKCommandEncoder : public MVKBaseDeviceObject { /** Begins a Metal compute encoding. */ void beginMetalComputeEncoding(MVKCommandUse cmdUse); - /** Binds a pipeline to a bind point. */ - void bindPipeline(VkPipelineBindPoint pipelineBindPoint, MVKPipeline* pipeline); + /** Binds a pipeline to a bind point. */ + void bindPipeline(VkPipelineBindPoint pipelineBindPoint, MVKPipeline *pipeline); /** Binds the descriptor set to the index at the bind point. */ void bindDescriptorSet(VkPipelineBindPoint pipelineBindPoint, uint32_t descSetIndex, - MVKDescriptorSet* descSet, - MVKShaderResourceBinding& dslMTLRezIdxOffsets, + MVKDescriptorSet *descSet, + MVKShaderResourceBinding &dslMTLRezIdxOffsets, MVKArrayRef dynamicOffsets, - uint32_t& dynamicOffsetIndex); + uint32_t &dynamicOffsetIndex); /** Encodes an operation to signal an event to a status. */ - void signalEvent(MVKEvent* mvkEvent, bool status); + void signalEvent(MVKEvent *mvkEvent, bool status); /** Clips the rect to ensure it fits inside the render area. */ VkRect2D clipToRenderArea(VkRect2D rect); @@ -311,8 +308,8 @@ class MVKCommandEncoder : public MVKBaseDeviceObject { /** Called by each graphics draw command to establish any outstanding state just prior to performing the draw. */ void finalizeDrawState(MVKGraphicsStage stage); - /** Called by each compute dispatch command to establish any outstanding state just prior to performing the dispatch. */ - void finalizeDispatchState(); + /** Called by each compute dispatch command to establish any outstanding state just prior to performing the dispatch. */ + void finalizeDispatchState(); /** Ends the current renderpass. */ void endRenderpass(); @@ -320,10 +317,10 @@ class MVKCommandEncoder : public MVKBaseDeviceObject { /** Ends the current dymamic rendering. */ void endRendering(); - /** + /** * Ends all encoding operations on the current Metal command encoder. * - * This must be called once all encoding is complete, and prior + * This must be called once all encoding is complete, and prior * to each switch between render, compute, and BLIT encoding. */ void endCurrentMetalEncoding(); @@ -331,7 +328,7 @@ class MVKCommandEncoder : public MVKBaseDeviceObject { /** Ends encoding operations on the current Metal command encoder if it is a rendering encoder. */ void endMetalRenderEncoding(); - /** + /** * Returns the current Metal compute encoder for the specified use, * which determines the label assigned to the returned encoder. * @@ -344,10 +341,10 @@ class MVKCommandEncoder : public MVKBaseDeviceObject { /** * Returns the current Metal BLIT encoder for the specified use, - * which determines the label assigned to the returned encoder. + * which determines the label assigned to the returned encoder. * - * If the current encoder is not a BLIT encoder, this function ends - * the current encoder before beginning BLIT encoding. + * If the current encoder is not a BLIT encoder, this function ends + * the current encoder before beginning BLIT encoding. */ id getMTLBlitEncoder(MVKCommandUse cmdUse); @@ -358,17 +355,17 @@ class MVKCommandEncoder : public MVKBaseDeviceObject { id getMTLEncoder(); /** Returns the push constants associated with the specified shader stage. */ - MVKPushConstantsCommandEncoderState* getPushConstants(VkShaderStageFlagBits shaderStage); + MVKPushConstantsCommandEncoderState *getPushConstants(VkShaderStageFlagBits shaderStage); /** Encode the buffer binding as a vertex attribute buffer. */ - void encodeVertexAttributeBuffer(MVKMTLBufferBinding& b, bool isDynamicStride); + void encodeVertexAttributeBuffer(MVKMTLBufferBinding &b, bool isDynamicStride); - /** + /** * Copy bytes into the Metal encoder at a Metal vertex buffer index, and optionally indicate * that this binding might override a desriptor binding. If so, the descriptor binding will * be marked dirty so that it will rebind before the next usage. */ - void setVertexBytes(id mtlEncoder, const void* bytes, + void setVertexBytes(id mtlEncoder, const void *bytes, NSUInteger length, uint32_t mtlBuffIndex, bool descOverride = false); /** @@ -376,7 +373,7 @@ class MVKCommandEncoder : public MVKBaseDeviceObject { * that this binding might override a desriptor binding. If so, the descriptor binding will * be marked dirty so that it will rebind before the next usage. */ - void setFragmentBytes(id mtlEncoder, const void* bytes, + void setFragmentBytes(id mtlEncoder, const void *bytes, NSUInteger length, uint32_t mtlBuffIndex, bool descOverride = false); /** @@ -384,51 +381,51 @@ class MVKCommandEncoder : public MVKBaseDeviceObject { * that this binding might override a desriptor binding. If so, the descriptor binding will * be marked dirty so that it will rebind before the next usage. */ - void setComputeBytes(id mtlEncoder, const void* bytes, + void setComputeBytes(id mtlEncoder, const void *bytes, NSUInteger length, uint32_t mtlBuffIndex, bool descOverride = false); - /** Get a temporary MTLBuffer that will be returned to a pool after the command buffer is finished. */ - const MVKMTLBufferAllocation* getTempMTLBuffer(NSUInteger length, bool isPrivate = false, bool isDedicated = false); + /** Get a temporary MTLBuffer that will be returned to a pool after the command buffer is finished. */ + const MVKMTLBufferAllocation *getTempMTLBuffer(NSUInteger length, bool isPrivate = false, bool isDedicated = false); /** Copy the bytes to a temporary MTLBuffer that will be returned to a pool after the command buffer is finished. */ - const MVKMTLBufferAllocation* copyToTempMTLBufferAllocation(const void* bytes, NSUInteger length, bool isDedicated = false); + const MVKMTLBufferAllocation *copyToTempMTLBufferAllocation(const void *bytes, NSUInteger length, bool isDedicated = false); - /** Returns the command encoding pool. */ - MVKCommandEncodingPool* getCommandEncodingPool(); + /** Returns the command encoding pool. */ + MVKCommandEncodingPool *getCommandEncodingPool(); #pragma mark Queries - /** Begins an occlusion query. */ - void beginOcclusionQuery(MVKOcclusionQueryPool* pQueryPool, uint32_t query, VkQueryControlFlags flags); + /** Begins an occlusion query. */ + void beginOcclusionQuery(MVKOcclusionQueryPool *pQueryPool, uint32_t query, VkQueryControlFlags flags); - /** Ends the current occlusion query. */ - void endOcclusionQuery(MVKOcclusionQueryPool* pQueryPool, uint32_t query); + /** Ends the current occlusion query. */ + void endOcclusionQuery(MVKOcclusionQueryPool *pQueryPool, uint32_t query); - /** Marks a timestamp for the specified query. */ - void markTimestamp(MVKTimestampQueryPool* pQueryPool, uint32_t query); + /** Marks a timestamp for the specified query. */ + void markTimestamp(MVKTimestampQueryPool *pQueryPool, uint32_t query); - /** Reset a range of queries. */ - void resetQueries(MVKQueryPool* pQueryPool, uint32_t firstQuery, uint32_t queryCount); + /** Reset a range of queries. */ + void resetQueries(MVKQueryPool *pQueryPool, uint32_t firstQuery, uint32_t queryCount); #pragma mark Dynamic encoding state accessed directly /** Context for tracking information across multiple encodings. */ - MVKCommandEncodingContext* _pEncodingContext; + MVKCommandEncodingContext *_pEncodingContext; - /** A reference to the Metal features supported by the device. */ - const MVKPhysicalDeviceMetalFeatures* _pDeviceMetalFeatures; + /** A reference to the Metal features supported by the device. */ + const MVKPhysicalDeviceMetalFeatures *_pDeviceMetalFeatures; - /** A reference to the Vulkan features supported by the device. */ - const VkPhysicalDeviceFeatures* _pDeviceFeatures; + /** A reference to the Vulkan features supported by the device. */ + const VkPhysicalDeviceFeatures *_pDeviceFeatures; - /** Pointer to the properties of the device. */ - const VkPhysicalDeviceProperties* _pDeviceProperties; + /** Pointer to the properties of the device. */ + const VkPhysicalDeviceProperties *_pDeviceProperties; - /** Pointer to the memory properties of the device. */ - const VkPhysicalDeviceMemoryProperties* _pDeviceMemoryProperties; + /** Pointer to the memory properties of the device. */ + const VkPhysicalDeviceMemoryProperties *_pDeviceMemoryProperties; /** The command buffer whose commands are being encoded. */ - MVKCommandBuffer* _cmdBuffer; + MVKCommandBuffer *_cmdBuffer; /** The current Metal command buffer. */ id _mtlCmdBuffer; @@ -436,20 +433,23 @@ class MVKCommandEncoder : public MVKBaseDeviceObject { /** The current Metal render encoder. */ id _mtlRenderEncoder; - /** Tracks the current graphics pipeline bound to the encoder. */ + /** Tracks the current graphics pipeline bound to the encoder. */ MVKPipelineCommandEncoderState _graphicsPipelineState; + /** Tracks the current line width state of the encoder. */ + MVKLineWidthCommandEncoderState _lineWidthState; + /** Tracks the current graphics resources state of the encoder. */ MVKGraphicsResourcesCommandEncoderState _graphicsResourcesState; - /** Tracks the current compute pipeline bound to the encoder. */ + /** Tracks the current compute pipeline bound to the encoder. */ MVKPipelineCommandEncoderState _computePipelineState; /** Tracks the current compute resources state of the encoder. */ MVKComputeResourcesCommandEncoderState _computeResourcesState; - /** Tracks the current depth stencil state of the encoder. */ - MVKDepthStencilCommandEncoderState _depthStencilState; + /** Tracks the current depth stencil state of the encoder. */ + MVKDepthStencilCommandEncoderState _depthStencilState; /** Tracks the current rendering states of the encoder. */ MVKRenderingCommandEncoderState _renderingState; @@ -457,8 +457,8 @@ class MVKCommandEncoder : public MVKBaseDeviceObject { /** Tracks the occlusion query state of the encoder. */ MVKOcclusionQueryCommandEncoderState _occlusionQueryState; - /** The size of the threadgroup for the compute shader. */ - MTLSize _mtlThreadgroupSize; + /** The size of the threadgroup for the compute shader. */ + MTLSize _mtlThreadgroupSize; /** Indicates whether the current render subpass is able to render to an array (layered) framebuffer. */ bool _canUseLayeredRendering; @@ -468,37 +468,40 @@ class MVKCommandEncoder : public MVKBaseDeviceObject { #pragma mark Construction - MVKCommandEncoder(MVKCommandBuffer* cmdBuffer, + MVKCommandEncoder(MVKCommandBuffer *cmdBuffer, MVKPrefillMetalCommandBuffersStyle prefillStyle = MVK_CONFIG_PREFILL_METAL_COMMAND_BUFFERS_STYLE_NO_PREFILL); ~MVKCommandEncoder() override; protected: - void addActivatedQueries(MVKQueryPool* pQueryPool, uint32_t query, uint32_t queryCount); - void finishQueries(); - void setSubpass(MVKCommand* passCmd, VkSubpassContents subpassContents, uint32_t subpassIndex, MVKCommandUse cmdUse); + void addActivatedQueries(MVKQueryPool *pQueryPool, uint32_t query, uint32_t queryCount); + void finishQueries(); + void setSubpass(MVKCommand *passCmd, VkSubpassContents subpassContents, uint32_t subpassIndex, MVKCommandUse cmdUse); void clearRenderArea(MVKCommandUse cmdUse); bool hasMoreMultiviewPasses(); void beginNextMultiviewPass(); - void encodeCommandsImpl(MVKCommand* command); - void encodeGPUCounterSample(MVKGPUCounterQueryPool* mvkQryPool, uint32_t sampleIndex, MVKCounterSamplingFlags samplingPoints); + void encodeCommandsImpl(MVKCommand *command); + void encodeGPUCounterSample(MVKGPUCounterQueryPool *mvkQryPool, uint32_t sampleIndex, MVKCounterSamplingFlags samplingPoints); void encodeTimestampStageCounterSamples(); id getStageCountersMTLFence(); - NSString* getMTLRenderCommandEncoderName(MVKCommandUse cmdUse); - template void retainIfImmediatelyEncoding(T& mtlEnc); - template void endMetalEncoding(T& mtlEnc); - - typedef struct GPUCounterQuery { - MVKGPUCounterQueryPool* queryPool = nullptr; + NSString *getMTLRenderCommandEncoderName(MVKCommandUse cmdUse); + template + void retainIfImmediatelyEncoding(T &mtlEnc); + template + void endMetalEncoding(T &mtlEnc); + + typedef struct GPUCounterQuery + { + MVKGPUCounterQueryPool *queryPool = nullptr; uint32_t query = 0; } GPUCounterQuery; VkRect2D _renderArea; - MVKCommand* _lastMultiviewPassCmd; - MVKActivatedQueries* _pActivatedQueries; + MVKCommand *_lastMultiviewPassCmd; + MVKActivatedQueries *_pActivatedQueries; MVKSmallVector _timestampStageCounterQueries; MVKSmallVector _clearValues; - MVKSmallVector _attachments; + MVKSmallVector _attachments; id _mtlComputeEncoder; id _mtlBlitEncoder; id _stageCountersMTLFence; @@ -511,21 +514,20 @@ class MVKCommandEncoder : public MVKBaseDeviceObject { VkSubpassContents _subpassContents; uint32_t _renderSubpassIndex; uint32_t _multiviewPassIndex; - uint32_t _flushCount; + uint32_t _flushCount; MVKCommandUse _mtlComputeEncoderUse; MVKCommandUse _mtlBlitEncoderUse; bool _isRenderingEntireAttachment; }; - #pragma mark - #pragma mark Support functions /** Returns a name, suitable for use as a MTLRenderCommandEncoder label, based on the MVKCommandUse. */ -NSString* mvkMTLRenderCommandEncoderLabel(MVKCommandUse cmdUse); +NSString *mvkMTLRenderCommandEncoderLabel(MVKCommandUse cmdUse); /** Returns a name, suitable for use as a MTLBlitCommandEncoder label, based on the MVKCommandUse. */ -NSString* mvkMTLBlitCommandEncoderLabel(MVKCommandUse cmdUse); +NSString *mvkMTLBlitCommandEncoderLabel(MVKCommandUse cmdUse); /** Returns a name, suitable for use as a MTLComputeCommandEncoder label, based on the MVKCommandUse. */ -NSString* mvkMTLComputeCommandEncoderLabel(MVKCommandUse cmdUse); +NSString *mvkMTLComputeCommandEncoderLabel(MVKCommandUse cmdUse); diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm index 44f0204e1..8c225fd6a 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm @@ -592,6 +592,7 @@ if ( !isRestart && !_isRenderingEntireAttachment ) { clearRenderArea(cmdUse); } _graphicsPipelineState.beginMetalRenderPass(); + _lineWidthState.beginMetalRenderPass(); _graphicsResourcesState.beginMetalRenderPass(); _depthStencilState.beginMetalRenderPass(); _renderingState.beginMetalRenderPass(); @@ -710,6 +711,7 @@ encodeStoreActions(true); } _graphicsPipelineState.encode(stage); // Must do first..it sets others + _lineWidthState.encode(stage); _graphicsResourcesState.encode(stage); // Before push constants, to allow them to override. _depthStencilState.encode(stage); _renderingState.encode(stage); @@ -804,6 +806,7 @@ getSubpass()->resolveUnresolvableAttachments(this, _attachments.contents()); _graphicsPipelineState.endMetalRenderPass(); + _lineWidthState.endMetalRenderPass(); _graphicsResourcesState.endMetalRenderPass(); _depthStencilState.endMetalRenderPass(); _renderingState.endMetalRenderPass(); @@ -1139,6 +1142,7 @@ MVKPrefillMetalCommandBuffersStyle prefillStyle) : MVKBaseDeviceObject(cmdBuffer->getDevice()), _cmdBuffer(cmdBuffer), _graphicsPipelineState(this), + _lineWidthState(this), _graphicsResourcesState(this), _computePipelineState(this), _computeResourcesState(this), diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h index 4ac895d43..6ca692e90 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h +++ b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h @@ -6,9 +6,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -34,152 +34,171 @@ class MVKOcclusionQueryPool; struct MVKShaderImplicitRezBinding; - #pragma mark - #pragma mark MVKCommandEncoderState -/** +/** * Abstract class that holds encoder state established by Vulkan commands. * - * Some Vulkan commands can be issued both inside or outside a render pass, and the state - * encoded by the command needs to be retained by the encoder for use by following render + * Some Vulkan commands can be issued both inside or outside a render pass, and the state + * encoded by the command needs to be retained by the encoder for use by following render * passes. In addition, some Vulkan commands can be issued multiple times to accumulate * encoded content that should be submitted in one shot to the Metal encoder. */ -class MVKCommandEncoderState : public MVKBaseObject { +class MVKCommandEncoderState : public MVKBaseObject +{ public: - /** Returns the Vulkan API opaque object controlling this object. */ - MVKVulkanAPIObject* getVulkanAPIObject() override; - - /** - * Marks the content of this instance as dirty, relative to the - * current or next Metal render pass, and in need of submission to Metal. - */ - virtual void markDirty() { - _isDirty = true; - _isModified = true; - } - - /** - * Called automatically when a Metal render pass begins. If the contents have been - * modified from the default values, this instance is marked as dirty, so the contents - * will be encoded to Metal. Default state can be left unencoded on a new Metal encoder. - */ - virtual void beginMetalRenderPass() { if (_isModified) { markDirty(); } } + MVKVulkanAPIObject *getVulkanAPIObject() override; + + /** + * Marks the content of this instance as dirty, relative to the + * current or next Metal render pass, and in need of submission to Metal. + */ + virtual void markDirty() + { + _isDirty = true; + _isModified = true; + } + + /** + * Called automatically when a Metal render pass begins. If the contents have been + * modified from the default values, this instance is marked as dirty, so the contents + * will be encoded to Metal. Default state can be left unencoded on a new Metal encoder. + */ + virtual void beginMetalRenderPass() + { + if (_isModified) + { + markDirty(); + } + } /** Called automatically when a Metal render pass ends. */ - virtual void endMetalRenderPass() { } + virtual void endMetalRenderPass() {} /** * Called automatically when a Metal compute pass begins. If the contents have been * modified from the default values, this instance is marked as dirty, so the contents * will be encoded to Metal. Default state can be left unencoded on a new Metal encoder. */ - virtual void beginMetalComputeEncoding() { if (_isModified) { markDirty(); } } + virtual void beginMetalComputeEncoding() + { + if (_isModified) + { + markDirty(); + } + } - /** - * If the content of this instance is dirty, marks this instance as no longer dirty - * and calls the encodeImpl() function to encode the content onto the Metal encoder. + /** + * If the content of this instance is dirty, marks this instance as no longer dirty + * and calls the encodeImpl() function to encode the content onto the Metal encoder. * Marking clean is done in advance so that subclass encodeImpl() implementations * can override to leave this instance in a dirty state. - * Subclasses must override the encodeImpl() function to do the actual work. - */ - void encode(uint32_t stage = 0) { - if ( !_isDirty ) { return; } + * Subclasses must override the encodeImpl() function to do the actual work. + */ + void encode(uint32_t stage = 0) + { + if (!_isDirty) + { + return; + } - _isDirty = false; - encodeImpl(stage); - } + _isDirty = false; + encodeImpl(stage); + } /** Constructs this instance for the specified command encoder. */ - MVKCommandEncoderState(MVKCommandEncoder* cmdEncoder) : _cmdEncoder(cmdEncoder) {} + MVKCommandEncoderState(MVKCommandEncoder *cmdEncoder) : _cmdEncoder(cmdEncoder) {} protected: - enum StateScope { + enum StateScope + { Static = 0, Dynamic, Count }; virtual void encodeImpl(uint32_t stage) = 0; - MVKDevice* getDevice(); + MVKDevice *getDevice(); bool isDynamicState(MVKRenderStateType state); - template T& getContent(T* iVarAry, bool isDynamic) { + template + T &getContent(T *iVarAry, bool isDynamic) + { return iVarAry[isDynamic ? StateScope::Dynamic : StateScope::Static]; } - template T& getContent(T* iVarAry, MVKRenderStateType state) { + template + T &getContent(T *iVarAry, MVKRenderStateType state) + { return getContent(iVarAry, isDynamicState(state)); } - MVKCommandEncoder* _cmdEncoder; + MVKCommandEncoder *_cmdEncoder; bool _isDirty = false; - bool _isModified = false; + bool _isModified = false; }; - #pragma mark - #pragma mark MVKPipelineCommandEncoderState /** Abstract class to hold encoder state established by pipeline commands. */ -class MVKPipelineCommandEncoderState : public MVKCommandEncoderState { +class MVKPipelineCommandEncoderState : public MVKCommandEncoderState +{ public: - void bindPipeline(MVKPipeline* pipeline); + void bindPipeline(MVKPipeline *pipeline); - MVKPipeline* getPipeline(); - MVKGraphicsPipeline* getGraphicsPipeline() { return (MVKGraphicsPipeline*)getPipeline(); } - MVKComputePipeline* getComputePipeline() { return (MVKComputePipeline*)getPipeline(); } + MVKPipeline *getPipeline(); + MVKGraphicsPipeline *getGraphicsPipeline() { return (MVKGraphicsPipeline *)getPipeline(); } + MVKComputePipeline *getComputePipeline() { return (MVKComputePipeline *)getPipeline(); } - MVKPipelineCommandEncoderState(MVKCommandEncoder* cmdEncoder) : MVKCommandEncoderState(cmdEncoder) {} + MVKPipelineCommandEncoderState(MVKCommandEncoder *cmdEncoder) : MVKCommandEncoderState(cmdEncoder) {} protected: - void encodeImpl(uint32_t stage) override; + void encodeImpl(uint32_t stage) override; - MVKPipeline* _pipeline = nullptr; + MVKPipeline *_pipeline = nullptr; }; - #pragma mark - #pragma mark MVKPushConstantsCommandEncoderState /** Holds encoder state established by push constant commands for a single shader stage. */ -class MVKPushConstantsCommandEncoderState : public MVKCommandEncoderState { +class MVKPushConstantsCommandEncoderState : public MVKCommandEncoderState +{ public: + /** Sets the specified push constants. */ + void setPushConstants(uint32_t offset, MVKArrayRef pushConstants); - /** Sets the specified push constants. */ - void setPushConstants(uint32_t offset, MVKArrayRef pushConstants); - - /** Sets the index of the Metal buffer used to hold the push constants. */ - void setMTLBufferIndex(uint32_t mtlBufferIndex, bool pipelineStageUsesPushConstants); + /** Sets the index of the Metal buffer used to hold the push constants. */ + void setMTLBufferIndex(uint32_t mtlBufferIndex, bool pipelineStageUsesPushConstants); - MVKPushConstantsCommandEncoderState(MVKCommandEncoder* cmdEncoder, - VkShaderStageFlagBits shaderStage) - : MVKCommandEncoderState(cmdEncoder), _shaderStage(shaderStage) {} + MVKPushConstantsCommandEncoderState(MVKCommandEncoder *cmdEncoder, + VkShaderStageFlagBits shaderStage) + : MVKCommandEncoderState(cmdEncoder), _shaderStage(shaderStage) {} protected: - void encodeImpl(uint32_t stage) override; + void encodeImpl(uint32_t stage) override; bool isTessellating(); - MVKSmallVector _pushConstants; - VkShaderStageFlagBits _shaderStage; - uint32_t _mtlBufferIndex = 0; + MVKSmallVector _pushConstants; + VkShaderStageFlagBits _shaderStage; + uint32_t _mtlBufferIndex = 0; bool _pipelineStageUsesPushConstants = false; }; - #pragma mark - #pragma mark MVKDepthStencilCommandEncoderState /** Holds encoder state established by depth stencil commands. */ -class MVKDepthStencilCommandEncoderState : public MVKCommandEncoderState { +class MVKDepthStencilCommandEncoderState : public MVKCommandEncoderState +{ public: - - /** Sets the depth stencil state during pipeline binding. */ - void setDepthStencilState(const VkPipelineDepthStencilStateCreateInfo& vkDepthStencilInfo); + /** Sets the depth stencil state during pipeline binding. */ + void setDepthStencilState(const VkPipelineDepthStencilStateCreateInfo &vkDepthStencilInfo); /** Enables or disables depth testing, from explicit dynamic command. */ void setDepthTestEnable(VkBool32 depthTestEnable); @@ -200,29 +219,32 @@ class MVKDepthStencilCommandEncoderState : public MVKCommandEncoderState { VkStencilOp depthFailOp, VkCompareOp compareOp); - /** Sets the stencil compare mask value of the indicated faces from explicit dynamic command. */ - void setStencilCompareMask(VkStencilFaceFlags faceMask, uint32_t stencilCompareMask); + /** Sets the stencil compare mask value of the indicated faces from explicit dynamic command. */ + void setStencilCompareMask(VkStencilFaceFlags faceMask, uint32_t stencilCompareMask); - /** Sets the stencil write mask value of the indicated faces from explicit dynamic command. */ - void setStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t stencilWriteMask); + /** Sets the stencil write mask value of the indicated faces from explicit dynamic command. */ + void setStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t stencilWriteMask); void beginMetalRenderPass() override; - /** Constructs this instance for the specified command encoder. */ - MVKDepthStencilCommandEncoderState(MVKCommandEncoder* cmdEncoder) - : MVKCommandEncoderState(cmdEncoder) {} + /** Constructs this instance for the specified command encoder. */ + MVKDepthStencilCommandEncoderState(MVKCommandEncoder *cmdEncoder) + : MVKCommandEncoderState(cmdEncoder) {} protected: - void encodeImpl(uint32_t stage) override; - MVKMTLDepthStencilDescriptorData& getData(MVKRenderStateType state) { return getContent(_depthStencilData, state); } - template void setContent(T& content, T value) { - if (content != value) { + void encodeImpl(uint32_t stage) override; + MVKMTLDepthStencilDescriptorData &getData(MVKRenderStateType state) { return getContent(_depthStencilData, state); } + template + void setContent(T &content, T value) + { + if (content != value) + { content = value; markDirty(); } } - void setStencilState(MVKMTLStencilDescriptorData& sData, const VkStencilOpState& vkStencil); - void setStencilOp(MVKMTLStencilDescriptorData& sData, VkStencilOp failOp, + void setStencilState(MVKMTLStencilDescriptorData &sData, const VkStencilOpState &vkStencil); + void setStencilOp(MVKMTLStencilDescriptorData &sData, VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp, VkCompareOp compareOp); MVKMTLDepthStencilDescriptorData _depthStencilData[StateScope::Count]; @@ -231,33 +253,37 @@ class MVKDepthStencilCommandEncoderState : public MVKCommandEncoderState { bool _hasStencilAttachment = false; }; - #pragma mark - #pragma mark MVKRenderingCommandEncoderState -struct MVKDepthBias { +struct MVKDepthBias +{ float depthBiasConstantFactor; float depthBiasSlopeFactor; float depthBiasClamp; }; -struct MVKStencilReference { +struct MVKStencilReference +{ uint32_t frontFaceValue; uint32_t backFaceValue; }; -struct MVKMTLViewports { +struct MVKMTLViewports +{ MTLViewport viewports[kMVKMaxViewportScissorCount]; uint32_t viewportCount; }; -struct MVKMTLScissors { +struct MVKMTLScissors +{ MTLScissorRect scissors[kMVKMaxViewportScissorCount]; uint32_t scissorCount; }; /** Holds encoder state established by various rendering state commands. */ -class MVKRenderingCommandEncoderState : public MVKCommandEncoderState { +class MVKRenderingCommandEncoderState : public MVKCommandEncoderState +{ public: void setCullMode(VkCullModeFlags cullMode, bool isDynamic); @@ -267,12 +293,12 @@ class MVKRenderingCommandEncoderState : public MVKCommandEncoderState { void setBlendConstants(float blendConstants[4], bool isDynamic); - void setDepthBias(const VkPipelineRasterizationStateCreateInfo& vkRasterInfo); + void setDepthBias(const VkPipelineRasterizationStateCreateInfo &vkRasterInfo); void setDepthBias(float depthBiasConstantFactor, float depthBiasSlopeFactor, float depthBiasClamp); void setDepthBiasEnable(VkBool32 depthBiasEnable); void setDepthClipEnable(bool depthClip, bool isDynamic); - void setStencilReferenceValues(const VkPipelineDepthStencilStateCreateInfo& vkDepthStencilInfo); + void setStencilReferenceValues(const VkPipelineDepthStencilStateCreateInfo &vkDepthStencilInfo); void setStencilReferenceValues(VkStencilFaceFlags faceMask, uint32_t stencilReference); void setViewports(const MVKArrayRef viewports, uint32_t firstViewport, bool isDynamic); @@ -298,18 +324,21 @@ class MVKRenderingCommandEncoderState : public MVKCommandEncoderState { bool isDirty(MVKRenderStateType state); void markDirty() override; - MVKRenderingCommandEncoderState(MVKCommandEncoder* cmdEncoder) : MVKCommandEncoderState(cmdEncoder) {} + MVKRenderingCommandEncoderState(MVKCommandEncoder *cmdEncoder) : MVKCommandEncoderState(cmdEncoder) {} protected: void encodeImpl(uint32_t stage) override; bool isDrawingTriangles(); - template void setContent(T* iVarAry, T* pVal, MVKRenderStateType state, bool isDynamic) { - auto* pIVar = &iVarAry[isDynamic ? StateScope::Dynamic : StateScope::Static]; - if( !mvkAreEqual(pVal, pIVar) ) { + template + void setContent(T *iVarAry, T *pVal, MVKRenderStateType state, bool isDynamic) + { + auto *pIVar = &iVarAry[isDynamic ? StateScope::Dynamic : StateScope::Static]; + if (!mvkAreEqual(pVal, pIVar)) + { *pIVar = *pVal; _dirtyStates.enable(state); _modifiedStates.enable(state); - MVKCommandEncoderState::markDirty(); // Avoid local markDirty() as it marks all states dirty. + MVKCommandEncoderState::markDirty(); // Avoid local markDirty() as it marks all states dirty. } } @@ -319,11 +348,11 @@ class MVKRenderingCommandEncoderState : public MVKCommandEncoderState { MVKColor32 _mtlBlendConstants[StateScope::Count] = {}; MVKDepthBias _mtlDepthBias[StateScope::Count] = {}; MVKStencilReference _mtlStencilReference[StateScope::Count] = {}; - MTLCullMode _mtlCullMode[StateScope::Count] = { MTLCullModeNone, MTLCullModeNone }; - MTLWinding _mtlFrontFace[StateScope::Count] = { MTLWindingClockwise, MTLWindingClockwise }; - MTLPrimitiveType _mtlPrimitiveTopology[StateScope::Count] = { MTLPrimitiveTypePoint, MTLPrimitiveTypePoint }; - MTLDepthClipMode _mtlDepthClipEnable[StateScope::Count] = { MTLDepthClipModeClip, MTLDepthClipModeClip }; - MTLTriangleFillMode _mtlPolygonMode[StateScope::Count] = { MTLTriangleFillModeFill, MTLTriangleFillModeFill }; + MTLCullMode _mtlCullMode[StateScope::Count] = {MTLCullModeNone, MTLCullModeNone}; + MTLWinding _mtlFrontFace[StateScope::Count] = {MTLWindingClockwise, MTLWindingClockwise}; + MTLPrimitiveType _mtlPrimitiveTopology[StateScope::Count] = {MTLPrimitiveTypePoint, MTLPrimitiveTypePoint}; + MTLDepthClipMode _mtlDepthClipEnable[StateScope::Count] = {MTLDepthClipModeClip, MTLDepthClipModeClip}; + MTLTriangleFillMode _mtlPolygonMode[StateScope::Count] = {MTLTriangleFillModeFill, MTLTriangleFillModeFill}; uint32_t _mtlPatchControlPoints[StateScope::Count] = {}; MVKRenderStateFlags _dirtyStates; MVKRenderStateFlags _modifiedStates; @@ -334,24 +363,41 @@ class MVKRenderingCommandEncoderState : public MVKCommandEncoderState { bool _cullBothFaces[StateScope::Count] = {}; }; +#pragma mark - +#pragma mark MVKLineWidthCommandEncoderState + +/** Holds encoder state established by line width commands. */ +class MVKLineWidthCommandEncoderState : public MVKCommandEncoderState +{ +public: + /** Sets the line width, either as part of pipeline binding, or dynamically. */ + void setLineWidth(float lineWidth, bool isDynamic); + + /** Constructs this instance for the specified command encoder. */ + MVKLineWidthCommandEncoderState(MVKCommandEncoder *cmdEncoder) : MVKCommandEncoderState(cmdEncoder) {} + +protected: + void encodeImpl(uint32_t stage) override; + + float _lineWidth = 1.0f; +}; #pragma mark - #pragma mark MVKResourcesCommandEncoderState /** Abstract resource state class for supporting encoder resources. */ -class MVKResourcesCommandEncoderState : public MVKCommandEncoderState { +class MVKResourcesCommandEncoderState : public MVKCommandEncoderState +{ public: - /** Returns the currently bound pipeline for this bind point. */ - virtual MVKPipeline* getPipeline() = 0; + virtual MVKPipeline *getPipeline() = 0; /** Binds the specified descriptor set to the specified index. */ void bindDescriptorSet(uint32_t descSetIndex, - MVKDescriptorSet* descSet, - MVKShaderResourceBinding& dslMTLRezIdxOffsets, + MVKDescriptorSet *descSet, + MVKShaderResourceBinding &dslMTLRezIdxOffsets, MVKArrayRef dynamicOffsets, - uint32_t& dynamicOffsetIndex); + uint32_t &dynamicOffsetIndex); /** Encodes the indirect use of the Metal resource to the Metal command encoder. */ virtual void encodeResourceUsage(MVKShaderStage stage, @@ -361,23 +407,28 @@ class MVKResourcesCommandEncoderState : public MVKCommandEncoderState { void markDirty() override; - MVKResourcesCommandEncoderState(MVKCommandEncoder* cmdEncoder) : - MVKCommandEncoderState(cmdEncoder), _boundDescriptorSets{} {} + MVKResourcesCommandEncoderState(MVKCommandEncoder *cmdEncoder) : MVKCommandEncoderState(cmdEncoder), _boundDescriptorSets{} {} protected: - - // Template function that marks both the vector and all binding elements in the vector as dirty. - template - void markDirty(T& bindings, bool& bindingsDirtyFlag) { - for (auto& b : bindings) { b.markDirty(); } - bindingsDirtyFlag = true; - } + // Template function that marks both the vector and all binding elements in the vector as dirty. + template + void markDirty(T &bindings, bool &bindingsDirtyFlag) + { + for (auto &b : bindings) + { + b.markDirty(); + } + bindingsDirtyFlag = true; + } // Template function to find and mark as overridden the binding that uses the index. - template - void markBufferIndexOverridden(T& bufferBindings, uint32_t index) { - for (auto& b : bufferBindings) { - if (b.index == index) { + template + void markBufferIndexOverridden(T &bufferBindings, uint32_t index) + { + for (auto &b : bufferBindings) + { + if (b.index == index) + { b.isOverridden = true; return; } @@ -385,10 +436,13 @@ class MVKResourcesCommandEncoderState : public MVKCommandEncoderState { } // Template function to mark any overridden bindings as dirty. - template - void markOverriddenBufferIndexesDirty(T& bufferBindings, bool& bindingsDirtyFlag) { - for (auto& b : bufferBindings) { - if (b.isOverridden) { + template + void markOverriddenBufferIndexesDirty(T &bufferBindings, bool &bindingsDirtyFlag) + { + for (auto &b : bufferBindings) + { + if (b.isOverridden) + { b.markDirty(); bindingsDirtyFlag = true; MVKCommandEncoderState::markDirty(); @@ -396,69 +450,92 @@ class MVKResourcesCommandEncoderState : public MVKCommandEncoderState { } } - // Template function that updates an existing binding or adds a new binding to a vector - // of bindings, and marks the binding, the vector, and this instance as dirty - template - void bind(const T& b, V& bindings, bool& bindingsDirtyFlag) { - if ( !b.mtlResource ) { return; } + // Template function that updates an existing binding or adds a new binding to a vector + // of bindings, and marks the binding, the vector, and this instance as dirty + template + void bind(const T &b, V &bindings, bool &bindingsDirtyFlag) + { + if (!b.mtlResource) + { + return; + } - for (auto& rb : bindings) { - if (rb.index == b.index) { - rb.update(b); - if (rb.isDirty) { + for (auto &rb : bindings) + { + if (rb.index == b.index) + { + rb.update(b); + if (rb.isDirty) + { bindingsDirtyFlag = true; MVKCommandEncoderState::markDirty(); } - return; - } - } + return; + } + } - bindings.push_back(b); - bindings.back().markDirty(); + bindings.push_back(b); + bindings.back().markDirty(); bindingsDirtyFlag = true; MVKCommandEncoderState::markDirty(); - } + } // For texture bindings, we also keep track of whether any bindings need a texture swizzle - template - void bind(const MVKMTLTextureBinding& tb, V& texBindings, bool& bindingsDirtyFlag, bool& needsSwizzleFlag) { + template + void bind(const MVKMTLTextureBinding &tb, V &texBindings, bool &bindingsDirtyFlag, bool &needsSwizzleFlag) + { bind(tb, texBindings, bindingsDirtyFlag); - if (tb.swizzle != 0) { needsSwizzleFlag = true; } + if (tb.swizzle != 0) + { + needsSwizzleFlag = true; + } } - // Template function that executes a lambda expression on each dirty element of - // a vector of bindings, and marks the bindings and the vector as no longer dirty. + // Template function that executes a lambda expression on each dirty element of + // a vector of bindings, and marks the bindings and the vector as no longer dirty. // Clear binding isDirty flag before operation to allow operation to possibly override. // If it does override, leave both the bindings and this instance as dirty. - template - void encodeBinding(V& bindings, - bool& bindingsDirtyFlag, - std::function mtlOperation) { - if (bindingsDirtyFlag) { + template + void encodeBinding(V &bindings, + bool &bindingsDirtyFlag, + std::function mtlOperation) + { + if (bindingsDirtyFlag) + { bindingsDirtyFlag = false; - for (auto& b : bindings) { - if (b.isDirty) { + for (auto &b : bindings) + { + if (b.isDirty) + { b.isDirty = false; mtlOperation(_cmdEncoder, b); - if (b.isDirty) { _isDirty = bindingsDirtyFlag = true; } + if (b.isDirty) + { + _isDirty = bindingsDirtyFlag = true; + } } } } } // Updates a value at the given index in the given vector, resizing if needed. - template - void updateImplicitBuffer(V &contents, uint32_t index, uint32_t value) { - if (index >= contents.size()) { contents.resize(index + 1); } + template + void updateImplicitBuffer(V &contents, uint32_t index, uint32_t value) + { + if (index >= contents.size()) + { + contents.resize(index + 1); + } contents[index] = value; } - void assertMissingSwizzles(bool needsSwizzle, const char* stageName, MVKArrayRef texBindings); + void assertMissingSwizzles(bool needsSwizzle, const char *stageName, MVKArrayRef texBindings); void encodeMetalArgumentBuffer(MVKShaderStage stage); - virtual void bindMetalArgumentBuffer(MVKShaderStage stage, MVKMTLBufferBinding& buffBind) = 0; + virtual void bindMetalArgumentBuffer(MVKShaderStage stage, MVKMTLBufferBinding &buffBind) = 0; - template - struct ResourceBindings { + template + struct ResourceBindings + { MVKSmallVector bufferBindings; MVKSmallVector textureBindings; MVKSmallVector samplerStateBindings; @@ -477,75 +554,74 @@ class MVKResourcesCommandEncoderState : public MVKCommandEncoderState { bool needsSwizzle = false; }; - MVKDescriptorSet* _boundDescriptorSets[kMVKMaxDescriptorSetCount]; + MVKDescriptorSet *_boundDescriptorSets[kMVKMaxDescriptorSetCount]; MVKBitArray _metalUsageDirtyDescriptors[kMVKMaxDescriptorSetCount]; MVKSmallVector _dynamicOffsets; - }; - #pragma mark - #pragma mark MVKGraphicsResourcesCommandEncoderState /** Holds graphics encoder resource state established by bind vertex buffer and descriptor set commands. */ -class MVKGraphicsResourcesCommandEncoderState : public MVKResourcesCommandEncoderState { +class MVKGraphicsResourcesCommandEncoderState : public MVKResourcesCommandEncoderState +{ public: - /** Returns the currently bound pipeline for this bind point. */ - MVKPipeline* getPipeline() override; + MVKPipeline *getPipeline() override; - /** Binds the specified buffer for the specified shader stage. */ - void bindBuffer(MVKShaderStage stage, const MVKMTLBufferBinding& binding); + /** Binds the specified buffer for the specified shader stage. */ + void bindBuffer(MVKShaderStage stage, const MVKMTLBufferBinding &binding); - /** Binds the specified texture for the specified shader stage. */ - void bindTexture(MVKShaderStage stage, const MVKMTLTextureBinding& binding); + /** Binds the specified texture for the specified shader stage. */ + void bindTexture(MVKShaderStage stage, const MVKMTLTextureBinding &binding); - /** Binds the specified sampler state for the specified shader stage. */ - void bindSamplerState(MVKShaderStage stage, const MVKMTLSamplerStateBinding& binding); + /** Binds the specified sampler state for the specified shader stage. */ + void bindSamplerState(MVKShaderStage stage, const MVKMTLSamplerStateBinding &binding); - /** The type of index that will be used to render primitives. Exposed directly. */ - MVKIndexMTLBufferBinding _mtlIndexBufferBinding; + /** The type of index that will be used to render primitives. Exposed directly. */ + MVKIndexMTLBufferBinding _mtlIndexBufferBinding; - /** Binds the specified index buffer. */ - void bindIndexBuffer(const MVKIndexMTLBufferBinding& binding) { - _mtlIndexBufferBinding = binding; // No need to track dirty state - } + /** Binds the specified index buffer. */ + void bindIndexBuffer(const MVKIndexMTLBufferBinding &binding) + { + _mtlIndexBufferBinding = binding; // No need to track dirty state + } - /** Sets the current swizzle buffer state. */ - void bindSwizzleBuffer(const MVKShaderImplicitRezBinding& binding, - bool needVertexSwizzleBuffer, - bool needTessCtlSwizzleBuffer, - bool needTessEvalSwizzleBuffer, - bool needFragmentSwizzleBuffer); + /** Sets the current swizzle buffer state. */ + void bindSwizzleBuffer(const MVKShaderImplicitRezBinding &binding, + bool needVertexSwizzleBuffer, + bool needTessCtlSwizzleBuffer, + bool needTessEvalSwizzleBuffer, + bool needFragmentSwizzleBuffer); - /** Sets the current buffer size buffer state. */ - void bindBufferSizeBuffer(const MVKShaderImplicitRezBinding& binding, - bool needVertexSizeBuffer, - bool needTessCtlSizeBuffer, - bool needTessEvalSizeBuffer, - bool needFragmentSizeBuffer); + /** Sets the current buffer size buffer state. */ + void bindBufferSizeBuffer(const MVKShaderImplicitRezBinding &binding, + bool needVertexSizeBuffer, + bool needTessCtlSizeBuffer, + bool needTessEvalSizeBuffer, + bool needFragmentSizeBuffer); /** Sets the current dynamic offset buffer state. */ - void bindDynamicOffsetBuffer(const MVKShaderImplicitRezBinding& binding, + void bindDynamicOffsetBuffer(const MVKShaderImplicitRezBinding &binding, bool needVertexDynanicOffsetBuffer, bool needTessCtlDynanicOffsetBuffer, bool needTessEvalDynanicOffsetBuffer, bool needFragmentDynanicOffsetBuffer); - /** Sets the current view range buffer state. */ - void bindViewRangeBuffer(const MVKShaderImplicitRezBinding& binding, - bool needVertexViewBuffer, - bool needFragmentViewBuffer); + /** Sets the current view range buffer state. */ + void bindViewRangeBuffer(const MVKShaderImplicitRezBinding &binding, + bool needVertexViewBuffer, + bool needFragmentViewBuffer); - void encodeBindings(MVKShaderStage stage, - const char* pStageName, - bool fullImageViewSwizzle, - std::function bindBuffer, - std::function)> bindImplicitBuffer, - std::function bindTexture, - std::function bindSampler); + void encodeBindings(MVKShaderStage stage, + const char *pStageName, + bool fullImageViewSwizzle, + std::function bindBuffer, + std::function)> bindImplicitBuffer, + std::function bindTexture, + std::function bindSampler); void encodeResourceUsage(MVKShaderStage stage, id mtlResource, @@ -553,7 +629,7 @@ class MVKGraphicsResourcesCommandEncoderState : public MVKResourcesCommandEncode MTLRenderStages mtlStages) override; /** Offset all buffers for vertex attribute bindings with zero divisors by the given number of strides. */ - void offsetZeroDivisorVertexBuffers(MVKGraphicsStage stage, MVKGraphicsPipeline* pipeline, uint32_t firstInstance); + void offsetZeroDivisorVertexBuffers(MVKGraphicsStage stage, MVKGraphicsPipeline *pipeline, uint32_t firstInstance); /** * Marks the buffer binding using the index as having been overridden, @@ -569,47 +645,46 @@ class MVKGraphicsResourcesCommandEncoderState : public MVKResourcesCommandEncode void markDirty() override; #pragma mark Construction - - /** Constructs this instance for the specified command encoder. */ - MVKGraphicsResourcesCommandEncoderState(MVKCommandEncoder* cmdEncoder) : MVKResourcesCommandEncoderState(cmdEncoder) {} + + /** Constructs this instance for the specified command encoder. */ + MVKGraphicsResourcesCommandEncoderState(MVKCommandEncoder *cmdEncoder) : MVKResourcesCommandEncoderState(cmdEncoder) {} protected: - void encodeImpl(uint32_t stage) override; - void bindMetalArgumentBuffer(MVKShaderStage stage, MVKMTLBufferBinding& buffBind) override; + void encodeImpl(uint32_t stage) override; + void bindMetalArgumentBuffer(MVKShaderStage stage, MVKMTLBufferBinding &buffBind) override; - ResourceBindings<8> _shaderStageResourceBindings[kMVKShaderStageFragment + 1]; + ResourceBindings<8> _shaderStageResourceBindings[kMVKShaderStageFragment + 1]; std::unordered_map, MTLRenderStages> _renderUsageStages; }; - #pragma mark - #pragma mark MVKComputeResourcesCommandEncoderState /** Holds compute encoder resource state established by bind vertex buffer and descriptor set commands. */ -class MVKComputeResourcesCommandEncoderState : public MVKResourcesCommandEncoderState { +class MVKComputeResourcesCommandEncoderState : public MVKResourcesCommandEncoderState +{ public: - /** Returns the currently bound pipeline for this bind point. */ - MVKPipeline* getPipeline() override; + MVKPipeline *getPipeline() override; - /** Binds the specified buffer. */ - void bindBuffer(const MVKMTLBufferBinding& binding); + /** Binds the specified buffer. */ + void bindBuffer(const MVKMTLBufferBinding &binding); - /** Binds the specified texture. */ - void bindTexture(const MVKMTLTextureBinding& binding); + /** Binds the specified texture. */ + void bindTexture(const MVKMTLTextureBinding &binding); - /** Binds the specified sampler state. */ - void bindSamplerState(const MVKMTLSamplerStateBinding& binding); + /** Binds the specified sampler state. */ + void bindSamplerState(const MVKMTLSamplerStateBinding &binding); - /** Sets the current swizzle buffer state. */ - void bindSwizzleBuffer(const MVKShaderImplicitRezBinding& binding, bool needSwizzleBuffer); + /** Sets the current swizzle buffer state. */ + void bindSwizzleBuffer(const MVKShaderImplicitRezBinding &binding, bool needSwizzleBuffer); - /** Sets the current buffer size buffer state. */ - void bindBufferSizeBuffer(const MVKShaderImplicitRezBinding& binding, bool needSizeBuffer); + /** Sets the current buffer size buffer state. */ + void bindBufferSizeBuffer(const MVKShaderImplicitRezBinding &binding, bool needSizeBuffer); /** Sets the current dynamic offset buffer state. */ - void bindDynamicOffsetBuffer(const MVKShaderImplicitRezBinding& binding, bool needDynamicOffsetBuffer); + void bindDynamicOffsetBuffer(const MVKShaderImplicitRezBinding &binding, bool needDynamicOffsetBuffer); void encodeResourceUsage(MVKShaderStage stage, id mtlResource, @@ -625,55 +700,53 @@ class MVKComputeResourcesCommandEncoderState : public MVKResourcesCommandEncoder /** Marks any overridden buffer indexes as dirty. */ void markOverriddenBufferIndexesDirty(); - void markDirty() override; + void markDirty() override; #pragma mark Construction - /** Constructs this instance for the specified command encoder. */ - MVKComputeResourcesCommandEncoderState(MVKCommandEncoder* cmdEncoder) : MVKResourcesCommandEncoderState(cmdEncoder) {} + /** Constructs this instance for the specified command encoder. */ + MVKComputeResourcesCommandEncoderState(MVKCommandEncoder *cmdEncoder) : MVKResourcesCommandEncoderState(cmdEncoder) {} protected: - void encodeImpl(uint32_t) override; - void bindMetalArgumentBuffer(MVKShaderStage stage, MVKMTLBufferBinding& buffBind) override; + void encodeImpl(uint32_t) override; + void bindMetalArgumentBuffer(MVKShaderStage stage, MVKMTLBufferBinding &buffBind) override; ResourceBindings<4> _resourceBindings; }; - #pragma mark - #pragma mark MVKOcclusionQueryCommandEncoderState /** Holds encoder state established by occlusion query commands. */ -class MVKOcclusionQueryCommandEncoderState : public MVKCommandEncoderState { +class MVKOcclusionQueryCommandEncoderState : public MVKCommandEncoderState +{ public: - void endMetalRenderPass() override; - /** Begins an occlusion query. */ - void beginOcclusionQuery(MVKOcclusionQueryPool* pQueryPool, uint32_t query, VkQueryControlFlags flags); + /** Begins an occlusion query. */ + void beginOcclusionQuery(MVKOcclusionQueryPool *pQueryPool, uint32_t query, VkQueryControlFlags flags); - /** Ends an occlusion query. */ - void endOcclusionQuery(MVKOcclusionQueryPool* pQueryPool, uint32_t query); + /** Ends an occlusion query. */ + void endOcclusionQuery(MVKOcclusionQueryPool *pQueryPool, uint32_t query); - MVKOcclusionQueryCommandEncoderState(MVKCommandEncoder* cmdEncoder) : MVKCommandEncoderState(cmdEncoder) {} + MVKOcclusionQueryCommandEncoderState(MVKCommandEncoder *cmdEncoder) : MVKCommandEncoderState(cmdEncoder) {} protected: - void encodeImpl(uint32_t) override; + void encodeImpl(uint32_t) override; - typedef struct OcclusionQueryLocation { - MVKOcclusionQueryPool* queryPool = nullptr; + typedef struct OcclusionQueryLocation + { + MVKOcclusionQueryPool *queryPool = nullptr; uint32_t query = 0; NSUInteger visibilityBufferOffset = 0; - OcclusionQueryLocation(MVKOcclusionQueryPool* qPool, uint32_t qIdx, NSUInteger vbOfst) - : queryPool(qPool), query(qIdx), visibilityBufferOffset(vbOfst) {} + OcclusionQueryLocation(MVKOcclusionQueryPool *qPool, uint32_t qIdx, NSUInteger vbOfst) + : queryPool(qPool), query(qIdx), visibilityBufferOffset(vbOfst) {} } OcclusionQueryLocation; MVKSmallVector _mtlRenderPassQueries; - MTLVisibilityResultMode _mtlVisibilityResultMode = MTLVisibilityResultModeDisabled; + MTLVisibilityResultMode _mtlVisibilityResultMode = MTLVisibilityResultModeDisabled; bool _hasRasterized = false; }; - - diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm index c7246a516..45d7e09d0 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm @@ -596,6 +596,33 @@ #undef setMTLContent +#pragma mark - +#pragma mark MVKLineWidthCommandEncoderState + +// An extension of the MTLRenderCommandEncoder protocol containing a declaration of the +// -setLineWidth: method. +@protocol MVKMTLRenderCommandEncoderLineWidth +-(void) setLineWidth:(float)width; +@end + +void MVKLineWidthCommandEncoderState::setLineWidth(float lineWidth, bool isDynamic) { + // Abort if dynamic allowed but call is not dynamic, or vice-versa + if (!(_cmdEncoder->_lineWidthState.isDynamicState(LineWidth) == isDynamic) ) { + return; + } + + _lineWidth = lineWidth; + markDirty(); +} + +void MVKLineWidthCommandEncoderState::encodeImpl(uint32_t stage) { + if (stage != kMVKGraphicsStageRasterization) { return; } + if (!_cmdEncoder->_pDeviceFeatures->wideLines) { return; } + if (![_cmdEncoder->_mtlRenderEncoder respondsToSelector: @selector(setLineWidth:)]) { return; } + [(id)_cmdEncoder->_mtlRenderEncoder setLineWidth: _lineWidth]; +} + + #pragma mark - #pragma mark MVKResourcesCommandEncoderState diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def b/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def index 6703a0bad..9e416ec96 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def +++ b/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def @@ -138,6 +138,7 @@ MVK_CMD_TYPE_POOL(DebugMarkerEnd) MVK_CMD_TYPE_POOL(DebugMarkerInsert) MVK_CMD_TYPE_POOLS_FROM_THRESHOLD(WaitEvents, 1) MVK_CMD_TYPE_POOL(SetEvent) +MVK_CMD_TYPE_POOL(SetLineWidth) MVK_CMD_TYPE_POOL_LAST(ResetEvent) #undef MVK_CMD_TYPE_POOL diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index af016e513..896d3ad8d 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -2271,6 +2271,7 @@ _features.depthBiasClamp = true; _features.fillModeNonSolid = true; _features.largePoints = true; + _features.wideLines = true; _features.alphaToOne = true; _features.samplerAnisotropy = true; _features.shaderImageGatherExtended = true; @@ -2687,8 +2688,8 @@ _properties.limits.pointSizeGranularity = 1; _properties.limits.lineWidthRange[0] = 1; - _properties.limits.lineWidthRange[1] = 1; - _properties.limits.lineWidthGranularity = 0; + _properties.limits.lineWidthRange[1] = 8; + _properties.limits.lineWidthGranularity = 0.125; _properties.limits.standardSampleLocations = VK_TRUE; _properties.limits.strictLines = _properties.vendorID == kIntelVendorId || _properties.vendorID == kNVVendorId; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm index c85ef684b..f06224d1b 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm @@ -308,6 +308,7 @@ cmdEncoder->_renderingState.setViewports(_viewports.contents(), 0, false); cmdEncoder->_renderingState.setScissors(_scissors.contents(), 0, false); if (_hasRasterInfo) { + cmdEncoder->_lineWidthState.setLineWidth(_rasterInfo.lineWidth, false); cmdEncoder->_renderingState.setCullMode(_rasterInfo.cullMode, false); cmdEncoder->_renderingState.setFrontFace(_rasterInfo.frontFace, false); cmdEncoder->_renderingState.setPolygonMode(_rasterInfo.polygonMode, false); diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index 293826a33..e399b8636 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -1466,6 +1466,7 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetLineWidth( float lineWidth) { MVKTraceVulkanCallStart(); + MVKAddCmd(SetLineWidth, commandBuffer, lineWidth); MVKTraceVulkanCallEnd(); }