Merge pull request #1284 from billhollings/queue-submit-finish-logging

Ensure queue submission message logging occurs before submission object is destroyed.
This commit is contained in:
Bill Hollings 2021-02-26 06:09:14 -05:00 committed by GitHub
commit 9dc1fc9442
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 22 deletions

View File

@ -181,7 +181,6 @@ protected:
MVKQueue* _queue;
MVKSmallVector<std::pair<MVKSemaphore*, uint64_t>> _waitSemaphores;
bool _trackPerformance;
};

View File

@ -244,8 +244,6 @@ MVKQueueSubmission::MVKQueueSubmission(MVKQueue* queue,
uint32_t waitSemaphoreCount,
const VkSemaphore* pWaitSemaphores) {
_queue = queue;
_trackPerformance = mvkGetMVKConfiguration()->performanceTracking;
_waitSemaphores.reserve(waitSemaphoreCount);
for (uint32_t i = 0; i < waitSemaphoreCount; i++) {
_waitSemaphores.push_back(make_pair((MVKSemaphore*)pWaitSemaphores[i], (uint64_t)0));
@ -315,25 +313,19 @@ void MVKQueueCommandBufferSubmission::commitActiveMTLCommandBuffer(bool signalCo
// If using inline semaphore waiting, do so now.
for (auto& ws : _waitSemaphores) { ws.first->encodeWait(nil, ws.second); }
MVKDevice* mkvDev = _queue->_device;
uint64_t startTime = mkvDev->getPerformanceTimestamp();
// If we need to signal completion, use getActiveMTLCommandBuffer() to ensure at least
// one MTLCommandBuffer is used, otherwise if this instance has no content, it will not
// finish(), signal the fence and semaphores ,and be destroyed.
// Use temp var for MTLCommandBuffer commit and release because completion callback
// may destroy this instance before this function ends.
id<MTLCommandBuffer> mtlCmdBuff = signalCompletion ? getActiveMTLCommandBuffer() : _activeMTLCommandBuffer;
_activeMTLCommandBuffer = nil;
// Use getActiveMTLCommandBuffer() to ensure at least one MTLCommandBuffer is used,
// otherwise if this instance has no content, it will not finish() and be destroyed.
if (signalCompletion || _trackPerformance) {
[getActiveMTLCommandBuffer() addCompletedHandler: ^(id<MTLCommandBuffer> mtlCmdBuff) {
mkvDev->addActivityPerformance(mkvDev->_performanceStatistics.queue.mtlCommandBufferCompletion, startTime);
if (signalCompletion) { this->finish(); }
}];
}
// Use temp vars because callback may destroy this instance before this function ends.
MVKDevice* device = _queue->getDevice();
id<MTLCommandBuffer> mtlCmdBuff = _activeMTLCommandBuffer;
// If command buffer execution fails, log it, and mark the device lost.
MVKDevice* mvkDev = _queue->getDevice();
uint64_t startTime = mvkDev->getPerformanceTimestamp();
[mtlCmdBuff addCompletedHandler: ^(id<MTLCommandBuffer> mtlCB) {
if (mtlCB.status == MTLCommandBufferStatusError) {
device->reportError(device->markLost(), "Command buffer %p \"%s\" execution failed (code %li): %s", mtlCB, mtlCB.label ? mtlCB.label.UTF8String : "", mtlCB.error.code, mtlCB.error.localizedDescription.UTF8String);
getVulkanAPIObject()->reportError(mvkDev->markLost(), "Command buffer %p \"%s\" execution failed (code %li): %s", mtlCB, mtlCB.label ? mtlCB.label.UTF8String : "", mtlCB.error.code, mtlCB.error.localizedDescription.UTF8String);
// Some errors indicate we lost the physical device as well.
switch (mtlCB.error.code) {
case MTLCommandBufferErrorBlacklisted:
@ -342,7 +334,7 @@ void MVKQueueCommandBufferSubmission::commitActiveMTLCommandBuffer(bool signalCo
#if MVK_MACOS && !MVK_MACCAT
case MTLCommandBufferErrorDeviceRemoved:
#endif
device->getPhysicalDevice()->setConfigurationResult(VK_ERROR_DEVICE_LOST);
mvkDev->getPhysicalDevice()->setConfigurationResult(VK_ERROR_DEVICE_LOST);
break;
}
#if MVK_XCODE_12
@ -366,15 +358,22 @@ void MVKQueueCommandBufferSubmission::commitActiveMTLCommandBuffer(bool signalCo
}
#if MVK_XCODE_12
if (mvkGetMVKConfiguration()->debugMode) {
MVKLogInfo("Shader log messages:");
bool isFirstMsg = true;
for (id<MTLFunctionLog> log in mtlCB.logs) {
if (isFirstMsg) {
MVKLogInfo("Shader log messages:");
isFirstMsg = false;
}
MVKLogInfo("%s", log.description.UTF8String);
}
}
#endif
// Ensure finish() is the last thing the completetion callback does.
mvkDev->addActivityPerformance(mvkDev->_performanceStatistics.queue.mtlCommandBufferCompletion, startTime);
if (signalCompletion) { this->finish(); }
}];
_activeMTLCommandBuffer = nil;
[mtlCmdBuff commit];
[mtlCmdBuff release]; // retained
}