aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Stroyan <mike@LunarG.com>2015-05-11 17:18:14 -0600
committerMike Stroyan <mike@LunarG.com>2015-05-12 16:03:44 -0600
commit8cf6756e49e60b7a10751e5b31e77daebf0ae13b (patch)
treed6c2be854f3078417ef53b3d246b4592825556c8
parente03c95bd7fbff4237cbac0279e256aca8aecf0c3 (diff)
downloadusermoji-8cf6756e49e60b7a10751e5b31e77daebf0ae13b.tar.xz
layers: rework Threading layer to match version 91
Handle multiple thread checked parameters. Thread-check parameters in some calls that start with a VkDevice parameter. Use more recent WSI name pattern.
-rwxr-xr-xvk-layer-generate.py82
1 files changed, 63 insertions, 19 deletions
diff --git a/vk-layer-generate.py b/vk-layer-generate.py
index ab112232..369d63b1 100755
--- a/vk-layer-generate.py
+++ b/vk-layer-generate.py
@@ -1364,7 +1364,7 @@ class ThreadingSubcommand(Subcommand):
header_txt.append(' if (objectsInUse.find(object) == objectsInUse.end()) {')
header_txt.append(' objectsInUse[object] = tid;')
header_txt.append(' } else {')
- header_txt.append(' if (objectsInUse[object] == tid) {')
+ header_txt.append(' if (objectsInUse[object] != tid) {')
header_txt.append(' char str[1024];')
header_txt.append(' sprintf(str, "THREADING ERROR : object of type %s is simultaneously used in thread %ld and thread %ld", type, objectsInUse[object], tid);')
header_txt.append(' layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, 0, 0, THREADING_CHECKER_MULTIPLE_THREADS, "THREADING", str);')
@@ -1390,6 +1390,17 @@ class ThreadingSubcommand(Subcommand):
# use default version
return None
decl = proto.c_func(prefix="vk", attr="VKAPI")
+ thread_check_objects = [
+ "VkQueue",
+ "VkDeviceMemory",
+ "VkObject",
+ "VkBuffer",
+ "VkImage",
+ "VkDescriptorSet",
+ "VkDescriptorPool",
+ "VkCmdBuffer",
+ "VkSemaphore"
+ ]
ret_val = ''
stmt = ''
funcs = []
@@ -1414,35 +1425,68 @@ class ThreadingSubcommand(Subcommand):
' return VK_SUCCESS;\n'
' }\n'
'}' % (qual, decl, proto.params[0].name, self.layer_name, ret_val, proto.c_call(), stmt, self.layer_name))
+ return "\n".join(funcs)
+ # Memory range calls are special in needed thread checking within structs
+ if proto.name in ["FlushMappedMemoryRanges","InvalidateMappedMemoryRanges"]:
+ funcs.append('%s%s\n'
+ '{\n'
+ ' for (int i=0; i<memRangeCount; i++) {\n'
+ ' useObject((VkObject) pMemRanges[i].mem, "VkDeviceMemory");\n'
+ ' }\n'
+ ' %snextTable.%s;\n'
+ ' for (int i=0; i<memRangeCount; i++) {\n'
+ ' finishUsingObject((VkObject) pMemRanges[i].mem);\n'
+ ' }\n'
+ '%s'
+ '}' % (qual, decl, ret_val, proto.c_call(), stmt))
+ return "\n".join(funcs)
# All functions that do a Get are thread safe
- elif 'Get' in proto.name:
- return None
- # All Wsi functions are thread safe
- elif 'WsiX11' in proto.name:
- return None
- # All functions that start with a device parameter are thread safe
- elif proto.params[0].ty in { "VkDevice" }:
+ if 'Get' in proto.name:
return None
- # Only watch core objects passed as first parameter
- elif proto.params[0].ty not in vulkan.core.objects:
+ # All WSI functions are thread safe
+ if 'WSI' in proto.name:
return None
- elif proto.params[0].ty != "VkPhysicalDevice":
+ # Initialize in early calls
+ if proto.params[0].ty == "VkPhysicalDevice":
funcs.append('%s%s\n'
'{\n'
- ' useObject((VkObject) %s, "%s");\n'
+ ' pCurObj = (VkBaseLayerObject *) %s;\n'
+ ' loader_platform_thread_once(&tabOnce, init%s);\n'
' %snextTable.%s;\n'
- ' finishUsingObject((VkObject) %s);\n'
'%s'
- '}' % (qual, decl, proto.params[0].name, proto.params[0].ty, ret_val, proto.c_call(), proto.params[0].name, stmt))
- else:
+ '}' % (qual, decl, proto.params[0].name, self.layer_name, ret_val, proto.c_call(), stmt))
+ return "\n".join(funcs)
+ # Functions changing command buffers need thread safe use of first parameter
+ if proto.params[0].ty == "VkCmdBuffer":
funcs.append('%s%s\n'
'{\n'
- ' pCurObj = (VkBaseLayerObject *) %s;\n'
- ' loader_platform_thread_once(&tabOnce, init%s);\n'
+ ' useObject((VkObject) %s, "%s");\n'
' %snextTable.%s;\n'
+ ' finishUsingObject((VkObject) %s);\n'
'%s'
- '}' % (qual, decl, proto.params[0].name, self.layer_name, ret_val, proto.c_call(), stmt))
- return "\n\n".join(funcs)
+ '}' % (qual, decl, proto.params[0].name, proto.params[0].ty, ret_val, proto.c_call(), proto.params[0].name, stmt))
+ return "\n".join(funcs)
+ # Non-Cmd functions that do a Wait are thread safe
+ if 'Wait' in proto.name:
+ return None
+ # Watch use of certain types of objects passed as any parameter
+ checked_params = []
+ for param in proto.params:
+ if param.ty in thread_check_objects:
+ checked_params.append(param)
+ if len(checked_params) == 0:
+ return None
+ # Surround call with useObject and finishUsingObject for each checked_param
+ funcs.append('%s%s' % (qual, decl))
+ funcs.append('{')
+ for param in checked_params:
+ funcs.append(' useObject((VkObject) %s, "%s");' % (param.name, param.ty))
+ funcs.append(' %snextTable.%s;' % (ret_val, proto.c_call()))
+ for param in checked_params:
+ funcs.append(' finishUsingObject((VkObject) %s);' % param.name)
+ funcs.append('%s'
+ '}' % stmt)
+ return "\n".join(funcs)
def generate_body(self):
self.layer_name = "Threading"