v3dv: ez_state/incompatible_ez_test could be recomputed at cmd_buffer
As the values depends on several values that can be dynamic too. Note that the current approach of this commit is keeping this info duplicated on the pipeline and the cmd_buffer. The alternative would be to just track it at the cmd_buffer, like we did recently with z_updates_enable, but getting the values for ez_state/incompatible_ez were more complex, so this commit still computes it when the pipeline is created, and uses it as default value. This is debatable though, and the alternative would be to just keep ez_state/incompatible_ez_state at the command buffer. Reviewed-by: Iago Toral Quiroga <itoral@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27609>
This commit is contained in:
committed by
Marge Bot
parent
b6e473cd58
commit
fbfb99cbc3
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user