Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: API parameterization #134

Merged
merged 2 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ set(CMAKE_CXX_VISIBILITY_PRESET "hidden")
set(CMAKE_C_VISIBILITY_PRESET "hidden")
set(CMAKE_VISIBILITY_INLINES_HIDDEN "YES")

# This variable enables downstream users to customize the target API
# variant (e.g. Vulkan SC)
set(API_TYPE "vulkan")

add_subdirectory(scripts)

find_package(VulkanHeaders CONFIG QUIET)
Expand All @@ -35,7 +39,7 @@ if (VUL_IS_TOP_LEVEL)

include(GNUInstallDirs)

install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/vulkan" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/${API_TYPE}/" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/vulkan")

set_target_properties(VulkanLayerSettings PROPERTIES EXPORT_NAME "LayerSettings")
set_target_properties(VulkanUtilityHeaders PROPERTIES EXPORT_NAME "UtilityHeaders")
Expand Down
2 changes: 2 additions & 0 deletions scripts/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ if (UPDATE_DEPS)
endif()
list(APPEND update_dep_command "--config")
list(APPEND update_dep_command "${_build_type}")
list(APPEND update_dep_command "--api")
list(APPEND update_dep_command "${API_TYPE}")

set(UPDATE_DEPS_DIR_SUFFIX "${_build_type}")
if (ANDROID)
Expand Down
31 changes: 25 additions & 6 deletions scripts/generate_source.py
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like @spencer-lunarg to approve the python code before merging though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. Thanks for the review, @juan-lunarg!

Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,32 @@ def RunGenerators(api: str, registry: str, targetFilter: str) -> None:
from generators.format_utils_generator import FormatUtilsOutputGenerator
from generators.struct_helper_generator import StructHelperOutputGenerator

# These set fields that are needed by both OutputGenerator and BaseGenerator,
# but are uniform and don't need to be set at a per-generated file level
from generators.base_generator import (SetTargetApiName, SetMergedApiNames)
SetTargetApiName(api)

# Build up a list of all generators and custom options
generators = {
'vk_dispatch_table.h' : {
'generator' : DispatchTableOutputGenerator,
'directory' : 'include/vulkan/utility',
'genCombined': True,
'directory' : f'include/{api}/utility',
},
'vk_enum_string_helper.h' : {
'generator' : EnumStringHelperOutputGenerator,
'directory' : 'include/vulkan',
'genCombined': True,
'directory' : f'include/{api}',
},
'vk_format_utils.h' : {
'generator' : FormatUtilsOutputGenerator,
'directory' : 'include/vulkan/utility',
'genCombined': True,
'directory' : f'include/{api}/utility',
},
'vk_struct_helper.hpp' : {
'generator' : StructHelperOutputGenerator,
'directory' : 'include/vulkan/utility',
'genCombined': True,
'directory' : f'include/{api}/utility',
},
}

Expand All @@ -61,11 +70,21 @@ def RunGenerators(api: str, registry: str, targetFilter: str) -> None:
generator = generators[target]['generator']
gen = generator()

# This code and the 'genCombined' generator metadata is used by downstream
# users to generate code with all Vulkan APIs merged into the target API variant
# (e.g. Vulkan SC) when needed. The constructed apiList is also used to filter
# out non-applicable extensions later below.
apiList = [api]
if api != 'vulkan' and generators[target]['genCombined']:
SetMergedApiNames('vulkan')
apiList.append('vulkan')
else:
SetMergedApiNames(None)

outDirectory = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', generators[target]['directory']))
options = BaseGeneratorOptions(
customFileName = target,
customDirectory = outDirectory,
customApiName = 'vulkan')
customDirectory = outDirectory)

# Create the registry object with the specified generator and generator
# options. The options are set before XML loading as they may affect it.
Expand Down
52 changes: 44 additions & 8 deletions scripts/generators/base_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,30 @@ def SetTargetApiName(apiname: str) -> None:
global globalApiName
globalApiName = apiname

def SetMergedApiNames(names: str) -> None:
global mergedApiNames
mergedApiNames = names


# This class is a container for any source code, data, or other behavior that is necessary to
# customize the generator script for a specific target API variant (e.g. Vulkan SC). As such,
# all of these API-specific interfaces and their use in the generator script are part of the
# contract between this repository and its downstream users. Changing or removing any of these
# interfaces or their use in the generator script will have downstream effects and thus
# should be avoided unless absolutely necessary.
class APISpecific:
# Version object factory method
@staticmethod
def createApiVersion(targetApiName: str, name: str, number: str) -> Version:
match targetApiName:

