Skip to content

Commit

Permalink
[Vk] Let checkVkResult() store device lost reason in VulkanDevice::mD…
Browse files Browse the repository at this point in the history
…eviceLostReason, somewhat similar to ID3D11Device::GetDeviceRemovedReason(). Also, hide cold error handling code inside onVulkanFailure() helper, for compact codegen.
  • Loading branch information
Eugene Golushkov committed Dec 23, 2024
1 parent 6635ef9 commit 9a56ec8
Show file tree
Hide file tree
Showing 25 changed files with 115 additions and 110 deletions.
4 changes: 3 additions & 1 deletion RenderSystems/Vulkan/include/OgreVulkanDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ namespace Ogre

uint32 mSupportedStages;

bool mIsDeviceLost;
VkResult mDeviceLostReason;
bool mIsExternal;

void fillDeviceFeatures();
Expand Down Expand Up @@ -203,6 +203,8 @@ namespace Ogre

/// Waits for the GPU to finish all pending commands.
void stall();

bool isDeviceLost() const { return mDeviceLostReason != VK_SUCCESS; }
};

// Mask away read flags from srcAccessMask
Expand Down
17 changes: 8 additions & 9 deletions RenderSystems/Vulkan/include/OgreVulkanPrerequisites.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,29 +147,28 @@ namespace Ogre
};
}

void onVulkanFailure( VulkanDevice *device, int result, const char *message, const char *func,
const char *file, long line );
} // namespace Ogre

#define OGRE_VK_EXCEPT( code, num, desc, src ) \
OGRE_EXCEPT_EX( code, num, desc + ( "\nVkResult = " + vkResultToString( num ) ), src )

#if OGRE_COMPILER == OGRE_COMPILER_MSVC
# define checkVkResult( result, functionName ) \
# define checkVkResult( device, result, functionName ) \
do \
{ \
if( result != VK_SUCCESS ) \
{ \
OGRE_VK_EXCEPT( Exception::ERR_RENDERINGAPI_ERROR, result, functionName " failed", \
__FUNCSIG__ ); \
onVulkanFailure( device, result, functionName " failed", __FUNCSIG__, __FILE__, \
__LINE__ ); \
} \
} while( 0 )
#else
# define checkVkResult( result, functionName ) \
# define checkVkResult( device, result, functionName ) \
do \
{ \
if( result != VK_SUCCESS ) \
{ \
OGRE_VK_EXCEPT( Exception::ERR_RENDERINGAPI_ERROR, result, functionName " failed", \
__PRETTY_FUNCTION__ ); \
onVulkanFailure( device, result, functionName " failed", __PRETTY_FUNCTION__, __FILE__, \
__LINE__ ); \
} \
} while( 0 )
#endif
Expand Down
3 changes: 2 additions & 1 deletion RenderSystems/Vulkan/include/OgreVulkanQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,8 @@ namespace Ogre
public:
VkCommandBuffer getCurrentCmdBuffer()
{
OGRE_ASSERT_LOW( mCurrentCmdBuffer );
if( !mCurrentCmdBuffer ) // device lost or any other error happens near vkSubmitQueue()
checkVkResult( mOwnerDevice, VK_ERROR_DEVICE_LOST, "getCurrentCmdBuffer" );
return mCurrentCmdBuffer;
}
EncoderState getEncoderState() const { return mEncoderState; }
Expand Down
2 changes: 1 addition & 1 deletion RenderSystems/Vulkan/src/OgreVulkanAsyncTextureTicket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ namespace Ogre
mQueue->releaseFence( mAccurateFence );
mAccurateFence = 0;

checkVkResult( result, "vkWaitForFences" );
checkVkResult( mQueue->mOwnerDevice, result, "vkWaitForFences" );
if( mStatus != Mapped )
mStatus = Ready;
retVal = true;
Expand Down
2 changes: 1 addition & 1 deletion RenderSystems/Vulkan/src/OgreVulkanCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ namespace Ogre

