diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index 5949cea9543f0b2deecc42ed1ab5a218aa474313..2ea6446da4ef41b7781ff9df388ec708f77a787c 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -1203,12 +1203,18 @@ class VkVariable(object): conversions.extend(m.get_conversions(unwrap, is_const)) - # Conversion requirements for the 'parent' parameter. - for conv in [False, True]: - if self.needs_conversion(conv, unwrap, Direction.INPUT, parent_const): - conversions.append(ConversionFunction(self, Direction.INPUT, conv, unwrap)) - if self.needs_conversion(conv, unwrap, Direction.OUTPUT, parent_const): - conversions.append(ConversionFunction(self, Direction.OUTPUT, conv, unwrap)) + if self.is_static_array() or self.is_dynamic_array(): + for conv in [False, True]: + if self.needs_conversion(conv, unwrap, Direction.INPUT, parent_const): + conversions.append(ArrayConversionFunction(self, Direction.INPUT, conv, unwrap)) + if self.needs_conversion(conv, unwrap, Direction.OUTPUT, parent_const): + conversions.append(ArrayConversionFunction(self, Direction.OUTPUT, conv, unwrap)) + elif self.is_struct(): + for conv in [False, True]: + if self.needs_conversion(conv, unwrap, Direction.INPUT, parent_const): + conversions.append(StructConversionFunction(self.struct, Direction.INPUT, conv, unwrap)) + if self.needs_conversion(conv, unwrap, Direction.OUTPUT, parent_const): + conversions.append(StructConversionFunction(self.struct, Direction.OUTPUT, conv, unwrap)) return conversions @@ -1992,102 +1998,28 @@ class VkStruct(Sequence): m.set_type_info(type_info) -class ConversionFunction(object): - def __init__(self, variable, direction, conv, unwrap): +class StructConversionFunction(object): + def __init__(self, struct, direction, conv, unwrap): self.direction = direction - self.array = variable.is_static_array() - self.dyn_array = variable.is_dynamic_array() - self.operand = variable.struct if variable.is_struct() else variable.handle - self.type = variable.type + self.operand = struct + self.type = struct.name self.conv = conv self.unwrap = unwrap or not self.operand.needs_unwrapping() - self.needs_alloc = direction != Direction.OUTPUT and variable.needs_alloc(conv, unwrap) - - if variable.is_static_array() and direction == Direction.INPUT: - LOGGER.error("Static array input conversion is not supported") - self._set_name() + name = "convert_{0}_".format(self.type) + win_type = "win32" if self.conv else "win64" + host_part = "host" if self.unwrap else "unwrapped_host" + if self.direction == Direction.INPUT: + name += "{0}_to_{1}".format(win_type, host_part) + else: # Direction.OUTPUT + name += "{0}_to_{1}".format(host_part, win_type) + self.name = name def __eq__(self, other): return self.name == other.name - def _generate_array_conversion_func(self): - """ Helper function for generating a conversion function for array operands. """ - - body = "" - - if self.conv: - body += "#if defined(USE_STRUCT_CONVERSION)\n" - else: - body += "#if !defined(USE_STRUCT_CONVERSION)\n" - - if self.conv and isinstance(self.operand, VkStruct) and self.operand.needs_host_type(): - host_type = "{0}_host".format(self.type) - else: - host_type = self.type - - if self.conv: - if self.direction == Direction.OUTPUT: - params = ["const {0} *in".format(host_type), "{0} *out".format(self.type), "uint32_t count"] - return_type = None - else: - params = ["const {0} *in".format(self.type), "uint32_t count"] - return_type = host_type - else: - params = ["const {0} *in".format(self.type), "uint32_t count"] - return_type = self.type - - # Generate function prototype. - if return_type: - body += "static inline {0} *{1}(".format(return_type, self.name) - else: - body += "static inline void {0}(".format(self.name) - if self.needs_alloc: - body += "struct conversion_context *ctx, " - body += ", ".join(p for p in params) - body += ")\n{\n" - - if return_type: - body += " {0} *out;\n".format(return_type) - - body += " unsigned int i;\n\n" - - if return_type: - body += " if (!in || !count) return NULL;\n\n" - else: - body += " if (!in) return;\n\n" - - if self.direction == Direction.INPUT: - body += " out = conversion_context_alloc(ctx, count * sizeof(*out));\n" - - body += " for (i = 0; i < count; i++)\n" - body += " {\n" - - if isinstance(self.operand, VkStruct): - for m in self.operand: - # TODO: support copying of pNext extension structures! - # Luckily though no extension struct at this point needs conversion. - body += " " + m.copy("in[i].", "out[i].", self.direction, self.conv, self.unwrap) - - elif isinstance(self.operand, VkHandle) and self.direction == Direction.INPUT: - body += " out[i] = " + self.operand.driver_handle("in[i]") + ";\n" - else: - LOGGER.warn("Unhandled conversion operand type") - body += " out[i] = in[i];\n" - - body += " }\n" - if return_type: - body += "\n return out;\n" - body += "}\n" - - body += "#endif /* USE_STRUCT_CONVERSION */\n" - - body += "\n" - - return body - - def _generate_conversion_func(self): - """ Helper function for generating a conversion function for non-array operands. """ + def definition(self): + """ Helper function for generating a struct conversion function. """ # It doesn't make sense to generate conversion functions for non-struct variables # which aren't in arrays, as this should be handled by the copy() function @@ -2101,6 +2033,8 @@ class ConversionFunction(object): else: body += "#if !defined(USE_STRUCT_CONVERSION)\n" + needs_alloc = self.direction != Direction.OUTPUT and self.operand.needs_alloc(self.conv, self.unwrap) + if self.conv: body += "static inline void {0}(".format(self.name) @@ -2110,7 +2044,7 @@ class ConversionFunction(object): params = ["const {0} *in".format(self.type), "{0}_host *out".format(self.type)] # Generate parameter list - if self.needs_alloc: + if needs_alloc: body += "struct conversion_context *ctx, " body += ", ".join(p for p in params) body += ")\n" @@ -2121,7 +2055,7 @@ class ConversionFunction(object): params = ["const {0} *in".format(self.type), "{0} *out".format(self.type)] # Generate parameter list - if self.needs_alloc: + if needs_alloc: body += "struct conversion_context *ctx, " body += ", ".join(p for p in params) body += ")\n" @@ -2148,9 +2082,6 @@ class ConversionFunction(object): def _set_name(self): name = "convert_{0}_".format(self.type) - if self.array or self.dyn_array: - name += "array_" - win_type = "win32" if self.conv else "win64" host_part = "host" if self.unwrap else "unwrapped_host" if self.direction == Direction.INPUT: @@ -2160,11 +2091,108 @@ class ConversionFunction(object): self.name = name + +class ArrayConversionFunction(object): + def __init__(self, array, direction, conv, unwrap): + self.array = array + self.direction = direction + self.operand = array.struct if array.is_struct() else array.handle + self.type = array.type + self.conv = conv + self.unwrap = unwrap or not array.needs_unwrapping() + + if array.is_static_array() and direction == Direction.INPUT: + LOGGER.error("Static array input conversion is not supported") + + name = "convert_{0}_array_".format(array.type) + win_type = "win32" if self.conv else "win64" + host_part = "host" if self.unwrap else "unwrapped_host" + if self.direction == Direction.INPUT: + name += "{0}_to_{1}".format(win_type, host_part) + else: # Direction.OUTPUT + name += "{0}_to_{1}".format(host_part, win_type) + self.name = name + + def __eq__(self, other): + return self.name == other.name + def definition(self): - if self.array or self.dyn_array: - return self._generate_array_conversion_func() + """ Helper function for generating a conversion function for array operands. """ + + body = "" + + if self.conv: + body += "#if defined(USE_STRUCT_CONVERSION)\n" + else: + body += "#if !defined(USE_STRUCT_CONVERSION)\n" + + needs_alloc = self.direction != Direction.OUTPUT and self.array.needs_alloc(self.conv, self.unwrap) + + if self.conv and self.array.is_struct() and self.array.struct.needs_host_type(): + host_type = "{0}_host".format(self.type) + else: + host_type = self.type + + if self.conv: + if self.direction == Direction.OUTPUT: + params = ["const {0} *in".format(host_type), "{0} *out".format(self.type), "uint32_t count"] + return_type = None + else: + params = ["const {0} *in".format(self.type), "uint32_t count"] + return_type = host_type + else: + params = ["const {0} *in".format(self.type), "uint32_t count"] + return_type = self.type + + # Generate function prototype. + if return_type: + body += "static inline {0} *{1}(".format(return_type, self.name) + else: + body += "static inline void {0}(".format(self.name) + if needs_alloc: + body += "struct conversion_context *ctx, " + body += ", ".join(p for p in params) + body += ")\n{\n" + + if return_type: + body += " {0} *out;\n".format(return_type) + + body += " unsigned int i;\n\n" + + if return_type: + body += " if (!in || !count) return NULL;\n\n" + else: + body += " if (!in) return;\n\n" + + if self.direction == Direction.INPUT: + body += " out = conversion_context_alloc(ctx, count * sizeof(*out));\n" + + body += " for (i = 0; i < count; i++)\n" + body += " {\n" + + if self.array.is_struct(): + for m in self.array.struct: + # TODO: support copying of pNext extension structures! + # Luckily though no extension struct at this point needs conversion. + body += " " + m.copy("in[i].", "out[i].", self.direction, self.conv, self.unwrap) + + elif self.array.is_handle() and self.direction == Direction.INPUT: + body += " out[i] = " + self.array.handle.driver_handle("in[i]") + ";\n" else: - return self._generate_conversion_func() + LOGGER.warning("Unhandled conversion operand type") + body += " out[i] = in[i];\n" + + body += " }\n" + if return_type: + body += "\n return out;\n" + body += "}\n" + + body += "#endif /* USE_STRUCT_CONVERSION */\n" + + body += "\n" + + return body + class StructChainConversionFunction(object): def __init__(self, direction, struct, ignores):