[Mesa-dev] [PATCH 7/9] anv/pipeline: Silently pass tests if depth or stencil is missing

Jason Ekstrand jason at jlekstrand.net
Wed Jun 1 21:44:58 UTC 2016


Signed-off-by: Jason Ekstrand <jason at jlekstrand.net>
Cc: "12.0" <mesa-stable at lists.freedesktop.org>
Cc: Ian Romanick <idr at freedesktop.org>
---
 src/intel/vulkan/gen7_pipeline.c      | 12 ++++++++++--
 src/intel/vulkan/gen8_pipeline.c      | 12 ++++++++++--
 src/intel/vulkan/genX_pipeline_util.h | 30 +++++++++++++++++++++++++++++-
 3 files changed, 49 insertions(+), 5 deletions(-)

diff --git a/src/intel/vulkan/gen7_pipeline.c b/src/intel/vulkan/gen7_pipeline.c
index 243b18b..0d2d086 100644
--- a/src/intel/vulkan/gen7_pipeline.c
+++ b/src/intel/vulkan/gen7_pipeline.c
@@ -155,6 +155,8 @@ genX(graphics_pipeline_create)(
     VkPipeline*                                 pPipeline)
 {
    ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_render_pass, pass, pCreateInfo->renderPass);
+   struct anv_subpass *subpass = &pass->subpasses[pCreateInfo->subpass];
    struct anv_pipeline *pipeline;
    VkResult result;
 
@@ -178,7 +180,7 @@ genX(graphics_pipeline_create)(
    assert(pCreateInfo->pRasterizationState);
    gen7_emit_rs_state(pipeline, pCreateInfo->pRasterizationState, extra);
 
-   emit_ds_state(pipeline, pCreateInfo->pDepthStencilState);
+   emit_ds_state(pipeline, pCreateInfo->pDepthStencilState, pass, subpass);
 
    gen7_emit_cb_state(pipeline, pCreateInfo->pColorBlendState,
                                 pCreateInfo->pMultisampleState);
@@ -369,10 +371,16 @@ genX(graphics_pipeline_create)(
          wm.PixelShaderUsesSourceW              = wm_prog_data->uses_src_w;
          wm.PixelShaderUsesInputCoverageMask    = wm_prog_data->uses_sample_mask;
 
+         /* TODO: We could probably do something a bit more intellegent here.
+          * However, CTS tests expect that if earliy fragment tests are not
+          * performed, the shader *will* be executed for every fragment.  In
+          * order to work around this we would have to check whether or not
+          * the shader has side-effects before we can set the mode to NORMAL.
+          */
          if (wm_prog_data->early_fragment_tests) {
             wm.EarlyDepthStencilControl         = EDSC_PREPS;
          } else {
-            wm.EarlyDepthStencilControl         = EDSC_NORMAL;
+            wm.EarlyDepthStencilControl         = EDSC_PSEXEC;
          }
 
          wm.BarycentricInterpolationMode        = wm_prog_data->barycentric_interp_modes;
diff --git a/src/intel/vulkan/gen8_pipeline.c b/src/intel/vulkan/gen8_pipeline.c
index 7cc7c51..4b477ee 100644
--- a/src/intel/vulkan/gen8_pipeline.c
+++ b/src/intel/vulkan/gen8_pipeline.c
@@ -268,6 +268,8 @@ genX(graphics_pipeline_create)(
     VkPipeline*                                 pPipeline)
 {
    ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_render_pass, pass, pCreateInfo->renderPass);
+   struct anv_subpass *subpass = &pass->subpasses[pCreateInfo->subpass];
    struct anv_pipeline *pipeline;
    VkResult result;
    uint32_t offset, length;
@@ -294,7 +296,7 @@ genX(graphics_pipeline_create)(
    emit_rs_state(pipeline, pCreateInfo->pRasterizationState,
                  pCreateInfo->pMultisampleState, extra);
    emit_ms_state(pipeline, pCreateInfo->pMultisampleState);
-   emit_ds_state(pipeline, pCreateInfo->pDepthStencilState);
+   emit_ds_state(pipeline, pCreateInfo->pDepthStencilState, pass, subpass);
    emit_cb_state(pipeline, pCreateInfo->pColorBlendState,
                            pCreateInfo->pMultisampleState);
 
@@ -330,10 +332,16 @@ genX(graphics_pipeline_create)(
       wm.ForceThreadDispatchEnable           = NORMAL;
       wm.PointRasterizationRule              = RASTRULE_UPPER_RIGHT;
 
+      /* TODO: We could probably do something a bit more intellegent here.
+       * However, CTS tests expect that if earliy fragment tests are not
+       * performed, the shader *will* be executed for every fragment.  In
+       * order to work around this we would have to check whether or not
+       * the shader has side-effects before we can set the mode to NORMAL.
+       */
       if (wm_prog_data && wm_prog_data->early_fragment_tests) {
          wm.EarlyDepthStencilControl         = PREPS;
       } else {
-         wm.EarlyDepthStencilControl         = NORMAL;
+         wm.EarlyDepthStencilControl         = PSEXEC;
       }
 
       wm.BarycentricInterpolationMode = pipeline->ps_ksp0 == NO_KERNEL ?
diff --git a/src/intel/vulkan/genX_pipeline_util.h b/src/intel/vulkan/genX_pipeline_util.h
index fe24048..669b456 100644
--- a/src/intel/vulkan/genX_pipeline_util.h
+++ b/src/intel/vulkan/genX_pipeline_util.h
@@ -21,6 +21,8 @@
  * IN THE SOFTWARE.
  */
 
+#include "vk_format_info.h"
+
 static uint32_t
 vertex_element_comp_control(enum isl_format format, unsigned comp)
 {
@@ -428,7 +430,9 @@ static const uint32_t vk_to_gen_stencil_op[] = {
 
 static void
 emit_ds_state(struct anv_pipeline *pipeline,
-              const VkPipelineDepthStencilStateCreateInfo *info)
+              const VkPipelineDepthStencilStateCreateInfo *info,
+              const struct anv_render_pass *pass,
+              const struct anv_subpass *subpass)
 {
 #if GEN_GEN == 7
 #  define depth_stencil_dw pipeline->gen7.depth_stencil_state
@@ -470,6 +474,30 @@ emit_ds_state(struct anv_pipeline *pipeline,
       .BackfaceStencilTestFunction = vk_to_gen_compare_op[info->back.compareOp],
    };
 
+   VkImageAspectFlags aspects = 0;
+   if (pass->attachments == NULL) {
+      /* This comes from meta.  Assume we have verything. */
+      aspects = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
+   } else if (subpass->depth_stencil_attachment != VK_ATTACHMENT_UNUSED) {
+      VkFormat depth_stencil_format =
+         pass->attachments[subpass->depth_stencil_attachment].format;
+      aspects = vk_format_aspects(depth_stencil_format);
+   }
+
+   /* The Vulkan spec requires that if either depth or stencil is not present,
+    * the pipeline is to act as if the test silently passes.
+    */
+   if (!(aspects & VK_IMAGE_ASPECT_DEPTH_BIT)) {
+      depth_stencil.DepthBufferWriteEnable = false;
+      depth_stencil.DepthTestFunction = PREFILTEROPALWAYS;
+   }
+
+   if (!(aspects & VK_IMAGE_ASPECT_STENCIL_BIT)) {
+      depth_stencil.StencilBufferWriteEnable = false;
+      depth_stencil.StencilTestFunction = PREFILTEROPALWAYS;
+      depth_stencil.BackfaceStencilTestFunction = PREFILTEROPALWAYS;
+   }
+
    /* From the Broadwell PRM:
     *
     *    "If Depth_Test_Enable = 1 AND Depth_Test_func = EQUAL, the
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list