| 31 | GpuDump::~GpuDump() {} |
| 32 | |
| 33 | std::vector<uint8_t> GpuDump::CopyDataFromMemory(VkDeviceAddress memory_addresss, VkDeviceSize copy_size) { |
| 34 | std::vector<uint8_t> result; |
| 35 | vvl::span<vvl::Buffer* const> buffer_list = device_state->GetBuffersByAddress(memory_addresss); |
| 36 | if (buffer_list.empty()) { |
| 37 | return result; |
| 38 | } |
| 39 | |
| 40 | auto buffer_state = *buffer_list.begin(); |
| 41 | const vvl::DeviceMemory& memory_state = *buffer_state->MemoryState(); |
| 42 | |
| 43 | // Prevent copying OOB of a buffer |
| 44 | if ((memory_addresss + copy_size) > buffer_state->DeviceAddressRange().end) { |
| 45 | return result; |
| 46 | } |
| 47 | |
| 48 | VkDeviceSize offset = memory_addresss - buffer_state->DeviceAddressRange().begin; |
| 49 | if (memory_state.mappable) { |
| 50 | uint8_t* data_ptr = static_cast<uint8_t*>(memory_state.p_driver_data); |
| 51 | |
| 52 | if (!memory_state.p_driver_data) { |
| 53 | // Just use WHOLE_SIZE to avoid issues with partial mappings |
| 54 | // Example: |
| 55 | // The |memory_address| is 0x1001 and |copy_size| is 4, the driver (or at least TestICD) will return back something |
| 56 | // aligned to a value like 64, so if the buffer is only 64 bytes, you will now be accessing data over it |
| 57 | DispatchMapMemory(device, memory_state.VkHandle(), offset, VK_WHOLE_SIZE, 0, (void**)&data_ptr); |
| 58 | |
| 59 | if (memory_state.cache_non_coherent) { |
| 60 | const VkDeviceSize atom_size = phys_dev_props.limits.nonCoherentAtomSize; |
| 61 | uint64_t aligned_offset = offset & ~(atom_size - 1); |
| 62 | if (aligned_offset < offset) { |
| 63 | aligned_offset = offset; |
| 64 | } |
| 65 | |
| 66 | VkMappedMemoryRange memory_range = vku::InitStructHelper(); |
| 67 | memory_range.memory = memory_state.VkHandle(); |
| 68 | memory_range.offset = aligned_offset; |
| 69 | memory_range.size = VK_WHOLE_SIZE; |
| 70 | DispatchInvalidateMappedMemoryRanges(device, 1, &memory_range); |
| 71 | } |
| 72 | } |
| 73 | |
| 74 | data_ptr += offset; |
| 75 | result.resize(static_cast<uint32_t>(copy_size)); |
| 76 | memcpy(result.data(), data_ptr, static_cast<uint32_t>(copy_size)); |
| 77 | |
| 78 | if (!memory_state.p_driver_data) { |
| 79 | DispatchUnmapMemory(device, memory_state.VkHandle()); |
| 80 | } |
| 81 | } else { |
| 82 | // TODO - Handle non-host visible memory |
| 83 | // When we add, we need to guard against if trying to read non-aligned data |
| 84 | // (which should have a warning already) |
| 85 | } |
| 86 | |
| 87 | return result; |
| 88 | } |
| 89 | |
| 90 | bool GpuDump::ListBuffers(std::ostringstream& ss, VkDeviceAddress address, uint32_t indents, bool new_line_start) { |
no test coverage detected