v3dv: implement stencil testing

This works on combined depth/stencil formats only, separate stencil
is not supported yet.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
This commit is contained in:
Iago Toral Quiroga 2020-01-29 16:35:39 +01:00 committed by Marge Bot
parent bb6e9d26dc
commit 55acd9f1ea
3 changed files with 81 additions and 0 deletions

View File

@ -1736,6 +1736,12 @@ cmd_buffer_emit_graphics_pipeline(struct v3dv_cmd_buffer *cmd_buffer)
cl_emit_prepacked(&job->bcl, &pipeline->cfg_bits);
if (pipeline->emit_stencil_cfg[0]) {
cl_emit_prepacked(&job->bcl, &pipeline->stencil_cfg[0]);
if (pipeline->emit_stencil_cfg[1])
cl_emit_prepacked(&job->bcl, &pipeline->stencil_cfg[1]);
}
/* FIXME: hardcoded values */
cl_emit(&job->bcl, ZERO_ALL_FLAT_SHADE_FLAGS, flags);
cl_emit(&job->bcl, ZERO_ALL_NON_PERSPECTIVE_FLAGS, flags);

View File

@ -976,6 +976,75 @@ pack_cfg_bits(struct v3dv_pipeline *pipeline,
};
}
static uint32_t
translate_stencil_op(enum pipe_stencil_op op)
{
switch (op) {
case VK_STENCIL_OP_KEEP:
return V3D_STENCIL_OP_KEEP;
case VK_STENCIL_OP_ZERO:
return V3D_STENCIL_OP_ZERO;
case VK_STENCIL_OP_REPLACE:
return V3D_STENCIL_OP_REPLACE;
case VK_STENCIL_OP_INCREMENT_AND_CLAMP:
return V3D_STENCIL_OP_INCR;
case VK_STENCIL_OP_DECREMENT_AND_CLAMP:
return V3D_STENCIL_OP_DECR;
case VK_STENCIL_OP_INVERT:
return V3D_STENCIL_OP_INVERT;
case VK_STENCIL_OP_INCREMENT_AND_WRAP:
return V3D_STENCIL_OP_INCWRAP;
case VK_STENCIL_OP_DECREMENT_AND_WRAP:
return V3D_STENCIL_OP_DECWRAP;
default:
unreachable("bad stencil op");
}
}
static void
pack_single_stencil_cfg(uint8_t *stencil_cfg,
bool is_front,
bool is_back,
const VkStencilOpState *stencil_state)
{
v3dv_pack(stencil_cfg, STENCIL_CFG, config) {
config.front_config = is_front;
config.back_config = is_back;
config.stencil_write_mask = stencil_state->writeMask;
config.stencil_test_mask = stencil_state->compareMask;
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 = stencil_state->reference;
}
}
static void
pack_stencil_cfg(struct v3dv_pipeline *pipeline,
const VkPipelineDepthStencilStateCreateInfo *ds_info)
{
assert(sizeof(pipeline->stencil_cfg) == 2 * cl_packet_length(STENCIL_CFG));
if (!ds_info || !ds_info->stencilTestEnable)
return;
/* If the front and back configurations are the same we can emit both with
* a single packet.
*/
pipeline->emit_stencil_cfg[0] = true;
if (memcmp(&ds_info->front, &ds_info->back, sizeof(ds_info->front)) == 0) {
pack_single_stencil_cfg(pipeline->stencil_cfg[0],
true, true, &ds_info->front);
} else {
pipeline->emit_stencil_cfg[1] = true;
pack_single_stencil_cfg(pipeline->stencil_cfg[0],
true, false, &ds_info->front);
pack_single_stencil_cfg(pipeline->stencil_cfg[1],
false, true, &ds_info->back);
}
}
static void
pack_shader_state_record(struct v3dv_pipeline *pipeline)
{
@ -1255,6 +1324,7 @@ pipeline_init(struct v3dv_pipeline *pipeline,
raster_enabled ? pCreateInfo->pColorBlendState : NULL;
pack_cfg_bits(pipeline, ds_info, rs_info, cb_info);
pack_stencil_cfg(pipeline, ds_info);
result = pipeline_compile_graphics(pipeline, pCreateInfo, alloc);

View File

@ -688,6 +688,10 @@ struct v3dv_pipeline {
struct vpm_config vpm_cfg;
struct vpm_config vpm_cfg_bin;
/* If the pipeline should emit any of the stencil configuration packets */
bool emit_stencil_cfg[2];
/* Packets prepacked during pipeline creation
*/
uint8_t cfg_bits[cl_packet_length(CFG_BITS)];
@ -695,6 +699,7 @@ struct v3dv_pipeline {
uint8_t vcm_cache_size[cl_packet_length(VCM_CACHE_SIZE)];
uint8_t vertex_attrs[cl_packet_length(GL_SHADER_STATE_ATTRIBUTE_RECORD) *
(MAX_VBS / 4)];
uint8_t stencil_cfg[2][cl_packet_length(STENCIL_CFG)];
};
uint32_t v3dv_physical_device_api_version(struct v3dv_physical_device *dev);