| /* |
| * MVKPipeline.h |
| * |
| * Copyright (c) 2015-2020 The Brenwill Workshop Ltd. (http://www.brenwill.com) |
| * |
| * 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. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #pragma once |
| |
| #include "MVKDevice.h" |
| #include "MVKDescriptorSet.h" |
| #include "MVKShaderModule.h" |
| #include "MVKSync.h" |
| #include "MVKSmallVector.h" |
| #include <MoltenVKSPIRVToMSLConverter/SPIRVReflection.h> |
| #include <MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.h> |
| #include <unordered_map> |
| #include <unordered_set> |
| #include <ostream> |
| |
| #import <Metal/Metal.h> |
| |
| class MVKCommandEncoder; |
| class MVKPipelineCache; |
| |
| |
| #pragma mark - |
| #pragma mark MVKPipelineLayout |
| |
| struct MVKShaderImplicitRezBinding { |
| uint32_t stages[kMVKShaderStageMax]; |
| }; |
| |
| /** Represents a Vulkan pipeline layout. */ |
| class MVKPipelineLayout : public MVKVulkanAPIDeviceObject { |
| |
| public: |
| |
| /** Returns the Vulkan type of this object. */ |
| VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_PIPELINE_LAYOUT; } |
| |
| /** Returns the debug report object type of this object. */ |
| VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT; } |
| |
| /** Binds descriptor sets to a command encoder. */ |
| void bindDescriptorSets(MVKCommandEncoder* cmdEncoder, |
| MVKArrayRef<MVKDescriptorSet*> descriptorSets, |
| uint32_t firstSet, |
| MVKArrayRef<uint32_t> dynamicOffsets); |
| |
| /** Updates a descriptor set in a command encoder. */ |
| void pushDescriptorSet(MVKCommandEncoder* cmdEncoder, |
| MVKArrayRef<VkWriteDescriptorSet> descriptorWrites, |
| uint32_t set); |
| |
| /** Updates a descriptor set from a template in a command encoder. */ |
| void pushDescriptorSet(MVKCommandEncoder* cmdEncoder, |
| MVKDescriptorUpdateTemplate* descriptorUpdateTemplate, |
| uint32_t set, |
| const void* pData); |
| |
| /** Populates the specified shader converter context. */ |
| void populateShaderConverterContext(SPIRVToMSLConversionConfiguration& context); |
| |
| /** Returns the current swizzle buffer bindings. */ |
| const MVKShaderImplicitRezBinding& getSwizzleBufferIndex() { return _swizzleBufferIndex; } |
| |
| /** Returns the current buffer size buffer bindings. */ |
| const MVKShaderImplicitRezBinding& getBufferSizeBufferIndex() { return _bufferSizeBufferIndex; } |
| |
| /** Returns the current view range buffer binding for multiview draws. */ |
| const MVKShaderImplicitRezBinding& getViewRangeBufferIndex() { return _viewRangeBufferIndex; } |
| |
| /** Returns the current indirect parameter buffer bindings. */ |
| const MVKShaderImplicitRezBinding& getIndirectParamsIndex() { return _indirectParamsIndex; } |
| |
| /** Returns the current captured output buffer bindings. */ |
| const MVKShaderImplicitRezBinding& getOutputBufferIndex() { return _outputBufferIndex; } |
| |
| /** Returns the current captured per-patch output buffer binding for the tess. control shader. */ |
| uint32_t getTessCtlPatchOutputBufferIndex() { return _tessCtlPatchOutputBufferIndex; } |
| |
| /** Returns the current tessellation level buffer binding for the tess. control shader. */ |
| uint32_t getTessCtlLevelBufferIndex() { return _tessCtlLevelBufferIndex; } |
| |
| /** Returns the number of textures in this layout. This is used to calculate the size of the swizzle buffer. */ |
| uint32_t getTextureCount() { return _pushConstantsMTLResourceIndexes.getMaxTextureIndex(); } |
| |
| /** Returns the number of buffers in this layout. This is used to calculate the size of the buffer size buffer. */ |
| uint32_t getBufferCount() { return _pushConstantsMTLResourceIndexes.getMaxBufferIndex(); } |
| |
| /** Returns the push constant binding info. */ |
| const MVKShaderResourceBinding& getPushConstantBindings() { return _pushConstantsMTLResourceIndexes; } |
| |
| /** Constructs an instance for the specified device. */ |
| MVKPipelineLayout(MVKDevice* device, const VkPipelineLayoutCreateInfo* pCreateInfo); |
| |
| ~MVKPipelineLayout() override; |
| |
| protected: |
| void propagateDebugName() override {} |
| |
| MVKSmallVector<MVKDescriptorSetLayout*, 1> _descriptorSetLayouts; |
| MVKSmallVector<MVKShaderResourceBinding, 1> _dslMTLResourceIndexOffsets; |
| MVKSmallVector<VkPushConstantRange> _pushConstants; |
| MVKShaderResourceBinding _pushConstantsMTLResourceIndexes; |
| MVKShaderImplicitRezBinding _swizzleBufferIndex; |
| MVKShaderImplicitRezBinding _bufferSizeBufferIndex; |
| MVKShaderImplicitRezBinding _viewRangeBufferIndex; |
| MVKShaderImplicitRezBinding _indirectParamsIndex; |
| MVKShaderImplicitRezBinding _outputBufferIndex; |
| uint32_t _tessCtlPatchOutputBufferIndex = 0; |
| uint32_t _tessCtlLevelBufferIndex = 0; |
| }; |
| |
| |
| #pragma mark - |
| #pragma mark MVKPipeline |
| |
| static const uint32_t kMVKTessCtlInputBufferIndex = 30; |
| static const uint32_t kMVKTessCtlNumReservedBuffers = 1; |
| |
| static const uint32_t kMVKTessEvalInputBufferIndex = 30; |
| static const uint32_t kMVKTessEvalPatchInputBufferIndex = 29; |
| static const uint32_t kMVKTessEvalLevelBufferIndex = 28; |
| static const uint32_t kMVKTessEvalNumReservedBuffers = 3; |
| |
| /** Represents an abstract Vulkan pipeline. */ |
| class MVKPipeline : public MVKVulkanAPIDeviceObject { |
| |
| public: |
| |
| /** Returns the Vulkan type of this object. */ |
| VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_PIPELINE; } |
| |
| /** Returns the debug report object type of this object. */ |
| VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT; } |
| |
| /** Binds this pipeline to the specified command encoder. */ |
| virtual void encode(MVKCommandEncoder* cmdEncoder, uint32_t stage = 0) = 0; |
| |
| /** Binds the push constants to a command encoder. */ |
| void bindPushConstants(MVKCommandEncoder* cmdEncoder); |
| |
| /** Returns the current swizzle buffer bindings. */ |
| const MVKShaderImplicitRezBinding& getSwizzleBufferIndex() { return _swizzleBufferIndex; } |
| |
| /** Returns the current buffer size buffer bindings. */ |
| const MVKShaderImplicitRezBinding& getBufferSizeBufferIndex() { return _bufferSizeBufferIndex; } |
| |
| /** Returns the current indirect parameter buffer bindings. */ |
| const MVKShaderImplicitRezBinding& getIndirectParamsIndex() { return _indirectParamsIndex; } |
| |
| /** Returns whether or not full image view swizzling is enabled for this pipeline. */ |
| bool fullImageViewSwizzle() const { return _fullImageViewSwizzle; } |
| |
| /** Returns whether all internal Metal pipeline states are valid. */ |
| bool hasValidMTLPipelineStates() { return _hasValidMTLPipelineStates; } |
| |
| /** Constructs an instance for the device. layout, and parent (which may be NULL). */ |
| MVKPipeline(MVKDevice* device, MVKPipelineCache* pipelineCache, MVKPipelineLayout* layout, MVKPipeline* parent); |
| |
| protected: |
| void propagateDebugName() override {} |
| |
| MVKPipelineCache* _pipelineCache; |
| MVKShaderImplicitRezBinding _swizzleBufferIndex; |
| MVKShaderImplicitRezBinding _bufferSizeBufferIndex; |
| MVKShaderImplicitRezBinding _indirectParamsIndex; |
| MVKShaderResourceBinding _pushConstantsMTLResourceIndexes; |
| bool _fullImageViewSwizzle; |
| bool _hasValidMTLPipelineStates = true; |
| |
| }; |
| |
| |
| #pragma mark - |
| #pragma mark MVKGraphicsPipeline |
| |
| /** Describes a buffer binding to accommodate vertex attributes with offsets greater than the stride. */ |
| struct MVKTranslatedVertexBinding { |
| uint16_t binding; |
| uint16_t translationBinding; |
| uint32_t translationOffset; |
| }; |
| |
| typedef MVKSmallVector<MVKGraphicsStage, 4> MVKPiplineStages; |
| |
| /** The number of dynamic states possible in Vulkan. */ |
| static const uint32_t kMVKVkDynamicStateCount = 32; |
| |
| /** Represents an Vulkan graphics pipeline. */ |
| class MVKGraphicsPipeline : public MVKPipeline { |
| |
| public: |
| |
| /** Returns the number and order of stages in this pipeline. Draws commands must encode this pipeline once per stage. */ |
| void getStages(MVKPiplineStages& stages); |
| |
| /** Binds this pipeline to the specified command encoder. */ |
| void encode(MVKCommandEncoder* cmdEncoder, uint32_t stage = 0) override; |
| |
| /** Returns whether this pipeline permits dynamic setting of the specifie state. */ |
| bool supportsDynamicState(VkDynamicState state); |
| |
| /** Returns whether this pipeline has tessellation shaders. */ |
| bool isTessellationPipeline() { return _pTessCtlSS && _pTessEvalSS && _tessInfo.patchControlPoints > 0; } |
| |
| /** Returns the number of input tessellation patch control points. */ |
| uint32_t getInputControlPointCount() { return _tessInfo.patchControlPoints; } |
| |
| /** Returns the number of output tessellation patch control points. */ |
| uint32_t getOutputControlPointCount() { return _outputControlPointCount; } |
| |
| /** Returns the current captured output buffer bindings. */ |
| const MVKShaderImplicitRezBinding& getOutputBufferIndex() { return _outputBufferIndex; } |
| |
| /** Returns the current captured per-patch output buffer binding for the tess. control shader. */ |
| uint32_t getTessCtlPatchOutputBufferIndex() { return _tessCtlPatchOutputBufferIndex; } |
| |
| /** Returns the current tessellation level buffer binding for the tess. control shader. */ |
| uint32_t getTessCtlLevelBufferIndex() { return _tessCtlLevelBufferIndex; } |
| |
| /** Returns the MTLComputePipelineState object for the vertex stage of a tessellated draw with no indices. */ |
| id<MTLComputePipelineState> getTessVertexStageState(); |
| |
| /** Returns the MTLComputePipelineState object for the vertex stage of a tessellated draw with 16-bit indices. */ |
| id<MTLComputePipelineState> getTessVertexStageIndex16State(); |
| |
| /** Returns the MTLComputePipelineState object for the vertex stage of a tessellated draw with 32-bit indices. */ |
| id<MTLComputePipelineState> getTessVertexStageIndex32State(); |
| |
| /** Returns the MTLComputePipelineState object for the tessellation control stage of a tessellated draw. */ |
| id<MTLComputePipelineState> getTessControlStageState() { return _mtlTessControlStageState; } |
| |
| /** Returns true if the vertex shader needs a buffer to store its output. */ |
| bool needsVertexOutputBuffer() { return _needsVertexOutputBuffer; } |
| |
| /** Returns true if the tessellation control shader needs a buffer to store its per-vertex output. */ |
| bool needsTessCtlOutputBuffer() { return _needsTessCtlOutputBuffer; } |
| |
| /** Returns true if the tessellation control shader needs a buffer to store its per-patch output. */ |
| bool needsTessCtlPatchOutputBuffer() { return _needsTessCtlPatchOutputBuffer; } |
| |
| /** Returns the Metal vertex buffer index to use for the specified vertex attribute binding number. */ |
| uint32_t getMetalBufferIndexForVertexAttributeBinding(uint32_t binding) { return _device->getMetalBufferIndexForVertexAttributeBinding(binding); } |
| |
| /** Returns the collection of translated vertex bindings. */ |
| MVKArrayRef<MVKTranslatedVertexBinding> getTranslatedVertexBindings() { return _translatedVertexBindings.contents(); } |
| |
| /** Constructs an instance for the device and parent (which may be NULL). */ |
| MVKGraphicsPipeline(MVKDevice* device, |
| MVKPipelineCache* pipelineCache, |
| MVKPipeline* parent, |
| const VkGraphicsPipelineCreateInfo* pCreateInfo); |
| |
| ~MVKGraphicsPipeline() override; |
| |
| protected: |
| typedef MVKSmallVector<SPIRVShaderOutput, 32> SPIRVShaderOutputs; |
| |
| id<MTLRenderPipelineState> getOrCompilePipeline(MTLRenderPipelineDescriptor* plDesc, id<MTLRenderPipelineState>& plState); |
| id<MTLComputePipelineState> getOrCompilePipeline(MTLComputePipelineDescriptor* plDesc, id<MTLComputePipelineState>& plState, const char* compilerType); |
| void initMTLRenderPipelineState(const VkGraphicsPipelineCreateInfo* pCreateInfo, const SPIRVTessReflectionData& reflectData); |
| void initMVKShaderConverterContext(SPIRVToMSLConversionConfiguration& _shaderContext, const VkGraphicsPipelineCreateInfo* pCreateInfo, const SPIRVTessReflectionData& reflectData); |
| void addVertexInputToShaderConverterContext(SPIRVToMSLConversionConfiguration& shaderContext, const VkGraphicsPipelineCreateInfo* pCreateInfo); |
| void addPrevStageOutputToShaderConverterContext(SPIRVToMSLConversionConfiguration& shaderContext, SPIRVShaderOutputs& outputs); |
| MTLRenderPipelineDescriptor* newMTLRenderPipelineDescriptor(const VkGraphicsPipelineCreateInfo* pCreateInfo, const SPIRVTessReflectionData& reflectData); |
| MTLComputePipelineDescriptor* newMTLTessVertexStageDescriptor(const VkGraphicsPipelineCreateInfo* pCreateInfo, const SPIRVTessReflectionData& reflectData, SPIRVToMSLConversionConfiguration& shaderContext); |
| MTLComputePipelineDescriptor* newMTLTessControlStageDescriptor(const VkGraphicsPipelineCreateInfo* pCreateInfo, const SPIRVTessReflectionData& reflectData, SPIRVToMSLConversionConfiguration& shaderContext); |
| MTLRenderPipelineDescriptor* newMTLTessRasterStageDescriptor(const VkGraphicsPipelineCreateInfo* pCreateInfo, const SPIRVTessReflectionData& reflectData, SPIRVToMSLConversionConfiguration& shaderContext); |
| bool addVertexShaderToPipeline(MTLRenderPipelineDescriptor* plDesc, const VkGraphicsPipelineCreateInfo* pCreateInfo, SPIRVToMSLConversionConfiguration& shaderContext); |
| bool addVertexShaderToPipeline(MTLComputePipelineDescriptor* plDesc, const VkGraphicsPipelineCreateInfo* pCreateInfo, SPIRVToMSLConversionConfiguration& shaderContext); |
| bool addTessCtlShaderToPipeline(MTLComputePipelineDescriptor* plDesc, const VkGraphicsPipelineCreateInfo* pCreateInfo, SPIRVToMSLConversionConfiguration& shaderContext, SPIRVShaderOutputs& prevOutput); |
| bool addTessEvalShaderToPipeline(MTLRenderPipelineDescriptor* plDesc, const VkGraphicsPipelineCreateInfo* pCreateInfo, SPIRVToMSLConversionConfiguration& shaderContext, SPIRVShaderOutputs& prevOutput); |
| bool addFragmentShaderToPipeline(MTLRenderPipelineDescriptor* plDesc, const VkGraphicsPipelineCreateInfo* pCreateInfo, SPIRVToMSLConversionConfiguration& shaderContext, SPIRVShaderOutputs& prevOutput); |
| template<class T> |
| bool addVertexInputToPipeline(T* inputDesc, const VkPipelineVertexInputStateCreateInfo* pVI, const SPIRVToMSLConversionConfiguration& shaderContext); |
| void adjustVertexInputForMultiview(MTLVertexDescriptor* inputDesc, const VkPipelineVertexInputStateCreateInfo* pVI, uint32_t viewCount, uint32_t oldViewCount = 1); |
| void addTessellationToPipeline(MTLRenderPipelineDescriptor* plDesc, const SPIRVTessReflectionData& reflectData, const VkPipelineTessellationStateCreateInfo* pTS); |
| void addFragmentOutputToPipeline(MTLRenderPipelineDescriptor* plDesc, const VkGraphicsPipelineCreateInfo* pCreateInfo); |
| bool isRenderingPoints(const VkGraphicsPipelineCreateInfo* pCreateInfo); |
| bool verifyImplicitBuffer(bool needsBuffer, MVKShaderImplicitRezBinding& index, MVKShaderStage stage, const char* name, uint32_t reservedBuffers); |
| uint32_t getTranslatedVertexBinding(uint32_t binding, uint32_t translationOffset, uint32_t maxBinding); |
| |
| const VkPipelineShaderStageCreateInfo* _pVertexSS = nullptr; |
| const VkPipelineShaderStageCreateInfo* _pTessCtlSS = nullptr; |
| const VkPipelineShaderStageCreateInfo* _pTessEvalSS = nullptr; |
| const VkPipelineShaderStageCreateInfo* _pFragmentSS = nullptr; |
| |
| VkPipelineTessellationStateCreateInfo _tessInfo; |
| VkPipelineRasterizationStateCreateInfo _rasterInfo; |
| VkPipelineDepthStencilStateCreateInfo _depthStencilInfo; |
| |
| MVKSmallVector<VkViewport, kMVKCachedViewportScissorCount> _viewports; |
| MVKSmallVector<VkRect2D, kMVKCachedViewportScissorCount> _scissors; |
| MVKSmallVector<MVKTranslatedVertexBinding> _translatedVertexBindings; |
| |
| MTLComputePipelineDescriptor* _mtlTessVertexStageDesc = nil; |
| id<MTLFunction> _mtlTessVertexFunctions[3] = {nil, nil, nil}; |
| |
| id<MTLComputePipelineState> _mtlTessVertexStageState = nil; |
| id<MTLComputePipelineState> _mtlTessVertexStageIndex16State = nil; |
| id<MTLComputePipelineState> _mtlTessVertexStageIndex32State = nil; |
| id<MTLComputePipelineState> _mtlTessControlStageState = nil; |
| id<MTLRenderPipelineState> _mtlPipelineState = nil; |
| std::unordered_map<uint32_t, id<MTLRenderPipelineState>> _multiviewMTLPipelineStates; |
| MTLCullMode _mtlCullMode; |
| MTLWinding _mtlFrontWinding; |
| MTLTriangleFillMode _mtlFillMode; |
| MTLDepthClipMode _mtlDepthClipMode; |
| MTLPrimitiveType _mtlPrimitiveType; |
| |
| float _blendConstants[4] = { 0.0, 0.0, 0.0, 1.0 }; |
| uint32_t _outputControlPointCount; |
| MVKShaderImplicitRezBinding _viewRangeBufferIndex; |
| MVKShaderImplicitRezBinding _outputBufferIndex; |
| uint32_t _tessCtlPatchOutputBufferIndex = 0; |
| uint32_t _tessCtlLevelBufferIndex = 0; |
| |
| bool _dynamicStateEnabled[kMVKVkDynamicStateCount]; |
| bool _hasDepthStencilInfo; |
| bool _needsVertexSwizzleBuffer = false; |
| bool _needsVertexBufferSizeBuffer = false; |
| bool _needsVertexViewRangeBuffer = false; |
| bool _needsVertexOutputBuffer = false; |
| bool _needsTessCtlSwizzleBuffer = false; |
| bool _needsTessCtlBufferSizeBuffer = false; |
| bool _needsTessCtlOutputBuffer = false; |
| bool _needsTessCtlPatchOutputBuffer = false; |
| bool _needsTessCtlInputBuffer = false; |
| bool _needsTessEvalSwizzleBuffer = false; |
| bool _needsTessEvalBufferSizeBuffer = false; |
| bool _needsFragmentSwizzleBuffer = false; |
| bool _needsFragmentBufferSizeBuffer = false; |
| bool _needsFragmentViewRangeBuffer = false; |
| }; |
| |
| |
| #pragma mark - |
| #pragma mark MVKComputePipeline |
| |
| /** Represents an Vulkan compute pipeline. */ |
| class MVKComputePipeline : public MVKPipeline { |
| |
| public: |
| |
| /** Binds this pipeline to the specified command encoder. */ |
| void encode(MVKCommandEncoder* cmdEncoder, uint32_t = 0) override; |
| |
| /** Returns if this pipeline allows non-zero dispatch bases in vkCmdDispatchBase(). */ |
| bool allowsDispatchBase() { return _allowsDispatchBase; } |
| |
| /** Constructs an instance for the device and parent (which may be NULL). */ |
| MVKComputePipeline(MVKDevice* device, |
| MVKPipelineCache* pipelineCache, |
| MVKPipeline* parent, |
| const VkComputePipelineCreateInfo* pCreateInfo); |
| |
| ~MVKComputePipeline() override; |
| |
| protected: |
| MVKMTLFunction getMTLFunction(const VkComputePipelineCreateInfo* pCreateInfo); |
| |
| id<MTLComputePipelineState> _mtlPipelineState; |
| MTLSize _mtlThreadgroupSize; |
| bool _needsSwizzleBuffer = false; |
| bool _needsBufferSizeBuffer = false; |
| bool _needsDispatchBaseBuffer = false; |
| bool _allowsDispatchBase = false; |
| }; |
| |
| |
| #pragma mark - |
| #pragma mark MVKPipelineCache |
| |
| /** Represents a Vulkan pipeline cache. */ |
| class MVKPipelineCache : public MVKVulkanAPIDeviceObject { |
| |
| public: |
| |
| /** Returns the Vulkan type of this object. */ |
| VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_PIPELINE_CACHE; } |
| |
| /** Returns the debug report object type of this object. */ |
| VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT; } |
| |
| /** |
| * If pData is not null, serializes at most pDataSize bytes of the contents of the cache into that |
| * memory location, and returns the number of bytes serialized in pDataSize. If pData is null, |
| * returns the number of bytes required to serialize the contents of this pipeline cache. |
| */ |
| VkResult writeData(size_t* pDataSize, void* pData); |
| |
| /** Return a shader library from the specified shader context sourced from the specified shader module. */ |
| MVKShaderLibrary* getShaderLibrary(SPIRVToMSLConversionConfiguration* pContext, MVKShaderModule* shaderModule); |
| |
| /** Merges the contents of the specified number of pipeline caches into this cache. */ |
| VkResult mergePipelineCaches(uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches); |
| |
| #pragma mark Construction |
| |
| /** Constructs an instance for the specified device. */ |
| MVKPipelineCache(MVKDevice* device, const VkPipelineCacheCreateInfo* pCreateInfo); |
| |
| ~MVKPipelineCache() override; |
| |
| protected: |
| void propagateDebugName() override {} |
| MVKShaderLibraryCache* getShaderLibraryCache(MVKShaderModuleKey smKey); |
| void readData(const VkPipelineCacheCreateInfo* pCreateInfo); |
| void writeData(std::ostream& outstream, bool isCounting = false); |
| void markDirty(); |
| |
| std::unordered_map<MVKShaderModuleKey, MVKShaderLibraryCache*> _shaderCache; |
| size_t _dataSize = 0; |
| std::mutex _shaderCacheLock; |
| }; |
| |
| |
| #pragma mark - |
| #pragma mark MVKRenderPipelineCompiler |
| |
| /** |
| * Creates a MTLRenderPipelineState from a descriptor. |
| * |
| * Instances of this class are one-shot, and can only be used for a single pipeline compilation. |
| */ |
| class MVKRenderPipelineCompiler : public MVKMetalCompiler { |
| |
| public: |
| |
| /** |
| * Returns a new (retained) MTLRenderPipelineState object compiled from the descriptor. |
| * |
| * If the Metal pipeline compiler does not return within MVKConfiguration::metalCompileTimeout |
| * nanoseconds, an error will be generated and logged, and nil will be returned. |
| */ |
| id<MTLRenderPipelineState> newMTLRenderPipelineState(MTLRenderPipelineDescriptor* mtlRPLDesc); |
| |
| |
| #pragma mark Construction |
| |
| MVKRenderPipelineCompiler(MVKVulkanAPIDeviceObject* owner) : MVKMetalCompiler(owner) { |
| _compilerType = "Render pipeline"; |
| _pPerformanceTracker = &_owner->getDevice()->_performanceStatistics.shaderCompilation.pipelineCompile; |
| } |
| |
| ~MVKRenderPipelineCompiler() override; |
| |
| protected: |
| bool compileComplete(id<MTLRenderPipelineState> pipelineState, NSError *error); |
| |
| id<MTLRenderPipelineState> _mtlRenderPipelineState = nil; |
| }; |
| |
| |
| #pragma mark - |
| #pragma mark MVKComputePipelineCompiler |
| |
| /** |
| * Creates a MTLComputePipelineState from a MTLFunction. |
| * |
| * Instances of this class are one-shot, and can only be used for a single pipeline compilation. |
| */ |
| class MVKComputePipelineCompiler : public MVKMetalCompiler { |
| |
| public: |
| |
| /** |
| * Returns a new (retained) MTLComputePipelineState object compiled from the MTLFunction. |
| * |
| * If the Metal pipeline compiler does not return within MVKConfiguration::metalCompileTimeout |
| * nanoseconds, an error will be generated and logged, and nil will be returned. |
| */ |
| id<MTLComputePipelineState> newMTLComputePipelineState(id<MTLFunction> mtlFunction); |
| |
| /** |
| * Returns a new (retained) MTLComputePipelineState object compiled from the MTLComputePipelineDescriptor. |
| * |
| * If the Metal pipeline compiler does not return within MVKConfiguration::metalCompileTimeout |
| * nanoseconds, an error will be generated and logged, and nil will be returned. |
| */ |
| id<MTLComputePipelineState> newMTLComputePipelineState(MTLComputePipelineDescriptor* plDesc); |
| |
| |
| #pragma mark Construction |
| |
| MVKComputePipelineCompiler(MVKVulkanAPIDeviceObject* owner, const char* compilerType = nullptr) : MVKMetalCompiler(owner) { |
| _compilerType = compilerType ? compilerType : "Compute pipeline"; |
| _pPerformanceTracker = &_owner->getDevice()->_performanceStatistics.shaderCompilation.pipelineCompile; |
| } |
| |
| ~MVKComputePipelineCompiler() override; |
| |
| protected: |
| bool compileComplete(id<MTLComputePipelineState> pipelineState, NSError *error); |
| |
| id<MTLComputePipelineState> _mtlComputePipelineState = nil; |
| }; |