From cc2dd1cc213c149bafb26f85e4605d4a6fd762ec Mon Sep 17 00:00:00 2001 From: Bill Hollings Date: Mon, 25 Mar 2019 11:48:48 -0400 Subject: [PATCH 1/2] Clean up sparse binding functions. Remove "unimplemented" error reporting from sparse binding functions. As per Vulkan spec, sparse binding query functions simply return zero responses. vkQueueBindSparse() returns VK_ERROR_FEATURE_NOT_PRESENT error. --- MoltenVK/MoltenVK/Vulkan/vulkan.mm | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index 71a9fd61..34d86756 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -366,7 +366,10 @@ MVK_PUBLIC_SYMBOL void vkGetImageSparseMemoryRequirements( uint32_t* pNumRequirements, VkSparseImageMemoryRequirements* pSparseMemoryRequirements) { - MVKLogUnimplemented("vkGetImageSparseMemoryRequirements"); + // Metal does not support sparse images. + // Vulkan spec: "If the image was not created with VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT then + // pSparseMemoryRequirementCount will be set to zero and pSparseMemoryRequirements will not be written to.". + *pNumRequirements = 0; } @@ -380,7 +383,10 @@ MVK_PUBLIC_SYMBOL void vkGetPhysicalDeviceSparseImageFormatProperties( uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties) { - MVKLogUnimplemented("vkGetPhysicalDeviceSparseImageFormatProperties"); + // Metal does not support sparse images. + // Vulkan spec: "If VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT is not supported for the given arguments, + // pPropertyCount will be set to zero upon return, and no data will be written to pProperties.". + *pPropertyCount = 0; } @@ -390,7 +396,7 @@ MVK_PUBLIC_SYMBOL VkResult vkQueueBindSparse( const VkBindSparseInfo* pBindInfo, VkFence fence) { - return MVKLogUnimplemented("vkQueueBindSparse"); + return mvkNotifyErrorWithText(VK_ERROR_FEATURE_NOT_PRESENT, "vkQueueBindSparse(): Sparse binding is not supported."); } MVK_PUBLIC_SYMBOL VkResult vkCreateFence( @@ -1569,7 +1575,10 @@ MVK_PUBLIC_SYMBOL void vkGetImageSparseMemoryRequirements2KHR( uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2KHR* pSparseMemoryRequirements) { - MVKLogUnimplemented("vkGetImageSparseMemoryRequirements2KHR"); + // Metal does not support sparse images. + // Vulkan spec: "If the image was not created with VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT then + // pSparseMemoryRequirementCount will be set to zero and pSparseMemoryRequirements will not be written to.". + *pSparseMemoryRequirementCount = 0; } @@ -1634,7 +1643,10 @@ MVK_PUBLIC_SYMBOL void vkGetPhysicalDeviceSparseImageFormatProperties2KHR( uint32_t* pPropertyCount, VkSparseImageFormatProperties2KHR* pProperties) { - MVKLogUnimplemented("vkGetPhysicalDeviceSparseImageFormatProperties"); + // Metal does not support sparse images. + // Vulkan spec: "If VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT is not supported for the given arguments, + // pPropertyCount will be set to zero upon return, and no data will be written to pProperties.". + *pPropertyCount = 0; } From 91f78b6beac50369d7b91746e153371292501a60 Mon Sep 17 00:00:00 2001 From: Bill Hollings Date: Mon, 25 Mar 2019 19:58:36 -0400 Subject: [PATCH 2/2] Add support for tracking device features enabled during vkCreateDevice(). Enable device features based on content of pCreateDeviceInfo. Validate requested features are available and return if not. Support returning error from vkCreateDevice(), vkFlushMappedMemoryRanges() and vkInvalidateMappedMemoryRanges(). Update What's New Document. --- Docs/Whats_New.md | 1 + .../MoltenVK/Commands/MVKCmdRenderPass.mm | 4 +- .../MoltenVK/Commands/MVKCommandBuffer.mm | 2 +- .../Commands/MVKCommandEncoderState.mm | 4 +- MoltenVK/MoltenVK/GPUObjects/MVKDevice.h | 20 ++- MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 155 +++++++++++++++++- MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm | 4 +- MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm | 2 +- MoltenVK/MoltenVK/Vulkan/vulkan.mm | 14 +- 9 files changed, 181 insertions(+), 25 deletions(-) diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md index 3d0b6293..e51ec249 100644 --- a/Docs/Whats_New.md +++ b/Docs/Whats_New.md @@ -22,6 +22,7 @@ Released TBD - Add correct function entry point handling. - Add support for `VK_KHR_get_surface_capabilities2` extension. - Implement newer `VK_KHR_swapchain` extension functions. +- Add support for tracking device features enabled during `vkCreateDevice()`. - Allow zero offset and stride combo in `VkVertexInputBindingDescription`. - Fix conditions when multiple functions return VK_INCOMPLETE. - Fix potential memory leak on synchronous command buffer submission. diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.mm b/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.mm index f0802737..2b798977 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.mm @@ -148,7 +148,7 @@ void MVKCmdSetLineWidth::setContent(float lineWidth) { // Validate clearConfigurationResult(); - if (_lineWidth != 1.0 || getDevice()->_pFeatures->wideLines) { + if (_lineWidth != 1.0 || getDevice()->_enabledFeatures.wideLines) { setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdSetLineWidth(): The current device does not support wide lines.")); } } @@ -207,7 +207,7 @@ void MVKCmdSetDepthBounds::setContent(float minDepthBounds, float maxDepthBounds // Validate clearConfigurationResult(); - if (getDevice()->_pFeatures->depthBounds) { + if (getDevice()->_enabledFeatures.depthBounds) { setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdSetDepthBounds(): The current device does not support setting depth bounds.")); } } diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm index 38277446..600f8927 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm @@ -532,7 +532,7 @@ MVKCommandEncoder::MVKCommandEncoder(MVKCommandBuffer* cmdBuffer) : MVKBaseDevic _computeResourcesState(this), _occlusionQueryState(this) { - _pDeviceFeatures = _device->_pFeatures; + _pDeviceFeatures = &_device->_enabledFeatures; _pDeviceMetalFeatures = _device->_pMetalFeatures; _pDeviceProperties = _device->_pProperties; _pDeviceMemoryProperties = _device->_pMemoryProperties; diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm index f62ffd5b..4b8eaec4 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm @@ -73,7 +73,7 @@ void MVKViewportCommandEncoderState::setViewports(const MVKVector & void MVKViewportCommandEncoderState::encodeImpl(uint32_t stage) { if (stage != kMVKGraphicsStageRasterization) { return; } MVKAssert(!_mtlViewports.empty(), "Must specify at least one viewport"); - if (_cmdEncoder->getDevice()->_pFeatures->multiViewport) { + if (_cmdEncoder->_pDeviceFeatures->multiViewport) { [_cmdEncoder->_mtlRenderEncoder setViewports: &_mtlViewports[0] count: _mtlViewports.size()]; } else { [_cmdEncoder->_mtlRenderEncoder setViewport: _mtlViewports[0]]; @@ -115,7 +115,7 @@ void MVKScissorCommandEncoderState::encodeImpl(uint32_t stage) { std::for_each(clippedScissors.begin(), clippedScissors.end(), [this](MTLScissorRect& scissor) { scissor = _cmdEncoder->clipToRenderArea(scissor); }); - if (_cmdEncoder->getDevice()->_pFeatures->multiViewport) { + if (_cmdEncoder->_pDeviceFeatures->multiViewport) { [_cmdEncoder->_mtlRenderEncoder setScissorRects: &clippedScissors[0] count: clippedScissors.size()]; } else { [_cmdEncoder->_mtlRenderEncoder setScissorRect: clippedScissors[0]]; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h index 5aa11f7a..7712bce5 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h @@ -583,8 +583,18 @@ public: /** Pointer to the MoltenVK configuration settings. */ const MVKConfiguration* _pMVKConfig; - /** Pointer to the feature set of the underlying physical device. */ - const VkPhysicalDeviceFeatures* _pFeatures; + /** Device features available and enabled. */ + const VkPhysicalDeviceFeatures _enabledFeatures; + const VkPhysicalDevice16BitStorageFeatures _enabledStorage16Features; + const VkPhysicalDevice8BitStorageFeaturesKHR _enabledStorage8Features; + const VkPhysicalDeviceFloat16Int8FeaturesKHR _enabledF16I8Features; + const VkPhysicalDeviceVariablePointerFeatures _enabledVarPtrFeatures; + const VkPhysicalDeviceHostQueryResetFeaturesEXT _enabledHostQryResetFeatures; + const VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT _enabledVtxAttrDivFeatures; + const VkPhysicalDevicePortabilitySubsetFeaturesEXTX _enabledPortabilityFeatures; + + /** The list of Vulkan extensions, indicating whether each has been enabled by the app for this device. */ + const MVKExtensionList _enabledExtensions; /** Pointer to the Metal-specific features of the underlying physical device. */ const MVKPhysicalDeviceMetalFeatures* _pMetalFeatures; @@ -595,9 +605,6 @@ public: /** Pointer to the memory properties of the underlying physical device. */ const VkPhysicalDeviceMemoryProperties* _pMemoryProperties; - /** The list of Vulkan extensions, indicating whether each has been enabled by the app for this device. */ - const MVKExtensionList _enabledExtensions; - /** Performance statistics. */ MVKPerformanceStatistics _performanceStatistics; @@ -629,6 +636,9 @@ protected: void initPerformanceTracking(); void initPhysicalDevice(MVKPhysicalDevice* physicalDevice); void initQueues(const VkDeviceCreateInfo* pCreateInfo); + void enableFeatures(const VkDeviceCreateInfo* pCreateInfo); + void enableFeatures(const VkBool32* pEnable, const VkBool32* pRequested, const VkBool32* pAvailable, uint32_t count); + void enableExtensions(const VkDeviceCreateInfo* pCreateInfo); const char* getActivityPerformanceDescription(MVKPerformanceTracker& shaderCompilationEvent); uint64_t getPerformanceTimestampImpl(); void addActivityPerformanceImpl(MVKPerformanceTracker& shaderCompilationEvent, diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index 28c47980..d8d9d5f6 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -2036,21 +2036,27 @@ uint32_t MVKDevice::expandVisibilityResultMTLBuffer(uint32_t queryCount) { #pragma mark Construction -MVKDevice::MVKDevice(MVKPhysicalDevice* physicalDevice, const VkDeviceCreateInfo* pCreateInfo) { +MVKDevice::MVKDevice(MVKPhysicalDevice* physicalDevice, const VkDeviceCreateInfo* pCreateInfo) : + _enabledFeatures(), + _enabledStorage16Features(), + _enabledStorage8Features(), + _enabledF16I8Features(), + _enabledVarPtrFeatures(), + _enabledHostQryResetFeatures(), + _enabledVtxAttrDivFeatures(), + _enabledPortabilityFeatures() +{ initPerformanceTracking(); initPhysicalDevice(physicalDevice); + enableFeatures(pCreateInfo); + enableExtensions(pCreateInfo); _globalVisibilityResultMTLBuffer = nil; _globalVisibilityQueryCount = 0; _commandResourceFactory = new MVKCommandResourceFactory(this); - MVKExtensionList* pWritableExtns = (MVKExtensionList*)&_enabledExtensions; - setConfigurationResult(pWritableExtns->enable(pCreateInfo->enabledExtensionCount, - pCreateInfo->ppEnabledExtensionNames, - getInstance()->getDriverLayer()->getSupportedExtensions())); - initQueues(pCreateInfo); string logMsg = "Created VkDevice to run on GPU %s with the following Vulkan extensions enabled:"; @@ -2083,7 +2089,6 @@ void MVKDevice::initPhysicalDevice(MVKPhysicalDevice* physicalDevice) { _physicalDevice = physicalDevice; _pMVKConfig = _physicalDevice->_mvkInstance->getMoltenVKConfiguration(); - _pFeatures = &_physicalDevice->_features; _pMetalFeatures = _physicalDevice->getMetalFeatures(); _pProperties = &_physicalDevice->_properties; _pMemoryProperties = &_physicalDevice->_memoryProperties; @@ -2103,6 +2108,142 @@ void MVKDevice::initPhysicalDevice(MVKPhysicalDevice* physicalDevice) { #endif } +void MVKDevice::enableFeatures(const VkDeviceCreateInfo* pCreateInfo) { + + // Start with all features disabled + memset((void*)&_enabledFeatures, 0, sizeof(_enabledFeatures)); + memset((void*)&_enabledStorage16Features, 0, sizeof(_enabledStorage16Features)); + memset((void*)&_enabledStorage8Features, 0, sizeof(_enabledStorage8Features)); + memset((void*)&_enabledF16I8Features, 0, sizeof(_enabledF16I8Features)); + memset((void*)&_enabledVarPtrFeatures, 0, sizeof(_enabledVarPtrFeatures)); + memset((void*)&_enabledHostQryResetFeatures, 0, sizeof(_enabledHostQryResetFeatures)); + memset((void*)&_enabledVtxAttrDivFeatures, 0, sizeof(_enabledVtxAttrDivFeatures)); + memset((void*)&_enabledPortabilityFeatures, 0, sizeof(_enabledPortabilityFeatures)); + + // Fetch the available physical device features. + VkPhysicalDevicePortabilitySubsetFeaturesEXTX pdPortabilityFeatures; + pdPortabilityFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_EXTX; + pdPortabilityFeatures.pNext = NULL; + + VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT pdVtxAttrDivFeatures; + pdVtxAttrDivFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT; + pdVtxAttrDivFeatures.pNext = &pdPortabilityFeatures; + + VkPhysicalDeviceHostQueryResetFeaturesEXT pdHostQryResetFeatures; + pdHostQryResetFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT; + pdHostQryResetFeatures.pNext = &pdVtxAttrDivFeatures; + + VkPhysicalDeviceVariablePointerFeatures pdVarPtrFeatures; + pdVarPtrFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES; + pdVarPtrFeatures.pNext = &pdHostQryResetFeatures; + + VkPhysicalDeviceFloat16Int8FeaturesKHR pdF16I8Features; + pdF16I8Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR; + pdF16I8Features.pNext = &pdVarPtrFeatures; + + VkPhysicalDevice8BitStorageFeaturesKHR pdStorage8Features; + pdStorage8Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR; + pdStorage8Features.pNext = &pdF16I8Features; + + VkPhysicalDevice16BitStorageFeatures pdStorage16Features; + pdStorage16Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES; + pdStorage16Features.pNext = &pdStorage8Features; + + VkPhysicalDeviceFeatures2 pdFeats2; + pdFeats2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; + pdFeats2.pNext = &pdStorage16Features; + + _physicalDevice->getFeatures(&pdFeats2); + + //Enable device features based on requested and available features + if (pCreateInfo->pEnabledFeatures) { + enableFeatures(&_enabledFeatures.robustBufferAccess, + &pCreateInfo->pEnabledFeatures->robustBufferAccess, + &pdFeats2.features.robustBufferAccess, 55); + } + + auto* next = (MVKVkAPIStructHeader*)pCreateInfo->pNext; + while (next) { + switch ((uint32_t)next->sType) { + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2: { + auto* requestedFeatures = (VkPhysicalDeviceFeatures2*)next; + enableFeatures(&_enabledFeatures.robustBufferAccess, + &requestedFeatures->features.robustBufferAccess, + &pdFeats2.features.robustBufferAccess, 55); + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES: { + auto* requestedFeatures = (VkPhysicalDevice16BitStorageFeatures*)next; + enableFeatures(&_enabledStorage16Features.storageBuffer16BitAccess, + &requestedFeatures->storageBuffer16BitAccess, + &pdStorage16Features.storageBuffer16BitAccess, 4); + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR: { + auto* requestedFeatures = (VkPhysicalDevice8BitStorageFeaturesKHR*)next; + enableFeatures(&_enabledStorage8Features.storageBuffer8BitAccess, + &requestedFeatures->storageBuffer8BitAccess, + &pdStorage8Features.storageBuffer8BitAccess, 3); + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR: { + auto* requestedFeatures = (VkPhysicalDeviceFloat16Int8FeaturesKHR*)next; + enableFeatures(&_enabledF16I8Features.shaderFloat16, + &requestedFeatures->shaderFloat16, + &pdF16I8Features.shaderFloat16, 2); + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES: { + auto* requestedFeatures = (VkPhysicalDeviceVariablePointerFeatures*)next; + enableFeatures(&_enabledVarPtrFeatures.variablePointersStorageBuffer, + &requestedFeatures->variablePointersStorageBuffer, + &pdVarPtrFeatures.variablePointersStorageBuffer, 2); + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT: { + auto* requestedFeatures = (VkPhysicalDeviceHostQueryResetFeaturesEXT*)next; + enableFeatures(&_enabledHostQryResetFeatures.hostQueryReset, + &requestedFeatures->hostQueryReset, + &pdHostQryResetFeatures.hostQueryReset, 1); + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: { + auto* requestedFeatures = (VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT*)next; + enableFeatures(&_enabledVtxAttrDivFeatures.vertexAttributeInstanceRateDivisor, + &requestedFeatures->vertexAttributeInstanceRateDivisor, + &pdVtxAttrDivFeatures.vertexAttributeInstanceRateDivisor, 2); + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_EXTX: { + auto* requestedFeatures = (VkPhysicalDevicePortabilitySubsetFeaturesEXTX*)next; + enableFeatures(&_enabledPortabilityFeatures.triangleFans, + &requestedFeatures->triangleFans, + &pdPortabilityFeatures.triangleFans, 5); + break; + } + default: + break; + } + next = (MVKVkAPIStructHeader*)next->pNext; + } +} + +void MVKDevice::enableFeatures(const VkBool32* pEnable, const VkBool32* pRequested, const VkBool32* pAvailable, uint32_t count) { + for (uint32_t i = 0; i < count; i++) { + ((VkBool32*)pEnable)[i] = pRequested[i] && pAvailable[i]; + if (pRequested[i] && !pAvailable[i]) { + setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateDevice(): Requested feature is not available on this device.")); + } + } +} + +void MVKDevice::enableExtensions(const VkDeviceCreateInfo* pCreateInfo) { + MVKExtensionList* pWritableExtns = (MVKExtensionList*)&_enabledExtensions; + setConfigurationResult(pWritableExtns->enable(pCreateInfo->enabledExtensionCount, + pCreateInfo->ppEnabledExtensionNames, + getInstance()->getDriverLayer()->getSupportedExtensions())); +} + // Create the command queues void MVKDevice::initQueues(const VkDeviceCreateInfo* pCreateInfo) { vector qFams = _physicalDevice->getQueueFamilies(); diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm index 84063271..9fdec174 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm @@ -226,7 +226,7 @@ void MVKGraphicsPipeline::encode(MVKCommandEncoder* cmdEncoder, uint32_t stage) [mtlCmdEnc setFrontFacingWinding: _mtlFrontWinding]; [mtlCmdEnc setTriangleFillMode: _mtlFillMode]; - if (_device->_pFeatures->depthClamp) { + if (_device->_enabledFeatures.depthClamp) { [mtlCmdEnc setDepthClipMode: _mtlDepthClipMode]; } @@ -323,7 +323,7 @@ MVKGraphicsPipeline::MVKGraphicsPipeline(MVKDevice* device, _mtlFrontWinding = mvkMTLWindingFromVkFrontFace(_rasterInfo.frontFace); _mtlFillMode = mvkMTLTriangleFillModeFromVkPolygonMode(_rasterInfo.polygonMode); if (_rasterInfo.depthClampEnable) { - if (_device->_pFeatures->depthClamp) { + if (_device->_enabledFeatures.depthClamp) { _mtlDepthClipMode = MTLDepthClipModeClamp; } else { setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_FEATURE_NOT_PRESENT, "This device does not support depth clamping.")); diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm b/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm index d81e7efe..ad052c08 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm @@ -244,7 +244,7 @@ MVKOcclusionQueryPool::~MVKOcclusionQueryPool() { MVKPipelineStatisticsQueryPool::MVKPipelineStatisticsQueryPool(MVKDevice* device, const VkQueryPoolCreateInfo* pCreateInfo) : MVKQueryPool(device, pCreateInfo, 1) { - if ( !_device->_pFeatures->pipelineStatisticsQuery ) { + if ( !_device->_enabledFeatures.pipelineStatisticsQuery ) { setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateQueryPool: VK_QUERY_TYPE_PIPELINE_STATISTICS is not supported.")); } } diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index 34d86756..2eeb83eb 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -159,7 +159,7 @@ MVK_PUBLIC_SYMBOL VkResult vkCreateDevice( MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice); MVKDevice* mvkDev = new MVKDevice(mvkPD, pCreateInfo); *pDevice = mvkDev->getVkDevice(); - return VK_SUCCESS; + return mvkDev->getConfigurationResult(); } MVK_PUBLIC_SYMBOL void vkDestroyDevice( @@ -288,12 +288,14 @@ MVK_PUBLIC_SYMBOL VkResult vkFlushMappedMemoryRanges( uint32_t memRangeCount, const VkMappedMemoryRange* pMemRanges) { + VkResult rslt = VK_SUCCESS; for (uint32_t i = 0; i < memRangeCount; i++) { const VkMappedMemoryRange* pMem = &pMemRanges[i]; MVKDeviceMemory* mvkMem = (MVKDeviceMemory*)pMem->memory; - mvkMem->flushToDevice(pMem->offset, pMem->size); + VkResult r = mvkMem->flushToDevice(pMem->offset, pMem->size); + if (rslt == VK_SUCCESS) { rslt = r; } } - return VK_SUCCESS; + return rslt; } MVK_PUBLIC_SYMBOL VkResult vkInvalidateMappedMemoryRanges( @@ -301,12 +303,14 @@ MVK_PUBLIC_SYMBOL VkResult vkInvalidateMappedMemoryRanges( uint32_t memRangeCount, const VkMappedMemoryRange* pMemRanges) { + VkResult rslt = VK_SUCCESS; for (uint32_t i = 0; i < memRangeCount; i++) { const VkMappedMemoryRange* pMem = &pMemRanges[i]; MVKDeviceMemory* mvkMem = (MVKDeviceMemory*)pMem->memory; - mvkMem->pullFromDevice(pMem->offset, pMem->size); + VkResult r = mvkMem->pullFromDevice(pMem->offset, pMem->size); + if (rslt == VK_SUCCESS) { rslt = r; } } - return VK_SUCCESS; + return rslt; } MVK_PUBLIC_SYMBOL void vkGetDeviceMemoryCommitment(