def beginFile(self, gen_opts): """Method override.""" BaseGenerator.beginFile(self, gen_opts) write( '#include "decode/custom_vulkan_struct_decoders_forward.h"', file=self.outFile ) write('#include "decode/handle_pointer_decoder.h"', file=self.outFile) write('#include "decode/pnext_node.h"', file=self.outFile) write('#include "decode/pointer_decoder.h"', file=self.outFile) write('#include "decode/string_array_decoder.h"', file=self.outFile) write('#include "decode/string_decoder.h"', file=self.outFile) write('#include "decode/struct_pointer_decoder.h"', file=self.outFile) write('#include "format/format.h"', file=self.outFile) write('#include "format/platform_types.h"', file=self.outFile) write( '#include "generated/generated_vulkan_struct_decoders_forward.h"', file=self.outFile ) write('#include "util/defines.h"', file=self.outFile) self.newline() self.includeVulkanHeaders(gen_opts) self.newline() write('#include <memory>', file=self.outFile) self.newline() write('GFXRECON_BEGIN_NAMESPACE(gfxrecon)', file=self.outFile) write('GFXRECON_BEGIN_NAMESPACE(decode)', file=self.outFile)
def beginFile(self, gen_opts): """Method override.""" BaseGenerator.beginFile(self, gen_opts) write('#include "decode/vulkan_decoder_base.h"', file=self.outFile) write('#include "util/defines.h"', file=self.outFile) self.newline() self.includeVulkanHeaders(gen_opts) self.newline() write('GFXRECON_BEGIN_NAMESPACE(gfxrecon)', file=self.outFile) write('GFXRECON_BEGIN_NAMESPACE(decode)', file=self.outFile) self.newline() write('class VulkanDecoder : public VulkanDecoderBase', file=self.outFile) write('{', file=self.outFile) write(' public:', file=self.outFile) write(' VulkanDecoder() { }\n', file=self.outFile) write(' virtual ~VulkanDecoder() override { }\n', file=self.outFile) write( ' virtual void DecodeFunctionCall(format::ApiCallId call_id,', file=self.outFile) write( ' const ApiCallInfo& call_info,', file=self.outFile) write( ' const uint8_t* parameter_buffer,', file=self.outFile) write( ' size_t buffer_size) override;\n', file=self.outFile) write(' private:', end='', file=self.outFile)
def beginFile(self, gen_opts): """Method override.""" BaseGenerator.beginFile(self, gen_opts) write('#include "encode/custom_vulkan_api_call_encoders.h"', file=self.outFile) write('#include "generated/generated_vulkan_api_call_encoders.h"', file=self.outFile) write('#include "layer/trace_layer.h"', file=self.outFile) write('#include "util/defines.h"', file=self.outFile) self.newline() self.includeVulkanHeaders(gen_opts) self.newline() write('#include <unordered_map>', file=self.outFile) self.newline() write('GFXRECON_BEGIN_NAMESPACE(gfxrecon)', file=self.outFile) self.newline() write( 'const std::unordered_map<std::string, PFN_vkVoidFunction> func_table = {', file=self.outFile)
def endFile(self): platform_type = 'Vulkan' map_types = 'Handles' map_type = 'Handle' map_table = '' map_object = '' is_dx12_class = self.is_dx12_class() if is_dx12_class: platform_type = 'Dx12' map_types = 'Objects' map_type = 'Object' map_table = ', const graphics::Dx12GpuVaMap& gpu_va_map' map_object = ', gpu_va_map' if not is_dx12_class: self.newline() write( 'void MapPNextStructHandles(const void* value, void* wrapper, const VulkanObjectInfoTable& object_info_table);', file=self.outFile) self.newline() write('template <typename T>', file=self.outFile) write( 'void MapStructArray{}(T* structs, size_t len, const {}ObjectInfoTable& object_info_table{})' .format(map_types, platform_type, map_table), file=self.outFile) write('{', file=self.outFile) write(' if (structs != nullptr)', file=self.outFile) write(' {', file=self.outFile) write(' for (size_t i = 0; i < len; ++i)', file=self.outFile) write(' {', file=self.outFile) write(' MapStruct{}(&structs[i], object_info_table{});'. format(map_types, map_object), file=self.outFile) write(' }', file=self.outFile) write(' }', file=self.outFile) write('}', file=self.outFile) self.newline() for struct in self.output_structs_with_handles: write( 'void AddStruct{}(format::HandleId parent_id, const Decoded_{type}* id_wrapper, const {type}* handle_struct, {}ObjectInfoTable* object_info_table{});' .format(map_types, platform_type, map_table, type=struct), file=self.outFile) self.newline() write('template <typename T>', file=self.outFile) write( 'void AddStructArray{}(format::HandleId parent_id, const T* id_wrappers, size_t id_len, const typename T::struct_type* handle_structs, size_t handle_len, {}ObjectInfoTable* object_info_table{})' .format(map_types, platform_type, map_table), file=self.outFile) write('{', file=self.outFile) write(' if (id_wrappers != nullptr && handle_structs != nullptr)', file=self.outFile) write(' {', file=self.outFile) write(' // TODO: Improved handling of array size mismatch.', file=self.outFile) write(' size_t len = std::min(id_len, handle_len);', file=self.outFile) write(' for (size_t i = 0; i < len; ++i)', file=self.outFile) write(' {', file=self.outFile) write( ' AddStruct{}(parent_id, &id_wrappers[i], &handle_structs[i], object_info_table);' .format(map_types), file=self.outFile) write(' }', file=self.outFile) write(' }', file=self.outFile) write('}', file=self.outFile) self.newline() for struct in self.output_structs_with_handles: if struct in self.structs_with_handle_ptrs: write( 'void SetStruct{map_type}Lengths(Decoded_{type}* wrapper);' .format(map_type=map_type, type=struct), file=self.outFile) self.newline() write('template <typename T>', file=self.outFile) write('void SetStructArray{}Lengths(T* wrappers, size_t len)'.format( map_type), file=self.outFile) write('{', file=self.outFile) write(' if (wrappers != nullptr)', file=self.outFile) write(' {', file=self.outFile) write(' for (size_t i = 0; i < len; ++i)', file=self.outFile) write(' {', file=self.outFile) write(' SetStruct{}Lengths(&wrappers[i]);'.format(map_type), file=self.outFile) write(' }', file=self.outFile) write(' }', file=self.outFile) write('}', file=self.outFile) self.newline() write('GFXRECON_END_NAMESPACE(decode)', file=self.outFile) write('GFXRECON_END_NAMESPACE(gfxrecon)', file=self.outFile)
def endFile(self): """Method override.""" # Generate the pNext shallow copy code, for pNext structs that don't have handles, but need to be preserved in the overall copy for handle wrapping. self.newline() write( 'static VkBaseInStructure* CopyPNextStruct(const VkBaseInStructure* base, HandleUnwrapMemory* unwrap_memory)', file=self.outFile ) write('{', file=self.outFile) write(' assert(base != nullptr);', file=self.outFile) self.newline() write(' VkBaseInStructure* copy = nullptr;', file=self.outFile) write(' switch (base->sType)', file=self.outFile) write(' {', file=self.outFile) write(' default:', file=self.outFile) write( ' GFXRECON_LOG_WARNING("Failed to copy entire pNext chain when unwrapping handles due to unrecognized sType %d", base->sType);', file=self.outFile ) write(' break;', file=self.outFile) write( ' case VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO:', file=self.outFile ) write( ' copy = reinterpret_cast<VkBaseInStructure*>(MakeUnwrapStructs(reinterpret_cast<const VkLayerInstanceCreateInfo*>(base), 1, unwrap_memory));', file=self.outFile ) write(' break;', file=self.outFile) write( ' case VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO:', file=self.outFile ) write( ' copy = reinterpret_cast<VkBaseInStructure*>(MakeUnwrapStructs(reinterpret_cast<const VkLayerDeviceCreateInfo*>(base), 1, unwrap_memory));', file=self.outFile ) write(' break;', file=self.outFile) for base_type in self.pnext_structs_without_handles: write( ' case {}:'.format( self.pnext_structs_without_handles[base_type] ), file=self.outFile ) write( ' copy = reinterpret_cast<VkBaseInStructure*>(MakeUnwrapStructs(reinterpret_cast<const {}*>(base), 1, unwrap_memory));' .format(base_type), file=self.outFile ) write(' break;', file=self.outFile) write(' }', file=self.outFile) self.newline() write(' return copy;', file=self.outFile) write('}', file=self.outFile) # Generate the pNext handle wrapping code. self.newline() write( 'const void* UnwrapPNextStructHandles(const void* value, HandleUnwrapMemory* unwrap_memory)', file=self.outFile ) write('{', file=self.outFile) write(' if (value != nullptr)', file=self.outFile) write(' {', file=self.outFile) write( ' const VkBaseInStructure* base = reinterpret_cast<const VkBaseInStructure*>(value);', file=self.outFile ) self.newline() write(' switch (base->sType)', file=self.outFile) write(' {', file=self.outFile) write(' default:', file=self.outFile) write(' {', file=self.outFile) write( ' // This structure does not contain handles, but may point to a structure that does.', file=self.outFile ) write( ' VkBaseInStructure* copy = CopyPNextStruct(base, unwrap_memory);', file=self.outFile ) write(' if (copy != nullptr)', file=self.outFile) write(' {', file=self.outFile) write( ' copy->pNext = reinterpret_cast<const VkBaseInStructure*>(UnwrapPNextStructHandles(base->pNext, unwrap_memory));', file=self.outFile ) write(' }', file=self.outFile) write(' return copy;', file=self.outFile) write(' }', file=self.outFile) for base_type in self.pnext_structs_with_handles: write( ' case {}:'.format( self.pnext_structs_with_handles[base_type] ), file=self.outFile ) write( ' return UnwrapStructPtrHandles(reinterpret_cast<const {}*>(base), unwrap_memory);' .format(base_type), file=self.outFile ) write(' }', file=self.outFile) write(' }', file=self.outFile) self.newline() write(' return nullptr;', file=self.outFile) write('}', file=self.outFile) self.newline() write('GFXRECON_END_NAMESPACE(encode)', file=self.outFile) write('GFXRECON_END_NAMESPACE(gfxrecon)', file=self.outFile) # Finish processing in superclass BaseGenerator.endFile(self)
def beginFile(self, gen_opts): """Method override.""" BaseGenerator.beginFile(self, gen_opts) write( '#include "encode/custom_vulkan_struct_handle_wrappers.h"', file=self.outFile ) write('#include "encode/handle_unwrap_memory.h"', file=self.outFile) write( '#include "encode/vulkan_handle_wrapper_util.h"', file=self.outFile ) write('#include "format/platform_types.h"', file=self.outFile) write('#include "util/defines.h"', file=self.outFile) self.newline() self.includeVulkanHeaders(gen_opts) self.newline() write('GFXRECON_BEGIN_NAMESPACE(gfxrecon)', file=self.outFile) write('GFXRECON_BEGIN_NAMESPACE(encode)', file=self.outFile)
def generate_no_op_funcs(self): """Generate no-op function definitions.""" write('GFXRECON_BEGIN_NAMESPACE(noop)', file=self.outFile) write('// clang-format off', file=self.outFile) for name in self.instance_cmd_names: write(self.instance_cmd_names[name], file=self.outFile) for name in self.device_cmd_names: write(self.device_cmd_names[name], file=self.outFile) write('// clang-format on', file=self.outFile) write('GFXRECON_END_NAMESPACE(noop)', file=self.outFile)
def endFile(self): if not self.is_dx12_class(): # Generate the pNext handle mapping code. self.newline() write( 'void MapPNextStructHandles(const void* value, void* wrapper, const VulkanObjectInfoTable& object_info_table)', file=self.outFile) write('{', file=self.outFile) write(' if ((value != nullptr) && (wrapper != nullptr))', file=self.outFile) write(' {', file=self.outFile) write( ' const VkBaseInStructure* base = reinterpret_cast<const VkBaseInStructure*>(value);', file=self.outFile) write('', file=self.outFile) write(' switch (base->sType)', file=self.outFile) write(' {', file=self.outFile) write(' default:', file=self.outFile) write( ' // TODO: Report or raise fatal error for unrecongized sType?', file=self.outFile) write(' break;', file=self.outFile) for base_type in self.pnext_structs: write(' case {}:'.format(self.pnext_structs[base_type]), file=self.outFile) write( ' MapStructHandles(reinterpret_cast<Decoded_{}*>(wrapper), object_info_table);' .format(base_type), file=self.outFile) write(' break;', file=self.outFile) write(' }', file=self.outFile) write(' }', file=self.outFile) write('}', file=self.outFile) # Generate handle adding functions for output structs with handles for struct in self.output_structs_with_handles: self.newline() write(self.make_struct_handle_additions( struct, self.structs_with_handles[struct]), file=self.outFile) # Generate handle memory allocation functions for output structs with handles for struct in self.output_structs_with_handles: if struct in self.structs_with_handle_ptrs: self.newline() write(self.make_struct_handle_allocations( struct, self.structs_with_handles[struct]), file=self.outFile) self.newline() write('GFXRECON_END_NAMESPACE(decode)', file=self.outFile) write('GFXRECON_END_NAMESPACE(gfxrecon)', file=self.outFile)
def beginFile(self, gen_opts): """Method override.""" BaseGenerator.beginFile(self, gen_opts) write('#include "decode/custom_vulkan_struct_decoders.h"', file=self.outFile) write('#include "decode/decode_allocator.h"', file=self.outFile) write('#include "decode/pnext_node.h"', file=self.outFile) write('#include "decode/pnext_typed_node.h"', file=self.outFile) write('#include "generated/generated_vulkan_struct_decoders.h"', file=self.outFile) write('#include "util/logging.h"', file=self.outFile) self.newline() write('#include <cassert>', file=self.outFile) self.newline() write('GFXRECON_BEGIN_NAMESPACE(gfxrecon)', file=self.outFile) write('GFXRECON_BEGIN_NAMESPACE(decode)', file=self.outFile) self.newline() write( 'size_t DecodePNextStruct(const uint8_t* parameter_buffer, size_t buffer_size, PNextNode** pNext)', file=self.outFile) write('{', file=self.outFile) write(' assert(pNext != nullptr);', file=self.outFile) self.newline() write(' size_t bytes_read = 0;', file=self.outFile) write(' uint32_t attrib = 0;', file=self.outFile) self.newline() write( ' if ((parameter_buffer != nullptr) && (buffer_size >= sizeof(attrib)))', file=self.outFile) write(' {', file=self.outFile) write(' size_t stype_offset = 0;', file=self.outFile) self.newline() write( ' // Peek at the pointer attribute mask to make sure we have a non-NULL value that can be decoded.', file=self.outFile) write( ' attrib = *(reinterpret_cast<const uint32_t*>(parameter_buffer));', file=self.outFile) self.newline() write( ' if ((attrib & format::PointerAttributes::kIsNull) != format::PointerAttributes::kIsNull)', file=self.outFile) write(' {', file=self.outFile) write( ' // Offset to VkStructureType, after the pointer encoding preamble.', file=self.outFile) write(' stype_offset = sizeof(attrib);', file=self.outFile) self.newline() write( ' if ((attrib & format::PointerAttributes::kHasAddress) == format::PointerAttributes::kHasAddress)', file=self.outFile) write(' {', file=self.outFile) write( ' stype_offset += sizeof(format::AddressEncodeType);', file=self.outFile) write(' }', file=self.outFile) write(' }', file=self.outFile) self.newline() write( ' if ((stype_offset != 0) && ((buffer_size - stype_offset) >= sizeof(VkStructureType)))', file=self.outFile) write(' {', file=self.outFile) write( ' const VkStructureType* sType = reinterpret_cast<const VkStructureType*>(parameter_buffer + stype_offset);', file=self.outFile) self.newline() write(' switch (*sType)', file=self.outFile) write(' {', file=self.outFile) write(' default:', file=self.outFile) write(' // TODO: This may need to be a fatal error', file=self.outFile) write( ' GFXRECON_LOG_ERROR("Failed to decode pNext value with unrecognized VkStructurType = %d", (*sType));', file=self.outFile) write(' break;', file=self.outFile)
def endFile(self): """Method override.""" self.newline() write('typedef const void* DispatchKey;', file=self.outFile) self.newline() write( '// Retrieve a dispatch key from a dispatchable handle', file=self.outFile ) write( 'static DispatchKey GetDispatchKey(const void* handle)', file=self.outFile ) write('{', file=self.outFile) write( ' const DispatchKey* dispatch_key = reinterpret_cast<const DispatchKey*>(handle);', file=self.outFile ) write(' return (*dispatch_key);', file=self.outFile) write('}', file=self.outFile) self.newline() self.generate_no_op_funcs() self.newline() write('struct LayerTable', file=self.outFile) write('{', file=self.outFile) write( ' PFN_vkCreateInstance CreateInstance{ nullptr };', file=self.outFile ) write( ' PFN_vkCreateDevice CreateDevice{ nullptr };', file=self.outFile ) write('};', file=self.outFile) self.newline() self.generate_instance_cmd_table() self.newline() self.generate_device_cmd_table() self.newline() write( 'template <typename GetProcAddr, typename Handle, typename FuncP>', file=self.outFile ) write( 'static void LoadFunction(GetProcAddr gpa, Handle handle, const char* name, FuncP* funcp)', file=self.outFile ) write('{', file=self.outFile) write( ' FuncP result = reinterpret_cast<FuncP>(gpa(handle, name));', file=self.outFile ) write(' if (result != nullptr)', file=self.outFile) write(' {', file=self.outFile) write(' (*funcp) = result;', file=self.outFile) write(' }', file=self.outFile) write('}', file=self.outFile) self.newline() self.generate_load_instance_table_func() self.newline() self.generate_load_device_table_func() self.newline() write('GFXRECON_END_NAMESPACE(encode)', file=self.outFile) write('GFXRECON_END_NAMESPACE(gfxrecon)', file=self.outFile) # Finish processing in superclass BaseGenerator.endFile(self)
def endFile(self): """Method override.""" write(' }', file=self.outFile) write(' }', file=self.outFile) write(' }', file=self.outFile) self.newline() write(' if ((bytes_read == 0) && (attrib != 0))', file=self.outFile) write(' {', file=self.outFile) write( ' // The encoded pointer attribute mask included kIsNull, or the sType was unrecognized.', file=self.outFile) write( ' // We will report that we read the attribute mask, but nothing else was decoded.', file=self.outFile) write(' bytes_read = sizeof(attrib);', file=self.outFile) write(' }', file=self.outFile) self.newline() write(' return bytes_read;', file=self.outFile) write('}', file=self.outFile) self.newline() write('GFXRECON_END_NAMESPACE(decode)', file=self.outFile) write('GFXRECON_END_NAMESPACE(gfxrecon)', file=self.outFile) # Finish processing in superclass BaseGenerator.endFile(self)
def beginFile(self, gen_opts): """Method override.""" BaseGenerator.beginFile(self, gen_opts) if gen_opts.replay_overrides: self.__load_replay_overrides(gen_opts.replay_overrides) write('#include "generated/generated_vulkan_replay_consumer.h"', file=self.outFile) self.newline() write('#include "decode/custom_vulkan_struct_handle_mappers.h"', file=self.outFile) write('#include "decode/vulkan_handle_mapping_util.h"', file=self.outFile) write('#include "generated/generated_vulkan_dispatch_table.h"', file=self.outFile) write('#include "generated/generated_vulkan_struct_handle_mappers.h"', file=self.outFile) write('#include "util/defines.h"', file=self.outFile) self.newline() write('GFXRECON_BEGIN_NAMESPACE(gfxrecon)', file=self.outFile) write('GFXRECON_BEGIN_NAMESPACE(decode)', file=self.outFile)
def beginFile(self, gen_opts): """Method override.""" BaseGenerator.beginFile(self, gen_opts) write('#include "encode/parameter_encoder.h"', file=self.outFile) write('#include "format/platform_types.h"', file=self.outFile) write('#include "util/defines.h"', file=self.outFile) self.newline() self.includeVulkanHeaders(gen_opts) self.newline() write('#include <cstdint>', file=self.outFile) self.newline() write('GFXRECON_BEGIN_NAMESPACE(gfxrecon)', file=self.outFile) write('GFXRECON_BEGIN_NAMESPACE(encode)', file=self.outFile) self.newline() write( 'void EncodePNextStruct(ParameterEncoder* encoder, const void* value);', file=self.outFile)
def beginFile(self, gen_opts): """Method override.""" BaseGenerator.beginFile(self, gen_opts) write( '#include "decode/{}"'.format(gen_opts.base_class_header), file=self.outFile ) write('#include "util/defines.h"', file=self.outFile) self.newline() self.includeVulkanHeaders(gen_opts) self.newline() write('GFXRECON_BEGIN_NAMESPACE(gfxrecon)', file=self.outFile) write('GFXRECON_BEGIN_NAMESPACE(decode)', file=self.outFile) self.newline() write( 'class {class_name} : public {class_name}Base'.format( class_name=gen_opts.class_name ), file=self.outFile ) write('{', file=self.outFile) write(' public:', file=self.outFile) if gen_opts.constructor_args: arg_list = ', '.join( [ arg.split(' ')[-1] for arg in gen_opts.constructor_args.split(',') ] ) write( ' {class_name}({}) : {class_name}Base({}) {{ }}\n'.format( gen_opts.constructor_args, arg_list, class_name=gen_opts.class_name ), file=self.outFile ) else: write( ' {}() {{ }}\n'.format(gen_opts.class_name), file=self.outFile ) write( ' virtual ~{}() override {{ }}'.format(gen_opts.class_name), file=self.outFile )
def generate_load_device_table_func(self): """Generate function to set the device table's functions with a getprocaddress routine.""" write( 'static void LoadDeviceTable(PFN_vkGetDeviceProcAddr gpa, VkDevice device, DeviceTable* table)', file=self.outFile ) write('{', file=self.outFile) write(' assert(table != nullptr);', file=self.outFile) self.newline() for name in self.device_cmd_names: if name == 'vkGetDeviceProcAddr': write(' table->GetDeviceProcAddr = gpa;', file=self.outFile) else: expr = ' LoadFunction(gpa, device, "{}", &table->{});'.format( name, name[2:] ) write(expr, file=self.outFile) write('}', file=self.outFile)
def beginFile(self, gen_opts): """Method override.""" BaseGenerator.beginFile(self, gen_opts) class_name = 'VulkanReferencedResourceConsumer' write('#include "decode/vulkan_referenced_resource_consumer_base.h"', file=self.outFile) write('#include "util/defines.h"', file=self.outFile) self.newline() self.includeVulkanHeaders(gen_opts) self.newline() write('GFXRECON_BEGIN_NAMESPACE(gfxrecon)', file=self.outFile) write('GFXRECON_BEGIN_NAMESPACE(decode)', file=self.outFile) self.newline() write('class {name} : public {name}Base'.format(name=class_name), file=self.outFile) write('{', file=self.outFile) write(' public:', file=self.outFile) write(' {}() {{ }}\n'.format(class_name), file=self.outFile) write(' virtual ~{}() override {{ }}'.format(class_name), file=self.outFile)
def beginFile(self, gen_opts): """Method override.""" BaseGenerator.beginFile(self, gen_opts) write('#include "format/platform_types.h"', file=self.outFile) write('#include "util/defines.h"', file=self.outFile) write('#include "util/logging.h"', file=self.outFile) self.newline() write('#include "vulkan/vk_layer.h"', file=self.outFile) self.includeVulkanHeaders(gen_opts) self.newline() write('#ifdef WIN32', file=self.outFile) write('#ifdef CreateEvent', file=self.outFile) write('#undef CreateEvent', file=self.outFile) write('#endif', file=self.outFile) write('#ifdef CreateSemaphore', file=self.outFile) write('#undef CreateSemaphore', file=self.outFile) write('#endif', file=self.outFile) write('#endif', file=self.outFile) self.newline() write('GFXRECON_BEGIN_NAMESPACE(gfxrecon)', file=self.outFile) write('GFXRECON_BEGIN_NAMESPACE(encode)', file=self.outFile)
def generate_feature(self): """Performs C++ code generation for the feature.""" platform_type = 'Vulkan' map_types = 'Handles' map_table = '' if self.is_dx12_class(): platform_type = 'Dx12' map_types = 'Objects' map_table = ', const graphics::Dx12GpuVaMap& gpu_va_map' for struct in self.get_filtered_struct_names(): if ((struct in self.structs_with_handles) or (struct in self.GENERIC_HANDLE_STRUCTS) or (struct in self.structs_with_map_data)): handle_members = list() generic_handle_members = dict() if struct in self.structs_with_handles: handle_members = self.structs_with_handles[struct].copy() if struct in self.structs_with_map_data: handle_members.extend( self.structs_with_map_data[struct].copy()) if struct in self.GENERIC_HANDLE_STRUCTS: generic_handle_members = self.GENERIC_HANDLE_STRUCTS[ struct] # Determine if the struct only contains members that are structs that contain handles or static arrays of handles, # and does not need a temporary variable referencing the struct value. needs_value_ptr = False if generic_handle_members: needs_value_ptr = True else: for member in handle_members: if ((self.is_handle(member.base_type) or self.is_class(member)) and not (member.is_array and not member.is_dynamic) ) or (member.base_type in self.MAP_STRUCT_TYPE): needs_value_ptr = True break body = '\n' body += 'void MapStruct{}(Decoded_{}* wrapper, const {}ObjectInfoTable& object_info_table{})\n'.format( map_types, struct, platform_type, map_table) body += '{\n' if not needs_value_ptr: body += ' if (wrapper != nullptr)\n' body += ' {' else: body += ' if ((wrapper != nullptr) && (wrapper->decoded_value != nullptr))\n' body += ' {\n' body += ' {}* value = wrapper->decoded_value;\n'.format( struct) body += self.make_struct_handle_mappings( struct, handle_members, generic_handle_members) body += ' }\n' body += '}' write(body, file=self.outFile)
def generate_decode_cases(self): """Generate the VulkanDecoder::DecodeFunctionCall method.""" write( 'void VulkanDecoder::DecodeFunctionCall(format::ApiCallId call_id,', file=self.outFile) write( ' const ApiCallInfo& call_info,', file=self.outFile) write( ' const uint8_t* parameter_buffer,', file=self.outFile) write( ' size_t buffer_size)', file=self.outFile) write('{', file=self.outFile) write(' switch(call_id)', file=self.outFile) write(' {', file=self.outFile) write(' default:', file=self.outFile) write( ' VulkanDecoderBase::DecodeFunctionCall(call_id, call_info, parameter_buffer, buffer_size);', file=self.outFile) write(' break;', file=self.outFile) for cmd in self.cmd_names: cmddef = ' case format::ApiCallId::ApiCall_{}:\n'.format(cmd) cmddef += ' Decode_{}(parameter_buffer, buffer_size);\n'.format( cmd) cmddef += ' break;' write(cmddef, file=self.outFile) write(' }', file=self.outFile) write('}\n', file=self.outFile)
def beginFile(self, gen_opts): """Method override.""" BaseGenerator.beginFile(self, gen_opts) write( '#include "generated/generated_vulkan_struct_handle_mappers.h"', file=self.outFile ) self.newline() write( '#include "decode/custom_vulkan_struct_decoders.h"', file=self.outFile ) write('#include "decode/handle_pointer_decoder.h"', file=self.outFile) write( '#include "decode/vulkan_handle_mapping_util.h"', file=self.outFile ) write( '#include "generated/generated_vulkan_struct_decoders.h"', file=self.outFile ) self.newline() write('#include <algorithm>', file=self.outFile) write('#include <cassert>', file=self.outFile) self.newline() write('GFXRECON_BEGIN_NAMESPACE(gfxrecon)', file=self.outFile) write('GFXRECON_BEGIN_NAMESPACE(decode)', file=self.outFile)
def endFile(self): """Method override.""" self.newline() write( 'const void* UnwrapPNextStructHandles(const void* value, HandleUnwrapMemory* unwrap_memory);', file=self.outFile ) self.newline() self.generate_create_wrapper_funcs() write( 'template <typename ParentWrapper, typename CoParentWrapper, typename T>', file=self.outFile ) write( 'void CreateWrappedStructArrayHandles(typename ParentWrapper::HandleType parent, typename CoParentWrapper::HandleType co_parent, T* value, size_t len, PFN_GetHandleId get_id)', file=self.outFile ) write('{', file=self.outFile) write(' if (value != nullptr)', file=self.outFile) write(' {', file=self.outFile) write(' for (size_t i = 0; i < len; ++i)', file=self.outFile) write(' {', file=self.outFile) write( ' CreateWrappedStructHandles<ParentWrapper, CoParentWrapper>(parent, co_parent, &value[i], get_id);', file=self.outFile ) write(' }', file=self.outFile) write(' }', file=self.outFile) write('}', file=self.outFile) self.newline() write('template <typename T>', file=self.outFile) write( 'T* MakeUnwrapStructs(const T* values, size_t len, HandleUnwrapMemory* unwrap_memory)', file=self.outFile ) write('{', file=self.outFile) write( ' assert((values != nullptr) && (len > 0) && (unwrap_memory != nullptr));', file=self.outFile ) self.newline() write( ' const uint8_t* bytes = reinterpret_cast<const uint8_t*>(values);', file=self.outFile ) write( ' size_t num_bytes = len * sizeof(T);', file=self.outFile ) self.newline() write( ' return reinterpret_cast<T*>(unwrap_memory->GetFilledBuffer(bytes, num_bytes));', file=self.outFile ) write('}', file=self.outFile) self.newline() write('template <typename T>', file=self.outFile) write( 'const T* UnwrapStructPtrHandles(const T* value, HandleUnwrapMemory* unwrap_memory)', file=self.outFile ) write('{', file=self.outFile) write(' T* unwrapped_struct = nullptr;', file=self.outFile) self.newline() write(' if (value != nullptr)', file=self.outFile) write(' {', file=self.outFile) write( ' unwrapped_struct = MakeUnwrapStructs(value, 1, unwrap_memory);', file=self.outFile ) write( ' UnwrapStructHandles(unwrapped_struct, unwrap_memory);', file=self.outFile ) write(' }', file=self.outFile) self.newline() write(' return unwrapped_struct;', file=self.outFile) write('}', file=self.outFile) self.newline() write('template <typename T>', file=self.outFile) write( 'const T* UnwrapStructArrayHandles(const T* values, size_t len, HandleUnwrapMemory* unwrap_memory)', file=self.outFile ) write('{', file=self.outFile) write(' if ((values != nullptr) && (len > 0))', file=self.outFile) write(' {', file=self.outFile) write( ' auto unwrapped_structs = MakeUnwrapStructs(values, len, unwrap_memory);', file=self.outFile ) self.newline() write(' for (size_t i = 0; i < len; ++i)', file=self.outFile) write(' {', file=self.outFile) write( ' UnwrapStructHandles(&unwrapped_structs[i], unwrap_memory);', file=self.outFile ) write(' }', file=self.outFile) self.newline() write(' return unwrapped_structs;', file=self.outFile) write(' }', file=self.outFile) self.newline() write( ' // Leave the original memory in place when the pointer is not null, but size is zero.', file=self.outFile ) write(' return values;', file=self.outFile) write('}', file=self.outFile) self.newline() write('GFXRECON_END_NAMESPACE(encode)', file=self.outFile) write('GFXRECON_END_NAMESPACE(gfxrecon)', file=self.outFile) # Finish processing in superclass BaseGenerator.endFile(self)