glave: Simplify codegen for trace packet sizing
diff --git a/glave-generate.py b/glave-generate.py
index 166a17f..20370e9 100755
--- a/glave-generate.py
+++ b/glave-generate.py
@@ -344,64 +344,105 @@
         um_body.append('}\n')
         return "\n".join(um_body)
 
+    # Take a list of params and return a list of packet size elements
+    def _get_packet_size(self, params):
+        ps = []
+        skip_list = [] # store params that are already accounted for so we don't count them twice
+        # Dict of specific params with unique custom sizes
+        custom_size_dict = {'xgl_shader_create_info': '((pCreateInfo != NULL) ? pCreateInfo->codeSize : 0) + sizeof(XGL_SHADER_CREATE_INFO)',
+                            'xgl_graphics_pipeline_create_info': '(calculate_pipeline_state_size(pCreateInfo->pNext)) + sizeof(XGL_GRAPHICS_PIPELINE_CREATE_INFO)',
+                            'pUpdateChain': 'sizeof(XGL_DESCRIPTOR_SET) + (calculate_update_descriptors_size(pUpdateChain))',
+                            'pSetBindPoints': '(XGL_SHADER_STAGE_COMPUTE * sizeof(uint32_t))', # Accounting for largest possible array
+                            'xgl_descriptor_set_layout_create_info': '(calculate_create_ds_layout_size(pSetLayoutInfoList))',
+                            'xgl_cmd_buffer_begin_info': 'sizeof(XGL_CMD_BUFFER_BEGIN_INFO) + (calculate_begin_cmdbuf_size(pBeginInfo->pNext))',
+                            'xgl_memory_alloc_info': 'sizeof(XGL_MEMORY_ALLOC_INFO) + calculate_alloc_memory_size(pAllocInfo->pNext)',
+                            'xgl_compute_pipeline_create_info': 'sizeof(XGL_COMPUTE_PIPELINE_CREATE_INFO) + calculate_pipeline_state_size(pCreateInfo->pNext)'}
+        for p in params:
+            #First handle custom cases
+            if p.ty.strip('*').replace('const ', '').lower() in custom_size_dict:
+                ps.append(custom_size_dict[p.ty.strip('*').replace('const ', '').lower()])
+                skip_list.append(p.name)
+            elif p.name in custom_size_dict:
+                ps.append(custom_size_dict[p.name])
+                skip_list.append(p.name)
+            # Skip any params already handled
+            if p.name in skip_list:
+                continue
+            # Now check to identify dynamic arrays which depend on two params
+            if 'count' in p.name.lower():
+                next_idx = params.index(p)+1
+                # If next element is a const *, then multiply count and array type
+                if next_idx < len(params) and '*' in params[next_idx].ty and 'const' in params[next_idx].ty.lower():
+                    if '*' in p.ty:
+                        ps.append('*%s*sizeof(%s)' % (p.name, params[next_idx].ty.strip('*').replace('const ', '')))
+                    else:
+                        ps.append('%s*sizeof(%s)' % (p.name, params[next_idx].ty.strip('*').replace('const ', '')))
+                    skip_list.append(params[next_idx].name)
+            elif '*' in p.ty and p.name not in ['pSysMem', 'pReserved']:
+                if 'pData' == p.name:
+                    if 'dataSize' == params[params.index(p)-1].name:
+                        ps.append('dataSize')
+                    elif 'counterCount' == params[params.index(p)-1].name:
+                        ps.append('sizeof(%s)' % p.ty.strip('*').replace('const ', ''))
+                    else:
+                        ps.append('((pDataSize != NULL && pData != NULL) ? *pDataSize : 0)')
+                elif '**' in p.ty and 'void' in p.ty:
+                    ps.append('sizeof(void*)')
+                elif 'void' in p.ty:
+                    ps.append('sizeof(%s)' % p.name)
+                elif 'char' in p.ty:
+                    ps.append('((%s != NULL) ? strlen(%s) + 1 : 0)' % (p.name, p.name))
+                elif 'DEVICE_CREATE_INFO' in p.ty:
+                    ps.append('calc_size_XGL_DEVICE_CREATE_INFO(pCreateInfo)')
+                elif 'pDataSize' in p.name:
+                    ps.append('((pDataSize != NULL) ? sizeof(size_t) : 0)')
+                elif 'IMAGE_SUBRESOURCE' in p.ty and 'pSubresource' == p.name:
+                    ps.append('((pSubresource != NULL) ? sizeof(XGL_IMAGE_SUBRESOURCE) : 0)')
+                else:
+                    ps.append('sizeof(%s)' % (p.ty.strip('*').replace('const ', '')))
+        return ps
+
     # Generate functions used to trace API calls and store the input and result data into a packet
+    # Here's the general flow of code insertion w/ option items flagged w/ "?"
+    # Result decl?
+    # Packet struct decl
+    # ?Special case : setup call to function first and do custom API call time tracking
+    # CREATE_PACKET
+    # Call (w/ result?)
+    # Assign packet values
+    # FINISH packet
+    # return result?
     def _generate_trace_funcs(self):
         func_body = []
         for proto in self.protos:
             if 'UnmapMemory' == proto.name:
                 func_body.append(self._gen_unmap_memory())
             elif 'Dbg' not in proto.name and 'Wsi' not in proto.name:
-                packet_update_txt = ''
+                raw_packet_update_list = [] # non-ptr elements placed directly into packet
                 return_txt = ''
-                packet_size = ''
+                packet_size = []
                 in_data_size = False # flag when we need to capture local input size variable for in/out size
                 buff_ptr_indices = []
                 func_body.append('GLVTRACER_EXPORT %s XGLAPI __HOOKED_xgl%s(' % (proto.ret, proto.name))
-                for p in proto.params: # TODO : For all of the ptr types, check them for NULL and return 0 is NULL
-                    if 'color' == p.name:
-                        func_body.append('    %s %s[4],' % (p.ty.replace('[4]', ''), p.name))
+                for p in proto.params: # TODO : For all of the ptr types, check them for NULL and return 0 if NULL
+                    if '[' in p.ty: # Correctly declare static arrays in function parameters
+                        func_body.append('    %s %s[%s],' % (p.ty[:p.ty.find('[')], p.name, p.ty[p.ty.find('[')+1:p.ty.find(']')]))
                     else:
                         func_body.append('    %s %s,' % (p.ty, p.name))
-                    if '*' in p.ty and 'pSysMem' != p.name and 'pReserved' != p.name:
-                        if 'pData' == p.name:
-                            if 'dataSize' == proto.params[proto.params.index(p)-1].name:
-                                packet_size += 'dataSize + '
-                            elif 'counterCount' == proto.params[proto.params.index(p)-1].name:
-                                packet_size += 'sizeof(%s) + ' % p.ty.strip('*').replace('const ', '')
-                            else:
-                                packet_size += '((pDataSize != NULL && pData != NULL) ? *pDataSize : 0) + '
-                        elif '**' in p.ty and 'void' in p.ty:
-                            packet_size += 'sizeof(void*) + '
-                        elif 'void' in p.ty:
-                            packet_size += 'sizeof(%s) + ' % p.name
-                        elif 'char' in p.ty:
-                            packet_size += '((%s != NULL) ? strlen(%s) + 1 : 0) + ' % (p.name, p.name)
-                        elif 'DEVICE_CREATE_INFO' in p.ty:
-                            packet_size += 'calc_size_XGL_DEVICE_CREATE_INFO(pCreateInfo) + '
-                        elif 'pDataSize' in p.name:
-                            packet_size += '((pDataSize != NULL) ? sizeof(size_t) : 0) + '
+                    if '*' in p.ty and p.name not in ['pSysMem', 'pReserved']:
+                        if 'pDataSize' in p.name:
                             in_data_size = True;
-                        elif 'IMAGE_SUBRESOURCE' in p.ty and 'pSubresource' == p.name:
-                            packet_size += '((pSubresource != NULL) ? sizeof(XGL_IMAGE_SUBRESOURCE) : 0) + '
-                        else:
-                            packet_size += 'sizeof(%s) + ' % p.ty.strip('*').replace('const ', '')
                         buff_ptr_indices.append(proto.params.index(p))
                     else:
-                        if 'color' == p.name:
+                        if '[' in p.ty:
                             array_str = p.ty[p.ty.find('[')+1:p.ty.find(']')]
-                            packet_update_txt += '    memcpy((void*)pPacket->color, color, %s * sizeof(%s));\n' % (array_str, p.ty.strip('*').replace('const ', '').replace('[%s]' % array_str, ''))
+                            raw_packet_update_list.append('    memcpy((void*)pPacket->color, color, %s * sizeof(%s));' % (array_str, p.ty.strip('*').replace('const ', '').replace('[%s]' % array_str, '')))
                         else:
-                            packet_update_txt += '    pPacket->%s = %s;\n' % (p.name, p.name)
-                    if 'Count' in p.name and proto.params[-1].name != p.name and p.name not in ['queryCount', 'vertexCount', 'indexCount', 'startCounter'] and proto.name not in ['CmdLoadAtomicCounters', 'CmdSaveAtomicCounters']:
-                        if '*' in p.ty:
-                            packet_size += '*%s*' % p.name
-                        else:
-                            packet_size += '%s*' % p.name
-                if '' == packet_size:
-                    packet_size = '0'
-                else:
-                    packet_size = packet_size.strip(' + ')
+                            raw_packet_update_list.append('    pPacket->%s = %s;' % (p.name, p.name))
+                # Get list of packet size modifiers due to ptr params
+                packet_size = self._get_packet_size(proto.params)
                 func_body[-1] = func_body[-1].replace(',', ')')
+                # End of function declaration portion, begin function body
                 func_body.append('{\n    glv_trace_packet_header* pHeader;')
                 if 'void' not in proto.ret or '*' in proto.ret:
                     func_body.append('    %s result;' % proto.ret)
@@ -410,7 +451,7 @@
                     func_body.append('    size_t _dataSize;')
                 func_body.append('    struct_xgl%s* pPacket = NULL;' % proto.name)
                 # functions that have non-standard sequence of  packet creation and calling real function
-                # NOTE: Anytime we call the function first, need to add custom code for correctly tracking API call time
+                # NOTE: Anytime we call the function before CREATE_TRACE_PACKET, need to add custom code for correctly tracking API call time
                 if 'CreateInstance' == proto.name:
                     func_body.append('    uint64_t startTime;')
                     func_body.append('    glv_platform_thread_once(&gInitOnce, InitTracer);')
@@ -454,25 +495,11 @@
                     func_body.append('    size_t customSize = (*pCount <= 0) ? (sizeof(XGL_DESCRIPTOR_SET)) : (*pCount * sizeof(XGL_DESCRIPTOR_SET));')
                     func_body.append('    CREATE_TRACE_PACKET(xglAllocDescriptorSets, sizeof(XGL_DESCRIPTOR_SET_LAYOUT) + customSize + sizeof(uint32_t));')
                     func_body.append('    pHeader->entrypoint_begin_time = startTime;')
-                elif proto.name in ['CreateShader', 'CreateFramebuffer', 'CreateRenderPass', 'BeginCommandBuffer', 'CreateDynamicViewportState', 
-                                    'AllocMemory', 'CreateGraphicsPipeline', 'CreateComputePipeline', 'UpdateDescriptors', 'CreateDescriptorSetLayout',
+                elif proto.name in ['CreateFramebuffer', 'CreateRenderPass', 'CreateDynamicViewportState', 
                                     'CreateDescriptorRegion', 'CmdWaitEvents', 'CmdPipelineBarrier']:
                     # these are regular case as far as sequence of tracing but custom sizes
                     func_body.append('    size_t customSize;')
-                    if 'CreateShader' == proto.name:
-                        func_body.append('    customSize = (pCreateInfo != NULL) ? pCreateInfo->codeSize : 0;')
-                        func_body.append('    CREATE_TRACE_PACKET(xglCreateShader, sizeof(XGL_SHADER_CREATE_INFO) + sizeof(XGL_SHADER) + customSize);')
-                    elif 'CreateGraphicsPipeline' == proto.name:
-                        func_body.append('    customSize = calculate_pipeline_state_size(pCreateInfo->pNext);')
-                        func_body.append('    CREATE_TRACE_PACKET(xglCreateGraphicsPipeline, sizeof(XGL_GRAPHICS_PIPELINE_CREATE_INFO) + sizeof(XGL_PIPELINE) + customSize);')
-                    elif 'UpdateDescriptors' == proto.name:
-                        func_body.append('    customSize = calculate_update_descriptors_size(pUpdateChain);')
-                        func_body.append('    CREATE_TRACE_PACKET(xglUpdateDescriptors, sizeof(XGL_DESCRIPTOR_SET) + customSize);')
-                    elif 'CreateDescriptorSetLayout' == proto.name:
-                        func_body.append('    customSize = calculate_create_ds_layout_size(pSetLayoutInfoList);')
-                        # NOTE : Just allocating enough packet size to account for largest array of uints
-                        func_body.append('    CREATE_TRACE_PACKET(xglCreateDescriptorSetLayout, XGL_SHADER_STAGE_COMPUTE * sizeof(uint32_t) + sizeof(XGL_DESCRIPTOR_SET_LAYOUT) + customSize);')
-                    elif 'CreateFramebuffer' == proto.name:
+                    if 'CreateFramebuffer' == proto.name:
                         func_body.append('    int dsSize = (pCreateInfo != NULL && pCreateInfo->pDepthStencilAttachment != NULL) ? sizeof(XGL_DEPTH_STENCIL_BIND_INFO) : 0;')
                         func_body.append('    uint32_t colorCount = (pCreateInfo != NULL && pCreateInfo->pColorAttachments != NULL) ? pCreateInfo->colorAttachmentCount : 0;')
                         func_body.append('    customSize = colorCount * sizeof(XGL_COLOR_ATTACHMENT_BIND_INFO) + dsSize;')
@@ -483,21 +510,15 @@
                         func_body.append('    customSize += colorCount * ((pCreateInfo->pColorStoreOps != NULL) ? sizeof(XGL_ATTACHMENT_STORE_OP) : 0);')
                         func_body.append('    customSize += colorCount * ((pCreateInfo->pColorLoadClearValues != NULL) ? sizeof(XGL_CLEAR_COLOR) : 0);')
                         func_body.append('    CREATE_TRACE_PACKET(xglCreateRenderPass, sizeof(XGL_RENDER_PASS_CREATE_INFO) + sizeof(XGL_RENDER_PASS) + customSize);')
-                    elif 'BeginCommandBuffer' == proto.name:
-                        func_body.append('    customSize = calculate_begin_cmdbuf_size(pBeginInfo->pNext);')
-                        func_body.append('    CREATE_TRACE_PACKET(xglBeginCommandBuffer, sizeof(XGL_CMD_BUFFER_BEGIN_INFO) + customSize);')
                     elif 'CreateDynamicViewportState' == proto.name:
                         func_body.append('    uint32_t vpsCount = (pCreateInfo != NULL && pCreateInfo->pViewports != NULL) ? pCreateInfo->viewportAndScissorCount : 0;')
                         func_body.append('    customSize = vpsCount * sizeof(XGL_VIEWPORT) + vpsCount * sizeof(XGL_RECT);')
                         func_body.append('    CREATE_TRACE_PACKET(xglCreateDynamicViewportState,  sizeof(XGL_DYNAMIC_VP_STATE_CREATE_INFO) + sizeof(XGL_DYNAMIC_VP_STATE_OBJECT) + customSize);')
-                    elif 'AllocMemory' == proto.name:
-                        func_body.append('    customSize = calculate_alloc_memory_size(pAllocInfo->pNext);')
-                        func_body.append('    CREATE_TRACE_PACKET(xglAllocMemory,  sizeof(XGL_MEMORY_ALLOC_INFO) + sizeof(XGL_GPU_MEMORY) + customSize);')
                     elif 'CreateDescriptorRegion' == proto.name:
                         func_body.append('    uint32_t rgCount = (pCreateInfo != NULL && pCreateInfo->pTypeCount != NULL) ? pCreateInfo->count : 0;')
                         func_body.append('    customSize = rgCount * sizeof(XGL_DESCRIPTOR_TYPE_COUNT);')
                         func_body.append('    CREATE_TRACE_PACKET(xglCreateDescriptorRegion,  sizeof(XGL_DESCRIPTOR_REGION_CREATE_INFO) + sizeof(XGL_DESCRIPTOR_REGION) + customSize);')
-                    elif proto.name in ['CmdWaitEvents', 'CmdPipelineBarrier']:
+                    else: # ['CmdWaitEvents', 'CmdPipelineBarrier']:
                         event_array_type = 'XGL_EVENT'
                         if 'CmdPipelineBarrier' == proto.name:
                             event_array_type = 'XGL_SET_EVENT'
@@ -505,17 +526,17 @@
                         func_body.append('    uint32_t mbCount = (%s != NULL && %s->ppMemBarriers != NULL) ? %s->memBarrierCount : 0;' % (proto.params[-1].name, proto.params[-1].name, proto.params[-1].name))
                         func_body.append('    customSize = (eventCount * sizeof(%s)) + mbCount * sizeof(void*) + calculate_memory_barrier_size(mbCount, %s->ppMemBarriers);' % (event_array_type, proto.params[-1].name))
                         func_body.append('    CREATE_TRACE_PACKET(xgl%s, sizeof(%s) + customSize);' % (proto.name, proto.params[-1].ty.strip('*').replace('const ', '')))
-                    else: #'CreateComputePipeline'
-                        func_body.append('    customSize = calculate_pipeline_state_size(pCreateInfo->pNext);')
-                        func_body.append('    CREATE_TRACE_PACKET(xglCreateComputePipeline, sizeof(XGL_COMPUTE_PIPELINE_CREATE_INFO) + sizeof(XGL_PIPELINE) + customSize + calculate_pipeline_shader_size(&pCreateInfo->cs));')
                     func_body.append('    %sreal_xgl%s;' % (return_txt, proto.c_call()))
                 else:
-                    func_body.append('    CREATE_TRACE_PACKET(xgl%s, %s);' % (proto.name, packet_size))
+                    if (0 == len(packet_size)):
+                        func_body.append('    CREATE_TRACE_PACKET(xgl%s, 0);' % (proto.name))
+                    else:
+                        func_body.append('    CREATE_TRACE_PACKET(xgl%s, %s);' % (proto.name, ' + '.join(packet_size)))
                     func_body.append('    %sreal_xgl%s;' % (return_txt, proto.c_call()))
                 if in_data_size:
                     func_body.append('    _dataSize = (pDataSize == NULL || pData == NULL) ? 0 : *pDataSize;')
                 func_body.append('    pPacket = interpret_body_as_xgl%s(pHeader);' % proto.name)
-                func_body.append(packet_update_txt.strip('\n'))
+                func_body.append('\n'.join(raw_packet_update_list))
                 if 'MapMemory' == proto.name: # Custom code for MapMem case
                     func_body.append('    if (ppData != NULL)')
                     func_body.append('    {')
@@ -575,7 +596,7 @@
                                       'AllocMemory', 'UpdateDescriptors', 'CreateDescriptorSetLayout', 'CreateGraphicsPipeline', 'CreateComputePipeline',
                                       'CreateDescriptorRegion', 'CmdWaitEvents', 'CmdPipelineBarrier']:
                         if 'CreateShader' == proto.name:
