diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c index 30fe3e130a4..38f03757503 100644 --- a/src/gallium/frontends/lavapipe/lvp_execute.c +++ b/src/gallium/frontends/lavapipe/lvp_execute.c @@ -5069,7 +5069,6 @@ void lvp_add_enqueue_cmd_entrypoints(struct vk_device_dispatch_table *disp) ENQUEUE_CMD(CmdCopyAccelerationStructureKHR) ENQUEUE_CMD(CmdCopyMemoryToAccelerationStructureKHR) ENQUEUE_CMD(CmdCopyAccelerationStructureToMemoryKHR) - ENQUEUE_CMD(CmdBuildAccelerationStructuresIndirectKHR) ENQUEUE_CMD(CmdWriteAccelerationStructuresPropertiesKHR) ENQUEUE_CMD(CmdSetRayTracingPipelineStackSizeKHR) diff --git a/src/vulkan/util/vk_cmd_queue_gen.py b/src/vulkan/util/vk_cmd_queue_gen.py index 3511fc4bba5..60cb7aa8c34 100644 --- a/src/vulkan/util/vk_cmd_queue_gen.py +++ b/src/vulkan/util/vk_cmd_queue_gen.py @@ -27,6 +27,7 @@ import argparse import os import re from collections import namedtuple +from enum import Enum, auto import xml.etree.ElementTree as et from mako.template import Template @@ -69,6 +70,8 @@ NO_ENQUEUE_COMMANDS = [ 'CmdSetPerformanceMarkerINTEL', 'CmdSetPerformanceStreamMarkerINTEL', 'CmdSetPerformanceOverrideINTEL', + + 'CmdBuildAccelerationStructuresIndirectKHR', ] TEMPLATE_H = Template(COPYRIGHT + """\ @@ -421,135 +424,149 @@ def to_struct_name(name): def get_array_len(param): return param.decl[param.decl.find("[") + 1:param.decl.find("]")] -def get_array_copy(builder, command, param, field_name): - if param.type == "void": - field_size = "1" - else: - field_size = "sizeof(*%s)" % field_name +class ParamCategory(Enum): + ASSIGNABLE = auto() + FLAT_ARRAY = auto() + UNSIZED_RAW_POINTER = auto() + STRING = auto() + NULL = auto() + PNEXT = auto() + STRUCT = auto() - builder.add("%s = linear_alloc_child(queue->ctx, %s * (%s));\n if (%s == NULL) return VK_ERROR_OUT_OF_HOST_MEMORY;" % ( - field_name, field_size, param.len, field_name - )) - builder.add("memcpy((void*)%s, %s, %s * (%s));" % (field_name, param.name, field_size, param.len)) +def categorize_param(types, parent_type, param): + if param.name == 'pNext': + return ParamCategory.PNEXT if not parent_type or types[parent_type].extended_by else ParamCategory.NULL -def get_pnext_member_copy(builder, struct, src_type, member, types): - if not types[src_type].extended_by: + if '[' in param.decl: + return ParamCategory.FLAT_ARRAY + + if param.type == "void" and not param.len: + return ParamCategory.UNSIZED_RAW_POINTER + + if param.len == 'null-terminated': + return ParamCategory.STRING + + if "*" not in param.decl: + return ParamCategory.ASSIGNABLE + + return ParamCategory.STRUCT + +def get_pnext_copy(builder, types, parent_type, src, dst): + if not types[parent_type].extended_by: return - field_name = "%s->%s" % (struct, member.name) - - builder.add("const VkBaseInStructure *pnext = %s;" % (field_name)) - builder.add("if (pnext) {") + builder.add("const VkBaseInStructure *pnext = %s;" % (src)) + builder.add("void **dst_pnext_link = (void **)&%s;" % (dst)) + builder.add("while (pnext) {") builder.level += 1 builder.add("switch ((int32_t)pnext->sType) {") - for type in types[src_type].extended_by: + for type in types[parent_type].extended_by: if type.guard is not None: builder.code += "#ifdef %s\n" % (type.guard) builder.add("case %s:" % (type.enum)) builder.level += 1 - get_struct_copy(builder, field_name, "pnext", type.name, types) + member = EntrypointParam(type=type.name, name="", decl="%s *" % (type.name), len=None) + get_param_copy(builder, types, "pnext", "(*dst_pnext_link)", member, nullable=False) builder.add("break;") builder.level -= 1 if type.guard is not None: builder.code += "#endif\n" - + builder.add("}") + builder.add("pnext = pnext->pNext;") + builder.add("dst_pnext_link = (void **)&((VkBaseOutStructure *)*dst_pnext_link)->pNext;") builder.level -= 1 builder.add("}") -def get_struct_copy(builder, dst, src_name, src_type, types, parent_name=None, len=None): - tmp_dst_name = builder.get_variable_name("tmp_dst") - tmp_src_name = builder.get_variable_name("tmp_src") - - builder.add("if (%s) {" % (src_name)) - builder.level += 1 +def get_param_copy(builder, types, src_parent_access, dst_parent_access, param, nullable=True, dst_snake_case=False): + src = src_parent_access + param.name + dst = dst_parent_access + (to_field_name(param.name) if dst_snake_case else param.name) - if src_type == "void": - size = "1" - else: - size = "sizeof(%s)" % src_type + match categorize_param(types, None, param): + case ParamCategory.ASSIGNABLE: + builder.add("%s = %s;" % (dst, src)) + case ParamCategory.FLAT_ARRAY: + builder.add("memcpy(%s, %s, sizeof(*%s) * %s);" % (dst, src, src, get_array_len(param))) + case ParamCategory.UNSIZED_RAW_POINTER: + builder.add("%s = (%s)%s;" % (dst, remove_suffix(param.decl.replace("const", ""), param.name), src)) + case ParamCategory.STRING: + builder.add("%s = linear_strdup(queue->ctx, %s);" % (dst, src)) + case ParamCategory.STRUCT: + if nullable: + builder.add("if (%s) {" % (src)) + builder.level += 1 - if len and len != "struct-ptr": - size = "%s * %s->%s" % (size, parent_name, len) + if param.type == "void": + size = 1 + else: + size = "sizeof(%s)" % param.type - builder.add("%s = linear_alloc_child(queue->ctx, %s);" % (dst, size)) - builder.add("if (%s == NULL) return VK_ERROR_OUT_OF_HOST_MEMORY;" % (dst)) - builder.add("%s *%s = (void *)%s;" % (src_type, tmp_dst_name, dst)) - builder.add("%s *%s = (void *)%s;" % (src_type, tmp_src_name, src_name)) - builder.add("memcpy(%s, %s, %s);" % (tmp_dst_name, tmp_src_name, size)) + is_ndarray = param.len and "," in param.len + if param.len and param.len != "struct-ptr" and not is_ndarray: + size = "%s * %s%s" % (size, src_parent_access, param.len) - struct_array_copy = len and len != "struct-ptr" and src_type != "void" - if struct_array_copy: - array_index = builder.get_variable_name("i") - builder.add("for (uint32_t %s = 0; %s < %s->%s; %s++) {" % (array_index, array_index, parent_name, len, array_index)) - builder.level += 1 - prev_tmp_dst_name = tmp_dst_name - prev_tmp_src_name = tmp_src_name - tmp_dst_name = builder.get_variable_name("tmp_dst") - tmp_src_name = builder.get_variable_name("tmp_src") - builder.add("%s *%s = %s + %s; (void)%s;" % (src_type, tmp_dst_name, prev_tmp_dst_name, array_index, tmp_dst_name)) - builder.add("%s *%s = %s + %s; (void)%s;" % (src_type, tmp_src_name, prev_tmp_src_name, array_index, tmp_src_name)) + builder.add("%s = linear_alloc_child(queue->ctx, %s);" % (dst, size)) + builder.add("if (%s == NULL) return VK_ERROR_OUT_OF_HOST_MEMORY;" % (dst)) + builder.add("memcpy((void *)%s, %s, %s);" % (dst, src, size)) - if src_type in types: - for member in types[src_type].members: - if member.len and member.len != 'null-terminated': - get_struct_copy(builder, "%s->%s" % (tmp_dst_name, member.name), "%s->%s" % ( - tmp_src_name, member.name - ), member.type, types, tmp_src_name, member.len) - elif member.len and member.len == 'null-terminated': - builder.add("%s->%s = linear_strdup(queue->ctx, %s->%s);" % (tmp_dst_name, member.name, tmp_src_name, member.name)) - elif member.name == 'pNext': - get_pnext_member_copy(builder, tmp_dst_name, src_type, member, types) + if param.type in types: + needs_member_copy = False + for member in types[param.type].members: + category = categorize_param(types, param.type, member) + if category == ParamCategory.PNEXT or category == ParamCategory.STRUCT or category == ParamCategory.STRING: + needs_member_copy = True - if struct_array_copy: - builder.level -= 1 - builder.add("}") + if needs_member_copy: + tmp_dst_name = builder.get_variable_name("tmp_dst") + tmp_src_name = builder.get_variable_name("tmp_src") - builder.level -= 1 - builder.add("} else {") - builder.level += 1 - builder.add("%s = NULL;" % (dst)) - builder.level -= 1 - builder.add("}") + builder.add("%s *%s = (void *)%s;" % (param.type, tmp_dst_name, dst)) + builder.add("%s *%s = (void *)%s;" % (param.type, tmp_src_name, src)) -def get_param_copy(builder, command, param, types): - dst = "cmd->u.%s.%s" % (to_struct_field_name(command.name), to_field_name(param.name)) + struct_array_copy = param.len and param.len != "struct-ptr" and param.type != "void" + if struct_array_copy: + array_index = builder.get_variable_name("i") + builder.add("for (uint32_t %s = 0; %s < %s%s; %s++) {" % (array_index, array_index, src_parent_access, param.len, array_index)) + builder.level += 1 + prev_tmp_dst_name = tmp_dst_name + prev_tmp_src_name = tmp_src_name + tmp_dst_name = builder.get_variable_name("tmp_dst") + tmp_src_name = builder.get_variable_name("tmp_src") + builder.add("%s *%s = %s + %s;" % (param.type, tmp_dst_name, prev_tmp_dst_name, array_index)) + builder.add("%s *%s = %s + %s;" % (param.type, tmp_src_name, prev_tmp_src_name, array_index)) - if param.len: - builder.add("if (%s) {" % (param.name)) - builder.level += 1 - get_array_copy(builder, command, param, dst) - builder.level -= 1 - builder.add("} else {") - builder.level += 1 - builder.add("%s = NULL;" % (dst)) - builder.level -= 1 - builder.add("}") - return True + for member in types[param.type].members: + category = categorize_param(types, param.type, member) + if category == ParamCategory.STRUCT or category == ParamCategory.STRING: + get_param_copy(builder, types, "%s->" % (tmp_src_name), "%s->" % (tmp_dst_name), member) + elif category == ParamCategory.PNEXT: + get_pnext_copy(builder, types, param.type, "%s->pNext" % (tmp_src_name), "%s->pNext" % (tmp_dst_name)) - if '[' in param.decl: - builder.add("memcpy(%s, %s, sizeof(*%s) * %s);" % (dst, param.name, param.name, get_array_len(param))) - return False + if struct_array_copy: + builder.level -= 1 + builder.add("}") - if param.type == "void": - builder.add("%s = (%s)%s;" % (dst, remove_suffix(param.decl.replace("const", ""), param.name), param.name)) - return False - - if '*' in param.decl: - get_struct_copy(builder, dst, param.name, param.type, types) - return True - - builder.add("cmd->u.%s.%s = %s;" % (to_struct_field_name(command.name), to_field_name(param.name), param.name)) - return False + if nullable: + builder.level -= 1 + builder.add("} else {") + builder.level += 1 + builder.add("%s = NULL;" % (dst)) + builder.level -= 1 + builder.add("}") + case ParamCategory.NULL: + assert False + case ParamCategory.PNEXT: + assert False def get_params_copy(command, types): builder = CodeBuilder(1) + struct_access = "cmd->u.%s." % (to_struct_field_name(command.name)) for param in command.params[1:]: - get_param_copy(builder, command, param, types) + get_param_copy(builder, types, "", struct_access, param, dst_snake_case=True) builder.code += "\n" builder.add("list_addtail(&cmd->cmd_link, &queue->cmds);")