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;