mirror of
https://github.com/KhronosGroup/Vulkan-Hpp.git
synced 2024-10-14 16:32:17 +00:00
Add support for Vulkan call delegation to support custom loaders. (#174)
This commit is contained in:
parent
d74e5f6199
commit
e97e34675d
@ -1541,6 +1541,7 @@ tinyxml2::XMLNode const* VulkanHppGenerator::readCommandParamType(tinyxml2::XMLN
|
|||||||
tinyxml2::XMLElement const* typeElement = node->ToElement();
|
tinyxml2::XMLElement const* typeElement = node->ToElement();
|
||||||
checkEmptyElement(typeElement);
|
checkEmptyElement(typeElement);
|
||||||
std::string type = strip(node->ToElement()->GetText(), "Vk");
|
std::string type = strip(node->ToElement()->GetText(), "Vk");
|
||||||
|
param.unchangedType = param.type + node->ToElement()->GetText();
|
||||||
param.type += type;
|
param.type += type;
|
||||||
param.pureType = type;
|
param.pureType = type;
|
||||||
|
|
||||||
@ -1552,6 +1553,7 @@ tinyxml2::XMLNode const* VulkanHppGenerator::readCommandParamType(tinyxml2::XMLN
|
|||||||
std::string value = trimEnd(node->Value());
|
std::string value = trimEnd(node->Value());
|
||||||
assert((value == "*") || (value == "**") || (value == "* const*"));
|
assert((value == "*") || (value == "**") || (value == "* const*"));
|
||||||
param.type += value;
|
param.type += value;
|
||||||
|
param.unchangedType += value;
|
||||||
node = node->NextSibling();
|
node = node->NextSibling();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1635,7 +1637,7 @@ void VulkanHppGenerator::readCommandsCommand(tinyxml2::XMLElement const* element
|
|||||||
}
|
}
|
||||||
else if (value == "proto")
|
else if (value == "proto")
|
||||||
{
|
{
|
||||||
readCommandProto(child, commandData.returnType, commandData.fullName);
|
readCommandProto(child, commandData.returnType, commandData.unchangedReturnType, commandData.fullName);
|
||||||
}
|
}
|
||||||
#if !defined(NDEBUG)
|
#if !defined(NDEBUG)
|
||||||
else
|
else
|
||||||
@ -1661,7 +1663,7 @@ void VulkanHppGenerator::readCommandsCommand(tinyxml2::XMLElement const* element
|
|||||||
m_commands.insert(std::make_pair(commandData.fullName, commandData));
|
m_commands.insert(std::make_pair(commandData.fullName, commandData));
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanHppGenerator::readCommandProto(tinyxml2::XMLElement const* element, std::string & returnType, std::string & fullName)
|
void VulkanHppGenerator::readCommandProto(tinyxml2::XMLElement const* element, std::string & returnType, std::string & unchangedReturnType, std::string & fullName)
|
||||||
{
|
{
|
||||||
checkAttributes(getAttributes(element), element->GetLineNum(), {}, {});
|
checkAttributes(getAttributes(element), element->GetLineNum(), {}, {});
|
||||||
std::vector<tinyxml2::XMLElement const*> children = getChildElements(element);
|
std::vector<tinyxml2::XMLElement const*> children = getChildElements(element);
|
||||||
@ -1669,6 +1671,7 @@ void VulkanHppGenerator::readCommandProto(tinyxml2::XMLElement const* element, s
|
|||||||
|
|
||||||
// get return type and name of the command
|
// get return type and name of the command
|
||||||
returnType = strip(children[0]->GetText(), "Vk");
|
returnType = strip(children[0]->GetText(), "Vk");
|
||||||
|
unchangedReturnType = children[0]->GetText();
|
||||||
fullName = startLowerCase(strip(children[1]->GetText(), "vk"));
|
fullName = startLowerCase(strip(children[1]->GetText(), "vk"));
|
||||||
|
|
||||||
// add an empty DependencyData to this name
|
// add an empty DependencyData to this name
|
||||||
@ -2777,7 +2780,7 @@ void VulkanHppGenerator::writeCall(std::ostream & os, CommandData const& command
|
|||||||
}
|
}
|
||||||
|
|
||||||
// the original function call
|
// the original function call
|
||||||
os << "vk" << startUpperCase(commandData.fullName) << "( ";
|
os << "d.vk" << startUpperCase(commandData.fullName) << "( ";
|
||||||
|
|
||||||
if (!commandData.className.empty())
|
if (!commandData.className.empty())
|
||||||
{
|
{
|
||||||
@ -3201,10 +3204,8 @@ void VulkanHppGenerator::writeExceptionsForEnum(std::ostream & os, EnumData cons
|
|||||||
|
|
||||||
void VulkanHppGenerator::writeFunction(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool definition, bool enhanced, bool singular, bool unique, bool isStructureChain)
|
void VulkanHppGenerator::writeFunction(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool definition, bool enhanced, bool singular, bool unique, bool isStructureChain)
|
||||||
{
|
{
|
||||||
if (enhanced && (!singular || isStructureChain))
|
writeFunctionHeaderTemplate(os, indentation, commandData, enhanced, !definition, isStructureChain);
|
||||||
{
|
|
||||||
writeFunctionHeaderTemplate(os, indentation, commandData, !definition, isStructureChain);
|
|
||||||
}
|
|
||||||
os << indentation << (definition ? "VULKAN_HPP_INLINE " : "");
|
os << indentation << (definition ? "VULKAN_HPP_INLINE " : "");
|
||||||
writeFunctionHeaderReturnType(os, indentation, commandData, enhanced, singular, unique, isStructureChain);
|
writeFunctionHeaderReturnType(os, indentation, commandData, enhanced, singular, unique, isStructureChain);
|
||||||
if (definition && !commandData.className.empty())
|
if (definition && !commandData.className.empty())
|
||||||
@ -3607,7 +3608,7 @@ void VulkanHppGenerator::writeFunctionBodyStandard(std::ostream & os, std::strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// call the original function
|
// call the original function
|
||||||
os << "vk" << startUpperCase(commandData.fullName) << "( ";
|
os << "d.vk" << startUpperCase(commandData.fullName) << "( ";
|
||||||
|
|
||||||
if (!commandData.className.empty())
|
if (!commandData.className.empty())
|
||||||
{
|
{
|
||||||
@ -3663,7 +3664,7 @@ void VulkanHppGenerator::writeFunctionHeaderArguments(std::ostream & os, Command
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
writeFunctionHeaderArgumentsStandard(os, commandData);
|
writeFunctionHeaderArgumentsStandard(os, commandData, withDefaults);
|
||||||
}
|
}
|
||||||
os << ")";
|
os << ")";
|
||||||
if (!commandData.className.empty())
|
if (!commandData.className.empty())
|
||||||
@ -3805,14 +3806,29 @@ void VulkanHppGenerator::writeFunctionHeaderArgumentsEnhanced(std::ostream & os,
|
|||||||
argEncountered = true;
|
argEncountered = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
os << " ";
|
|
||||||
|
if (argEncountered)
|
||||||
|
{
|
||||||
|
os << ", ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
os << "Dispatch const &d";
|
||||||
|
if (withDefaults)
|
||||||
|
{
|
||||||
|
os << " = Dispatch()";
|
||||||
|
}
|
||||||
|
|
||||||
|
os << " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanHppGenerator::writeFunctionHeaderArgumentsStandard(std::ostream & os, CommandData const& commandData)
|
void VulkanHppGenerator::writeFunctionHeaderArgumentsStandard(std::ostream & os, CommandData const& commandData, bool withDefaults)
|
||||||
{
|
{
|
||||||
// for the standard case, just list all the arguments as we've got them
|
// for the standard case, just list all the arguments as we've got them
|
||||||
bool argEncountered = false;
|
bool argEncountered = false;
|
||||||
|
|
||||||
|
// determine the last argument, where we might provide some default for
|
||||||
|
size_t lastArgument = commandData.params.size() - 1;
|
||||||
|
|
||||||
for (size_t i = commandData.className.empty() ? 0 : 1; i < commandData.params.size(); i++)
|
for (size_t i = commandData.className.empty() ? 0 : 1; i < commandData.params.size(); i++)
|
||||||
{
|
{
|
||||||
if (argEncountered)
|
if (argEncountered)
|
||||||
@ -3825,11 +3841,36 @@ void VulkanHppGenerator::writeFunctionHeaderArgumentsStandard(std::ostream & os,
|
|||||||
{
|
{
|
||||||
os << "[" << commandData.params[i].arraySize << "]";
|
os << "[" << commandData.params[i].arraySize << "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (withDefaults && (lastArgument == i))
|
||||||
|
{
|
||||||
|
// check if the very last argument is a flag without any bits -> provide some empty default for it
|
||||||
|
std::map<std::string, BitmaskData>::const_iterator flagIt = m_bitmasks.find(commandData.params[i].pureType);
|
||||||
|
if (flagIt != m_bitmasks.end())
|
||||||
|
{
|
||||||
|
// get the enum corresponding to this flag, to check if it's empty
|
||||||
|
std::list<DependencyData>::const_iterator depIt = std::find_if(m_dependencies.begin(), m_dependencies.end(), [&flagIt](DependencyData const& dd) { return(dd.name == flagIt->first); });
|
||||||
|
assert((depIt != m_dependencies.end()) && (depIt->dependencies.size() == 1));
|
||||||
|
std::map<std::string, EnumData>::const_iterator enumIt = m_enums.find(*depIt->dependencies.begin());
|
||||||
|
assert(enumIt != m_enums.end());
|
||||||
|
if (enumIt->second.values.empty())
|
||||||
|
{
|
||||||
|
// there are no bits in this flag -> provide the default
|
||||||
|
os << " = " << commandData.params[i].pureType << "()";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
argEncountered = true;
|
argEncountered = true;
|
||||||
}
|
}
|
||||||
if (argEncountered)
|
if (argEncountered)
|
||||||
{
|
{
|
||||||
os << " ";
|
os << ", ";
|
||||||
|
}
|
||||||
|
|
||||||
|
os << "Dispatch const &d";
|
||||||
|
if (withDefaults)
|
||||||
|
{
|
||||||
|
os << " = Dispatch() ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3893,19 +3934,20 @@ void VulkanHppGenerator::writeFunctionHeaderReturnType(std::ostream & os, std::s
|
|||||||
os << replaceWithMap(templateString, { { "returnType", returnType } });
|
os << replaceWithMap(templateString, { { "returnType", returnType } });
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanHppGenerator::writeFunctionHeaderTemplate(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool withDefault, bool isStructureChain)
|
void VulkanHppGenerator::writeFunctionHeaderTemplate(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool enhanced, bool withDefault, bool isStructureChain)
|
||||||
{
|
{
|
||||||
if (isStructureChain)
|
std::string dispatch = withDefault ? std::string("typename Dispatch = DispatchLoader") : std::string("typename Dispatch");
|
||||||
|
if (enhanced && isStructureChain)
|
||||||
{
|
{
|
||||||
os << indentation << "template <typename ...T>" << std::endl;
|
os << indentation << "template <typename ...T, " << dispatch << ">" << std::endl;
|
||||||
}
|
}
|
||||||
else if ((commandData.templateParam != ~0) && ((commandData.templateParam != commandData.returnParam) || (commandData.enhancedReturnType == "Result")))
|
else if (enhanced && (commandData.templateParam != ~0) && ((commandData.templateParam != commandData.returnParam) || (commandData.enhancedReturnType == "Result")))
|
||||||
{
|
{
|
||||||
// if there's a template parameter, not being the return parameter or where the enhanced return type is 'Result' -> templatize on type 'T'
|
// if there's a template parameter, not being the return parameter or where the enhanced return type is 'Result' -> templatize on type 'T'
|
||||||
assert(commandData.enhancedReturnType.find("Allocator") == std::string::npos);
|
assert(commandData.enhancedReturnType.find("Allocator") == std::string::npos);
|
||||||
os << indentation << "template <typename T>" << std::endl;
|
os << indentation << "template <typename T, " << dispatch << ">" << std::endl;
|
||||||
}
|
}
|
||||||
else if ((commandData.enhancedReturnType.find("Allocator") != std::string::npos))
|
else if (enhanced && (commandData.enhancedReturnType.find("Allocator") != std::string::npos))
|
||||||
{
|
{
|
||||||
// otherwise, if there's an Allocator used in the enhanced return type, we templatize on that Allocator
|
// otherwise, if there's an Allocator used in the enhanced return type, we templatize on that Allocator
|
||||||
assert((commandData.enhancedReturnType.substr(0, 12) == "std::vector<") && (commandData.enhancedReturnType.find(',') != std::string::npos) && (12 < commandData.enhancedReturnType.find(',')));
|
assert((commandData.enhancedReturnType.substr(0, 12) == "std::vector<") && (commandData.enhancedReturnType.find(',') != std::string::npos) && (12 < commandData.enhancedReturnType.find(',')));
|
||||||
@ -3915,8 +3957,13 @@ void VulkanHppGenerator::writeFunctionHeaderTemplate(std::ostream & os, std::str
|
|||||||
// for the default type get the type from the enhancedReturnType, which is of the form 'std::vector<Type,Allocator>'
|
// for the default type get the type from the enhancedReturnType, which is of the form 'std::vector<Type,Allocator>'
|
||||||
os << " = std::allocator<" << commandData.enhancedReturnType.substr(12, commandData.enhancedReturnType.find(',') - 12) << ">";
|
os << " = std::allocator<" << commandData.enhancedReturnType.substr(12, commandData.enhancedReturnType.find(',') - 12) << ">";
|
||||||
}
|
}
|
||||||
|
os << ", " << dispatch;
|
||||||
os << "> " << std::endl;
|
os << "> " << std::endl;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
os << indentation << "template<" << dispatch << ">" << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanHppGenerator::writeResultEnum(std::ostream & os)
|
void VulkanHppGenerator::writeResultEnum(std::ostream & os)
|
||||||
@ -4771,6 +4818,48 @@ void VulkanHppGenerator::EnumData::addEnumValue(std::string const &name, std::st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VulkanHppGenerator::writeDelegationClass(std::ostream &os)
|
||||||
|
{
|
||||||
|
os << "class DispatchLoader" << std::endl
|
||||||
|
<< "{" << std::endl
|
||||||
|
<< "public:\n";
|
||||||
|
|
||||||
|
for (auto command : m_commands)
|
||||||
|
{
|
||||||
|
enterProtect(os, command.second.protect);
|
||||||
|
os << " " << command.second.unchangedReturnType << " vk" << startUpperCase(command.second.fullName) << "( ";
|
||||||
|
bool first = true;
|
||||||
|
for (auto param : command.second.params)
|
||||||
|
{
|
||||||
|
if (!first) {
|
||||||
|
os << ", ";
|
||||||
|
}
|
||||||
|
os << param.unchangedType << " " << param.name;
|
||||||
|
if (!param.arraySize.empty())
|
||||||
|
{
|
||||||
|
os << "[" << param.arraySize << "]";
|
||||||
|
}
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
os << " ) const\n"
|
||||||
|
<< " {\n"
|
||||||
|
<< " return ::vk" << startUpperCase(command.second.fullName) << "( ";
|
||||||
|
first = true;
|
||||||
|
for (auto param : command.second.params)
|
||||||
|
{
|
||||||
|
if (!first) {
|
||||||
|
os << ", ";
|
||||||
|
}
|
||||||
|
os << param.name;
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
os << ");\n";
|
||||||
|
os << " }\n";
|
||||||
|
leaveProtect(os, command.second.protect);
|
||||||
|
}
|
||||||
|
os << "};\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main( int argc, char **argv )
|
int main( int argc, char **argv )
|
||||||
{
|
{
|
||||||
@ -4900,6 +4989,8 @@ int main( int argc, char **argv )
|
|||||||
<< resultValueHeader
|
<< resultValueHeader
|
||||||
<< createResultValueHeader;
|
<< createResultValueHeader;
|
||||||
|
|
||||||
|
generator.writeDelegationClass(ofs);
|
||||||
|
|
||||||
generator.writeTypes(ofs, defaultValues);
|
generator.writeTypes(ofs, defaultValues);
|
||||||
generator.writeStructureChainValidation(ofs);
|
generator.writeStructureChainValidation(ofs);
|
||||||
generator.writeToStringFunctions(ofs);
|
generator.writeToStringFunctions(ofs);
|
||||||
|
@ -46,6 +46,7 @@ class VulkanHppGenerator
|
|||||||
void writeStructureChainValidation(std::ostream & os);
|
void writeStructureChainValidation(std::ostream & os);
|
||||||
void writeToStringFunctions(std::ostream & os);
|
void writeToStringFunctions(std::ostream & os);
|
||||||
void writeTypes(std::ostream & os, std::map<std::string, std::string> const& defaultValues);
|
void writeTypes(std::ostream & os, std::map<std::string, std::string> const& defaultValues);
|
||||||
|
void writeDelegationClass(std::ostream &os);
|
||||||
#if !defined(NDEBUG)
|
#if !defined(NDEBUG)
|
||||||
void checkExtensionRequirements();
|
void checkExtensionRequirements();
|
||||||
void skipVendorIDs(tinyxml2::XMLElement const* element);
|
void skipVendorIDs(tinyxml2::XMLElement const* element);
|
||||||
@ -87,6 +88,7 @@ class VulkanHppGenerator
|
|||||||
struct ParamData
|
struct ParamData
|
||||||
{
|
{
|
||||||
std::string type;
|
std::string type;
|
||||||
|
std::string unchangedType;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string arraySize;
|
std::string arraySize;
|
||||||
std::string pureType;
|
std::string pureType;
|
||||||
@ -110,6 +112,7 @@ class VulkanHppGenerator
|
|||||||
std::string reducedName;
|
std::string reducedName;
|
||||||
size_t returnParam;
|
size_t returnParam;
|
||||||
std::string returnType;
|
std::string returnType;
|
||||||
|
std::string unchangedReturnType;
|
||||||
std::set<size_t> skippedParams;
|
std::set<size_t> skippedParams;
|
||||||
std::vector<std::string> successCodes;
|
std::vector<std::string> successCodes;
|
||||||
size_t templateParam;
|
size_t templateParam;
|
||||||
@ -211,7 +214,7 @@ class VulkanHppGenerator
|
|||||||
bool readCommandParam(tinyxml2::XMLElement const* element, std::set<std::string> & dependencies, std::vector<ParamData> & params);
|
bool readCommandParam(tinyxml2::XMLElement const* element, std::set<std::string> & dependencies, std::vector<ParamData> & params);
|
||||||
tinyxml2::XMLNode const* readCommandParamType(tinyxml2::XMLNode const* node, ParamData& param);
|
tinyxml2::XMLNode const* readCommandParamType(tinyxml2::XMLNode const* node, ParamData& param);
|
||||||
void readCommandsCommand(tinyxml2::XMLElement const* element);
|
void readCommandsCommand(tinyxml2::XMLElement const* element);
|
||||||
void readCommandProto(tinyxml2::XMLElement const* element, std::string & returnType, std::string & fullName);
|
void readCommandProto(tinyxml2::XMLElement const* element, std::string & returnType, std::string & unchangedReturnType, std::string & fullName);
|
||||||
void readDisabledExtensionRequire(tinyxml2::XMLElement const* element);
|
void readDisabledExtensionRequire(tinyxml2::XMLElement const* element);
|
||||||
void readEnumsEnum(tinyxml2::XMLElement const* element, EnumData & enumData, std::string const& tag);
|
void readEnumsEnum(tinyxml2::XMLElement const* element, EnumData & enumData, std::string const& tag);
|
||||||
void readEnumsConstant(tinyxml2::XMLElement const* element);
|
void readEnumsConstant(tinyxml2::XMLElement const* element);
|
||||||
@ -260,9 +263,9 @@ class VulkanHppGenerator
|
|||||||
void writeFunctionBodyStandard(std::ostream & os, std::string const& indentation, CommandData const& commandData);
|
void writeFunctionBodyStandard(std::ostream & os, std::string const& indentation, CommandData const& commandData);
|
||||||
void writeFunctionHeaderArguments(std::ostream & os, CommandData const& commandData, bool enhanced, bool singular, bool withDefaults);
|
void writeFunctionHeaderArguments(std::ostream & os, CommandData const& commandData, bool enhanced, bool singular, bool withDefaults);
|
||||||
void writeFunctionHeaderArgumentsEnhanced(std::ostream & os, CommandData const& commandData, bool singular, bool withDefaults);
|
void writeFunctionHeaderArgumentsEnhanced(std::ostream & os, CommandData const& commandData, bool singular, bool withDefaults);
|
||||||
void writeFunctionHeaderArgumentsStandard(std::ostream & os, CommandData const& commandData);
|
void writeFunctionHeaderArgumentsStandard(std::ostream & os, CommandData const& commandData, bool withDefaults);
|
||||||
void writeFunctionHeaderReturnType(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool enhanced, bool singular, bool unique, bool isStructureChain);
|
void writeFunctionHeaderReturnType(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool enhanced, bool singular, bool unique, bool isStructureChain);
|
||||||
void writeFunctionHeaderTemplate(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool withDefault, bool isStructureChain);
|
void writeFunctionHeaderTemplate(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool enhanced, bool withDefault, bool isStructureChain);
|
||||||
void writeStructConstructor(std::ostream & os, std::string const& name, StructData const& structData, std::map<std::string, std::string> const& defaultValues);
|
void writeStructConstructor(std::ostream & os, std::string const& name, StructData const& structData, std::map<std::string, std::string> const& defaultValues);
|
||||||
void writeStructSetter(std::ostream & os, std::string const& structureName, MemberData const& memberData);
|
void writeStructSetter(std::ostream & os, std::string const& structureName, MemberData const& memberData);
|
||||||
void writeStructureChainValidation(std::ostream & os, DependencyData const& dependencyData);
|
void writeStructureChainValidation(std::ostream & os, DependencyData const& dependencyData);
|
||||||
|
2
tinyxml2
2
tinyxml2
@ -1 +1 @@
|
|||||||
Subproject commit 4155ac0c7345c760be0b79d44040691a5c4fff06
|
Subproject commit cc1745b552dd12bb1297a99f82044f83b06729e0
|
5963
vulkan/vulkan.hpp
5963
vulkan/vulkan.hpp
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user