VkResult result =
vkCreateRenderPass( mDevice->mGraphicsQueue.mDevice, &rpciCopy, 0, &retVal );
checkVkResult( result, "vkCreateRenderPass" );
checkVkResult( mDevice, result, "vkCreateRenderPass" );

mRenderPassCache[rpciCopy] = retVal;
}
Expand Down
4 changes: 2 additions & 2 deletions RenderSystems/Vulkan/src/OgreVulkanDescriptorPool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ namespace Ogre

// Create the Vulkan descriptor pool
VkResult result = vkCreateDescriptorPool( device->mDevice, &poolCi, 0, &pool.pool );
checkVkResult( result, "vkCreateDescriptorPool" );
checkVkResult( device, result, "vkCreateDescriptorPool" );

mPools.push_back( pool );
mCurrentPoolIdx = mPools.size() - 1u;
Expand Down Expand Up @@ -192,7 +192,7 @@ namespace Ogre
while( itor != endt )
{
VkResult result = vkResetDescriptorPool( device->mDevice, itor->pool, 0 );
checkVkResult( result, "vkResetDescriptorPool" );
checkVkResult( device, result, "vkResetDescriptorPool" );
itor->size = 0u;
++itor;
}
Expand Down
42 changes: 16 additions & 26 deletions RenderSystems/Vulkan/src/OgreVulkanDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,12 @@ namespace Ogre
FastArray<VkExtensionProperties> availableExtensions;
uint32 numExtensions = 0u;
VkResult result = vkEnumerateInstanceExtensionProperties( 0, &numExtensions, 0 );
checkVkResult( result, "vkEnumerateInstanceExtensionProperties" );
checkVkResult( nullptr, result, "vkEnumerateInstanceExtensionProperties" );

availableExtensions.resize( numExtensions );
result =
vkEnumerateInstanceExtensionProperties( 0, &numExtensions, availableExtensions.begin() );
checkVkResult( result, "vkEnumerateInstanceExtensionProperties" );
checkVkResult( nullptr, result, "vkEnumerateInstanceExtensionProperties" );

for( const VkExtensionProperties &ext : availableExtensions )
{
Expand All @@ -112,11 +112,11 @@ namespace Ogre
FastArray<VkLayerProperties> availableLayers;
uint32 numInstanceLayers = 0u;
result = vkEnumerateInstanceLayerProperties( &numInstanceLayers, 0 );
checkVkResult( result, "vkEnumerateInstanceLayerProperties" );
checkVkResult( nullptr, result, "vkEnumerateInstanceLayerProperties" );

availableLayers.resize( numInstanceLayers );
result = vkEnumerateInstanceLayerProperties( &numInstanceLayers, availableLayers.begin() );
checkVkResult( result, "vkEnumerateInstanceLayerProperties" );
checkVkResult( nullptr, result, "vkEnumerateInstanceLayerProperties" );

for( auto &layer : availableLayers )
LogManager::getSingleton().logMessage( "Vulkan: Found instance layer: " +
Expand Down Expand Up @@ -290,7 +290,7 @@ namespace Ogre
#endif

VkResult result = vkCreateInstance( &createInfo, 0, &mVkInstance );
checkVkResult( result, "vkCreateInstance" );
checkVkResult( nullptr, result, "vkCreateInstance" );
}

#if OGRE_DEBUG_MODE >= OGRE_DEBUG_MEDIUM
Expand Down Expand Up @@ -347,19 +347,7 @@ namespace Ogre
dbgCreateInfo.pUserData = userdata;
VkResult result =
CreateDebugReportCallback( mVkInstance, &dbgCreateInfo, 0, &mDebugReportCallback );
switch( result )
{
case VK_SUCCESS:
break;
case VK_ERROR_OUT_OF_HOST_MEMORY:
OGRE_VK_EXCEPT( Exception::ERR_RENDERINGAPI_ERROR, result,
"CreateDebugReportCallback: out of host memory",
"VulkanInstance::addInstanceDebugCallback" );
default:
OGRE_VK_EXCEPT( Exception::ERR_RENDERINGAPI_ERROR, result,
"vkCreateDebugReportCallbackEXT",
"VulkanInstance::addInstanceDebugCallback" );
}
checkVkResult( nullptr, result, "vkCreateDebugReportCallbackEXT" );
}
#endif

