winevulkan: Generate "in_ext" definition on demand

There are cases in StructConversionFunction.definition where we will generate copy code for extension struct members, without emitting the definition of the "in_ext" variable used in the copy code.

This issue is triggered by mismatches in the condition that guards the generation of the "in_ext" definition, and the condition(s) that govern the generation of the member copy code (e.g., in StructConversionFunction.member_needs_copy and VkMember.needs_conversion).

In order to avoid such mismatches and the burden of having to keep the conditions in sync, this commit generates the definition on demand, by checking if it's actually needed by the member copy code.

Signed-off-by: Alexandros Frantzis alexandros.frantzis@collabora.com

--

Some more details in case a different solution becomes apparent.

An example of the aforementioned issue can be triggered if we make VK_EXT_image_drm_format_modifier an UNEXPOSED extension in make_vulkan:

../wine/dlls/winevulkan/vulkan_thunks.c: In function ‘convert_VkFormatProperties2_win32_to_host’:
../wine/dlls/winevulkan/vulkan_thunks.c:10214:119: error: ‘in_ext’ undeclared (first use in this function); did you mean ‘index’?
10214 |             out_ext->pDrmFormatModifierProperties = convert_VkDrmFormatModifierPropertiesEXT_array_win32_to_host(ctx, in_ext->pDrmFormatModifierProperties, in_ext->drmFormatModifierCount);
      |                                                                                                                       ^~~~~~
      |                                                                                                                       index

In this particular case the mismatch happens because for the VkDrmFormatModifierPropertiesListEXT (returnedonly=true) struct in the INPUT direction the current check doesn't emit in_ext:

if self.direction == Direction.OUTPUT or not ext.returnedonly: # Not triggered
     body += ident + "{0} *in_ext = ({0} *)in_header;\n".format(in_type)

but self.member_needs_copy(ext, m) below for the "pDrmFormatModifierProperties" member returns True, requiring in_ext. The flow is:

* self.member_needs_copy(ext, m) => True
   if m.name != "sType" and struct.returnedonly and not m.needs_conversion(self.conv, self.unwrap, Direction.INPUT, self.const): # Not triggered
      return False
   return True
   * m.needs_conversion(self.conv, self.unwrap, Direction.INPUT, self.const) => True
       # if pointer member needs output conversion, it also needs input conversion
       # to allocate the pointer
       if direction == Direction.INPUT and self.is_pointer() and \
          self.needs_conversion(conv, unwrap, Direction.OUTPUT, struct_const):
          return True

Merge request reports

Loading