Module: wine Branch: master Commit: a00efa12e27035a4a1afb961daefa69766e86b17 URL: https://gitlab.winehq.org/wine/wine/-/commit/a00efa12e27035a4a1afb961daefa69...
Author: Zebediah Figura zfigura@codeweavers.com Date: Thu Sep 14 14:14:16 2023 -0500
wined3d: Use dynamic state for multisample state if possible.
---
dlls/wined3d/adapter_vk.c | 6 ++++++ dlls/wined3d/context.c | 1 + dlls/wined3d/context_vk.c | 25 +++++++++++++++++++++++-- dlls/wined3d/cs.c | 9 ++++++--- dlls/wined3d/wined3d_private.h | 5 +++-- dlls/wined3d/wined3d_vk.h | 7 ++++++- 6 files changed, 45 insertions(+), 8 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index b31e65cde58..32acfddf41f 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -2296,6 +2296,7 @@ static enum wined3d_feature_level feature_level_from_caps(const struct wined3d_p
static void wined3d_adapter_vk_init_d3d_info(struct wined3d_adapter_vk *adapter_vk, uint32_t wined3d_creation_flags) { + const struct VkPhysicalDeviceExtendedDynamicState3FeaturesEXT *dynamic_state3; struct wined3d_d3d_info *d3d_info = &adapter_vk->a.d3d_info; struct wined3d_vk_info *vk_info = &adapter_vk->vk_info; struct wined3d_physical_device_info device_info; @@ -2382,6 +2383,11 @@ 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; + + dynamic_state3 = &device_info.dynamic_state3_features; + vk_info->dynamic_multisample_state = dynamic_state3->extendedDynamicState3RasterizationSamples + && dynamic_state3->extendedDynamicState3AlphaToCoverageEnable + && dynamic_state3->extendedDynamicState3SampleMask; }
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 d0193237d25..b6c24c3d837 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -116,6 +116,7 @@ void wined3d_context_init(struct wined3d_context *context, struct wined3d_swapch
context->update_primitive_type = 1; context->update_patch_vertex_count = 1; + context->update_multisample_state = 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 e59069ab809..76fcde1d06b 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -1907,6 +1907,7 @@ void wined3d_context_vk_submit_command_buffer(struct wined3d_context_vk *context 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_vk->c.update_multisample_state = 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); @@ -2145,6 +2146,12 @@ static void wined3d_context_vk_init_graphics_pipeline_key(struct wined3d_context } if (vk_info->dynamic_patch_vertex_count) dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT; + if (vk_info->dynamic_multisample_state) + { + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT; + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT; + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_SAMPLE_MASK_EXT; + }
key = &context_vk->graphics.pipeline_key_vk; memset(key, 0, sizeof(*key)); @@ -2176,6 +2183,8 @@ static void wined3d_context_vk_init_graphics_pipeline_key(struct wined3d_context
key->ms_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; key->ms_desc.pSampleMask = &key->sample_mask; + /* This has to be initialized to a nonzero value even if it's dynamic. */ + key->ms_desc.rasterizationSamples = 1;
key->ds_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; key->ds_desc.maxDepthBounds = 1.0f; @@ -2526,8 +2535,9 @@ static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_conte update = true; }
- if (key->ms_desc.rasterizationSamples != context_vk->sample_count - || isStateDirty(&context_vk->c, STATE_BLEND) || isStateDirty(&context_vk->c, STATE_SAMPLE_MASK)) + if (!vk_info->dynamic_multisample_state + && (key->ms_desc.rasterizationSamples != context_vk->sample_count + || isStateDirty(&context_vk->c, STATE_BLEND) || isStateDirty(&context_vk->c, STATE_SAMPLE_MASK))) { key->ms_desc.rasterizationSamples = context_vk->sample_count; key->ms_desc.alphaToCoverageEnable = state->blend_state && state->blend_state->desc.alpha_to_coverage; @@ -3878,6 +3888,17 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c context_vk->c.update_patch_vertex_count = 0; }
+ if (vk_info->dynamic_multisample_state && context_vk->c.update_multisample_state) + { + unsigned int sample_count = context_vk->sample_count; + + VK_CALL(vkCmdSetAlphaToCoverageEnableEXT(vk_command_buffer, + state->blend_state && state->blend_state->desc.alpha_to_coverage)); + VK_CALL(vkCmdSetRasterizationSamplesEXT(vk_command_buffer, sample_count)); + VK_CALL(vkCmdSetSampleMaskEXT(vk_command_buffer, sample_count, &state->sample_mask)); + context_vk->c.update_multisample_state = 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 3b1891321a4..5ee4c8d1538 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -1758,17 +1758,20 @@ void wined3d_device_context_emit_set_shader(struct wined3d_device_context *conte static void wined3d_cs_exec_set_blend_state(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_blend_state *op = data; + struct wined3d_device *device = cs->c.device; struct wined3d_state *state = &cs->state;
if (state->blend_state != op->state) { state->blend_state = op->state; - device_invalidate_state(cs->c.device, STATE_BLEND); + device_invalidate_state(device, STATE_BLEND); } state->blend_factor = op->factor; - device_invalidate_state(cs->c.device, STATE_BLEND_FACTOR); + device_invalidate_state(device, STATE_BLEND_FACTOR); state->sample_mask = op->sample_mask; - device_invalidate_state(cs->c.device, STATE_SAMPLE_MASK); + device_invalidate_state(device, STATE_SAMPLE_MASK); + for (unsigned int i = 0; i < device->context_count; ++i) + device->contexts[i]->update_multisample_state = 1; }
void wined3d_device_context_emit_set_blend_state(struct wined3d_device_context *context, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index f42d5d7d050..1ef99272b53 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1967,7 +1967,8 @@ struct wined3d_context DWORD namedArraysLoaded : 1; DWORD update_primitive_type : 1; DWORD update_patch_vertex_count : 1; - DWORD padding : 3; + DWORD update_multisample_state : 1; + DWORD padding : 2;
DWORD clip_distance_mask : 8; /* WINED3D_MAX_CLIP_DISTANCES, 8 */
@@ -2912,7 +2913,7 @@ struct wined3d_state unsigned int render_states[WINEHIGHEST_RENDER_STATE + 1]; struct wined3d_blend_state *blend_state; struct wined3d_color blend_factor; - unsigned int sample_mask; + uint32_t sample_mask; struct wined3d_depth_stencil_state *depth_stencil_state; unsigned int stencil_ref; bool depth_bounds_enable; diff --git a/dlls/wined3d/wined3d_vk.h b/dlls/wined3d/wined3d_vk.h index e995ef3c408..dfa876b8048 100644 --- a/dlls/wined3d/wined3d_vk.h +++ b/dlls/wined3d/wined3d_vk.h @@ -189,6 +189,10 @@ struct wined3d_device_vk; /* VK_EXT_extended_dynamic_state2 */ \ VK_DEVICE_EXT_PFN(vkCmdSetPatchControlPointsEXT) \ VK_DEVICE_EXT_PFN(vkCmdSetPrimitiveRestartEnableEXT) \ + /* VK_EXT_extended_dynamic_state3 */ \ + VK_DEVICE_EXT_PFN(vkCmdSetAlphaToCoverageEnableEXT) \ + VK_DEVICE_EXT_PFN(vkCmdSetRasterizationSamplesEXT) \ + VK_DEVICE_EXT_PFN(vkCmdSetSampleMaskEXT) \ /* VK_EXT_transform_feedback */ \ VK_DEVICE_EXT_PFN(vkCmdBeginQueryIndexedEXT) \ VK_DEVICE_EXT_PFN(vkCmdBeginTransformFeedbackEXT) \ @@ -249,6 +253,7 @@ struct wined3d_vk_info bool multiple_viewports; bool dynamic_state2; bool dynamic_patch_vertex_count; + bool dynamic_multisample_state; };
#define VK_CALL(f) (vk_info->vk_ops.f) @@ -571,7 +576,7 @@ struct wined3d_context_vk
const struct wined3d_vk_info *vk_info;
- VkDynamicState dynamic_states[14]; + VkDynamicState dynamic_states[17];
uint32_t update_compute_pipeline : 1; uint32_t update_stream_output : 1;