Merge pull request #818 from billhollings/master

Support preallocated descriptor pooling via VkDescriptorPoolSize.
This commit is contained in:
Bill Hollings 2020-01-21 10:15:07 -05:00 committed by GitHub
commit 8463eb5d8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 2139 additions and 1177 deletions

View File

@ -157,6 +157,10 @@
A95B7D6A1D3EE486003183D3 /* MVKCommandEncoderState.h in Headers */ = {isa = PBXBuildFile; fileRef = A95B7D671D3EE486003183D3 /* MVKCommandEncoderState.h */; };
A95B7D6B1D3EE486003183D3 /* MVKCommandEncoderState.mm in Sources */ = {isa = PBXBuildFile; fileRef = A95B7D681D3EE486003183D3 /* MVKCommandEncoderState.mm */; };
A95B7D6C1D3EE486003183D3 /* MVKCommandEncoderState.mm in Sources */ = {isa = PBXBuildFile; fileRef = A95B7D681D3EE486003183D3 /* MVKCommandEncoderState.mm */; };
A966A5DF23C535D000BBF9B4 /* MVKDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = A966A5DC23C535D000BBF9B4 /* MVKDescriptor.h */; };
A966A5E023C535D000BBF9B4 /* MVKDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = A966A5DC23C535D000BBF9B4 /* MVKDescriptor.h */; };
A966A5E123C535D000BBF9B4 /* MVKDescriptor.mm in Sources */ = {isa = PBXBuildFile; fileRef = A966A5DE23C535D000BBF9B4 /* MVKDescriptor.mm */; };
A966A5E223C535D000BBF9B4 /* MVKDescriptor.mm in Sources */ = {isa = PBXBuildFile; fileRef = A966A5DE23C535D000BBF9B4 /* MVKDescriptor.mm */; };
A981494D1FB6A3F7005F00B4 /* MVKBaseObject.mm in Sources */ = {isa = PBXBuildFile; fileRef = A98149411FB6A3F7005F00B4 /* MVKBaseObject.mm */; };
A981494E1FB6A3F7005F00B4 /* MVKBaseObject.mm in Sources */ = {isa = PBXBuildFile; fileRef = A98149411FB6A3F7005F00B4 /* MVKBaseObject.mm */; };
A981494F1FB6A3F7005F00B4 /* MVKBaseObject.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149421FB6A3F7005F00B4 /* MVKBaseObject.h */; };
@ -373,6 +377,8 @@
A95870F71C90D29F009EB096 /* MVKCommandResourceFactory.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCommandResourceFactory.mm; sourceTree = "<group>"; };
A95B7D671D3EE486003183D3 /* MVKCommandEncoderState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKCommandEncoderState.h; sourceTree = "<group>"; };
A95B7D681D3EE486003183D3 /* MVKCommandEncoderState.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCommandEncoderState.mm; sourceTree = "<group>"; };
A966A5DC23C535D000BBF9B4 /* MVKDescriptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKDescriptor.h; sourceTree = "<group>"; };
A966A5DE23C535D000BBF9B4 /* MVKDescriptor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKDescriptor.mm; sourceTree = "<group>"; };
A98149411FB6A3F7005F00B4 /* MVKBaseObject.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKBaseObject.mm; sourceTree = "<group>"; };
A98149421FB6A3F7005F00B4 /* MVKBaseObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKBaseObject.h; sourceTree = "<group>"; };
A98149431FB6A3F7005F00B4 /* MVKEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKEnvironment.h; sourceTree = "<group>"; };
@ -483,6 +489,8 @@
children = (
A94FB77F1C7DFB4800632CA3 /* MVKBuffer.h */,
A94FB7801C7DFB4800632CA3 /* MVKBuffer.mm */,
A966A5DC23C535D000BBF9B4 /* MVKDescriptor.h */,
A966A5DE23C535D000BBF9B4 /* MVKDescriptor.mm */,
A94FB7811C7DFB4800632CA3 /* MVKDescriptorSet.h */,
A94FB7821C7DFB4800632CA3 /* MVKDescriptorSet.mm */,
A94FB7831C7DFB4800632CA3 /* MVKDevice.h */,
@ -695,6 +703,7 @@
A94FB7F01C7DFB4800632CA3 /* MVKImage.h in Headers */,
4553AEFD2251617100E8EBCD /* MVKBlockObserver.h in Headers */,
A94FB7B81C7DFB4800632CA3 /* MVKCmdTransfer.h in Headers */,
A966A5DF23C535D000BBF9B4 /* MVKDescriptor.h in Headers */,
A94FB7C81C7DFB4800632CA3 /* MVKCmdDraw.h in Headers */,
A94FB7D01C7DFB4800632CA3 /* MVKCommandBuffer.h in Headers */,
A9E53DF32100B302002781DD /* MTLRenderPassDescriptor+MoltenVK.h in Headers */,
@ -763,6 +772,7 @@
A94FB7F11C7DFB4800632CA3 /* MVKImage.h in Headers */,
4553AEFE2251617100E8EBCD /* MVKBlockObserver.h in Headers */,
A94FB7B91C7DFB4800632CA3 /* MVKCmdTransfer.h in Headers */,
A966A5E023C535D000BBF9B4 /* MVKDescriptor.h in Headers */,
A94FB7C91C7DFB4800632CA3 /* MVKCmdDraw.h in Headers */,
A94FB7D11C7DFB4800632CA3 /* MVKCommandBuffer.h in Headers */,
A9E53DF42100B302002781DD /* MTLRenderPassDescriptor+MoltenVK.h in Headers */,
@ -1004,6 +1014,7 @@
A98149551FB6A3F7005F00B4 /* MVKFoundation.cpp in Sources */,
A94FB7E61C7DFB4800632CA3 /* MVKDevice.mm in Sources */,
A9E53DF52100B302002781DD /* MTLRenderPassDescriptor+MoltenVK.m in Sources */,
A966A5E123C535D000BBF9B4 /* MVKDescriptor.mm in Sources */,
A94FB7FA1C7DFB4800632CA3 /* MVKPipeline.mm in Sources */,
A94FB8021C7DFB4800632CA3 /* MVKQueue.mm in Sources */,
A9E53DD72100B197002781DD /* MTLSamplerDescriptor+MoltenVK.m in Sources */,
@ -1060,6 +1071,7 @@
A98149561FB6A3F7005F00B4 /* MVKFoundation.cpp in Sources */,
A94FB7E71C7DFB4800632CA3 /* MVKDevice.mm in Sources */,
A9E53DF62100B302002781DD /* MTLRenderPassDescriptor+MoltenVK.m in Sources */,
A966A5E223C535D000BBF9B4 /* MVKDescriptor.mm in Sources */,
A94FB7FB1C7DFB4800632CA3 /* MVKPipeline.mm in Sources */,
A94FB8031C7DFB4800632CA3 /* MVKQueue.mm in Sources */,
A9E53DD82100B197002781DD /* MTLSamplerDescriptor+MoltenVK.m in Sources */,

