From: Zebediah Figura zfigura@codeweavers.com
--- dlls/wined3d/adapter_vk.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index 7b4bf898fd1..b31e65cde58 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -243,6 +243,7 @@ struct wined3d_physical_device_info { VkPhysicalDeviceExtendedDynamicStateFeaturesEXT dynamic_state_features; VkPhysicalDeviceExtendedDynamicState2FeaturesEXT dynamic_state2_features; + VkPhysicalDeviceExtendedDynamicState3FeaturesEXT dynamic_state3_features; VkPhysicalDeviceHostQueryResetFeatures host_query_reset_features; VkPhysicalDeviceShaderDrawParametersFeatures draw_parameters_features; VkPhysicalDeviceTransformFeedbackFeaturesEXT xfb_features; @@ -253,6 +254,7 @@ struct wined3d_physical_device_info
static void wined3d_disable_vulkan_features(struct wined3d_physical_device_info *info) { + VkPhysicalDeviceExtendedDynamicState3FeaturesEXT *dynamic_state3 = &info->dynamic_state3_features; VkPhysicalDeviceFeatures *features = &info->features2.features;
features->depthBounds = VK_FALSE; @@ -280,6 +282,31 @@ static void wined3d_disable_vulkan_features(struct wined3d_physical_device_info features->sparseResidency16Samples = VK_FALSE; features->sparseResidencyAliased = VK_FALSE; features->inheritedQueries = VK_FALSE; + + dynamic_state3->extendedDynamicState3AlphaToOneEnable = VK_FALSE; + dynamic_state3->extendedDynamicState3ColorBlendAdvanced = VK_FALSE; + dynamic_state3->extendedDynamicState3ConservativeRasterizationMode = VK_FALSE; + dynamic_state3->extendedDynamicState3CoverageModulationMode = VK_FALSE; + dynamic_state3->extendedDynamicState3CoverageModulationTable = VK_FALSE; + dynamic_state3->extendedDynamicState3CoverageModulationTableEnable = VK_FALSE; + dynamic_state3->extendedDynamicState3CoverageReductionMode = VK_FALSE; + dynamic_state3->extendedDynamicState3CoverageToColorEnable = VK_FALSE; + dynamic_state3->extendedDynamicState3CoverageToColorLocation = VK_FALSE; + dynamic_state3->extendedDynamicState3DepthClipEnable = VK_FALSE; + dynamic_state3->extendedDynamicState3DepthClipNegativeOneToOne = VK_FALSE; + dynamic_state3->extendedDynamicState3ExtraPrimitiveOverestimationSize = VK_FALSE; + dynamic_state3->extendedDynamicState3LineRasterizationMode = VK_FALSE; + dynamic_state3->extendedDynamicState3LineStippleEnable = VK_FALSE; + dynamic_state3->extendedDynamicState3LogicOpEnable = VK_FALSE; + dynamic_state3->extendedDynamicState3PolygonMode = VK_FALSE; + dynamic_state3->extendedDynamicState3ProvokingVertexMode = VK_FALSE; + dynamic_state3->extendedDynamicState3RasterizationStream = VK_FALSE; + dynamic_state3->extendedDynamicState3RepresentativeFragmentTestEnable = VK_FALSE; + dynamic_state3->extendedDynamicState3SampleLocationsEnable = VK_FALSE; + dynamic_state3->extendedDynamicState3ShadingRateImageEnable = VK_FALSE; + dynamic_state3->extendedDynamicState3TessellationDomainOrigin = VK_FALSE; + dynamic_state3->extendedDynamicState3ViewportWScalingEnable = VK_FALSE; + dynamic_state3->extendedDynamicState3ViewportSwizzle = VK_FALSE; }
static struct wined3d_allocator_chunk *wined3d_allocator_vk_create_chunk(struct wined3d_allocator *allocator, @@ -339,6 +366,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; + VkPhysicalDeviceExtendedDynamicState3FeaturesEXT *dynamic_state3_features = &info->dynamic_state3_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; @@ -365,8 +393,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_state3_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_3_FEATURES_EXT; + dynamic_state3_features->pNext = host_query_reset_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_state2_features->pNext = dynamic_state3_features;
dynamic_state_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT; dynamic_state_features->pNext = dynamic_state2_features; @@ -2374,6 +2405,7 @@ static bool wined3d_adapter_vk_init_device_extensions(struct wined3d_adapter_vk { {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_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME, ~0u}, {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 | 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..81c2bfb9a30 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_patch_vertex_count = 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;
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/wined3d/adapter_vk.c | 3 ++ dlls/wined3d/context_vk.c | 85 ++++++++++++++++++++++++++++++++++++++- dlls/wined3d/wined3d_vk.h | 6 ++- 3 files changed, 91 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index 32acfddf41f..3d7b4fe1cc6 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -2388,6 +2388,9 @@ static void wined3d_adapter_vk_init_d3d_info(struct wined3d_adapter_vk *adapter_ vk_info->dynamic_multisample_state = dynamic_state3->extendedDynamicState3RasterizationSamples && dynamic_state3->extendedDynamicState3AlphaToCoverageEnable && dynamic_state3->extendedDynamicState3SampleMask; + vk_info->dynamic_blend_state = dynamic_state3->extendedDynamicState3ColorBlendEnable + && dynamic_state3->extendedDynamicState3ColorBlendEquation + && dynamic_state3->extendedDynamicState3ColorWriteMask; }
static bool wined3d_adapter_vk_init_device_extensions(struct wined3d_adapter_vk *adapter_vk) diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index 76fcde1d06b..123b358bc78 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -1910,6 +1910,7 @@ void wined3d_context_vk_submit_command_buffer(struct wined3d_context_vk *context 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); 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); @@ -2152,6 +2153,12 @@ static void wined3d_context_vk_init_graphics_pipeline_key(struct wined3d_context dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT; dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_SAMPLE_MASK_EXT; } + if (vk_info->dynamic_blend_state) + { + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT; + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT; + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT; + }
key = &context_vk->graphics.pipeline_key_vk; memset(key, 0, sizeof(*key)); @@ -2350,6 +2357,75 @@ static void wined3d_context_vk_update_blend_state(const struct wined3d_context_v } }
+static void wined3d_context_vk_set_dynamic_blend_state(const struct wined3d_context_vk *context_vk, + VkCommandBuffer vk_command_buffer, const struct wined3d_vk_info *vk_info, const struct wined3d_state *state) +{ + VkColorBlendEquationEXT equations[WINED3D_MAX_RENDER_TARGETS] = {{0}}; + VkColorComponentFlags write_mask[WINED3D_MAX_RENDER_TARGETS]; + unsigned int rt_count = context_vk->rt_count; + VkBool32 enable[WINED3D_MAX_RENDER_TARGETS]; + const struct wined3d_blend_state_desc *b; + + if (!state->blend_state) + { + static const VkBool32 default_enable[WINED3D_MAX_RENDER_TARGETS]; +#define X (VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT) + static const VkColorComponentFlags default_write_mask[WINED3D_MAX_RENDER_TARGETS] = {X, X, X, X, X, X, X, X}; +#undef X + + VK_CALL(vkCmdSetColorBlendEnableEXT(vk_command_buffer, 0, rt_count, default_enable)); + VK_CALL(vkCmdSetColorWriteMaskEXT(vk_command_buffer, 0, rt_count, default_write_mask)); + return; + } + + b = &state->blend_state->desc; + for (unsigned int i = 0; i < rt_count; ++i) + { + const struct wined3d_rendertarget_blend_state_desc *rt = &b->rt[b->independent ? i : 0]; + const struct wined3d_rendertarget_view *rtv = state->fb.render_targets[i]; + VkColorBlendEquationEXT *eq = &equations[i]; + enum wined3d_blend src_blend, dst_blend; + const struct wined3d_format *rt_format; + + write_mask[i] = vk_colour_write_mask_from_wined3d(rt->writemask); + enable[i] = rt->enable; + + if (!rt->enable) + continue; + + if (rtv) + rt_format = rtv->format; + else + rt_format = wined3d_get_format(context_vk->c.device->adapter, WINED3DFMT_NULL, 0); + + src_blend = rt->src; + dst_blend = rt->dst; + if (src_blend == WINED3D_BLEND_BOTHSRCALPHA) + { + src_blend = WINED3D_BLEND_SRCALPHA; + dst_blend = WINED3D_BLEND_INVSRCALPHA; + } + else if (src_blend == WINED3D_BLEND_BOTHINVSRCALPHA) + { + src_blend = WINED3D_BLEND_INVSRCALPHA; + dst_blend = WINED3D_BLEND_SRCALPHA; + } + eq->srcColorBlendFactor = vk_blend_factor_from_wined3d(src_blend, rt_format, FALSE); + eq->dstColorBlendFactor = vk_blend_factor_from_wined3d(dst_blend, rt_format, FALSE); + eq->colorBlendOp = vk_blend_op_from_wined3d(rt->op); + + src_blend = rt->src_alpha; + dst_blend = rt->dst_alpha; + eq->srcAlphaBlendFactor = vk_blend_factor_from_wined3d(src_blend, rt_format, TRUE); + eq->dstAlphaBlendFactor = vk_blend_factor_from_wined3d(dst_blend, rt_format, TRUE); + eq->alphaBlendOp = vk_blend_op_from_wined3d(rt->op_alpha); + } + + VK_CALL(vkCmdSetColorBlendEnableEXT(vk_command_buffer, 0, rt_count, enable)); + VK_CALL(vkCmdSetColorWriteMaskEXT(vk_command_buffer, 0, rt_count, write_mask)); + VK_CALL(vkCmdSetColorBlendEquationEXT(vk_command_buffer, 0, rt_count, equations)); +} + static VkFormat vk_format_from_component_type(enum wined3d_component_type component_type) { switch (component_type) @@ -2591,8 +2667,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_BLEND) - || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_FRAMEBUFFER)) + if (!vk_info->dynamic_blend_state + && (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_BLEND) + || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_FRAMEBUFFER))) { wined3d_context_vk_update_blend_state(context_vk, state, key);
@@ -3899,6 +3976,10 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c context_vk->c.update_multisample_state = 0; }
+ if (vk_info->dynamic_blend_state && (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_BLEND) + || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_FRAMEBUFFER))) + wined3d_context_vk_set_dynamic_blend_state(context_vk, vk_command_buffer, vk_info, state); + 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/wined3d_vk.h b/dlls/wined3d/wined3d_vk.h index dfa876b8048..549245eb81f 100644 --- a/dlls/wined3d/wined3d_vk.h +++ b/dlls/wined3d/wined3d_vk.h @@ -191,6 +191,9 @@ struct wined3d_device_vk; VK_DEVICE_EXT_PFN(vkCmdSetPrimitiveRestartEnableEXT) \ /* VK_EXT_extended_dynamic_state3 */ \ VK_DEVICE_EXT_PFN(vkCmdSetAlphaToCoverageEnableEXT) \ + VK_DEVICE_EXT_PFN(vkCmdSetColorBlendEnableEXT) \ + VK_DEVICE_EXT_PFN(vkCmdSetColorBlendEquationEXT) \ + VK_DEVICE_EXT_PFN(vkCmdSetColorWriteMaskEXT) \ VK_DEVICE_EXT_PFN(vkCmdSetRasterizationSamplesEXT) \ VK_DEVICE_EXT_PFN(vkCmdSetSampleMaskEXT) \ /* VK_EXT_transform_feedback */ \ @@ -254,6 +257,7 @@ struct wined3d_vk_info bool dynamic_state2; bool dynamic_patch_vertex_count; bool dynamic_multisample_state; + bool dynamic_blend_state; };
#define VK_CALL(f) (vk_info->vk_ops.f) @@ -576,7 +580,7 @@ struct wined3d_context_vk
const struct wined3d_vk_info *vk_info;
- VkDynamicState dynamic_states[17]; + VkDynamicState dynamic_states[20];
uint32_t update_compute_pipeline : 1; uint32_t update_stream_output : 1;
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/wined3d/adapter_vk.c | 4 +++ dlls/wined3d/context_vk.c | 76 +++++++++++++++++++++++++++++++++++++-- dlls/wined3d/wined3d_vk.h | 8 ++++- 3 files changed, 85 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index 3d7b4fe1cc6..418b67de8b6 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -2391,6 +2391,10 @@ static void wined3d_adapter_vk_init_d3d_info(struct wined3d_adapter_vk *adapter_ vk_info->dynamic_blend_state = dynamic_state3->extendedDynamicState3ColorBlendEnable && dynamic_state3->extendedDynamicState3ColorBlendEquation && dynamic_state3->extendedDynamicState3ColorWriteMask; + /* Rasterizer state needs EDS2, for rasterizer discard, and EDS1, for cull mode and front face. */ + vk_info->dynamic_rasterizer_state = dynamic_state3->extendedDynamicState3DepthClampEnable + && vk_info->dynamic_state2 + && adapter_vk->vk_info.supported[WINED3D_VK_EXT_EXTENDED_DYNAMIC_STATE]; }
static bool wined3d_adapter_vk_init_device_extensions(struct wined3d_adapter_vk *adapter_vk) diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index 123b358bc78..2b0c0132f79 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -1913,6 +1913,7 @@ void wined3d_context_vk_submit_command_buffer(struct wined3d_context_vk *context context_invalidate_state(&context_vk->c, STATE_BLEND); 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_RASTERIZER); 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); @@ -2159,6 +2160,15 @@ static void wined3d_context_vk_init_graphics_pipeline_key(struct wined3d_context dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT; dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT; } + if (vk_info->dynamic_rasterizer_state) + { + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT; + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT; + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_CULL_MODE_EXT; + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_FRONT_FACE_EXT; + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT; + dynamic_states[dynamic_state_count++] = VK_DYNAMIC_STATE_DEPTH_BIAS; + }
key = &context_vk->graphics.pipeline_key_vk; memset(key, 0, sizeof(*key)); @@ -2291,6 +2301,64 @@ static void wined3d_context_vk_update_rasterisation_state(const struct wined3d_c desc->depthBiasClamp = r->depth_bias_clamp; }
+static void wined3d_context_vk_set_dynamic_rasterizer_state(const struct wined3d_context_vk *context_vk, + VkCommandBuffer vk_command_buffer, const struct wined3d_vk_info *vk_info, const struct wined3d_state *state) +{ + const struct wined3d_d3d_info *d3d_info = context_vk->c.d3d_info; + const struct wined3d_rasterizer_state_desc *r; + float scale_bias; + union + { + uint32_t u32; + float f32; + } const_bias; + + VK_CALL(vkCmdSetRasterizerDiscardEnableEXT(vk_command_buffer, + is_rasterization_disabled(state->shader[WINED3D_SHADER_TYPE_GEOMETRY]))); + + if (!state->rasterizer_state) + { + VK_CALL(vkCmdSetDepthClampEnableEXT(vk_command_buffer, VK_FALSE)); + VK_CALL(vkCmdSetCullModeEXT(vk_command_buffer, VK_CULL_MODE_BACK_BIT)); + VK_CALL(vkCmdSetFrontFaceEXT(vk_command_buffer, VK_FRONT_FACE_CLOCKWISE)); + VK_CALL(vkCmdSetDepthBiasEnableEXT(vk_command_buffer, VK_FALSE)); + return; + } + + r = &state->rasterizer_state->desc; + VK_CALL(vkCmdSetDepthClampEnableEXT(vk_command_buffer, !r->depth_clip)); + VK_CALL(vkCmdSetCullModeEXT(vk_command_buffer, vk_cull_mode_from_wined3d(r->cull_mode))); + VK_CALL(vkCmdSetFrontFaceEXT(vk_command_buffer, + r->front_ccw ? VK_FRONT_FACE_COUNTER_CLOCKWISE : VK_FRONT_FACE_CLOCKWISE)); + + scale_bias = r->scale_bias; + const_bias.f32 = r->depth_bias; + if (!scale_bias && !const_bias.f32) + { + VK_CALL(vkCmdSetDepthBiasEnableEXT(vk_command_buffer, VK_FALSE)); + return; + } + VK_CALL(vkCmdSetDepthBiasEnableEXT(vk_command_buffer, VK_TRUE)); + if (d3d_info->wined3d_creation_flags & WINED3D_LEGACY_DEPTH_BIAS) + { + const struct wined3d_rendertarget_view *dsv; + + if ((dsv = state->fb.depth_stencil)) + { + VK_CALL(vkCmdSetDepthBias(vk_command_buffer, -(float)const_bias.u32 / dsv->format->depth_bias_scale, + r->depth_bias_clamp, -(float)const_bias.u32)); + } + else + { + VK_CALL(vkCmdSetDepthBias(vk_command_buffer, 0.0f, r->depth_bias_clamp, 0.0f)); + } + } + else + { + VK_CALL(vkCmdSetDepthBias(vk_command_buffer, const_bias.f32, r->depth_bias_clamp, scale_bias)); + } +} + static void wined3d_context_vk_update_blend_state(const struct wined3d_context_vk *context_vk, const struct wined3d_state *state, struct wined3d_graphics_pipeline_key_vk *key) { @@ -2603,8 +2671,8 @@ 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_RASTERIZER) - || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_SHADER(WINED3D_SHADER_TYPE_GEOMETRY))) + if (!vk_info->dynamic_rasterizer_state && (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)))) { wined3d_context_vk_update_rasterisation_state(context_vk, state, key);
@@ -3976,6 +4044,10 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c context_vk->c.update_multisample_state = 0; }
+ if (vk_info->dynamic_rasterizer_state && (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)))) + wined3d_context_vk_set_dynamic_rasterizer_state(context_vk, vk_command_buffer, vk_info, state); + if (vk_info->dynamic_blend_state && (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_BLEND) || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_FRAMEBUFFER))) wined3d_context_vk_set_dynamic_blend_state(context_vk, vk_command_buffer, vk_info, state); diff --git a/dlls/wined3d/wined3d_vk.h b/dlls/wined3d/wined3d_vk.h index 549245eb81f..94a6b6c0c5e 100644 --- a/dlls/wined3d/wined3d_vk.h +++ b/dlls/wined3d/wined3d_vk.h @@ -194,7 +194,12 @@ struct wined3d_device_vk; VK_DEVICE_EXT_PFN(vkCmdSetColorBlendEnableEXT) \ VK_DEVICE_EXT_PFN(vkCmdSetColorBlendEquationEXT) \ VK_DEVICE_EXT_PFN(vkCmdSetColorWriteMaskEXT) \ + VK_DEVICE_EXT_PFN(vkCmdSetCullModeEXT) \ + VK_DEVICE_EXT_PFN(vkCmdSetDepthBiasEnableEXT) \ + VK_DEVICE_EXT_PFN(vkCmdSetDepthClampEnableEXT) \ + VK_DEVICE_EXT_PFN(vkCmdSetFrontFaceEXT) \ VK_DEVICE_EXT_PFN(vkCmdSetRasterizationSamplesEXT) \ + VK_DEVICE_EXT_PFN(vkCmdSetRasterizerDiscardEnableEXT) \ VK_DEVICE_EXT_PFN(vkCmdSetSampleMaskEXT) \ /* VK_EXT_transform_feedback */ \ VK_DEVICE_EXT_PFN(vkCmdBeginQueryIndexedEXT) \ @@ -258,6 +263,7 @@ struct wined3d_vk_info bool dynamic_patch_vertex_count; bool dynamic_multisample_state; bool dynamic_blend_state; + bool dynamic_rasterizer_state; };
#define VK_CALL(f) (vk_info->vk_ops.f) @@ -580,7 +586,7 @@ struct wined3d_context_vk
const struct wined3d_vk_info *vk_info;
- VkDynamicState dynamic_states[20]; + VkDynamicState dynamic_states[27];
uint32_t update_compute_pipeline : 1; uint32_t update_stream_output : 1;
Jan Sikorski (@jsikorski) commented about dlls/wined3d/cs.c:
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);
} state->blend_factor = op->factor;device_invalidate_state(device, STATE_BLEND);
- 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_patch_vertex_count = 1;
Should this set `update_multisample_state`?
+static void wined3d_context_vk_set_dynamic_blend_state(const struct wined3d_context_vk *context_vk, + VkCommandBuffer vk_command_buffer, const struct wined3d_vk_info *vk_info, const struct wined3d_state *state)
Would it make sense to reuse (part of) wined3d_context_vk_update_blend_state() here? Perhaps using some helper functions for state translation? Likewise for wined3d_context_vk_set_dynamic_rasterizer_state().
On Tue Apr 9 09:04:57 2024 +0000, Jan Sikorski wrote:
Should this set `update_multisample_state`?
Oops :-(
Would it make sense to reuse (part of) wined3d_context_vk_update_blend_state() here? Perhaps using some helper functions for state translation? Likewise for wined3d_context_vk_set_dynamic_rasterizer_state().
Possibly, though it'd result in at least redundant copies from VkPipelineColorBlendStateCreateInfo to VkColorBlendEquationEXT.
Would it make sense to reuse (part of) wined3d_context_vk_update_blend_state() here? Perhaps using some helper functions for state translation? Likewise for wined3d_context_vk_set_dynamic_rasterizer_state().
Possibly, though it'd result in at least redundant copies from VkPipelineColorBlendStateCreateInfo to VkColorBlendEquationEXT.
It's not necessarily pretty, but note that in principle something like this would work if we cared to avoid that particular issue: ```c VkPipelineColorBlendAttachmentState *a = ...; VkColorBlendEquationEXT *b;
b = (VkColorBlendEquationEXT *)&a->srcColorBlendFactor; vk_blend_equation_from_wined3d(b, ...); ```
Oh hrm, those structures are byte compatible. I'll try that approach, then.