From 55acd9f1ea4d614f47c869883b698115b351cad0 Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Wed, 29 Jan 2020 16:35:39 +0100 Subject: [PATCH] v3dv: implement stencil testing This works on combined depth/stencil formats only, separate stencil is not supported yet. Part-of: --- src/broadcom/vulkan/v3dv_cmd_buffer.c | 6 +++ src/broadcom/vulkan/v3dv_pipeline.c | 70 +++++++++++++++++++++++++++++++++++ src/broadcom/vulkan/v3dv_private.h | 5 +++ 3 files changed, 81 insertions(+) diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c index f18a88e..da65efa 100644 --- a/src/broadcom/vulkan/v3dv_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c @@ -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); diff --git a/src/broadcom/vulkan/v3dv_pipeline.c b/src/broadcom/vulkan/v3dv_pipeline.c index b3bb7ef..db0d98c 100644 --- a/src/broadcom/vulkan/v3dv_pipeline.c +++ b/src/broadcom/vulkan/v3dv_pipeline.c @@ -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); diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index 0cd0c52..22ab9a9 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -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); -- 2.7.4