Add support for the VK_EXT_debug_utils extension.

Dispatch messenger callbacks on any reported message or error.
Add MVKDebugUtilsMessenger class.
Add MVKVulkanAPIObject::getVkObjectType() function and override in all Vulkan API objects.
MVKDevice::getMTLPixelFormatFromVkFormat() take base object for reporting.
This commit is contained in:
Bill Hollings 2019-05-29 17:26:50 -04:00
parent 7d37d5be16
commit 3e069c4a78
29 changed files with 424 additions and 31 deletions

View File

@ -21,6 +21,7 @@ Released TBD
- Add support for extensions:
- `VK_EXT_debug_report`
- `VK_EXT_debug_marker`
- `VK_EXT_debug_utils`
- `VK_NV_glsl_shader`
- Change log indication of error in logs from `[***MoltenVK ERROR***]` to
`[mvk-error]`, for consistency with other log level indications.

View File

@ -89,3 +89,9 @@ void mvkCmdDebugMarkerEnd(MVKCommandBuffer* cmdBuff);
void mvkCmdDebugMarkerInsert(MVKCommandBuffer* cmdBuff, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo);
void mvkCmdBeginDebugUtilsLabel(MVKCommandBuffer* cmdBuff, const VkDebugUtilsLabelEXT* pLabelInfo);
void mvkCmdEndDebugUtilsLabel(MVKCommandBuffer* cmdBuff);
void mvkCmdInsertDebugUtilsLabel(MVKCommandBuffer* cmdBuff, const VkDebugUtilsLabelEXT* pLabelInfo);

View File

@ -104,4 +104,20 @@ void mvkCmdDebugMarkerInsert(MVKCommandBuffer* cmdBuff, const VkDebugMarkerMarke
cmdBuff->addCommand(cmd);
}
void mvkCmdBeginDebugUtilsLabel(MVKCommandBuffer* cmdBuff, const VkDebugUtilsLabelEXT* pLabelInfo) {
MVKCmdDebugMarkerBegin* cmd = cmdBuff->_commandPool->_cmdDebugMarkerBeginPool.acquireObject();
cmd->setContent(pLabelInfo->pLabelName, pLabelInfo->color);
cmdBuff->addCommand(cmd);
}
void mvkCmdEndDebugUtilsLabel(MVKCommandBuffer* cmdBuff) {
MVKCmdDebugMarkerEnd* cmd = cmdBuff->_commandPool->_cmdDebugMarkerEndPool.acquireObject();
cmdBuff->addCommand(cmd);
}
void mvkCmdInsertDebugUtilsLabel(MVKCommandBuffer* cmdBuff, const VkDebugUtilsLabelEXT* pLabelInfo) {
MVKCmdDebugMarkerInsert* cmd = cmdBuff->_commandPool->_cmdDebugMarkerInsertPool.acquireObject();
cmd->setContent(pLabelInfo->pLabelName, pLabelInfo->color);
cmdBuff->addCommand(cmd);
}

View File

@ -54,6 +54,9 @@ class MVKCommandBuffer : public MVKDispatchableVulkanAPIObject, public MVKDevice
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_COMMAND_BUFFER; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT; }

View File

@ -53,6 +53,9 @@ class MVKCommandPool : public MVKVulkanAPIDeviceObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_COMMAND_POOL; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT; }

View File

@ -31,6 +31,9 @@ class MVKBuffer : public MVKResource {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_BUFFER; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT; }
@ -97,6 +100,9 @@ class MVKBufferView : public MVKVulkanAPIDeviceObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_BUFFER_VIEW; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT; }

View File

@ -203,7 +203,7 @@ MVKBufferView::MVKBufferView(MVKDevice* device, const VkBufferViewCreateInfo* pC
// Multiple rows will automatically align with PoT max texture dimension, but need to align upwards if less than full single row.
size_t maxBlocksPerRow = _device->_pMetalFeatures->maxTextureDimension / fmtBlockSize.width;
size_t blocksPerRow = min(blockCount, maxBlocksPerRow);
_mtlBytesPerRow = mvkAlignByteOffset(blocksPerRow * bytesPerBlock, _device->getVkFormatTexelBufferAlignment(pCreateInfo->format));
_mtlBytesPerRow = mvkAlignByteOffset(blocksPerRow * bytesPerBlock, _device->getVkFormatTexelBufferAlignment(pCreateInfo->format, this));
size_t rowCount = blockCount / blocksPerRow;
if (blockCount % blocksPerRow) { rowCount++; }

View File

@ -134,6 +134,9 @@ class MVKDescriptorSetLayout : public MVKVulkanAPIDeviceObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT; }
@ -283,6 +286,9 @@ class MVKDescriptorSet : public MVKVulkanAPIDeviceObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_DESCRIPTOR_SET; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT; }
@ -334,6 +340,9 @@ class MVKDescriptorPool : public MVKVulkanAPIDeviceObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_DESCRIPTOR_POOL; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT; }
@ -372,6 +381,9 @@ class MVKDescriptorUpdateTemplate : public MVKVulkanAPIDeviceObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT; }

