mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-03-12 09:00:42 +01:00
vulkan/cmd_queue: Rework copy codegen
The new code handles pNext chanis correctly. Reviewed-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39902>
This commit is contained in:
parent
ecb6c5d555
commit
f2bb6103c3
2 changed files with 109 additions and 93 deletions
|
|
@ -5069,7 +5069,6 @@ void lvp_add_enqueue_cmd_entrypoints(struct vk_device_dispatch_table *disp)
|
||||||
ENQUEUE_CMD(CmdCopyAccelerationStructureKHR)
|
ENQUEUE_CMD(CmdCopyAccelerationStructureKHR)
|
||||||
ENQUEUE_CMD(CmdCopyMemoryToAccelerationStructureKHR)
|
ENQUEUE_CMD(CmdCopyMemoryToAccelerationStructureKHR)
|
||||||
ENQUEUE_CMD(CmdCopyAccelerationStructureToMemoryKHR)
|
ENQUEUE_CMD(CmdCopyAccelerationStructureToMemoryKHR)
|
||||||
ENQUEUE_CMD(CmdBuildAccelerationStructuresIndirectKHR)
|
|
||||||
ENQUEUE_CMD(CmdWriteAccelerationStructuresPropertiesKHR)
|
ENQUEUE_CMD(CmdWriteAccelerationStructuresPropertiesKHR)
|
||||||
|
|
||||||
ENQUEUE_CMD(CmdSetRayTracingPipelineStackSizeKHR)
|
ENQUEUE_CMD(CmdSetRayTracingPipelineStackSizeKHR)
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import argparse
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
from enum import Enum, auto
|
||||||
import xml.etree.ElementTree as et
|
import xml.etree.ElementTree as et
|
||||||
|
|
||||||
from mako.template import Template
|
from mako.template import Template
|
||||||
|
|
@ -69,6 +70,8 @@ NO_ENQUEUE_COMMANDS = [
|
||||||
'CmdSetPerformanceMarkerINTEL',
|
'CmdSetPerformanceMarkerINTEL',
|
||||||
'CmdSetPerformanceStreamMarkerINTEL',
|
'CmdSetPerformanceStreamMarkerINTEL',
|
||||||
'CmdSetPerformanceOverrideINTEL',
|
'CmdSetPerformanceOverrideINTEL',
|
||||||
|
|
||||||
|
'CmdBuildAccelerationStructuresIndirectKHR',
|
||||||
]
|
]
|
||||||
|
|
||||||
TEMPLATE_H = Template(COPYRIGHT + """\
|
TEMPLATE_H = Template(COPYRIGHT + """\
|
||||||
|
|
@ -421,35 +424,51 @@ def to_struct_name(name):
|
||||||
def get_array_len(param):
|
def get_array_len(param):
|
||||||
return param.decl[param.decl.find("[") + 1:param.decl.find("]")]
|
return param.decl[param.decl.find("[") + 1:param.decl.find("]")]
|
||||||
|
|
||||||
def get_array_copy(builder, command, param, field_name):
|
class ParamCategory(Enum):
|
||||||
if param.type == "void":
|
ASSIGNABLE = auto()
|
||||||
field_size = "1"
|
FLAT_ARRAY = auto()
|
||||||
else:
|
UNSIZED_RAW_POINTER = auto()
|
||||||
field_size = "sizeof(*%s)" % field_name
|
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;" % (
|
def categorize_param(types, parent_type, param):
|
||||||
field_name, field_size, param.len, field_name
|
if param.name == 'pNext':
|
||||||
))
|
return ParamCategory.PNEXT if not parent_type or types[parent_type].extended_by else ParamCategory.NULL
|
||||||
builder.add("memcpy((void*)%s, %s, %s * (%s));" % (field_name, param.name, field_size, param.len))
|
|
||||||
|
|
||||||
def get_pnext_member_copy(builder, struct, src_type, member, types):
|
if '[' in param.decl:
|
||||||
if not types[src_type].extended_by:
|
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
|
return
|
||||||
|
|
||||||
field_name = "%s->%s" % (struct, member.name)
|
builder.add("const VkBaseInStructure *pnext = %s;" % (src))
|
||||||
|
builder.add("void **dst_pnext_link = (void **)&%s;" % (dst))
|
||||||
builder.add("const VkBaseInStructure *pnext = %s;" % (field_name))
|
builder.add("while (pnext) {")
|
||||||
builder.add("if (pnext) {")
|
|
||||||
builder.level += 1
|
builder.level += 1
|
||||||
builder.add("switch ((int32_t)pnext->sType) {")
|
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:
|
if type.guard is not None:
|
||||||
builder.code += "#ifdef %s\n" % (type.guard)
|
builder.code += "#ifdef %s\n" % (type.guard)
|
||||||
|
|
||||||
builder.add("case %s:" % (type.enum))
|
builder.add("case %s:" % (type.enum))
|
||||||
builder.level += 1
|
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.add("break;")
|
||||||
builder.level -= 1
|
builder.level -= 1
|
||||||
|
|
||||||
|
|
@ -457,99 +476,97 @@ def get_pnext_member_copy(builder, struct, src_type, member, types):
|
||||||
builder.code += "#endif\n"
|
builder.code += "#endif\n"
|
||||||
|
|
||||||
builder.add("}")
|
builder.add("}")
|
||||||
|
builder.add("pnext = pnext->pNext;")
|
||||||
|
builder.add("dst_pnext_link = (void **)&((VkBaseOutStructure *)*dst_pnext_link)->pNext;")
|
||||||
builder.level -= 1
|
builder.level -= 1
|
||||||
builder.add("}")
|
builder.add("}")
|
||||||
|
|
||||||
def get_struct_copy(builder, dst, src_name, src_type, types, parent_name=None, len=None):
|
def get_param_copy(builder, types, src_parent_access, dst_parent_access, param, nullable=True, dst_snake_case=False):
|
||||||
tmp_dst_name = builder.get_variable_name("tmp_dst")
|
src = src_parent_access + param.name
|
||||||
tmp_src_name = builder.get_variable_name("tmp_src")
|
dst = dst_parent_access + (to_field_name(param.name) if dst_snake_case else param.name)
|
||||||
|
|
||||||
builder.add("if (%s) {" % (src_name))
|
match categorize_param(types, None, param):
|
||||||
builder.level += 1
|
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 src_type == "void":
|
if param.type == "void":
|
||||||
size = "1"
|
size = 1
|
||||||
else:
|
else:
|
||||||
size = "sizeof(%s)" % src_type
|
size = "sizeof(%s)" % param.type
|
||||||
|
|
||||||
if len and len != "struct-ptr":
|
is_ndarray = param.len and "," in param.len
|
||||||
size = "%s * %s->%s" % (size, parent_name, len)
|
if param.len and param.len != "struct-ptr" and not is_ndarray:
|
||||||
|
size = "%s * %s%s" % (size, src_parent_access, param.len)
|
||||||
|
|
||||||
builder.add("%s = linear_alloc_child(queue->ctx, %s);" % (dst, size))
|
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("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("memcpy((void *)%s, %s, %s);" % (dst, src, size))
|
||||||
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))
|
|
||||||
|
|
||||||
struct_array_copy = len and len != "struct-ptr" and src_type != "void"
|
if param.type in types:
|
||||||
if struct_array_copy:
|
needs_member_copy = False
|
||||||
array_index = builder.get_variable_name("i")
|
for member in types[param.type].members:
|
||||||
builder.add("for (uint32_t %s = 0; %s < %s->%s; %s++) {" % (array_index, array_index, parent_name, len, array_index))
|
category = categorize_param(types, param.type, member)
|
||||||
builder.level += 1
|
if category == ParamCategory.PNEXT or category == ParamCategory.STRUCT or category == ParamCategory.STRING:
|
||||||
prev_tmp_dst_name = tmp_dst_name
|
needs_member_copy = True
|
||||||
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))
|
|
||||||
|
|
||||||
if src_type in types:
|
if needs_member_copy:
|
||||||
for member in types[src_type].members:
|
tmp_dst_name = builder.get_variable_name("tmp_dst")
|
||||||
if member.len and member.len != 'null-terminated':
|
tmp_src_name = builder.get_variable_name("tmp_src")
|
||||||
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 struct_array_copy:
|
builder.add("%s *%s = (void *)%s;" % (param.type, tmp_dst_name, dst))
|
||||||
builder.level -= 1
|
builder.add("%s *%s = (void *)%s;" % (param.type, tmp_src_name, src))
|
||||||
builder.add("}")
|
|
||||||
|
|
||||||
builder.level -= 1
|
struct_array_copy = param.len and param.len != "struct-ptr" and param.type != "void"
|
||||||
builder.add("} else {")
|
if struct_array_copy:
|
||||||
builder.level += 1
|
array_index = builder.get_variable_name("i")
|
||||||
builder.add("%s = NULL;" % (dst))
|
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
|
builder.level += 1
|
||||||
builder.add("}")
|
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))
|
||||||
|
|
||||||
def get_param_copy(builder, command, param, types):
|
for member in types[param.type].members:
|
||||||
dst = "cmd->u.%s.%s" % (to_struct_field_name(command.name), to_field_name(param.name))
|
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 param.len:
|
if struct_array_copy:
|
||||||
builder.add("if (%s) {" % (param.name))
|
builder.level -= 1
|
||||||
builder.level += 1
|
builder.add("}")
|
||||||
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
|
|
||||||
|
|
||||||
if '[' in param.decl:
|
if nullable:
|
||||||
builder.add("memcpy(%s, %s, sizeof(*%s) * %s);" % (dst, param.name, param.name, get_array_len(param)))
|
builder.level -= 1
|
||||||
return False
|
builder.add("} else {")
|
||||||
|
builder.level += 1
|
||||||
if param.type == "void":
|
builder.add("%s = NULL;" % (dst))
|
||||||
builder.add("%s = (%s)%s;" % (dst, remove_suffix(param.decl.replace("const", ""), param.name), param.name))
|
builder.level -= 1
|
||||||
return False
|
builder.add("}")
|
||||||
|
case ParamCategory.NULL:
|
||||||
if '*' in param.decl:
|
assert False
|
||||||
get_struct_copy(builder, dst, param.name, param.type, types)
|
case ParamCategory.PNEXT:
|
||||||
return True
|
assert False
|
||||||
|
|
||||||
builder.add("cmd->u.%s.%s = %s;" % (to_struct_field_name(command.name), to_field_name(param.name), param.name))
|
|
||||||
return False
|
|
||||||
|
|
||||||
def get_params_copy(command, types):
|
def get_params_copy(command, types):
|
||||||
builder = CodeBuilder(1)
|
builder = CodeBuilder(1)
|
||||||
|
|
||||||
|
struct_access = "cmd->u.%s." % (to_struct_field_name(command.name))
|
||||||
for param in command.params[1:]:
|
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.code += "\n"
|
||||||
builder.add("list_addtail(&cmd->cmd_link, &queue->cmds);")
|
builder.add("list_addtail(&cmd->cmd_link, &queue->cmds);")
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue