um_body.append(' XGL_RESULT result;')
um_body.append(' struct_xglUnmapMemory* pPacket;')
um_body.append(' XGLAllocInfo *entry;')
- um_body.append(' SEND_ENTRYPOINT_PARAMS("xglUnmapMemory(mem %p)\\n", mem);')
+ um_body.append(' size_t siz = 0;')
um_body.append(' // insert into packet the data that was written by CPU between the xglMapMemory call and here')
um_body.append(' // Note must do this prior to the real xglUnMap() or else may get a FAULT')
um_body.append(' glv_enter_critical_section(&g_memInfoLock);')
um_body.append(' entry = find_mem_info_entry(mem);')
- um_body.append(' CREATE_TRACE_PACKET(xglUnmapMemory, (entry) ? entry->size : 0);')
+ um_body.append(' if (entry != NULL && entry->rangeSize == 0 && entry->rangeOffset == 0)')
+ um_body.append(' // no xglRecordMemoryRange has occured so copy entire buffer')
+ um_body.append(' siz = entry->size;')
+ um_body.append(' CREATE_TRACE_PACKET(xglUnmapMemory, siz);')
um_body.append(' pPacket = interpret_body_as_xglUnmapMemory(pHeader);')
- um_body.append(' if (entry)')
+ um_body.append(' if (siz)')
um_body.append(' {')
um_body.append(' assert(entry->handle == mem);')
- um_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**) &(pPacket->pData), entry->size, entry->pData);')
+ um_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**) &(pPacket->pData), siz, entry->pData);')
um_body.append(' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pData));')
um_body.append(' entry->pData = NULL;')
- um_body.append(' } else')
- um_body.append(' {')
- um_body.append(' glv_LogError("Failed to copy app memory into trace packet (idx = %u) on xglUnmapMemory\\n", pHeader->global_packet_index);')
um_body.append(' }')
um_body.append(' glv_leave_critical_section(&g_memInfoLock);')
um_body.append(' result = real_xglUnmapMemory(mem);')
um_body.append(' pPacket->mem = mem;')
+ um_body.append(' pPacket->size = siz;')
um_body.append(' pPacket->result = result;')
um_body.append(' FINISH_TRACE_PACKET();')
um_body.append(' return result;')
um_body.append('}\n')
return "\n".join(um_body)
+ def _gen_record_memory_range(self):
+ rmr_body = []
+ rmr_body.append('GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglRecordMemoryRange(')
+ rmr_body.append(' XGL_GPU_MEMORY mem,')
+ rmr_body.append(' XGL_GPU_SIZE rangeSize,')
+ rmr_body.append(' XGL_GPU_SIZE rangeOffset)')
+ rmr_body.append('{')
+ rmr_body.append(' glv_trace_packet_header* pHeader;')
+ rmr_body.append(' XGL_RESULT result;')
+ rmr_body.append(' size_t siz;')
+ rmr_body.append(' XGLAllocInfo *entry;')
+ rmr_body.append(' struct_xglRecordMemoryRange* pPacket;')
+ rmr_body.append(' // insert into packet the data that was written by CPU between the xglMapMemory call and here')
+ rmr_body.append(' glv_enter_critical_section(&g_memInfoLock);')
+ rmr_body.append(' entry = find_mem_info_entry(mem);')
+ rmr_body.append(' siz = (entry) ? rangeSize : 0;')
+ rmr_body.append(' CREATE_TRACE_PACKET(xglRecordMemoryRange, siz);')
+ rmr_body.append(' pPacket = interpret_body_as_xglRecordMemoryRange(pHeader);')
+ rmr_body.append(' if (siz)')
+ rmr_body.append(' {')
+ rmr_body.append(' assert(entry->size >= rangeSize + rangeOffset);')
+ rmr_body.append(' assert(entry->handle == mem);')
+ rmr_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**) &(pPacket->pData), siz, entry->pData + rangeOffset);')
+ rmr_body.append(' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pData));')
+ rmr_body.append(' entry->pData = NULL;')
+ rmr_body.append(' entry->rangeSize = rangeSize;')
+ rmr_body.append(' entry->rangeOffset = (rangeSize == 0) ? 0 : rangeOffset;')
+ rmr_body.append(' } else')
+ rmr_body.append(' {')
+ rmr_body.append(' glv_LogError("Failed to copy app memory into trace packet (idx = %u) on xglUnmapMemory\\n", pHeader->global_packet_index);')
+ rmr_body.append(' }')
+ rmr_body.append(' glv_leave_critical_section(&g_memInfoLock);')
+ rmr_body.append(' result = real_xglRecordMemoryRange(mem, rangeSize, rangeOffset);')
+ rmr_body.append(' pPacket->mem = mem;')
+ rmr_body.append(' pPacket->rangeSize = rangeSize;')
+ rmr_body.append(' pPacket->rangeOffset = rangeOffset;')
+ rmr_body.append(' pPacket->result = result;')
+ rmr_body.append(' FINISH_TRACE_PACKET();')
+ rmr_body.append(' return result;')
+ rmr_body.append('}\n')
+ return "\n".join(rmr_body)
+
# Generate functions used to trace API calls and store the input and result data into a packet
def _generate_trace_funcs(self):
func_body = []
for proto in self.protos:
if 'UnmapMemory' == proto.name:
func_body.append(self._gen_unmap_memory())
+ elif 'RecordMemoryRange' == proto.name:
+ func_body.append(self._gen_record_memory_range())
elif 'Dbg' not in proto.name and 'Wsi' not in proto.name:
packet_update_txt = ''
return_txt = ''
hf_body.append(' XGL_GPU_SIZE size;')
hf_body.append(' XGL_GPU_MEMORY handle;')
hf_body.append(' void *pData;')
+ hf_body.append(' XGL_GPU_SIZE rangeOffset;')
+ hf_body.append(' XGL_GPU_SIZE rangeSize;')
hf_body.append(' BOOL valid;')
hf_body.append('} XGLAllocInfo;')
hf_body.append('typedef struct _XGLMemInfo {')
hf_body.append('')
hf_body.append('static void init_mem_info_entrys(XGLAllocInfo *ptr, const unsigned int num)')
hf_body.append('{')
- hf_body.append(' unsigned int i;')
- hf_body.append(' for (i = 0; i < num; i++)')
- hf_body.append(' {')
- hf_body.append(' XGLAllocInfo *entry = ptr + i;')
- hf_body.append(' entry->pData = NULL;')
- hf_body.append(' entry->size = 0;')
- hf_body.append(' entry->handle = NULL;')
- hf_body.append(' entry->valid = FALSE;')
- hf_body.append(' }')
+ hf_body.append(' memset(ptr, 0, num * sizeof(XGLAllocInfo));')
hf_body.append('}')
hf_body.append('')
hf_body.append('// caller must hold the g_memInfoLock')
hf_body.append(' if (entry)')
hf_body.append(' {')
hf_body.append(' entry->pData = pData;')
+ hf_body.append(' entry->rangeSize = 0;')
+ hf_body.append(' entry->rangeOffset = 0;')
hf_body.append(' }')
hf_body.append(' g_memInfo.pLastMapped = entry;')
hf_body.append(' glv_leave_critical_section(&g_memInfoLock);')
hf_body.append(' entry->valid = FALSE;')
hf_body.append(' entry->pData = NULL;')
hf_body.append(' entry->size = 0;')
+ hf_body.append(' entry->rangeSize = 0;')
+ hf_body.append(' entry->rangeOffset = 0;')
hf_body.append(' entry->handle = NULL;')
hf_body.append('')
hf_body.append(' if (entry == g_memInfo.pLastMapped)')
for proto in self.protos:
if 'Wsi' not in proto.name and 'Dbg' not in proto.name:
if 'UnmapMemory' == proto.name:
+ proto.params.append(xgl.Param("XGL_GPU_SIZE", "size"))
+ proto.params.append(xgl.Param("void*", "pData"))
+ elif 'RecordMemoryRange' == proto.name:
proto.params.append(xgl.Param("void*", "pData"))
if_body.append('typedef struct struct_xgl%s {' % proto.name)
if_body.append(' glv_trace_packet_header* header;')
cd_body.append('typedef struct _XGLAllocInfo {')
cd_body.append(' XGL_GPU_SIZE size;')
cd_body.append(' void *pData;')
+ cd_body.append(' bool rangeUpdated;')
cd_body.append('} XGLAllocInfo;')
return "\n".join(cd_body)
rc_body.append(' XGLAllocInfo info;')
rc_body.append(' info.pData = NULL;')
rc_body.append(' info.size = size;')
+ rc_body.append(' info.rangeUpdated = false;')
rc_body.append(' m_mapData.insert(std::pair<XGL_GPU_MEMORY, XGLAllocInfo>(handle, info));')
rc_body.append(' }')
rc_body.append(' void add_mapping_to_mapData(XGL_GPU_MEMORY handle, void *pData)')
rc_body.append(' return;')
rc_body.append(' m_mapData.erase(it);')
rc_body.append(' }')
- rc_body.append(' void rm_mapping_from_mapData(XGL_GPU_MEMORY handle, void* pData)')
+ rc_body.append(' void copy_data_mapData(XGL_GPU_MEMORY handle, void* pData, XGL_GPU_SIZE size, XGL_GPU_SIZE offset, bool rangeUpdate)')
rc_body.append(' {')
rc_body.append(' std::map<XGL_GPU_MEMORY,XGLAllocInfo>::iterator it = m_mapData.find(handle);')
rc_body.append(' if (it == m_mapData.end())')
rc_body.append(' return;\n')
rc_body.append(' XGLAllocInfo &info = it->second;')
- rc_body.append(' if (!pData || !info.pData)')
+ rc_body.append(' if (!pData && size > 0)')
rc_body.append(' {')
- rc_body.append(' if (!pData)')
- rc_body.append(' glv_LogWarn("rm_mapping_from_mapData() null src pointer\\n");')
- rc_body.append(' else')
- rc_body.append(' glv_LogWarn("rm_mapping_from_mapData() null dest pointer size=%u\\n", info.size);')
+ rc_body.append(' glv_LogError("copy_data_mapData() null src pointer\\n");')
rc_body.append(' info.pData = NULL;')
rc_body.append(' return;')
rc_body.append(' }')
- rc_body.append(' memcpy(info.pData, pData, info.size);')
- rc_body.append(' info.pData = NULL;')
+ rc_body.append(' if (!info.pData)')
+ rc_body.append(' {')
+ rc_body.append(' glv_LogError("copy_data_mapData() null dest pointer size=%u\\n", info.size);')
+ rc_body.append(' return;')
+ rc_body.append(' }')
+ rc_body.append(' memcpy((char *) info.pData + offset, pData, size);')
+ rc_body.append(' info.rangeUpdated = rangeUpdate;')
+ rc_body.append(' if (!rangeUpdate)')
+ rc_body.append(' info.pData = NULL;')
rc_body.append(' }\n')
+ rc_body.append('')
rc_body.append(' /*std::map<XGL_PHYSICAL_GPU, XGL_PHYSICAL_GPU> m_gpus;')
rc_body.append(' void add_to_map(XGL_PHYSICAL_GPU* pTraceGpu, XGL_PHYSICAL_GPU* pReplayGpu)')
rc_body.append(' {')
def _gen_replay_unmap_memory(self):
um_body = []
um_body.append(' XGL_GPU_MEMORY handle = remap(pPacket->mem);')
- um_body.append(' rm_mapping_from_mapData(handle, pPacket->pData); // copies data from packet into memory buffer')
+ um_body.append(' // copies data from packet into memory buffer')
+ um_body.append(' copy_data_mapData(handle, pPacket->pData, pPacket->size, 0, false);')
um_body.append(' replayResult = m_xglFuncs.real_xglUnmapMemory(handle);')
return "\n".join(um_body)
+ def _gen_replay_record_memory_range(self):
+ rmr_body = []
+ rmr_body.append(' XGL_GPU_MEMORY handle = remap(pPacket->mem);')
+ rmr_body.append(' copy_data_mapData(handle, pPacket->pData, pPacket->rangeSize, pPacket->rangeOffset, true);')
+ rmr_body.append(' replayResult = m_xglFuncs.real_xglRecordMemoryRange(handle, pPacket->rangeSize, pPacket->rangeOffset);')
+ return "\n".join(rmr_body)
+
def _gen_replay_bind_dynamic_memory_view(self):
bdmv_body = []
bdmv_body.append(' XGL_MEMORY_VIEW_ATTACH_INFO memView;')
'FreeMemory': self._gen_replay_free_memory,
'MapMemory': self._gen_replay_map_memory,
'UnmapMemory': self._gen_replay_unmap_memory,
+ 'RecordMemoryRange': self._gen_replay_record_memory_range,
'CmdBindDynamicMemoryView': self._gen_replay_bind_dynamic_memory_view,
'UpdateDescriptors': self._gen_replay_update_descriptors,
'CreateDescriptorSetLayout': self._gen_replay_create_descriptor_set_layout,