v3dv: StencilOp and StencilTestEnable are now dynamic
This commit introduces a significant change when we emit STENCIL_CFG, with any dynamic state: we stop to use cl_emit_with_prepacked, and use directly cl_emit. The reason is that now most of the STENCIL_CFG parameters are dynamic, any improvement of using cl_emit_with_prepacked is minimized. Also gets the code simpler, and avoid the need to be extra careful with the fact that cl_emit_with_prepaked doesn't override values. 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
2526f74ade
commit
60e9237e81
@@ -3006,6 +3006,7 @@ v3dv_cmd_buffer_emit_pre_draw(struct v3dv_cmd_buffer *cmd_buffer,
|
||||
if (*dirty & (V3DV_CMD_DIRTY_PIPELINE) ||
|
||||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_CULL_MODE) ||
|
||||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_FRONT_FACE) ||
|
||||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE) ||
|
||||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_ENABLE)) {
|
||||
v3dv_X(device, cmd_buffer_emit_configuration_bits)(cmd_buffer);
|
||||
}
|
||||
@@ -3028,7 +3029,8 @@ v3dv_cmd_buffer_emit_pre_draw(struct v3dv_cmd_buffer *cmd_buffer,
|
||||
bool any_dynamic_stencil_dirty =
|
||||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK) ||
|
||||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK) ||
|
||||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE);
|
||||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE) ||
|
||||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_OP);
|
||||
|
||||
if (*dirty & V3DV_CMD_DIRTY_PIPELINE || any_dynamic_stencil_dirty)
|
||||
v3dv_X(device, cmd_buffer_emit_stencil)(cmd_buffer);
|
||||
|
||||
@@ -1442,29 +1442,40 @@ v3dX(cmd_buffer_emit_stencil)(struct v3dv_cmd_buffer *cmd_buffer)
|
||||
bool any_dynamic_stencil_state =
|
||||
BITSET_TEST(dyn->set, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK) ||
|
||||
BITSET_TEST(dyn->set, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK) ||
|
||||
BITSET_TEST(dyn->set, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE);
|
||||
BITSET_TEST(dyn->set, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE) ||
|
||||
BITSET_TEST(dyn->set, MESA_VK_DYNAMIC_DS_STENCIL_OP);
|
||||
|
||||
bool emitted_stencil = false;
|
||||
const struct vk_stencil_test_face_state *front = &dyn->ds.stencil.front;
|
||||
const struct vk_stencil_test_face_state *back = &dyn->ds.stencil.back;
|
||||
|
||||
for (uint32_t i = 0; i < 2; i++) {
|
||||
const bool needs_front_and_back = any_dynamic_stencil_state ?
|
||||
memcmp(front, back, sizeof(*front)) != 0 :
|
||||
pipeline->emit_stencil_cfg[1] == true;
|
||||
const unsigned stencil_packets = needs_front_and_back ? 2 : 1;
|
||||
|
||||
for (uint32_t i = 0; i < stencil_packets; i++) {
|
||||
if (pipeline->emit_stencil_cfg[i]) {
|
||||
if (any_dynamic_stencil_state) {
|
||||
cl_emit_with_prepacked(&job->bcl, STENCIL_CFG,
|
||||
pipeline->stencil_cfg[i], config) {
|
||||
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK)) {
|
||||
config.stencil_test_mask =
|
||||
i == 0 ? front->compare_mask : back->compare_mask;
|
||||
}
|
||||
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK)) {
|
||||
config.stencil_write_mask =
|
||||
i == 0 ? front->write_mask : back->write_mask;
|
||||
}
|
||||
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE)) {
|
||||
config.stencil_ref_value =
|
||||
i == 0 ? front->reference : back->reference;
|
||||
}
|
||||
const struct vk_stencil_test_face_state *stencil_state =
|
||||
i == 0 ? front : back;
|
||||
|
||||
/* If we have any dynamic stencil state we just emit the entire
|
||||
* packet since for simplicity
|
||||
*/
|
||||
cl_emit(&job->bcl, STENCIL_CFG, config) {
|
||||
config.front_config = !needs_front_and_back || i == 0;
|
||||
config.back_config = !needs_front_and_back || i == 1;
|
||||
config.stencil_test_mask = stencil_state->compare_mask & 0xff;
|
||||
config.stencil_write_mask = stencil_state->write_mask & 0xff;
|
||||
config.stencil_ref_value = stencil_state->reference & 0xff;
|
||||
config.stencil_test_function = stencil_state->op.compare;
|
||||
config.stencil_pass_op =
|
||||
v3dX(translate_stencil_op)(stencil_state->op.pass);
|
||||
config.depth_test_fail_op =
|
||||
v3dX(translate_stencil_op)(stencil_state->op.depth_fail);
|
||||
config.stencil_test_fail_op =
|
||||
v3dX(translate_stencil_op)(stencil_state->op.fail);
|
||||
}
|
||||
} else {
|
||||
cl_emit_prepacked(&job->bcl, &pipeline->stencil_cfg[i]);
|
||||
@@ -1476,6 +1487,7 @@ v3dX(cmd_buffer_emit_stencil)(struct v3dv_cmd_buffer *cmd_buffer)
|
||||
BITSET_CLEAR(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK);
|
||||
BITSET_CLEAR(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE);
|
||||
BITSET_CLEAR(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK);
|
||||
BITSET_CLEAR(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_OP);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1970,8 +1982,11 @@ v3dX(cmd_buffer_emit_configuration_bits)(struct v3dv_cmd_buffer *cmd_buffer)
|
||||
struct vk_dynamic_graphics_state *dyn =
|
||||
&cmd_buffer->vk.dynamic_graphics_state;
|
||||
|
||||
/* Disable depth/stencil if we don't have a D/S attachment */
|
||||
bool has_depth =
|
||||
pipeline->rendering_info.depth_attachment_format != VK_FORMAT_UNDEFINED;
|
||||
bool has_stencil =
|
||||
pipeline->rendering_info.stencil_attachment_format != VK_FORMAT_UNDEFINED;
|
||||
|
||||
cl_emit_with_prepacked(&job->bcl, CFG_BITS, pipeline->cfg_bits, config) {
|
||||
if (dyn->ds.depth.test_enable && has_depth) {
|
||||
@@ -1981,6 +1996,8 @@ v3dX(cmd_buffer_emit_configuration_bits)(struct v3dv_cmd_buffer *cmd_buffer)
|
||||
config.depth_test_function = VK_COMPARE_OP_ALWAYS;
|
||||
}
|
||||
|
||||
config.stencil_enable = dyn->ds.stencil.test_enable && has_stencil;
|
||||
|
||||
cmd_buffer->state.z_updates_enable = config.z_updates_enable;
|
||||
#if V3D_VERSION == 42
|
||||
bool enable_ez = cmd_buffer_update_ez_state(cmd_buffer, pipeline);
|
||||
@@ -2012,6 +2029,7 @@ v3dX(cmd_buffer_emit_configuration_bits)(struct v3dv_cmd_buffer *cmd_buffer)
|
||||
BITSET_CLEAR(dyn->dirty, MESA_VK_DYNAMIC_RS_CULL_MODE);
|
||||
BITSET_CLEAR(dyn->dirty, MESA_VK_DYNAMIC_RS_FRONT_FACE);
|
||||
BITSET_CLEAR(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_ENABLE);
|
||||
BITSET_CLEAR(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -199,13 +199,6 @@ pack_cfg_bits(struct v3dv_pipeline *pipeline,
|
||||
|
||||
config.blend_enable = pipeline->blend.enables != 0;
|
||||
|
||||
/* Disable depth/stencil if we don't have a D/S attachment */
|
||||
const struct vk_render_pass_state *ri = &pipeline->rendering_info;
|
||||
bool has_stencil = ri->stencil_attachment_format != VK_FORMAT_UNDEFINED;
|
||||
|
||||
config.stencil_enable =
|
||||
ds_info ? ds_info->stencilTestEnable && has_stencil: false;
|
||||
|
||||
#if V3D_VERSION >= 71
|
||||
/* From the Vulkan spec:
|
||||
*
|
||||
@@ -240,8 +233,8 @@ pack_cfg_bits(struct v3dv_pipeline *pipeline,
|
||||
};
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
translate_stencil_op(VkStencilOp op)
|
||||
uint32_t
|
||||
v3dX(translate_stencil_op)(VkStencilOp op)
|
||||
{
|
||||
switch (op) {
|
||||
case VK_STENCIL_OP_KEEP:
|
||||
@@ -283,33 +276,20 @@ pack_single_stencil_cfg(struct v3dv_pipeline *pipeline,
|
||||
*
|
||||
* In our case, 's' is always 8, so we clamp to that to prevent our packing
|
||||
* functions to assert in debug mode if they see larger values.
|
||||
*
|
||||
* If we have dynamic state we need to make sure we set the corresponding
|
||||
* state bits to 0, since cl_emit_with_prepacked ORs the new value with
|
||||
* the old.
|
||||
*/
|
||||
const uint8_t write_mask =
|
||||
BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK) ?
|
||||
0 : stencil_state->writeMask & 0xff;
|
||||
|
||||
const uint8_t compare_mask =
|
||||
BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK) ?
|
||||
0 : stencil_state->compareMask & 0xff;
|
||||
|
||||
const uint8_t reference =
|
||||
BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE) ?
|
||||
0 : stencil_state->reference & 0xff;
|
||||
|
||||
v3dvx_pack(stencil_cfg, STENCIL_CFG, config) {
|
||||
config.front_config = is_front;
|
||||
config.back_config = is_back;
|
||||
config.stencil_write_mask = write_mask;
|
||||
config.stencil_test_mask = compare_mask;
|
||||
config.stencil_write_mask = stencil_state->writeMask & 0xff;
|
||||
config.stencil_test_mask = stencil_state->compareMask & 0xff;
|
||||
config.stencil_test_function = stencil_state->compareOp;
|
||||
config.stencil_pass_op = translate_stencil_op(stencil_state->passOp);
|
||||
config.depth_test_fail_op = translate_stencil_op(stencil_state->depthFailOp);
|
||||
config.stencil_test_fail_op = translate_stencil_op(stencil_state->failOp);
|
||||
config.stencil_ref_value = reference;
|
||||
config.stencil_pass_op =
|
||||
v3dX(translate_stencil_op)(stencil_state->passOp);
|
||||
config.depth_test_fail_op =
|
||||
v3dX(translate_stencil_op)(stencil_state->depthFailOp);
|
||||
config.stencil_test_fail_op =
|
||||
v3dX(translate_stencil_op)(stencil_state->failOp);
|
||||
config.stencil_ref_value = stencil_state->reference & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,8 +300,10 @@ pack_stencil_cfg(struct v3dv_pipeline *pipeline,
|
||||
{
|
||||
assert(sizeof(pipeline->stencil_cfg) == 2 * cl_packet_length(STENCIL_CFG));
|
||||
|
||||
if (!ds_info || !ds_info->stencilTestEnable)
|
||||
if ((!ds_info || !ds_info->stencilTestEnable) &&
|
||||
(!BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE))) {
|
||||
return;
|
||||
}
|
||||
|
||||
const struct vk_render_pass_state *ri = &pipeline->rendering_info;
|
||||
if (ri->stencil_attachment_format == VK_FORMAT_UNDEFINED)
|
||||
@@ -330,7 +312,9 @@ pack_stencil_cfg(struct v3dv_pipeline *pipeline,
|
||||
const bool any_dynamic_stencil_states =
|
||||
BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK) ||
|
||||
BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK) ||
|
||||
BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE);
|
||||
BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE) ||
|
||||
BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE) ||
|
||||
BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_OP);
|
||||
|
||||
/* If front != back or we have dynamic stencil state we can't emit a single
|
||||
* packet for both faces.
|
||||
|
||||
@@ -368,3 +368,6 @@ void
|
||||
v3dX(viewport_compute_xform)(const VkViewport *viewport,
|
||||
float scale[3],
|
||||
float translate[3]);
|
||||
|
||||
uint32_t
|
||||
v3dX(translate_stencil_op)(VkStencilOp op);
|
||||
|
||||
Reference in New Issue
Block a user