View File

@ -79,6 +79,9 @@ class MVKPhysicalDevice : public MVKDispatchableVulkanAPIObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_PHYSICAL_DEVICE; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT; }
@ -345,6 +348,9 @@ class MVKDevice : public MVKDispatchableVulkanAPIObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_DEVICE; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT; }
@ -561,10 +567,10 @@ public:
*
* All other pixel formats are returned unchanged.
*/
MTLPixelFormat getMTLPixelFormatFromVkFormat(VkFormat vkFormat);
MTLPixelFormat getMTLPixelFormatFromVkFormat(VkFormat vkFormat, MVKBaseObject* mvkObj);
/** Returns the memory alignment required for the format when used in a texel buffer. */
VkDeviceSize getVkFormatTexelBufferAlignment(VkFormat format);
VkDeviceSize getVkFormatTexelBufferAlignment(VkFormat format, MVKBaseObject* mvkObj);
/**
* Returns the MTLBuffer used to hold occlusion query results,
@ -694,7 +700,7 @@ public:
* are managed for each platform device.
*/
inline MTLPixelFormat getMTLPixelFormatFromVkFormat(VkFormat vkFormat) {
return _device ? _device->getMTLPixelFormatFromVkFormat(vkFormat)
return _device ? _device->getMTLPixelFormatFromVkFormat(vkFormat, getBaseObject())
: mvkMTLPixelFormatFromVkFormatInObj(vkFormat, getBaseObject());
}

View File

@ -2027,8 +2027,8 @@ uint32_t MVKDevice::getMetalBufferIndexForVertexAttributeBinding(uint32_t bindin
return ((_pMetalFeatures->maxPerStageBufferCount - 1) - binding);
}
MTLPixelFormat MVKDevice::getMTLPixelFormatFromVkFormat(VkFormat vkFormat) {
MTLPixelFormat mtlPixFmt = mvkMTLPixelFormatFromVkFormat(vkFormat);
MTLPixelFormat MVKDevice::getMTLPixelFormatFromVkFormat(VkFormat vkFormat, MVKBaseObject* mvkObj) {
MTLPixelFormat mtlPixFmt = mvkMTLPixelFormatFromVkFormatInObj(vkFormat, mvkObj);
#if MVK_MACOS
if (mtlPixFmt == MTLPixelFormatDepth24Unorm_Stencil8 &&
!getMTLDevice().isDepth24Stencil8PixelFormatSupported) {
@ -2038,8 +2038,8 @@ MTLPixelFormat MVKDevice::getMTLPixelFormatFromVkFormat(VkFormat vkFormat) {
return mtlPixFmt;
}
VkDeviceSize MVKDevice::getVkFormatTexelBufferAlignment(VkFormat format) {
VkDeviceSize deviceAlignment = mvkMTLPixelFormatLinearTextureAlignment(getMTLPixelFormatFromVkFormat(format), getMTLDevice());
VkDeviceSize MVKDevice::getVkFormatTexelBufferAlignment(VkFormat format, MVKBaseObject* mvkObj) {
VkDeviceSize deviceAlignment = mvkMTLPixelFormatLinearTextureAlignment(getMTLPixelFormatFromVkFormat(format, mvkObj), getMTLDevice());
return deviceAlignment ? deviceAlignment : _pProperties->limits.minTexelBufferOffsetAlignment;
}

View File

@ -35,6 +35,9 @@ class MVKDeviceMemory : public MVKVulkanAPIDeviceObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_DEVICE_MEMORY; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT; }

View File

@ -30,6 +30,9 @@ class MVKFramebuffer : public MVKVulkanAPIDeviceObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_FRAMEBUFFER; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT; }

View File

@ -48,6 +48,9 @@ class MVKImage : public MVKResource {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_IMAGE; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT; }
@ -262,6 +265,9 @@ class MVKImageView : public MVKVulkanAPIDeviceObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_IMAGE_VIEW; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT; }
@ -330,6 +336,9 @@ class MVKSampler : public MVKVulkanAPIDeviceObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_SAMPLER; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT; }

View File

@ -584,7 +584,7 @@ MVKImage::MVKImage(MVKDevice* device, const VkImageCreateInfo* pCreateInfo) : MV
_hasExpectedTexelSize = (mvkMTLPixelFormatBytesPerBlock(_mtlPixelFormat) == mvkVkFormatBytesPerBlock(pCreateInfo->format));
// Calc _byteCount after _byteAlignment
_byteAlignment = _isLinear ? _device->getVkFormatTexelBufferAlignment(pCreateInfo->format) : mvkEnsurePowerOfTwo(mvkVkFormatBytesPerBlock(pCreateInfo->format));
_byteAlignment = _isLinear ? _device->getVkFormatTexelBufferAlignment(pCreateInfo->format, this) : mvkEnsurePowerOfTwo(mvkVkFormatBytesPerBlock(pCreateInfo->format));
for (uint32_t mipLvl = 0; mipLvl < _mipLevels; mipLvl++) {
_byteCount += getBytesPerLayer(mipLvl) * _extent.depth * _arrayLayers;
}

View File

@ -31,6 +31,7 @@ class MVKPhysicalDevice;
class MVKDevice;
class MVKSurface;
class MVKDebugReportCallback;
class MVKDebugUtilsMessenger;
/** Tracks info about entry point function pointer addresses. */
@ -55,6 +56,9 @@ class MVKInstance : public MVKDispatchableVulkanAPIObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_INSTANCE; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT; }
@ -104,10 +108,21 @@ public:
const char* pLayerPrefix,
const char* pMessage);
MVKDebugUtilsMessenger* createDebugUtilsMessenger(const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator);
void destroyDebugUtilsMessenger(MVKDebugUtilsMessenger* mvkDUM,
const VkAllocationCallbacks* pAllocator);
void debugUtilsMessage(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData);
void debugReportMessage(MVKVulkanAPIObject* mvkAPIObj, int aslLvl, const char* pMessage);
/** Returns whether debug report callbacks are being used. */
bool hasDebugReportCallbacks() { return _hasDebugReportCallbacks; }
/** Returns whether debug callbacks are being used. */
bool hasDebugCallbacks() { return _hasDebugReportCallbacks || _hasDebugUtilsMessengers; }
/** Returns the MoltenVK configuration settings. */
const MVKConfiguration* getMoltenVKConfiguration() { return &_mvkConfig; }
@ -145,8 +160,9 @@ protected:
void propogateDebugName() override {}
void initProcAddrs();
void initCreationDebugReportCallbacks(const VkInstanceCreateInfo* pCreateInfo);
void initDebugCallbacks(const VkInstanceCreateInfo* pCreateInfo);
VkDebugReportFlagsEXT getVkDebugReportFlagsFromASLLevel(int aslLvl);
VkDebugUtilsMessageSeverityFlagBitsEXT getVkDebugUtilsMessageSeverityFlagBitsFromASLLevel(int aslLvl);
MVKEntryPoint* getEntryPoint(const char* pName);
void initConfig();
void logVersions();
@ -157,8 +173,10 @@ protected:
std::vector<MVKPhysicalDevice*> _physicalDevices;
std::unordered_map<std::string, MVKEntryPoint> _entryPoints;
std::vector<MVKDebugReportCallback*> _debugReportCallbacks;
std::mutex _drcbLock;
std::vector<MVKDebugUtilsMessenger*> _debugUtilMessengers;
std::mutex _dcbLock;
bool _hasDebugReportCallbacks;
bool _hasDebugUtilsMessengers;
bool _useCreationCallbacks;
const char* _debugReportCallbackLayerPrefix;
};
@ -172,8 +190,11 @@ class MVKDebugReportCallback : public MVKVulkanAPIObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT; }
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT; }
/** Returns a pointer to the Vulkan instance. */
MVKInstance* getInstance() override { return _mvkInstance; }
@ -181,7 +202,10 @@ public:
MVKDebugReportCallback(MVKInstance* mvkInstance,
const VkDebugReportCallbackCreateInfoEXT* pCreateInfo,
bool isCreationCallback) :
_mvkInstance(mvkInstance), _info(*pCreateInfo), _isCreationCallback(isCreationCallback) {
_mvkInstance(mvkInstance),
_info(*pCreateInfo),
_isCreationCallback(isCreationCallback) {
_info.pNext = nullptr;
}
@ -195,3 +219,41 @@ protected:
bool _isCreationCallback;
};
#pragma mark -
#pragma mark MVKDebugUtilsMessenger
/** Represents a Vulkan Debug Utils callback. */
class MVKDebugUtilsMessenger : public MVKVulkanAPIObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT; }
/** Returns a pointer to the Vulkan instance. */
MVKInstance* getInstance() override { return _mvkInstance; }
MVKDebugUtilsMessenger(MVKInstance* mvkInstance,
const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
bool isCreationCallback) :
_mvkInstance(mvkInstance),
_info(*pCreateInfo),
_isCreationCallback(isCreationCallback) {
_info.pNext = nullptr;
}
protected:
friend MVKInstance;
void propogateDebugName() override {}
MVKInstance* _mvkInstance;
VkDebugUtilsMessengerCreateInfoEXT _info;
bool _isCreationCallback;
};

View File

@ -82,7 +82,7 @@ void MVKInstance::destroySurface(MVKSurface* mvkSrfc,
MVKDebugReportCallback* MVKInstance::createDebugReportCallback(const VkDebugReportCallbackCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator) {
lock_guard<mutex> lock(_drcbLock);
lock_guard<mutex> lock(_dcbLock);
MVKDebugReportCallback* mvkDRCB = new MVKDebugReportCallback(this, pCreateInfo, _useCreationCallbacks);
_debugReportCallbacks.push_back(mvkDRCB);
@ -92,7 +92,7 @@ MVKDebugReportCallback* MVKInstance::createDebugReportCallback(const VkDebugRepo
void MVKInstance::destroyDebugReportCallback(MVKDebugReportCallback* mvkDRCB,
const VkAllocationCallbacks* pAllocator) {
lock_guard<mutex> lock(_drcbLock);
lock_guard<mutex> lock(_dcbLock);
mvkRemoveAllOccurances(_debugReportCallbacks, mvkDRCB);
_hasDebugReportCallbacks = (_debugReportCallbacks.size() != 0);
@ -110,25 +110,96 @@ void MVKInstance::debugReportMessage(VkDebugReportFlagsEXT flags,
// Fail fast to avoid further unnecessary processing and locking.
if ( !(_hasDebugReportCallbacks) ) { return; }
lock_guard<mutex> lock(_drcbLock);
lock_guard<mutex> lock(_dcbLock);
for (auto mvkDRCB : _debugReportCallbacks) {
auto& drbcInfo = mvkDRCB->_info;
if (drbcInfo.pfnCallback && mvkIsAnyFlagEnabled(drbcInfo.flags, flags) && (mvkDRCB->_isCreationCallback == _useCreationCallbacks)) {
if (drbcInfo.pfnCallback &&
mvkIsAnyFlagEnabled(drbcInfo.flags, flags) &&
(mvkDRCB->_isCreationCallback == _useCreationCallbacks)) {
drbcInfo.pfnCallback(flags, objectType, object, location, messageCode, pLayerPrefix, pMessage, drbcInfo.pUserData);
}
}
}
MVKDebugUtilsMessenger* MVKInstance::createDebugUtilsMessenger(const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator) {
lock_guard<mutex> lock(_dcbLock);
MVKDebugUtilsMessenger* mvkDUM = new MVKDebugUtilsMessenger(this, pCreateInfo, _useCreationCallbacks);
_debugUtilMessengers.push_back(mvkDUM);
_hasDebugUtilsMessengers = true;
return mvkDUM;
}
void MVKInstance::destroyDebugUtilsMessenger(MVKDebugUtilsMessenger* mvkDUM,
const VkAllocationCallbacks* pAllocator) {
lock_guard<mutex> lock(_dcbLock);
mvkRemoveAllOccurances(_debugUtilMessengers, mvkDUM);
_hasDebugUtilsMessengers = (_debugUtilMessengers.size() != 0);
mvkDUM->destroy();
}
void MVKInstance::debugUtilsMessage(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData) {
// Fail fast to avoid further unnecessary processing and locking.
if ( !(_hasDebugUtilsMessengers) ) { return; }
lock_guard<mutex> lock(_dcbLock);
for (auto mvkDUM : _debugUtilMessengers) {
auto& dumInfo = mvkDUM->_info;
if (dumInfo.pfnUserCallback &&
mvkIsAnyFlagEnabled(dumInfo.messageSeverity, messageSeverity) &&
mvkIsAnyFlagEnabled(dumInfo.messageType, messageTypes) &&
(mvkDUM->_isCreationCallback == _useCreationCallbacks)) {
dumInfo.pfnUserCallback(messageSeverity, messageTypes, pCallbackData, dumInfo.pUserData);
}
}
}
void MVKInstance::debugReportMessage(MVKVulkanAPIObject* mvkAPIObj, int aslLvl, const char* pMessage) {
// Fail fast to avoid further unnecessary processing and locking.
if ( !(_hasDebugReportCallbacks) ) { return; }
if (_hasDebugReportCallbacks) {
VkDebugReportFlagsEXT flags = getVkDebugReportFlagsFromASLLevel(aslLvl);
uint64_t object = (uint64_t)(mvkAPIObj ? mvkAPIObj->getVkHandle() : nullptr);
VkDebugReportObjectTypeEXT objectType = mvkAPIObj ? mvkAPIObj->getVkDebugReportObjectType() : VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT;
debugReportMessage(flags, objectType, object, 0, 0, _debugReportCallbackLayerPrefix, pMessage);
}
if (_hasDebugUtilsMessengers) {
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity = getVkDebugUtilsMessageSeverityFlagBitsFromASLLevel(aslLvl);
uint64_t objectHandle = (uint64_t)(mvkAPIObj ? mvkAPIObj->getVkHandle() : nullptr);
VkObjectType objectType = mvkAPIObj ? mvkAPIObj->getVkObjectType() : VK_OBJECT_TYPE_UNKNOWN;
VkDebugUtilsObjectNameInfoEXT duObjName = {
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.pNext = nullptr,
.objectType = objectType,
.objectHandle = objectHandle,
.pObjectName = mvkAPIObj ? mvkAPIObj->getDebugName().UTF8String : nullptr
};
VkDebugUtilsMessengerCallbackDataEXT dumcbd = {
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT,
.pNext = nullptr,
.flags = 0,
.pMessageIdName = nullptr,
.messageIdNumber = 0,
.pMessage = pMessage,
.queueLabelCount = 0,
.pQueueLabels = nullptr,
.cmdBufLabelCount = 0,
.pCmdBufLabels = nullptr,
.objectCount = 1,
.pObjects = &duObjName
};
debugUtilsMessage(messageSeverity, VK_DEBUG_UTILS_MESSAGE_TYPE_FLAG_BITS_MAX_ENUM_EXT, &dumcbd);
}
}
VkDebugReportFlagsEXT MVKInstance::getVkDebugReportFlagsFromASLLevel(int aslLvl) {
@ -152,6 +223,27 @@ VkDebugReportFlagsEXT MVKInstance::getVkDebugReportFlagsFromASLLevel(int aslLvl)
}
}
VkDebugUtilsMessageSeverityFlagBitsEXT MVKInstance::getVkDebugUtilsMessageSeverityFlagBitsFromASLLevel(int aslLvl) {
switch (aslLvl) {
case ASL_LEVEL_DEBUG:
return VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
case ASL_LEVEL_INFO:
case ASL_LEVEL_NOTICE:
return VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
case ASL_LEVEL_WARNING:
return VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
case ASL_LEVEL_ERR:
case ASL_LEVEL_CRIT:
case ASL_LEVEL_ALERT:
case ASL_LEVEL_EMERG:
default:
return VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
}
}
#pragma mark Object Creation
@ -205,7 +297,7 @@ static NSArray<id<MTLDevice>>* getAvailableMTLDevices() {
MVKInstance::MVKInstance(const VkInstanceCreateInfo* pCreateInfo) : _enabledExtensions(this) {
initCreationDebugReportCallbacks(pCreateInfo); // Do before any creation activities
initDebugCallbacks(pCreateInfo); // Do before any creation activities
_appInfo.apiVersion = MVK_VULKAN_API_VERSION; // Default
mvkSetOrClear(&_appInfo, pCreateInfo->pApplicationInfo);
@ -245,9 +337,10 @@ MVKInstance::MVKInstance(const VkInstanceCreateInfo* pCreateInfo) : _enabledExte
_useCreationCallbacks = false;
}
void MVKInstance::initCreationDebugReportCallbacks(const VkInstanceCreateInfo* pCreateInfo) {
void MVKInstance::initDebugCallbacks(const VkInstanceCreateInfo* pCreateInfo) {
_useCreationCallbacks = true;
_hasDebugReportCallbacks = false;
_hasDebugUtilsMessengers = false;
_debugReportCallbackLayerPrefix = getDriverLayer()->getName();
MVKVkAPIStructHeader* next = (MVKVkAPIStructHeader*)pCreateInfo->pNext;
@ -256,6 +349,9 @@ void MVKInstance::initCreationDebugReportCallbacks(const VkInstanceCreateInfo* p
case VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT:
createDebugReportCallback((VkDebugReportCallbackCreateInfoEXT*)next, nullptr);
break;
case VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT:
createDebugUtilsMessenger((VkDebugUtilsMessengerCreateInfoEXT*)next, nullptr);
break;
default:
break;
}
@ -433,6 +529,17 @@ void MVKInstance::initProcAddrs() {
ADD_INST_EXT_ENTRY_POINT(vkCreateDebugReportCallbackEXT, EXT_DEBUG_REPORT);
ADD_INST_EXT_ENTRY_POINT(vkDestroyDebugReportCallbackEXT, EXT_DEBUG_REPORT);
ADD_INST_EXT_ENTRY_POINT(vkDebugReportMessageEXT, EXT_DEBUG_REPORT);
ADD_INST_EXT_ENTRY_POINT(vkSetDebugUtilsObjectNameEXT, EXT_DEBUG_UTILS);
ADD_INST_EXT_ENTRY_POINT(vkSetDebugUtilsObjectTagEXT, EXT_DEBUG_UTILS);
ADD_INST_EXT_ENTRY_POINT(vkQueueBeginDebugUtilsLabelEXT, EXT_DEBUG_UTILS);
ADD_INST_EXT_ENTRY_POINT(vkQueueEndDebugUtilsLabelEXT, EXT_DEBUG_UTILS);
ADD_INST_EXT_ENTRY_POINT(vkQueueInsertDebugUtilsLabelEXT, EXT_DEBUG_UTILS);
ADD_INST_EXT_ENTRY_POINT(vkCmdBeginDebugUtilsLabelEXT, EXT_DEBUG_UTILS);
ADD_INST_EXT_ENTRY_POINT(vkCmdEndDebugUtilsLabelEXT, EXT_DEBUG_UTILS);
ADD_INST_EXT_ENTRY_POINT(vkCmdInsertDebugUtilsLabelEXT, EXT_DEBUG_UTILS);
ADD_INST_EXT_ENTRY_POINT(vkCreateDebugUtilsMessengerEXT, EXT_DEBUG_UTILS);
ADD_INST_EXT_ENTRY_POINT(vkDestroyDebugUtilsMessengerEXT, EXT_DEBUG_UTILS);
ADD_INST_EXT_ENTRY_POINT(vkSubmitDebugUtilsMessageEXT, EXT_DEBUG_UTILS);
#ifdef VK_USE_PLATFORM_IOS_MVK
ADD_INST_EXT_ENTRY_POINT(vkCreateIOSSurfaceMVK, MVK_IOS_SURFACE);
@ -527,7 +634,7 @@ MVKInstance::~MVKInstance() {
_useCreationCallbacks = true;
mvkDestroyContainerContents(_physicalDevices);
lock_guard<mutex> lock(_drcbLock);
lock_guard<mutex> lock(_dcbLock);
mvkDestroyContainerContents(_debugReportCallbacks);
}

View File

@ -46,6 +46,9 @@ class MVKPipelineLayout : public MVKVulkanAPIDeviceObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_PIPELINE_LAYOUT; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT; }
@ -129,6 +132,9 @@ class MVKPipeline : public MVKVulkanAPIDeviceObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_PIPELINE; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT; }
@ -332,6 +338,9 @@ class MVKPipelineCache : public MVKVulkanAPIDeviceObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_PIPELINE_CACHE; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT; }

View File

@ -44,6 +44,9 @@ class MVKQueryPool : public MVKVulkanAPIDeviceObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_QUERY_POOL; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT; }

View File

@ -78,6 +78,9 @@ class MVKQueue : public MVKDispatchableVulkanAPIObject, public MVKDeviceTracking
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_QUEUE; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT; }

View File

@ -147,6 +147,9 @@ class MVKRenderPass : public MVKVulkanAPIDeviceObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_RENDER_PASS; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT; }

View File

@ -169,6 +169,9 @@ class MVKShaderModule : public MVKVulkanAPIDeviceObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_SHADER_MODULE; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT; }

View File

@ -47,6 +47,9 @@ class MVKSurface : public MVKVulkanAPIObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_SURFACE_KHR; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT; }

