summaryrefslogtreecommitdiff
path: root/src/broadcom/vulkan/v3dv_pipeline.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/broadcom/vulkan/v3dv_pipeline.c')
-rw-r--r--src/broadcom/vulkan/v3dv_pipeline.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/broadcom/vulkan/v3dv_pipeline.c b/src/broadcom/vulkan/v3dv_pipeline.c
index b3bb7ef5931..db0d98ca7d2 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);