View File

@ -0,0 +1,555 @@
/*
* MVKDescriptor.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 "MVKImage.h"
#include "MVKVector.h"
#include <vector>
class MVKDescriptorSet;
class MVKDescriptorSetLayout;
class MVKCommandEncoder;
#pragma mark MVKShaderStageResourceBinding
/** Indicates the Metal resource indexes used by a single shader stage in a descriptor. */
typedef struct MVKShaderStageResourceBinding {
uint32_t bufferIndex = 0;
uint32_t textureIndex = 0;
uint32_t samplerIndex = 0;
MVKShaderStageResourceBinding operator+ (const MVKShaderStageResourceBinding& rhs);
MVKShaderStageResourceBinding& operator+= (const MVKShaderStageResourceBinding& rhs);
} MVKShaderStageResourceBinding;
#pragma mark MVKShaderResourceBinding
/** Indicates the Metal resource indexes used by each shader stage in a descriptor. */
typedef struct MVKShaderResourceBinding {
MVKShaderStageResourceBinding stages[kMVKShaderStageMax];
uint32_t getMaxBufferIndex();
uint32_t getMaxTextureIndex();
uint32_t getMaxSamplerIndex();
MVKShaderResourceBinding operator+ (const MVKShaderResourceBinding& rhs);
MVKShaderResourceBinding& operator+= (const MVKShaderResourceBinding& rhs);
} MVKShaderResourceBinding;
#pragma mark -
#pragma mark MVKDescriptorSetLayoutBinding
/** Represents a Vulkan descriptor set layout binding. */
class MVKDescriptorSetLayoutBinding : public MVKBaseDeviceObject {
public:
/** Returns the Vulkan API opaque object controlling this object. */
MVKVulkanAPIObject* getVulkanAPIObject() override;
/** Returns the binding number of this layout. */
inline uint32_t getBinding() { return _info.binding; }
/** Returns the number of descriptors in this layout. */
inline uint32_t getDescriptorCount() { return _info.descriptorCount; }
/** Returns the descriptor type of this layout. */
inline VkDescriptorType getDescriptorType() { return _info.descriptorType; }
/** Returns the immutable sampler at the index, or nullptr if immutable samplers are not used. */
MVKSampler* getImmutableSampler(uint32_t index);
/**
* Encodes the descriptors in the descriptor set that are specified by this layout,
* starting with the descriptor at the index, on the the command encoder.
* Returns the number of descriptors that were encoded.
*/
uint32_t bind(MVKCommandEncoder* cmdEncoder,
MVKDescriptorSet* descSet,
uint32_t descStartIndex,
MVKShaderResourceBinding& dslMTLRezIdxOffsets,
MVKVector<uint32_t>& dynamicOffsets,
uint32_t* pDynamicOffsetIndex);
/** Encodes this binding layout and the specified descriptor on the specified command encoder immediately. */
void push(MVKCommandEncoder* cmdEncoder,
uint32_t& dstArrayElement,
uint32_t& descriptorCount,
uint32_t& descriptorsPushed,
VkDescriptorType descriptorType,
size_t stride,
const void* pData,
MVKShaderResourceBinding& dslMTLRezIdxOffsets);
/** Populates the specified shader converter context, at the specified descriptor set binding. */
void populateShaderConverterContext(mvk::SPIRVToMSLConversionConfiguration& context,
MVKShaderResourceBinding& dslMTLRezIdxOffsets,
uint32_t dslIndex);
MVKDescriptorSetLayoutBinding(MVKDevice* device,
MVKDescriptorSetLayout* layout,
const VkDescriptorSetLayoutBinding* pBinding);
MVKDescriptorSetLayoutBinding(const MVKDescriptorSetLayoutBinding& binding);
~MVKDescriptorSetLayoutBinding() override;
protected:
void initMetalResourceIndexOffsets(MVKShaderStageResourceBinding* pBindingIndexes,
MVKShaderStageResourceBinding* pDescSetCounts,
const VkDescriptorSetLayoutBinding* pBinding);
bool validate(MVKSampler* mvkSampler);
MVKDescriptorSetLayout* _layout;
VkDescriptorSetLayoutBinding _info;
std::vector<MVKSampler*> _immutableSamplers;
MVKShaderResourceBinding _mtlResourceIndexOffsets;
bool _applyToStage[kMVKShaderStageMax];
};
#pragma mark -
#pragma mark MVKDescriptor
/** Represents a Vulkan descriptor. */
class MVKDescriptor : public MVKBaseObject {
public:
/** Returns the Vulkan API opaque object controlling this object. */
MVKVulkanAPIObject* getVulkanAPIObject() override { return nullptr; };
virtual VkDescriptorType getDescriptorType() = 0;
/** Encodes this descriptor (based on its layout binding index) on the the command encoder. */
virtual void bind(MVKCommandEncoder* cmdEncoder,
VkDescriptorType descriptorType,
uint32_t descriptorIndex,
bool stages[],
MVKShaderResourceBinding& mtlIndexes,
MVKVector<uint32_t>& dynamicOffsets,
uint32_t* pDynamicOffsetIndex) = 0;
/**
* Updates the internal binding from the specified content. The format of the content depends
* on the descriptor type, and is extracted from pData at the location given by srcIndex * stride.
*/
virtual void write(MVKDescriptorSet* mvkDescSet,
VkDescriptorType descriptorType,
uint32_t srcIndex,
size_t stride,
const void* pData) = 0;
/**
* Updates the specified content arrays from the internal binding.
*
* Depending on the descriptor type, the binding content is placed into one of the
* specified pImageInfo, pBufferInfo, or pTexelBufferView arrays, and the other
* arrays are ignored (and may be a null pointer).
*
* The dstIndex parameter indicates the index of the initial descriptor element
* at which to start writing.
*/
virtual void read(MVKDescriptorSet* mvkDescSet,
VkDescriptorType descriptorType,
uint32_t dstIndex,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
VkBufferView* pTexelBufferView,
VkWriteDescriptorSetInlineUniformBlockEXT* inlineUniformBlock) = 0;
/** Sets the binding layout. */
virtual void setLayout(MVKDescriptorSetLayoutBinding* dslBinding, uint32_t index) {}
/** Resets any internal content. */
virtual void reset() {}
~MVKDescriptor() { reset(); }
};
#pragma mark -
#pragma mark MVKBufferDescriptor
/** Represents a Vulkan descriptor tracking a buffer. */
class MVKBufferDescriptor : public MVKDescriptor {
public:
void bind(MVKCommandEncoder* cmdEncoder,
VkDescriptorType descriptorType,
uint32_t descriptorIndex,
bool stages[],
MVKShaderResourceBinding& mtlIndexes,
MVKVector<uint32_t>& dynamicOffsets,
uint32_t* pDynamicOffsetIndex) override;
void write(MVKDescriptorSet* mvkDescSet,
VkDescriptorType descriptorType,
uint32_t srcIndex,
size_t stride,
const void* pData) override;
void read(MVKDescriptorSet* mvkDescSet,
VkDescriptorType descriptorType,
uint32_t dstIndex,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
VkBufferView* pTexelBufferView,
VkWriteDescriptorSetInlineUniformBlockEXT* inlineUniformBlock) override;
void reset() override;
~MVKBufferDescriptor() { reset(); }
protected:
MVKBuffer* _mvkBuffer = nullptr;
VkDeviceSize _buffOffset = 0;
VkDeviceSize _buffRange = 0;
};
#pragma mark -
#pragma mark MVKUniformBufferDescriptor
class MVKUniformBufferDescriptor : public MVKBufferDescriptor {
public:
VkDescriptorType getDescriptorType() override { return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; }
};
#pragma mark -
#pragma mark MVKUniformBufferDynamicDescriptor
class MVKUniformBufferDynamicDescriptor : public MVKBufferDescriptor {
public:
VkDescriptorType getDescriptorType() override { return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; }
};
#pragma mark -
#pragma mark MVKStorageBufferDescriptor
class MVKStorageBufferDescriptor : public MVKBufferDescriptor {
public:
VkDescriptorType getDescriptorType() override { return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; }
};
#pragma mark -
#pragma mark MVKStorageBufferDynamicDescriptor
class MVKStorageBufferDynamicDescriptor : public MVKBufferDescriptor {
public:
VkDescriptorType getDescriptorType() override { return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC; }
};
#pragma mark -
#pragma mark MVKInlineUniformBlockDescriptor
/** Represents a Vulkan descriptor tracking an inline block of uniform data. */
class MVKInlineUniformBlockDescriptor : public MVKDescriptor {
public:
VkDescriptorType getDescriptorType() override { return VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT; }
void bind(MVKCommandEncoder* cmdEncoder,
VkDescriptorType descriptorType,
uint32_t descriptorIndex,
bool stages[],
MVKShaderResourceBinding& mtlIndexes,
MVKVector<uint32_t>& dynamicOffsets,
uint32_t* pDynamicOffsetIndex) override;
void write(MVKDescriptorSet* mvkDescSet,
VkDescriptorType descriptorType,
uint32_t srcIndex,
size_t stride,
const void* pData) override;
void read(MVKDescriptorSet* mvkDescSet,
VkDescriptorType descriptorType,
uint32_t dstIndex,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
VkBufferView* pTexelBufferView,
VkWriteDescriptorSetInlineUniformBlockEXT* inlineUniformBlock) override;
void reset() override;
~MVKInlineUniformBlockDescriptor() { reset(); }
protected:
id<MTLBuffer> _mtlBuffer = nil;
uint32_t _dataSize = 0;
};
#pragma mark -
#pragma mark MVKImageDescriptor
/** Represents a Vulkan descriptor tracking an image. */
class MVKImageDescriptor : public MVKDescriptor {
public:
void bind(MVKCommandEncoder* cmdEncoder,
VkDescriptorType descriptorType,
uint32_t descriptorIndex,
bool stages[],
MVKShaderResourceBinding& mtlIndexes,
MVKVector<uint32_t>& dynamicOffsets,
uint32_t* pDynamicOffsetIndex) override;
void write(MVKDescriptorSet* mvkDescSet,
VkDescriptorType descriptorType,
uint32_t srcIndex,
size_t stride,
const void* pData) override;
void read(MVKDescriptorSet* mvkDescSet,
VkDescriptorType descriptorType,
uint32_t dstIndex,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
VkBufferView* pTexelBufferView,
VkWriteDescriptorSetInlineUniformBlockEXT* inlineUniformBlock) override;
void reset() override;
~MVKImageDescriptor() { reset(); }
protected:
MVKImageView* _mvkImageView = nullptr;
VkImageLayout _imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
};
#pragma mark -
#pragma mark MVKSampledImageDescriptor
class MVKSampledImageDescriptor : public MVKImageDescriptor {
public:
VkDescriptorType getDescriptorType() override { return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; }
};
#pragma mark -
#pragma mark MVKStorageImageDescriptor
class MVKStorageImageDescriptor : public MVKImageDescriptor {
public:
VkDescriptorType getDescriptorType() override { return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; }
};
#pragma mark -
#pragma mark MVKInputAttachmentDescriptor
class MVKInputAttachmentDescriptor : public MVKImageDescriptor {
public:
VkDescriptorType getDescriptorType() override { return VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; }
};
#pragma mark -
#pragma mark MVKSamplerDescriptorMixin
/**
* This mixin class adds the ability for a descriptor to track a sampler.
*
* As a mixin, this class should only be used as a component of multiple inheritance.
* Any class that inherits from this class should also inherit from MVKDescriptor.
* This requirement is to avoid the diamond problem of multiple inheritance.
*/
class MVKSamplerDescriptorMixin {
protected:
void bind(MVKCommandEncoder* cmdEncoder,
VkDescriptorType descriptorType,
uint32_t descriptorIndex,
bool stages[],
MVKShaderResourceBinding& mtlIndexes,
MVKVector<uint32_t>& dynamicOffsets,
uint32_t* pDynamicOffsetIndex);
void write(MVKDescriptorSet* mvkDescSet,
VkDescriptorType descriptorType,
uint32_t srcIndex,
size_t stride,
const void* pData);
void read(MVKDescriptorSet* mvkDescSet,
VkDescriptorType descriptorType,
uint32_t dstIndex,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
VkBufferView* pTexelBufferView,
VkWriteDescriptorSetInlineUniformBlockEXT* inlineUniformBlock);
void setLayout(MVKDescriptorSetLayoutBinding* dslBinding, uint32_t index);
void reset();
~MVKSamplerDescriptorMixin() { reset(); }
MVKSampler* _mvkSampler = nullptr;
bool _hasDynamicSampler = true;
};
#pragma mark -
#pragma mark MVKSamplerDescriptor
/** Represents a Vulkan descriptor tracking a sampler. */
class MVKSamplerDescriptor : public MVKDescriptor, public MVKSamplerDescriptorMixin {
public:
VkDescriptorType getDescriptorType() override { return VK_DESCRIPTOR_TYPE_SAMPLER; }
void bind(MVKCommandEncoder* cmdEncoder,
VkDescriptorType descriptorType,
uint32_t descriptorIndex,
bool stages[],
MVKShaderResourceBinding& mtlIndexes,
MVKVector<uint32_t>& dynamicOffsets,
uint32_t* pDynamicOffsetIndex) override;
void write(MVKDescriptorSet* mvkDescSet,
VkDescriptorType descriptorType,
uint32_t srcIndex,
size_t stride,
const void* pData) override;
void read(MVKDescriptorSet* mvkDescSet,
VkDescriptorType descriptorType,
uint32_t dstIndex,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
VkBufferView* pTexelBufferView,
VkWriteDescriptorSetInlineUniformBlockEXT* inlineUniformBlock) override;
void setLayout(MVKDescriptorSetLayoutBinding* dslBinding, uint32_t index) override;
void reset() override;
~MVKSamplerDescriptor() { reset(); }
};
#pragma mark -
#pragma mark MVKCombinedImageSamplerDescriptor
/** Represents a Vulkan descriptor tracking a combined image and sampler. */
class MVKCombinedImageSamplerDescriptor : public MVKImageDescriptor, public MVKSamplerDescriptorMixin {
public:
VkDescriptorType getDescriptorType() override { return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; }
void bind(MVKCommandEncoder* cmdEncoder,
VkDescriptorType descriptorType,
uint32_t descriptorIndex,
bool stages[],
MVKShaderResourceBinding& mtlIndexes,
MVKVector<uint32_t>& dynamicOffsets,
uint32_t* pDynamicOffsetIndex) override;
void write(MVKDescriptorSet* mvkDescSet,
VkDescriptorType descriptorType,
uint32_t srcIndex,
size_t stride,
const void* pData) override;
void read(MVKDescriptorSet* mvkDescSet,
VkDescriptorType descriptorType,
uint32_t dstIndex,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
VkBufferView* pTexelBufferView,
VkWriteDescriptorSetInlineUniformBlockEXT* inlineUniformBlock) override;
void setLayout(MVKDescriptorSetLayoutBinding* dslBinding, uint32_t index) override;
void reset() override;
~MVKCombinedImageSamplerDescriptor() { reset(); }
};
#pragma mark -
#pragma mark MVKTexelBufferDescriptor
/** Represents a Vulkan descriptor tracking a texel buffer. */
class MVKTexelBufferDescriptor : public MVKDescriptor {
public:
void bind(MVKCommandEncoder* cmdEncoder,
VkDescriptorType descriptorType,
uint32_t descriptorIndex,
bool stages[],
MVKShaderResourceBinding& mtlIndexes,
MVKVector<uint32_t>& dynamicOffsets,
uint32_t* pDynamicOffsetIndex) override;
void write(MVKDescriptorSet* mvkDescSet,
VkDescriptorType descriptorType,
uint32_t srcIndex,
size_t stride,
const void* pData) override;
void read(MVKDescriptorSet* mvkDescSet,
VkDescriptorType descriptorType,
uint32_t dstIndex,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
VkBufferView* pTexelBufferView,
VkWriteDescriptorSetInlineUniformBlockEXT* inlineUniformBlock) override;
void reset() override;
~MVKTexelBufferDescriptor() { reset(); }
protected:
MVKBufferView* _mvkBufferView = nullptr;
};
#pragma mark -
#pragma mark MVKUniformTexelBufferDescriptor
class MVKUniformTexelBufferDescriptor : public MVKTexelBufferDescriptor {
public:
VkDescriptorType getDescriptorType() override { return VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; }
};
#pragma mark -
#pragma mark MVKStorageTexelBufferDescriptor
class MVKStorageTexelBufferDescriptor : public MVKTexelBufferDescriptor {
public:
VkDescriptorType getDescriptorType() override { return VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; }
};

