panvk: Fully transition to vk_depth_stencil_state

Replace our ZS state by the vk_depth_stencil_state provided by the
vulkan runtime lib.

This was the last bit using panvk_dynamic_state_bits enum, so we kill it
here along with the parse_dynamic_state() function.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Mary Guillemard <mary.guillemard@collabora.com>
Acked-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28927>
This commit is contained in:
Boris Brezillon
2024-04-23 14:54:40 +02:00
committed by Marge Bot
parent a58171fb3c
commit a3e024a59e
4 changed files with 127 additions and 244 deletions

View File

@@ -72,14 +72,6 @@ struct panvk_cmd_event_op {
struct panvk_event *event;
};
enum panvk_dynamic_state_bits {
PANVK_DYNAMIC_DEPTH_BOUNDS = 1 << 5,
PANVK_DYNAMIC_STENCIL_COMPARE_MASK = 1 << 6,
PANVK_DYNAMIC_STENCIL_WRITE_MASK = 1 << 7,
PANVK_DYNAMIC_STENCIL_REFERENCE = 1 << 8,
PANVK_DYNAMIC_ALL = (1 << 9) - 1,
};
struct panvk_descriptor_state {
const struct panvk_descriptor_set *sets[MAX_SETS];
struct panvk_push_descriptor_set *push_sets[MAX_SETS];
@@ -133,14 +125,6 @@ struct panvk_cmd_graphics_state {
uint32_t first_vertex, base_vertex, base_instance;
} ib;
struct {
struct {
uint8_t compare_mask;
uint8_t write_mask;
uint8_t ref;
} s_front, s_back;
} zs;
struct {
struct pan_fb_info info;
bool crc_valid[MAX_RTS];

View File

@@ -77,8 +77,6 @@ struct panvk_graphics_pipeline {
struct panvk_varyings_info varyings;
struct {
uint32_t dynamic_mask;
struct {
struct panvk_attribs_info attribs;
bool writes_point_size;
@@ -93,22 +91,6 @@ struct panvk_graphics_pipeline {
struct mali_renderer_state_packed rsd_template;
} fs;
struct {
bool z_test;
bool z_write;
unsigned z_compare_func;
bool s_test;
struct {
unsigned fail_op;
unsigned pass_op;
unsigned z_fail_op;
unsigned compare_func;
uint8_t compare_mask;
uint8_t write_mask;
uint8_t ref;
} s_front, s_back;
} zs;
struct {
uint8_t rast_samples;
uint8_t min_samples;

View File

@@ -541,14 +541,18 @@ panvk_draw_prepare_fs_rsd(struct panvk_cmd_buffer *cmdbuf,
bool dirty = is_dirty(cmdbuf, RS_DEPTH_BIAS_FACTORS) ||
is_dirty(cmdbuf, CB_BLEND_CONSTANTS) ||
is_dirty(cmdbuf, DS_STENCIL_COMPARE_MASK) ||
is_dirty(cmdbuf, DS_STENCIL_WRITE_MASK) ||
is_dirty(cmdbuf, DS_STENCIL_REFERENCE) ||
!cmdbuf->state.gfx.fs_rsd;
if (dirty) {
const struct panvk_cmd_graphics_state *state = &cmdbuf->state.gfx;
const struct vk_rasterization_state *rs =
&cmdbuf->vk.dynamic_graphics_state.rs;
const struct vk_color_blend_state *cb =
&cmdbuf->vk.dynamic_graphics_state.cb;
const struct vk_depth_stencil_state *ds =
&cmdbuf->vk.dynamic_graphics_state.ds;
struct panfrost_ptr rsd = pan_pool_alloc_desc_aggregate(
&cmdbuf->desc_pool.base, PAN_DESC(RENDERER_STATE),
PAN_DESC_ARRAY(pipeline->state.blend.pstate.rt_count, BLEND));
@@ -562,25 +566,13 @@ panvk_draw_prepare_fs_rsd(struct panvk_cmd_buffer *cmdbuf,
cfg.depth_factor = rs->depth_bias.slope;
cfg.depth_bias_clamp = rs->depth_bias.clamp;
if (pipeline->state.dynamic_mask &
(1 << VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK)) {
cfg.stencil_front.mask = state->zs.s_front.compare_mask;
cfg.stencil_back.mask = state->zs.s_back.compare_mask;
}
if (pipeline->state.dynamic_mask &
(1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK)) {
cfg.stencil_mask_misc.stencil_mask_front =
state->zs.s_front.write_mask;
cfg.stencil_mask_misc.stencil_mask_back =
state->zs.s_back.write_mask;
}
if (pipeline->state.dynamic_mask &
(1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE)) {
cfg.stencil_front.reference_value = state->zs.s_front.ref;
cfg.stencil_back.reference_value = state->zs.s_back.ref;
}
cfg.stencil_front.mask = ds->stencil.front.compare_mask;
cfg.stencil_back.mask = ds->stencil.back.compare_mask;
cfg.stencil_mask_misc.stencil_mask_front =
ds->stencil.front.write_mask;
cfg.stencil_mask_misc.stencil_mask_back = ds->stencil.back.write_mask;
cfg.stencil_front.reference_value = ds->stencil.front.reference;
cfg.stencil_back.reference_value = ds->stencil.back.reference;
}
pan_merge(rsd_dyn, (*rsd_templ), RENDERER_STATE);
@@ -2199,64 +2191,6 @@ panvk_per_arch(CmdBindPipeline)(VkCommandBuffer commandBuffer,
}
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdSetDepthBounds)(VkCommandBuffer commandBuffer,
float minDepthBounds, float maxDepthBounds)
{
panvk_stub();
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdSetStencilCompareMask)(VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
uint32_t compareMask)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
cmdbuf->state.gfx.zs.s_front.compare_mask = compareMask;
if (faceMask & VK_STENCIL_FACE_BACK_BIT)
cmdbuf->state.gfx.zs.s_back.compare_mask = compareMask;
cmdbuf->state.gfx.dirty |= PANVK_DYNAMIC_STENCIL_COMPARE_MASK;
cmdbuf->state.gfx.fs_rsd = 0;
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdSetStencilWriteMask)(VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
uint32_t writeMask)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
cmdbuf->state.gfx.zs.s_front.write_mask = writeMask;
if (faceMask & VK_STENCIL_FACE_BACK_BIT)
cmdbuf->state.gfx.zs.s_back.write_mask = writeMask;
cmdbuf->state.gfx.dirty |= PANVK_DYNAMIC_STENCIL_WRITE_MASK;
cmdbuf->state.gfx.fs_rsd = 0;
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdSetStencilReference)(VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
uint32_t reference)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
cmdbuf->state.gfx.zs.s_front.ref = reference;
if (faceMask & VK_STENCIL_FACE_BACK_BIT)
cmdbuf->state.gfx.zs.s_back.ref = reference;
cmdbuf->state.gfx.dirty |= PANVK_DYNAMIC_STENCIL_REFERENCE;
cmdbuf->state.gfx.fs_rsd = 0;
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdDrawIndirect)(VkCommandBuffer commandBuffer, VkBuffer _buffer,
VkDeviceSize offset, uint32_t drawCount,

View File

@@ -141,12 +141,97 @@ emit_non_fs_rsd(const struct pan_shader_info *shader_info, mali_ptr shader_ptr,
}
}
static bool
writes_depth(const struct vk_depth_stencil_state *ds)
{
return ds && ds->depth.test_enable && ds->depth.write_enable &&
ds->depth.compare_op != VK_COMPARE_OP_NEVER;
}
static bool
writes_stencil(const struct vk_depth_stencil_state *ds)
{
return ds && ds->stencil.test_enable &&
((ds->stencil.front.write_mask &&
(ds->stencil.front.op.fail != VK_STENCIL_OP_KEEP ||
ds->stencil.front.op.pass != VK_STENCIL_OP_KEEP ||
ds->stencil.front.op.depth_fail != VK_STENCIL_OP_KEEP)) ||
(ds->stencil.back.write_mask &&
(ds->stencil.back.op.fail != VK_STENCIL_OP_KEEP ||
ds->stencil.back.op.pass != VK_STENCIL_OP_KEEP ||
ds->stencil.back.op.depth_fail != VK_STENCIL_OP_KEEP)));
}
static bool
ds_test_always_passes(const struct vk_depth_stencil_state *ds)
{
if (!ds)
return true;
if (ds->depth.test_enable && ds->depth.compare_op != VK_COMPARE_OP_ALWAYS)
return false;
if (ds->stencil.test_enable &&
(ds->stencil.front.op.compare != VK_COMPARE_OP_ALWAYS ||
ds->stencil.back.op.compare != VK_COMPARE_OP_ALWAYS))
return false;
return true;
}
static inline enum mali_func
translate_compare_func(VkCompareOp comp)
{
STATIC_ASSERT(VK_COMPARE_OP_NEVER == (VkCompareOp)MALI_FUNC_NEVER);
STATIC_ASSERT(VK_COMPARE_OP_LESS == (VkCompareOp)MALI_FUNC_LESS);
STATIC_ASSERT(VK_COMPARE_OP_EQUAL == (VkCompareOp)MALI_FUNC_EQUAL);
STATIC_ASSERT(VK_COMPARE_OP_LESS_OR_EQUAL == (VkCompareOp)MALI_FUNC_LEQUAL);
STATIC_ASSERT(VK_COMPARE_OP_GREATER == (VkCompareOp)MALI_FUNC_GREATER);
STATIC_ASSERT(VK_COMPARE_OP_NOT_EQUAL == (VkCompareOp)MALI_FUNC_NOT_EQUAL);
STATIC_ASSERT(VK_COMPARE_OP_GREATER_OR_EQUAL ==
(VkCompareOp)MALI_FUNC_GEQUAL);
STATIC_ASSERT(VK_COMPARE_OP_ALWAYS == (VkCompareOp)MALI_FUNC_ALWAYS);
return (enum mali_func)comp;
}
static enum mali_stencil_op
translate_stencil_op(VkStencilOp in)
{
switch (in) {
case VK_STENCIL_OP_KEEP:
return MALI_STENCIL_OP_KEEP;
case VK_STENCIL_OP_ZERO:
return MALI_STENCIL_OP_ZERO;
case VK_STENCIL_OP_REPLACE:
return MALI_STENCIL_OP_REPLACE;
case VK_STENCIL_OP_INCREMENT_AND_CLAMP:
return MALI_STENCIL_OP_INCR_SAT;
case VK_STENCIL_OP_DECREMENT_AND_CLAMP:
return MALI_STENCIL_OP_DECR_SAT;
case VK_STENCIL_OP_INCREMENT_AND_WRAP:
return MALI_STENCIL_OP_INCR_WRAP;
case VK_STENCIL_OP_DECREMENT_AND_WRAP:
return MALI_STENCIL_OP_DECR_WRAP;
case VK_STENCIL_OP_INVERT:
return MALI_STENCIL_OP_INVERT;
default:
unreachable("Invalid stencil op");
}
}
static void
emit_base_fs_rsd(const struct panvk_graphics_pipeline *pipeline,
const struct vk_graphics_pipeline_state *state, void *rsd)
{
const struct pan_shader_info *info = &pipeline->state.fs.info;
const struct vk_rasterization_state *rs = state->rs;
const struct vk_depth_stencil_state *ds = state->ds;
bool test_s = ds && ds->stencil.test_enable;
bool test_z = ds && ds->depth.test_enable;
bool writes_z = writes_depth(ds);
bool writes_s = writes_stencil(ds);
pan_pack(rsd, RENDERER_STATE, cfg) {
if (pipeline->state.fs.required) {
@@ -160,10 +245,8 @@ emit_base_fs_rsd(const struct panvk_graphics_pipeline *pipeline,
!pipeline->state.ms.alpha_to_coverage &&
!pipeline->state.blend.reads_dest;
bool writes_zs =
pipeline->state.zs.z_write || pipeline->state.zs.s_test;
bool zs_always_passes =
!pipeline->state.zs.z_test && !pipeline->state.zs.s_test;
bool writes_zs = writes_z || writes_s;
bool zs_always_passes = ds_test_always_passes(ds);
bool oq = false; /* TODO: Occlusion queries */
struct pan_earlyzs_state earlyzs = pan_earlyzs_get(
@@ -185,16 +268,16 @@ emit_base_fs_rsd(const struct panvk_graphics_pipeline *pipeline,
msaa ? pipeline->state.ms.sample_mask : UINT16_MAX;
cfg.multisample_misc.depth_function =
pipeline->state.zs.z_test ? pipeline->state.zs.z_compare_func
: MALI_FUNC_ALWAYS;
test_z ? translate_compare_func(ds->depth.compare_op)
: MALI_FUNC_ALWAYS;
cfg.multisample_misc.depth_write_mask = pipeline->state.zs.z_write;
cfg.multisample_misc.depth_write_mask = writes_z;
cfg.multisample_misc.fixed_function_near_discard =
!rs->depth_clamp_enable;
cfg.multisample_misc.fixed_function_far_discard = !rs->depth_clamp_enable;
cfg.multisample_misc.shader_depth_range_fixed = true;
cfg.stencil_mask_misc.stencil_enable = pipeline->state.zs.s_test;
cfg.stencil_mask_misc.stencil_enable = test_s;
cfg.stencil_mask_misc.alpha_to_coverage =
pipeline->state.ms.alpha_to_coverage;
cfg.stencil_mask_misc.alpha_test_compare_function = MALI_FUNC_ALWAYS;
@@ -210,32 +293,39 @@ emit_base_fs_rsd(const struct panvk_graphics_pipeline *pipeline,
}
if (dyn_state_is_set(pipeline, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK)) {
cfg.stencil_front.mask = pipeline->state.zs.s_front.compare_mask;
cfg.stencil_back.mask = pipeline->state.zs.s_back.compare_mask;
cfg.stencil_front.mask = ds->stencil.front.compare_mask;
cfg.stencil_back.mask = ds->stencil.back.compare_mask;
}
if (dyn_state_is_set(pipeline, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK)) {
cfg.stencil_mask_misc.stencil_mask_front =
pipeline->state.zs.s_front.write_mask;
cfg.stencil_mask_misc.stencil_mask_back =
pipeline->state.zs.s_back.write_mask;
ds->stencil.front.write_mask;
cfg.stencil_mask_misc.stencil_mask_back = ds->stencil.back.write_mask;
}
if (dyn_state_is_set(pipeline, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE)) {
cfg.stencil_front.reference_value = pipeline->state.zs.s_front.ref;
cfg.stencil_back.reference_value = pipeline->state.zs.s_back.ref;
cfg.stencil_front.reference_value = ds->stencil.front.reference;
cfg.stencil_back.reference_value = ds->stencil.back.reference;
}
cfg.stencil_front.compare_function =
pipeline->state.zs.s_front.compare_func;
cfg.stencil_front.stencil_fail = pipeline->state.zs.s_front.fail_op;
cfg.stencil_front.depth_fail = pipeline->state.zs.s_front.z_fail_op;
cfg.stencil_front.depth_pass = pipeline->state.zs.s_front.pass_op;
cfg.stencil_back.compare_function =
pipeline->state.zs.s_back.compare_func;
cfg.stencil_back.stencil_fail = pipeline->state.zs.s_back.fail_op;
cfg.stencil_back.depth_fail = pipeline->state.zs.s_back.z_fail_op;
cfg.stencil_back.depth_pass = pipeline->state.zs.s_back.pass_op;
if (test_s) {
cfg.stencil_front.compare_function =
translate_compare_func(ds->stencil.front.op.compare);
cfg.stencil_front.stencil_fail =
translate_stencil_op(ds->stencil.front.op.fail);
cfg.stencil_front.depth_fail =
translate_stencil_op(ds->stencil.front.op.depth_fail);
cfg.stencil_front.depth_pass =
translate_stencil_op(ds->stencil.front.op.pass);
cfg.stencil_back.compare_function =
translate_compare_func(ds->stencil.back.op.compare);
cfg.stencil_back.stencil_fail =
translate_stencil_op(ds->stencil.back.op.fail);
cfg.stencil_back.depth_fail =
translate_stencil_op(ds->stencil.back.op.depth_fail);
cfg.stencil_back.depth_pass =
translate_stencil_op(ds->stencil.back.op.pass);
}
}
}
@@ -392,20 +482,6 @@ init_shaders(struct panvk_pipeline *pipeline,
#define is_dyn(__state, __name) \
BITSET_TEST((__state)->dynamic, MESA_VK_DYNAMIC_##__name)
static void
parse_dynamic_state(struct panvk_graphics_pipeline *pipeline,
const struct vk_graphics_pipeline_state *state)
{
if (is_dyn(state, DS_DEPTH_BOUNDS_TEST_BOUNDS))
pipeline->state.dynamic_mask |= PANVK_DYNAMIC_DEPTH_BOUNDS;
if (is_dyn(state, DS_STENCIL_COMPARE_MASK))
pipeline->state.dynamic_mask |= PANVK_DYNAMIC_STENCIL_COMPARE_MASK;
if (is_dyn(state, DS_STENCIL_WRITE_MASK))
pipeline->state.dynamic_mask |= PANVK_DYNAMIC_STENCIL_WRITE_MASK;
if (is_dyn(state, DS_STENCIL_REFERENCE))
pipeline->state.dynamic_mask |= PANVK_DYNAMIC_STENCIL_REFERENCE;
}
static uint32_t
get_active_color_attachments(const struct vk_graphics_pipeline_state *state)
{
@@ -516,97 +592,6 @@ parse_multisample(struct panvk_graphics_pipeline *pipeline,
MAX2(ms->min_sample_shading * nr_samples, 1);
}
static enum mali_stencil_op
translate_stencil_op(VkStencilOp in)
{
switch (in) {
case VK_STENCIL_OP_KEEP:
return MALI_STENCIL_OP_KEEP;
case VK_STENCIL_OP_ZERO:
return MALI_STENCIL_OP_ZERO;
case VK_STENCIL_OP_REPLACE:
return MALI_STENCIL_OP_REPLACE;
case VK_STENCIL_OP_INCREMENT_AND_CLAMP:
return MALI_STENCIL_OP_INCR_SAT;
case VK_STENCIL_OP_DECREMENT_AND_CLAMP:
return MALI_STENCIL_OP_DECR_SAT;
case VK_STENCIL_OP_INCREMENT_AND_WRAP:
return MALI_STENCIL_OP_INCR_WRAP;
case VK_STENCIL_OP_DECREMENT_AND_WRAP:
return MALI_STENCIL_OP_DECR_WRAP;
case VK_STENCIL_OP_INVERT:
return MALI_STENCIL_OP_INVERT;
default:
unreachable("Invalid stencil op");
}
}
static inline enum mali_func
translate_compare_func(VkCompareOp comp)
{
STATIC_ASSERT(VK_COMPARE_OP_NEVER == (VkCompareOp)MALI_FUNC_NEVER);
STATIC_ASSERT(VK_COMPARE_OP_LESS == (VkCompareOp)MALI_FUNC_LESS);
STATIC_ASSERT(VK_COMPARE_OP_EQUAL == (VkCompareOp)MALI_FUNC_EQUAL);
STATIC_ASSERT(VK_COMPARE_OP_LESS_OR_EQUAL == (VkCompareOp)MALI_FUNC_LEQUAL);
STATIC_ASSERT(VK_COMPARE_OP_GREATER == (VkCompareOp)MALI_FUNC_GREATER);
STATIC_ASSERT(VK_COMPARE_OP_NOT_EQUAL == (VkCompareOp)MALI_FUNC_NOT_EQUAL);
STATIC_ASSERT(VK_COMPARE_OP_GREATER_OR_EQUAL ==
(VkCompareOp)MALI_FUNC_GEQUAL);
STATIC_ASSERT(VK_COMPARE_OP_ALWAYS == (VkCompareOp)MALI_FUNC_ALWAYS);
return (enum mali_func)comp;
}
static void
parse_zs(struct panvk_graphics_pipeline *pipeline,
const struct vk_graphics_pipeline_state *state)
{
const struct vk_depth_stencil_state *ds = state->ds;
if (!ds)
return;
pipeline->state.zs.z_test = ds->depth.test_enable;
/* The Vulkan spec says:
*
* depthWriteEnable controls whether depth writes are enabled when
* depthTestEnable is VK_TRUE. Depth writes are always disabled when
* depthTestEnable is VK_FALSE.
*
* The hardware does not make this distinction, though, so we AND in the
* condition ourselves.
*/
pipeline->state.zs.z_write =
pipeline->state.zs.z_test && ds->depth.write_enable;
pipeline->state.zs.z_compare_func =
translate_compare_func(ds->depth.compare_op);
pipeline->state.zs.s_test = ds->stencil.test_enable;
pipeline->state.zs.s_front.fail_op =
translate_stencil_op(ds->stencil.front.op.fail);
pipeline->state.zs.s_front.pass_op =
translate_stencil_op(ds->stencil.front.op.pass);
pipeline->state.zs.s_front.z_fail_op =
translate_stencil_op(ds->stencil.front.op.depth_fail);
pipeline->state.zs.s_front.compare_func =
translate_compare_func(ds->stencil.front.op.compare);
pipeline->state.zs.s_front.compare_mask = ds->stencil.front.compare_mask;
pipeline->state.zs.s_front.write_mask = ds->stencil.front.write_mask;
pipeline->state.zs.s_front.ref = ds->stencil.front.reference;
pipeline->state.zs.s_back.fail_op =
translate_stencil_op(ds->stencil.back.op.fail);
pipeline->state.zs.s_back.pass_op =
translate_stencil_op(ds->stencil.back.op.pass);
pipeline->state.zs.s_back.z_fail_op =
translate_stencil_op(ds->stencil.back.op.depth_fail);
pipeline->state.zs.s_back.compare_func =
translate_compare_func(ds->stencil.back.op.compare);
pipeline->state.zs.s_back.compare_mask = ds->stencil.back.compare_mask;
pipeline->state.zs.s_back.write_mask = ds->stencil.back.write_mask;
pipeline->state.zs.s_back.ref = ds->stencil.back.reference;
}
static bool
fs_required(struct panvk_graphics_pipeline *pipeline)
{
@@ -802,13 +787,11 @@ panvk_graphics_pipeline_create(struct panvk_device *dev,
struct panvk_shader *shaders[MESA_SHADER_STAGES] = {NULL};
parse_dynamic_state(gfx_pipeline, &state);
parse_color_blend(gfx_pipeline, &state);
compile_shaders(&gfx_pipeline->base, create_info->pStages,
create_info->stageCount, alloc, shaders);
collect_varyings(gfx_pipeline, shaders);
parse_multisample(gfx_pipeline, &state);
parse_zs(gfx_pipeline, &state);
parse_vertex_input(gfx_pipeline, &state, shaders);
init_fs_state(gfx_pipeline, &state, shaders[MESA_SHADER_FRAGMENT]);
init_shaders(&gfx_pipeline->base, create_info, &state, shaders);