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;