Closed tycho closed 1 year ago
This workaround seems to generate an almost-correct header + loader, but I don't like commenting out that check:
diff --git a/glad/parse.py b/glad/parse.py
index a133b40..5492a38 100644
--- a/glad/parse.py
+++ b/glad/parse.py
@@ -367,9 +367,10 @@ class Specification(object):
else:
# technically not required, but better throw more
# than generate broken code because of a broken specification
- if not enum.value == enums[enum.name].value:
- raise ValueError('extension enum {} required multiple times '
- 'with different values'.format(e.name))
+ #if not enum.value == enums[enum.name].value:
+ # raise ValueError('extension enum {} required multiple times '
+ # 'with different values'.format(e.name))
+ pass
enums[enum.name].also_extended_by(extension.attrib['name'])
t.enums = list(enums.values())
@@ -450,7 +451,8 @@ class Specification(object):
features = defaultdict(dict)
for element in self.root.iter('feature'):
num = Version(*map(int, element.attrib['number'].split('.')))
- features[element.attrib['api']][num] = Feature.from_element(element)
+ for api in element.attrib['api'].split(','):
+ features[api][num] = Feature.from_element(element)
for api, api_features in features.items():
features[api] = OrderedDict(sorted(api_features.items(), key=lambda x: x[0]))
@@ -1321,7 +1323,7 @@ class Extension(IdentifiedByName):
@classmethod
def from_element(cls, element):
name = element.attrib['name']
- supported = element.attrib['supported'].split('|')
+ supported = re.split(r'\||,', element.attrib['supported'])
requires = [Require.from_element(require) for require in element.findall('require')]
There's some wonky results though, so there is still something wrong:
typedef struct VkPipelineShaderStageCreateInfo {
VkStructureType sType;
const void * pNext;
VkPipelineShaderStageCreateFlags flags;
VkShaderStageFlagBits stage;
VkShaderModule module;
const char * pName;
const char * pName; // <--- DUPE, one is defined as api="vulkan" another is defined as api="vulkansc", so it gets added twice somehow
const VkSpecializationInfo * pSpecializationInfo;
} VkPipelineShaderStageCreateInfo;
It looks like the member
element handler needs to understand the api
attribute. And looking at other issues, it looks like the param
handler needs it as well.
Thanks for making me aware of it and the good summary.
This is quite an annoying change to deal with and makes parsing the XML so much harder then it needs to be with a lot more edge cases than before. Instead of allowing sub attributes (struct members and command parameters) to behave differently between APIs they could have just duplicated the blocks and used the previously already used api
attribute on those.
I would argue this doesn't even help for human readability, it certainly makes it a lot harder to parse from code.
Glad now duplicates enums, types and commands for each found sub-api. The selection algorithm could already deal with that (used in GL).
The additional change introduced with depends
attributes does not affect glad, because it already has a smarter dependency selection algorithm and does not rely on these attributes at all.
I am currently finishing a fix for this. If everything goes well there will be a fixed version within 30 minutes.
Thanks for the quick fix @Dav1dde!
And I agree, it makes a mess of the XML that didn't need to be there, and is inconsistent with the GL XML as well (the pipe vs comma delimiting for example).
Khronos made some changes to the Vulkan specification XML that appear to confuse GLAD:
Seems to be a result of Khronos adding comma-separated API names, e.g.:
I tried doing a quick workaround:
but this leads to other issues I haven't dug into yet: