Skip to content
Snippets Groups Projects
Commit a242422e authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard
Browse files

winevulkan: Use separated classes for struct and array conversions.

parent 0bfad658
No related branches found
No related tags found
No related merge requests found
......@@ -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):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment