diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c index 9f11c810086..4f6d5732b9a 100644 --- a/src/freedreno/vulkan/tu_pipeline.c +++ b/src/freedreno/vulkan/tu_pipeline.c @@ -2495,6 +2495,47 @@ tu_pipeline_builder_parse_depth_stencil(struct tu_pipeline_builder *builder, tu_cs_emit_regs(&cs, A6XX_RB_STENCILREF(.ref = ds_info->front.reference & 0xff, .bfref = ds_info->back.reference & 0xff)); } + + if (ds_info->depthTestEnable) { + pipeline->lrz.write = ds_info->depthWriteEnable; + pipeline->lrz.invalidate = false; + pipeline->lrz.z_test_enable = true; + + /* LRZ does not support some depth modes. + * + * The HW has a flag for GREATER and GREATER_OR_EQUAL modes which is used + * in freedreno, however there are some dEQP-VK tests that fail if we use here. + * Furthermore, blob disables LRZ on these comparison opcodes too. + * + * TODO: investigate if we can enable GREATER flag here. + */ + switch(ds_info->depthCompareOp) { + case VK_COMPARE_OP_ALWAYS: + case VK_COMPARE_OP_NOT_EQUAL: + case VK_COMPARE_OP_GREATER: + case VK_COMPARE_OP_GREATER_OR_EQUAL: + pipeline->lrz.invalidate = true; + pipeline->lrz.write = false; + break; + case VK_COMPARE_OP_EQUAL: + case VK_COMPARE_OP_NEVER: + pipeline->lrz.enable = true; + pipeline->lrz.write = false; + break; + case VK_COMPARE_OP_LESS: + case VK_COMPARE_OP_LESS_OR_EQUAL: + pipeline->lrz.enable = true; + break; + default: + unreachable("bad VK_COMPARE_OP value"); + break; + }; + } + + if (ds_info->stencilTestEnable) { + pipeline->lrz.write = false; + pipeline->lrz.invalidate = true; + } } static void diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h index 0917481e2aa..1dd9d5fa38d 100644 --- a/src/freedreno/vulkan/tu_private.h +++ b/src/freedreno/vulkan/tu_private.h @@ -837,6 +837,16 @@ struct tu_cache_state { enum tu_cmd_flush_bits flush_bits; }; +struct tu_lrz_pipeline +{ + bool write : 1; + bool invalidate : 1; + + bool enable : 1; + bool greater : 1; + bool z_test_enable : 1; +}; + struct tu_cmd_state { uint32_t dirty; @@ -1116,6 +1126,8 @@ struct tu_pipeline { uint32_t local_size[3]; } compute; + + struct tu_lrz_pipeline lrz; }; void