aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDustin Graves <dustin@lunarg.com>2016-03-03 14:17:08 -0700
committerDustin Graves <dustin@lunarg.com>2016-03-07 12:06:57 -0700
commit5aefef01499d849a090b5af5143efce45bf0ebea (patch)
tree0c9469d1fcd6953d42261d36f53961ed04f93cc2
parent9d7503f4d1563d1be2e8fcdea9a4e8e33f1bd541 (diff)
downloadusermoji-5aefef01499d849a090b5af5143efce45bf0ebea.tar.xz
layers: Add param checks for CreateInstance/Device
Add parameter checks for vkCreateDevice and vkCreateInstance. Includes a local fix for GitHub Vulkan-Docs issue #104 to prevent false positives from being generated for the pCreateInfo->pEnabledFeatures == NULL case. Change-Id: I1f3642e7e18c8bfb32b0996b6e2e57a5f9d8e011
-rw-r--r--generator.py33
-rw-r--r--layers/param_checker.cpp71
-rw-r--r--vk.xml2
3 files changed, 63 insertions, 43 deletions
diff --git a/generator.py b/generator.py
index cdca69ab..702627f3 100644
--- a/generator.py
+++ b/generator.py
@@ -2708,8 +2708,8 @@ class ParamCheckerOutputGenerator(OutputGenerator):
self.INDENT_SPACES = 4
# Commands to ignore
self.blacklist = [
- 'vkCreateInstance', 'vkCreateDevice',
- 'vkGetInstanceProcAddr', 'vkGetDeviceProcAddr',
+ 'vkGetInstanceProcAddr',
+ 'vkGetDeviceProcAddr',
'vkEnumerateInstanceLayerProperties',
'vkEnumerateInstanceExtensionsProperties',
'vkEnumerateDeviceLayerProperties',
@@ -2735,7 +2735,7 @@ class ParamCheckerOutputGenerator(OutputGenerator):
if indent:
return indent + inc
return inc
-
+ #
def decIndent(self, indent):
if indent and (len(indent) > self.INDENT_SPACES):
return indent[:-self.INDENT_SPACES]
@@ -3032,8 +3032,13 @@ class ParamCheckerOutputGenerator(OutputGenerator):
lines = cmd.cdecl[:-1].split('\n')
# Replace Vulkan prototype
lines[0] = 'static VkBool32 param_check_' + cmd.name + '('
- # Replace the first argument with debug_report_data
- lines[1] = ' debug_report_data*'.ljust(self.genOpts.alignFuncParam) + 'report_data,'
+ # Replace the first argument with debug_report_data, when the first
+ # argument is a handle (not vkCreateInstance)
+ reportData = ' debug_report_data*'.ljust(self.genOpts.alignFuncParam) + 'report_data,'
+ if cmd.name != 'vkCreateInstance':
+ lines[1] = reportData
+ else:
+ lines.insert(1, reportData)
return '\n'.join(lines)
#
# Generate the code to check for a NULL dereference before calling the
@@ -3129,8 +3134,6 @@ class ParamCheckerOutputGenerator(OutputGenerator):
checkExpr = 'skipCall |= validate_array(report_data, {}, "{ln}", {dn}, {pf}{ln}, {pf}{vn}, {}, {});\n'.format(name, cvReq, req, ln=lenParam.name, dn=valueDisplayName, vn=value.name, pf=valuePrefix)
elif not value.isoptional:
checkExpr = 'skipCall |= validate_required_pointer(report_data, {}, {}, {}{vn});\n'.format(name, valueDisplayName, valuePrefix, vn=value.name)
- else:
- unused.append(value.name)
#
# If this is a pointer to a struct, see if it contains members
# that need to be checked
@@ -3145,8 +3148,6 @@ class ParamCheckerOutputGenerator(OutputGenerator):
# The name prefix used when reporting an error with a struct member (eg. the 'pCreateInfor->' in 'pCreateInfo->sType')
prefix = '(std::string({}) + std::string("{}.")).c_str()'.format(variablePrefix, value.name) if variablePrefix else '"{}."'.format(value.name)
checkExpr += 'skipCall |= param_check_{}(report_data, {}, {}, &({}{}));\n'.format(value.type, name, prefix, valuePrefix, value.name)
- elif not value.iscount:
- unused.append(value.name)
#
# Append the parameter check to the function body for the current command
if checkExpr:
@@ -3156,6 +3157,10 @@ class ParamCheckerOutputGenerator(OutputGenerator):
funcBody += self.genCheckedLengthCall(indent, lenParam.name, checkExpr)
else:
funcBody += indent + checkExpr
+ elif not value.iscount:
+ # The parameter is not checked (counts will be checked with
+ # their associated array)
+ unused.append(value.name)
return funcBody, unused
#
# Post-process the collected struct member data to create a list of structs
@@ -3224,8 +3229,12 @@ class ParamCheckerOutputGenerator(OutputGenerator):
cmdDef += '{\n'
# Process unused parameters
# Ignore the first dispatch handle parameter, which is not
- # processed by param_check
- for name in unused[1:]:
+ # processed by param_check (except for vkCreateInstance, which
+ # does not have a handle as its first parameter)
+ startIndex = 1
+ if command.name == 'vkCreateInstance':
+ startIndex = 0
+ for name in unused[startIndex:]:
cmdDef += indent + 'UNUSED_PARAMETER({});\n'.format(name)
if len(unused) > 1:
cmdDef += '\n'
@@ -3235,5 +3244,3 @@ class ParamCheckerOutputGenerator(OutputGenerator):
cmdDef += indent + 'return skipCall;\n'
cmdDef += '}\n'
self.appendSection('command', cmdDef)
-
-
diff --git a/layers/param_checker.cpp b/layers/param_checker.cpp
index cf8c76f0..8dcfec16 100644
--- a/layers/param_checker.cpp
+++ b/layers/param_checker.cpp
@@ -1797,49 +1797,59 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(
const VkAllocationCallbacks* pAllocator,
VkInstance* pInstance)
{
- VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
- VkBool32 skipCall = VK_FALSE;
+ VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
- if (skipCall == VK_FALSE) {
- VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
- assert(chain_info->u.pLayerInfo);
- PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
- PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance");
- if (fpCreateInstance == NULL) {
- return VK_ERROR_INITIALIZATION_FAILED;
- }
+ VkLayerInstanceCreateInfo *chain_info =
+ get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
+ assert(chain_info->u.pLayerInfo);
+ PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr =
+ chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+ PFN_vkCreateInstance fpCreateInstance =
+ (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
+ if (fpCreateInstance == NULL) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
- // Advance the link info for the next element on the chain
- chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+ // Advance the link info for the next element on the chain
+ chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
- result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
- if (result != VK_SUCCESS)
- return result;
+ result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
+ if (result != VK_SUCCESS) {
+ return result;
+ }
- layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
- VkLayerInstanceDispatchTable *pTable = initInstanceTable(*pInstance, fpGetInstanceProcAddr, pc_instance_table_map);
+ layer_data *my_data =
+ get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
+ VkLayerInstanceDispatchTable *pTable = initInstanceTable(
+ *pInstance, fpGetInstanceProcAddr, pc_instance_table_map);
- my_data->report_data = debug_report_create_instance(
- pTable,
- *pInstance,
- pCreateInfo->enabledExtensionCount,
- pCreateInfo->ppEnabledExtensionNames);
+ my_data->report_data = debug_report_create_instance(
+ pTable, *pInstance, pCreateInfo->enabledExtensionCount,
+ pCreateInfo->ppEnabledExtensionNames);
- InitParamChecker(my_data, pAllocator);
- }
+ InitParamChecker(my_data, pAllocator);
// Ordinarily we'd check these before calling down the chain, but none of the layer
// support is in place until now, if we survive we can report the issue now.
- layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
+ layer_data *my_instance_data =
+ get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
+
+ param_check_vkCreateInstance(my_instance_data->report_data, pCreateInfo,
+ pAllocator, pInstance);
+
if (pCreateInfo->pApplicationInfo) {
if (pCreateInfo->pApplicationInfo->pApplicationName) {
- skipCall |= validate_string(my_device_data, "vkCreateInstance()", "VkInstanceCreateInfo->VkApplicationInfo->pApplicationName",
- pCreateInfo->pApplicationInfo->pApplicationName);
+ validate_string(
+ my_instance_data, "vkCreateInstance()",
+ "VkInstanceCreateInfo->VkApplicationInfo->pApplicationName",
+ pCreateInfo->pApplicationInfo->pApplicationName);
}
if (pCreateInfo->pApplicationInfo->pEngineName) {
- skipCall |= validate_string(my_device_data, "vkCreateInstance()", "VkInstanceCreateInfo->VkApplicationInfo->pEngineName",
- pCreateInfo->pApplicationInfo->pEngineName);
+ validate_string(
+ my_instance_data, "vkCreateInstance()",
+ "VkInstanceCreateInfo->VkApplicationInfo->pEngineName",
+ pCreateInfo->pApplicationInfo->pEngineName);
}
}
@@ -2237,6 +2247,9 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(
VkBool32 skipCall = VK_FALSE;
layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+ skipCall |= param_check_vkCreateDevice(my_instance_data->report_data,
+ pCreateInfo, pAllocator, pDevice);
+
if ((pCreateInfo->enabledLayerCount > 0) && (pCreateInfo->ppEnabledLayerNames != NULL)) {
for (auto i = 0; i < pCreateInfo->enabledLayerCount; i++) {
skipCall |= validate_string(my_instance_data, "vkCreateDevice()", "VkDeviceCreateInfo->ppEnabledLayerNames",
diff --git a/vk.xml b/vk.xml
index 41e151a2..c863c5a8 100644
--- a/vk.xml
+++ b/vk.xml
@@ -488,7 +488,7 @@ maintained in the master branch of the Khronos Vulkan Github project.
<member optional="true" len="enabledLayerCount,null-terminated">const <type>char</type>* const* <name>ppEnabledLayerNames</name></member> <!-- Ordered list of layer names to be enabled -->
<member optional="true"><type>uint32_t</type> <name>enabledExtensionCount</name></member>
<member optional="true" len="enabledExtensionCount,null-terminated">const <type>char</type>* const* <name>ppEnabledExtensionNames</name></member>
- <member>const <type>VkPhysicalDeviceFeatures</type>* <name>pEnabledFeatures</name></member>
+ <member optional="true">const <type>VkPhysicalDeviceFeatures</type>* <name>pEnabledFeatures</name></member>
<validity>
<usage>Any given element of pname:ppEnabledLayerNames must: be the name of a layer present on the system, exactly matching a string returned in the sname:VkLayerProperties structure by fname:vkEnumerateDeviceLayerProperties</usage>
<usage>Any given element of pname:ppEnabledExtensionNames must: be the name of an extension present on the system, exactly matching a string returned in the sname:VkExtensionProperties structure by fname:vkEnumerateDeviceExtensionProperties</usage>