View File

@ -34,6 +34,9 @@ class MVKSwapchain : public MVKVulkanAPIDeviceObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_SWAPCHAIN_KHR; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT; }

View File

@ -112,6 +112,9 @@ class MVKSemaphore : public MVKVulkanAPIDeviceObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_SEMAPHORE; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT; }
@ -158,6 +161,9 @@ class MVKFence : public MVKVulkanAPIDeviceObject {
public:
/** Returns the Vulkan type of this object. */
VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_FENCE; }
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT; }

View File

@ -50,6 +50,9 @@ public:
/** Returns a reference to this object suitable for use as a Vulkan API handle. */
virtual void* getVkHandle() { return this; }
/** Returns the Vulkan type of this object. */
virtual VkObjectType getVkObjectType() = 0;
/** Returns the debug report object type of this object. */
virtual VkDebugReportObjectTypeEXT getVkDebugReportObjectType() = 0;
@ -86,6 +89,9 @@ public:
/** Returns the MVKVulkanAPIObject instance referenced by the object of the given type. */
static MVKVulkanAPIObject* getMVKVulkanAPIObject(VkDebugReportObjectTypeEXT objType, uint64_t object);
/** Returns the MVKVulkanAPIObject instance referenced by the object of the given type. */
static MVKVulkanAPIObject* getMVKVulkanAPIObject(VkObjectType objType, uint64_t objectHandle);
/** Construct an empty instance. Declared here to support copy constructor. */
MVKVulkanAPIObject() {}

