Skip to content

Commit

Permalink
DX12 Convert - Better Return Value Generation
Browse files Browse the repository at this point in the history
Enums printed prettily.
Fewer comments in generated file.
  • Loading branch information
andrew-lunarg committed Nov 26, 2023
1 parent 1e8de8c commit 6849948
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 252 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def write_include(self):
)
write(code, file=self.outFile)

def get_consumer_function_body(self, class_name, method_info, return_type):
def get_consumer_function_body(self, class_name, method_info, return_type, return_value):
return '{}'

def change_param_type(self, param):
Expand All @@ -110,6 +110,7 @@ def get_consumer_function(
class_method_name = class_name + '_' + class_method_name

rtn_type = method_info['rtnType']
return_value = None
if rtn_type.find('void ') == -1 or rtn_type.find('void *') != -1:
rtn_type1 = self.clean_type_define(rtn_type)
return_value = self.get_return_value_info(
Expand Down Expand Up @@ -178,7 +179,7 @@ def get_consumer_function(
_class_name,
method_info['name'],
parameters,
self.get_consumer_function_body(class_name, method_info, rtn_type))
self.get_consumer_function_body(class_name, method_info, rtn_type, return_value))
return code

def write_constructor_class(self, consumer_type):
Expand Down
21 changes: 11 additions & 10 deletions framework/generated/dx12_generators/dx12_json_common_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,17 @@ class Dx12JsonCommonGenerator(Dx12BaseGenerator):
# HresultToJson
# Plus all the unique signatures for flag sets like FieldToJson_D3D_PARAMETER_FLAGS
def choose_field_to_json_name(self, value_info):
if value_info.base_type in self.HEX_TYPES:
return "FieldToJsonAsHex"
if "BOOL" in value_info.base_type:
return "Bool32ToJson"
if self.is_handle(value_info.base_type):
return "HandleToJson"
if("HRESULT" in value_info.base_type):
return "HresultToJson"
if ends_with_any(value_info.base_type, self.BIT_FLAG_SUFFIXES):
return "FieldToJson_" + value_info.base_type
if value_info != None:
if value_info.base_type in self.HEX_TYPES:
return "FieldToJsonAsHex"
if "BOOL" in value_info.base_type:
return "Bool32ToJson"
if self.is_handle(value_info.base_type):
return "HandleToJson"
if("HRESULT" in value_info.base_type):
return "HresultToJson"
if ends_with_any(value_info.base_type, self.BIT_FLAG_SUFFIXES):
return "FieldToJson_" + value_info.base_type
return "FieldToJson"
pass

Original file line number Diff line number Diff line change
Expand Up @@ -88,65 +88,40 @@ def get_decoder_class_define(self, consumer_type):
class_end = ''
return (declaration, indent, function_class, class_end)

def get_consumer_function_body(self, class_name, method_info, return_type):
def get_consumer_function_body(self, class_name, method_info, return_type, return_value):
class_method_name = method_info['name']
code = '''
{
using namespace gfxrecon::util;
'''
if(class_name == None or len(class_name) == 0):
code += self.make_consumer_func_body(method_info, return_type)
code += self.make_consumer_func_body(method_info, return_type, return_value)
else:
code += self.make_consumer_method_body(class_name, method_info, return_type)
code += self.make_consumer_method_body(class_name, method_info, return_type, return_value)

code += "\n}"
code = "\n" + format_cpp_code(code)
return code

## Generate a FieldToJson appropriate to the return type.
## @param func_type Either "function" or "method" for expected use.
def make_return(self, func_type, return_type):
type_start = return_type.split()[0]
ret_line = "FieldToJson({0}[format::kNameReturn], return_value, options);\n"
if "void" in return_type:
if "*" in return_type:
ret_line = "// Void pointer return should be a PointerDecoder<uint_8>:\n" + ret_line
else:
ret_line = "// Nothing returned.\n"
elif "BOOL" in return_type:
ret_line = "Bool32ToJson({0}[format::kNameReturn], return_value, options);\n"
elif "HRESULT" in return_type:
ret_line = "HresultToJson({0}[format::kNameReturn], return_value, options);\n"
elif self.is_struct(type_start) or (type_start == "const" and "_DESC * " in return_type):
ret_line = "// Structs use the default signature:\n" + ret_line
elif return_type.startswith("HANDLE "):
## This is a Windows handle, probably to a waitable object so we output it as a JSON number:
## <https://learn.microsoft.com/en-us/windows/win32/sysinfo/handles-and-objects>
## <https://learn.microsoft.com/en-us/windows/win32/sync/wait-functions>
ret_line = "// Using the default for the underlying type of " + type_start + ":\n" + ret_line
elif return_type.startswith("D3D12_GPU_VIRTUAL_ADDRESS") or return_type.startswith("LPVOID"):
ret_line = "FieldToJsonAsHex({0}[format::kNameReturn], return_value, options);\n"
elif return_type.startswith("UINT ") or return_type.startswith("UINT64 ") or return_type.startswith("ULONG ") or return_type.startswith("SIZE_T "):
ret_line = "// The default will resolve correctly for " + type_start + ":\n" + ret_line
elif type_start.endswith("_FLAGS") or type_start.endswith("D3D12_DEBUG_FEATURE"):
# Flags may convert incorrectly here or in arguments of struct fields but that should probably be addressed in the EnumToString function generator:
# <https://github.com/LunarG/gfxreconstruct/issues/1349>
ret_line = "// A flags enum uses the default signature:\n" + ret_line
elif self.is_enum(type_start):
ret_line = "// A regular non-flags enum uses the default signature:\n" + ret_line
else:
msg = "An unknown return type was seen in generation. Defaulting to the base converter signature."
print("ALERT: " + msg + " (" + return_type + ")")
ret_line = "// " + msg + "\n" + ret_line

ret_line = ret_line.format(func_type)
def make_return(self, func_type, return_value):
if(None == return_value):
return ""
function_name = self.choose_field_to_json_name(return_value)
ret_line = "{0}({1}[format::kNameReturn], return_value, options);\n"
## if return_type.startswith("HANDLE "):
## This is a Windows handle, probably to a waitable object so we output it as a JSON number:
## <https://learn.microsoft.com/en-us/windows/win32/sysinfo/handles-and-objects>
## <https://learn.microsoft.com/en-us/windows/win32/sync/wait-functions>
ret_line = ret_line.format(function_name, func_type)
return ret_line

def make_consumer_func_body(self, method_info, return_type):
def make_consumer_func_body(self, method_info, return_type, return_value):
# Deal with the function's returned value:
if return_type != 'HRESULT WINAPI':
print ("Warning - Unexpected return type:", return_type)
ret_line = self.make_return("function", return_type)
ret_line = self.make_return("function", return_value)

code = '''
nlohmann::ordered_json& function = writer_->WriteApiCallStart(call_info, "{}");
Expand All @@ -168,14 +143,14 @@ def make_consumer_func_body(self, method_info, return_type):
code = code.format(method_info['name'])
return code

def make_consumer_method_body(self, class_name, method_info, return_type):
def make_consumer_method_body(self, class_name, method_info, return_type, return_value):
code = '''
nlohmann::ordered_json& method = writer_->WriteApiCallStart(call_info, "{0}", object_id, "{1}");
const JsonOptions& options = writer_->GetOptions();
'''

# Deal with the function's returned value:
ret_line = self.make_return("method", return_type)
ret_line = self.make_return("method", return_value)
code += ret_line

# Deal with function argumentS:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def write_include(self):
code = ("\n" "#include \"decode/dx12_json_consumer_base.h\"\n" "\n")
write(code, file=self.outFile)

def get_consumer_function_body(self, class_name, method_info, return_type):
def get_consumer_function_body(self, class_name, method_info, return_type, return_value):
# Marking functions as override helps to ensure the code gen for
# base and derived classes never gets out of sync.
return ' override;'
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,5 @@ def write_include(self):
code = ("\n" "#include \"decode/dx12_replay_consumer_base.h\"\n" "\n")
write(code, file=self.outFile)

def get_consumer_function_body(self, class_name, method_info, return_type):
def get_consumer_function_body(self, class_name, method_info, return_type, return_value):
return ';'
Loading

0 comments on commit 6849948

Please sign in to comment.