Log and return VK_ERROR_FEATURE_NOT_PRESENT error if array
of textures or array of samplers requested but not supported. Add MVKPhysicalDeviceMetalFeatures::arrayOfTextures & arrayOfSamplers flags. MVKDescriptorSetLayoutBinding log and return appropriate error. Add MVKPhysicalDevice::getName() and MVKDevice::getName() functions.
This commit is contained in:
parent
e792a3a575
commit
16377056f0
@ -483,6 +483,8 @@ typedef struct {
|
||||
VkSampleCountFlags supportedSampleCounts; /**< A bitmask identifying the sample counts supported by the device. */
|
||||
uint32_t minSwapchainImageCount; /**< The minimum number of swapchain images that can be supported by a surface. */
|
||||
uint32_t maxSwapchainImageCount; /**< The maximum number of swapchain images that can be supported by a surface. */
|
||||
VkBool32 arrayOfTextures; /**< If true, arrays of textures is supported. */
|
||||
VkBool32 arrayOfSamplers; /**< If true, arrays of texture samplers is supported. */
|
||||
} MVKPhysicalDeviceMetalFeatures;
|
||||
|
||||
/**
|
||||
|
@ -73,7 +73,7 @@ typedef struct MVKShaderResourceBinding {
|
||||
#pragma mark MVKDescriptorSetLayoutBinding
|
||||
|
||||
/** Represents a Vulkan descriptor set layout binding. */
|
||||
class MVKDescriptorSetLayoutBinding : public MVKConfigurableObject {
|
||||
class MVKDescriptorSetLayoutBinding : public MVKBaseDeviceObject {
|
||||
|
||||
public:
|
||||
|
||||
@ -100,7 +100,8 @@ public:
|
||||
uint32_t dslIndex);
|
||||
|
||||
/** Constructs an instance. */
|
||||
MVKDescriptorSetLayoutBinding(MVKDescriptorSetLayout* layout,
|
||||
MVKDescriptorSetLayoutBinding(MVKDevice* device,
|
||||
MVKDescriptorSetLayout* layout,
|
||||
const VkDescriptorSetLayoutBinding* pBinding);
|
||||
|
||||
MVKDescriptorSetLayoutBinding(const MVKDescriptorSetLayoutBinding& binding);
|
||||
@ -112,9 +113,9 @@ protected:
|
||||
friend class MVKDescriptorBinding;
|
||||
friend class MVKPipelineLayout;
|
||||
|
||||
VkResult initMetalResourceIndexOffsets(MVKShaderStageResourceBinding* pBindingIndexes,
|
||||
MVKShaderStageResourceBinding* pDescSetCounts,
|
||||
const VkDescriptorSetLayoutBinding* pBinding);
|
||||
void initMetalResourceIndexOffsets(MVKShaderStageResourceBinding* pBindingIndexes,
|
||||
MVKShaderStageResourceBinding* pDescSetCounts,
|
||||
const VkDescriptorSetLayoutBinding* pBinding);
|
||||
|
||||
VkDescriptorSetLayoutBinding _info;
|
||||
std::vector<MVKSampler*> _immutableSamplers;
|
||||
|
@ -405,30 +405,31 @@ void MVKDescriptorSetLayoutBinding::populateShaderConverterContext(SPIRVToMSLCon
|
||||
}
|
||||
}
|
||||
|
||||
MVKDescriptorSetLayoutBinding::MVKDescriptorSetLayoutBinding(MVKDescriptorSetLayout* layout,
|
||||
const VkDescriptorSetLayoutBinding* pBinding) : MVKConfigurableObject() {
|
||||
MVKDescriptorSetLayoutBinding::MVKDescriptorSetLayoutBinding(MVKDevice* device,
|
||||
MVKDescriptorSetLayout* layout,
|
||||
const VkDescriptorSetLayoutBinding* pBinding) : MVKBaseDeviceObject(device) {
|
||||
// Determine the shader stages used by this binding
|
||||
_applyToVertexStage = mvkAreFlagsEnabled(pBinding->stageFlags, VK_SHADER_STAGE_VERTEX_BIT);
|
||||
_applyToFragmentStage = mvkAreFlagsEnabled(pBinding->stageFlags, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
_applyToComputeStage = mvkAreFlagsEnabled(pBinding->stageFlags, VK_SHADER_STAGE_COMPUTE_BIT);
|
||||
|
||||
// If this binding is used by the vertex shader, set the Metal resource index
|
||||
if (_applyToVertexStage) {
|
||||
setConfigurationResult(initMetalResourceIndexOffsets(&_mtlResourceIndexOffsets.vertexStage,
|
||||
&layout->_mtlResourceCounts.vertexStage, pBinding));
|
||||
}
|
||||
// If this binding is used by the vertex shader, set the Metal resource index
|
||||
if (_applyToVertexStage) {
|
||||
initMetalResourceIndexOffsets(&_mtlResourceIndexOffsets.vertexStage,
|
||||
&layout->_mtlResourceCounts.vertexStage, pBinding);
|
||||
}
|
||||
|
||||
// If this binding is used by the fragment shader, set the Metal resource index
|
||||
if (_applyToFragmentStage) {
|
||||
setConfigurationResult(initMetalResourceIndexOffsets(&_mtlResourceIndexOffsets.fragmentStage,
|
||||
&layout->_mtlResourceCounts.fragmentStage, pBinding));
|
||||
}
|
||||
// If this binding is used by the fragment shader, set the Metal resource index
|
||||
if (_applyToFragmentStage) {
|
||||
initMetalResourceIndexOffsets(&_mtlResourceIndexOffsets.fragmentStage,
|
||||
&layout->_mtlResourceCounts.fragmentStage, pBinding);
|
||||
}
|
||||
|
||||
// If this binding is used by a compute shader, set the Metal resource index
|
||||
if (_applyToComputeStage) {
|
||||
setConfigurationResult(initMetalResourceIndexOffsets(&_mtlResourceIndexOffsets.computeStage,
|
||||
&layout->_mtlResourceCounts.computeStage, pBinding));
|
||||
}
|
||||
// If this binding is used by a compute shader, set the Metal resource index
|
||||
if (_applyToComputeStage) {
|
||||
initMetalResourceIndexOffsets(&_mtlResourceIndexOffsets.computeStage,
|
||||
&layout->_mtlResourceCounts.computeStage, pBinding);
|
||||
}
|
||||
|
||||
// If immutable samplers are defined, copy them in
|
||||
if ( pBinding->pImmutableSamplers &&
|
||||
@ -446,7 +447,7 @@ MVKDescriptorSetLayoutBinding::MVKDescriptorSetLayoutBinding(MVKDescriptorSetLay
|
||||
}
|
||||
|
||||
MVKDescriptorSetLayoutBinding::MVKDescriptorSetLayoutBinding(const MVKDescriptorSetLayoutBinding& binding) :
|
||||
MVKConfigurableObject(), _info(binding._info), _immutableSamplers(binding._immutableSamplers),
|
||||
MVKBaseDeviceObject(binding._device), _info(binding._info), _immutableSamplers(binding._immutableSamplers),
|
||||
_mtlResourceIndexOffsets(binding._mtlResourceIndexOffsets),
|
||||
_applyToVertexStage(binding._applyToVertexStage), _applyToFragmentStage(binding._applyToFragmentStage),
|
||||
_applyToComputeStage(binding._applyToComputeStage) {
|
||||
@ -461,17 +462,19 @@ MVKDescriptorSetLayoutBinding::~MVKDescriptorSetLayoutBinding() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the appropriate Metal resource indexes within this binding from the
|
||||
* specified descriptor set binding counts, and updates those counts accordingly.
|
||||
*/
|
||||
VkResult MVKDescriptorSetLayoutBinding::initMetalResourceIndexOffsets(MVKShaderStageResourceBinding* pBindingIndexes,
|
||||
MVKShaderStageResourceBinding* pDescSetCounts,
|
||||
const VkDescriptorSetLayoutBinding* pBinding) {
|
||||
// Sets the appropriate Metal resource indexes within this binding from the
|
||||
// specified descriptor set binding counts, and updates those counts accordingly.
|
||||
void MVKDescriptorSetLayoutBinding::initMetalResourceIndexOffsets(MVKShaderStageResourceBinding* pBindingIndexes,
|
||||
MVKShaderStageResourceBinding* pDescSetCounts,
|
||||
const VkDescriptorSetLayoutBinding* pBinding) {
|
||||
switch (pBinding->descriptorType) {
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
||||
pBindingIndexes->samplerIndex = pDescSetCounts->samplerIndex;
|
||||
pDescSetCounts->samplerIndex += pBinding->descriptorCount;
|
||||
|
||||
if (pBinding->descriptorCount > 1 && !_device->_pMetalFeatures->arrayOfSamplers) {
|
||||
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_FEATURE_NOT_PRESENT, "Device %s does not support arrays of samplers.", _device->getName()));
|
||||
}
|
||||
break;
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||
@ -479,6 +482,15 @@ VkResult MVKDescriptorSetLayoutBinding::initMetalResourceIndexOffsets(MVKShaderS
|
||||
pDescSetCounts->textureIndex += pBinding->descriptorCount;
|
||||
pBindingIndexes->samplerIndex = pDescSetCounts->samplerIndex;
|
||||
pDescSetCounts->samplerIndex += pBinding->descriptorCount;
|
||||
|
||||
if (pBinding->descriptorCount > 1) {
|
||||
if ( !_device->_pMetalFeatures->arrayOfTextures ) {
|
||||
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_FEATURE_NOT_PRESENT, "Device %s does not support arrays of textures.", _device->getName()));
|
||||
}
|
||||
if ( !_device->_pMetalFeatures->arrayOfSamplers ) {
|
||||
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_FEATURE_NOT_PRESENT, "Device %s does not support arrays of samplers.", _device->getName()));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||
@ -488,6 +500,10 @@ VkResult MVKDescriptorSetLayoutBinding::initMetalResourceIndexOffsets(MVKShaderS
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
||||
pBindingIndexes->textureIndex = pDescSetCounts->textureIndex;
|
||||
pDescSetCounts->textureIndex += pBinding->descriptorCount;
|
||||
|
||||
if (pBinding->descriptorCount > 1 && !_device->_pMetalFeatures->arrayOfTextures) {
|
||||
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_FEATURE_NOT_PRESENT, "Device %s does not support arrays of textures.", _device->getName()));
|
||||
}
|
||||
break;
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
||||
@ -501,7 +517,6 @@ VkResult MVKDescriptorSetLayoutBinding::initMetalResourceIndexOffsets(MVKShaderS
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@ -634,7 +649,7 @@ MVKDescriptorSetLayout::MVKDescriptorSetLayout(MVKDevice* device,
|
||||
// Create the descriptor bindings
|
||||
_bindings.reserve(pCreateInfo->bindingCount);
|
||||
for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) {
|
||||
_bindings.emplace_back(this, &pCreateInfo->pBindings[i]);
|
||||
_bindings.emplace_back(_device, this, &pCreateInfo->pBindings[i]);
|
||||
_bindingToIndex[pCreateInfo->pBindings[i].binding] = i;
|
||||
setConfigurationResult(_bindings.back().getConfigurationResult());
|
||||
}
|
||||
|
@ -90,6 +90,9 @@ public:
|
||||
/** Populates the specified structure with the properties of this device. */
|
||||
void getProperties(VkPhysicalDeviceProperties2* properties);
|
||||
|
||||
/** Returns the name of this device. */
|
||||
inline const char* getName() { return _properties.deviceName; }
|
||||
|
||||
/** Returns whether the specified format is supported on this device. */
|
||||
bool getFormatIsSupported(VkFormat format);
|
||||
|
||||
@ -315,6 +318,9 @@ public:
|
||||
/** Returns the physical device underlying this logical device. */
|
||||
inline MVKPhysicalDevice* getPhysicalDevice() { return _physicalDevice; }
|
||||
|
||||
/** Returns the name of this device. */
|
||||
inline const char* getName() { return _pProperties->deviceName; }
|
||||
|
||||
/** Returns the common resource factory for creating command resources. */
|
||||
inline MVKCommandResourceFactory* getCommandResourceFactory() { return _commandResourceFactory; }
|
||||
|
||||
|
@ -618,6 +618,14 @@ void MVKPhysicalDevice::initMetalFeatures() {
|
||||
_metalFeatures.mtlBufferAlignment = 16; // Min float4 alignment for typical vertex buffers. MTLBuffer may go down to 4 bytes for other data.
|
||||
_metalFeatures.maxTextureDimension = (16 * KIBI);
|
||||
}
|
||||
|
||||
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily3_v2] ) {
|
||||
_metalFeatures.arrayOfTextures = true;
|
||||
}
|
||||
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily3_v3] ) {
|
||||
_metalFeatures.arrayOfSamplers = true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if MVK_MACOS
|
||||
@ -642,6 +650,8 @@ void MVKPhysicalDevice::initMetalFeatures() {
|
||||
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_macOS_GPUFamily1_v3] ) {
|
||||
_metalFeatures.mslVersion = SPIRVToMSLConverterOptions::makeMSLVersion(2);
|
||||
_metalFeatures.texelBuffers = true;
|
||||
_metalFeatures.arrayOfTextures = true;
|
||||
_metalFeatures.arrayOfSamplers = true;
|
||||
_metalFeatures.presentModeImmediate = true;
|
||||
}
|
||||
|
||||
@ -683,6 +693,9 @@ void MVKPhysicalDevice::initFeatures() {
|
||||
_features.shaderInt16 = true;
|
||||
_features.multiDrawIndirect = true;
|
||||
|
||||
_features.shaderSampledImageArrayDynamicIndexing = _metalFeatures.arrayOfTextures;
|
||||
_features.shaderStorageImageArrayDynamicIndexing = _metalFeatures.arrayOfTextures;
|
||||
|
||||
if (_metalFeatures.indirectDrawing && _metalFeatures.baseVertexInstanceDrawing) {
|
||||
_features.drawIndirectFirstInstance = true;
|
||||
}
|
||||
@ -696,10 +709,6 @@ void MVKPhysicalDevice::initFeatures() {
|
||||
|
||||
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily3_v1] ) {
|
||||
_features.occlusionQueryPrecise = true;
|
||||
}
|
||||
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily3_v2] ) {
|
||||
_features.shaderSampledImageArrayDynamicIndexing = true;
|
||||
_features.shaderStorageImageArrayDynamicIndexing = true;
|
||||
}
|
||||
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily2_v4] ) {
|
||||
_features.depthClamp = true;
|
||||
@ -720,8 +729,6 @@ void MVKPhysicalDevice::initFeatures() {
|
||||
|
||||
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_macOS_GPUFamily1_v3] ) {
|
||||
_features.multiViewport = true;
|
||||
_features.shaderSampledImageArrayDynamicIndexing = true;
|
||||
_features.shaderStorageImageArrayDynamicIndexing = true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user