-- v2: wined3d: Use dynamic state for patch vertex count if possible. wined3d: Use dynamic state for primitive type if possible.
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/wined3d/adapter_vk.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index 45d92e907b3..5b1437337c1 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -242,6 +242,7 @@ static HRESULT wined3d_select_vulkan_queue_family(const struct wined3d_adapter_v struct wined3d_physical_device_info { VkPhysicalDeviceExtendedDynamicStateFeaturesEXT dynamic_state_features; + VkPhysicalDeviceExtendedDynamicState2FeaturesEXT dynamic_state2_features; VkPhysicalDeviceHostQueryResetFeatures host_query_reset_features; VkPhysicalDeviceShaderDrawParametersFeatures draw_parameters_features; VkPhysicalDeviceTransformFeedbackFeaturesEXT xfb_features; @@ -338,6 +339,7 @@ static const struct wined3d_allocator_ops wined3d_allocator_vk_ops = static void get_physical_device_info(const struct wined3d_adapter_vk *adapter_vk, struct wined3d_physical_device_info *info) { VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *vertex_divisor_features = &info->vertex_divisor_features; + VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *dynamic_state2_features = &info->dynamic_state2_features; VkPhysicalDeviceShaderDrawParametersFeatures *draw_parameters_features = &info->draw_parameters_features; VkPhysicalDeviceExtendedDynamicStateFeaturesEXT *dynamic_state_features = &info->dynamic_state_features; VkPhysicalDeviceHostQueryResetFeatures *host_query_reset_features = &info->host_query_reset_features; @@ -363,8 +365,11 @@ static void get_physical_device_info(const struct wined3d_adapter_vk *adapter_vk host_query_reset_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES; host_query_reset_features->pNext = vertex_divisor_features;
+ dynamic_state2_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT; + dynamic_state2_features->pNext = host_query_reset_features; + dynamic_state_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT; - dynamic_state_features->pNext = host_query_reset_features; + dynamic_state_features->pNext = dynamic_state2_features;
features2->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; features2->pNext = dynamic_state_features; @@ -2366,6 +2371,7 @@ static bool wined3d_adapter_vk_init_device_extensions(struct wined3d_adapter_vk info[] = { {VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, VK_API_VERSION_1_3}, + {VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME, VK_API_VERSION_1_3}, {VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, VK_API_VERSION_1_2}, {VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, ~0u}, {VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, ~0u},
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/wined3d/adapter_vk.c | 1 + dlls/wined3d/context.c | 2 + dlls/wined3d/context_vk.c | 71 +++++++++++++++++++++++++++++++--- dlls/wined3d/cs.c | 2 + dlls/wined3d/wined3d_private.h | 3 +- dlls/wined3d/wined3d_vk.h | 8 +++- 6 files changed, 78 insertions(+), 9 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index 5b1437337c1..af27bcfbb05 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -2349,6 +2349,7 @@ static void wined3d_adapter_vk_init_d3d_info(struct wined3d_adapter_vk *adapter_ d3d_info->multisample_draw_location = WINED3D_LOCATION_TEXTURE_RGB;
vk_info->multiple_viewports = device_info.features2.features.multiViewport; + vk_info->dynamic_state2 = device_info.dynamic_state2_features.extendedDynamicState2; }
static bool wined3d_adapter_vk_init_device_extensions(struct wined3d_adapter_vk *adapter_vk) diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 90a588415ea..7a82d74edf8 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -113,6 +113,8 @@ void wined3d_context_init(struct wined3d_context *context, struct wined3d_swapch | (1u << WINED3D_SHADER_TYPE_HULL) | (1u << WINED3D_SHADER_TYPE_DOMAIN) | (1u << WINED3D_SHADER_TYPE_COMPUTE); + + context->update_primitive_type = 1; }
HRESULT wined3d_context_no3d_init(struct wined3d_context *context_no3d, struct wined3d_swapchain *swapchain) diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index 3f13e66e2fd..55d6be8704e 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -216,6 +216,36 @@ static VkPrimitiveTopology vk_topology_from_wined3d(enum wined3d_primitive_type } }
+static VkPrimitiveTopology vk_topology_class_from_wined3d(enum wined3d_primitive_type t) +{ + switch (t) + { + case WINED3D_PT_POINTLIST: + return VK_PRIMITIVE_TOPOLOGY_POINT_LIST; + + case WINED3D_PT_LINELIST: + case WINED3D_PT_LINELIST_ADJ: + case WINED3D_PT_LINESTRIP: + case WINED3D_PT_LINESTRIP_ADJ: + return VK_PRIMITIVE_TOPOLOGY_LINE_LIST; + + case WINED3D_PT_TRIANGLEFAN: + case WINED3D_PT_TRIANGLELIST: + case WINED3D_PT_TRIANGLELIST_ADJ: + case WINED3D_PT_TRIANGLESTRIP: + case WINED3D_PT_TRIANGLESTRIP_ADJ: + return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + + case WINED3D_PT_PATCH: + return VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; + + default: + FIXME("Unhandled primitive type %s.\n", debug_d3dprimitivetype(t)); + case WINED3D_PT_UNDEFINED: + return ~0u; + } +} + static VkStencilOp vk_stencil_op_from_wined3d(enum wined3d_stencil_op op) { switch (op) @@ -1875,6 +1905,7 @@ void wined3d_context_vk_submit_command_buffer(struct wined3d_context_vk *context context_vk->c.update_compute_shader_resource_bindings = 1; context_vk->c.update_unordered_access_view_bindings = 1; context_vk->c.update_compute_unordered_access_view_bindings = 1; + context_vk->c.update_primitive_type = 1; context_invalidate_state(&context_vk->c, STATE_STREAMSRC); context_invalidate_state(&context_vk->c, STATE_INDEXBUFFER); context_invalidate_state(&context_vk->c, STATE_BLEND_FACTOR); @@ -2105,6 +2136,12 @@ static void wined3d_context_vk_init_graphics_pipeline_key(struct wined3d_context dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK; dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK; } + if (vk_info->dynamic_state2) + { + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT; + if (!(context_vk->c.d3d_info->wined3d_creation_flags & WINED3D_NO_PRIMITIVE_RESTART)) + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT; + }
key = &context_vk->graphics.pipeline_key_vk; memset(key, 0, sizeof(*key)); @@ -2449,14 +2486,26 @@ static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_conte update = true; }
- vk_topology = vk_topology_from_wined3d(state->primitive_type); - if (key->ia_desc.topology != vk_topology) + if (vk_info->dynamic_state2) { - key->ia_desc.topology = vk_topology; - key->ia_desc.primitiveRestartEnable = !(d3d_info->wined3d_creation_flags & WINED3D_NO_PRIMITIVE_RESTART) - && !wined3d_primitive_type_is_list(state->primitive_type); + vk_topology = vk_topology_class_from_wined3d(state->primitive_type); + if (key->ia_desc.topology != vk_topology) + { + key->ia_desc.topology = vk_topology; + update = true; + } + } + else + { + vk_topology = vk_topology_from_wined3d(state->primitive_type); + if (key->ia_desc.topology != vk_topology) + { + key->ia_desc.topology = vk_topology; + key->ia_desc.primitiveRestartEnable = !(d3d_info->wined3d_creation_flags & WINED3D_NO_PRIMITIVE_RESTART) + && !wined3d_primitive_type_is_list(state->primitive_type);
- update = true; + update = true; + } }
if (key->ts_desc.patchControlPoints != state->patch_vertex_count) @@ -3539,6 +3588,7 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c const struct wined3d_state *state, struct wined3d_buffer_vk *indirect_vk, bool indexed) { struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); + const struct wined3d_d3d_info *d3d_info = context_vk->c.d3d_info; const struct wined3d_vk_info *vk_info = context_vk->vk_info; const struct wined3d_blend_state *b = state->blend_state; bool dual_source_blend = b && b->dual_source; @@ -3809,6 +3859,15 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c VK_CALL(vkCmdSetScissor(vk_command_buffer, 0, viewport_count, scissors)); }
+ if (vk_info->dynamic_state2 && context_vk->c.update_primitive_type) + { + VK_CALL(vkCmdSetPrimitiveTopologyEXT(vk_command_buffer, vk_topology_from_wined3d(state->primitive_type))); + if (!(d3d_info->wined3d_creation_flags & WINED3D_NO_PRIMITIVE_RESTART)) + VK_CALL(vkCmdSetPrimitiveRestartEnableEXT(vk_command_buffer, + !wined3d_primitive_type_is_list(state->primitive_type))); + context_vk->c.update_primitive_type = 0; + } + if (vk_info->supported[WINED3D_VK_EXT_EXTENDED_DYNAMIC_STATE] && (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_DEPTH_STENCIL) || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_FRAMEBUFFER))) diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 091b461fbbf..8a7e859daea 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -1044,6 +1044,8 @@ static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) if (state->primitive_type == WINED3D_PT_POINTLIST || op->primitive_type == WINED3D_PT_POINTLIST) device_invalidate_state(cs->c.device, STATE_POINT_ENABLE); state->primitive_type = op->primitive_type; + for (i = 0; i < device->context_count; ++i) + device->contexts[i]->update_primitive_type = 1; } state->patch_vertex_count = op->patch_vertex_count;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 4b928781117..f6e7bffecb0 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1967,7 +1967,8 @@ struct wined3d_context DWORD destroyed : 1; DWORD destroy_delayed : 1; DWORD namedArraysLoaded : 1; - DWORD padding : 5; + DWORD update_primitive_type : 1; + DWORD padding : 4;
DWORD clip_distance_mask : 8; /* WINED3D_MAX_CLIP_DISTANCES, 8 */
diff --git a/dlls/wined3d/wined3d_vk.h b/dlls/wined3d/wined3d_vk.h index 280f36f692a..0f0e51baa0f 100644 --- a/dlls/wined3d/wined3d_vk.h +++ b/dlls/wined3d/wined3d_vk.h @@ -183,8 +183,11 @@ struct wined3d_device_vk; VK_DEVICE_EXT_PFN(vkCmdSetDepthCompareOpEXT) \ VK_DEVICE_EXT_PFN(vkCmdSetDepthTestEnableEXT) \ VK_DEVICE_EXT_PFN(vkCmdSetDepthWriteEnableEXT) \ + VK_DEVICE_EXT_PFN(vkCmdSetPrimitiveTopologyEXT) \ VK_DEVICE_EXT_PFN(vkCmdSetStencilOpEXT) \ VK_DEVICE_EXT_PFN(vkCmdSetStencilTestEnableEXT) \ + /* VK_EXT_extended_dynamic_state2 */ \ + VK_DEVICE_EXT_PFN(vkCmdSetPrimitiveRestartEnableEXT) \ /* VK_EXT_transform_feedback */ \ VK_DEVICE_EXT_PFN(vkCmdBeginQueryIndexedEXT) \ VK_DEVICE_EXT_PFN(vkCmdBeginTransformFeedbackEXT) \ @@ -242,7 +245,8 @@ struct wined3d_vk_info BOOL supported[WINED3D_VK_EXT_COUNT]; HMODULE vulkan_lib;
- unsigned int multiple_viewports : 1; + bool multiple_viewports; + bool dynamic_state2; };
#define VK_CALL(f) (vk_info->vk_ops.f) @@ -565,7 +569,7 @@ struct wined3d_context_vk
const struct wined3d_vk_info *vk_info;
- VkDynamicState dynamic_states[11]; + VkDynamicState dynamic_states[13];
uint32_t update_compute_pipeline : 1; uint32_t update_stream_output : 1;
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/wined3d/adapter_vk.c | 1 + dlls/wined3d/context.c | 1 + dlls/wined3d/context_vk.c | 12 +++++++++++- dlls/wined3d/cs.c | 5 +++++ dlls/wined3d/wined3d_private.h | 3 ++- dlls/wined3d/wined3d_vk.h | 4 +++- 6 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index af27bcfbb05..7b4bf898fd1 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -2350,6 +2350,7 @@ static void wined3d_adapter_vk_init_d3d_info(struct wined3d_adapter_vk *adapter_
vk_info->multiple_viewports = device_info.features2.features.multiViewport; vk_info->dynamic_state2 = device_info.dynamic_state2_features.extendedDynamicState2; + vk_info->dynamic_patch_vertex_count = device_info.dynamic_state2_features.extendedDynamicState2PatchControlPoints; }
static bool wined3d_adapter_vk_init_device_extensions(struct wined3d_adapter_vk *adapter_vk) diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 7a82d74edf8..d0193237d25 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -115,6 +115,7 @@ void wined3d_context_init(struct wined3d_context *context, struct wined3d_swapch | (1u << WINED3D_SHADER_TYPE_COMPUTE);
context->update_primitive_type = 1; + context->update_patch_vertex_count = 1; }
HRESULT wined3d_context_no3d_init(struct wined3d_context *context_no3d, struct wined3d_swapchain *swapchain) diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index 55d6be8704e..e59069ab809 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -1906,6 +1906,7 @@ void wined3d_context_vk_submit_command_buffer(struct wined3d_context_vk *context context_vk->c.update_unordered_access_view_bindings = 1; context_vk->c.update_compute_unordered_access_view_bindings = 1; context_vk->c.update_primitive_type = 1; + context_vk->c.update_patch_vertex_count = 1; context_invalidate_state(&context_vk->c, STATE_STREAMSRC); context_invalidate_state(&context_vk->c, STATE_INDEXBUFFER); context_invalidate_state(&context_vk->c, STATE_BLEND_FACTOR); @@ -2142,6 +2143,8 @@ static void wined3d_context_vk_init_graphics_pipeline_key(struct wined3d_context if (!(context_vk->c.d3d_info->wined3d_creation_flags & WINED3D_NO_PRIMITIVE_RESTART)) dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT; } + if (vk_info->dynamic_patch_vertex_count) + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT;
key = &context_vk->graphics.pipeline_key_vk; memset(key, 0, sizeof(*key)); @@ -2508,7 +2511,7 @@ static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_conte } }
- if (key->ts_desc.patchControlPoints != state->patch_vertex_count) + if (!vk_info->dynamic_patch_vertex_count && key->ts_desc.patchControlPoints != state->patch_vertex_count) { key->ts_desc.patchControlPoints = state->patch_vertex_count;
@@ -3868,6 +3871,13 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c context_vk->c.update_primitive_type = 0; }
+ if (vk_info->dynamic_patch_vertex_count && context_vk->c.update_patch_vertex_count) + { + if (state->patch_vertex_count) + VK_CALL(vkCmdSetPatchControlPointsEXT(vk_command_buffer, state->patch_vertex_count)); + context_vk->c.update_patch_vertex_count = 0; + } + if (vk_info->supported[WINED3D_VK_EXT_EXTENDED_DYNAMIC_STATE] && (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_DEPTH_STENCIL) || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_FRAMEBUFFER))) diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 8a7e859daea..3b1891321a4 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -1047,6 +1047,11 @@ static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) for (i = 0; i < device->context_count; ++i) device->contexts[i]->update_primitive_type = 1; } + if (state->patch_vertex_count != op->patch_vertex_count) + { + for (i = 0; i < device->context_count; ++i) + device->contexts[i]->update_patch_vertex_count = 1; + } state->patch_vertex_count = op->patch_vertex_count;
cs->c.device->adapter->adapter_ops->adapter_draw_primitive(cs->c.device, state, &op->parameters); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index f6e7bffecb0..b0663e67d7e 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1968,7 +1968,8 @@ struct wined3d_context DWORD destroy_delayed : 1; DWORD namedArraysLoaded : 1; DWORD update_primitive_type : 1; - DWORD padding : 4; + DWORD update_patch_vertex_count : 1; + DWORD padding : 3;
DWORD clip_distance_mask : 8; /* WINED3D_MAX_CLIP_DISTANCES, 8 */
diff --git a/dlls/wined3d/wined3d_vk.h b/dlls/wined3d/wined3d_vk.h index 0f0e51baa0f..e995ef3c408 100644 --- a/dlls/wined3d/wined3d_vk.h +++ b/dlls/wined3d/wined3d_vk.h @@ -187,6 +187,7 @@ struct wined3d_device_vk; VK_DEVICE_EXT_PFN(vkCmdSetStencilOpEXT) \ VK_DEVICE_EXT_PFN(vkCmdSetStencilTestEnableEXT) \ /* VK_EXT_extended_dynamic_state2 */ \ + VK_DEVICE_EXT_PFN(vkCmdSetPatchControlPointsEXT) \ VK_DEVICE_EXT_PFN(vkCmdSetPrimitiveRestartEnableEXT) \ /* VK_EXT_transform_feedback */ \ VK_DEVICE_EXT_PFN(vkCmdBeginQueryIndexedEXT) \ @@ -247,6 +248,7 @@ struct wined3d_vk_info
bool multiple_viewports; bool dynamic_state2; + bool dynamic_patch_vertex_count; };
#define VK_CALL(f) (vk_info->vk_ops.f) @@ -569,7 +571,7 @@ struct wined3d_context_vk
const struct wined3d_vk_info *vk_info;
- VkDynamicState dynamic_states[13]; + VkDynamicState dynamic_states[14];
uint32_t update_compute_pipeline : 1; uint32_t update_stream_output : 1;
This merge request was approved by Jan Sikorski.