mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 13:10:10 +01:00
gfxstream: Add dispatcher validity checks
Add conditioning before making driver calls to be able to workaround some of the fatal errors, such as unboxing issues during or after snapshot load. This enables invalidating a host dispatcher based on the application state. A default error will be returned for vulkan calls. Builtin expectation function is used to reduce performance cost of the checks. Reviewed-by: Aaron Ruby <aruby@qnx.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34418>
This commit is contained in:
parent
284a1d5cb6
commit
c46e8ca4e6
3 changed files with 46 additions and 7 deletions
|
|
@ -629,7 +629,9 @@ class CodeGen(object):
|
|||
def generalLengthAccessGuard(self, vulkanType, parentVarName="parent"):
|
||||
return self.makeLengthAccess(vulkanType, parentVarName)[1]
|
||||
|
||||
def vkApiCall(self, api, customPrefix="", globalStatePrefix="", customParameters=None, checkForDeviceLost=False, checkForOutOfMemory=False):
|
||||
def vkApiCall(self, api, customPrefix="", globalStatePrefix="",
|
||||
customParameters=None, checkForDeviceLost=False,
|
||||
checkForOutOfMemory=False, checkDispatcher=None):
|
||||
callLhs = None
|
||||
|
||||
retTypeName = api.getRetTypeExpr()
|
||||
|
|
@ -637,9 +639,22 @@ class CodeGen(object):
|
|||
|
||||
if retTypeName != "void":
|
||||
retVar = api.getRetVarExpr()
|
||||
self.stmt("%s %s = (%s)0" % (retTypeName, retVar, retTypeName))
|
||||
defaultReturn = "(%s)0" % retTypeName
|
||||
if retTypeName == "VkResult":
|
||||
# TODO: return a valid error code based on the call
|
||||
# This is used to handle invalid dispatcher and snapshot states
|
||||
deviceLostFunctions = ["vkQueueSubmit",
|
||||
"vkQueueWaitIdle",
|
||||
"vkWaitForFences"]
|
||||
defaultReturn = "VK_ERROR_OUT_OF_HOST_MEMORY"
|
||||
if api in deviceLostFunctions:
|
||||
defaultReturn = "VK_ERROR_DEVICE_LOST"
|
||||
self.stmt("%s %s = %s" % (retTypeName, retVar, defaultReturn))
|
||||
callLhs = retVar
|
||||
|
||||
if (checkDispatcher):
|
||||
self.beginIf(checkDispatcher)
|
||||
|
||||
if customParameters is None:
|
||||
self.funcCall(
|
||||
callLhs, customPrefix + api.name, [p.paramName for p in api.parameters])
|
||||
|
|
@ -647,6 +662,9 @@ class CodeGen(object):
|
|||
self.funcCall(
|
||||
callLhs, customPrefix + api.name, customParameters)
|
||||
|
||||
if (checkDispatcher):
|
||||
self.endIf()
|
||||
|
||||
if retTypeName == "VkResult" and checkForDeviceLost:
|
||||
self.stmt("if ((%s) == VK_ERROR_DEVICE_LOST) %sDeviceLost()" % (callLhs, globalStatePrefix))
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ DELAYED_DECODER_DELETE_DICT_ENTRIES = [
|
|||
]
|
||||
|
||||
GLOBAL_COMMANDS_WITHOUT_DISPATCH = [
|
||||
"vkCreateInstance",
|
||||
"vkEnumerateInstanceVersion",
|
||||
"vkEnumerateInstanceExtensionProperties",
|
||||
"vkEnumerateInstanceLayerProperties",
|
||||
]
|
||||
|
|
@ -216,6 +218,10 @@ def emit_dispatch_unmarshal(typeInfo: VulkanTypeInfo, param: VulkanType, cgen, g
|
|||
cgen.stmt("auto vk = dispatch_%s(%s)" %
|
||||
(param.typeName, param.paramName))
|
||||
cgen.stmt("// End manual dispatchable handle unboxing for %s" % param.paramName)
|
||||
else:
|
||||
# Still need to check dispatcher validity to handle threads with fatal errors
|
||||
cgen.stmt("auto vk = dispatch_%s(%s)" %
|
||||
(param.typeName, param.paramName))
|
||||
|
||||
|
||||
def emit_transform(typeInfo, param, cgen, variant="tohost"):
|
||||
|
|
@ -344,12 +350,14 @@ def emit_dispatch_call(api, cgen):
|
|||
cgen.stmt("m_state->lock()")
|
||||
|
||||
whichDispatch = "vk->"
|
||||
checkDispatcher = "CC_LIKELY(vk)"
|
||||
if api.name in GLOBAL_COMMANDS_WITHOUT_DISPATCH:
|
||||
whichDispatch = "m_vk->"
|
||||
checkDispatcher = None
|
||||
|
||||
cgen.vkApiCall(api, customPrefix=whichDispatch, customParameters=customParams, \
|
||||
globalStatePrefix=global_state_prefix, checkForDeviceLost=True,
|
||||
checkForOutOfMemory=True)
|
||||
checkForOutOfMemory=True, checkDispatcher=checkDispatcher)
|
||||
|
||||
if api.name in driver_workarounds_global_lock_apis:
|
||||
if not delay:
|
||||
|
|
@ -366,7 +374,7 @@ def emit_global_state_wrapped_call(api, cgen, context):
|
|||
coreCustomParams = list(map(lambda p: p.paramName, api.parameters))
|
||||
|
||||
if delay:
|
||||
cgen.line("std::function<void()> delayed_remove_callback = [%s]() {" % ", ".join(coreCustomParams))
|
||||
cgen.line("std::function<void()> delayed_remove_callback = [vk, %s]() {" % ", ".join(coreCustomParams))
|
||||
cgen.stmt("auto m_state = VkDecoderGlobalState::get()")
|
||||
customParams = ["nullptr", "nullptr"] + coreCustomParams
|
||||
else:
|
||||
|
|
@ -374,9 +382,13 @@ def emit_global_state_wrapped_call(api, cgen, context):
|
|||
|
||||
if context:
|
||||
customParams += ["context"]
|
||||
|
||||
checkDispatcher = "CC_LIKELY(vk)"
|
||||
if api.name in GLOBAL_COMMANDS_WITHOUT_DISPATCH:
|
||||
checkDispatcher = None
|
||||
cgen.vkApiCall(api, customPrefix=global_state_prefix, \
|
||||
customParameters=customParams, globalStatePrefix=global_state_prefix, \
|
||||
checkForDeviceLost=True, checkForOutOfMemory=True)
|
||||
checkForDeviceLost=True, checkForOutOfMemory=True, checkDispatcher=checkDispatcher)
|
||||
|
||||
if delay:
|
||||
cgen.line("};")
|
||||
|
|
@ -835,6 +847,11 @@ class VulkanDecoder(VulkanWrapperGenerator):
|
|||
def onBegin(self,):
|
||||
self.module.appendImpl(
|
||||
"#define MAX_PACKET_LENGTH %s\n" % MAX_PACKET_LENGTH)
|
||||
self.module.appendImpl(
|
||||
"#define CC_LIKELY(exp) (__builtin_expect( !!(exp), true ))\n")
|
||||
self.module.appendImpl(
|
||||
"#define CC_UNLIKELY(exp) (__builtin_expect( !!(exp), false ))\n")
|
||||
|
||||
self.module.appendHeader(decoder_decl_preamble)
|
||||
self.module.appendImpl(decoder_impl_preamble)
|
||||
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ def emit_dispatch_call(api, cgen):
|
|||
|
||||
cgen.vkApiCall(api, customPrefix="vk->", customParameters=customParams,
|
||||
checkForDeviceLost=True, globalStatePrefix=global_state_prefix,
|
||||
checkForOutOfMemory=True)
|
||||
checkForOutOfMemory=True, checkDispatcher="CC_LIKELY(vk)")
|
||||
|
||||
if api.name in driver_workarounds_global_lock_apis:
|
||||
cgen.stmt("unlock()")
|
||||
|
|
@ -274,7 +274,7 @@ def emit_global_state_wrapped_call(api, cgen, context=False):
|
|||
customParams += ["context"];
|
||||
cgen.vkApiCall(api, customPrefix=global_state_prefix,
|
||||
customParameters=customParams, checkForDeviceLost=True,
|
||||
checkForOutOfMemory=True, globalStatePrefix=global_state_prefix)
|
||||
checkForOutOfMemory=True, globalStatePrefix=global_state_prefix, checkDispatcher="CC_LIKELY(vk)")
|
||||
|
||||
|
||||
def emit_default_decoding(typeInfo, api, cgen):
|
||||
|
|
@ -331,6 +331,10 @@ class VulkanSubDecoder(VulkanWrapperGenerator):
|
|||
|
||||
self.module.appendImpl(
|
||||
"#define MAX_PACKET_LENGTH %s\n" % MAX_PACKET_LENGTH)
|
||||
self.module.appendImpl(
|
||||
"#define CC_LIKELY(exp) (__builtin_expect( !!(exp), true ))\n")
|
||||
self.module.appendImpl(
|
||||
"#define CC_UNLIKELY(exp) (__builtin_expect( !!(exp), false ))\n")
|
||||
|
||||
self.module.appendImpl(
|
||||
"size_t subDecode(VulkanMemReadingStream* readStream, VulkanDispatch* vk, void* boxed_dispatchHandle, void* dispatchHandle, VkDeviceSize subDecodeDataSize, const void* pSubDecodeData, const VkDecoderContext& context)\n")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue