This includes viewport and scissor rect (core in 1.0), and depth/stencil state (comprised entirely of elements in EXT_extended_dynamic_state).
Further patches add other dynamic state extensions and make other parts of the pipeline state dynamic.
Theoretically dynamic state should be an improvement, giving greater freedom to the driver and hardware to optimize, and (perhaps more importantly) reducing the time needed to look up and compile new pipeline states. In practice I haven't observed a clear and measureable difference in either performance or stutter; however, my testing has been extremely scarce.
Note: This patch series in particular introduces a new validation warning which prints on almost every draw. The warning is described at [1]. Similar warnings are triggered by future patches making other parts of the pipeline state dynamic.
An unfortunately internal Khronos discussion has determined that the warning is undesirable, and there is currently motion to adjust the specification accordingly; however, the validation layers have not yet been adjusted.
From: Zebediah Figura zfigura@codeweavers.com
It never changes. --- dlls/wined3d/context_vk.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index 29a4a4998d4..9a0b2342440 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -2119,6 +2119,8 @@ static void wined3d_context_vk_init_graphics_pipeline_key(struct wined3d_context key->vp_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; key->vp_desc.pViewports = key->viewports; key->vp_desc.pScissors = key->scissors; + key->vp_desc.viewportCount = (context_vk->vk_info->multiple_viewports ? WINED3D_MAX_VIEWPORTS : 1); + key->vp_desc.scissorCount = key->vp_desc.viewportCount;
key->rs_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; key->rs_desc.lineWidth = 1.0f; @@ -2458,9 +2460,6 @@ static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_conte || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_SCISSORRECT) || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_RASTERIZER)) { - key->vp_desc.viewportCount = (context_vk->vk_info->multiple_viewports ? WINED3D_MAX_VIEWPORTS : 1); - key->vp_desc.scissorCount = key->vp_desc.viewportCount; - for (i = 0; i < key->vp_desc.viewportCount; ++i) { const struct wined3d_viewport *src_viewport = &state->viewports[i];
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/wined3d/context_vk.c | 69 ++++++++++++++++++++++++--------------- dlls/wined3d/wined3d_vk.h | 1 - 2 files changed, 43 insertions(+), 27 deletions(-)
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index 9a0b2342440..37ebf2671d9 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -1879,6 +1879,7 @@ void wined3d_context_vk_submit_command_buffer(struct wined3d_context_vk *context context_invalidate_state(&context_vk->c, STATE_INDEXBUFFER); context_invalidate_state(&context_vk->c, STATE_BLEND_FACTOR); context_invalidate_state(&context_vk->c, STATE_STENCIL_REF); + context_invalidate_state(&context_vk->c, STATE_VIEWPORT);
VK_CALL(vkEndCommandBuffer(buffer->vk_command_buffer));
@@ -2037,8 +2038,6 @@ static int wined3d_graphics_pipeline_vk_compare(const void *key, const struct wi if ((ret = wined3d_uint32_compare(a->ts_desc.patchControlPoints, b->ts_desc.patchControlPoints))) return ret;
- if ((ret = memcmp(a->viewports, b->viewports, sizeof(a->viewports)))) - return ret; if ((ret = memcmp(a->scissors, b->scissors, sizeof(a->scissors)))) return ret;
@@ -2093,6 +2092,7 @@ static void wined3d_context_vk_init_graphics_pipeline_key(struct wined3d_context { VK_DYNAMIC_STATE_BLEND_CONSTANTS, VK_DYNAMIC_STATE_STENCIL_REFERENCE, + VK_DYNAMIC_STATE_VIEWPORT, };
key = &context_vk->graphics.pipeline_key_vk; @@ -2117,7 +2117,6 @@ static void wined3d_context_vk_init_graphics_pipeline_key(struct wined3d_context key->ts_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
key->vp_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - key->vp_desc.pViewports = key->viewports; key->vp_desc.pScissors = key->scissors; key->vp_desc.viewportCount = (context_vk->vk_info->multiple_viewports ? WINED3D_MAX_VIEWPORTS : 1); key->vp_desc.scissorCount = key->vp_desc.viewportCount; @@ -2456,36 +2455,20 @@ static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_conte update = true; }
- if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_VIEWPORT) - || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_SCISSORRECT) + if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_SCISSORRECT) || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_RASTERIZER)) { for (i = 0; i < key->vp_desc.viewportCount; ++i) { const struct wined3d_viewport *src_viewport = &state->viewports[i]; - VkViewport *viewport = &key->viewports[i]; VkRect2D *scissor = &key->scissors[i];
if (i >= state->viewport_count) { - viewport->x = 0.0f; - viewport->y = 0.0f; - viewport->width = 1.0f; - viewport->height = 1.0f; - viewport->minDepth = 0.0f; - viewport->maxDepth = 0.0f; - memset(scissor, 0, sizeof(*scissor)); continue; }
- viewport->x = src_viewport->x; - viewport->y = src_viewport->y; - viewport->width = src_viewport->width; - viewport->height = src_viewport->height; - viewport->minDepth = src_viewport->min_z; - viewport->maxDepth = src_viewport->max_z; - if (state->rasterizer_state && state->rasterizer_state->desc.scissor) { const RECT *r = &state->scissor_rects[i]; @@ -2503,18 +2486,16 @@ static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_conte } else { - scissor->offset.x = viewport->x; - scissor->offset.y = viewport->y; - scissor->extent.width = viewport->width; - scissor->extent.height = viewport->height; + scissor->offset.x = src_viewport->x; + scissor->offset.y = src_viewport->y; + scissor->extent.width = src_viewport->width; + scissor->extent.height = src_viewport->height; } /* Scissor offsets need to be non-negative (VUID-VkPipelineViewportStateCreateInfo-x-02821) */ if (scissor->offset.x < 0) scissor->offset.x = 0; if (scissor->offset.y < 0) scissor->offset.y = 0; - viewport->y += viewport->height; - viewport->height = -viewport->height; }
update = true; @@ -3792,6 +3773,42 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_BLEND_FACTOR)) VK_CALL(vkCmdSetBlendConstants(vk_command_buffer, &state->blend_factor.r));
+ if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_VIEWPORT)) + { + unsigned int viewport_count = (context_vk->vk_info->multiple_viewports ? WINED3D_MAX_VIEWPORTS : 1); + VkViewport viewports[WINED3D_MAX_VIEWPORTS]; + unsigned int i; + + for (i = 0; i < viewport_count; ++i) + { + const struct wined3d_viewport *src_viewport = &state->viewports[i]; + VkViewport *viewport = &viewports[i]; + + if (i >= state->viewport_count) + { + viewport->x = 0.0f; + viewport->y = 0.0f; + viewport->width = 1.0f; + viewport->height = 1.0f; + viewport->minDepth = 0.0f; + viewport->maxDepth = 0.0f; + continue; + } + + viewport->x = src_viewport->x; + viewport->y = src_viewport->y; + viewport->width = src_viewport->width; + viewport->height = src_viewport->height; + viewport->minDepth = src_viewport->min_z; + viewport->maxDepth = src_viewport->max_z; + + viewport->y += viewport->height; + viewport->height = -viewport->height; + } + + VK_CALL(vkCmdSetViewport(vk_command_buffer, 0, viewport_count, viewports)); + } + memset(context_vk->c.dirty_graphics_states, 0, sizeof(context_vk->c.dirty_graphics_states)); context_vk->c.shader_update_mask &= 1u << WINED3D_SHADER_TYPE_COMPUTE;
diff --git a/dlls/wined3d/wined3d_vk.h b/dlls/wined3d/wined3d_vk.h index 90e0a3de497..04264e6db84 100644 --- a/dlls/wined3d/wined3d_vk.h +++ b/dlls/wined3d/wined3d_vk.h @@ -497,7 +497,6 @@ struct wined3d_graphics_pipeline_key_vk VkVertexInputBindingDivisorDescriptionEXT divisors[MAX_ATTRIBS]; VkVertexInputAttributeDescription attributes[MAX_ATTRIBS]; VkVertexInputBindingDescription bindings[MAX_ATTRIBS]; - VkViewport viewports[WINED3D_MAX_VIEWPORTS]; VkRect2D scissors[WINED3D_MAX_VIEWPORTS]; VkSampleMask sample_mask; VkPipelineColorBlendAttachmentState blend_attachments[WINED3D_MAX_RENDER_TARGETS];
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/wined3d/context_vk.c | 88 ++++++++++++++++----------------------- dlls/wined3d/wined3d_vk.h | 1 - 2 files changed, 37 insertions(+), 52 deletions(-)
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index 37ebf2671d9..d16359f046d 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -1880,6 +1880,7 @@ void wined3d_context_vk_submit_command_buffer(struct wined3d_context_vk *context context_invalidate_state(&context_vk->c, STATE_BLEND_FACTOR); context_invalidate_state(&context_vk->c, STATE_STENCIL_REF); context_invalidate_state(&context_vk->c, STATE_VIEWPORT); + context_invalidate_state(&context_vk->c, STATE_SCISSORRECT);
VK_CALL(vkEndCommandBuffer(buffer->vk_command_buffer));
@@ -2038,9 +2039,6 @@ static int wined3d_graphics_pipeline_vk_compare(const void *key, const struct wi if ((ret = wined3d_uint32_compare(a->ts_desc.patchControlPoints, b->ts_desc.patchControlPoints))) return ret;
- if ((ret = memcmp(a->scissors, b->scissors, sizeof(a->scissors)))) - return ret; - if ((ret = memcmp(&a->rs_desc, &b->rs_desc, sizeof(a->rs_desc)))) return ret;
@@ -2093,6 +2091,7 @@ static void wined3d_context_vk_init_graphics_pipeline_key(struct wined3d_context VK_DYNAMIC_STATE_BLEND_CONSTANTS, VK_DYNAMIC_STATE_STENCIL_REFERENCE, VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR, };
key = &context_vk->graphics.pipeline_key_vk; @@ -2117,7 +2116,6 @@ static void wined3d_context_vk_init_graphics_pipeline_key(struct wined3d_context key->ts_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
key->vp_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - key->vp_desc.pScissors = key->scissors; key->vp_desc.viewportCount = (context_vk->vk_info->multiple_viewports ? WINED3D_MAX_VIEWPORTS : 1); key->vp_desc.scissorCount = key->vp_desc.viewportCount;
@@ -2455,52 +2453,6 @@ static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_conte update = true; }
- if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_SCISSORRECT) - || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_RASTERIZER)) - { - for (i = 0; i < key->vp_desc.viewportCount; ++i) - { - const struct wined3d_viewport *src_viewport = &state->viewports[i]; - VkRect2D *scissor = &key->scissors[i]; - - if (i >= state->viewport_count) - { - memset(scissor, 0, sizeof(*scissor)); - continue; - } - - if (state->rasterizer_state && state->rasterizer_state->desc.scissor) - { - const RECT *r = &state->scissor_rects[i]; - - if (i >= state->scissor_rect_count) - { - memset(scissor, 0, sizeof(*scissor)); - continue; - } - - scissor->offset.x = r->left; - scissor->offset.y = r->top; - scissor->extent.width = r->right - r->left; - scissor->extent.height = r->bottom - r->top; - } - else - { - scissor->offset.x = src_viewport->x; - scissor->offset.y = src_viewport->y; - scissor->extent.width = src_viewport->width; - scissor->extent.height = src_viewport->height; - } - /* Scissor offsets need to be non-negative (VUID-VkPipelineViewportStateCreateInfo-x-02821) */ - if (scissor->offset.x < 0) - scissor->offset.x = 0; - if (scissor->offset.y < 0) - scissor->offset.y = 0; - } - - update = true; - } - if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_RASTERIZER) || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_SHADER(WINED3D_SHADER_TYPE_GEOMETRY))) { @@ -3773,16 +3725,20 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_BLEND_FACTOR)) VK_CALL(vkCmdSetBlendConstants(vk_command_buffer, &state->blend_factor.r));
- if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_VIEWPORT)) + if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_VIEWPORT) + || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_SCISSORRECT) + || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_RASTERIZER)) { unsigned int viewport_count = (context_vk->vk_info->multiple_viewports ? WINED3D_MAX_VIEWPORTS : 1); VkViewport viewports[WINED3D_MAX_VIEWPORTS]; + VkRect2D scissors[WINED3D_MAX_VIEWPORTS]; unsigned int i;
for (i = 0; i < viewport_count; ++i) { const struct wined3d_viewport *src_viewport = &state->viewports[i]; VkViewport *viewport = &viewports[i]; + VkRect2D *scissor = &scissors[i];
if (i >= state->viewport_count) { @@ -3792,6 +3748,7 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c viewport->height = 1.0f; viewport->minDepth = 0.0f; viewport->maxDepth = 0.0f; + memset(scissor, 0, sizeof(*scissor)); continue; }
@@ -3802,11 +3759,40 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c viewport->minDepth = src_viewport->min_z; viewport->maxDepth = src_viewport->max_z;
+ if (state->rasterizer_state && state->rasterizer_state->desc.scissor) + { + const RECT *r = &state->scissor_rects[i]; + + if (i >= state->scissor_rect_count) + { + memset(scissor, 0, sizeof(*scissor)); + continue; + } + + scissor->offset.x = r->left; + scissor->offset.y = r->top; + scissor->extent.width = r->right - r->left; + scissor->extent.height = r->bottom - r->top; + } + else + { + scissor->offset.x = src_viewport->x; + scissor->offset.y = src_viewport->y; + scissor->extent.width = src_viewport->width; + scissor->extent.height = src_viewport->height; + } + + /* Scissor offsets need to be non-negative (VUID-VkPipelineViewportStateCreateInfo-x-02821) */ + if (scissor->offset.x < 0) + scissor->offset.x = 0; + if (scissor->offset.y < 0) + scissor->offset.y = 0; viewport->y += viewport->height; viewport->height = -viewport->height; }
VK_CALL(vkCmdSetViewport(vk_command_buffer, 0, viewport_count, viewports)); + VK_CALL(vkCmdSetScissor(vk_command_buffer, 0, viewport_count, scissors)); }
memset(context_vk->c.dirty_graphics_states, 0, sizeof(context_vk->c.dirty_graphics_states)); diff --git a/dlls/wined3d/wined3d_vk.h b/dlls/wined3d/wined3d_vk.h index 04264e6db84..00f57a9496e 100644 --- a/dlls/wined3d/wined3d_vk.h +++ b/dlls/wined3d/wined3d_vk.h @@ -497,7 +497,6 @@ struct wined3d_graphics_pipeline_key_vk VkVertexInputBindingDivisorDescriptionEXT divisors[MAX_ATTRIBS]; VkVertexInputAttributeDescription attributes[MAX_ATTRIBS]; VkVertexInputBindingDescription bindings[MAX_ATTRIBS]; - VkRect2D scissors[WINED3D_MAX_VIEWPORTS]; VkSampleMask sample_mask; VkPipelineColorBlendAttachmentState blend_attachments[WINED3D_MAX_RENDER_TARGETS];
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/wined3d/adapter_vk.c | 20 +++++++++++++++----- dlls/wined3d/wined3d_vk.h | 3 ++- 2 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index 1216a84e990..6d3b31aeb97 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -241,10 +241,11 @@ static HRESULT wined3d_select_vulkan_queue_family(const struct wined3d_adapter_v
struct wined3d_physical_device_info { - VkPhysicalDeviceTransformFeedbackFeaturesEXT xfb_features; - VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vertex_divisor_features; + VkPhysicalDeviceExtendedDynamicStateFeaturesEXT dynamic_state_features; VkPhysicalDeviceHostQueryResetFeatures host_query_reset_features; VkPhysicalDeviceShaderDrawParametersFeatures draw_parameters_features; + VkPhysicalDeviceTransformFeedbackFeaturesEXT xfb_features; + VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vertex_divisor_features;
VkPhysicalDeviceFeatures2 features2; }; @@ -338,6 +339,7 @@ static void get_physical_device_info(const struct wined3d_adapter_vk *adapter_vk { VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *vertex_divisor_features = &info->vertex_divisor_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; VkPhysicalDeviceTransformFeedbackFeaturesEXT *xfb_features = &info->xfb_features; VkPhysicalDevice physical_device = adapter_vk->physical_device; @@ -361,8 +363,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_state_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT; + dynamic_state_features->pNext = host_query_reset_features; + features2->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; - features2->pNext = host_query_reset_features; + features2->pNext = dynamic_state_features;
if (vk_info->vk_ops.vkGetPhysicalDeviceFeatures2) VK_CALL(vkGetPhysicalDeviceFeatures2(physical_device, features2)); @@ -2264,6 +2269,9 @@ static void wined3d_adapter_vk_init_d3d_info(struct wined3d_adapter_vk *adapter_
get_physical_device_info(adapter_vk, &device_info);
+ if (!device_info.dynamic_state_features.extendedDynamicState) + adapter_vk->vk_info.supported[WINED3D_VK_EXT_EXTENDED_DYNAMIC_STATE] = FALSE; + if (!device_info.host_query_reset_features.hostQueryReset) adapter_vk->vk_info.supported[WINED3D_VK_EXT_HOST_QUERY_RESET] = FALSE;
@@ -2357,6 +2365,8 @@ 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_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}, {VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, ~0u, true}, @@ -2365,7 +2375,6 @@ static bool wined3d_adapter_vk_init_device_extensions(struct wined3d_adapter_vk {VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME,VK_API_VERSION_1_2}, {VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, VK_API_VERSION_1_1}, {VK_KHR_SWAPCHAIN_EXTENSION_NAME, ~0u, true}, - {VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, VK_API_VERSION_1_2}, };
static const struct @@ -2375,12 +2384,13 @@ static bool wined3d_adapter_vk_init_device_extensions(struct wined3d_adapter_vk } map[] = { + {VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, WINED3D_VK_EXT_EXTENDED_DYNAMIC_STATE}, + {VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, WINED3D_VK_EXT_HOST_QUERY_RESET}, {VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, WINED3D_VK_EXT_SHADER_STENCIL_EXPORT}, {VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, WINED3D_VK_EXT_TRANSFORM_FEEDBACK}, {VK_KHR_MAINTENANCE2_EXTENSION_NAME, WINED3D_VK_KHR_MAINTENANCE2}, {VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME, WINED3D_VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE}, {VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, WINED3D_VK_KHR_SHADER_DRAW_PARAMETERS}, - {VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, WINED3D_VK_EXT_HOST_QUERY_RESET}, };
if ((vr = VK_CALL(vkEnumerateDeviceExtensionProperties(physical_device, NULL, &count, NULL))) < 0) diff --git a/dlls/wined3d/wined3d_vk.h b/dlls/wined3d/wined3d_vk.h index 00f57a9496e..f94ba11346c 100644 --- a/dlls/wined3d/wined3d_vk.h +++ b/dlls/wined3d/wined3d_vk.h @@ -215,12 +215,13 @@ enum wined3d_vk_extension { WINED3D_VK_EXT_NONE,
+ WINED3D_VK_EXT_EXTENDED_DYNAMIC_STATE, + WINED3D_VK_EXT_HOST_QUERY_RESET, WINED3D_VK_EXT_SHADER_STENCIL_EXPORT, WINED3D_VK_EXT_TRANSFORM_FEEDBACK, WINED3D_VK_KHR_MAINTENANCE2, WINED3D_VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE, WINED3D_VK_KHR_SHADER_DRAW_PARAMETERS, - WINED3D_VK_EXT_HOST_QUERY_RESET,
WINED3D_VK_EXT_COUNT, };
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/wined3d/context_vk.c | 73 ++++++++++++++++++++++++++++++++++----- dlls/wined3d/wined3d_vk.h | 8 +++++ 2 files changed, 72 insertions(+), 9 deletions(-)
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index d16359f046d..8302237c73b 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -1878,6 +1878,7 @@ void wined3d_context_vk_submit_command_buffer(struct wined3d_context_vk *context 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); + context_invalidate_state(&context_vk->c, STATE_DEPTH_STENCIL); context_invalidate_state(&context_vk->c, STATE_STENCIL_REF); context_invalidate_state(&context_vk->c, STATE_VIEWPORT); context_invalidate_state(&context_vk->c, STATE_SCISSORRECT); @@ -2082,17 +2083,28 @@ static int wined3d_bo_slab_vk_compare(const void *key, const struct wine_rb_entr
static void wined3d_context_vk_init_graphics_pipeline_key(struct wined3d_context_vk *context_vk) { + const struct wined3d_vk_info *vk_info = context_vk->vk_info; + VkDynamicState *dynamic_states = context_vk->dynamic_states; struct wined3d_graphics_pipeline_key_vk *key; VkPipelineShaderStageCreateInfo *stage; + uint32_t dynamic_state_count = 0; unsigned int i;
- static const VkDynamicState dynamic_states[] = + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_BLEND_CONSTANTS; + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_STENCIL_REFERENCE; + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_VIEWPORT; + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_SCISSOR; + + if (vk_info->supported[WINED3D_VK_EXT_EXTENDED_DYNAMIC_STATE]) { - VK_DYNAMIC_STATE_BLEND_CONSTANTS, - VK_DYNAMIC_STATE_STENCIL_REFERENCE, - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_SCISSOR, - }; + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT; + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT; + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT; + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT; + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_STENCIL_OP_EXT; + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK; + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK; + }
key = &context_vk->graphics.pipeline_key_vk; memset(key, 0, sizeof(*key)); @@ -2137,7 +2149,7 @@ static void wined3d_context_vk_init_graphics_pipeline_key(struct wined3d_context key->blend_desc.blendConstants[3] = 1.0f;
key->dynamic_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - key->dynamic_desc.dynamicStateCount = ARRAY_SIZE(dynamic_states); + key->dynamic_desc.dynamicStateCount = dynamic_state_count; key->dynamic_desc.pDynamicStates = dynamic_states;
key->pipeline_desc.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; @@ -2309,6 +2321,7 @@ static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_conte { unsigned int i, attribute_count, binding_count, divisor_count, stage_count; const struct wined3d_d3d_info *d3d_info = context_vk->c.d3d_info; + const struct wined3d_vk_info *vk_info = context_vk->vk_info; struct wined3d_graphics_pipeline_key_vk *key; VkPipelineShaderStageCreateInfo *stage; struct wined3d_stream_info stream_info; @@ -2471,8 +2484,9 @@ static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_conte update = true; }
- if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_DEPTH_STENCIL) - || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_FRAMEBUFFER)) + 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))) { const struct wined3d_depth_stencil_state *d = state->depth_stencil_state;
@@ -3795,6 +3809,47 @@ 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->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))) + { + const struct wined3d_depth_stencil_state *d = state->depth_stencil_state; + + if (d) + { + VkBool32 stencil_enable = state->fb.depth_stencil && d->desc.stencil; + + VK_CALL(vkCmdSetDepthTestEnableEXT(vk_command_buffer, d->desc.depth)); + VK_CALL(vkCmdSetDepthWriteEnableEXT(vk_command_buffer, d->desc.depth_write)); + VK_CALL(vkCmdSetDepthCompareOpEXT(vk_command_buffer, vk_compare_op_from_wined3d(d->desc.depth_func))); + VK_CALL(vkCmdSetStencilTestEnableEXT(vk_command_buffer, stencil_enable)); + if (stencil_enable) + { + VK_CALL(vkCmdSetStencilOpEXT(vk_command_buffer, VK_STENCIL_FACE_FRONT_BIT, + vk_stencil_op_from_wined3d(d->desc.front.fail_op), + vk_stencil_op_from_wined3d(d->desc.front.pass_op), + vk_stencil_op_from_wined3d(d->desc.front.depth_fail_op), + vk_compare_op_from_wined3d(d->desc.front.func))); + VK_CALL(vkCmdSetStencilOpEXT(vk_command_buffer, VK_STENCIL_FACE_BACK_BIT, + vk_stencil_op_from_wined3d(d->desc.back.fail_op), + vk_stencil_op_from_wined3d(d->desc.back.pass_op), + vk_stencil_op_from_wined3d(d->desc.back.depth_fail_op), + vk_compare_op_from_wined3d(d->desc.back.func))); + VK_CALL(vkCmdSetStencilCompareMask(vk_command_buffer, + VK_STENCIL_FACE_FRONT_AND_BACK, d->desc.stencil_read_mask)); + VK_CALL(vkCmdSetStencilWriteMask(vk_command_buffer, + VK_STENCIL_FACE_FRONT_AND_BACK, d->desc.stencil_write_mask)); + } + } + else + { + VK_CALL(vkCmdSetDepthTestEnableEXT(vk_command_buffer, VK_TRUE)); + VK_CALL(vkCmdSetDepthWriteEnableEXT(vk_command_buffer, VK_TRUE)); + VK_CALL(vkCmdSetDepthCompareOpEXT(vk_command_buffer, VK_COMPARE_OP_LESS)); + VK_CALL(vkCmdSetStencilTestEnableEXT(vk_command_buffer, VK_FALSE)); + } + } + memset(context_vk->c.dirty_graphics_states, 0, sizeof(context_vk->c.dirty_graphics_states)); context_vk->c.shader_update_mask &= 1u << WINED3D_SHADER_TYPE_COMPUTE;
diff --git a/dlls/wined3d/wined3d_vk.h b/dlls/wined3d/wined3d_vk.h index f94ba11346c..280f36f692a 100644 --- a/dlls/wined3d/wined3d_vk.h +++ b/dlls/wined3d/wined3d_vk.h @@ -179,6 +179,12 @@ struct wined3d_device_vk; VK_DEVICE_PFN(vkUnmapMemory) \ VK_DEVICE_PFN(vkUpdateDescriptorSets) \ VK_DEVICE_PFN(vkWaitForFences) \ + /* VK_EXT_extended_dynamic_state */ \ + VK_DEVICE_EXT_PFN(vkCmdSetDepthCompareOpEXT) \ + VK_DEVICE_EXT_PFN(vkCmdSetDepthTestEnableEXT) \ + VK_DEVICE_EXT_PFN(vkCmdSetDepthWriteEnableEXT) \ + VK_DEVICE_EXT_PFN(vkCmdSetStencilOpEXT) \ + VK_DEVICE_EXT_PFN(vkCmdSetStencilTestEnableEXT) \ /* VK_EXT_transform_feedback */ \ VK_DEVICE_EXT_PFN(vkCmdBeginQueryIndexedEXT) \ VK_DEVICE_EXT_PFN(vkCmdBeginTransformFeedbackEXT) \ @@ -559,6 +565,8 @@ struct wined3d_context_vk
const struct wined3d_vk_info *vk_info;
+ VkDynamicState dynamic_states[11]; + uint32_t update_compute_pipeline : 1; uint32_t update_stream_output : 1; uint32_t padding : 30;
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=143064
Your paranoid android.
=== debian11b (64 bit WoW report) ===
adsldp: ldap: Timeout
This merge request was approved by Jan Sikorski.