diff --git a/hw/xbox/nv2a/pgraph/vk/draw.c b/hw/xbox/nv2a/pgraph/vk/draw.c index 8dabf9325b..6eea839c44 100644 --- a/hw/xbox/nv2a/pgraph/vk/draw.c +++ b/hw/xbox/nv2a/pgraph/vk/draw.c @@ -951,7 +951,7 @@ static void create_pipeline(PGRAPHState *pg) int num_dynamic_states = 2; snode->has_dynamic_line_width = - (r->physical_device_features.wideLines == VK_TRUE) + (r->enabled_physical_device_features.wideLines == VK_TRUE) && (r->shader_binding->state.polygon_front_mode == POLY_MODE_LINE || r->shader_binding->state.primitive_mode == PRIM_TYPE_LINES || r->shader_binding->state.primitive_mode == PRIM_TYPE_LINE_LOOP || diff --git a/hw/xbox/nv2a/pgraph/vk/instance.c b/hw/xbox/nv2a/pgraph/vk/instance.c index 416f12dff8..0ee2bd3235 100644 --- a/hw/xbox/nv2a/pgraph/vk/instance.c +++ b/hw/xbox/nv2a/pgraph/vk/instance.c @@ -522,36 +522,47 @@ static bool create_logical_device(PGRAPHState *pg, Error **errp) .pQueuePriorities = &queuePriority, }; - // Ensure device supports required features - VkPhysicalDeviceFeatures enabled_features; - vkGetPhysicalDeviceFeatures(r->physical_device, &r->physical_device_features); - memset(&enabled_features, 0, sizeof(enabled_features)); + // Check device features + VkPhysicalDeviceFeatures physical_device_features; + vkGetPhysicalDeviceFeatures(r->physical_device, &physical_device_features); + memset(&r->enabled_physical_device_features, 0, + sizeof(r->enabled_physical_device_features)); struct { const char *name; VkBool32 available, *enabled; - } required_features[] = { - #define F(n) { #n, r->physical_device_features.n, &enabled_features.n } - F(shaderClipDistance), - F(geometryShader), - F(shaderTessellationAndGeometryPointSize), - F(depthClamp), - F(occlusionQueryPrecise), + bool required; + } desired_features[] = { + // clang-format off + #define F(n, req) { \ + .name = #n, \ + .available = physical_device_features.n, \ + .enabled = &r->enabled_physical_device_features.n, \ + .required = req, \ + } + F(shaderClipDistance, true), + F(geometryShader, true), + F(shaderTessellationAndGeometryPointSize, true), + F(depthClamp, true), + F(occlusionQueryPrecise, true), + F(wideLines, false), #undef F + // clang-format on }; - bool all_features_available = true; - for (int i = 0; i < ARRAY_SIZE(required_features); i++) { - if (required_features[i].available != VK_TRUE) { + bool all_required_features_available = true; + for (int i = 0; i < ARRAY_SIZE(desired_features); i++) { + if (desired_features[i].required && + desired_features[i].available != VK_TRUE) { fprintf(stderr, "Error: Device does not support required feature %s\n", - required_features[i].name); - all_features_available = false; + desired_features[i].name); + all_required_features_available = false; } - *required_features[i].enabled = VK_TRUE; + *desired_features[i].enabled = desired_features[i].available; } - if (!all_features_available) { + if (!all_required_features_available) { error_setg(errp, "Device does not support required features"); return false; } @@ -584,7 +595,7 @@ static bool create_logical_device(PGRAPHState *pg, Error **errp) .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, .queueCreateInfoCount = 1, .pQueueCreateInfos = &queue_create_info, - .pEnabledFeatures = &enabled_features, + .pEnabledFeatures = &r->enabled_physical_device_features, .enabledExtensionCount = enabled_extension_names->len, .ppEnabledExtensionNames = &g_array_index(enabled_extension_names, const char *, 0), diff --git a/hw/xbox/nv2a/pgraph/vk/renderer.h b/hw/xbox/nv2a/pgraph/vk/renderer.h index 1009fe589c..9ca738244c 100644 --- a/hw/xbox/nv2a/pgraph/vk/renderer.h +++ b/hw/xbox/nv2a/pgraph/vk/renderer.h @@ -335,7 +335,7 @@ typedef struct PGRAPHVkState { bool memory_budget_extension_enabled; VkPhysicalDevice physical_device; - VkPhysicalDeviceFeatures physical_device_features; + VkPhysicalDeviceFeatures enabled_physical_device_features; VkPhysicalDeviceProperties device_props; VkDevice device; VmaAllocator allocator;