diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm index 033f613c..35d6a025 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm @@ -44,7 +44,10 @@ void MVKPipelineCommandEncoderState::setPipeline(MVKPipeline* pipeline) { MVKPipeline* MVKPipelineCommandEncoderState::getPipeline() { return _pipeline; } void MVKPipelineCommandEncoderState::encodeImpl(uint32_t stage) { - if (_pipeline) { _pipeline->encode(_cmdEncoder, stage); } + if (_pipeline) { + _pipeline->encode(_cmdEncoder, stage); + _pipeline->bindPushConstants(_cmdEncoder); + } } void MVKPipelineCommandEncoderState::resetImpl() { diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h index a6ecc88a..7b56702c 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h @@ -58,9 +58,6 @@ public: uint32_t firstSet, MVKVector& dynamicOffsets); - /** Populates the specified shader converter context. */ - void populateShaderConverterContext(SPIRVToMSLConversionConfiguration& context); - /** Updates a descriptor set in a command encoder. */ void pushDescriptorSet(MVKCommandEncoder* cmdEncoder, MVKVector& descriptorWrites, @@ -72,6 +69,9 @@ public: 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; } @@ -96,6 +96,9 @@ public: /** 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); @@ -144,6 +147,9 @@ public: /** 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; } @@ -157,9 +163,7 @@ public: bool hasValidMTLPipelineStates() { return _hasValidMTLPipelineStates; } /** Constructs an instance for the device. layout, and parent (which may be NULL). */ - MVKPipeline(MVKDevice* device, MVKPipelineCache* pipelineCache, MVKPipeline* parent) : MVKVulkanAPIDeviceObject(device), - _pipelineCache(pipelineCache), - _fullImageViewSwizzle(device->_pMVKConfig->fullImageViewSwizzle) {} + MVKPipeline(MVKDevice* device, MVKPipelineCache* pipelineCache, MVKPipelineLayout* layout, MVKPipeline* parent); protected: void propogateDebugName() override {} @@ -167,6 +171,7 @@ protected: MVKPipelineCache* _pipelineCache; MVKShaderImplicitRezBinding _swizzleBufferIndex; MVKShaderImplicitRezBinding _bufferSizeBufferIndex; + MVKShaderResourceBinding _pushConstantsMTLResourceIndexes; bool _fullImageViewSwizzle; bool _hasValidMTLPipelineStates = true; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm index d3978dff..abbdc49a 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm @@ -53,11 +53,6 @@ void MVKPipelineLayout::bindDescriptorSets(MVKCommandEncoder* cmdEncoder, dynamicOffsets, &pDynamicOffsetIndex); setConfigurationResult(dsl.getConfigurationResult()); } - if (cmdEncoder) { - for (uint32_t i = kMVKShaderStageVertex; i < kMVKShaderStageMax; i++) { - cmdEncoder->getPushConstants(mvkVkShaderStageFlagBitsFromMVKShaderStage(MVKShaderStage(i)))->setMTLBufferIndex(_pushConstantsMTLResourceIndexes.stages[i].bufferIndex); - } - } } // A null cmdEncoder can be passed to perform a validation pass @@ -68,12 +63,6 @@ void MVKPipelineLayout::pushDescriptorSet(MVKCommandEncoder* cmdEncoder, auto& dsl = _descriptorSetLayouts[set]; dsl.pushDescriptorSet(cmdEncoder, descriptorWrites, _dslMTLResourceIndexOffsets[set]); setConfigurationResult(dsl.getConfigurationResult()); - - if (cmdEncoder) { - for (uint32_t i = kMVKShaderStageVertex; i < kMVKShaderStageMax; i++) { - cmdEncoder->getPushConstants(mvkVkShaderStageFlagBitsFromMVKShaderStage(MVKShaderStage(i)))->setMTLBufferIndex(_pushConstantsMTLResourceIndexes.stages[i].bufferIndex); - } - } } // A null cmdEncoder can be passed to perform a validation pass @@ -85,12 +74,6 @@ void MVKPipelineLayout::pushDescriptorSet(MVKCommandEncoder* cmdEncoder, auto& dsl = _descriptorSetLayouts[set]; dsl.pushDescriptorSet(cmdEncoder, descUpdateTemplate, pData, _dslMTLResourceIndexOffsets[set]); setConfigurationResult(dsl.getConfigurationResult()); - - if (cmdEncoder) { - for (uint32_t i = kMVKShaderStageVertex; i < kMVKShaderStageMax; i++) { - cmdEncoder->getPushConstants(mvkVkShaderStageFlagBitsFromMVKShaderStage(MVKShaderStage(i)))->setMTLBufferIndex(_pushConstantsMTLResourceIndexes.stages[i].bufferIndex); - } - } } void MVKPipelineLayout::populateShaderConverterContext(SPIRVToMSLConversionConfiguration& context) { @@ -168,6 +151,24 @@ MVKPipelineLayout::MVKPipelineLayout(MVKDevice* device, } +#pragma mark - +#pragma mark MVKPipeline + +void MVKPipeline::bindPushConstants(MVKCommandEncoder* cmdEncoder) { + if (cmdEncoder) { + for (uint32_t i = kMVKShaderStageVertex; i < kMVKShaderStageMax; i++) { + cmdEncoder->getPushConstants(mvkVkShaderStageFlagBitsFromMVKShaderStage(MVKShaderStage(i)))->setMTLBufferIndex(_pushConstantsMTLResourceIndexes.stages[i].bufferIndex); + } + } +} + +MVKPipeline::MVKPipeline(MVKDevice* device, MVKPipelineCache* pipelineCache, MVKPipelineLayout* layout, MVKPipeline* parent) : + MVKVulkanAPIDeviceObject(device), + _pipelineCache(pipelineCache), + _pushConstantsMTLResourceIndexes(layout->getPushConstantBindings()), + _fullImageViewSwizzle(device->_pMVKConfig->fullImageViewSwizzle) {} + + #pragma mark - #pragma mark MVKGraphicsPipeline @@ -285,7 +286,8 @@ bool MVKGraphicsPipeline::supportsDynamicState(VkDynamicState state) { MVKGraphicsPipeline::MVKGraphicsPipeline(MVKDevice* device, MVKPipelineCache* pipelineCache, MVKPipeline* parent, - const VkGraphicsPipelineCreateInfo* pCreateInfo) : MVKPipeline(device, pipelineCache, parent) { + const VkGraphicsPipelineCreateInfo* pCreateInfo) : + MVKPipeline(device, pipelineCache, (MVKPipelineLayout*)pCreateInfo->layout, parent) { // Get the tessellation shaders, if present. Do this now, because we need to extract // reflection data from them that informs everything else. @@ -1275,7 +1277,9 @@ void MVKComputePipeline::encode(MVKCommandEncoder* cmdEncoder, uint32_t) { MVKComputePipeline::MVKComputePipeline(MVKDevice* device, MVKPipelineCache* pipelineCache, MVKPipeline* parent, - const VkComputePipelineCreateInfo* pCreateInfo) : MVKPipeline(device, pipelineCache, parent) { + const VkComputePipelineCreateInfo* pCreateInfo) : + MVKPipeline(device, pipelineCache, (MVKPipelineLayout*)pCreateInfo->layout, parent) { + MVKMTLFunction shaderFunc = getMTLFunction(pCreateInfo); _mtlThreadgroupSize = shaderFunc.threadGroupSize; _mtlPipelineState = nil;