Expand Down Expand Up @@ -412,11 +400,11 @@ namespace Ogre
FastArray<VkPhysicalDevice> devices;
uint32 numDevices = 0u;
VkResult result = vkEnumeratePhysicalDevices( mVkInstance, &numDevices, NULL );
checkVkResult( result, "vkEnumeratePhysicalDevices" );
checkVkResult( nullptr, result, "vkEnumeratePhysicalDevices" );

devices.resize( numDevices );
result = vkEnumeratePhysicalDevices( mVkInstance, &numDevices, devices.begin() );
checkVkResult( result, "vkEnumeratePhysicalDevices" );
checkVkResult( nullptr, result, "vkEnumeratePhysicalDevices" );

if( numDevices == 0u )
{
Expand Down Expand Up @@ -507,7 +495,7 @@ namespace Ogre
mVaoManager( 0 ),
mRenderSystem( renderSystem ),
mSupportedStages( 0xFFFFFFFF ),
mIsDeviceLost( false ),
mDeviceLostReason( VK_SUCCESS ),
mIsExternal( false )
{
}
Expand Down Expand Up @@ -664,6 +652,8 @@ namespace Ogre
{
destroy();

mDeviceLostReason = VK_SUCCESS;

if( externalDevice )
{
LogManager::getSingleton().logMessage(
Expand Down Expand Up @@ -715,13 +705,13 @@ namespace Ogre
// Obtain logical device
uint32 numExtensions = 0;
VkResult result = vkEnumerateDeviceExtensionProperties( mPhysicalDevice, 0, &numExtensions, 0 );
checkVkResult( result, "vkEnumerateDeviceExtensionProperties" );
checkVkResult( this, result, "vkEnumerateDeviceExtensionProperties" );

FastArray<VkExtensionProperties> availableExtensions;
availableExtensions.resize( numExtensions );
result = vkEnumerateDeviceExtensionProperties( mPhysicalDevice, 0, &numExtensions,
availableExtensions.begin() );
checkVkResult( result, "vkEnumerateDeviceExtensionProperties" );
checkVkResult( this, result, "vkEnumerateDeviceExtensionProperties" );

if( !externalDevice )
{
Expand Down Expand Up @@ -780,7 +770,7 @@ namespace Ogre
VkPipelineCacheCreateInfo pipelineCacheCreateInfo;
makeVkStruct( pipelineCacheCreateInfo, VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO );
result = vkCreatePipelineCache( mDevice, &pipelineCacheCreateInfo, nullptr, &mPipelineCache );
checkVkResult( result, "vkCreatePipelineCache" );
checkVkResult( this, result, "vkCreatePipelineCache" );

// debug utils
initUtils( mDevice );
Expand Down Expand Up @@ -984,7 +974,7 @@ namespace Ogre
createInfo.pEnabledFeatures = &mDeviceFeatures;

VkResult result = vkCreateDevice( mPhysicalDevice, &createInfo, NULL, &mDevice );
checkVkResult( result, "vkCreateDevice" );
checkVkResult( this, result, "vkCreateDevice" );
}
//-------------------------------------------------------------------------
bool VulkanDevice::hasDeviceExtension( const IdString extension ) const
Expand Down Expand Up @@ -1067,7 +1057,7 @@ namespace Ogre
mRenderSystem->resetAllBindings();

VkResult result = vkDeviceWaitIdle( mDevice );
checkVkResult( result, "vkDeviceWaitIdle" );
checkVkResult( this, result, "vkDeviceWaitIdle" );

mRenderSystem->_notifyDeviceStalled();
}
Expand Down
2 changes: 1 addition & 1 deletion RenderSystems/Vulkan/src/OgreVulkanGpuProgramManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ namespace Ogre

VkResult result =
vkCreateDescriptorSetLayout( mDevice->mDevice, &descSetLayoutCi, 0, &retVal );
checkVkResult( result, "vkCreateDescriptorSetLayout" );
checkVkResult( mDevice, result, "vkCreateDescriptorSetLayout" );
mDescriptorSetMap[set] = retVal;
}
else
Expand Down
6 changes: 3 additions & 3 deletions RenderSystems/Vulkan/src/OgreVulkanProgram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ namespace Ogre
moduleCi.codeSize = mSpirv.size() * sizeof( uint32 );
moduleCi.pCode = mSpirv.data();
VkResult result = vkCreateShaderModule( mDevice->mDevice, &moduleCi, 0, &mShaderModule );
checkVkResult( result, "vkCreateShaderModule" );
checkVkResult( mDevice, result, "vkCreateShaderModule" );

setObjectName( mDevice->mDevice, (uint64_t)mShaderModule,
VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, mName.c_str() );
Expand Down Expand Up @@ -383,7 +383,7 @@ namespace Ogre
moduleCi.pCode = mSpirv.data();
VkResult result =
vkCreateShaderModule( mDevice->mDevice, &moduleCi, 0, &mShaderModule );
checkVkResult( result, "vkCreateShaderModule" );
checkVkResult( mDevice, result, "vkCreateShaderModule" );

setObjectName( mDevice->mDevice, (uint64_t)mShaderModule,
VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, mName.c_str() );
Expand Down Expand Up @@ -802,7 +802,7 @@ namespace Ogre
moduleCi.codeSize = mSpirv.size() * sizeof( uint32 );
moduleCi.pCode = mSpirv.data();
VkResult result = vkCreateShaderModule( mDevice->mDevice, &moduleCi, 0, &mShaderModule );
checkVkResult( result, "vkCreateShaderModule" );
checkVkResult( mDevice, result, "vkCreateShaderModule" );

setObjectName( mDevice->mDevice, (uint64_t)mShaderModule,
VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, mName.c_str() );
Expand Down
26 changes: 12 additions & 14 deletions RenderSystems/Vulkan/src/OgreVulkanQueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ namespace Ogre
VkFenceCreateInfo fenceCi;
makeVkStruct( fenceCi, VK_STRUCTURE_TYPE_FENCE_CREATE_INFO );
VkResult result = vkCreateFence( mDevice, &fenceCi, 0, &retVal );
checkVkResult( result, "vkCreateFence" );
checkVkResult( mOwnerDevice, result, "vkCreateFence" );
}
return retVal;
}
Expand Down Expand Up @@ -163,7 +163,7 @@ namespace Ogre
{
VkResult result =
vkResetFences( mDevice, numFencesToReset, &mAvailableFences[oldNumAvailableFences] );
checkVkResult( result, "vkResetFences" );
checkVkResult( mOwnerDevice, result, "vkResetFences" );
}
}
//-------------------------------------------------------------------------
Expand Down Expand Up @@ -191,14 +191,14 @@ namespace Ogre
allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocateInfo.commandBufferCount = 1u;
VkResult result = vkAllocateCommandBuffers( mDevice, &allocateInfo, &cmdBuffer );
checkVkResult( result, "vkAllocateCommandBuffers" );
checkVkResult( mOwnerDevice, result, "vkAllocateCommandBuffers" );