-                            func_body.append('    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo->pCode), customSize, pCreateInfo->pCode);')
+                            func_body.append('    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo->pCode), ((pCreateInfo != NULL) ? pCreateInfo->codeSize : 0), pCreateInfo->pCode);')
                             func_body.append('    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo->pCode));')
                         elif 'CreateFramebuffer' == proto.name:
                             func_body.append('    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo->pColorAttachments), colorCount * sizeof(XGL_COLOR_ATTACHMENT_BIND_INFO), pCreateInfo->pColorAttachments);')
@@ -1559,6 +1580,7 @@
         return "\n".join(pid_enum)
 
     # Interpret functions used on replay to read in packets and interpret their contents
+    #  This code gets generated into glvtrace_xgl_xgl_structs.h file
     def _generate_interp_funcs(self):
         # Custom txt for given function and parameter.  First check if param is NULL, then insert txt if not
         # TODO : This code is now too large and complex, need to make codegen smarter for pointers embedded in struct params to handle those cases automatically
@@ -1837,6 +1859,8 @@
                             if_body.append('    pPacket->%s = interpret_XGL_DEVICE_CREATE_INFO(pHeader, (intptr_t)pPacket->%s);' % (p.name, p.name))
                         else:
                             if_body.append('    pPacket->%s = (%s)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->%s);' % (p.name, p.ty, p.name))
+                        # TODO : Generalize this custom code to kill dict data struct above.
+                        #  Really the point of this block is to catch params w/ embedded ptrs to structs and chains of structs
                         if proto.name in custom_case_dict and p.name == custom_case_dict[proto.name]['param']:
                             if_body.append('    if (pPacket->%s != NULL)' % custom_case_dict[proto.name]['param'])
                             if_body.append('    {')