summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJon Leech <[email protected]>2019-08-17 15:58:46 -0700
committerJon Leech <[email protected]>2019-08-17 15:59:53 -0700
commit4ee33d2fbd1e7a072c4d8a6cf8f01c4f96d7483d (patch)
tree267945d47d5ce0a4ccff68e1a6523aad4f766f5a
parent23b2e8e64bdf3f25b3d73f1593e72977ebfcd39b (diff)
downloadVulkan-Headers-1.1.120.tar.gz
Vulkan-Headers-1.1.120.zip
Update for Vulkan-Docs 1.1.120v1.1.120
-rw-r--r--include/vulkan/vulkan.hpp57
-rw-r--r--include/vulkan/vulkan_android.h9
-rw-r--r--include/vulkan/vulkan_core.h36
-rw-r--r--include/vulkan/vulkan_fuchsia.h9
-rw-r--r--include/vulkan/vulkan_ggp.h9
-rw-r--r--include/vulkan/vulkan_ios.h9
-rw-r--r--include/vulkan/vulkan_macos.h9
-rw-r--r--include/vulkan/vulkan_metal.h9
-rw-r--r--include/vulkan/vulkan_vi.h9
-rw-r--r--include/vulkan/vulkan_wayland.h9
-rw-r--r--include/vulkan/vulkan_win32.h9
-rw-r--r--include/vulkan/vulkan_xcb.h9
-rw-r--r--include/vulkan/vulkan_xlib.h9
-rw-r--r--include/vulkan/vulkan_xlib_xrandr.h9
-rw-r--r--registry/cgenerator.py74
-rw-r--r--registry/conventions.py254
-rw-r--r--registry/generator.py244
-rw-r--r--registry/genvk.py26
-rw-r--r--registry/reg.py26
-rw-r--r--registry/validusage.json40
-rw-r--r--registry/vk.xml9
-rw-r--r--registry/vkconventions.py70
22 files changed, 598 insertions, 346 deletions
diff --git a/include/vulkan/vulkan.hpp b/include/vulkan/vulkan.hpp
index f3a7df6..a3fbd2a 100644
--- a/include/vulkan/vulkan.hpp
+++ b/include/vulkan/vulkan.hpp
@@ -56,7 +56,7 @@
# define VULKAN_HPP_ASSERT assert
#endif
-static_assert( VK_HEADER_VERSION == 119 , "Wrong VK_HEADER_VERSION!" );
+static_assert( VK_HEADER_VERSION == 120 , "Wrong VK_HEADER_VERSION!" );
// 32-bit vulkan is not typesafe for handles, so don't allow copy constructors on this platform by default.
// To enable this feature on 32-bit platforms please define VULKAN_HPP_TYPESAFE_CONVERSION
@@ -6017,7 +6017,8 @@ namespace VULKAN_HPP_NAMESPACE
enum class ValidationFeatureEnableEXT
{
eGpuAssisted = VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT,
- eGpuAssistedReserveBindingSlot = VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT
+ eGpuAssistedReserveBindingSlot = VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT,
+ eBestPractices = VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT
};
VULKAN_HPP_INLINE std::string to_string( ValidationFeatureEnableEXT value )
@@ -6026,6 +6027,7 @@ namespace VULKAN_HPP_NAMESPACE
{
case ValidationFeatureEnableEXT::eGpuAssisted : return "GpuAssisted";
case ValidationFeatureEnableEXT::eGpuAssistedReserveBindingSlot : return "GpuAssistedReserveBindingSlot";
+ case ValidationFeatureEnableEXT::eBestPractices : return "BestPractices";
default: return "invalid";
}
}
@@ -23020,8 +23022,8 @@ namespace VULKAN_HPP_NAMESPACE
vk::ClearColorValue color;
vk::ClearDepthStencilValue depthStencil;
#else
- Vkvk::ClearColorValue color;
- Vkvk::ClearDepthStencilValue depthStencil;
+ VkClearColorValue color;
+ VkClearDepthStencilValue depthStencil;
#endif /*VULKAN_HPP_HAS_UNRESTRICTED_UNIONS*/
};
@@ -42563,7 +42565,7 @@ namespace VULKAN_HPP_NAMESPACE
uint32_t value32;
uint64_t value64;
float valueFloat;
- Vkvk::Bool32 valueBool;
+ VkBool32 valueBool;
const char* valueString;
#endif /*VULKAN_HPP_HAS_UNRESTRICTED_UNIONS*/
};
@@ -52291,49 +52293,6 @@ namespace VULKAN_HPP_NAMESPACE
union PipelineExecutableStatisticValueKHR
{
- PipelineExecutableStatisticValueKHR( vk::Bool32 b32_ = 0 )
- {
- b32 = b32_;
- }
-
- PipelineExecutableStatisticValueKHR( int64_t i64_ )
- {
- i64 = i64_;
- }
-
- PipelineExecutableStatisticValueKHR( uint64_t u64_ )
- {
- u64 = u64_;
- }
-
- PipelineExecutableStatisticValueKHR( double f64_ )
- {
- f64 = f64_;
- }
-
- PipelineExecutableStatisticValueKHR & setB32( vk::Bool32 b32_ )
- {
- b32 = b32_;
- return *this;
- }
-
- PipelineExecutableStatisticValueKHR & setI64( int64_t i64_ )
- {
- i64 = i64_;
- return *this;
- }
-
- PipelineExecutableStatisticValueKHR & setU64( uint64_t u64_ )
- {
- u64 = u64_;
- return *this;
- }
-
- PipelineExecutableStatisticValueKHR & setF64( double f64_ )
- {
- f64 = f64_;
- return *this;
- }
operator VkPipelineExecutableStatisticValueKHR const&() const
{
return *reinterpret_cast<const VkPipelineExecutableStatisticValueKHR*>(this);
@@ -52350,7 +52309,7 @@ namespace VULKAN_HPP_NAMESPACE
uint64_t u64;
double f64;
#else
- Vkvk::Bool32 b32;
+ VkBool32 b32;
int64_t i64;
uint64_t u64;
double f64;
diff --git a/include/vulkan/vulkan_android.h b/include/vulkan/vulkan_android.h
index 1861802..9b8d3e2 100644
--- a/include/vulkan/vulkan_android.h
+++ b/include/vulkan/vulkan_android.h
@@ -1,10 +1,6 @@
#ifndef VULKAN_ANDROID_H_
#define VULKAN_ANDROID_H_ 1
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/*
** Copyright (c) 2015-2019 The Khronos Group Inc.
**
@@ -27,6 +23,11 @@ extern "C" {
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
#define VK_KHR_android_surface 1
struct ANativeWindow;
diff --git a/include/vulkan/vulkan_core.h b/include/vulkan/vulkan_core.h
index e811beb..888674e 100644
--- a/include/vulkan/vulkan_core.h
+++ b/include/vulkan/vulkan_core.h
@@ -1,10 +1,6 @@
#ifndef VULKAN_CORE_H_
#define VULKAN_CORE_H_ 1
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/*
** Copyright (c) 2015-2019 The Khronos Group Inc.
**
@@ -27,6 +23,11 @@ extern "C" {
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
#define VK_VERSION_1_0 1
#include "vk_platform.h"
@@ -43,7 +44,7 @@ extern "C" {
#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff)
#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff)
// Version of this file
-#define VK_HEADER_VERSION 119
+#define VK_HEADER_VERSION 120
#define VK_NULL_HANDLE 0
@@ -8446,6 +8447,15 @@ VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureNV)
#define VK_NV_RAY_TRACING_EXTENSION_NAME "VK_NV_ray_tracing"
#define VK_SHADER_UNUSED_NV (~0U)
+typedef enum VkAccelerationStructureTypeNV {
+ VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV = 0,
+ VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV = 1,
+ VK_ACCELERATION_STRUCTURE_TYPE_BEGIN_RANGE_NV = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV,
+ VK_ACCELERATION_STRUCTURE_TYPE_END_RANGE_NV = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV,
+ VK_ACCELERATION_STRUCTURE_TYPE_RANGE_SIZE_NV = (VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV - VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV + 1),
+ VK_ACCELERATION_STRUCTURE_TYPE_MAX_ENUM_NV = 0x7FFFFFFF
+} VkAccelerationStructureTypeNV;
+
typedef enum VkRayTracingShaderGroupTypeNV {
VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV = 0,
VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_NV = 1,
@@ -8465,15 +8475,6 @@ typedef enum VkGeometryTypeNV {
VK_GEOMETRY_TYPE_MAX_ENUM_NV = 0x7FFFFFFF
} VkGeometryTypeNV;
-typedef enum VkAccelerationStructureTypeNV {
- VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV = 0,
- VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV = 1,
- VK_ACCELERATION_STRUCTURE_TYPE_BEGIN_RANGE_NV = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV,
- VK_ACCELERATION_STRUCTURE_TYPE_END_RANGE_NV = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV,
- VK_ACCELERATION_STRUCTURE_TYPE_RANGE_SIZE_NV = (VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV - VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV + 1),
- VK_ACCELERATION_STRUCTURE_TYPE_MAX_ENUM_NV = 0x7FFFFFFF
-} VkAccelerationStructureTypeNV;
-
typedef enum VkCopyAccelerationStructureModeNV {
VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV = 0,
VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV = 1,
@@ -9538,15 +9539,16 @@ typedef struct VkImageStencilUsageCreateInfoEXT {
#define VK_EXT_validation_features 1
-#define VK_EXT_VALIDATION_FEATURES_SPEC_VERSION 1
+#define VK_EXT_VALIDATION_FEATURES_SPEC_VERSION 2
#define VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME "VK_EXT_validation_features"
typedef enum VkValidationFeatureEnableEXT {
VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT = 0,
VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT = 1,
+ VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT = 2,
VK_VALIDATION_FEATURE_ENABLE_BEGIN_RANGE_EXT = VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT,
- VK_VALIDATION_FEATURE_ENABLE_END_RANGE_EXT = VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT,
- VK_VALIDATION_FEATURE_ENABLE_RANGE_SIZE_EXT = (VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT - VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT + 1),
+ VK_VALIDATION_FEATURE_ENABLE_END_RANGE_EXT = VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT,
+ VK_VALIDATION_FEATURE_ENABLE_RANGE_SIZE_EXT = (VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT - VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT + 1),
VK_VALIDATION_FEATURE_ENABLE_MAX_ENUM_EXT = 0x7FFFFFFF
} VkValidationFeatureEnableEXT;
diff --git a/include/vulkan/vulkan_fuchsia.h b/include/vulkan/vulkan_fuchsia.h
index 4c62a7c..81ebe55 100644
--- a/include/vulkan/vulkan_fuchsia.h
+++ b/include/vulkan/vulkan_fuchsia.h
@@ -1,10 +1,6 @@
#ifndef VULKAN_FUCHSIA_H_
#define VULKAN_FUCHSIA_H_ 1
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/*
** Copyright (c) 2015-2019 The Khronos Group Inc.
**
@@ -27,6 +23,11 @@ extern "C" {
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
#define VK_FUCHSIA_imagepipe_surface 1
#define VK_FUCHSIA_IMAGEPIPE_SURFACE_SPEC_VERSION 1
diff --git a/include/vulkan/vulkan_ggp.h b/include/vulkan/vulkan_ggp.h
index 3d67c4b..fd30613 100644
--- a/include/vulkan/vulkan_ggp.h
+++ b/include/vulkan/vulkan_ggp.h
@@ -1,10 +1,6 @@
#ifndef VULKAN_GGP_H_
#define VULKAN_GGP_H_ 1
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/*
** Copyright (c) 2015-2019 The Khronos Group Inc.
**
@@ -27,6 +23,11 @@ extern "C" {
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
#define VK_GGP_stream_descriptor_surface 1
#define VK_GGP_STREAM_DESCRIPTOR_SURFACE_SPEC_VERSION 1
diff --git a/include/vulkan/vulkan_ios.h b/include/vulkan/vulkan_ios.h
index 1846df5..72ef1a8 100644
--- a/include/vulkan/vulkan_ios.h
+++ b/include/vulkan/vulkan_ios.h
@@ -1,10 +1,6 @@
#ifndef VULKAN_IOS_H_
#define VULKAN_IOS_H_ 1
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/*
** Copyright (c) 2015-2019 The Khronos Group Inc.
**
@@ -27,6 +23,11 @@ extern "C" {
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
#define VK_MVK_ios_surface 1
#define VK_MVK_IOS_SURFACE_SPEC_VERSION 2
diff --git a/include/vulkan/vulkan_macos.h b/include/vulkan/vulkan_macos.h
index dca623b..e6e5dea 100644
--- a/include/vulkan/vulkan_macos.h
+++ b/include/vulkan/vulkan_macos.h
@@ -1,10 +1,6 @@
#ifndef VULKAN_MACOS_H_
#define VULKAN_MACOS_H_ 1
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/*
** Copyright (c) 2015-2019 The Khronos Group Inc.
**
@@ -27,6 +23,11 @@ extern "C" {
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
#define VK_MVK_macos_surface 1
#define VK_MVK_MACOS_SURFACE_SPEC_VERSION 2
diff --git a/include/vulkan/vulkan_metal.h b/include/vulkan/vulkan_metal.h
index 1650523..3dec68c 100644
--- a/include/vulkan/vulkan_metal.h
+++ b/include/vulkan/vulkan_metal.h
@@ -1,10 +1,6 @@
#ifndef VULKAN_METAL_H_
#define VULKAN_METAL_H_ 1
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/*
** Copyright (c) 2015-2019 The Khronos Group Inc.
**
@@ -27,6 +23,11 @@ extern "C" {
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
#define VK_EXT_metal_surface 1
diff --git a/include/vulkan/vulkan_vi.h b/include/vulkan/vulkan_vi.h
index 50aa27d..6fb66f9 100644
--- a/include/vulkan/vulkan_vi.h
+++ b/include/vulkan/vulkan_vi.h
@@ -1,10 +1,6 @@
#ifndef VULKAN_VI_H_
#define VULKAN_VI_H_ 1
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/*
** Copyright (c) 2015-2019 The Khronos Group Inc.
**
@@ -27,6 +23,11 @@ extern "C" {
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
#define VK_NN_vi_surface 1
#define VK_NN_VI_SURFACE_SPEC_VERSION 1
diff --git a/include/vulkan/vulkan_wayland.h b/include/vulkan/vulkan_wayland.h
index 12a5f04..599d05b 100644
--- a/include/vulkan/vulkan_wayland.h
+++ b/include/vulkan/vulkan_wayland.h
@@ -1,10 +1,6 @@
#ifndef VULKAN_WAYLAND_H_
#define VULKAN_WAYLAND_H_ 1
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/*
** Copyright (c) 2015-2019 The Khronos Group Inc.
**
@@ -27,6 +23,11 @@ extern "C" {
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
#define VK_KHR_wayland_surface 1
#define VK_KHR_WAYLAND_SURFACE_SPEC_VERSION 6
diff --git a/include/vulkan/vulkan_win32.h b/include/vulkan/vulkan_win32.h
index a61a7d8..7e6016e 100644
--- a/include/vulkan/vulkan_win32.h
+++ b/include/vulkan/vulkan_win32.h
@@ -1,10 +1,6 @@
#ifndef VULKAN_WIN32_H_
#define VULKAN_WIN32_H_ 1
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/*
** Copyright (c) 2015-2019 The Khronos Group Inc.
**
@@ -27,6 +23,11 @@ extern "C" {
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
#define VK_KHR_win32_surface 1
#define VK_KHR_WIN32_SURFACE_SPEC_VERSION 6
diff --git a/include/vulkan/vulkan_xcb.h b/include/vulkan/vulkan_xcb.h
index 7d6905d..4cc0bc0 100644
--- a/include/vulkan/vulkan_xcb.h
+++ b/include/vulkan/vulkan_xcb.h
@@ -1,10 +1,6 @@
#ifndef VULKAN_XCB_H_
#define VULKAN_XCB_H_ 1
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/*
** Copyright (c) 2015-2019 The Khronos Group Inc.
**
@@ -27,6 +23,11 @@ extern "C" {
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
#define VK_KHR_xcb_surface 1
#define VK_KHR_XCB_SURFACE_SPEC_VERSION 6
diff --git a/include/vulkan/vulkan_xlib.h b/include/vulkan/vulkan_xlib.h
index 7a05d29..ee2b48a 100644
--- a/include/vulkan/vulkan_xlib.h
+++ b/include/vulkan/vulkan_xlib.h
@@ -1,10 +1,6 @@
#ifndef VULKAN_XLIB_H_
#define VULKAN_XLIB_H_ 1
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/*
** Copyright (c) 2015-2019 The Khronos Group Inc.
**
@@ -27,6 +23,11 @@ extern "C" {
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
#define VK_KHR_xlib_surface 1
#define VK_KHR_XLIB_SURFACE_SPEC_VERSION 6
diff --git a/include/vulkan/vulkan_xlib_xrandr.h b/include/vulkan/vulkan_xlib_xrandr.h
index 3a20953..08c4fd7 100644
--- a/include/vulkan/vulkan_xlib_xrandr.h
+++ b/include/vulkan/vulkan_xlib_xrandr.h
@@ -1,10 +1,6 @@
#ifndef VULKAN_XLIB_XRANDR_H_
#define VULKAN_XLIB_XRANDR_H_ 1
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/*
** Copyright (c) 2015-2019 The Khronos Group Inc.
**
@@ -27,6 +23,11 @@ extern "C" {
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
#define VK_EXT_acquire_xlib_display 1
#define VK_EXT_ACQUIRE_XLIB_DISPLAY_SPEC_VERSION 1
diff --git a/registry/cgenerator.py b/registry/cgenerator.py
index 7f2d9bc..75e03cf 100644
--- a/registry/cgenerator.py
+++ b/registry/cgenerator.py
@@ -134,15 +134,11 @@ class COutputGenerator(OutputGenerator):
'group', 'bitmask', 'funcpointer', 'struct']
ALL_SECTIONS = TYPE_SECTIONS + ['commandPointer', 'command']
- def __init__(self,
- errFile = sys.stderr,
- warnFile = sys.stderr,
- diagFile = sys.stdout):
- OutputGenerator.__init__(self, errFile, warnFile, diagFile)
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
# Internal state - accumulators for different inner block text
self.sections = {section: [] for section in self.ALL_SECTIONS}
self.feature_not_empty = False
- self.need_platform_include = False
self.may_alias = None
def beginFile(self, genOpts):
@@ -156,16 +152,19 @@ class COutputGenerator(OutputGenerator):
write('#ifndef', headerSym, file=self.outFile)
write('#define', headerSym, '1', file=self.outFile)
self.newline()
- write('#ifdef __cplusplus', file=self.outFile)
- write('extern "C" {', file=self.outFile)
- write('#endif', file=self.outFile)
- self.newline()
# User-supplied prefix text, if any (list of strings)
if genOpts.prefixText:
for s in genOpts.prefixText:
write(s, file=self.outFile)
+ # C++ extern wrapper - after prefix lines so they can add includes.
+ self.newline()
+ write('#ifdef __cplusplus', file=self.outFile)
+ write('extern "C" {', file=self.outFile)
+ write('#endif', file=self.outFile)
+ self.newline()
+
def endFile(self):
# C-specific
# Finish C++ wrapper and multiple inclusion protection
@@ -206,14 +205,6 @@ class COutputGenerator(OutputGenerator):
self.newline()
write('#define', self.featureName, '1', file=self.outFile)
for section in self.TYPE_SECTIONS:
- # OpenXR:
- # If we need the explicit include of the external platform header,
- # put it right before the function pointer definitions
- if section == "funcpointer" and self.need_platform_include:
- write('// Include for OpenXR Platform-Specific Types', file=self.outFile)
- write('#include "openxr_platform.h"', file=self.outFile)
- self.newline()
- self.need_platform_include = False
contents = self.sections[section]
if contents:
write('\n'.join(contents), file=self.outFile)
@@ -292,27 +283,19 @@ class COutputGenerator(OutputGenerator):
def genProtectString(self, protect_str):
protect_if_str = ''
protect_end_str = ''
- protect_list = []
- if protect_str:
- if ',' in protect_str:
- protect_list.extend(protect_str.split(","))
- protect_def_str = ''
- count = 0
- for protect_define in protect_list:
- if count > 0:
- protect_def_str += ' &&'
- protect_def_str += ' defined(%s)' % protect_define
- count = count + 1
- count = count + 1
- protect_if_str = '#if'
- protect_if_str += protect_def_str
- protect_if_str += '\n'
- protect_end_str = '#endif //'
- protect_end_str += protect_def_str
- protect_end_str += '\n'
- else:
- protect_if_str += '#ifdef %s\n' % protect_str
- protect_end_str += '#endif // %s\n' % protect_str
+ if not protect_str:
+ return (protect_if_str, protect_end_str)
+
+ if ',' in protect_str:
+ protect_list = protect_str.split(",")
+ protect_defs = ('defined(%s)' % d for d in protect_list)
+ protect_def_str = ' && '.join(protect_defs)
+ protect_if_str = '#if %s\n' % protect_def_str
+ protect_end_str = '#endif // %s\n' % protect_def_str
+ else:
+ protect_if_str = '#ifdef %s\n' % protect_str
+ protect_end_str = '#endif // %s\n' % protect_str
+
return (protect_if_str, protect_end_str)
def typeMayAlias(self, typeName):
@@ -326,11 +309,10 @@ class COutputGenerator(OutputGenerator):
if data.elem.get('mayalias') == 'true')
# Every type mentioned in some other type's parentstruct attribute.
- self.may_alias.update(set(x for x in
- [otherType.elem.get('parentstruct')
- for _, otherType in self.registry.typedict.items()]
- if x is not None
- ))
+ parent_structs = (otherType.elem.get('parentstruct')
+ for otherType in self.registry.typedict.values())
+ self.may_alias.update(set(x for x in parent_structs
+ if x is not None))
return typeName in self.may_alias
# Struct (e.g. C "struct" type) generation.
@@ -364,9 +346,7 @@ class COutputGenerator(OutputGenerator):
body += ' ' + typeName + ' {\n'
- targetLen = 0
- for member in typeElem.findall('.//member'):
- targetLen = max(targetLen, self.getCParamTypeLength(member))
+ targetLen = self.getMaxCParamTypeLength(typeinfo)
for member in typeElem.findall('.//member'):
body += self.makeCParamDecl(member, targetLen + 4)
body += ';\n'
diff --git a/registry/conventions.py b/registry/conventions.py
index b37a494..8991b17 100644
--- a/registry/conventions.py
+++ b/registry/conventions.py
@@ -17,35 +17,96 @@
# Base class for working-group-specific style conventions,
# used in generation.
-from abc import ABCMeta, abstractmethod
+from enum import Enum
-ABC = ABCMeta('ABC', (object,), {})
+# Type categories that respond "False" to isStructAlwaysValid
+# basetype is home to typedefs like ..Bool32
+CATEGORIES_REQUIRING_VALIDATION = set(('handle',
+ 'enum',
+ 'bitmask',
+ 'basetype',
+ None))
-class ConventionsBase(ABC):
+# These are basic C types pulled in via openxr_platform_defines.h
+TYPES_KNOWN_ALWAYS_VALID = set(('char',
+ 'float',
+ 'int8_t', 'uint8_t',
+ 'int32_t', 'uint32_t',
+ 'int64_t', 'uint64_t',
+ 'size_t',
+ 'uintptr_t',
+ 'int',
+ ))
+
+
+class ProseListFormats(Enum):
+ """A connective, possibly with a quantifier."""
+ AND = 0
+ EACH_AND = 1
+ OR = 2
+ ANY_OR = 3
+
+ @classmethod
+ def from_string(cls, s):
+ if s == 'or':
+ return cls.OR
+ if s == 'and':
+ return cls.AND
+ return None
+
+ @property
+ def connective(self):
+ if self in (ProseListFormats.OR, ProseListFormats.ANY_OR):
+ return 'or'
+ return 'and'
+
+ def quantifier(self, n):
+ """Return the desired quantifier for a list of a given length."""
+ if self == ProseListFormats.ANY_OR:
+ if n > 1:
+ return 'any of '
+ elif self == ProseListFormats.EACH_AND:
+ if n > 2:
+ return 'each of '
+ if n == 2:
+ return 'both of '
+ return ''
+
+
+class ConventionsBase:
"""WG-specific conventions."""
- @abstractmethod
+ def __init__(self):
+ self._command_prefix = None
+ self._type_prefix = None
+
def formatExtension(self, name):
- """Mark up a name as an extension for the spec."""
+ """Mark up a name as an extension for the spec.
+
+ Must implement."""
raise NotImplementedError
@property
- @abstractmethod
def null(self):
"""Preferred spelling of NULL."""
raise NotImplementedError
- def makeProseList(self, elements, connective='and'):
+ def makeProseList(self, elements, fmt=ProseListFormats.AND, with_verb=False, *args, **kwargs):
"""Make a (comma-separated) list for use in prose.
Adds a connective (by default, 'and')
before the last element if there are more than 1.
+ Adds the right one of "is" or "are" to the end if with_verb is true.
+
+ Optionally adds a quantifier (like 'any') before a list of 2 or more,
+ if specified by fmt.
+
Override with a different method or different call to
_implMakeProseList if you want to add a comma for two elements,
or not use a serial comma.
"""
- return self._implMakeProseList(elements, connective)
+ return self._implMakeProseList(elements, fmt, with_verb, *args, **kwargs)
@property
def struct_macro(self):
@@ -55,20 +116,20 @@ class ConventionsBase(ABC):
"""
return 'sname:'
- def makeStructName(self, name):
- """Prepend the appropriate format macro for a structure to a structure type name.
-
- Uses struct_macro, so just override that if you want to change behavior.
- """
- return self.struct_macro + name
-
@property
def external_macro(self):
"""Get the appropriate format macro for an external type like uint32_t.
May override.
"""
- return 'basetype:'
+ return 'code:'
+
+ def makeStructName(self, name):
+ """Prepend the appropriate format macro for a structure to a structure type name.
+
+ Uses struct_macro, so just override that if you want to change behavior.
+ """
+ return self.struct_macro + name
def makeExternalTypeName(self, name):
"""Prepend the appropriate format macro for an external type like uint32_t to a type name.
@@ -77,7 +138,7 @@ class ConventionsBase(ABC):
"""
return self.external_macro + name
- def _implMakeProseList(self, elements, connective, comma_for_two_elts=False, serial_comma=True):
+ def _implMakeProseList(self, elements, fmt, with_verb, comma_for_two_elts=False, serial_comma=True):
"""Internal-use implementation to make a (comma-separated) list for use in prose.
Adds a connective (by default, 'and')
@@ -85,48 +146,171 @@ class ConventionsBase(ABC):
and only includes commas if there are more than 2
(if comma_for_two_elts is False).
+ Adds the right one of "is" or "are" to the end if with_verb is true.
+
+ Optionally adds a quantifier (like 'any') before a list of 2 or more,
+ if specified by fmt.
+
Don't edit these defaults, override self.makeProseList().
"""
assert(serial_comma) # didn't implement what we didn't need
+ if isinstance(fmt, str):
+ fmt = ProseListFormats.from_string(fmt)
+
my_elts = list(elements)
if len(my_elts) > 1:
- my_elts[-1] = '{} {}'.format(connective, my_elts[-1])
+ my_elts[-1] = '{} {}'.format(fmt.connective, my_elts[-1])
if not comma_for_two_elts and len(my_elts) <= 2:
- return ' '.join(my_elts)
- return ', '.join(my_elts)
+ prose = ' '.join(my_elts)
+ else:
+ prose = ', '.join(my_elts)
+
+ quantifier = fmt.quantifier(len(my_elts))
+
+ parts = [quantifier, prose]
+
+ if with_verb:
+ if len(my_elts) > 1:
+ parts.append(' are')
+ else:
+ parts.append(' is')
+ return ''.join(parts)
@property
- @abstractmethod
def file_suffix(self):
"""Return suffix of generated Asciidoctor files"""
raise NotImplementedError
- @abstractmethod
- def api_name(self, spectype = None):
- """Return API name"""
+ def api_name(self, spectype=None):
+ """Return API or specification name for citations in ref pages.
+
+ spectype is the spec this refpage is for.
+ 'api' (the default value) is the main API Specification.
+ If an unrecognized spectype is given, returns None.
+
+ Must implement."""
raise NotImplementedError
+ def should_insert_may_alias_macro(self, genOpts):
+ """Return true if we should insert a "may alias" macro in this file.
+
+ Only used by OpenXR right now."""
+ return False
+
+ @property
+ def command_prefix(self):
+ """Return the expected prefix of commands/functions.
+
+ Implemented in terms of api_prefix."""
+ if not self._command_prefix:
+ self._command_prefix = self.api_prefix[:].replace('_', '').lower()
+ return self._command_prefix
+
+ @property
+ def type_prefix(self):
+ """Return the expected prefix of type names.
+
+ Implemented in terms of command_prefix (and in turn, api_prefix)."""
+ if not self._type_prefix:
+ self._type_prefix = ''.join(
+ (self.command_prefix[0:1].upper(), self.command_prefix[1:]))
+ return self._type_prefix
+
@property
- @abstractmethod
def api_prefix(self):
- """Return API token prefix"""
+ """Return API token prefix.
+
+ Typically two uppercase letters followed by an underscore.
+
+ Must implement."""
raise NotImplementedError
@property
- @abstractmethod
def api_version_prefix(self):
- """Return API core version token prefix"""
- raise NotImplementedError
+ """Return API core version token prefix.
+
+ Implemented in terms of api_prefix.
+
+ May override."""
+ return self.api_prefix + 'VERSION_'
@property
- @abstractmethod
def KHR_prefix(self):
- """Return extension name prefix for KHR extensions"""
- raise NotImplementedError
+ """Return extension name prefix for KHR extensions.
+
+ Implemented in terms of api_prefix.
+
+ May override."""
+ return self.api_prefix + 'KHR_'
@property
- @abstractmethod
def EXT_prefix(self):
- """Return extension name prefix for EXT extensions"""
- raise NotImplementedError
+ """Return extension name prefix for EXT extensions.
+
+ Implemented in terms of api_prefix.
+
+ May override."""
+ return self.api_prefix + 'EXT_'
+
+ def writeFeature(self, featureExtraProtect, filename):
+ """Return True if OutputGenerator.endFeature should write this feature.
+
+ Defaults to always True.
+ Used in COutputGenerator.
+
+ May override."""
+ return True
+
+ def requires_error_validation(self, return_type):
+ """Return True if the return_type element is an API result code
+ requiring error validation.
+
+ Defaults to always False.
+
+ May override."""
+ return False
+
+ @property
+ def required_errors(self):
+ """Return a list of required error codes for validation.
+
+ Defaults to an empty list.
+
+ May override."""
+ return []
+
+ def is_voidpointer_alias(self, tag, text, tail):
+ """Return True if the declaration components (tag,text,tail) of an
+ element represents a void * type.
+
+ Defaults to a reasonable implementation.
+
+ May override."""
+ return tag == 'type' and text == 'void' and tail.startswith('*')
+
+ def make_voidpointer_alias(self, tail):
+ """Reformat a void * declaration to include the API alias macro.
+
+ Defaults to a no-op.
+
+ Must override if you actually want to use this feature in your project."""
+ return tail
+
+ def category_requires_validation(self, category):
+ """Return True if the given type 'category' always requires validation.
+
+ Defaults to a reasonable implementation.
+
+ May override."""
+ return category in CATEGORIES_REQUIRING_VALIDATION
+
+ def type_always_valid(self, typename):
+ """Return True if the given type name is always valid (never requires validation).
+
+ This is for things like integers.
+
+ Defaults to a reasonable implementation.
+
+ May override."""
+ return typename in TYPES_KNOWN_ALWAYS_VALID
diff --git a/registry/generator.py b/registry/generator.py
index f62b71f..8573655 100644
--- a/registry/generator.py
+++ b/registry/generator.py
@@ -18,17 +18,20 @@ from __future__ import unicode_literals
import io
import os
-import re
import pdb
+import re
import sys
try:
from pathlib import Path
except ImportError:
from pathlib2 import Path
-def write( *args, **kwargs ):
- file = kwargs.pop('file',sys.stdout)
- end = kwargs.pop('end','\n')
+from spec_tools.util import getElemName, getElemType
+
+
+def write(*args, **kwargs):
+ file = kwargs.pop('file', sys.stdout)
+ end = kwargs.pop('end', '\n')
file.write(' '.join(str(arg) for arg in args))
file.write(end)
@@ -83,9 +86,10 @@ def regSortExtensionNumberKey(feature):
# then by version number (for features)
# then by extension number (for extensions)
def regSortFeatures(featureList):
- featureList.sort(key = regSortExtensionNumberKey)
- featureList.sort(key = regSortFeatureVersionKey)
- featureList.sort(key = regSortCategoryKey)
+ featureList.sort(key=regSortExtensionNumberKey)
+ featureList.sort(key=regSortFeatureVersionKey)
+ featureList.sort(key=regSortCategoryKey)
+
# GeneratorOptions - base class for options used during header production
# These options are target language independent, and used by
@@ -125,18 +129,18 @@ class GeneratorOptions:
"""Represents options during header production from an API registry"""
def __init__(self,
- conventions = None,
- filename = None,
- directory = '.',
- apiname = None,
- profile = None,
- versions = '.*',
- emitversions = '.*',
- defaultExtensions = None,
- addExtensions = None,
- removeExtensions = None,
- emitExtensions = None,
- sortProcedure = regSortFeatures):
+ conventions=None,
+ filename=None,
+ directory='.',
+ apiname=None,
+ profile=None,
+ versions='.*',
+ emitversions='.*',
+ defaultExtensions=None,
+ addExtensions=None,
+ removeExtensions=None,
+ emitExtensions=None,
+ sortProcedure=regSortFeatures):
self.conventions = conventions
self.filename = filename
self.directory = directory
@@ -205,19 +209,19 @@ class OutputGenerator:
# categoryToPath - map XML 'category' to include file directory name
categoryToPath = {
- 'bitmask' : 'flags',
- 'enum' : 'enums',
- 'funcpointer' : 'funcpointers',
- 'handle' : 'handles',
- 'define' : 'defines',
- 'basetype' : 'basetypes',
+ 'bitmask': 'flags',
+ 'enum': 'enums',
+ 'funcpointer': 'funcpointers',
+ 'handle': 'handles',
+ 'define': 'defines',
+ 'basetype': 'basetypes',
}
# Constructor
def __init__(self,
- errFile = sys.stderr,
- warnFile = sys.stderr,
- diagFile = sys.stdout):
+ errFile=sys.stderr,
+ warnFile=sys.stderr,
+ diagFile=sys.stdout):
self.outFile = None
self.errFile = errFile
self.warnFile = warnFile
@@ -227,7 +231,7 @@ class OutputGenerator:
self.genOpts = None
self.registry = None
# Used for extension enum value generation
- self.extBase = 1000000000
+ self.extBase = 1000000000
self.extBlockSize = 1000
self.madeDirs = {}
@@ -295,21 +299,21 @@ class OutputGenerator:
bitpos = int(value, 0)
numVal = 1 << bitpos
value = '0x%08x' % numVal
- if( bitpos >= 32 ):
+ if bitpos >= 32:
value = value + 'ULL'
self.logMsg('diag', 'Enum', name, '-> bitpos [', numVal, ',', value, ']')
return [numVal, value]
if 'offset' in elem.keys():
# Obtain values in the mapping from the attributes
enumNegative = False
- offset = int(elem.get('offset'),0)
- extnumber = int(elem.get('extnumber'),0)
+ offset = int(elem.get('offset'), 0)
+ extnumber = int(elem.get('extnumber'), 0)
extends = elem.get('extends')
if 'dir' in elem.keys():
enumNegative = True
self.logMsg('diag', 'Enum', name, 'offset =', offset,
- 'extnumber =', extnumber, 'extends =', extends,
- 'enumNegative =', enumNegative)
+ 'extnumber =', extnumber, 'extends =', extends,
+ 'enumNegative =', enumNegative)
# Now determine the actual enumerant value, as defined
# in the "Layers and Extensions" appendix of the spec.
numVal = self.extBase + (extnumber - 1) * self.extBlockSize + offset
@@ -346,7 +350,7 @@ class OutputGenerator:
# happens when defining the same enum conditionally in
# several extension blocks.
if (strVal2 == strVal or (numVal is not None and
- numVal == numVal2)):
+ numVal == numVal2)):
True
# self.logMsg('info', 'checkDuplicateEnums: Duplicate enum (' + name +
# ') found with the same value:' + strVal)
@@ -364,14 +368,14 @@ class OutputGenerator:
try:
self.logMsg('warn', 'Two enums found with the same value: '
- + name + ' = ' + name2.get('name') + ' = ' + strVal)
+ + name + ' = ' + name2.get('name') + ' = ' + strVal)
except:
pdb.set_trace()
# Track this enum to detect followon duplicates
- nameMap[name] = [ elem, numVal, strVal ]
+ nameMap[name] = [elem, numVal, strVal]
if numVal is not None:
- valueMap[numVal] = [ elem, numVal, strVal ]
+ valueMap[numVal] = [elem, numVal, strVal]
# Add this enum to the list
stripped.append(elem)
@@ -385,7 +389,7 @@ class OutputGenerator:
groupElem = groupinfo.elem
if self.genOpts.conventions.constFlagBits and groupElem.get('type') == 'bitmask':
- return self.buildEnumCDecl_Bitmask( groupinfo, groupName)
+ return self.buildEnumCDecl_Bitmask(groupinfo, groupName)
else:
return self.buildEnumCDecl_Enum(expand, groupinfo, groupName)
@@ -406,7 +410,7 @@ class OutputGenerator:
# Should catch exceptions here for more complex constructs. Not yet.
(_, strVal) = self.enumToValue(elem, True)
name = elem.get('name')
- body += "static const " + flagTypeName + " " + name + " = " + strVal + ";\n"
+ body += "static const {} {} = {};\n".format(flagTypeName, name, strVal)
# Postfix
@@ -418,17 +422,17 @@ class OutputGenerator:
# Break the group name into prefix and suffix portions for range
# enum generation
- expandName = re.sub(r'([0-9a-z_])([A-Z0-9])',r'\1_\2',groupName).upper()
+ expandName = re.sub(r'([0-9a-z_])([A-Z0-9])', r'\1_\2', groupName).upper()
expandPrefix = expandName
expandSuffix = ''
- expandSuffixMatch = re.search(r'[A-Z][A-Z]+$',groupName)
+ expandSuffixMatch = re.search(r'[A-Z][A-Z]+$', groupName)
if expandSuffixMatch:
expandSuffix = '_' + expandSuffixMatch.group()
# Strip off the suffix from the prefix
expandPrefix = expandName.rsplit(expandSuffix, 1)[0]
# Prefix
- body = "typedef enum " + groupName + " {\n"
+ body = ["typedef enum %s {" % groupName]
# @@ Should use the type="bitmask" attribute instead
isEnum = ('FLAG_BITS' not in expandPrefix)
@@ -450,22 +454,22 @@ class OutputGenerator:
# them following the numeric values, to allow for aliases.
# NOTE: this doesn't do a topological sort yet, so aliases of
# aliases can still get in the wrong order.
- aliasText = ""
+ aliasText = []
for elem in enums:
# Convert the value to an integer and use that to track min/max.
# Values of form -(number) are accepted but nothing more complex.
# Should catch exceptions here for more complex constructs. Not yet.
- (numVal,strVal) = self.enumToValue(elem, True)
+ (numVal, strVal) = self.enumToValue(elem, True)
name = elem.get('name')
# Extension enumerants are only included if they are required
if self.isEnumRequired(elem):
- decl = " " + name + " = " + strVal + ",\n"
+ decl = " {} = {},".format(name, strVal)
if numVal is not None:
- body += decl
+ body.append(decl)
else:
- aliasText += decl
+ aliasText.append(decl)
# Don't track min/max for non-numbers (numVal is None)
if isEnum and numVal is not None and elem.get('extends') is None:
@@ -480,20 +484,21 @@ class OutputGenerator:
maxValue = numVal
# Now append the non-numeric enumerant values
- body += aliasText
+ body.extend(aliasText)
# Generate min/max value tokens and a range-padding enum. Need some
# additional padding to generate correct names...
if isEnum and expand:
- body += " " + expandPrefix + "_BEGIN_RANGE" + expandSuffix + " = " + minName + ",\n"
- body += " " + expandPrefix + "_END_RANGE" + expandSuffix + " = " + maxName + ",\n"
- body += " " + expandPrefix + "_RANGE_SIZE" + expandSuffix + " = (" + maxName + " - " + minName + " + 1),\n"
+ body.extend((" {}_BEGIN_RANGE{} = {},".format(expandPrefix, expandSuffix, minName),
+ " {}_END_RANGE{} = {},".format(
+ expandPrefix, expandSuffix, maxName),
+ " {}_RANGE_SIZE{} = ({} - {} + 1),".format(expandPrefix, expandSuffix, maxName, minName)))
- # Always generate this to make sure the enumerated type is 32 bits
- body += " " + expandPrefix + "_MAX_ENUM" + expandSuffix + " = 0x7FFFFFFF\n"
+ body.append(" {}_MAX_ENUM{} = 0x7FFFFFFF".format(
+ expandPrefix, expandSuffix))
# Postfix
- body += "} " + groupName + ";"
+ body.append("} %s;" % groupName)
# Determine appropriate section for this declaration
if groupElem.get('type') == 'bitmask':
@@ -501,7 +506,7 @@ class OutputGenerator:
else:
section = 'group'
- return (section, body)
+ return (section, '\n'.join(body))
def makeDir(self, path):
self.logMsg('diag', 'OutputGenerator::makeDir(' + path + ')')
@@ -514,6 +519,10 @@ class OutputGenerator:
def beginFile(self, genOpts):
self.genOpts = genOpts
+ self.should_insert_may_alias_macro = \
+ self.genOpts.conventions.should_insert_may_alias_macro(self.genOpts)
+
+ self.conventions = genOpts.conventions
# Open specified output file. Not done in constructor since a
# Generator can be used without writing to a file.
@@ -603,13 +612,14 @@ class OutputGenerator:
# aligncol - if non-zero, attempt to align the nested <name> element
# at this column
def makeCParamDecl(self, param, aligncol):
- paramdecl = ' ' + noneStr(param.text)
+ indent = ' '
+ paramdecl = indent + noneStr(param.text)
for elem in param:
text = noneStr(elem.text)
tail = noneStr(elem.tail)
- if self.genOpts.conventions.is_voidpointer_alias(elem.tag, text, tail):
- # OpenXR-specific macro insertion
+ if self.should_insert_may_alias_macro and self.genOpts.conventions.is_voidpointer_alias(elem.tag, text, tail):
+ # OpenXR-specific macro insertion - but not in apiinc for the spec
tail = self.genOpts.conventions.make_voidpointer_alias(tail)
if elem.tag == 'name' and aligncol > 0:
self.logMsg('diag', 'Aligning parameter', elem.text, 'to column', self.genOpts.alignFuncParam)
@@ -619,17 +629,22 @@ class OutputGenerator:
# This works around a problem where very long type names -
# longer than the alignment column - would run into the tail
# text.
- paramdecl = paramdecl.ljust(aligncol-1) + ' '
+ paramdecl = paramdecl.ljust(aligncol - 1) + ' '
newLen = len(paramdecl)
self.logMsg('diag', 'Adjust length of parameter decl from', oldLen, 'to', newLen, ':', paramdecl)
paramdecl += text + tail
+ if aligncol == 0:
+ # Squeeze out multiple spaces other than the identation
+ paramdecl = indent + ' '.join(paramdecl.split())
return paramdecl
- # getCParamTypeLength - return the length of the type field is an indented, formatted
- # declaration for a <param> or <member> block (e.g. function parameter
- # or structure/union member).
+ # getCParamTypeLength - return the length of the type field in an
+ # indented, formatted declaration for a <param> or <member> block (e.g.
+ # function parameter or structure/union member). This relies on the
+ # presence of the <name> tag; if not present, return zero.
# param - Element (<param> or <member>) to identify
def getCParamTypeLength(self, param):
+ newLen = 0
paramdecl = ' ' + noneStr(param.text)
for elem in param:
text = noneStr(elem.text)
@@ -646,17 +661,106 @@ class OutputGenerator:
return newLen
+ def getMaxCParamTypeLength(self, info):
+ """Return the length of the longest type field for a member/parameter.
+
+ info - TypeInfo or CommandInfo.
+ """
+ lengths = (self.getCParamTypeLength(member)
+ for member in info.getMembers())
+ return max(lengths)
+
+ def getHandleParent(self, typename):
+ """Get the parent of a handle object."""
+ info = self.registry.typedict.get(typename)
+ if info is None:
+ return None
+
+ elem = info.elem
+ if elem is not None:
+ return elem.get('parent')
+
+ return None
+
+ def iterateHandleAncestors(self, typename):
+ """Iterate through the ancestors of a handle type."""
+ current = self.getHandleParent(typename)
+ while current is not None:
+ yield current
+ current = self.getHandleParent(current)
+
+ def getHandleAncestors(self, typename):
+ """Get the ancestors of a handle object."""
+ return list(self.iterateHandleAncestors(typename))
+
+ def getTypeCategory(self, typename):
+ """Get the category of a type."""
+ info = self.registry.typedict.get(typename)
+ if info is None:
+ return None
+
+ elem = info.elem
+ if elem is not None:
+ return elem.get('category')
+ return None
+
+ def isStructAlwaysValid(self, structname):
+ """Try to do check if a structure is always considered valid (i.e. there's no rules to its acceptance)."""
+ # A conventions object is required for this call.
+ if not self.conventions:
+ raise RuntimeError("To use isStructAlwaysValid, be sure your options include a Conventions object.")
+
+ if self.conventions.type_always_valid(structname):
+ return True
+
+ category = self.getTypeCategory(structname)
+ if self.conventions.category_requires_validation(category):
+ return False
+
+ info = self.registry.typedict.get(structname)
+ assert(info is not None)
+
+ members = info.getMembers()
+
+ for member in members:
+ member_name = getElemName(member)
+ if member_name in (self.conventions.structtype_member_name,
+ self.conventions.nextpointer_member_name):
+ return False
+
+ if member.get('noautovalidity'):
+ return False
+
+ member_type = getElemType(member)
+
+ if member_type in ('void', 'char') or self.paramIsArray(member) or self.paramIsPointer(member):
+ return False
+
+ if self.conventions.type_always_valid(member_type):
+ continue
+
+ member_category = self.getTypeCategory(member_type)
+
+ if self.conventions.category_requires_validation(member_category):
+ return False
+
+ if member_category in ('struct', 'union'):
+ if self.isStructAlwaysValid(member_type) is False:
+ return False
+
+ return True
+
# isEnumRequired(elem) - return True if this <enum> element is
# required, False otherwise
# elem - <enum> element to test
def isEnumRequired(self, elem):
required = elem.get('required') is not None
self.logMsg('diag', 'isEnumRequired:', elem.get('name'),
- '->', required)
+ '->', required)
return required
- #@@@ This code is overridden by equivalent code now run in
- #@@@ Registry.generateFeature
+ # @@@ This code is overridden by equivalent code now run in
+ # @@@ Registry.generateFeature
required = False
@@ -707,6 +811,12 @@ class OutputGenerator:
else:
pdecl += text + tail
tdecl += text + tail
+
+ if self.genOpts.alignFuncParam == 0:
+ # Squeeze out multiple spaces - there is no indentation
+ pdecl = ' '.join(pdecl.split())
+ tdecl = ' '.join(tdecl.split())
+
# Now add the parameter declaration list, which is identical
# for prototypes and typedefs. Concatenate all the text from
# a <param> node without the tags. No tree walking required
@@ -732,7 +842,7 @@ class OutputGenerator:
else:
paramdecl += 'void'
paramdecl += ");"
- return [ pdecl + indentdecl, tdecl + paramdecl ]
+ return [pdecl + indentdecl, tdecl + paramdecl]
def newline(self):
write('', file=self.outFile)
diff --git a/registry/genvk.py b/registry/genvk.py
index 6355f86..84cad3c 100644
--- a/registry/genvk.py
+++ b/registry/genvk.py
@@ -48,12 +48,14 @@ def endTimer(timeit, msg):
write(msg, endTime - startTime, file=sys.stderr)
startTime = None
-# Turn a list of strings into a regexp string matching exactly those strings
-def makeREstring(list, default = None):
- if len(list) > 0 or default is None:
- return '^(' + '|'.join(list) + ')$'
- else:
- return default
+
+def makeREstring(strings, default=None, strings_are_regex=False):
+ """Turn a list of strings into a regexp string matching exactly those strings."""
+ if strings or default is None:
+ if not strings_are_regex:
+ strings = (re.escape(s) for s in strings)
+ return '^(' + '|'.join(strings) + ')$'
+ return default
# Returns a directory of [ generator function, generator options ] indexed
# by specified short names. The generator options incorporate the following
@@ -275,8 +277,10 @@ def makeGenOpts(args):
allPlatformExtensions += platform[1]
- addPlatformExtensionsRE = makeREstring(platform[1] + platform[2])
- emitPlatformExtensionsRE = makeREstring(platform[1])
+ addPlatformExtensionsRE = makeREstring(
+ platform[1] + platform[2], strings_are_regex=True)
+ emitPlatformExtensionsRE = makeREstring(
+ platform[1], strings_are_regex=True)
opts = CGeneratorOptions(
conventions = conventions,
@@ -312,7 +316,8 @@ def makeGenOpts(args):
# It removes all platform extensions (from the platform headers options
# constructed above) as well as any explicitly specified removals.
- removeExtensionsPat = makeREstring(allPlatformExtensions + removeExtensions, None)
+ removeExtensionsPat = makeREstring(
+ allPlatformExtensions + removeExtensions, None, strings_are_regex=True)
genOpts['vulkan_core.h'] = [
COutputGenerator,
@@ -533,7 +538,8 @@ if __name__ == '__main__':
if args.debug:
pdb.run('genTarget(args)')
elif args.profile:
- import cProfile, pstats
+ import cProfile
+ import pstats
cProfile.run('genTarget(args)', 'profile.txt')
p = pstats.Stats('profile.txt')
p.strip_dirs().sort_stats('time').print_stats(50)
diff --git a/registry/reg.py b/registry/reg.py
index 982c04c..fb30ed8 100644
--- a/registry/reg.py
+++ b/registry/reg.py
@@ -104,8 +104,8 @@ class BaseInfo:
# be different when redefining the same interface in different feature
# and/or extension blocks.
for key in selfKeys:
- if (key != 'extname' and key != 'extnumber' and
- (self.elem.get(key) != info.elem.get(key))):
+ if key not in ('extname', 'extnumber') and \
+ (self.elem.get(key) != info.elem.get(key)):
return False
return True
@@ -118,6 +118,10 @@ class TypeInfo(BaseInfo):
BaseInfo.__init__(self, elem)
self.additionalValidity = []
self.removedValidity = []
+
+ def getMembers(self):
+ return self.elem.findall('member')
+
def resetState(self):
BaseInfo.resetState(self)
self.additionalValidity = []
@@ -148,6 +152,10 @@ class CmdInfo(BaseInfo):
BaseInfo.__init__(self, elem)
self.additionalValidity = []
self.removedValidity = []
+
+ def getParams(self):
+ return self.elem.findall('param')
+
def resetState(self):
BaseInfo.resetState(self)
self.additionalValidity = []
@@ -251,6 +259,7 @@ class Registry:
self.emitFeatures = False
self.breakPat = None
# self.breakPat = re.compile('VkFenceImportFlagBits.*')
+ self.filename = None
def loadElementTree(self, tree):
"""Load ElementTree into a Registry object and parse it"""
@@ -259,6 +268,7 @@ class Registry:
def loadFile(self, file):
"""Load an API registry XML file into a Registry object and parse it"""
+ self.filename = file
self.tree = etree.parse(file)
self.parseTree()
@@ -450,7 +460,11 @@ class Registry:
gi.elem.append(enum)
# Remove element from parent <require> tag
# This should be a no-op in lxml.etree
- elem.remove(enum)
+ try:
+ elem.remove(enum)
+ except ValueError:
+ # Must be lxml.etree
+ pass
else:
self.gen.logMsg('warn', 'NO matching group',
groupName, 'for enum', enum.get('name'), 'found.')
@@ -500,7 +514,11 @@ class Registry:
gi.elem.append(enum)
# Remove element from parent <require> tag
# This should be a no-op in lxml.etree
- elem.remove(enum)
+ try:
+ elem.remove(enum)
+ except ValueError:
+ # Must be lxml.etree
+ pass
else:
self.gen.logMsg('warn', 'NO matching group',
groupName, 'for enum', enum.get('name'), 'found.')
diff --git a/registry/validusage.json b/registry/validusage.json
index 8a2ea3e..9240390 100644
--- a/registry/validusage.json
+++ b/registry/validusage.json
@@ -1,9 +1,9 @@
{
"version info": {
"schema version": 2,
- "api version": "1.1.119",
- "comment": "from git branch: github-master commit: 5a1c484b7e65eb7d83b160f8c92b0cfd77ddbd53",
- "date": "2019-08-12 06:32:53Z"
+ "api version": "1.1.120",
+ "comment": "from git branch: github-master commit: 521e98405f8587ce6506811125c001f1eda26314",
+ "date": "2019-08-17 22:33:44Z"
},
"validation": {
"vkGetInstanceProcAddr": {
@@ -717,6 +717,10 @@
{
"vuid": "VUID-vkAllocateCommandBuffers-pCommandBuffers-parameter",
"text": " <code>pCommandBuffers</code> <strong class=\"purple\">must</strong> be a valid pointer to an array of <code>pAllocateInfo</code>::commandBufferCount <code>VkCommandBuffer</code> handles"
+ },
+ {
+ "vuid": "VUID-vkAllocateCommandBuffers-pAllocateInfo::commandBufferCount-arraylength",
+ "text": " The value referenced by <code>pAllocateInfo</code>::<code>commandBufferCount</code> <strong class=\"purple\">must</strong> be greater than <code>0</code>"
}
]
},
@@ -863,6 +867,14 @@
"text": " If the <a href=\"#features-inheritedQueries\">inherited queries</a> feature is enabled, <code>queryFlags</code> <strong class=\"purple\">must</strong> be a valid combination of <a href=\"#VkQueryControlFlagBits\">VkQueryControlFlagBits</a> values"
},
{
+ "vuid": "VUID-VkCommandBufferInheritanceInfo-queryFlags-02788",
+ "text": " If the <a href=\"#features-inheritedQueries\">inherited queries</a> feature is not enabled, <code>queryFlags</code> <strong class=\"purple\">must</strong> be <code>0</code>"
+ },
+ {
+ "vuid": "VUID-VkCommandBufferInheritanceInfo-pipelineStatistics-02789",
+ "text": " If the <a href=\"#features-pipelineStatisticsQuery\">pipeline statistics queries</a> feature is enabled, <code>pipelineStatistics</code> <strong class=\"purple\">must</strong> be a valid combination of <a href=\"#VkQueryPipelineStatisticFlagBits\">VkQueryPipelineStatisticFlagBits</a> values"
+ },
+ {
"vuid": "VUID-VkCommandBufferInheritanceInfo-pipelineStatistics-00058",
"text": " If the <a href=\"#features-pipelineStatisticsQuery\">pipeline statistics queries</a> feature is not enabled, <code>pipelineStatistics</code> <strong class=\"purple\">must</strong> be <code>0</code>"
},
@@ -954,7 +966,7 @@
},
{
"vuid": "VUID-vkQueueSubmit-pWaitSemaphores-00068",
- "text": " When a semaphore unsignal operation defined by any element of the <code>pWaitSemaphores</code> member of any element of <code>pSubmits</code> executes on <code>queue</code>, no other queue <strong class=\"purple\">must</strong> be waiting on the same semaphore."
+ "text": " When a semaphore unsignal operation defined by any element of the <code>pWaitSemaphores</code> member of any element of <code>pSubmits</code> executes on <code>queue</code>, there <strong class=\"purple\">must</strong> be no other queues waiting on the same semaphore."
},
{
"vuid": "VUID-vkQueueSubmit-pWaitSemaphores-00069",
@@ -6216,7 +6228,7 @@
"(VK_KHR_pipeline_executable_properties)": [
{
"vuid": "VUID-VkPipelineExecutableInfoKHR-executableIndex-03275",
- "text": " <code>executableIndex</code> <strong class=\"purple\">must</strong> be less than or equal to the number of executables associated with <code>pipeline</code> as returned in the <code>pExecutableCount</code> parameter of <code>vkGetPipelineExecutablePropertiesKHR</code>."
+ "text": " <code>executableIndex</code> <strong class=\"purple\">must</strong> be less than the number of executables associated with <code>pipeline</code> as returned in the <code>pExecutableCount</code> parameter of <code>vkGetPipelineExecutablePropertiesKHR</code>."
},
{
"vuid": "VUID-VkPipelineExecutableInfoKHR-sType-sType",
@@ -6288,11 +6300,11 @@
},
{
"vuid": "VUID-VkPipelineExecutableInternalRepresentationKHR-name-parameter",
- "text": " Any given element of <code>name</code> <strong class=\"purple\">must</strong> be a valid"
+ "text": " <code>name</code> <strong class=\"purple\">must</strong> be a null-terminated UTF-8 string whose length is less than or equal to VK_MAX_DESCRIPTION_SIZE"
},
{
"vuid": "VUID-VkPipelineExecutableInternalRepresentationKHR-description-parameter",
- "text": " Any given element of <code>description</code> <strong class=\"purple\">must</strong> be a valid"
+ "text": " <code>description</code> <strong class=\"purple\">must</strong> be a null-terminated UTF-8 string whose length is less than or equal to VK_MAX_DESCRIPTION_SIZE"
},
{
"vuid": "VUID-VkPipelineExecutableInternalRepresentationKHR-pData-parameter",
@@ -6339,8 +6351,8 @@
"text": " <code>sType</code> <strong class=\"purple\">must</strong> be <code>VK_STRUCTURE_TYPE_PIPELINE_COMPILER_CONTROL_CREATE_INFO_AMD</code>"
},
{
- "vuid": "VUID-VkPipelineCompilerControlCreateInfoAMD-compilerControlFlags-parameter",
- "text": " <code>compilerControlFlags</code> <strong class=\"purple\">must</strong> be a valid combination of <a href=\"#VkPipelineCompilerControlFlagBitsAMD\">VkPipelineCompilerControlFlagBitsAMD</a> values"
+ "vuid": "VUID-VkPipelineCompilerControlCreateInfoAMD-compilerControlFlags-zerobitmask",
+ "text": " <code>compilerControlFlags</code> <strong class=\"purple\">must</strong> be <code>0</code>"
}
]
},
@@ -9256,7 +9268,7 @@
},
{
"vuid": "VUID-VkImageViewHandleInfoNVX-imageView-02656",
- "text": " If descriptorType is <code>VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE</code> or <code>VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER</code>, the image that <code>imageView</code> was created from <strong class=\"purple\">must</strong> have been created with the <code>VK_IMAGE_USAGE_SAMPLED_BIT</code> usage bit set"
+ "text": " If descriptorType is <code>VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE</code> or <code>VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER</code>, the image that <code>imageView</code> was created from <strong class=\"purple\">must</strong> have been created with the <code>VK_IMAGE_USAGE_SAMPLED_BIT</code> usage bit set"
},
{
"vuid": "VUID-VkImageViewHandleInfoNVX-imageView-02657",
@@ -11523,6 +11535,10 @@
{
"vuid": "VUID-vkAllocateDescriptorSets-pDescriptorSets-parameter",
"text": " <code>pDescriptorSets</code> <strong class=\"purple\">must</strong> be a valid pointer to an array of <code>pAllocateInfo</code>::descriptorSetCount <code>VkDescriptorSet</code> handles"
+ },
+ {
+ "vuid": "VUID-vkAllocateDescriptorSets-pAllocateInfo::descriptorSetCount-arraylength",
+ "text": " The value referenced by <code>pAllocateInfo</code>::<code>descriptorSetCount</code> <strong class=\"purple\">must</strong> be greater than <code>0</code>"
}
]
},
@@ -20578,7 +20594,7 @@
},
{
"vuid": "VUID-vkQueueBindSparse-pWaitSemaphores-01116",
- "text": " When a semaphore unsignal operation defined by any element of the <code>pWaitSemaphores</code> member of any element of <code>pBindInfo</code> executes on <code>queue</code>, no other queue <strong class=\"purple\">must</strong> be waiting on the same semaphore."
+ "text": " When a semaphore unsignal operation defined by any element of the <code>pWaitSemaphores</code> member of any element of <code>pBindInfo</code> executes on <code>queue</code>, there <strong class=\"purple\">must</strong> be no other queues waiting on the same semaphore."
},
{
"vuid": "VUID-vkQueueBindSparse-pWaitSemaphores-01117",
@@ -22670,7 +22686,7 @@
},
{
"vuid": "VUID-vkQueuePresentKHR-pWaitSemaphores-01294",
- "text": " When a semaphore unsignal operation defined by the elements of the <code>pWaitSemaphores</code> member of <code>pPresentInfo</code> executes on <code>queue</code>, no other queue <strong class=\"purple\">must</strong> be waiting on the same semaphore."
+ "text": " When a semaphore unsignal operation defined by the elements of the <code>pWaitSemaphores</code> member of <code>pPresentInfo</code> executes on <code>queue</code>, there <strong class=\"purple\">must</strong> be no other queues waiting on the same semaphore."
},
{
"vuid": "VUID-vkQueuePresentKHR-pWaitSemaphores-01295",
diff --git a/registry/vk.xml b/registry/vk.xml
index f76c0c8..bc1c63d 100644
--- a/registry/vk.xml
+++ b/registry/vk.xml
@@ -154,7 +154,7 @@ server.
<type category="define">// Vulkan 1.1 version number
#define <name>VK_API_VERSION_1_1</name> <type>VK_MAKE_VERSION</type>(1, 1, 0)// Patch version should always be set to 0</type>
<type category="define">// Version of this file
-#define <name>VK_HEADER_VERSION</name> 119</type>
+#define <name>VK_HEADER_VERSION</name> 120</type>
<type category="define">
#define <name>VK_DEFINE_HANDLE</name>(object) typedef struct object##_T* object;</type>
@@ -5040,12 +5040,11 @@ typedef void <name>CAMetalLayer</name>;
<enums name="VkValidationCheckEXT" type="enum">
<enum value="0" name="VK_VALIDATION_CHECK_ALL_EXT"/>
<enum value="1" name="VK_VALIDATION_CHECK_SHADERS_EXT"/>
- <comment>Placeholder for validation enums to be defined for VK_EXT_Validation_flags extension</comment>
</enums>
<enums name="VkValidationFeatureEnableEXT" type="enum">
<enum value="0" name="VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT"/>
<enum value="1" name="VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT"/>
- <comment>Placeholder for validation feature enable enums to be defined for VK_EXT_validation_features extension</comment>
+ <enum value="2" name="VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT"/>
</enums>
<enums name="VkValidationFeatureDisableEXT" type="enum">
<enum value="0" name="VK_VALIDATION_FEATURE_DISABLE_ALL_EXT"/>
@@ -5055,7 +5054,6 @@ typedef void <name>CAMetalLayer</name>;
<enum value="4" name="VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT"/>
<enum value="5" name="VK_VALIDATION_FEATURE_DISABLE_CORE_CHECKS_EXT"/>
<enum value="6" name="VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT"/>
- <comment>Placeholder for validation feature disable enums to be defined for VK_EXT_validation_features extension</comment>
</enums>
<enums name="VkSubgroupFeatureFlagBits" type="bitmask">
<enum bitpos="0" name="VK_SUBGROUP_FEATURE_BASIC_BIT" comment="Basic subgroup operations"/>
@@ -10412,6 +10410,7 @@ typedef void <name>CAMetalLayer</name>;
<enum offset="0" extends="VkObjectType" name="VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV"/>
<enum offset="0" extends="VkDebugReportObjectTypeEXT" name="VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT"/>
<enum offset="0" extends="VkIndexType" name="VK_INDEX_TYPE_NONE_NV"/>
+ <type name="VkAccelerationStructureTypeNV"/>
<type name="VkRayTracingShaderGroupCreateInfoNV"/>
<type name="VkRayTracingShaderGroupTypeNV"/>
<type name="VkRayTracingPipelineCreateInfoNV"/>
@@ -11156,7 +11155,7 @@ typedef void <name>CAMetalLayer</name>;
</extension>
<extension name="VK_EXT_validation_features" number="248" type="instance" author="LUNARG" contact="Karl Schultz @karl-lunarg" supported="vulkan">
<require>
- <enum value="1" name="VK_EXT_VALIDATION_FEATURES_SPEC_VERSION"/>
+ <enum value="2" name="VK_EXT_VALIDATION_FEATURES_SPEC_VERSION"/>
<enum value="&quot;VK_EXT_validation_features&quot;" name="VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME"/>
<enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT"/>
<type name="VkValidationFeaturesEXT"/>
diff --git a/registry/vkconventions.py b/registry/vkconventions.py
index 37235c1..7230fa2 100644
--- a/registry/vkconventions.py
+++ b/registry/vkconventions.py
@@ -22,6 +22,10 @@ import re
from conventions import ConventionsBase
+# Modified from default implementation - see category_requires_validation() below
+CATEGORIES_REQUIRING_VALIDATION = set(('handle', 'enum', 'bitmask'))
+
+
class VulkanConventions(ConventionsBase):
def formatExtension(self, name):
"""Mark up a name as an extension for the spec."""
@@ -38,14 +42,6 @@ class VulkanConventions(ConventionsBase):
return False
@property
- def struct_macro(self):
- return 'sname:'
-
- @property
- def external_macro(self):
- return 'code:'
-
- @property
def structtype_member_name(self):
"""Return name of the structure type member"""
return 'sType'
@@ -89,7 +85,7 @@ class VulkanConventions(ConventionsBase):
"""Return suffix of generated Asciidoctor files"""
return '.txt'
- def api_name(self, spectype = 'api'):
+ def api_name(self, spectype='api'):
"""Return API or specification name for citations in ref pages.ref
pages should link to for
@@ -113,21 +109,6 @@ class VulkanConventions(ConventionsBase):
return 'VK_'
@property
- def api_version_prefix(self):
- """Return API core version token prefix"""
- return 'VK_VERSION_'
-
- @property
- def KHR_prefix(self):
- """Return extension name prefix for KHR extensions"""
- return 'VK_KHR_'
-
- @property
- def EXT_prefix(self):
- """Return extension name prefix for EXT extensions"""
- return 'VK_EXT_'
-
- @property
def write_contacts(self):
"""Return whether contact list should be written to extension appendices"""
return True
@@ -137,22 +118,10 @@ class VulkanConventions(ConventionsBase):
"""Return whether refpage include should be written to extension appendices"""
return True
- def writeFeature(self, featureExtraProtect, filename):
- """Returns True if OutputGenerator.endFeature should write this feature.
- Used in COutputGenerator
- """
- return True
-
- def requires_error_validation(self, return_type):
- """Returns True if the return_type element is an API result code
- requiring error validation.
- """
- return False
-
@property
- def required_errors(self):
- """Return a list of required error codes for validation."""
- return []
+ def member_used_for_unique_vuid(self):
+ """Return the member name used in the VUID-...-...-unique ID."""
+ return self.structtype_member_name
def is_externsync_command(self, protoname):
"""Returns True if the protoname element is an API command requiring
@@ -167,19 +136,7 @@ class VulkanConventions(ConventionsBase):
"""
return name[0:2].lower() == 'vk' or name[0:6] == 'PFN_vk'
- def is_voidpointer_alias(self, tag, text, tail):
- """Return True if the declaration components (tag,text,tail) of an
- element represents a void * type
- """
- return tag == 'type' and text == 'void' and tail.startswith('*')
-
- def make_voidpointer_alias(self, tail):
- """Reformat a void * declaration to include the API alias macro.
- Vulkan doesn't have an API alias macro, so do nothing.
- """
- return tail
-
- def specURL(self, spectype = 'api'):
+ def specURL(self, spectype='api'):
"""Return public registry URL which ref pages should link to for the
current all-extensions HTML specification, so xrefs in the
asciidoc source that aren't to ref pages can link into it
@@ -232,3 +189,12 @@ class VulkanConventions(ConventionsBase):
"""
return ('scripts', 'style')
+ @property
+ def zero(self):
+ return '`0`'
+
+ def category_requires_validation(self, category):
+ """Return True if the given type 'category' always requires validation.
+
+ Overridden because Vulkan doesn't require "valid" text for basetype in the spec right now."""
+ return category in CATEGORIES_REQUIRING_VALIDATION