diff --git a/src/broadcom/vulkan/v3dv_pipeline.c b/src/broadcom/vulkan/v3dv_pipeline.c index ba46aae5974..44b6b259dff 100644 --- a/src/broadcom/vulkan/v3dv_pipeline.c +++ b/src/broadcom/vulkan/v3dv_pipeline.c @@ -2646,10 +2646,10 @@ compute_vpm_config(struct v3dv_pipeline *pipeline) } static bool -stencil_op_is_no_op(const VkStencilOpState *stencil) +stencil_op_is_no_op(struct vk_stencil_test_face_state *stencil) { - return stencil->depthFailOp == VK_STENCIL_OP_KEEP && - stencil->compareOp == VK_COMPARE_OP_ALWAYS; + return stencil->op.depth_fail == VK_STENCIL_OP_KEEP && + stencil->op.compare == VK_COMPARE_OP_ALWAYS; } static void @@ -2672,39 +2672,45 @@ enable_depth_bias(struct v3dv_pipeline *pipeline, pipeline->depth_bias.enabled = true; } -static void -pipeline_set_ez_state(struct v3dv_pipeline *pipeline, - const VkPipelineDepthStencilStateCreateInfo *ds_info) +/* Computes the ez_state based on a given vk_dynamic_graphics_state. Note + * that the parameter dyn doesn't need to be pipeline->dynamic_graphics_state, + * as this method can be used by the cmd_buffer too. + */ +void +v3dv_compute_ez_state(struct vk_dynamic_graphics_state *dyn, + struct v3dv_pipeline *pipeline, + enum v3dv_ez_state *ez_state, + bool *incompatible_ez_test) { - if (!ds_info || !ds_info->depthTestEnable) { - pipeline->ez_state = V3D_EZ_DISABLED; + if (!dyn->ds.depth.test_enable) { + *ez_state = V3D_EZ_DISABLED; return; } - switch (ds_info->depthCompareOp) { + switch (dyn->ds.depth.compare_op) { case VK_COMPARE_OP_LESS: case VK_COMPARE_OP_LESS_OR_EQUAL: - pipeline->ez_state = V3D_EZ_LT_LE; + *ez_state = V3D_EZ_LT_LE; break; case VK_COMPARE_OP_GREATER: case VK_COMPARE_OP_GREATER_OR_EQUAL: - pipeline->ez_state = V3D_EZ_GT_GE; + *ez_state = V3D_EZ_GT_GE; break; case VK_COMPARE_OP_NEVER: case VK_COMPARE_OP_EQUAL: - pipeline->ez_state = V3D_EZ_UNDECIDED; + *ez_state = V3D_EZ_UNDECIDED; break; default: - pipeline->ez_state = V3D_EZ_DISABLED; - pipeline->incompatible_ez_test = true; + *ez_state = V3D_EZ_DISABLED; + *incompatible_ez_test = true; break; } /* If stencil is enabled and is not a no-op, we need to disable EZ */ - if (ds_info->stencilTestEnable && - (!stencil_op_is_no_op(&ds_info->front) || - !stencil_op_is_no_op(&ds_info->back))) { - pipeline->ez_state = V3D_EZ_DISABLED; + if (dyn->ds.stencil.test_enable && + (!stencil_op_is_no_op(&dyn->ds.stencil.front) || + !stencil_op_is_no_op(&dyn->ds.stencil.back))) { + *ez_state = V3D_EZ_DISABLED; } /* If the FS writes Z, then it may update against the chosen EZ direction */ @@ -2712,10 +2718,11 @@ pipeline_set_ez_state(struct v3dv_pipeline *pipeline, pipeline->shared_data->variants[BROADCOM_SHADER_FRAGMENT]; if (fs_variant && fs_variant->prog_data.fs->writes_z && !fs_variant->prog_data.fs->writes_z_from_fep) { - pipeline->ez_state = V3D_EZ_DISABLED; + *ez_state = V3D_EZ_DISABLED; } } + static void pipeline_set_sample_mask(struct v3dv_pipeline *pipeline, const VkPipelineMultisampleStateCreateInfo *ms_info) @@ -3001,7 +3008,10 @@ pipeline_init(struct v3dv_pipeline *pipeline, } /* This must be done after the pipeline has been compiled */ - pipeline_set_ez_state(pipeline, ds_info); + v3dv_compute_ez_state(&pipeline->dynamic_graphics_state, + pipeline, + &pipeline->ez_state, + &pipeline->incompatible_ez_test); return result; } diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index c5813d67521..d54b1f3cff9 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -1606,6 +1606,17 @@ struct v3dv_cmd_buffer_state { /* This is dynamic state since VK_EXT_extended_dynamic_state. */ bool z_updates_enable; + + /* ez_state can be dynamic since VK_EXT_extended_dynamic_state so we need + * to keep track of it in the cmd_buffer state + */ + enum v3dv_ez_state ez_state; + + /* incompatible_ez_test can be dynamic since VK_EXT_extended_dynamic_state + * so we need to keep track of it in the cmd_buffer state + */ + bool incompatible_ez_test; + }; void @@ -2687,6 +2698,13 @@ float v3dv_get_aa_line_width(struct v3dv_pipeline *pipeline, struct v3dv_cmd_buffer *buffer); + +void +v3dv_compute_ez_state(struct vk_dynamic_graphics_state *dyn, + struct v3dv_pipeline *pipeline, + enum v3dv_ez_state *ez_state, + bool *incompatible_ez_test); + #if DETECT_OS_ANDROID VkResult v3dv_gralloc_to_drm_explicit_layout(struct u_gralloc *gralloc, diff --git a/src/broadcom/vulkan/v3dvx_cmd_buffer.c b/src/broadcom/vulkan/v3dvx_cmd_buffer.c index 7394b0b297b..4d3edaa8636 100644 --- a/src/broadcom/vulkan/v3dvx_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dvx_cmd_buffer.c @@ -1784,14 +1784,32 @@ v3dX(cmd_buffer_emit_varyings_state)(struct v3dv_cmd_buffer *cmd_buffer) } #if V3D_VERSION == 42 -/* Updates job early Z state tracking. Returns False if EZ must be disabled - * for the current draw call. +/* Updates cmd_buffer, and their job, early z state tracking. Returns false if + * EZ must be disabled for the current draw call. */ static bool -job_update_ez_state(struct v3dv_job *job, - struct v3dv_pipeline *pipeline, - struct v3dv_cmd_buffer *cmd_buffer) +cmd_buffer_update_ez_state(struct v3dv_cmd_buffer *cmd_buffer, + struct v3dv_pipeline *pipeline) { + struct vk_dynamic_graphics_state *dyn = &cmd_buffer->vk.dynamic_graphics_state; + /* Update first cmd_buffer ez_state tracking. If possible we reuse the + * values from the pipeline + */ + if (!BITSET_TEST(dyn->set, MESA_VK_DYNAMIC_DS_STENCIL_OP) && + !BITSET_TEST(dyn->set, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE) && + !BITSET_TEST(dyn->set, MESA_VK_DYNAMIC_DS_DEPTH_TEST_ENABLE) && + !BITSET_TEST(dyn->set, MESA_VK_DYNAMIC_DS_DEPTH_COMPARE_OP)) { + cmd_buffer->state.ez_state = pipeline->ez_state; + cmd_buffer->state.incompatible_ez_test = + pipeline->incompatible_ez_test; + } else { + v3dv_compute_ez_state(dyn, pipeline, + &cmd_buffer->state.ez_state, + &cmd_buffer->state.incompatible_ez_test); + } + + struct v3dv_job *job = cmd_buffer->state.job; + assert(job); /* If first_ez_state is V3D_EZ_DISABLED it means that we have already * determined that we should disable EZ completely for all draw calls in * this job. This will cause us to disable EZ for the entire job in the @@ -1818,7 +1836,7 @@ job_update_ez_state(struct v3dv_job *job, /* If this is the first time we update EZ state for this job we first check * if there is anything that requires disabling it completely for the entire * job (based on state that is not related to the current draw call and - * pipeline state). + * pipeline/cmd_buffer state). */ if (!job->decided_global_ez_enable) { job->decided_global_ez_enable = true; @@ -1884,11 +1902,12 @@ job_update_ez_state(struct v3dv_job *job, } /* Otherwise, we can decide to selectively enable or disable EZ for draw - * calls using the CFG_BITS packet based on the bound pipeline state. + * calls using the CFG_BITS packet based on the bound pipeline state, or + * cmd_buffer state if some stencil/depth flags were dynamic. */ bool disable_ez = false; bool incompatible_test = false; - switch (pipeline->ez_state) { + switch (cmd_buffer->state.ez_state) { case V3D_EZ_UNDECIDED: /* If the pipeline didn't pick a direction but didn't disable, then go * along with the current EZ state. This allows EZ optimization for Z @@ -1902,7 +1921,7 @@ job_update_ez_state(struct v3dv_job *job, * direction if we've decided on one. */ if (job->ez_state == V3D_EZ_UNDECIDED) { - job->ez_state = pipeline->ez_state; + job->ez_state = cmd_buffer->state.ez_state; } else if (job->ez_state != pipeline->ez_state) { disable_ez = true; incompatible_test = true; @@ -1911,7 +1930,7 @@ job_update_ez_state(struct v3dv_job *job, case V3D_EZ_DISABLED: disable_ez = true; - incompatible_test = pipeline->incompatible_ez_test; + incompatible_test = cmd_buffer->state.incompatible_ez_test; break; } @@ -1964,7 +1983,7 @@ v3dX(cmd_buffer_emit_configuration_bits)(struct v3dv_cmd_buffer *cmd_buffer) cmd_buffer->state.z_updates_enable = config.z_updates_enable; #if V3D_VERSION == 42 - bool enable_ez = job_update_ez_state(job, pipeline, cmd_buffer); + bool enable_ez = cmd_buffer_update_ez_state(cmd_buffer, pipeline); config.early_z_enable = enable_ez; config.early_z_updates_enable = config.early_z_enable && cmd_buffer->state.z_updates_enable;