You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
350 lines
10 KiB
350 lines
10 KiB
local header =
|
|
[[
|
|
/*
|
|
* Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
* SPDX-FileCopyrightText: Copyright (c) 2018-2021 NVIDIA CORPORATION
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
# function nvvk::make, nvvk::clear
|
|
Contains templated `nvvk::make<T>` and `nvvk::clear<T>` functions that are
|
|
auto-generated by `structs.lua`. The functions provide default
|
|
structs for the Vulkan C api by initializing the `VkStructureType sType`
|
|
field (also for nested structs) and clearing the rest to zero.
|
|
|
|
``` c++
|
|
auto compCreateInfo = nvvk::make<VkComputePipelineCreateInfo>;
|
|
```
|
|
*/
|
|
|
|
#pragma once
|
|
]]
|
|
|
|
-- HOW TO USE
|
|
--
|
|
-- 1. Setup environment variable NVVK_VULKAN_XML pointing to vk.xml
|
|
-- or use VULKAN_SDK >= 1.2.135.0
|
|
--
|
|
-- 2. Modify the extension subset (allowlist)
|
|
--
|
|
-- 3. Check out this and the other structs_vk files for write access
|
|
--
|
|
-- 4. Run with a lua5.1 compatible lua runtime and the lua2xml project
|
|
-- https://github.com/manoelcampos/xml2lua
|
|
-- (shared_internal has all the files).
|
|
--
|
|
-- lua structs_vk.lua
|
|
--
|
|
-- within this directory.
|
|
|
|
local VULKAN_XML = os.getenv("NVVK_VULKAN_XML") or os.getenv("VULKAN_SDK").."/share/vulkan/registry/vk.xml"
|
|
local extensionSubset = [[
|
|
VK_KHR_acceleration_structure
|
|
VK_KHR_ray_query
|
|
VK_KHR_ray_tracing_pipeline
|
|
VK_KHR_push_descriptor
|
|
VK_KHR_8bit_storage
|
|
VK_KHR_create_renderpass2
|
|
VK_KHR_depth_stencil_resolve
|
|
VK_KHR_draw_indirect_count
|
|
VK_KHR_driver_properties
|
|
VK_KHR_pipeline_executable_properties
|
|
|
|
VK_NV_compute_shader_derivatives
|
|
VK_NV_cooperative_matrix
|
|
VK_NV_corner_sampled_image
|
|
VK_NV_coverage_reduction_mode
|
|
VK_NV_dedicated_allocation_image_aliasing
|
|
VK_NV_mesh_shader
|
|
VK_NV_ray_tracing
|
|
VK_NV_representative_fragment_test
|
|
VK_NV_shading_rate_image
|
|
VK_NV_viewport_array2
|
|
VK_NV_viewport_swizzle
|
|
VK_NV_scissor_exclusive
|
|
VK_NV_device_generated_commands
|
|
|
|
VK_EXT_buffer_device_address
|
|
VK_EXT_debug_marker
|
|
VK_EXT_calibrated_timestamps
|
|
VK_EXT_conservative_rasterization
|
|
VK_EXT_descriptor_indexing
|
|
VK_EXT_depth_clip_enable
|
|
VK_EXT_memory_budget
|
|
VK_EXT_memory_priority
|
|
VK_EXT_pci_bus_info
|
|
VK_EXT_sample_locations
|
|
VK_EXT_sampler_filter_minmax
|
|
VK_EXT_texel_buffer_alignment
|
|
VK_EXT_debug_utils
|
|
VK_EXT_host_query_reset
|
|
|
|
VK_KHR_external_memory_win32
|
|
VK_KHR_external_semaphore_win32
|
|
VK_KHR_external_fence_win32
|
|
|
|
VK_KHR_external_memory_fd
|
|
VK_KHR_external_semaphore_fd
|
|
|
|
VK_EXT_validation_features
|
|
VK_KHR_swapchain
|
|
]]
|
|
|
|
|
|
local function generate(outfilename, header, whitelist)
|
|
|
|
local override = {
|
|
VkRayTracingShaderGroupCreateInfoNV =
|
|
[[
|
|
template<> inline VkRayTracingShaderGroupCreateInfoNV make<VkRayTracingShaderGroupCreateInfoNV>(){
|
|
VkRayTracingShaderGroupCreateInfoNV ret = {VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV};
|
|
ret.generalShader = VK_SHADER_UNUSED_NV;
|
|
ret.closestHitShader = VK_SHADER_UNUSED_NV;
|
|
ret.anyHitShader = VK_SHADER_UNUSED_NV;
|
|
ret.intersectionShader = VK_SHADER_UNUSED_NV;
|
|
return ret;
|
|
}
|
|
]],
|
|
VkRayTracingShaderGroupCreateInfoKHR =
|
|
[[
|
|
template<> inline VkRayTracingShaderGroupCreateInfoKHR make<VkRayTracingShaderGroupCreateInfoKHR>(){
|
|
VkRayTracingShaderGroupCreateInfoKHR ret = {VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR};
|
|
ret.generalShader = VK_SHADER_UNUSED_KHR;
|
|
ret.closestHitShader = VK_SHADER_UNUSED_KHR;
|
|
ret.anyHitShader = VK_SHADER_UNUSED_KHR;
|
|
ret.intersectionShader = VK_SHADER_UNUSED_KHR;
|
|
return ret;
|
|
}
|
|
]],
|
|
}
|
|
|
|
local function toTab(str)
|
|
local tab = {}
|
|
for name in str:gmatch("[%w_]+") do
|
|
tab[name] = true
|
|
end
|
|
return tab
|
|
end
|
|
|
|
local whitelist = whitelist and toTab(whitelist)
|
|
|
|
local xml2lua = require("xml2lua")
|
|
local handler = require("xmlhandler.tree")
|
|
local filename = VULKAN_XML
|
|
local f = io.open(filename,"rt")
|
|
assert(f, filename.." not found")
|
|
|
|
local xml = f:read("*a")
|
|
f:close()
|
|
|
|
-- Bug workaround https://github.com/manoelcampos/xml2lua/issues/35
|
|
xml = xml:gsub("(<member>)(<type>[%w_]+</type>)%* ", function(p,typ)
|
|
-- add _ dummy symbol
|
|
return "<member>_"..typ.."* "
|
|
end)
|
|
|
|
local parser = xml2lua.parser(handler)
|
|
parser:parse(xml)
|
|
|
|
local version = xml:match("VK_HEADER_VERSION</name> (%d+)")
|
|
assert(version)
|
|
|
|
local structenums = {}
|
|
local structextensions = {}
|
|
|
|
local function enumID(name)
|
|
name = name:lower()
|
|
name = name:gsub("_","")
|
|
return name
|
|
end
|
|
|
|
for name in xml:gmatch('"VK_STRUCTURE_TYPE_([%w_]-)"') do
|
|
structenums[enumID(name)] = "VK_STRUCTURE_TYPE_"..name
|
|
end
|
|
|
|
xml = nil
|
|
|
|
local types = handler.root.registry.types
|
|
local commands = handler.root.registry.commands
|
|
local extensions = handler.root.registry.extensions.extension
|
|
|
|
-- debugging
|
|
if (false) then
|
|
local serpent = require "serpent"
|
|
local f = io.open(filename..".types.lua", "wt")
|
|
f:write(serpent.block(types))
|
|
local f = io.open(filename..".exts.lua", "wt")
|
|
f:write(serpent.block(extensions))
|
|
end
|
|
|
|
-- build list struct types with structure type init
|
|
local lktypes = {}
|
|
local lkall = {}
|
|
local lkcore = {}
|
|
for _,v in ipairs(types.type) do
|
|
if (v._attr.category == "struct") then
|
|
local alias = v._attr.alias
|
|
local name = v._attr.name
|
|
if (alias) then
|
|
lktypes[name] = lktypes[alias]
|
|
else
|
|
local members = type(v.member[1]) == "table" and v.member or {v.member}
|
|
local tab = {name=name, members=members}
|
|
if (members[1].type == "VkStructureType") then
|
|
lktypes[name] = tab
|
|
lkcore[name] = true
|
|
end
|
|
lkall[name] = tab
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
local platforms = {
|
|
ggp = "VK_USE_PLATFORM_GGP",
|
|
win32 = "VK_USE_PLATFORM_WIN32_KHR",
|
|
vi = "VK_USE_PLATFORM_VI_NN",
|
|
ios = "VK_USE_PLATFORM_IOS_MVK",
|
|
macos = "VK_USE_PLATFORM_MACOS_MVK",
|
|
android = "VK_USE_PLATFORM_ANDROID_KHR",
|
|
fuchsia = "VK_USE_PLATFORM_FUCHSIA",
|
|
metal = "VK_USE_PLATFORM_METAL_EXT",
|
|
xlib = "VK_USE_PLATFORM_XLIB_KHR",
|
|
xcb = "VK_USE_PLATFORM_XCB_KHR",
|
|
wayland = "VK_USE_PLATFORM_WAYLAND_KHR",
|
|
xlib_xrandr = "VK_USE_PLATFORM_XLIB_XRANDR_EXT",
|
|
}
|
|
|
|
-- fill extension list
|
|
local extLists = {}
|
|
|
|
for _,v in ipairs(extensions) do
|
|
if (v.require) then
|
|
local reqs = v.require[1] and v.require or {v.require}
|
|
local list = {}
|
|
local valid = false
|
|
for _,r in ipairs(reqs) do
|
|
if (r.type) then
|
|
local types = r.type[1] and r.type or {r.type}
|
|
for _,t in ipairs(types) do
|
|
local tname = t._attr.name
|
|
if (lktypes[tname]) then
|
|
lkcore[tname] = false
|
|
table.insert(list, tname)
|
|
valid = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if (valid and ((whitelist and whitelist[v._attr.name]) or not whitelist)) then
|
|
table.insert(extLists, {list=list, ext=v._attr.name, platform=platforms[v._attr.platform or "_"] })
|
|
end
|
|
end
|
|
end
|
|
|
|
-- fill core list
|
|
local coreList = {}
|
|
for _,v in ipairs(types.type) do
|
|
if (v._attr.category == "struct" and lkcore[v._attr.name]) then
|
|
table.insert(coreList, v._attr.name)
|
|
end
|
|
end
|
|
|
|
local out = ""
|
|
out = out.." template <class T> T make(){ return T(); }\n"
|
|
out = out.." template <class T> void clear(T& ref){ ref = make<T>(); }\n"
|
|
|
|
local function process(t)
|
|
local ext = nil
|
|
|
|
for _,sname in ipairs(t.list) do
|
|
local enum = structenums[enumID(sname:match("Vk(.*)"))]
|
|
local struct = lktypes[sname]
|
|
if (enum and struct and not struct.exported) then
|
|
if ((not ext) and t.ext) then
|
|
out = out.."#if "..t.ext.."\n"
|
|
ext = t.ext
|
|
end
|
|
|
|
local complex = ""
|
|
|
|
local function addComplex(prefix, members)
|
|
for _,m in ipairs(members) do
|
|
local mvar = m.name
|
|
local mtype = m.type
|
|
local mstruct = lkall[mtype]
|
|
-- skip pointers
|
|
if (mstruct and not m[1]) then
|
|
local mexp = mstruct.exported
|
|
local mmembers = mstruct.members
|
|
if (mexp == true) then
|
|
complex = complex..prefix..mvar.." = make<"..mtype..">();\n"
|
|
elseif (mexp) then
|
|
complex = complex..prefix..mvar.." = {"..mexp.."};\n"
|
|
elseif (mmembers) then
|
|
addComplex(prefix..mvar..".", mmembers)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
addComplex(" ret.", struct.members)
|
|
|
|
|
|
if (override[sname]) then
|
|
out = out..override[sname]
|
|
print("override", sname)
|
|
struct.exported = true
|
|
elseif (complex ~= "") then
|
|
out = out.." template<> inline "..sname.." make<"..sname..">(){\n "..sname.." ret = {"..enum.."};\n"..complex.." return ret;\n }\n"
|
|
print("complex", sname)
|
|
struct.exported = true
|
|
else
|
|
out = out.." template<> inline "..sname.." make<"..sname..">(){\n return "..sname.."{"..enum.."};\n }\n"
|
|
struct.exported = enum
|
|
end
|
|
|
|
|
|
end
|
|
end
|
|
|
|
if (ext) then
|
|
out = out.."#endif\n"
|
|
end
|
|
end
|
|
|
|
-- process core
|
|
process({list=coreList})
|
|
-- process whitelisted extensions
|
|
for _,ext in ipairs(extLists) do
|
|
process(ext)
|
|
end
|
|
|
|
local outfile = io.open(outfilename, "wt")
|
|
assert(outfile, "could not open "..outfilename.." for writing")
|
|
|
|
outfile:write("/* based on VK_HEADER_VERSION "..version.." */\n")
|
|
outfile:write(header)
|
|
outfile:write("namespace nvvk {\n")
|
|
outfile:write(out)
|
|
outfile:write("}\n")
|
|
outfile:flush()
|
|
outfile:close()
|
|
end
|
|
|
|
generate("structs_vk.hpp", header, extensionSubset)
|