File diff suppressed because it is too large Load Diff

View File

@ -18,112 +18,16 @@
#pragma once
#include "MVKDevice.h"
#include "MVKImage.h"
#include "MVKVector.h"
#include <MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.h>
#include "MVKDescriptor.h"
#include <unordered_set>
#include <unordered_map>
#include <vector>
class MVKDescriptorPool;
class MVKDescriptorBinding;
class MVKDescriptorSet;
class MVKDescriptorSetLayout;
class MVKPipelineLayout;
class MVKCommandEncoder;
#pragma mark MVKShaderStageResourceBinding
/** Indicates the Metal resource indexes used by a single shader stage in a descriptor binding. */
typedef struct MVKShaderStageResourceBinding {
uint32_t bufferIndex = 0;
uint32_t textureIndex = 0;
uint32_t samplerIndex = 0;
MVKShaderStageResourceBinding operator+ (const MVKShaderStageResourceBinding& rhs);
MVKShaderStageResourceBinding& operator+= (const MVKShaderStageResourceBinding& rhs);
} MVKShaderStageResourceBinding;
#pragma mark MVKShaderResourceBinding
/** Indicates the Metal resource indexes used by each shader stage in a descriptor binding. */
typedef struct MVKShaderResourceBinding {
MVKShaderStageResourceBinding stages[kMVKShaderStageMax];
uint32_t getMaxBufferIndex();
uint32_t getMaxTextureIndex();
uint32_t getMaxSamplerIndex();
MVKShaderResourceBinding operator+ (const MVKShaderResourceBinding& rhs);
MVKShaderResourceBinding& operator+= (const MVKShaderResourceBinding& rhs);
} MVKShaderResourceBinding;
#pragma mark -
#pragma mark MVKDescriptorSetLayoutBinding
/** Represents a Vulkan descriptor set layout binding. */
class MVKDescriptorSetLayoutBinding : public MVKBaseDeviceObject {
public:
/** Returns the Vulkan API opaque object controlling this object. */
MVKVulkanAPIObject* getVulkanAPIObject() override;
/** Encodes this binding layout and the specified descriptor set binding on the specified command encoder. */
void bind(MVKCommandEncoder* cmdEncoder,
MVKDescriptorBinding& descBinding,
MVKShaderResourceBinding& dslMTLRezIdxOffsets,
MVKVector<uint32_t>& dynamicOffsets,
uint32_t* pDynamicOffsetIndex);
/** Encodes this binding layout and the specified descriptor binding on the specified command encoder immediately. */
void push(MVKCommandEncoder* cmdEncoder,
uint32_t& dstArrayElement,
uint32_t& descriptorCount,
uint32_t& descriptorsPushed,
VkDescriptorType descriptorType,
size_t stride,
const void* pData,
MVKShaderResourceBinding& dslMTLRezIdxOffsets);
/** Populates the specified shader converter context, at the specified descriptor set binding. */
void populateShaderConverterContext(mvk::SPIRVToMSLConversionConfiguration& context,
MVKShaderResourceBinding& dslMTLRezIdxOffsets,
uint32_t dslIndex);
/** Constructs an instance. */
MVKDescriptorSetLayoutBinding(MVKDevice* device,
MVKDescriptorSetLayout* layout,
const VkDescriptorSetLayoutBinding* pBinding);
MVKDescriptorSetLayoutBinding(const MVKDescriptorSetLayoutBinding& binding);
/** Destuctor. */
~MVKDescriptorSetLayoutBinding() override;
protected:
friend class MVKDescriptorBinding;
friend class MVKPipelineLayout;
void initMetalResourceIndexOffsets(MVKShaderStageResourceBinding* pBindingIndexes,
MVKShaderStageResourceBinding* pDescSetCounts,
const VkDescriptorSetLayoutBinding* pBinding);
bool validate(MVKSampler* mvkSampler);
MVKDescriptorSetLayout* _layout;
VkDescriptorSetLayoutBinding _info;
std::vector<MVKSampler*> _immutableSamplers;
MVKShaderResourceBinding _mtlResourceIndexOffsets;
bool _applyToStage[kMVKShaderStageMax];
};
#pragma mark -
#pragma mark MVKDescriptorSetLayout
@ -169,8 +73,6 @@ public:
MVKDescriptorSetLayout(MVKDevice* device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo);
~MVKDescriptorSetLayout();
protected:
friend class MVKDescriptorSetLayoutBinding;
@ -179,109 +81,15 @@ protected:
friend class MVKDescriptorPool;
void propogateDebugName() override {}
void addDescriptorPool(MVKDescriptorPool* mvkDescPool) { _descriptorPools.insert(mvkDescPool); }
void removeDescriptorPool(MVKDescriptorPool* mvkDescPool) { _descriptorPools.erase(mvkDescPool); }
inline uint32_t getDescriptorCount() { return _descriptorCount; }
uint32_t getDescriptorIndex(uint32_t binding, uint32_t elementIndex);
inline MVKDescriptorSetLayoutBinding* getBinding(uint32_t binding) { return &_bindings[_bindingToIndex[binding]]; }
MVKVectorInline<MVKDescriptorSetLayoutBinding, 1> _bindings;
std::vector<MVKDescriptorSetLayoutBinding> _bindings;
std::unordered_map<uint32_t, uint32_t> _bindingToIndex;
MVKShaderResourceBinding _mtlResourceCounts;
std::unordered_set<MVKDescriptorPool*> _descriptorPools;
bool _isPushDescriptorLayout : 1;
};
#pragma mark -
#pragma mark MVKDescriptorBinding
/** Represents a Vulkan descriptor binding. */
class MVKDescriptorBinding : public MVKBaseObject {
public:
/** Returns the Vulkan API opaque object controlling this object. */
MVKVulkanAPIObject* getVulkanAPIObject() override;
/**
* Updates the internal element bindings from the specified content.
*
* Depending on the descriptor type of the descriptor set, the binding content is
* extracted from one of the specified pImageInfo, pBufferInfo, or pTexelBufferView
* arrays, and the other arrays are ignored (and may be a null pointer).
*
* The srcStartIndex parameter indicates the index of the initial pDescriptor element
* at which to start reading, and the dstStartIndex parameter indicates the index of
* the initial internal element at which to start writing.
*
* The count parameter indicates how many internal elements should be updated, and
* may be larger than the number of descriptors that can be updated in this instance.
* If count is larger than the number of internal elements remaining after dstStartIndex,
* only the remaining elements will be updated, and the number of pDescriptors that were
* not read will be returned, so that the remaining unread pDescriptors can be read by
* another MVKDescriptorBinding instance within the same descriptor set. If all of the
* remaining pDescriptors are read by this intance, this function returns zero, indicating
* that there is nothing left to be read by another MVKDescriptorBinding instance.
*/
uint32_t writeBindings(uint32_t srcStartIndex,
uint32_t dstStartIndex,
uint32_t count,
size_t stride,
const void* pData);
/**
* Updates the specified content arrays from the internal element bindings.
*
* Depending on the descriptor type of the descriptor set, the binding content is
* placed into one of the specified pImageInfo, pBufferInfo, or pTexelBufferView
* arrays, and the other arrays are ignored (and may be a null pointer).
*
* The srcStartIndex parameter indicates the index of the initial internal element
* at which to start reading, and the dstStartIndex parameter indicates the index of
* the initial pDescriptor element at which to start writing.
*
* The count parameter indicates how many internal elements should be read, and may
* be larger than the number of descriptors that can be read from this instance.
* If count is larger than the number of internal elements remaining after srcStartIndex,
* only the remaining elements will be read, and the number of pDescriptors that were not
* updated will be returned, so that the remaining pDescriptors can be updated by another
* MVKDescriptorBinding instance within the same descriptor set. If all of the remaining
* pDescriptors are updated by this intance, this function returns zero, indicating that
* there is nothing left to be updated by another MVKDescriptorBinding instance.
*/
uint32_t readBindings(uint32_t srcStartIndex,
uint32_t dstStartIndex,
uint32_t count,
VkDescriptorType& descType,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
VkBufferView* pTexelBufferView,
VkWriteDescriptorSetInlineUniformBlockEXT* inlineUniformBlock);
/** Returns whether this instance represents the specified Vulkan binding point. */
bool hasBinding(uint32_t binding);
/** Constructs an instance. */
MVKDescriptorBinding(MVKDescriptorSet* pDescSet, MVKDescriptorSetLayoutBinding* pBindingLayout);
/** Destructor. */
~MVKDescriptorBinding();
protected:
friend class MVKDescriptorSetLayoutBinding;
void initMTLSamplers(MVKDescriptorSetLayoutBinding* pBindingLayout);
bool validate(MVKSampler* mvkSampler) { return _pBindingLayout->validate(mvkSampler); }
MVKDescriptorSet* _pDescSet;
MVKDescriptorSetLayoutBinding* _pBindingLayout;
std::vector<VkDescriptorImageInfo> _imageBindings;
std::vector<VkDescriptorBufferInfo> _bufferBindings;
std::vector<VkWriteDescriptorSetInlineUniformBlockEXT> _inlineBindings;
std::vector<VkBufferView> _texelBufferBindings;
std::vector<id<MTLBuffer>> _mtlBuffers;
std::vector<NSUInteger> _mtlBufferOffsets;
std::vector<id<MTLTexture>> _mtlTextures;
std::vector<id<MTLSamplerState>> _mtlSamplers;
bool _hasDynamicSamplers;
uint32_t _descriptorCount;
bool _isPushDescriptorLayout;
};
@ -289,7 +97,7 @@ protected:
#pragma mark MVKDescriptorSet
/** Represents a Vulkan descriptor set. */
class MVKDescriptorSet : public MVKVulkanAPIDeviceObject, public MVKLinkableMixin<MVKDescriptorSet> {
class MVKDescriptorSet : public MVKVulkanAPIDeviceObject {
public:
@ -299,43 +107,106 @@ public:
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT; }
/** Returns the descriptor type for the specified binding number. */
VkDescriptorType getDescriptorType(uint32_t binding);
/** Updates the resource bindings in this instance from the specified content. */
template<typename DescriptorAction>
void writeDescriptorSets(const DescriptorAction* pDescriptorAction,
size_t stride,
const void* pData);
void write(const DescriptorAction* pDescriptorAction, size_t stride, const void* pData);
/**
* Reads the resource bindings defined in the specified content
* from this instance into the specified collection of bindings.
*/
void readDescriptorSets(const VkCopyDescriptorSet* pDescriptorCopies,
VkDescriptorType& descType,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
VkBufferView* pTexelBufferView,
VkWriteDescriptorSetInlineUniformBlockEXT* pInlineUniformBlock);
void read(const VkCopyDescriptorSet* pDescriptorCopies,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
VkBufferView* pTexelBufferView,
VkWriteDescriptorSetInlineUniformBlockEXT* pInlineUniformBlock);
MVKDescriptorSet(MVKDevice* device) : MVKVulkanAPIDeviceObject(device) {}
MVKDescriptorSet(MVKDescriptorSetLayout* layout, MVKDescriptorPool* pool);
~MVKDescriptorSet() override;
protected:
friend class MVKDescriptorSetLayout;
friend class MVKDescriptorSetLayoutBinding;
friend class MVKDescriptorPool;
void propogateDebugName() override {}
void setLayout(MVKDescriptorSetLayout* layout);
MVKDescriptorBinding* getBinding(uint32_t binding);
inline MVKDescriptor* getDescriptor(uint32_t index) { return _descriptors[index]; }
MVKDescriptorSetLayout* _pLayout = nullptr;
MVKVectorInline<MVKDescriptorBinding, 1> _bindings;
MVKDescriptorSetLayout* _layout;
MVKDescriptorPool* _pool;
std::vector<MVKDescriptor*> _descriptors;
};
#pragma mark -
#pragma mark MVKDescriptorTypePreallocation
/** Support class for MVKDescriptorPool that holds preallocated instances of a single concrete descriptor class. */
template<class DescriptorClass>
class MVKDescriptorTypePreallocation : public MVKBaseObject {
public:
/** Returns the Vulkan API opaque object controlling this object. */
MVKVulkanAPIObject* getVulkanAPIObject() override { return nullptr; };
MVKDescriptorTypePreallocation(const VkDescriptorPoolCreateInfo* pCreateInfo,
VkDescriptorType descriptorType);
protected:
friend class MVKPreallocatedDescriptors;
VkResult allocateDescriptor(MVKDescriptor** pMVKDesc);
bool findDescriptor(uint32_t endIndex, MVKDescriptor** pMVKDesc);
void freeDescriptor(MVKDescriptor* mvkDesc);
std::vector<DescriptorClass> _descriptors;
std::vector<bool> _availability;
uint32_t _nextAvailableIndex;
bool _supportAvailability;
};
#pragma mark -
#pragma mark MVKPreallocatedDescriptors
/** Support class for MVKDescriptorPool that holds preallocated instances of all concrete descriptor classes. */
class MVKPreallocatedDescriptors : public MVKBaseObject {
public:
/** Returns the Vulkan API opaque object controlling this object. */
MVKVulkanAPIObject* getVulkanAPIObject() override { return nullptr; };
MVKPreallocatedDescriptors(const VkDescriptorPoolCreateInfo* pCreateInfo);
protected:
friend class MVKDescriptorPool;
VkResult allocateDescriptor(VkDescriptorType descriptorType, MVKDescriptor** pMVKDesc);
void freeDescriptor(MVKDescriptor* mvkDesc);
MVKDescriptorTypePreallocation<MVKUniformBufferDescriptor> _uniformBufferDescriptors;
MVKDescriptorTypePreallocation<MVKStorageBufferDescriptor> _storageBufferDescriptors;
MVKDescriptorTypePreallocation<MVKUniformBufferDynamicDescriptor> _uniformBufferDynamicDescriptors;
MVKDescriptorTypePreallocation<MVKStorageBufferDynamicDescriptor> _storageBufferDynamicDescriptors;
MVKDescriptorTypePreallocation<MVKInlineUniformBlockDescriptor> _inlineUniformBlockDescriptors;
MVKDescriptorTypePreallocation<MVKSampledImageDescriptor> _sampledImageDescriptors;
MVKDescriptorTypePreallocation<MVKStorageImageDescriptor> _storageImageDescriptors;
MVKDescriptorTypePreallocation<MVKInputAttachmentDescriptor> _inputAttachmentDescriptors;
MVKDescriptorTypePreallocation<MVKSamplerDescriptor> _samplerDescriptors;
MVKDescriptorTypePreallocation<MVKCombinedImageSamplerDescriptor> _combinedImageSamplerDescriptors;
MVKDescriptorTypePreallocation<MVKUniformTexelBufferDescriptor> _uniformTexelBufferDescriptors;
MVKDescriptorTypePreallocation<MVKStorageTexelBufferDescriptor> _storageTexelBufferDescriptors;
};
#pragma mark -
#pragma mark MVKDescriptorPool
typedef MVKDeviceObjectPool<MVKDescriptorSet> MVKDescriptorSetPool;
/** Represents a Vulkan descriptor pool. */
class MVKDescriptorPool : public MVKVulkanAPIDeviceObject {
@ -358,23 +229,22 @@ public:
/** Destoys all currently allocated descriptor sets. */
VkResult reset(VkDescriptorPoolResetFlags flags);
/** Removes the pool associated with a descriptor set layout. */
void removeDescriptorSetPool(MVKDescriptorSetLayout* mvkDescSetLayout);
/** Constructs an instance for the specified device. */
MVKDescriptorPool(MVKDevice* device, const VkDescriptorPoolCreateInfo* pCreateInfo);
/** Destructor. */
~MVKDescriptorPool() override;
protected:
friend class MVKDescriptorSet;
void propogateDebugName() override {}
MVKDescriptorSetPool* getDescriptorSetPool(MVKDescriptorSetLayout* mvkDescSetLayout);
void returnDescriptorSet(MVKDescriptorSet* mvkDescSet);
VkResult allocateDescriptorSet(MVKDescriptorSetLayout* mvkDSL, VkDescriptorSet* pVKDS);
void freeDescriptorSet(MVKDescriptorSet* mvkDS);
VkResult allocateDescriptor(VkDescriptorType descriptorType, MVKDescriptor** pMVKDesc);
void freeDescriptor(MVKDescriptor* mvkDesc);
uint32_t _maxSets;
std::unordered_set<MVKDescriptorSet*> _allocatedSets;
std::unordered_map<MVKDescriptorSetLayout*, MVKDescriptorSetPool*> _descriptorSetPools;
MVKPreallocatedDescriptors* _preallocatedDescriptors;
};
@ -438,7 +308,3 @@ void mvkPopulateShaderConverterContext(mvk::SPIRVToMSLConversionConfiguration& c
uint32_t descriptorSetIndex,
uint32_t bindingIndex,
MVKSampler* immutableSampler);

File diff suppressed because it is too large Load Diff

View File

@ -1143,7 +1143,7 @@ MTLSamplerDescriptor* MVKSampler::newMTLSamplerDescriptor(const VkSamplerCreateI
// If compareEnable is true, but dynamic samplers with depth compare are not available
// on this device, this sampler must only be used as an immutable sampler, and will
// be automatically hardcoded into the shader MSL. An error will be triggered if this
// sampler is used to update or push a descriptor binding.
// sampler is used to update or push a descriptor.
if (pCreateInfo->compareEnable && !_requiresConstExprSampler) {
mtlSampDesc.compareFunctionMVK = mvkMTLCompareFunctionFromVkCompareOp(pCreateInfo->compareOp);
}

View File

@ -117,6 +117,9 @@ public:
if (_configurationResult == VK_SUCCESS) { _configurationResult = vkResult; }
}
/** Returns whether the configuration was successful. */
inline bool wasConfigurationSuccessful() { return _configurationResult == VK_SUCCESS; }
/** Resets the indication of the success of the configuration of this instance back to VK_SUCCESS. */
inline void clearConfigurationResult() { _configurationResult = VK_SUCCESS; }