ui: device picker shows the auto-selected adapter; no wrap on stepper clicks
This commit is contained in:
parent
855ed66c82
commit
2cab1be8eb
4 changed files with 82 additions and 23 deletions
|
|
@ -20,6 +20,10 @@ struct GraphicsDeviceList {
|
|||
// "vulkan_device"); empty when no backend has published a list.
|
||||
std::string cvar_name;
|
||||
std::vector<std::string> device_names;
|
||||
// Index (in device_names / cvar order) of the device the backend actually
|
||||
// selected this session; -1 while unknown. Lets UI show the device that
|
||||
// automatic selection resolved to.
|
||||
int32_t active_index = -1;
|
||||
};
|
||||
|
||||
void SetGraphicsDeviceList(GraphicsDeviceList list);
|
||||
|
|
|
|||
|
|
@ -345,6 +345,28 @@ bool D3D12Provider::Initialize() {
|
|||
dxgi_factory->Release();
|
||||
return false;
|
||||
}
|
||||
// Publish which cvar-order index the selection landed on (the automatic
|
||||
// path walks a preference-ordered enumeration, so its index does not match
|
||||
// the published list) so the settings device picker can show the adapter
|
||||
// automatic selection resolved to. Matched by LUID against the plain
|
||||
// enumeration the list was built from.
|
||||
{
|
||||
GraphicsDeviceList device_list = GetGraphicsDeviceList();
|
||||
IDXGIAdapter1* match_adapter;
|
||||
for (uint32_t i = 0; dxgi_factory->EnumAdapters1(i, &match_adapter) == S_OK; ++i) {
|
||||
DXGI_ADAPTER_DESC1 match_desc;
|
||||
const bool matched =
|
||||
SUCCEEDED(match_adapter->GetDesc1(&match_desc)) &&
|
||||
match_desc.AdapterLuid.LowPart == adapter_desc.AdapterLuid.LowPart &&
|
||||
match_desc.AdapterLuid.HighPart == adapter_desc.AdapterLuid.HighPart;
|
||||
match_adapter->Release();
|
||||
if (matched) {
|
||||
device_list.active_index = int32_t(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
SetGraphicsDeviceList(std::move(device_list));
|
||||
}
|
||||
adapter_vendor_id_ = GpuVendorID(adapter_desc.VendorId);
|
||||
int adapter_name_mb_size =
|
||||
WideCharToMultiByte(CP_UTF8, 0, adapter_desc.Description, -1, nullptr, 0, nullptr, nullptr);
|
||||
|
|
|
|||
|
|
@ -220,16 +220,19 @@ std::vector<std::string_view> GetSimpleSettingsCvars() {
|
|||
return cvars;
|
||||
}
|
||||
|
||||
// 0 = automatic selection (cvar -1); i+1 = the list's device i.
|
||||
// The picker lists devices directly (no separate automatic entry):
|
||||
// automatic selection (cvar -1) reads as the device the backend reported
|
||||
// actually picking.
|
||||
int DeviceIndexFromCvar(const GraphicsDeviceList& device_list) {
|
||||
if (device_list.device_names.empty() || !HasCvar(device_list.cvar_name)) {
|
||||
return 0;
|
||||
}
|
||||
int32_t current = rex::cvar::Query<int32_t>(device_list.cvar_name);
|
||||
if (current >= 0 && current < static_cast<int32_t>(device_list.device_names.size())) {
|
||||
return current + 1;
|
||||
return current;
|
||||
}
|
||||
return 0;
|
||||
return std::clamp(device_list.active_index, 0,
|
||||
static_cast<int32_t>(device_list.device_names.size()) - 1);
|
||||
}
|
||||
|
||||
int ResolutionIndexFromScale(int32_t scale) {
|
||||
|
|
@ -952,10 +955,14 @@ void SimpleSettingsDialog::SaveVideo() {
|
|||
std::clamp(aspect_ratio_index_, 0, static_cast<int>(kAspectRatioLabels.size()) - 1);
|
||||
field_of_view_ = std::clamp(field_of_view_, 40.0f, 120.0f);
|
||||
if (!device_list_.device_names.empty() && HasCvar(device_list_.cvar_name)) {
|
||||
device_index_ =
|
||||
std::clamp(device_index_, 0, static_cast<int>(device_list_.device_names.size()));
|
||||
device_index_ = std::clamp(device_index_, 0,
|
||||
static_cast<int>(device_list_.device_names.size()) - 1);
|
||||
// Selecting the device automatic selection already picked keeps the cvar
|
||||
// automatic, so new hardware still re-picks the best adapter.
|
||||
rex::cvar::SetFlagByName(device_list_.cvar_name,
|
||||
device_index_ == 0 ? "-1" : std::to_string(device_index_ - 1));
|
||||
device_index_ == device_list_.active_index
|
||||
? "-1"
|
||||
: std::to_string(device_index_));
|
||||
}
|
||||
const auto scale = std::to_string(kResolutionScales[resolution_scale_index_]);
|
||||
rex::cvar::SetFlagByName("resolution_scale", scale);
|
||||
|
|
@ -1058,19 +1065,20 @@ void SimpleSettingsDialog::BuildRows(std::vector<RowSpec>& rows, int category) {
|
|||
row.kind = RowSpec::kEnum;
|
||||
row.label = "Graphics Device";
|
||||
row.desc =
|
||||
"Select which GPU renders the game. Auto picks the highest-performance adapter.";
|
||||
"Select which GPU renders the game. The highest-performance "
|
||||
"adapter is selected automatically.";
|
||||
// Index-prefixed labels: virtual display drivers (Parsec etc.) make
|
||||
// the same physical GPU enumerate several times, and the index is
|
||||
// what the device cvar and the startup log speak in.
|
||||
row.options.push_back("Auto (recommended)");
|
||||
// what the device cvar and the startup log speak in. No separate
|
||||
// automatic entry; the row shows the adapter automatic selection
|
||||
// resolved to, and re-selecting it keeps the choice automatic.
|
||||
for (size_t i = 0; i < device_list_.device_names.size(); ++i) {
|
||||
row.options.push_back(std::to_string(i) + ": " + device_list_.device_names[i]);
|
||||
}
|
||||
row.index = &device_index_;
|
||||
if (device_index_ > 0 && device_index_ <= int(device_list_.device_names.size())) {
|
||||
row.desc_extra = "Current: " + row.options[device_index_];
|
||||
}
|
||||
row.reset = [this] { device_index_ = 0; };
|
||||
row.reset = [this] {
|
||||
device_index_ = std::max(device_list_.active_index, 0);
|
||||
};
|
||||
rows.push_back(std::move(row));
|
||||
}
|
||||
{
|
||||
|
|
@ -2333,12 +2341,17 @@ void SimpleSettingsDialog::OnDraw(ImGuiIO& io) {
|
|||
// a circle greys out (and stops responding) at its end of the range.
|
||||
const bool can_left = row.enabled && value > 0;
|
||||
const bool can_right = row.enabled && value < count - 1;
|
||||
bool left_hover = can_left &&
|
||||
mouse_in(left_center.x - chevron_r - 4.0f, cy - chevron_r - 4.0f,
|
||||
left_center.x + chevron_r + 4.0f, cy + chevron_r + 4.0f);
|
||||
bool right_hover = can_right &&
|
||||
mouse_in(right_center.x - chevron_r - 4.0f, cy - chevron_r - 4.0f,
|
||||
right_center.x + chevron_r + 4.0f, cy + chevron_r + 4.0f);
|
||||
// Hit areas are tracked separately from enablement: a click on a
|
||||
// greyed-out stepper must be swallowed, not fall through to the
|
||||
// row-body wrap-around cycle below.
|
||||
const bool left_hit =
|
||||
mouse_in(left_center.x - chevron_r - 4.0f, cy - chevron_r - 4.0f,
|
||||
left_center.x + chevron_r + 4.0f, cy + chevron_r + 4.0f);
|
||||
const bool right_hit =
|
||||
mouse_in(right_center.x - chevron_r - 4.0f, cy - chevron_r - 4.0f,
|
||||
right_center.x + chevron_r + 4.0f, cy + chevron_r + 4.0f);
|
||||
bool left_hover = can_left && left_hit;
|
||||
bool right_hover = can_right && right_hit;
|
||||
const ImU32 chev_disabled = focused ? kColChevDisabledOnDark : kColChevDisabled;
|
||||
DrawChevron(dl, left_center, chevron_r, true,
|
||||
can_left ? (left_hover ? kColInteractHover : kColInteract)
|
||||
|
|
@ -2369,10 +2382,14 @@ void SimpleSettingsDialog::OnDraw(ImGuiIO& io) {
|
|||
text.c_str());
|
||||
}
|
||||
if (clicked && row.enabled) {
|
||||
if (left_hover) {
|
||||
step_row(row, -1);
|
||||
} else if (right_hover) {
|
||||
step_row(row, 1);
|
||||
if (left_hit) {
|
||||
if (can_left) {
|
||||
step_row(row, -1);
|
||||
}
|
||||
} else if (right_hit) {
|
||||
if (can_right) {
|
||||
step_row(row, 1);
|
||||
}
|
||||
} else if (hovered) {
|
||||
activate_row(row); // row-body click cycles with wrap-around
|
||||
}
|
||||
|
|
|
|||
|
|
@ -165,6 +165,22 @@ std::unique_ptr<VulkanProvider> VulkanProvider::Create(const bool with_gpu_emula
|
|||
}
|
||||
}
|
||||
|
||||
// Publish which enumeration index the selection landed on (the automatic
|
||||
// path walks a preference-ordered copy of the list) so the settings device
|
||||
// picker can show the device automatic selection resolved to.
|
||||
{
|
||||
const VkPhysicalDevice active_physical_device =
|
||||
provider->vulkan_device_->physical_device();
|
||||
for (size_t i = 0; i < physical_devices.size(); ++i) {
|
||||
if (physical_devices[i] == active_physical_device) {
|
||||
GraphicsDeviceList device_list = GetGraphicsDeviceList();
|
||||
device_list.active_index = int32_t(i);
|
||||
SetGraphicsDeviceList(std::move(device_list));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (with_presentation) {
|
||||
provider->ui_samplers_ = UISamplers::Create(provider->vulkan_device_.get());
|
||||
if (!provider->ui_samplers_) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue