diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 050808ea7e7..91a026b2f87 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -545,6 +545,29 @@ radv_cmd_set_stencil_test_enable(struct radv_cmd_buffer *cmd_buffer, bool stenci state->dirty_dynamic |= RADV_DYNAMIC_STENCIL_TEST_ENABLE; } +ALWAYS_INLINE static void +radv_cmd_set_stencil_op(struct radv_cmd_buffer *cmd_buffer, VkStencilFaceFlags face_mask, VkStencilOp fail_op, + VkStencilOp pass_op, VkStencilOp depth_fail_op, VkCompareOp compare_op) +{ + struct radv_cmd_state *state = &cmd_buffer->state; + + if (face_mask & VK_STENCIL_FACE_FRONT_BIT) { + state->dynamic.vk.ds.stencil.front.op.fail = fail_op; + state->dynamic.vk.ds.stencil.front.op.pass = pass_op; + state->dynamic.vk.ds.stencil.front.op.depth_fail = depth_fail_op; + state->dynamic.vk.ds.stencil.front.op.compare = compare_op; + } + + if (face_mask & VK_STENCIL_FACE_BACK_BIT) { + state->dynamic.vk.ds.stencil.back.op.fail = fail_op; + state->dynamic.vk.ds.stencil.back.op.pass = pass_op; + state->dynamic.vk.ds.stencil.back.op.depth_fail = depth_fail_op; + state->dynamic.vk.ds.stencil.back.op.compare = compare_op; + } + + state->dirty_dynamic |= RADV_DYNAMIC_STENCIL_OP; +} + static void radv_bind_dynamic_state(struct radv_cmd_buffer *cmd_buffer, const struct radv_dynamic_state *src) { @@ -648,14 +671,6 @@ radv_bind_dynamic_state(struct radv_cmd_buffer *cmd_buffer, const struct radv_dy dest_mask |= RADV_DYNAMIC_INPUT_ATTACHMENT_MAP; } -#define RADV_CMP_COPY(field, flag) \ - if (copy_mask & flag) { \ - if (dest->field != src->field) { \ - dest->field = src->field; \ - dest_mask |= flag; \ - } \ - } - if (copy_mask & RADV_DYNAMIC_PRIMITIVE_TOPOLOGY) { if (dest->vk.ia.primitive_topology != src->vk.ia.primitive_topology) { radv_cmd_set_primitive_topology(cmd_buffer, src->vk.ia.primitive_topology); @@ -886,14 +901,24 @@ radv_bind_dynamic_state(struct radv_cmd_buffer *cmd_buffer, const struct radv_dy } } - RADV_CMP_COPY(vk.ds.stencil.front.op.fail, RADV_DYNAMIC_STENCIL_OP); - RADV_CMP_COPY(vk.ds.stencil.front.op.pass, RADV_DYNAMIC_STENCIL_OP); - RADV_CMP_COPY(vk.ds.stencil.front.op.depth_fail, RADV_DYNAMIC_STENCIL_OP); - RADV_CMP_COPY(vk.ds.stencil.front.op.compare, RADV_DYNAMIC_STENCIL_OP); - RADV_CMP_COPY(vk.ds.stencil.back.op.fail, RADV_DYNAMIC_STENCIL_OP); - RADV_CMP_COPY(vk.ds.stencil.back.op.pass, RADV_DYNAMIC_STENCIL_OP); - RADV_CMP_COPY(vk.ds.stencil.back.op.depth_fail, RADV_DYNAMIC_STENCIL_OP); - RADV_CMP_COPY(vk.ds.stencil.back.op.compare, RADV_DYNAMIC_STENCIL_OP); + if (copy_mask & RADV_DYNAMIC_STENCIL_OP) { + if (dest->vk.ds.stencil.front.op.fail != src->vk.ds.stencil.front.op.fail || + dest->vk.ds.stencil.front.op.pass != src->vk.ds.stencil.front.op.pass || + dest->vk.ds.stencil.front.op.depth_fail != src->vk.ds.stencil.front.op.depth_fail || + dest->vk.ds.stencil.front.op.compare != src->vk.ds.stencil.front.op.compare) { + radv_cmd_set_stencil_op(cmd_buffer, VK_STENCIL_FACE_FRONT_BIT, src->vk.ds.stencil.front.op.fail, + src->vk.ds.stencil.front.op.pass, src->vk.ds.stencil.front.op.depth_fail, + src->vk.ds.stencil.front.op.compare); + } + if (dest->vk.ds.stencil.back.op.fail != src->vk.ds.stencil.back.op.fail || + dest->vk.ds.stencil.back.op.pass != src->vk.ds.stencil.back.op.pass || + dest->vk.ds.stencil.back.op.depth_fail != src->vk.ds.stencil.back.op.depth_fail || + dest->vk.ds.stencil.back.op.compare != src->vk.ds.stencil.back.op.compare) { + radv_cmd_set_stencil_op(cmd_buffer, VK_STENCIL_FACE_BACK_BIT, src->vk.ds.stencil.back.op.fail, + src->vk.ds.stencil.back.op.pass, src->vk.ds.stencil.back.op.depth_fail, + src->vk.ds.stencil.back.op.compare); + } + } if (copy_mask & RADV_DYNAMIC_LOGIC_OP) { if (dest->vk.cb.logic_op != src->vk.cb.logic_op) { @@ -946,8 +971,6 @@ radv_bind_dynamic_state(struct radv_cmd_buffer *cmd_buffer, const struct radv_dy } } -#undef RADV_CMP_COPY - cmd_buffer->state.dirty_dynamic |= dest_mask; /* Handle driver specific states that need to be re-emitted when PSO are bound. */ @@ -8728,23 +8751,7 @@ radv_CmdSetStencilOp(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, VkStencilOp depthFailOp, VkCompareOp compareOp) { VK_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); - struct radv_cmd_state *state = &cmd_buffer->state; - - if (faceMask & VK_STENCIL_FACE_FRONT_BIT) { - state->dynamic.vk.ds.stencil.front.op.fail = failOp; - state->dynamic.vk.ds.stencil.front.op.pass = passOp; - state->dynamic.vk.ds.stencil.front.op.depth_fail = depthFailOp; - state->dynamic.vk.ds.stencil.front.op.compare = compareOp; - } - - if (faceMask & VK_STENCIL_FACE_BACK_BIT) { - state->dynamic.vk.ds.stencil.back.op.fail = failOp; - state->dynamic.vk.ds.stencil.back.op.pass = passOp; - state->dynamic.vk.ds.stencil.back.op.depth_fail = depthFailOp; - state->dynamic.vk.ds.stencil.back.op.compare = compareOp; - } - - state->dirty_dynamic |= RADV_DYNAMIC_STENCIL_OP; + radv_cmd_set_stencil_op(cmd_buffer, faceMask, failOp, passOp, depthFailOp, compareOp); } VKAPI_ATTR void VKAPI_CALL