-- v2: wined3d: Use dynamic state for rasterizer state if possible. wined3d: Use dynamic state for blend state if possible. wined3d: Use dynamic state for multisample state if possible.
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..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;
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/wined3d/adapter_vk.c | 3 + dlls/wined3d/context_vk.c | 118 ++++++++++++++++++++++++++++---------- dlls/wined3d/wined3d_vk.h | 6 +- 3 files changed, 97 insertions(+), 30 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..c91be5e82ed 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)); @@ -2284,6 +2291,40 @@ static void wined3d_context_vk_update_rasterisation_state(const struct wined3d_c desc->depthBiasClamp = r->depth_bias_clamp; }
+static void blend_equation_from_wined3d(const struct wined3d_context_vk *context_vk, VkColorBlendEquationEXT *eq, + const struct wined3d_rendertarget_blend_state_desc *rt, const struct wined3d_rendertarget_view *rtv) +{ + enum wined3d_blend src_blend, dst_blend; + const struct wined3d_format *rt_format; + + 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); +} + 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) { @@ -2311,43 +2352,57 @@ static void wined3d_context_vk_update_blend_state(const struct wined3d_context_v for (i = 0; i < context_vk->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]; VkPipelineColorBlendAttachmentState *a = &key->blend_attachments[i]; - enum wined3d_blend src_blend, dst_blend; - const struct wined3d_format *rt_format;
a->colorWriteMask = vk_colour_write_mask_from_wined3d(rt->writemask); if (!rt->enable) continue;
- if (rtv) - rt_format = rtv->format; - else - rt_format = wined3d_get_format(context_vk->c.device->adapter, WINED3DFMT_NULL, 0); a->blendEnable = VK_TRUE;
- 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; - } - a->srcColorBlendFactor = vk_blend_factor_from_wined3d(src_blend, rt_format, FALSE); - a->dstColorBlendFactor = vk_blend_factor_from_wined3d(dst_blend, rt_format, FALSE); - a->colorBlendOp = vk_blend_op_from_wined3d(rt->op); + blend_equation_from_wined3d(context_vk, + (VkColorBlendEquationEXT *)&a->srcColorBlendFactor, rt, state->fb.render_targets[i]); + } +}
- src_blend = rt->src_alpha; - dst_blend = rt->dst_alpha; - a->srcAlphaBlendFactor = vk_blend_factor_from_wined3d(src_blend, rt_format, TRUE); - a->dstAlphaBlendFactor = vk_blend_factor_from_wined3d(dst_blend, rt_format, TRUE); - a->alphaBlendOp = vk_blend_op_from_wined3d(rt->op_alpha); +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]; + + write_mask[i] = vk_colour_write_mask_from_wined3d(rt->writemask); + enable[i] = rt->enable; + + if (!rt->enable) + continue; + + blend_equation_from_wined3d(context_vk, &equations[i], rt, state->fb.render_targets[i]); + } + + 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) @@ -2591,8 +2646,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 +3955,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 | 44 ++++++++++++++++++++++++++++++++------- dlls/wined3d/wined3d_vk.h | 8 ++++++- 3 files changed, 48 insertions(+), 8 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 c91be5e82ed..dc793a839bb 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)); @@ -2222,11 +2232,9 @@ static void wined3d_context_vk_init_graphics_pipeline_key(struct wined3d_context key->pipeline_desc.basePipelineIndex = -1; }
-static void wined3d_context_vk_update_rasterisation_state(const struct wined3d_context_vk *context_vk, - const struct wined3d_state *state, struct wined3d_graphics_pipeline_key_vk *key) +static void rasterizer_state_from_wined3d(VkPipelineRasterizationStateCreateInfo *desc, + const struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info) { - const struct wined3d_d3d_info *d3d_info = context_vk->c.d3d_info; - VkPipelineRasterizationStateCreateInfo *desc = &key->rs_desc; const struct wined3d_rasterizer_state_desc *r; float scale_bias; union @@ -2291,6 +2299,24 @@ 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) +{ + VkPipelineRasterizationStateCreateInfo desc; + + rasterizer_state_from_wined3d(&desc, state, context_vk->c.d3d_info); + + VK_CALL(vkCmdSetRasterizerDiscardEnableEXT(vk_command_buffer, desc.rasterizerDiscardEnable)); + VK_CALL(vkCmdSetDepthClampEnableEXT(vk_command_buffer, desc.depthClampEnable)); + VK_CALL(vkCmdSetCullModeEXT(vk_command_buffer, desc.cullMode)); + VK_CALL(vkCmdSetFrontFaceEXT(vk_command_buffer, desc.frontFace)); + VK_CALL(vkCmdSetDepthBiasEnableEXT(vk_command_buffer, desc.depthBiasEnable)); + + if (desc.depthBiasEnable) + VK_CALL(vkCmdSetDepthBias(vk_command_buffer, desc.depthBiasConstantFactor, + desc.depthBiasClamp, desc.depthBiasSlopeFactor)); +} + static void blend_equation_from_wined3d(const struct wined3d_context_vk *context_vk, VkColorBlendEquationEXT *eq, const struct wined3d_rendertarget_blend_state_desc *rt, const struct wined3d_rendertarget_view *rtv) { @@ -2582,10 +2608,10 @@ 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); + rasterizer_state_from_wined3d(&key->rs_desc, state, d3d_info);
update = true; } @@ -3955,6 +3981,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;
Oh hrm, those structures are byte compatible. I'll try that approach, then.
Works for me.
This merge request was approved by Jan Sikorski.