View File

@ -77,6 +77,20 @@ MVKVulkanAPIObject* MVKVulkanAPIObject::getMVKVulkanAPIObject(VkDebugReportObjec
}
}
MVKVulkanAPIObject* MVKVulkanAPIObject::getMVKVulkanAPIObject(VkObjectType objType, uint64_t objectHandle) {
void* pVkObj = (void*)objectHandle;
switch (objType) {
case VK_OBJECT_TYPE_INSTANCE:
case VK_OBJECT_TYPE_PHYSICAL_DEVICE:
case VK_OBJECT_TYPE_DEVICE:
case VK_OBJECT_TYPE_QUEUE:
case VK_OBJECT_TYPE_COMMAND_BUFFER:
return MVKDispatchableVulkanAPIObject::getDispatchableObject(pVkObj);
default:
return (MVKVulkanAPIObject*)pVkObj;
}
}
MVKVulkanAPIObject::~MVKVulkanAPIObject() {
[_debugName release];
}

View File

@ -54,6 +54,7 @@ MVK_EXTENSION(KHR_swapchain_mutable_format, KHR_SWAPCHAIN_MUTABLE_FORMAT)
MVK_EXTENSION(KHR_variable_pointers, KHR_VARIABLE_POINTERS)
MVK_EXTENSION(EXT_debug_marker, EXT_DEBUG_MARKER)
MVK_EXTENSION(EXT_debug_report, EXT_DEBUG_REPORT)
MVK_EXTENSION(EXT_debug_utils, EXT_DEBUG_UTILS)
MVK_EXTENSION(EXT_host_query_reset, EXT_HOST_QUERY_RESET)
MVK_EXTENSION(EXT_memory_budget, EXT_MEMORY_BUDGET)
MVK_EXTENSION(EXT_shader_viewport_index_layer, EXT_SHADER_VIEWPORT_INDEX_LAYER)

View File

@ -98,11 +98,11 @@ void MVKBaseObject::reportMessage(MVKBaseObject* mvkObj, int aslLvl, const char*
MVKVulkanAPIObject* mvkAPIObj = mvkObj ? mvkObj->getVulkanAPIObject() : nullptr;
MVKInstance* mvkInst = mvkAPIObj ? mvkAPIObj->getInstance() : nullptr;
bool hasDebugReportCallbacks = mvkInst && mvkInst->hasDebugReportCallbacks();
bool hasDebugCallbacks = mvkInst && mvkInst->hasDebugCallbacks();
bool shouldLog = (aslLvl < (_mvkLogLevel << 2));
// Fail fast to avoid further unnecessary processing.
if ( !(shouldLog || hasDebugReportCallbacks) ) { return; }
if ( !(shouldLog || hasDebugCallbacks) ) { return; }
va_list origArgs, redoArgs;
va_copy(origArgs, args);
@ -131,7 +131,7 @@ void MVKBaseObject::reportMessage(MVKBaseObject* mvkObj, int aslLvl, const char*
if (shouldLog) { fprintf(stderr, "[%s] %s\n", getReportingLevelString(aslLvl), pMessage); }
// Broadcast the message to any Vulkan debug report callbacks
if (hasDebugReportCallbacks) { mvkInst->debugReportMessage(mvkAPIObj, aslLvl, pMessage); }
if (hasDebugCallbacks) { mvkInst->debugReportMessage(mvkAPIObj, aslLvl, pMessage); }
}
VkResult MVKBaseObject::reportError(VkResult vkErr, const char* format, ...) {

View File

@ -2180,6 +2180,108 @@ MVK_PUBLIC_SYMBOL void vkCmdDebugMarkerInsertEXT(
}
#pragma mark -
#pragma mark VK_EXT_debug_utils extension
MVK_PUBLIC_SYMBOL VkResult vkSetDebugUtilsObjectNameEXT(
VkDevice device,
const VkDebugUtilsObjectNameInfoEXT* pNameInfo) {
MVKTraceVulkanCall();
MVKVulkanAPIObject* mvkObj = MVKVulkanAPIObject::getMVKVulkanAPIObject(pNameInfo->objectType, pNameInfo->objectHandle);
return mvkObj ? mvkObj->setDebugName(pNameInfo->pObjectName) : VK_SUCCESS;
}
MVK_PUBLIC_SYMBOL VkResult vkSetDebugUtilsObjectTagEXT(
VkDevice device,
const VkDebugUtilsObjectTagInfoEXT* pTagInfo) {
MVKTraceVulkanCall();
return VK_SUCCESS;
}
MVK_PUBLIC_SYMBOL void vkQueueBeginDebugUtilsLabelEXT(
VkQueue queue,
const VkDebugUtilsLabelEXT* pLabelInfo) {
MVKTraceVulkanCall();
}
MVK_PUBLIC_SYMBOL void vkQueueEndDebugUtilsLabelEXT(
VkQueue queue) {
MVKTraceVulkanCall();
}
MVK_PUBLIC_SYMBOL void vkQueueInsertDebugUtilsLabelEXT(
VkQueue queue,
const VkDebugUtilsLabelEXT* pLabelInfo) {
MVKTraceVulkanCall();
}
MVK_PUBLIC_SYMBOL void vkCmdBeginDebugUtilsLabelEXT(
VkCommandBuffer commandBuffer,
const VkDebugUtilsLabelEXT* pLabelInfo) {
MVKTraceVulkanCall();
MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
mvkCmdBeginDebugUtilsLabel(cmdBuff, pLabelInfo);
}
MVK_PUBLIC_SYMBOL void vkCmdEndDebugUtilsLabelEXT(
VkCommandBuffer commandBuffer) {
MVKTraceVulkanCall();
MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
mvkCmdEndDebugUtilsLabel(cmdBuff);
}
MVK_PUBLIC_SYMBOL void vkCmdInsertDebugUtilsLabelEXT(
VkCommandBuffer commandBuffer,
const VkDebugUtilsLabelEXT* pLabelInfo) {
MVKTraceVulkanCall();
MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
mvkCmdInsertDebugUtilsLabel(cmdBuff, pLabelInfo);
}
MVK_PUBLIC_SYMBOL VkResult vkCreateDebugUtilsMessengerEXT(
VkInstance instance,
const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkDebugUtilsMessengerEXT* pMessenger) {
MVKTraceVulkanCall();
MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance);
MVKDebugUtilsMessenger* mvkDUM = mvkInst->createDebugUtilsMessenger(pCreateInfo, pAllocator);
*pMessenger = (VkDebugUtilsMessengerEXT)mvkDUM;
return mvkDUM->getConfigurationResult();
}
MVK_PUBLIC_SYMBOL void vkDestroyDebugUtilsMessengerEXT(
VkInstance instance,
VkDebugUtilsMessengerEXT messenger,
const VkAllocationCallbacks* pAllocator) {
MVKTraceVulkanCall();
if ( !messenger ) { return; }
MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance);
mvkInst->destroyDebugUtilsMessenger((MVKDebugUtilsMessenger*)messenger, pAllocator);
}
MVK_PUBLIC_SYMBOL void vkSubmitDebugUtilsMessageEXT(
VkInstance instance,
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData) {
MVKTraceVulkanCall();
MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance);
mvkInst->debugUtilsMessage(messageSeverity, messageTypes, pCallbackData);
}
#pragma mark -
#pragma mark iOS & macOS surface extensions