frameData.mCommands.push_back( cmdBuffer );
}
else if( frameData.mCurrentCmdIdx == 0u )
{
VkResult result = vkResetCommandPool( mDevice, frameData.mCmdPool, 0 );
checkVkResult( result, "vkResetCommandPool" );
checkVkResult( mOwnerDevice, result, "vkResetCommandPool" );
}

return frameData.mCommands[frameData.mCurrentCmdIdx++];
Expand Down Expand Up @@ -276,7 +276,7 @@ namespace Ogre
for( size_t i = 0; i < maxNumFrames; ++i )
{
VkResult result = vkCreateFence( mDevice, &fenceCi, 0, &mAvailableFences[i] );
checkVkResult( result, "vkCreateFence" );
checkVkResult( mOwnerDevice, result, "vkCreateFence" );
}

// Create one cmd pool per thread (assume single threaded for now)
Expand All @@ -290,7 +290,7 @@ namespace Ogre
{
VkResult result =
vkCreateCommandPool( mDevice, &cmdPoolCreateInfo, 0, &mPerFrameData[i].mCmdPool );
checkVkResult( result, "vkCreateCommandPool" );
checkVkResult( mOwnerDevice, result, "vkCreateCommandPool" );
}

newCommandBuffer();
Expand All @@ -305,7 +305,7 @@ namespace Ogre
makeVkStruct( beginInfo, VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO );
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
VkResult result = vkBeginCommandBuffer( mCurrentCmdBuffer, &beginInfo );
checkVkResult( result, "vkBeginCommandBuffer" );
checkVkResult( mOwnerDevice, result, "vkBeginCommandBuffer" );
}
//-------------------------------------------------------------------------
void VulkanQueue::endCommandBuffer()
Expand All @@ -315,7 +315,7 @@ namespace Ogre
endAllEncoders();

