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) ||
|
if (*dirty & (V3DV_CMD_DIRTY_PIPELINE) ||
|
||||||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_CULL_MODE) ||
|
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_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)) {
|
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_ENABLE)) {
|
||||||
v3dv_X(device, cmd_buffer_emit_configuration_bits)(cmd_buffer);
|
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 =
|
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_COMPARE_MASK) ||
|
||||||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_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)
|
if (*dirty & V3DV_CMD_DIRTY_PIPELINE || any_dynamic_stencil_dirty)
|
||||||
v3dv_X(device, cmd_buffer_emit_stencil)(cmd_buffer);
|
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 =
|
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_COMPARE_MASK) ||
|
||||||
BITSET_TEST(dyn->set, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_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;
|
bool emitted_stencil = false;
|
||||||
const struct vk_stencil_test_face_state *front = &dyn->ds.stencil.front;
|
const struct vk_stencil_test_face_state *front = &dyn->ds.stencil.front;
|
||||||
const struct vk_stencil_test_face_state *back = &dyn->ds.stencil.back;
|
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 (pipeline->emit_stencil_cfg[i]) {
|
||||||
if (any_dynamic_stencil_state) {
|
if (any_dynamic_stencil_state) {
|
||||||
cl_emit_with_prepacked(&job->bcl, STENCIL_CFG,
|
const struct vk_stencil_test_face_state *stencil_state =
|
||||||
pipeline->stencil_cfg[i], config) {
|
i == 0 ? front : back;
|
||||||
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK)) {
|
|
||||||
config.stencil_test_mask =
|
/* If we have any dynamic stencil state we just emit the entire
|
||||||
i == 0 ? front->compare_mask : back->compare_mask;
|
* packet since for simplicity
|
||||||
}
|
*/
|
||||||
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK)) {
|
cl_emit(&job->bcl, STENCIL_CFG, config) {
|
||||||
config.stencil_write_mask =
|
config.front_config = !needs_front_and_back || i == 0;
|
||||||
i == 0 ? front->write_mask : back->write_mask;
|
config.back_config = !needs_front_and_back || i == 1;
|
||||||
}
|
config.stencil_test_mask = stencil_state->compare_mask & 0xff;
|
||||||
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE)) {
|
config.stencil_write_mask = stencil_state->write_mask & 0xff;
|
||||||
config.stencil_ref_value =
|
config.stencil_ref_value = stencil_state->reference & 0xff;
|
||||||
i == 0 ? front->reference : back->reference;
|
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 {
|
} else {
|
||||||
cl_emit_prepacked(&job->bcl, &pipeline->stencil_cfg[i]);
|
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_COMPARE_MASK);
|
||||||
BITSET_CLEAR(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE);
|
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_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 =
|
struct vk_dynamic_graphics_state *dyn =
|
||||||
&cmd_buffer->vk.dynamic_graphics_state;
|
&cmd_buffer->vk.dynamic_graphics_state;
|
||||||
|
|
||||||
|
/* Disable depth/stencil if we don't have a D/S attachment */
|
||||||
bool has_depth =
|
bool has_depth =
|
||||||
pipeline->rendering_info.depth_attachment_format != VK_FORMAT_UNDEFINED;
|
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) {
|
cl_emit_with_prepacked(&job->bcl, CFG_BITS, pipeline->cfg_bits, config) {
|
||||||
if (dyn->ds.depth.test_enable && has_depth) {
|
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.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;
|
cmd_buffer->state.z_updates_enable = config.z_updates_enable;
|
||||||
#if V3D_VERSION == 42
|
#if V3D_VERSION == 42
|
||||||
bool enable_ez = cmd_buffer_update_ez_state(cmd_buffer, pipeline);
|
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_CULL_MODE);
|
||||||
BITSET_CLEAR(dyn->dirty, MESA_VK_DYNAMIC_RS_FRONT_FACE);
|
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_DEPTH_BOUNDS_TEST_ENABLE);
|
||||||
|
BITSET_CLEAR(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -199,13 +199,6 @@ pack_cfg_bits(struct v3dv_pipeline *pipeline,
|
|||||||
|
|
||||||
config.blend_enable = pipeline->blend.enables != 0;
|
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
|
#if V3D_VERSION >= 71
|
||||||
/* From the Vulkan spec:
|
/* From the Vulkan spec:
|
||||||
*
|
*
|
||||||
@@ -240,8 +233,8 @@ pack_cfg_bits(struct v3dv_pipeline *pipeline,
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
uint32_t
|
||||||
translate_stencil_op(VkStencilOp op)
|
v3dX(translate_stencil_op)(VkStencilOp op)
|
||||||
{
|
{
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case VK_STENCIL_OP_KEEP:
|
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
|
* 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.
|
* 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) {
|
v3dvx_pack(stencil_cfg, STENCIL_CFG, config) {
|
||||||
config.front_config = is_front;
|
config.front_config = is_front;
|
||||||
config.back_config = is_back;
|
config.back_config = is_back;
|
||||||
config.stencil_write_mask = write_mask;
|
config.stencil_write_mask = stencil_state->writeMask & 0xff;
|
||||||
config.stencil_test_mask = compare_mask;
|
config.stencil_test_mask = stencil_state->compareMask & 0xff;
|
||||||
config.stencil_test_function = stencil_state->compareOp;
|
config.stencil_test_function = stencil_state->compareOp;
|
||||||
config.stencil_pass_op = translate_stencil_op(stencil_state->passOp);
|
config.stencil_pass_op =
|
||||||
config.depth_test_fail_op = translate_stencil_op(stencil_state->depthFailOp);
|
v3dX(translate_stencil_op)(stencil_state->passOp);
|
||||||
config.stencil_test_fail_op = translate_stencil_op(stencil_state->failOp);
|
config.depth_test_fail_op =
|
||||||
config.stencil_ref_value = reference;
|
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));
|
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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const struct vk_render_pass_state *ri = &pipeline->rendering_info;
|
const struct vk_render_pass_state *ri = &pipeline->rendering_info;
|
||||||
if (ri->stencil_attachment_format == VK_FORMAT_UNDEFINED)
|
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 =
|
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_WRITE_MASK) ||
|
||||||
BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_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
|
/* If front != back or we have dynamic stencil state we can't emit a single
|
||||||
* packet for both faces.
|
* packet for both faces.
|
||||||
|
|||||||
@@ -368,3 +368,6 @@ void
|
|||||||
v3dX(viewport_compute_xform)(const VkViewport *viewport,
|
v3dX(viewport_compute_xform)(const VkViewport *viewport,
|
||||||
float scale[3],
|
float scale[3],
|
||||||
float translate[3]);
|
float translate[3]);
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
v3dX(translate_stencil_op)(VkStencilOp op);
|
||||||
|
|||||||
Reference in New Issue
Block a user