diff --git a/cli/device.cpp b/cli/device.cpp index d0a9a4b..e973e1f 100644 --- a/cli/device.cpp +++ b/cli/device.cpp @@ -350,6 +350,9 @@ bool VulkanDevice::init_device(const Options &opts) if (vkEnumeratePhysicalDevices(instance, &gpu_count, gpus.data()) != VK_SUCCESS) return false; + int selected_gpu_index = -1; + bool pci_filter_set = opts.device_pci_vendor != 0; + bool pci_filter_matched = false; for (uint32_t i = 0; i < gpu_count; i++) { vkGetPhysicalDeviceProperties(gpus[i], &gpu_props); @@ -359,9 +362,32 @@ bool VulkanDevice::init_device(const Options &opts) VK_VERSION_MAJOR(gpu_props.apiVersion), VK_VERSION_MINOR(gpu_props.apiVersion), VK_VERSION_PATCH(gpu_props.apiVersion)); + LOGI(" vendorID: 0x%x\n", gpu_props.vendorID); + LOGI(" deviceID: 0x%x\n", gpu_props.deviceID); + + if (gpu_props.vendorID == opts.device_pci_vendor) + { + if (opts.device_pci_device == 0 || gpu_props.deviceID == opts.device_pci_device) + { + selected_gpu_index = i; + pci_filter_matched = true; + break; + } + } + } + + if (pci_filter_set && !pci_filter_matched) + { + LOGW("No GPU matched --device-pci-vendor 0x%x%s; falling back to default selection.\n", + opts.device_pci_vendor, + opts.device_pci_device ? " (with --device-pci-device)" : ""); } - if (opts.device_index >= 0) + if (selected_gpu_index >= 0) + { + gpu = gpus[selected_gpu_index]; + } + else if (opts.device_index >= 0) { if (size_t(opts.device_index) >= gpus.size()) { diff --git a/cli/device.hpp b/cli/device.hpp index c99e45d..c41f1ee 100644 --- a/cli/device.hpp +++ b/cli/device.hpp @@ -38,6 +38,8 @@ class VulkanDevice : public DeviceQueryInterface bool null_device = false; bool want_pipeline_stats = false; int device_index = -1; + unsigned device_pci_vendor = 0; + unsigned device_pci_device = 0; const VkApplicationInfo *application_info = nullptr; const VkPhysicalDeviceFeatures2 *features = nullptr; }; diff --git a/cli/fossilize_replay.cpp b/cli/fossilize_replay.cpp index 77b11f7..b48abc4 100644 --- a/cli/fossilize_replay.cpp +++ b/cli/fossilize_replay.cpp @@ -3637,6 +3637,8 @@ static void print_help() LOGI("fossilize-replay\n" "\t[--help]\n" "\t[--device-index ]\n" + "\t[--device-pci-vendor ]\n" + "\t[--device-pci-device ]\n" "\t[--enable-validation]\n" "\t[--enable-pipeline-stats ]\n" "\t[--spirv-val]\n" @@ -4599,6 +4601,12 @@ int main(int argc, char *argv[]) cbs.default_handler = [&](const char *arg) { databases.push_back(arg); }; cbs.add("--help", [](CLIParser &parser) { print_help(); parser.end(); }); cbs.add("--device-index", [&](CLIParser &parser) { opts.device_index = parser.next_uint(); }); + cbs.add("--device-pci-vendor", [&](CLIParser &parser) { + opts.device_pci_vendor = strtoul(parser.next_string(), nullptr, 0); + }); + cbs.add("--device-pci-device", [&](CLIParser &parser) { + opts.device_pci_device = strtoul(parser.next_string(), nullptr, 0); + }); cbs.add("--enable-validation", [&](CLIParser &) { opts.enable_validation = true; }); cbs.add("--spirv-val", [&](CLIParser &) { replayer_opts.spirv_validate = true; }); cbs.add("--on-disk-pipeline-cache", [&](CLIParser &parser) { replayer_opts.on_disk_pipeline_cache_path = parser.next_string(); }); diff --git a/fossilize_external_replayer.hpp b/fossilize_external_replayer.hpp index 55c86d7..3e02b28 100644 --- a/fossilize_external_replayer.hpp +++ b/fossilize_external_replayer.hpp @@ -107,6 +107,10 @@ class ExternalReplayer // Maps to --device-index. unsigned device_index; + // Maps to --device-pci-vendor and --device-pci-device. + unsigned device_pci_vendor; + unsigned device_pci_device; + // Carve out a range of which pipelines to replay if use_pipeline_range is set. // Used for multi-process replays where each process gets its own slice to churn through. unsigned start_graphics_index; diff --git a/fossilize_external_replayer_linux.hpp b/fossilize_external_replayer_linux.hpp index 828ae86..0aa3221 100644 --- a/fossilize_external_replayer_linux.hpp +++ b/fossilize_external_replayer_linux.hpp @@ -705,6 +705,21 @@ void ExternalReplayer::Impl::start_replayer_process(const ExternalReplayer::Opti sprintf(index_name, "%u", options.device_index); argv.push_back(index_name); + char pci_vendor_name[16], pci_device_name[16]; + if (options.device_pci_vendor != 0) + { + argv.push_back("--device-pci-vendor"); + sprintf(pci_vendor_name, "0x%x", options.device_pci_vendor); + argv.push_back(pci_vendor_name); + } + + if (options.device_pci_device != 0) + { + argv.push_back("--device-pci-device"); + sprintf(pci_device_name, "0x%x", options.device_pci_device); + argv.push_back(pci_device_name); + } + char graphics_range_start[16], graphics_range_end[16]; char compute_range_start[16], compute_range_end[16]; char raytracing_range_start[16], raytracing_range_end[16]; diff --git a/fossilize_external_replayer_windows.hpp b/fossilize_external_replayer_windows.hpp index cc81c07..915a97f 100644 --- a/fossilize_external_replayer_windows.hpp +++ b/fossilize_external_replayer_windows.hpp @@ -586,6 +586,19 @@ bool ExternalReplayer::Impl::start(const ExternalReplayer::Options &options) cmdline += " --device-index "; cmdline += std::to_string(options.device_index); + char hex_buf[32]; + if (options.device_pci_vendor != 0) + { + snprintf(hex_buf, sizeof(hex_buf), " --device-pci-vendor 0x%x", options.device_pci_vendor); + cmdline += hex_buf; + } + + if (options.device_pci_device != 0) + { + snprintf(hex_buf, sizeof(hex_buf), " --device-pci-device 0x%x", options.device_pci_device); + cmdline += hex_buf; + } + if (options.enable_validation) cmdline += " --enable-validation";