VkResult result = vkEndCommandBuffer( mCurrentCmdBuffer );
checkVkResult( result, "vkEndCommandBuffer" );
checkVkResult( mOwnerDevice, result, "vkEndCommandBuffer" );

mPendingCmds.push_back( mCurrentCmdBuffer );
mCurrentCmdBuffer = 0;
Expand Down Expand Up @@ -1130,7 +1130,7 @@ namespace Ogre
if( itor->second.recycleAfterRelease )
{
VkResult result = vkResetFences( mDevice, 1u, &itor->first );
checkVkResult( result, "vkResetFences" );
checkVkResult( mOwnerDevice, result, "vkResetFences" );
mAvailableFences.push_back( itor->first );
}
mRefCountedFences.erase( itor );
Expand Down Expand Up @@ -1159,7 +1159,7 @@ namespace Ogre
{
const uint32 numFences = static_cast<uint32>( fences.size() );
VkResult result = vkWaitForFences( mDevice, numFences, &fences[0], VK_TRUE, UINT64_MAX );
checkVkResult( result, "vkWaitForFences" );
checkVkResult( mOwnerDevice, result, "vkWaitForFences" );
recycleFences( fences );
}
}
Expand All @@ -1175,7 +1175,7 @@ namespace Ogre
VkResult result = vkWaitForFences( mDevice, numFences, &fences[0], VK_TRUE, 0u );
if( result != VK_TIMEOUT )
{
checkVkResult( result, "vkWaitForFences" );
checkVkResult( mOwnerDevice, result, "vkWaitForFences" );
recycleFences( fences );
}
else
Expand Down Expand Up @@ -1254,8 +1254,6 @@ namespace Ogre
VkFence fence = mCurrentFence; // Note: mCurrentFence may be nullptr

VkResult result = vkQueueSubmit( mQueue, 1u, &submitInfo, fence );
if( result != VK_SUCCESS )
mOwnerDevice->mIsDeviceLost = true;
// we need some cleanup before checking result

mGpuWaitSemaphForCurrCmdBuff.clear();
Expand All @@ -1274,7 +1272,7 @@ namespace Ogre

mPendingCmds.clear();

checkVkResult( result, "vkQueueSubmit" );
checkVkResult( mOwnerDevice, result, "vkQueueSubmit" );

if( submissionType >= SubmissionType::EndFrameAndSwap )
{
Expand Down
Loading

0 comments on commit 9a56ec8

Please sign in to comment.