# Vulkan specific API version creation
case 'vulkan':
nameApi = name.replace('VK_', 'VK_API_')
nameString = f'"{name}"'
return Version(name, nameString, nameApi, number)


# This Generator Option is used across all generators.
# After years of use, it has shown that most the options are unified across each generator (file)
# as it is easier to modifiy things per-file that need the difference
Expand All @@ -79,7 +103,7 @@ def __init__(self,
filename = customFileName if customFileName else globalFileName,
directory = customDirectory if customDirectory else globalDirectory,
apiname = customApiName if customApiName else globalApiName,
mergeApiNames = None,
mergeApiNames = mergedApiNames,
defaultExtensions = customApiName if customApiName else globalApiName,
emitExtensions = '.*',
emitSpirv = '.*',
Expand All @@ -97,6 +121,7 @@ class BaseGenerator(OutputGenerator):
def __init__(self):
OutputGenerator.__init__(self, None, None, None)
self.vk = VulkanObject()
self.targetApiName = globalApiName

# reg.py has a `self.featureName` but this is nicer because
# it will be either the Version or Extension object
Expand Down Expand Up @@ -162,6 +187,15 @@ def applyExtensionDependency(self):
# one or more extension and/or core version names
for required in dict:
for commandName in dict[required]:
# Skip commands removed in the target API
# This check is needed because parts of the base generator code bypass the
# dependency resolution logic in the registry tooling and thus the generator
# may attempt to generate code for commands which are not supported in the
# target API variant, thus this check needs to happen even if any specific
# target API variant may not specifically need it
if not commandName in self.vk.commands:
continue

command = self.vk.commands[commandName]
# Make sure list is unique
command.extensions.extend([extension] if extension not in command.extensions else [])
Expand Down Expand Up @@ -307,9 +341,7 @@ def beginFeature(self, interface, emit):
else: # version
number = interface.get('number')
if number != '1.0':
nameApi = name.replace('VK_', 'VK_API_')
nameString = f'"{name}"'
self.currentVersion = Version(name, nameString, nameApi, number)
self.currentVersion = APISpecific.createApiVersion(self.targetApiName, name, number)
self.vk.versions[name] = self.currentVersion

def endFeature(self):
Expand Down Expand Up @@ -638,8 +670,10 @@ def genSyncStage(self, sync):
equivalent = SyncEquivalent(stages, accesses, False)

flagName = syncElem.get('name')
flag = [x for x in self.vk.bitmasks['VkPipelineStageFlagBits2'].flags if x.name == flagName][0]
self.vk.syncStage.append(SyncStage(flag, support, equivalent))
flag = [x for x in self.vk.bitmasks['VkPipelineStageFlagBits2'].flags if x.name == flagName]
# This check is needed because not all API variants have VK_KHR_synchronization2
if flag:
self.vk.syncStage.append(SyncStage(flag[0], support, equivalent))

def genSyncAccess(self, sync):
OutputGenerator.genSyncAccess(self, sync)
Expand All @@ -663,8 +697,10 @@ def genSyncAccess(self, sync):
equivalent = SyncEquivalent(stages, accesses, False)

flagName = syncElem.get('name')
flag = [x for x in self.vk.bitmasks['VkAccessFlagBits2'].flags if x.name == flagName][0]
self.vk.syncAccess.append(SyncAccess(flag, support, equivalent))
flag = [x for x in self.vk.bitmasks['VkAccessFlagBits2'].flags if x.name == flagName]
# This check is needed because not all API variants have VK_KHR_synchronization2
if flag:
self.vk.syncAccess.append(SyncAccess(flag[0], support, equivalent))

def genSyncPipeline(self, sync):
OutputGenerator.genSyncPipeline(self, sync)
Expand Down
1 change: 1 addition & 0 deletions scripts/known_good.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"repos": [
{
"name": "Vulkan-Headers",
"api": "vulkan",
"url": "https://github.com/KhronosGroup/Vulkan-Headers.git",
"sub_dir": "Vulkan-Headers",
"build_dir": "Vulkan-Headers/build",
Expand Down