summaryrefslogtreecommitdiffstats
path: root/src/freedreno/vulkan
diff options
context:
space:
mode:
Diffstat (limited to 'src/freedreno/vulkan')
-rw-r--r--src/freedreno/vulkan/tu_pipeline.c190
-rw-r--r--src/freedreno/vulkan/tu_private.h16
2 files changed, 204 insertions, 2 deletions
diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c
index 030e107896a..9f91ffe3290 100644
--- a/src/freedreno/vulkan/tu_pipeline.c
+++ b/src/freedreno/vulkan/tu_pipeline.c
@@ -49,6 +49,7 @@ struct tu_pipeline_builder
bool rasterizer_discard;
/* these states are affectd by rasterizer_discard */
VkSampleCountFlagBits samples;
+ bool use_depth_stencil_attachment;
};
static enum tu_dynamic_state_bits
@@ -110,6 +111,58 @@ tu6_primtype(VkPrimitiveTopology topology)
}
}
+static enum adreno_compare_func
+tu6_compare_func(VkCompareOp op)
+{
+ switch (op) {
+ case VK_COMPARE_OP_NEVER:
+ return FUNC_NEVER;
+ case VK_COMPARE_OP_LESS:
+ return FUNC_LESS;
+ case VK_COMPARE_OP_EQUAL:
+ return FUNC_EQUAL;
+ case VK_COMPARE_OP_LESS_OR_EQUAL:
+ return FUNC_LEQUAL;
+ case VK_COMPARE_OP_GREATER:
+ return FUNC_GREATER;
+ case VK_COMPARE_OP_NOT_EQUAL:
+ return FUNC_NOTEQUAL;
+ case VK_COMPARE_OP_GREATER_OR_EQUAL:
+ return FUNC_GEQUAL;
+ case VK_COMPARE_OP_ALWAYS:
+ return FUNC_ALWAYS;
+ default:
+ unreachable("invalid VkCompareOp");
+ return FUNC_NEVER;
+ }
+}
+
+static enum adreno_stencil_op
+tu6_stencil_op(VkStencilOp op)
+{
+ switch (op) {
+ case VK_STENCIL_OP_KEEP:
+ return STENCIL_KEEP;
+ case VK_STENCIL_OP_ZERO:
+ return STENCIL_ZERO;
+ case VK_STENCIL_OP_REPLACE:
+ return STENCIL_REPLACE;
+ case VK_STENCIL_OP_INCREMENT_AND_CLAMP:
+ return STENCIL_INCR_CLAMP;
+ case VK_STENCIL_OP_DECREMENT_AND_CLAMP:
+ return STENCIL_DECR_CLAMP;
+ case VK_STENCIL_OP_INVERT:
+ return STENCIL_INVERT;
+ case VK_STENCIL_OP_INCREMENT_AND_WRAP:
+ return STENCIL_INCR_WRAP;
+ case VK_STENCIL_OP_DECREMENT_AND_WRAP:
+ return STENCIL_DECR_WRAP;
+ default:
+ unreachable("invalid VkStencilOp");
+ return STENCIL_KEEP;
+ }
+}
+
static uint32_t
tu6_guardband_adj(uint32_t v)
{
@@ -257,6 +310,84 @@ tu6_emit_depth_bias(struct tu_cs *cs,
tu_cs_emit(cs, A6XX_GRAS_SU_POLY_OFFSET_OFFSET_CLAMP(clamp));
}
+static void
+tu6_emit_alpha_control_disable(struct tu_cs *cs)
+{
+ tu_cs_emit_pkt4(cs, REG_A6XX_RB_ALPHA_CONTROL, 1);
+ tu_cs_emit(cs, 0);
+}
+
+static void
+tu6_emit_depth_control(struct tu_cs *cs,
+ const VkPipelineDepthStencilStateCreateInfo *ds_info)
+{
+ assert(!ds_info->depthBoundsTestEnable);
+
+ uint32_t rb_depth_cntl = 0;
+ if (ds_info->depthTestEnable) {
+ rb_depth_cntl |=
+ A6XX_RB_DEPTH_CNTL_Z_ENABLE |
+ A6XX_RB_DEPTH_CNTL_ZFUNC(tu6_compare_func(ds_info->depthCompareOp)) |
+ A6XX_RB_DEPTH_CNTL_Z_TEST_ENABLE;
+
+ if (ds_info->depthWriteEnable)
+ rb_depth_cntl |= A6XX_RB_DEPTH_CNTL_Z_WRITE_ENABLE;
+ }
+
+ tu_cs_emit_pkt4(cs, REG_A6XX_RB_DEPTH_CNTL, 1);
+ tu_cs_emit(cs, rb_depth_cntl);
+}
+
+static void
+tu6_emit_stencil_control(struct tu_cs *cs,
+ const VkPipelineDepthStencilStateCreateInfo *ds_info)
+{
+ uint32_t rb_stencil_control = 0;
+ if (ds_info->stencilTestEnable) {
+ const VkStencilOpState *front = &ds_info->front;
+ const VkStencilOpState *back = &ds_info->back;
+ rb_stencil_control |=
+ A6XX_RB_STENCIL_CONTROL_STENCIL_ENABLE |
+ A6XX_RB_STENCIL_CONTROL_STENCIL_ENABLE_BF |
+ A6XX_RB_STENCIL_CONTROL_STENCIL_READ |
+ A6XX_RB_STENCIL_CONTROL_FUNC(tu6_compare_func(front->compareOp)) |
+ A6XX_RB_STENCIL_CONTROL_FAIL(tu6_stencil_op(front->failOp)) |
+ A6XX_RB_STENCIL_CONTROL_ZPASS(tu6_stencil_op(front->passOp)) |
+ A6XX_RB_STENCIL_CONTROL_ZFAIL(tu6_stencil_op(front->depthFailOp)) |
+ A6XX_RB_STENCIL_CONTROL_FUNC_BF(tu6_compare_func(back->compareOp)) |
+ A6XX_RB_STENCIL_CONTROL_FAIL_BF(tu6_stencil_op(back->failOp)) |
+ A6XX_RB_STENCIL_CONTROL_ZPASS_BF(tu6_stencil_op(back->passOp)) |
+ A6XX_RB_STENCIL_CONTROL_ZFAIL_BF(tu6_stencil_op(back->depthFailOp));
+ }
+
+ tu_cs_emit_pkt4(cs, REG_A6XX_RB_STENCIL_CONTROL, 1);
+ tu_cs_emit(cs, rb_stencil_control);
+}
+
+void
+tu6_emit_stencil_compare_mask(struct tu_cs *cs, uint32_t front, uint32_t back)
+{
+ tu_cs_emit_pkt4(cs, REG_A6XX_RB_STENCILMASK, 1);
+ tu_cs_emit(
+ cs, A6XX_RB_STENCILMASK_MASK(front) | A6XX_RB_STENCILMASK_BFMASK(back));
+}
+
+void
+tu6_emit_stencil_write_mask(struct tu_cs *cs, uint32_t front, uint32_t back)
+{
+ tu_cs_emit_pkt4(cs, REG_A6XX_RB_STENCILWRMASK, 1);
+ tu_cs_emit(cs, A6XX_RB_STENCILWRMASK_WRMASK(front) |
+ A6XX_RB_STENCILWRMASK_BFWRMASK(back));
+}
+
+void
+tu6_emit_stencil_reference(struct tu_cs *cs, uint32_t front, uint32_t back)
+{
+ tu_cs_emit_pkt4(cs, REG_A6XX_RB_STENCILREF, 1);
+ tu_cs_emit(cs,
+ A6XX_RB_STENCILREF_REF(front) | A6XX_RB_STENCILREF_BFREF(back));
+}
+
static VkResult
tu_pipeline_builder_create_pipeline(struct tu_pipeline_builder *builder,
struct tu_pipeline **out_pipeline)
@@ -379,6 +510,51 @@ tu_pipeline_builder_parse_rasterization(struct tu_pipeline_builder *builder,
}
static void
+tu_pipeline_builder_parse_depth_stencil(struct tu_pipeline_builder *builder,
+ struct tu_pipeline *pipeline)
+{
+ /* The spec says:
+ *
+ * pDepthStencilState is a pointer to an instance of the
+ * VkPipelineDepthStencilStateCreateInfo structure, and is ignored if
+ * the pipeline has rasterization disabled or if the subpass of the
+ * render pass the pipeline is created against does not use a
+ * depth/stencil attachment.
+ *
+ * We disable both depth and stenil tests in those cases.
+ */
+ static const VkPipelineDepthStencilStateCreateInfo dummy_ds_info;
+ const VkPipelineDepthStencilStateCreateInfo *ds_info =
+ builder->use_depth_stencil_attachment
+ ? builder->create_info->pDepthStencilState
+ : &dummy_ds_info;
+
+ struct tu_cs ds_cs;
+ tu_cs_begin_sub_stream(builder->device, &pipeline->cs, 12, &ds_cs);
+
+ /* move to hw ctx init? */
+ tu6_emit_alpha_control_disable(&ds_cs);
+
+ tu6_emit_depth_control(&ds_cs, ds_info);
+ tu6_emit_stencil_control(&ds_cs, ds_info);
+
+ if (!(pipeline->dynamic_state.mask & TU_DYNAMIC_STENCIL_COMPARE_MASK)) {
+ tu6_emit_stencil_compare_mask(&ds_cs, ds_info->front.compareMask,
+ ds_info->back.compareMask);
+ }
+ if (!(pipeline->dynamic_state.mask & TU_DYNAMIC_STENCIL_WRITE_MASK)) {
+ tu6_emit_stencil_write_mask(&ds_cs, ds_info->front.writeMask,
+ ds_info->back.writeMask);
+ }
+ if (!(pipeline->dynamic_state.mask & TU_DYNAMIC_STENCIL_REFERENCE)) {
+ tu6_emit_stencil_reference(&ds_cs, ds_info->front.reference,
+ ds_info->back.reference);
+ }
+
+ pipeline->ds.state_ib = tu_cs_end_sub_stream(&pipeline->cs, &ds_cs);
+}
+
+static void
tu_pipeline_finish(struct tu_pipeline *pipeline,
struct tu_device *dev,
const VkAllocationCallbacks *alloc)
@@ -398,6 +574,7 @@ tu_pipeline_builder_build(struct tu_pipeline_builder *builder,
tu_pipeline_builder_parse_input_assembly(builder, *pipeline);
tu_pipeline_builder_parse_viewport(builder, *pipeline);
tu_pipeline_builder_parse_rasterization(builder, *pipeline);
+ tu_pipeline_builder_parse_depth_stencil(builder, *pipeline);
/* we should have reserved enough space upfront such that the CS never
* grows
@@ -425,10 +602,19 @@ tu_pipeline_builder_init_graphics(
builder->rasterizer_discard =
create_info->pRasterizationState->rasterizerDiscardEnable;
- if (builder->rasterizer_discard)
+ if (builder->rasterizer_discard) {
builder->samples = VK_SAMPLE_COUNT_1_BIT;
- else
+ } else {
builder->samples = create_info->pMultisampleState->rasterizationSamples;
+
+ const struct tu_render_pass *pass =
+ tu_render_pass_from_handle(create_info->renderPass);
+ const struct tu_subpass *subpass =
+ &pass->subpasses[create_info->subpass];
+
+ builder->use_depth_stencil_attachment =
+ subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED;
+ }
}
VkResult
diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h
index 31f5364774e..e8c0e91a877 100644
--- a/src/freedreno/vulkan/tu_private.h
+++ b/src/freedreno/vulkan/tu_private.h
@@ -1002,6 +1002,11 @@ struct tu_pipeline
uint32_t gras_su_cntl;
struct tu_cs_entry state_ib;
} rast;
+
+ struct
+ {
+ struct tu_cs_entry state_ib;
+ } ds;
};
void
@@ -1021,6 +1026,17 @@ tu6_emit_depth_bias(struct tu_cs *cs,
float clamp,
float slope_factor);
+void
+tu6_emit_stencil_compare_mask(struct tu_cs *cs,
+ uint32_t front,
+ uint32_t back);
+
+void
+tu6_emit_stencil_write_mask(struct tu_cs *cs, uint32_t front, uint32_t back);
+
+void
+tu6_emit_stencil_reference(struct tu_cs *cs, uint32_t front, uint32_t back);
+
struct tu_userdata_info *
tu_lookup_user_sgpr(struct tu_pipeline *pipeline,
gl_shader_stage stage,