Merge pull request #305 from billhollings/master
Update shader caching for compatibility with texture swizzling.
This commit is contained in:
commit
79e4d75e1b
@ -48,7 +48,7 @@ extern "C" {
|
||||
*/
|
||||
#define MVK_VERSION_MAJOR 1
|
||||
#define MVK_VERSION_MINOR 0
|
||||
#define MVK_VERSION_PATCH 24
|
||||
#define MVK_VERSION_PATCH 25
|
||||
|
||||
#define MVK_MAKE_VERSION(major, minor, patch) (((major) * 10000) + ((minor) * 100) + (patch))
|
||||
#define MVK_VERSION MVK_MAKE_VERSION(MVK_VERSION_MAJOR, MVK_VERSION_MINOR, MVK_VERSION_PATCH)
|
||||
@ -631,7 +631,7 @@ typedef uint32_t MVKMSLSPIRVHeader;
|
||||
|
||||
#endif // VK_NO_PROTOTYPES
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
@ -58,6 +58,10 @@ typedef struct MVKShaderResourceBinding {
|
||||
MVKShaderStageResourceBinding fragmentStage;
|
||||
MVKShaderStageResourceBinding computeStage;
|
||||
|
||||
uint32_t getMaxBufferIndex();
|
||||
uint32_t getMaxTextureIndex();
|
||||
uint32_t getMaxSamplerIndex();
|
||||
|
||||
MVKShaderResourceBinding operator+ (const MVKShaderResourceBinding& rhs);
|
||||
MVKShaderResourceBinding& operator+= (const MVKShaderResourceBinding& rhs);
|
||||
|
||||
|
@ -46,6 +46,18 @@ MVK_PUBLIC_SYMBOL MVKShaderStageResourceBinding& MVKShaderStageResourceBinding::
|
||||
|
||||
#pragma mark MVKShaderResourceBinding
|
||||
|
||||
MVK_PUBLIC_SYMBOL uint32_t MVKShaderResourceBinding::getMaxBufferIndex() {
|
||||
return max({vertexStage.bufferIndex, fragmentStage.bufferIndex, computeStage.bufferIndex});
|
||||
}
|
||||
|
||||
MVK_PUBLIC_SYMBOL uint32_t MVKShaderResourceBinding::getMaxTextureIndex() {
|
||||
return max({vertexStage.textureIndex, fragmentStage.textureIndex, computeStage.textureIndex});
|
||||
}
|
||||
|
||||
MVK_PUBLIC_SYMBOL uint32_t MVKShaderResourceBinding::getMaxSamplerIndex() {
|
||||
return max({vertexStage.samplerIndex, fragmentStage.samplerIndex, computeStage.samplerIndex});
|
||||
}
|
||||
|
||||
MVK_PUBLIC_SYMBOL MVKShaderResourceBinding MVKShaderResourceBinding::operator+ (const MVKShaderResourceBinding& rhs) {
|
||||
MVKShaderResourceBinding rslt;
|
||||
rslt.vertexStage = this->vertexStage + rhs.vertexStage;
|
||||
|
@ -75,18 +75,17 @@ public:
|
||||
const MVKShaderAuxBufferBinding& getAuxBufferIndex() { return _auxBufferIndex; }
|
||||
|
||||
/** Returns the number of textures in this layout. This is used to calculate the size of the auxiliary buffer. */
|
||||
uint32_t getNumTextures() { return _numTextures; }
|
||||
uint32_t getMaxTextureIndex() { return _pushConstantsMTLResourceIndexes.getMaxTextureIndex(); }
|
||||
|
||||
/** Constructs an instance for the specified device. */
|
||||
MVKPipelineLayout(MVKDevice* device, const VkPipelineLayoutCreateInfo* pCreateInfo);
|
||||
|
||||
private:
|
||||
protected:
|
||||
std::vector<MVKDescriptorSetLayout> _descriptorSetLayouts;
|
||||
std::vector<MVKShaderResourceBinding> _dslMTLResourceIndexOffsets;
|
||||
std::vector<VkPushConstantRange> _pushConstants;
|
||||
MVKShaderResourceBinding _pushConstantsMTLResourceIndexOffsets;
|
||||
MVKShaderResourceBinding _pushConstantsMTLResourceIndexes;
|
||||
MVKShaderAuxBufferBinding _auxBufferIndex;
|
||||
uint32_t _numTextures;
|
||||
};
|
||||
|
||||
|
||||
@ -108,6 +107,10 @@ public:
|
||||
MVKPipeline(MVKDevice* device, MVKPipelineCache* pipelineCache, MVKPipeline* parent) : MVKBaseDeviceObject(device),
|
||||
_pipelineCache(pipelineCache) {}
|
||||
|
||||
~MVKPipeline() override {
|
||||
[_auxBuffer release];
|
||||
};
|
||||
|
||||
protected:
|
||||
MVKPipelineCache* _pipelineCache;
|
||||
MVKShaderAuxBufferBinding _auxBufferIndex;
|
||||
|
@ -49,9 +49,9 @@ void MVKPipelineLayout::bindDescriptorSets(MVKCommandEncoder* cmdEncoder,
|
||||
_dslMTLResourceIndexOffsets[dslIdx],
|
||||
dynamicOffsets, &pDynamicOffsetIndex);
|
||||
}
|
||||
cmdEncoder->getPushConstants(VK_SHADER_STAGE_VERTEX_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexOffsets.vertexStage.bufferIndex);
|
||||
cmdEncoder->getPushConstants(VK_SHADER_STAGE_FRAGMENT_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexOffsets.fragmentStage.bufferIndex);
|
||||
cmdEncoder->getPushConstants(VK_SHADER_STAGE_COMPUTE_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexOffsets.computeStage.bufferIndex);
|
||||
cmdEncoder->getPushConstants(VK_SHADER_STAGE_VERTEX_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexes.vertexStage.bufferIndex);
|
||||
cmdEncoder->getPushConstants(VK_SHADER_STAGE_FRAGMENT_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexes.fragmentStage.bufferIndex);
|
||||
cmdEncoder->getPushConstants(VK_SHADER_STAGE_COMPUTE_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexes.computeStage.bufferIndex);
|
||||
}
|
||||
|
||||
void MVKPipelineLayout::pushDescriptorSet(MVKCommandEncoder* cmdEncoder,
|
||||
@ -60,9 +60,9 @@ void MVKPipelineLayout::pushDescriptorSet(MVKCommandEncoder* cmdEncoder,
|
||||
|
||||
_descriptorSetLayouts[set].pushDescriptorSet(cmdEncoder, descriptorWrites,
|
||||
_dslMTLResourceIndexOffsets[set]);
|
||||
cmdEncoder->getPushConstants(VK_SHADER_STAGE_VERTEX_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexOffsets.vertexStage.bufferIndex);
|
||||
cmdEncoder->getPushConstants(VK_SHADER_STAGE_FRAGMENT_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexOffsets.fragmentStage.bufferIndex);
|
||||
cmdEncoder->getPushConstants(VK_SHADER_STAGE_COMPUTE_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexOffsets.computeStage.bufferIndex);
|
||||
cmdEncoder->getPushConstants(VK_SHADER_STAGE_VERTEX_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexes.vertexStage.bufferIndex);
|
||||
cmdEncoder->getPushConstants(VK_SHADER_STAGE_FRAGMENT_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexes.fragmentStage.bufferIndex);
|
||||
cmdEncoder->getPushConstants(VK_SHADER_STAGE_COMPUTE_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexes.computeStage.bufferIndex);
|
||||
}
|
||||
|
||||
void MVKPipelineLayout::pushDescriptorSet(MVKCommandEncoder* cmdEncoder,
|
||||
@ -73,9 +73,9 @@ void MVKPipelineLayout::pushDescriptorSet(MVKCommandEncoder* cmdEncoder,
|
||||
_descriptorSetLayouts[set].pushDescriptorSet(cmdEncoder, descUpdateTemplate,
|
||||
pData,
|
||||
_dslMTLResourceIndexOffsets[set]);
|
||||
cmdEncoder->getPushConstants(VK_SHADER_STAGE_VERTEX_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexOffsets.vertexStage.bufferIndex);
|
||||
cmdEncoder->getPushConstants(VK_SHADER_STAGE_FRAGMENT_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexOffsets.fragmentStage.bufferIndex);
|
||||
cmdEncoder->getPushConstants(VK_SHADER_STAGE_COMPUTE_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexOffsets.computeStage.bufferIndex);
|
||||
cmdEncoder->getPushConstants(VK_SHADER_STAGE_VERTEX_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexes.vertexStage.bufferIndex);
|
||||
cmdEncoder->getPushConstants(VK_SHADER_STAGE_FRAGMENT_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexes.fragmentStage.bufferIndex);
|
||||
cmdEncoder->getPushConstants(VK_SHADER_STAGE_COMPUTE_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexes.computeStage.bufferIndex);
|
||||
}
|
||||
|
||||
void MVKPipelineLayout::populateShaderConverterContext(SPIRVToMSLConverterContext& context) {
|
||||
@ -91,62 +91,26 @@ void MVKPipelineLayout::populateShaderConverterContext(SPIRVToMSLConverterContex
|
||||
|
||||
// Add any resource bindings used by push-constants
|
||||
mvkPopulateShaderConverterContext(context,
|
||||
_pushConstantsMTLResourceIndexOffsets.vertexStage,
|
||||
_pushConstantsMTLResourceIndexes.vertexStage,
|
||||
spv::ExecutionModelVertex,
|
||||
kPushConstDescSet,
|
||||
kPushConstBinding);
|
||||
|
||||
mvkPopulateShaderConverterContext(context,
|
||||
_pushConstantsMTLResourceIndexOffsets.fragmentStage,
|
||||
_pushConstantsMTLResourceIndexes.fragmentStage,
|
||||
spv::ExecutionModelFragment,
|
||||
kPushConstDescSet,
|
||||
kPushConstBinding);
|
||||
|
||||
mvkPopulateShaderConverterContext(context,
|
||||
_pushConstantsMTLResourceIndexOffsets.computeStage,
|
||||
_pushConstantsMTLResourceIndexes.computeStage,
|
||||
spv::ExecutionModelGLCompute,
|
||||
kPushConstDescSet,
|
||||
kPushConstBinding);
|
||||
|
||||
// Scan the resource bindings, looking for an unused buffer index.
|
||||
// FIXME: If we ever encounter a device that supports more than 31 buffer
|
||||
// bindings, we'll need to update this code.
|
||||
unordered_map<uint32_t, uint32_t> freeBufferMasks;
|
||||
freeBufferMasks[spv::ExecutionModelVertex] = freeBufferMasks[spv::ExecutionModelFragment] = freeBufferMasks[spv::ExecutionModelGLCompute] = (1 << _device->_pMetalFeatures->maxPerStageBufferCount) - 1;
|
||||
_numTextures = 0;
|
||||
for (auto& binding : context.resourceBindings) {
|
||||
if (binding.descriptorSet == kPushConstDescSet && binding.binding == kPushConstBinding) {
|
||||
// This is the special push constant buffer.
|
||||
freeBufferMasks[binding.stage] &= ~(1 << binding.mslBuffer);
|
||||
continue;
|
||||
}
|
||||
VkDescriptorType descriptorType = _descriptorSetLayouts[binding.descriptorSet]._bindings[binding.binding]._info.descriptorType;
|
||||
switch (descriptorType) {
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
|
||||
// This buffer is being used.
|
||||
freeBufferMasks[binding.stage] &= ~(1 << binding.mslBuffer);
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
|
||||
// If it results in a texture binding, we need to account for it so
|
||||
// we know how big to make the auxiliary buffer.
|
||||
if (binding.mslTexture + 1 > _numTextures)
|
||||
_numTextures = binding.mslTexture + 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Pick the lowest index that isn't used.
|
||||
_auxBufferIndex.vertex = ffs(freeBufferMasks[spv::ExecutionModelVertex]) - 1;
|
||||
_auxBufferIndex.fragment = ffs(freeBufferMasks[spv::ExecutionModelFragment]) - 1;
|
||||
_auxBufferIndex.compute = ffs(freeBufferMasks[spv::ExecutionModelGLCompute]) - 1;
|
||||
_auxBufferIndex.vertex = _pushConstantsMTLResourceIndexes.vertexStage.bufferIndex + 1;
|
||||
_auxBufferIndex.fragment = _pushConstantsMTLResourceIndexes.fragmentStage.bufferIndex + 1;
|
||||
_auxBufferIndex.compute = _pushConstantsMTLResourceIndexes.computeStage.bufferIndex + 1;
|
||||
}
|
||||
|
||||
MVKPipelineLayout::MVKPipelineLayout(MVKDevice* device,
|
||||
@ -167,8 +131,8 @@ MVKPipelineLayout::MVKPipelineLayout(MVKDevice* device,
|
||||
for (uint32_t i = 0; i < pCreateInfo->setLayoutCount; i++) {
|
||||
MVKDescriptorSetLayout* pDescSetLayout = (MVKDescriptorSetLayout*)pCreateInfo->pSetLayouts[i];
|
||||
_descriptorSetLayouts.push_back(*pDescSetLayout);
|
||||
_dslMTLResourceIndexOffsets.push_back(_pushConstantsMTLResourceIndexOffsets);
|
||||
_pushConstantsMTLResourceIndexOffsets += pDescSetLayout->_mtlResourceCounts;
|
||||
_dslMTLResourceIndexOffsets.push_back(_pushConstantsMTLResourceIndexes);
|
||||
_pushConstantsMTLResourceIndexes += pDescSetLayout->_mtlResourceCounts;
|
||||
}
|
||||
|
||||
// Add push constants
|
||||
@ -339,7 +303,7 @@ MTLRenderPipelineDescriptor* MVKGraphicsPipeline::getMTLRenderPipelineDescriptor
|
||||
initMVKShaderConverterContext(shaderContext, pCreateInfo);
|
||||
auto* mvkLayout = (MVKPipelineLayout*)pCreateInfo->layout;
|
||||
_auxBufferIndex = mvkLayout->getAuxBufferIndex();
|
||||
uint32_t auxBufferSize = sizeof(uint32_t) * mvkLayout->getNumTextures();
|
||||
uint32_t auxBufferSize = sizeof(uint32_t) * mvkLayout->getMaxTextureIndex();
|
||||
|
||||
// Retrieve the render subpass for which this pipeline is being constructed
|
||||
MVKRenderPass* mvkRendPass = (MVKRenderPass*)pCreateInfo->renderPass;
|
||||
@ -394,7 +358,7 @@ MTLRenderPipelineDescriptor* MVKGraphicsPipeline::getMTLRenderPipelineDescriptor
|
||||
}
|
||||
|
||||
if (_needsVertexAuxBuffer || _needsFragmentAuxBuffer) {
|
||||
_auxBuffer = [_device->getMTLDevice() newBufferWithLength: auxBufferSize options: MTLResourceStorageModeShared];
|
||||
_auxBuffer = [_device->getMTLDevice() newBufferWithLength: auxBufferSize options: MTLResourceStorageModeShared]; // retained
|
||||
}
|
||||
|
||||
// Vertex attributes
|
||||
@ -584,14 +548,14 @@ MVKMTLFunction MVKComputePipeline::getMTLFunction(const VkComputePipelineCreateI
|
||||
MVKPipelineLayout* layout = (MVKPipelineLayout*)pCreateInfo->layout;
|
||||
layout->populateShaderConverterContext(shaderContext);
|
||||
_auxBufferIndex = layout->getAuxBufferIndex();
|
||||
uint32_t auxBufferSize = sizeof(uint32_t) * layout->getNumTextures();
|
||||
uint32_t auxBufferSize = sizeof(uint32_t) * layout->getMaxTextureIndex();
|
||||
shaderContext.options.auxBufferIndex = _auxBufferIndex.compute;
|
||||
|
||||
MVKShaderModule* mvkShdrMod = (MVKShaderModule*)pSS->module;
|
||||
auto func = mvkShdrMod->getMTLFunction(&shaderContext, pSS->pSpecializationInfo, _pipelineCache);
|
||||
_needsAuxBuffer = shaderContext.options.needsAuxBuffer;
|
||||
if (_needsAuxBuffer) {
|
||||
_auxBuffer = [_device->getMTLDevice() newBufferWithLength: auxBufferSize options: MTLResourceStorageModeShared];
|
||||
_auxBuffer = [_device->getMTLDevice() newBufferWithLength: auxBufferSize options: MTLResourceStorageModeShared]; // retained
|
||||
}
|
||||
return func;
|
||||
}
|
||||
@ -661,9 +625,11 @@ namespace mvk {
|
||||
opt.entryPointStage,
|
||||
opt.mslVersion,
|
||||
opt.texelBufferTextureWidth,
|
||||
opt.auxBufferIndex,
|
||||
opt.shouldFlipVertexY,
|
||||
opt.isRenderingPoints,
|
||||
opt.isRasterizationDisabled);
|
||||
opt.isRasterizationDisabled,
|
||||
opt.needsAuxBuffer);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
|
@ -42,6 +42,7 @@ MVK_PUBLIC_SYMBOL bool SPIRVToMSLConverterOptions::matches(const SPIRVToMSLConve
|
||||
if (entryPointStage != other.entryPointStage) { return false; }
|
||||
if (mslVersion != other.mslVersion) { return false; }
|
||||
if (texelBufferTextureWidth != other.texelBufferTextureWidth) { return false; }
|
||||
if (auxBufferIndex != other.auxBufferIndex) { return false; }
|
||||
if (!!shouldFlipVertexY != !!other.shouldFlipVertexY) { return false; }
|
||||
if (!!isRenderingPoints != !!other.isRenderingPoints) { return false; }
|
||||
if (entryPointName != other.entryPointName) { return false; }
|
||||
@ -103,6 +104,7 @@ MVK_PUBLIC_SYMBOL bool SPIRVToMSLConverterContext::matches(const SPIRVToMSLConve
|
||||
MVK_PUBLIC_SYMBOL void SPIRVToMSLConverterContext::alignWith(const SPIRVToMSLConverterContext& srcContext) {
|
||||
|
||||
options.isRasterizationDisabled = srcContext.options.isRasterizationDisabled;
|
||||
options.needsAuxBuffer = srcContext.options.needsAuxBuffer;
|
||||
|
||||
if (options.entryPointStage == spv::ExecutionModelVertex) {
|
||||
for (auto& va : vertexAttributes) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user