winevulkan: Add support for unwrapping handles in thunks.
Signed-off-by: Derek Lesho <dlesho@codeweavers.com> Signed-off-by: Georg Lehmann <dadschoorse@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
45a48b5a84
commit
fb8ab5e9d0
|
@ -204,14 +204,14 @@ FUNCTION_OVERRIDES = {
|
|||
|
||||
# VK_KHR_get_surface_capabilities2
|
||||
"vkGetPhysicalDeviceSurfaceCapabilities2KHR" : {"dispatch" : True, "driver" : True, "thunk" : ThunkType.PRIVATE},
|
||||
"vkGetPhysicalDeviceSurfaceFormats2KHR" : {"dispatch" : True, "driver" : True, "thunk" : ThunkType.PRIVATE},
|
||||
"vkGetPhysicalDeviceSurfaceFormats2KHR" : {"dispatch" : True, "driver" : True, "thunk" : ThunkType.PUBLIC},
|
||||
|
||||
# VK_KHR_win32_surface
|
||||
"vkCreateWin32SurfaceKHR" : {"dispatch" : True, "driver" : True, "thunk" : ThunkType.NONE},
|
||||
"vkGetPhysicalDeviceWin32PresentationSupportKHR" : {"dispatch" : True, "driver" : True, "thunk" : ThunkType.PUBLIC},
|
||||
|
||||
# VK_KHR_swapchain
|
||||
"vkCreateSwapchainKHR" : {"dispatch" : True, "driver" : True, "thunk" : ThunkType.PRIVATE},
|
||||
"vkCreateSwapchainKHR" : {"dispatch" : True, "driver" : True, "thunk" : ThunkType.PUBLIC},
|
||||
"vkDestroySwapchainKHR" : {"dispatch" : True, "driver" : True, "thunk" : ThunkType.PUBLIC},
|
||||
"vkGetSwapchainImagesKHR": {"dispatch" : True, "driver" : True, "thunk" : ThunkType.PUBLIC},
|
||||
"vkQueuePresentKHR": {"dispatch" : True, "driver" : True, "thunk" : ThunkType.PUBLIC},
|
||||
|
@ -645,6 +645,18 @@ class VkFunction(object):
|
|||
|
||||
return False
|
||||
|
||||
def needs_unwrapping(self):
|
||||
""" Check if the function needs any input/output type unwrapping.
|
||||
Functions need input/output unwrapping if struct parameters have
|
||||
wrapped handles.
|
||||
"""
|
||||
|
||||
for p in self.params:
|
||||
if p.needs_unwrapping():
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def needs_dispatch(self):
|
||||
return self.dispatch
|
||||
|
||||
|
@ -739,7 +751,7 @@ class VkFunction(object):
|
|||
|
||||
return body
|
||||
|
||||
def body_conversion(self):
|
||||
def body_conversion(self, conv):
|
||||
body = ""
|
||||
|
||||
# Declare a variable to hold the result for non-void functions.
|
||||
|
@ -748,27 +760,28 @@ class VkFunction(object):
|
|||
|
||||
# Declare any tmp parameters for conversion.
|
||||
for p in self.params:
|
||||
if not p.needs_conversion():
|
||||
continue
|
||||
|
||||
if p.is_dynamic_array():
|
||||
body += " {0}_host *{1}_host;\n".format(p.type, p.name)
|
||||
else:
|
||||
body += " {0}_host {1}_host;\n".format(p.type, p.name)
|
||||
if p.needs_conversion() and conv:
|
||||
if p.is_dynamic_array():
|
||||
body += " {0}_host *{1}_host;\n".format(p.type, p.name)
|
||||
else:
|
||||
body += " {0}_host {1}_host;\n".format(p.type, p.name)
|
||||
elif p.needs_unwrapping():
|
||||
if p.is_dynamic_array():
|
||||
body += " {0} *{1}_host;\n".format(p.type, p.name)
|
||||
else:
|
||||
body += " {0} {1}_host;\n".format(p.type, p.name)
|
||||
|
||||
if not self.needs_private_thunk():
|
||||
body += " {0}\n".format(self.trace())
|
||||
|
||||
# Call any win_to_host conversion calls.
|
||||
for p in self.params:
|
||||
if not p.needs_input_conversion():
|
||||
continue
|
||||
|
||||
body += p.copy(Direction.INPUT)
|
||||
if p.needs_input_conversion() and (p.needs_unwrapping() or conv):
|
||||
body += p.copy(Direction.INPUT)
|
||||
|
||||
# Build list of parameters containing converted and non-converted parameters.
|
||||
# The param itself knows if conversion is needed and applies it when we set conv=True.
|
||||
params = ", ".join([p.variable(conv=True) for p in self.params])
|
||||
params = ", ".join([p.variable(conv=conv) for p in self.params])
|
||||
|
||||
# Call the native Vulkan function.
|
||||
if self.type == "void":
|
||||
|
@ -787,10 +800,8 @@ class VkFunction(object):
|
|||
|
||||
# Perform any required cleanups. Most of these are for array functions.
|
||||
for p in self.params:
|
||||
if not p.needs_free():
|
||||
continue
|
||||
|
||||
body += p.free()
|
||||
if p.needs_free() and (p.needs_unwrapping() or conv):
|
||||
body += p.free()
|
||||
|
||||
# Finally return the result.
|
||||
if self.type != "void":
|
||||
|
@ -840,10 +851,15 @@ class VkFunction(object):
|
|||
|
||||
if self.needs_conversion():
|
||||
thunk += "#if defined(USE_STRUCT_CONVERSION)\n"
|
||||
thunk += self.body_conversion()
|
||||
thunk += self.body_conversion(conv=True)
|
||||
thunk += "#else\n"
|
||||
thunk += self.body()
|
||||
if self.needs_unwrapping():
|
||||
thunk += self.body_conversion(conv=False)
|
||||
else:
|
||||
thunk += self.body()
|
||||
thunk += "#endif\n"
|
||||
elif self.needs_unwrapping():
|
||||
thunk += self.body_conversion(conv=False)
|
||||
else:
|
||||
thunk += self.body()
|
||||
|
||||
|
@ -1063,6 +1079,12 @@ class VkHandle(object):
|
|||
def is_wrapped(self):
|
||||
return self.native_handle("test") is not None
|
||||
|
||||
def needs_conversion(self):
|
||||
return False
|
||||
|
||||
def needs_unwrapping(self):
|
||||
return self.is_wrapped()
|
||||
|
||||
class VkMember(object):
|
||||
def __init__(self, const=False, struct_fwd_decl=False,_type=None, pointer=None, name=None, array_len=None,
|
||||
dyn_array_len=None, optional=False, values=None):
|
||||
|
@ -1148,10 +1170,11 @@ class VkMember(object):
|
|||
return VkMember(const=const, struct_fwd_decl=struct_fwd_decl, _type=member_type, pointer=pointer, name=name_elem.text,
|
||||
array_len=array_len, dyn_array_len=dyn_array_len, optional=optional, values=values)
|
||||
|
||||
def copy(self, input, output, direction):
|
||||
""" Helper method for use by conversion logic to generate a C-code statement to copy this member. """
|
||||
def copy(self, input, output, direction, conv):
|
||||
""" Helper method for use by conversion logic to generate a C-code statement to copy this member.
|
||||
- `conv` indicates whether the statement is in a struct alignment conversion path. """
|
||||
|
||||
if self.needs_conversion():
|
||||
if (conv and self.needs_conversion()) or self.needs_unwrapping():
|
||||
if self.is_dynamic_array():
|
||||
if direction == Direction.OUTPUT:
|
||||
LOGGER.warn("TODO: implement copying of returnedonly dynamic array for {0}.{1}".format(self.type, self.name))
|
||||
|
@ -1167,6 +1190,12 @@ class VkMember(object):
|
|||
else:
|
||||
# Nothing needed this yet.
|
||||
LOGGER.warn("TODO: implement copying of static array for {0}.{1}".format(self.type, self.name))
|
||||
elif self.is_handle() and self.needs_unwrapping():
|
||||
if direction == Direction.OUTPUT:
|
||||
LOGGER.err("OUTPUT parameter {0}.{1} cannot be unwrapped".format(self.type, self.name))
|
||||
else:
|
||||
handle = self.type_info["data"]
|
||||
return "{0}{1} = {2};\n".format(output, self.name, handle.driver_handle("{0}{1}".format(input, self.name)))
|
||||
else:
|
||||
if direction == Direction.OUTPUT:
|
||||
return "convert_{0}_host_to_win(&{2}{1}, &{3}{1});\n".format(self.type, self.name, input, output)
|
||||
|
@ -1178,6 +1207,36 @@ class VkMember(object):
|
|||
else:
|
||||
return "{0}{1} = {2}{1};\n".format(output, self.name, input)
|
||||
|
||||
def free(self, location, conv):
|
||||
""" Helper method for use by conversion logic to generate a C-code statement to free this member. """
|
||||
|
||||
if not self.needs_unwrapping() and not conv:
|
||||
return ""
|
||||
|
||||
# Add a cast to ignore const on conversion structs we allocated ourselves.
|
||||
# sample expected output: (VkSparseMemoryBind_host *)
|
||||
if self.is_const():
|
||||
cast = "(" + self.type
|
||||
if self.needs_conversion() and conv:
|
||||
cast += "_host"
|
||||
cast += " *)"
|
||||
else:
|
||||
cast = ""
|
||||
|
||||
if self.is_dynamic_array():
|
||||
count = self.dyn_array_len if isinstance(self.dyn_array_len, int) else "{0}{1}".format(location, self.dyn_array_len)
|
||||
if self.is_struct() and self.type_info["data"].returnedonly:
|
||||
# For returnedonly, counts is stored in a pointer.
|
||||
return "free_{0}_array({1}{2}{3}, *{4});\n".format(self.type, cast, location, self.name, count)
|
||||
else:
|
||||
return "free_{0}_array({1}{2}{3}, {4});\n".format(self.type, cast, location, self.name, count)
|
||||
else:
|
||||
# We are operating on a single structure. Some structs (very rare) contain dynamic members,
|
||||
# which would need freeing.
|
||||
if self.needs_free():
|
||||
return "free_{0}({1}&{2}{3});\n".format(self.type, cast, location, self.name)
|
||||
return ""
|
||||
|
||||
def definition(self, align=False, conv=False):
|
||||
""" Generate prototype for given function.
|
||||
|
||||
|
@ -1216,31 +1275,34 @@ class VkMember(object):
|
|||
|
||||
# Check if we need conversion either for this member itself or for any child members
|
||||
# in case member represents a struct.
|
||||
if not self.needs_conversion():
|
||||
if not self.needs_conversion() and not self.needs_unwrapping():
|
||||
return None
|
||||
|
||||
conversions = []
|
||||
|
||||
# Collect any conversion for any member structs.
|
||||
struct = self.type_info["data"]
|
||||
for m in struct:
|
||||
m.needs_struct_extensions_conversion()
|
||||
if m.needs_conversion():
|
||||
conversions.extend(m.get_conversions())
|
||||
if self.is_struct():
|
||||
struct = self.type_info["data"]
|
||||
for m in struct:
|
||||
m.needs_struct_extensions_conversion()
|
||||
if m.needs_conversion() or m.needs_unwrapping():
|
||||
conversions.extend(m.get_conversions())
|
||||
|
||||
struct.needs_struct_extensions_conversion()
|
||||
struct.needs_struct_extensions_conversion()
|
||||
direction = Direction.OUTPUT if struct.returnedonly else Direction.INPUT
|
||||
elif self.is_handle():
|
||||
direction = Direction.INPUT
|
||||
|
||||
struct = self.type_info["data"]
|
||||
direction = Direction.OUTPUT if struct.returnedonly else Direction.INPUT
|
||||
operand = self.type_info["data"]
|
||||
if self.is_dynamic_array():
|
||||
conversions.append(ConversionFunction(False, True, direction, struct))
|
||||
conversions.append(ConversionFunction(False, True, direction, operand))
|
||||
elif self.is_static_array():
|
||||
conversions.append(ConversionFunction(True, False, direction, struct))
|
||||
conversions.append(ConversionFunction(True, False, direction, operand))
|
||||
else:
|
||||
conversions.append(ConversionFunction(False, False, direction, struct))
|
||||
conversions.append(ConversionFunction(False, False, direction, operand))
|
||||
|
||||
if self.needs_free():
|
||||
conversions.append(FreeFunction(self.is_dynamic_array(), struct))
|
||||
conversions.append(FreeFunction(self.is_dynamic_array(), operand))
|
||||
|
||||
return conversions
|
||||
|
||||
|
@ -1307,8 +1369,21 @@ class VkMember(object):
|
|||
struct = self.type_info["data"]
|
||||
return struct.needs_conversion()
|
||||
|
||||
def needs_unwrapping(self):
|
||||
""" Structures with wrapped handles need unwrapping. """
|
||||
|
||||
if self.is_struct():
|
||||
struct = self.type_info["data"]
|
||||
return struct.needs_unwrapping()
|
||||
|
||||
if self.is_handle():
|
||||
handle = self.type_info["data"]
|
||||
return handle.is_wrapped()
|
||||
|
||||
return False
|
||||
|
||||
def needs_free(self):
|
||||
if not self.needs_conversion():
|
||||
if not self.needs_conversion() and not self.needs_unwrapping():
|
||||
return False
|
||||
|
||||
if self.is_dynamic_array():
|
||||
|
@ -1392,21 +1467,23 @@ class VkParam(object):
|
|||
self.free_func = None
|
||||
self.input_conv = None
|
||||
self.output_conv = None
|
||||
if not self.needs_conversion():
|
||||
if not self.needs_conversion() and not self.needs_unwrapping():
|
||||
return
|
||||
|
||||
operand = self.struct if self.is_struct() else self.handle
|
||||
|
||||
# Input functions require win to host conversion.
|
||||
if self._direction in [Direction.INPUT, Direction.INPUT_OUTPUT]:
|
||||
self.input_conv = ConversionFunction(False, self.is_dynamic_array(), Direction.INPUT, self.struct)
|
||||
self.input_conv = ConversionFunction(False, self.is_dynamic_array(), Direction.INPUT, operand)
|
||||
|
||||
# Output functions require host to win conversion.
|
||||
if self._direction in [Direction.INPUT_OUTPUT, Direction.OUTPUT]:
|
||||
self.output_conv = ConversionFunction(False, self.is_dynamic_array(), Direction.OUTPUT, self.struct)
|
||||
self.output_conv = ConversionFunction(False, self.is_dynamic_array(), Direction.OUTPUT, operand)
|
||||
|
||||
# Dynamic arrays, but also some normal structs (e.g. VkCommandBufferBeginInfo) need memory
|
||||
# allocation and thus some cleanup.
|
||||
if self.is_dynamic_array() or self.struct.needs_free():
|
||||
self.free_func = FreeFunction(self.is_dynamic_array(), self.struct)
|
||||
self.free_func = FreeFunction(self.is_dynamic_array(), operand)
|
||||
|
||||
def _set_direction(self):
|
||||
""" Internal helper function to set parameter direction (input/output/input_output). """
|
||||
|
@ -1544,7 +1621,7 @@ class VkParam(object):
|
|||
|
||||
def free(self):
|
||||
if self.is_dynamic_array():
|
||||
if self.struct.returnedonly:
|
||||
if self.is_struct() and self.struct.returnedonly:
|
||||
# For returnedonly, counts is stored in a pointer.
|
||||
return " free_{0}_array({1}_host, *{2});\n".format(self.type, self.name, self.dyn_array_len)
|
||||
else:
|
||||
|
@ -1552,7 +1629,7 @@ class VkParam(object):
|
|||
else:
|
||||
# We are operating on a single structure. Some structs (very rare) contain dynamic members,
|
||||
# which would need freeing.
|
||||
if self.struct.needs_free():
|
||||
if self.is_struct() and self.struct.needs_free():
|
||||
return " free_{0}(&{1}_host);\n".format(self.type, self.name)
|
||||
return ""
|
||||
|
||||
|
@ -1563,14 +1640,14 @@ class VkParam(object):
|
|||
required.
|
||||
"""
|
||||
|
||||
if not self.is_struct():
|
||||
if self.is_struct():
|
||||
self.struct.needs_struct_extensions_conversion()
|
||||
for m in self.struct:
|
||||
m.needs_struct_extensions_conversion()
|
||||
elif not self.is_handle():
|
||||
return None
|
||||
|
||||
self.struct.needs_struct_extensions_conversion()
|
||||
for m in self.struct:
|
||||
m.needs_struct_extensions_conversion()
|
||||
|
||||
if not self.needs_conversion():
|
||||
if not self.needs_conversion() and not self.needs_unwrapping():
|
||||
return None
|
||||
|
||||
conversions = []
|
||||
|
@ -1578,14 +1655,15 @@ class VkParam(object):
|
|||
# Collect any member conversions first, so we can guarantee
|
||||
# those functions will be defined prior to usage by the
|
||||
# 'parent' param requiring conversion.
|
||||
for m in self.struct:
|
||||
if not m.is_struct():
|
||||
continue
|
||||
if self.is_struct():
|
||||
for m in self.struct:
|
||||
if not m.is_struct():
|
||||
continue
|
||||
|
||||
if not m.needs_conversion():
|
||||
continue
|
||||
if not m.needs_conversion() and not m.needs_unwrapping():
|
||||
continue
|
||||
|
||||
conversions.extend(m.get_conversions())
|
||||
conversions.extend(m.get_conversions())
|
||||
|
||||
# Conversion requirements for the 'parent' parameter.
|
||||
if self.input_conv is not None:
|
||||
|
@ -1641,6 +1719,18 @@ class VkParam(object):
|
|||
|
||||
return False
|
||||
|
||||
def needs_unwrapping(self):
|
||||
""" Returns if parameter needs unwrapping of handle. """
|
||||
|
||||
# Wrapped handle parameters are handled seperately, only look for wrapped handles in structs
|
||||
if self.is_struct():
|
||||
return self.struct.needs_unwrapping()
|
||||
|
||||
if self.is_handle() and self.is_dynamic_array():
|
||||
return self.handle.needs_unwrapping()
|
||||
|
||||
return False
|
||||
|
||||
def needs_free(self):
|
||||
return self.free_func is not None
|
||||
|
||||
|
@ -1691,7 +1781,7 @@ class VkParam(object):
|
|||
LOGGER.debug("TODO: setting NULL VkAllocationCallbacks for {0}".format(self.name))
|
||||
return "NULL"
|
||||
|
||||
if conv and self.needs_conversion():
|
||||
if self.needs_unwrapping() or (conv and self.needs_conversion()):
|
||||
if self.is_dynamic_array():
|
||||
return "{0}_host".format(self.name)
|
||||
else:
|
||||
|
@ -1880,6 +1970,14 @@ class VkStruct(Sequence):
|
|||
return True
|
||||
return False
|
||||
|
||||
def needs_unwrapping(self):
|
||||
""" Returns if struct members need unwrapping of handle. """
|
||||
|
||||
for m in self.members:
|
||||
if m.needs_unwrapping():
|
||||
return True
|
||||
return False
|
||||
|
||||
def needs_free(self):
|
||||
""" Check if any struct member needs some memory freeing."""
|
||||
|
||||
|
@ -1897,7 +1995,10 @@ class VkStruct(Sequence):
|
|||
|
||||
for e in self.struct_extensions:
|
||||
if e.required and e.needs_conversion():
|
||||
LOGGER.error("Unhandled pNext chain conversion for {0}".format(e.name))
|
||||
LOGGER.error("Unhandled pNext chain alignment conversion for {0}".format(e.name))
|
||||
ret = True
|
||||
if e.required and e.needs_unwrapping():
|
||||
LOGGER.error("Unhandled pNext chain unwrapping conversion for {0}".format(e.name))
|
||||
ret = True
|
||||
|
||||
return ret
|
||||
|
@ -1913,12 +2014,12 @@ class VkStruct(Sequence):
|
|||
|
||||
|
||||
class ConversionFunction(object):
|
||||
def __init__(self, array, dyn_array, direction, struct):
|
||||
def __init__(self, array, dyn_array, direction, operand):
|
||||
self.array = array
|
||||
self.direction = direction
|
||||
self.dyn_array = dyn_array
|
||||
self.struct = struct
|
||||
self.type = struct.name
|
||||
self.operand = operand
|
||||
self.type = operand.name
|
||||
|
||||
self._set_name()
|
||||
|
||||
|
@ -1926,21 +2027,44 @@ class ConversionFunction(object):
|
|||
return self.name == other.name
|
||||
|
||||
def _generate_array_conversion_func(self):
|
||||
""" Helper function for generating a conversion function for array structs. """
|
||||
""" Helper function for generating a conversion function for array operands. """
|
||||
|
||||
body = ""
|
||||
|
||||
if self.operand.needs_conversion():
|
||||
body += "#if defined(USE_STRUCT_CONVERSION)\n"
|
||||
|
||||
if self.direction == Direction.OUTPUT:
|
||||
params = ["const {0}_host *in".format(self.type), "uint32_t count"]
|
||||
return_type = self.type
|
||||
else:
|
||||
params = ["const {0} *in".format(self.type), "uint32_t count"]
|
||||
return_type = "{0}_host".format(self.type)
|
||||
|
||||
# Generate function prototype.
|
||||
body += "static inline {0} *{1}(".format(return_type, self.name)
|
||||
body += ", ".join(p for p in params)
|
||||
body += ")\n{\n"
|
||||
|
||||
body += " {0} *out;\n".format(return_type)
|
||||
|
||||
if self.operand.needs_unwrapping():
|
||||
if self.operand.needs_conversion():
|
||||
body += "#else\n"
|
||||
|
||||
if self.direction == Direction.OUTPUT:
|
||||
params = ["const {0}_host *in".format(self.type), "uint32_t count"]
|
||||
return_type = self.type
|
||||
else:
|
||||
params = ["const {0} *in".format(self.type), "uint32_t count"]
|
||||
return_type = "{0}_host".format(self.type)
|
||||
return_type = "{0}".format(self.type)
|
||||
|
||||
# Generate function prototype.
|
||||
body = "static inline {0} *{1}(".format(return_type, self.name)
|
||||
body += ", ".join(p for p in params)
|
||||
body += ")\n{\n"
|
||||
# Generate function prototype.
|
||||
body += "static inline {0} *{1}(".format(return_type, self.name)
|
||||
body += ", ".join(p for p in params)
|
||||
body += ")\n{\n"
|
||||
|
||||
body += " {0} *out;\n".format(return_type)
|
||||
|
||||
if self.operand.needs_conversion():
|
||||
body += "#endif /* USE_STRUCT_CONVERSION */\n"
|
||||
|
||||
body += " {0} *out;\n".format(return_type)
|
||||
body += " unsigned int i;\n\n"
|
||||
body += " if (!in) return NULL;\n\n"
|
||||
|
||||
|
@ -1949,33 +2073,82 @@ class ConversionFunction(object):
|
|||
body += " for (i = 0; i < count; i++)\n"
|
||||
body += " {\n"
|
||||
|
||||
for m in self.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)
|
||||
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.
|
||||
convert = m.copy("in[i].", "out[i].", self.direction, conv=True)
|
||||
if self.operand.needs_conversion() and not self.operand.needs_unwrapping():
|
||||
body += " " + convert
|
||||
else:
|
||||
unwrap = m.copy("in[i].", "out[i].", self.direction, conv=False)
|
||||
if unwrap == convert:
|
||||
body += " " + unwrap
|
||||
else:
|
||||
body += "#if defined(USE_STRUCT_CONVERSION)\n"
|
||||
body += " " + convert
|
||||
body += "#else\n"
|
||||
body += " " + unwrap
|
||||
body += "#endif /* USE_STRUCT_CONVERSION */\n"
|
||||
|
||||
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\n"
|
||||
body += " return out;\n"
|
||||
body += "}\n\n"
|
||||
body += "}\n"
|
||||
|
||||
if not self.operand.needs_unwrapping():
|
||||
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 structs. """
|
||||
""" Helper function for generating a conversion function for non-array operands. """
|
||||
|
||||
if self.direction == Direction.OUTPUT:
|
||||
params = ["const {0}_host *in".format(self.type), "{0} *out".format(self.type)]
|
||||
else:
|
||||
params = ["const {0} *in".format(self.type), "{0}_host *out".format(self.type)]
|
||||
# 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
|
||||
if not isinstance(self.operand, VkStruct):
|
||||
return ""
|
||||
|
||||
body = "static inline void {0}(".format(self.name)
|
||||
body = ""
|
||||
|
||||
# Generate parameter list
|
||||
body += ", ".join(p for p in params)
|
||||
body += ")\n{\n"
|
||||
if self.operand.needs_conversion():
|
||||
body += "#if defined(USE_STRUCT_CONVERSION)\n"
|
||||
body += "static inline void {0}(".format(self.name)
|
||||
|
||||
body += " if (!in) return;\n\n"
|
||||
if self.direction == Direction.OUTPUT:
|
||||
params = ["const {0}_host *in".format(self.type), "{0} *out".format(self.type)]
|
||||
else:
|
||||
params = ["const {0} *in".format(self.type), "{0}_host *out".format(self.type)]
|
||||
|
||||
if self.direction == Direction.INPUT and "pNext" in self.struct and self.struct.returnedonly:
|
||||
# Generate parameter list
|
||||
body += ", ".join(p for p in params)
|
||||
body += ")\n"
|
||||
|
||||
if self.operand.needs_unwrapping():
|
||||
if self.operand.needs_conversion():
|
||||
body += "#else\n"
|
||||
|
||||
body += "static inline void {0}(".format(self.name)
|
||||
|
||||
params = ["const {0} *in".format(self.type), "{0} *out".format(self.type)]
|
||||
|
||||
# Generate parameter list
|
||||
body += ", ".join(p for p in params)
|
||||
body += ")\n"
|
||||
|
||||
if self.operand.needs_conversion():
|
||||
body += "#endif /* USE_STRUCT_CONVERSION */\n"
|
||||
|
||||
body += "{\n if (!in) return;\n\n"
|
||||
|
||||
if self.direction == Direction.INPUT and "pNext" in self.operand and self.operand.returnedonly:
|
||||
# We are dealing with an input_output parameter. For these we only need to copy
|
||||
# pNext and sType as the other fields are filled in by the host. We do potentially
|
||||
# have to iterate over pNext and perform conversions based on switch(sType)!
|
||||
|
@ -1984,36 +2157,96 @@ class ConversionFunction(object):
|
|||
body += " out->pNext = in->pNext;\n"
|
||||
body += " out->sType = in->sType;\n"
|
||||
else:
|
||||
for m in self.struct:
|
||||
for m in self.operand:
|
||||
# TODO: support copying of pNext extension structures!
|
||||
body += " " + m.copy("in->", "out->", self.direction)
|
||||
convert = m.copy("in->", "out->", self.direction, conv=True)
|
||||
if self.operand.needs_conversion() and not self.operand.needs_unwrapping():
|
||||
body += " " + convert
|
||||
else:
|
||||
unwrap = m.copy("in->", "out->", self.direction, conv=False)
|
||||
if unwrap == convert:
|
||||
body += " " + unwrap
|
||||
else:
|
||||
body += "#if defined(USE_STRUCT_CONVERSION)\n"
|
||||
body += " " + convert
|
||||
body += "#else\n"
|
||||
body += " " + unwrap
|
||||
body += "#endif /* USE_STRUCT_CONVERSION */\n"
|
||||
|
||||
body += "}\n"
|
||||
|
||||
if not self.operand.needs_unwrapping():
|
||||
body += "#endif /* USE_STRUCT_CONVERSION */\n"
|
||||
|
||||
body += "\n"
|
||||
|
||||
body += "}\n\n"
|
||||
return body
|
||||
|
||||
def _generate_static_array_conversion_func(self):
|
||||
""" Helper function for generating a conversion function for array structs. """
|
||||
""" Helper function for generating a conversion function for array operands. """
|
||||
|
||||
if self.direction == Direction.OUTPUT:
|
||||
params = ["const {0}_host *in".format(self.type), "{0} *out".format(self.type), "uint32_t count"]
|
||||
else:
|
||||
params = ["const {0} *in".format(self.type), "{0} *out_host".format(self.type), "uint32_t count"]
|
||||
body = ""
|
||||
|
||||
# Generate function prototype.
|
||||
body = "static inline void {0}(".format(self.name)
|
||||
body += ", ".join(p for p in params)
|
||||
body += ")\n{\n"
|
||||
if self.operand.needs_conversion():
|
||||
body += "#if defined(USE_STRUCT_CONVERSION)\n"
|
||||
|
||||
if self.direction == Direction.OUTPUT:
|
||||
params = ["const {0}_host *in".format(self.type), "{0} *out".format(self.type), "uint32_t count"]
|
||||
else:
|
||||
params = ["const {0} *in".format(self.type), "{0} *out_host".format(self.type), "uint32_t count"]
|
||||
|
||||
# Generate function prototype.
|
||||
body += "static inline void {0}(".format(self.name)
|
||||
body += ", ".join(p for p in params)
|
||||
body += ")\n"
|
||||
|
||||
if self.operand.needs_unwrapping():
|
||||
if self.operand.needs_conversion():
|
||||
body += "#else\n"
|
||||
|
||||
params = ["const {0} *in".format(self.type), "{0} *out".format(self.type), "uint32_t count"]
|
||||
|
||||
# Generate function prototype.
|
||||
body += "static inline void {0}(".format(self.name)
|
||||
body += ", ".join(p for p in params)
|
||||
body += ")\n"
|
||||
|
||||
body += "{\n"
|
||||
body += " unsigned int i;\n\n"
|
||||
body += " if (!in) return;\n\n"
|
||||
body += " for (i = 0; i < count; i++)\n"
|
||||
body += " {\n"
|
||||
|
||||
for m in self.struct:
|
||||
# TODO: support copying of pNext extension structures!
|
||||
body += " " + m.copy("in[i].", "out[i].", self.direction)
|
||||
if isinstance(self.operand, VkStruct):
|
||||
for m in self.operand:
|
||||
# TODO: support copying of pNext extension structures!
|
||||
convert = m.copy("in[i].", "out[i].", self.direction, conv=True)
|
||||
if self.operand.needs_conversion() and not self.operand.needs_unwrapping():
|
||||
body += " " + convert
|
||||
else:
|
||||
unwrap = m.copy("in[i].", "out[i].", self.direction, conv=False)
|
||||
if unwrap == convert:
|
||||
body += " " + unwrap
|
||||
else:
|
||||
body += "#if defined(USE_STRUCT_CONVERSION)\n"
|
||||
body += " " + convert
|
||||
body += "#else\n"
|
||||
body += " " + unwrap
|
||||
body += "#endif /* USE_STRUCT_CONVERSION */\n"
|
||||
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"
|
||||
body += "}\n\n"
|
||||
body += "}\n"
|
||||
|
||||
if not self.operand.needs_unwrapping():
|
||||
body += "#endif /* USE_STRUCT_CONVERSION) */\n"
|
||||
|
||||
body += "\n"
|
||||
|
||||
return body
|
||||
|
||||
def _set_name(self):
|
||||
|
@ -2044,10 +2277,10 @@ class ConversionFunction(object):
|
|||
|
||||
|
||||
class FreeFunction(object):
|
||||
def __init__(self, dyn_array, struct):
|
||||
def __init__(self, dyn_array, operand):
|
||||
self.dyn_array = dyn_array
|
||||
self.struct = struct
|
||||
self.type = struct.name
|
||||
self.operand = operand
|
||||
self.type = operand.name
|
||||
|
||||
if dyn_array:
|
||||
self.name = "free_{0}_array".format(self.type)
|
||||
|
@ -2060,52 +2293,120 @@ class FreeFunction(object):
|
|||
def _generate_array_free_func(self):
|
||||
""" Helper function for cleaning up temporary buffers required for array conversions. """
|
||||
|
||||
# Generate function prototype.
|
||||
body = "static inline void {0}({1}_host *in, uint32_t count)\n{{\n".format(self.name, self.type)
|
||||
body = ""
|
||||
|
||||
if self.operand.needs_conversion():
|
||||
body += "#if defined(USE_STRUCT_CONVERSION)\n"
|
||||
# Generate function prototype.
|
||||
body += "static inline void {0}({1}_host *in, uint32_t count)\n".format(self.name, self.type)
|
||||
|
||||
if self.operand.needs_unwrapping():
|
||||
if self.operand.needs_conversion():
|
||||
body += "#else\n"
|
||||
|
||||
# Generate function prototype.
|
||||
body += "static inline void {0}({1} *in, uint32_t count)\n".format(self.name, self.type)
|
||||
|
||||
if self.operand.needs_conversion():
|
||||
body += "#endif /* USE_STRUCT_CONVERSION */\n"
|
||||
|
||||
body += "{\n"
|
||||
|
||||
# E.g. VkGraphicsPipelineCreateInfo_host needs freeing for pStages.
|
||||
if self.struct.needs_free():
|
||||
if isinstance(self.operand, VkStruct) and self.operand.needs_free():
|
||||
body += " unsigned int i;\n\n"
|
||||
body += " if (!in) return;\n\n"
|
||||
body += " for (i = 0; i < count; i++)\n"
|
||||
body += " {\n"
|
||||
|
||||
for m in self.struct:
|
||||
if m.needs_conversion() and m.is_dynamic_array():
|
||||
if m.is_const():
|
||||
# Add a cast to ignore const on conversion structs we allocated ourselves.
|
||||
body += " free_{0}_array(({0}_host *)in[i].{1}, in[i].{2});\n".format(m.type, m.name, m.dyn_array_len)
|
||||
for m in self.operand:
|
||||
if m.needs_free():
|
||||
convert = m.free("in[i].", conv=True)
|
||||
if self.operand.needs_conversion() and not self.operand.needs_unwrapping():
|
||||
body += " " + convert
|
||||
else:
|
||||
body += " free_{0}_array(in[i].{1}, in[i].{2});\n".format(m.type, m.name, m.dyn_array_len)
|
||||
elif m.needs_conversion():
|
||||
LOGGER.error("Unhandled conversion for {0}".format(m.name))
|
||||
unwrap = m.free("in[i].", conv=False)
|
||||
if convert == unwrap:
|
||||
body += " " + unwrap
|
||||
elif unwrap == "":
|
||||
body += "#if defined(USE_STRUCT_CONVERSION)\n"
|
||||
body += " " + convert
|
||||
body += "#endif /* USE_STRUCT_CONVERSION */\n"
|
||||
else:
|
||||
body += "#if defined(USE_STRUCT_CONVERSION)\n"
|
||||
body += " " + convert
|
||||
body += "#else\n"
|
||||
body += " " + unwrap
|
||||
body += "#endif /* USE_STRUCT_CONVERSION */\n"
|
||||
body += " }\n"
|
||||
else:
|
||||
body += " if (!in) return;\n\n"
|
||||
|
||||
body += " free(in);\n"
|
||||
|
||||
body += "}\n\n"
|
||||
body += "}\n"
|
||||
|
||||
if not self.operand.needs_unwrapping():
|
||||
body += "#endif /* USE_STRUCT_CONVERSION */\n"
|
||||
|
||||
body += "\n"
|
||||
|
||||
return body
|
||||
|
||||
def _generate_free_func(self):
|
||||
# E.g. VkCommandBufferBeginInfo.pInheritanceInfo needs freeing.
|
||||
if not self.struct.needs_free():
|
||||
if not self.operand.needs_free():
|
||||
return ""
|
||||
|
||||
# Generate function prototype.
|
||||
body = "static inline void {0}({1}_host *in)\n{{\n".format(self.name, self.type)
|
||||
if not isinstance(self.operand, VkStruct):
|
||||
return ""
|
||||
|
||||
for m in self.struct:
|
||||
if m.needs_conversion() and m.is_dynamic_array():
|
||||
count = m.dyn_array_len if isinstance(m.dyn_array_len, int) else "in->{0}".format(m.dyn_array_len)
|
||||
if m.is_const():
|
||||
# Add a cast to ignore const on conversion structs we allocated ourselves.
|
||||
body += " free_{0}_array(({0}_host *)in->{1}, {2});\n".format(m.type, m.name, count)
|
||||
body = ""
|
||||
|
||||
if self.operand.needs_conversion():
|
||||
body += "#if defined(USE_STRUCT_CONVERSION)\n"
|
||||
# Generate function prototype.
|
||||
body += "static inline void {0}({1}_host *in)\n".format(self.name, self.type)
|
||||
|
||||
if self.operand.needs_unwrapping():
|
||||
if self.operand.needs_conversion():
|
||||
body += "#else\n"
|
||||
|
||||
# Generate function prototype.
|
||||
body += "static inline void {0}({1} *in)\n".format(self.name, self.type)
|
||||
|
||||
if self.operand.needs_conversion():
|
||||
body += "#endif /* USE_STRUCT_CONVERSION */\n"
|
||||
|
||||
body += "{\n"
|
||||
|
||||
for m in self.operand:
|
||||
if m.needs_free():
|
||||
convert = m.free("in->", conv=True)
|
||||
if self.operand.needs_conversion() and not self.operand.needs_unwrapping():
|
||||
body += " " + convert
|
||||
else:
|
||||
body += " free_{0}_array(in->{1}, {2});\n".format(m.type, m.name, count)
|
||||
unwrap = m.free("in->", conv=False)
|
||||
if convert == unwrap:
|
||||
body += " " + unwrap
|
||||
elif unwrap == "":
|
||||
body += "#if defined(USE_STRUCT_CONVERSION)\n"
|
||||
body += " " + convert
|
||||
body += "#endif /* USE_STRUCT_CONVERSION */\n"
|
||||
else:
|
||||
body += "#if defined(USE_STRUCT_CONVERSION)\n"
|
||||
body += " " + convert
|
||||
body += "#else\n"
|
||||
body += " " + unwrap
|
||||
body += "#endif /* USE_STRUCT_CONVERSION */\n"
|
||||
|
||||
body += "}\n"
|
||||
|
||||
if not self.operand.needs_unwrapping():
|
||||
body += "#endif /* USE_STRUCT_CONVERSION */\n"
|
||||
|
||||
body += "\n"
|
||||
|
||||
body += "}\n\n"
|
||||
return body
|
||||
|
||||
def definition(self):
|
||||
|
@ -2168,7 +2469,16 @@ class StructChainConversionFunction(object):
|
|||
if m.name == "pNext":
|
||||
body += " out->pNext = NULL;\n"
|
||||
else:
|
||||
body += " " + m.copy("in->", "out->", self.direction)
|
||||
convert = m.copy("in->", "out->", self.direction, conv=True)
|
||||
unwrap = m.copy("in->", "out->", self.direction, conv=False)
|
||||
if unwrap == convert:
|
||||
body += " " + unwrap
|
||||
else:
|
||||
body += "#if defined(USE_STRUCT_CONVERSION)\n"
|
||||
body += " " + convert
|
||||
body += "#else\n"
|
||||
body += " " + unwrap
|
||||
body += "#endif /* USE_STRUCT_CONVERSION */\n"
|
||||
|
||||
body += "\n out_header->pNext = (VkBaseOutStructure *)out;\n"
|
||||
body += " out_header = out_header->pNext;\n"
|
||||
|
@ -2212,7 +2522,47 @@ class FreeStructChainFunction(object):
|
|||
|
||||
body += " while (header)\n"
|
||||
body += " {\n"
|
||||
body += " void *prev = header;\n"
|
||||
body += " void *prev = header;\n\n"
|
||||
body += " switch (header->sType)\n"
|
||||
body += " {\n"
|
||||
|
||||
for e in self.struct.struct_extensions:
|
||||
if not e.required:
|
||||
continue
|
||||
|
||||
if not any(m.needs_free() for m in e):
|
||||
continue
|
||||
|
||||
stype = next(x for x in e.members if x.name == "sType")
|
||||
|
||||
body += " case {0}:\n".format(stype.values)
|
||||
body += " {\n"
|
||||
body += " {0} *structure = ({0} *) header;\n".format(e.name)
|
||||
|
||||
for m in e:
|
||||
if m.needs_free():
|
||||
convert = m.free("structure->", conv=True)
|
||||
unwrap = m.free("structure->", conv=False)
|
||||
if convert == unwrap:
|
||||
body += " " + unwrap
|
||||
elif unwrap == "":
|
||||
body += "#if defined(USE_STRUCT_CONVERSION)\n"
|
||||
body += " " + convert
|
||||
body += "#endif /* USE_STRUCT_CONVERSION */\n"
|
||||
else:
|
||||
body += "#if defined(USE_STRUCT_CONVERSION)\n"
|
||||
body += " " + convert
|
||||
body += "#else\n"
|
||||
body += " " + unwrap
|
||||
body += "#endif /* USE_STRUCT_CONVERSION */\n"
|
||||
|
||||
body += " break;\n"
|
||||
body += " }\n"
|
||||
|
||||
body += " default:\n"
|
||||
body += " break;\n"
|
||||
body += " }\n"
|
||||
|
||||
body += " header = header->pNext;\n"
|
||||
body += " free(prev);\n"
|
||||
body += " }\n\n"
|
||||
|
@ -2235,7 +2585,7 @@ class VkGenerator(object):
|
|||
if not func.is_required():
|
||||
continue
|
||||
|
||||
if not func.needs_conversion():
|
||||
if not func.needs_conversion() and not func.needs_unwrapping():
|
||||
continue
|
||||
|
||||
conversions = func.get_conversions()
|
||||
|
@ -2246,15 +2596,26 @@ class VkGenerator(object):
|
|||
if not any(c == conv for c in self.conversions):
|
||||
self.conversions.append(conv)
|
||||
|
||||
if not isinstance(conv.operand, VkStruct):
|
||||
continue
|
||||
|
||||
# Structs can be used in different ways by different conversions
|
||||
# e.g. array vs non-array. Just make sure we pull in each struct once.
|
||||
if not any(s.name == conv.struct.name for s in self.host_structs):
|
||||
self.host_structs.append(conv.struct)
|
||||
if not any(s.name == conv.operand.name for s in self.host_structs):
|
||||
self.host_structs.append(conv.operand)
|
||||
|
||||
for struct in self.registry.structs:
|
||||
if struct.name in STRUCT_CHAIN_CONVERSIONS:
|
||||
self.struct_chain_conversions.append(StructChainConversionFunction(Direction.INPUT, struct))
|
||||
self.struct_chain_conversions.append(FreeStructChainFunction(struct))
|
||||
# Once we decide to support pNext chains conversion everywhere, move this under get_conversions
|
||||
for e in struct.struct_extensions:
|
||||
for m in e:
|
||||
if m.needs_conversion() or m.needs_unwrapping():
|
||||
conversions = m.get_conversions()
|
||||
for conv in conversions:
|
||||
if not any(c == conv for c in self.conversions):
|
||||
self.conversions.append(conv)
|
||||
|
||||
def _generate_copyright(self, f, spec_file=False):
|
||||
f.write("# " if spec_file else "/* ")
|
||||
|
@ -2281,10 +2642,8 @@ class VkGenerator(object):
|
|||
f.write("WINE_DEFAULT_DEBUG_CHANNEL(vulkan);\n\n")
|
||||
|
||||
# Generate any conversion helper functions.
|
||||
f.write("#if defined(USE_STRUCT_CONVERSION)\n")
|
||||
for conv in self.conversions:
|
||||
f.write(conv.definition())
|
||||
f.write("#endif /* USE_STRUCT_CONVERSION */\n\n")
|
||||
|
||||
for conv in self.struct_chain_conversions:
|
||||
f.write(conv.definition())
|
||||
|
|
|
@ -360,20 +360,12 @@ static void wine_vk_device_get_queues(struct VkDevice_T *device,
|
|||
|
||||
static void wine_vk_device_free_create_info(VkDeviceCreateInfo *create_info)
|
||||
{
|
||||
VkDeviceGroupDeviceCreateInfo *group_info;
|
||||
|
||||
if ((group_info = wine_vk_find_struct(create_info, DEVICE_GROUP_DEVICE_CREATE_INFO)))
|
||||
{
|
||||
free((void *)group_info->pPhysicalDevices);
|
||||
}
|
||||
|
||||
free_VkDeviceCreateInfo_struct_chain(create_info);
|
||||
}
|
||||
|
||||
static VkResult wine_vk_device_convert_create_info(const VkDeviceCreateInfo *src,
|
||||
VkDeviceCreateInfo *dst)
|
||||
{
|
||||
VkDeviceGroupDeviceCreateInfo *group_info;
|
||||
unsigned int i;
|
||||
VkResult res;
|
||||
|
||||
|
@ -385,23 +377,6 @@ static VkResult wine_vk_device_convert_create_info(const VkDeviceCreateInfo *src
|
|||
return res;
|
||||
}
|
||||
|
||||
/* FIXME: convert_VkDeviceCreateInfo_struct_chain() should unwrap handles for us. */
|
||||
if ((group_info = wine_vk_find_struct(dst, DEVICE_GROUP_DEVICE_CREATE_INFO)))
|
||||
{
|
||||
VkPhysicalDevice *physical_devices;
|
||||
|
||||
if (!(physical_devices = calloc(group_info->physicalDeviceCount, sizeof(*physical_devices))))
|
||||
{
|
||||
free_VkDeviceCreateInfo_struct_chain(dst);
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
for (i = 0; i < group_info->physicalDeviceCount; ++i)
|
||||
{
|
||||
physical_devices[i] = group_info->pPhysicalDevices[i]->phys_dev;
|
||||
}
|
||||
group_info->pPhysicalDevices = physical_devices;
|
||||
}
|
||||
|
||||
/* Should be filtered out by loader as ICDs don't support layers. */
|
||||
dst->enabledLayerCount = 0;
|
||||
dst->ppEnabledLayerNames = NULL;
|
||||
|
@ -1540,19 +1515,6 @@ void WINAPI wine_vkGetPrivateDataEXT(VkDevice device, VkObjectType object_type,
|
|||
device->funcs.p_vkGetPrivateDataEXT(device->device, object_type, object_handle, private_data_slot, data);
|
||||
}
|
||||
|
||||
VkResult WINAPI wine_vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *create_info,
|
||||
const VkAllocationCallbacks *allocator, VkSwapchainKHR *swapchain)
|
||||
{
|
||||
VkSwapchainCreateInfoKHR native_info;
|
||||
|
||||
TRACE("%p, %p, %p, %p\n", device, create_info, allocator, swapchain);
|
||||
|
||||
native_info = *create_info;
|
||||
native_info.surface = wine_surface_from_handle(create_info->surface)->driver_surface;
|
||||
|
||||
return thunk_vkCreateSwapchainKHR(device, &native_info, allocator, swapchain);
|
||||
}
|
||||
|
||||
VkResult WINAPI wine_vkCreateWin32SurfaceKHR(VkInstance instance,
|
||||
const VkWin32SurfaceCreateInfoKHR *createInfo, const VkAllocationCallbacks *allocator, VkSurfaceKHR *surface)
|
||||
{
|
||||
|
@ -1601,19 +1563,6 @@ void WINAPI wine_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
|
|||
free(object);
|
||||
}
|
||||
|
||||
VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice phys_dev,
|
||||
const VkPhysicalDeviceSurfaceInfo2KHR *surface_info, uint32_t *formats_count, VkSurfaceFormat2KHR *formats)
|
||||
{
|
||||
VkPhysicalDeviceSurfaceInfo2KHR native_info;
|
||||
|
||||
TRACE("%p, %p, %p, %p\n", phys_dev, surface_info, formats_count, formats);
|
||||
|
||||
native_info = *surface_info;
|
||||
native_info.surface = wine_surface_from_handle(surface_info->surface)->driver_surface;
|
||||
|
||||
return thunk_vkGetPhysicalDeviceSurfaceFormats2KHR(phys_dev, &native_info, formats_count, formats);
|
||||
}
|
||||
|
||||
static inline void adjust_max_image_count(VkPhysicalDevice phys_dev, VkSurfaceCapabilitiesKHR* capabilities)
|
||||
{
|
||||
/* Many Windows games, for example Strange Brigade, No Man's Sky, Path of Exile
|
||||
|
@ -1647,15 +1596,11 @@ VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice
|
|||
VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice phys_dev,
|
||||
const VkPhysicalDeviceSurfaceInfo2KHR *surface_info, VkSurfaceCapabilities2KHR *capabilities)
|
||||
{
|
||||
VkPhysicalDeviceSurfaceInfo2KHR native_info;
|
||||
VkResult res;
|
||||
|
||||
TRACE("%p, %p, %p\n", phys_dev, surface_info, capabilities);
|
||||
|
||||
native_info = *surface_info;
|
||||
native_info.surface = wine_surface_from_handle(surface_info->surface)->driver_surface;
|
||||
|
||||
res = thunk_vkGetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev, &native_info, capabilities);
|
||||
res = thunk_vkGetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev, surface_info, capabilities);
|
||||
|
||||
if (res == VK_SUCCESS)
|
||||
adjust_max_image_count(phys_dev, &capabilities->surfaceCapabilities);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -22,7 +22,6 @@ VkResult WINAPI wine_vkCreateDebugReportCallbackEXT(VkInstance instance, const V
|
|||
VkResult WINAPI wine_vkCreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT *pMessenger) DECLSPEC_HIDDEN;
|
||||
VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice);
|
||||
VkResult WINAPI wine_vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance);
|
||||
VkResult WINAPI wine_vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain);
|
||||
VkResult WINAPI wine_vkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
|
||||
VkResult WINAPI wine_vkDebugMarkerSetObjectNameEXT(VkDevice device, const VkDebugMarkerObjectNameInfoEXT *pNameInfo) DECLSPEC_HIDDEN;
|
||||
VkResult WINAPI wine_vkDebugMarkerSetObjectTagEXT(VkDevice device, const VkDebugMarkerObjectTagInfoEXT *pTagInfo) DECLSPEC_HIDDEN;
|
||||
|
@ -58,7 +57,6 @@ VkResult WINAPI wine_vkGetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice
|
|||
VkResult WINAPI wine_vkGetPhysicalDeviceImageFormatProperties2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, VkImageFormatProperties2 *pImageFormatProperties) DECLSPEC_HIDDEN;
|
||||
VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, VkSurfaceCapabilities2KHR *pSurfaceCapabilities);
|
||||
VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities);
|
||||
VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, uint32_t *pSurfaceFormatCount, VkSurfaceFormat2KHR *pSurfaceFormats);
|
||||
void WINAPI wine_vkGetPrivateDataEXT(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlotEXT privateDataSlot, uint64_t *pData) DECLSPEC_HIDDEN;
|
||||
VkResult WINAPI wine_vkQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence);
|
||||
VkResult WINAPI wine_vkSetDebugUtilsObjectNameEXT(VkDevice device, const VkDebugUtilsObjectNameInfoEXT *pNameInfo) DECLSPEC_HIDDEN;
|
||||
|
@ -67,14 +65,12 @@ VkResult WINAPI wine_vkSetPrivateDataEXT(VkDevice device, VkObjectType objectTyp
|
|||
void WINAPI wine_vkSubmitDebugUtilsMessageEXT(VkInstance instance, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Private thunks */
|
||||
VkResult thunk_vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) DECLSPEC_HIDDEN;
|
||||
VkResult thunk_vkDebugMarkerSetObjectNameEXT(VkDevice device, const VkDebugMarkerObjectNameInfoEXT *pNameInfo) DECLSPEC_HIDDEN;
|
||||
VkResult thunk_vkDebugMarkerSetObjectTagEXT(VkDevice device, const VkDebugMarkerObjectTagInfoEXT *pTagInfo) DECLSPEC_HIDDEN;
|
||||
VkResult thunk_vkGetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, VkImageFormatProperties2 *pImageFormatProperties) DECLSPEC_HIDDEN;
|
||||
VkResult thunk_vkGetPhysicalDeviceImageFormatProperties2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, VkImageFormatProperties2 *pImageFormatProperties) DECLSPEC_HIDDEN;
|
||||
VkResult thunk_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, VkSurfaceCapabilities2KHR *pSurfaceCapabilities) DECLSPEC_HIDDEN;
|
||||
VkResult thunk_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) DECLSPEC_HIDDEN;
|
||||
VkResult thunk_vkGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, uint32_t *pSurfaceFormatCount, VkSurfaceFormat2KHR *pSurfaceFormats) DECLSPEC_HIDDEN;
|
||||
VkResult thunk_vkSetDebugUtilsObjectNameEXT(VkDevice device, const VkDebugUtilsObjectNameInfoEXT *pNameInfo) DECLSPEC_HIDDEN;
|
||||
VkResult thunk_vkSetDebugUtilsObjectTagEXT(VkDevice device, const VkDebugUtilsObjectTagInfoEXT *pTagInfo) DECLSPEC_HIDDEN;
|
||||
void thunk_vkSubmitDebugUtilsMessageEXT(VkInstance instance, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData) DECLSPEC_HIDDEN;
|
||||
|
@ -867,6 +863,17 @@ typedef struct VkDebugMarkerObjectTagInfoEXT_host
|
|||
} VkDebugMarkerObjectTagInfoEXT_host;
|
||||
|
||||
|
||||
typedef struct VkPhysicalDeviceGroupProperties_host
|
||||
{
|
||||
VkStructureType sType;
|
||||
void *pNext;
|
||||
uint32_t physicalDeviceCount;
|
||||
VkPhysicalDevice physicalDevices[VK_MAX_DEVICE_GROUP_SIZE];
|
||||
VkBool32 subsetAllocation;
|
||||
} VkPhysicalDeviceGroupProperties_host;
|
||||
|
||||
typedef VkPhysicalDeviceGroupProperties VkPhysicalDeviceGroupPropertiesKHR;
|
||||
|
||||
typedef struct VkMappedMemoryRange_host
|
||||
{
|
||||
VkStructureType sType;
|
||||
|
@ -1280,6 +1287,20 @@ typedef struct VkBindSparseInfo_host
|
|||
} VkBindSparseInfo_host;
|
||||
|
||||
|
||||
typedef struct VkSubmitInfo_host
|
||||
{
|
||||
VkStructureType sType;
|
||||
const void *pNext;
|
||||
uint32_t waitSemaphoreCount;
|
||||
const VkSemaphore *pWaitSemaphores;
|
||||
const VkPipelineStageFlags *pWaitDstStageMask;
|
||||
uint32_t commandBufferCount;
|
||||
const VkCommandBuffer *pCommandBuffers;
|
||||
uint32_t signalSemaphoreCount;
|
||||
const VkSemaphore *pSignalSemaphores;
|
||||
} VkSubmitInfo_host;
|
||||
|
||||
|
||||
typedef struct VkSemaphoreSubmitInfoKHR_host
|
||||
{
|
||||
VkStructureType sType;
|
||||
|
@ -1291,6 +1312,15 @@ typedef struct VkSemaphoreSubmitInfoKHR_host
|
|||
} VkSemaphoreSubmitInfoKHR_host;
|
||||
|
||||
|
||||
typedef struct VkCommandBufferSubmitInfoKHR_host
|
||||
{
|
||||
VkStructureType sType;
|
||||
const void *pNext;
|
||||
VkCommandBuffer commandBuffer;
|
||||
uint32_t deviceMask;
|
||||
} VkCommandBufferSubmitInfoKHR_host;
|
||||
|
||||
|
||||
typedef struct VkSubmitInfo2KHR_host
|
||||
{
|
||||
VkStructureType sType;
|
||||
|
|
Loading…
Reference in New Issue