vk: Fix format of anv_depth_stencil_view
authorChad Versace <chad.versace@intel.com>
Fri, 28 Aug 2015 14:44:32 +0000 (07:44 -0700)
committerChad Versace <chad.versace@intel.com>
Fri, 28 Aug 2015 14:44:32 +0000 (07:44 -0700)
The format of the view itself and of the view's image may differ.
Moreover, if the view's format has no depth aspect but the image's
format does, we must not program the depth buffer. Ditto for stencil.

src/vulkan/anv_image.c
src/vulkan/anv_private.h
src/vulkan/gen7_cmd_buffer.c
src/vulkan/gen8_cmd_buffer.c

index 198f4a40212585793f07f7be05a69e3e440d2fbf..6ab541e5bce894935062cd6841d51ac5adc54311 100644 (file)
@@ -475,14 +475,28 @@ anv_depth_stencil_view_init(struct anv_depth_stencil_view *view,
 
    view->bo = image->bo;
 
-   view->depth_stride = image->depth_surface.stride;
-   view->depth_offset = image->offset + image->depth_surface.offset;
-   view->depth_format = image->format->depth_format;
-   view->depth_qpitch = 0; /* FINISHME: QPitch */
-
-   view->stencil_stride = image->stencil_surface.stride;
-   view->stencil_offset = image->offset + image->stencil_surface.offset;
-   view->stencil_qpitch = 0; /* FINISHME: QPitch */
+   view->format = anv_format_for_vk_format(pCreateInfo->format);
+   assert(anv_format_is_depth_or_stencil(view->format));
+
+   if (view->format->depth_format) {
+      view->depth_stride = image->depth_surface.stride;
+      view->depth_offset = image->offset + image->depth_surface.offset;
+      view->depth_qpitch = 0; /* FINISHME: QPitch */
+   } else {
+      view->depth_stride = 0;
+      view->depth_offset = 0;
+      view->depth_qpitch = 0;
+   }
+
+   if (view->format->has_stencil) {
+      view->stencil_stride = image->stencil_surface.stride;
+      view->stencil_offset = image->offset + image->stencil_surface.offset;
+      view->stencil_qpitch = 0; /* FINISHME: QPitch */
+   } else {
+      view->stencil_stride = 0;
+      view->stencil_offset = 0;
+      view->stencil_qpitch = 0;
+   }
 }
 
 struct anv_surface *
index 2d037b4cbb30ff5472a3d358dbef3af6535a95cd..594b4fedc6c91742d84f28e57342031ae1c61e49 100644 (file)
@@ -1119,6 +1119,7 @@ struct anv_color_attachment_view {
 
 struct anv_depth_stencil_view {
    struct anv_attachment_view base;
+   const struct anv_format *format; /**< VkAttachmentViewCreateInfo::format */
 
    struct anv_bo *bo;
 
index d9644e2a06a0b7fbdbf41596eeb6aab0f945a52a..1028b6dae22fb04f57d314c0510454a8899e6615 100644 (file)
@@ -543,14 +543,18 @@ gen7_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
       view = (const struct anv_depth_stencil_view *)aview;
    }
 
-   if (view) {
+   const bool has_depth = view && view->format->depth_format;
+   const bool has_stencil = view && view->format->has_stencil;
+
+   /* Emit 3DSTATE_DEPTH_BUFFER */
+   if (has_depth) {
       anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_DEPTH_BUFFER,
          .SurfaceType = SURFTYPE_2D,
-         .DepthWriteEnable = view->depth_stride > 0,
-         .StencilWriteEnable = view->stencil_stride > 0,
+         .DepthWriteEnable = view->format->depth_format,
+         .StencilWriteEnable = has_stencil,
          .HierarchicalDepthBufferEnable = false,
-         .SurfaceFormat = view->depth_format,
-         .SurfacePitch = view->depth_stride > 0 ? view->depth_stride - 1 : 0,
+         .SurfaceFormat = view->format->depth_format,
+         .SurfacePitch = view->depth_stride - 1,
          .SurfaceBaseAddress = { view->bo,  view->depth_offset },
          .Height = fb->height - 1,
          .Width = fb->width - 1,
@@ -559,11 +563,6 @@ gen7_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
          .MinimumArrayElement = 0,
          .DepthBufferObjectControlState = GEN7_MOCS,
          .RenderTargetViewExtent = 1 - 1);
-
-      anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_STENCIL_BUFFER,
-         .StencilBufferObjectControlState = GEN7_MOCS,
-         .SurfacePitch = view->stencil_stride > 0 ? view->stencil_stride - 1 : 0,
-         .SurfaceBaseAddress = { view->bo, view->stencil_offset });
    } else {
       /* Even when no depth buffer is present, the hardware requires that
        * 3DSTATE_DEPTH_BUFFER be programmed correctly. The Broadwell PRM says:
@@ -579,15 +578,24 @@ gen7_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
        *       3DSTATE_WM_DEPTH_STENCIL.DepthBufferWriteEnable = 0
        *
        * The PRM is wrong, though. The width and height must be programmed to
-       * actual framebuffer's width and height.
+       * actual framebuffer's width and height, even when neither depth buffer
+       * nor stencil buffer is present.
        */
       anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_DEPTH_BUFFER,
          .SurfaceType = SURFTYPE_2D,
          .SurfaceFormat = D16_UNORM,
          .Width = fb->width - 1,
-         .Height = fb->height - 1);
+         .Height = fb->height - 1,
+         .StencilWriteEnable = has_stencil);
+   }
 
-      /* Disable the stencil buffer. */
+   /* Emit 3DSTATE_STENCIL_BUFFER */
+   if (has_stencil) {
+      anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_STENCIL_BUFFER,
+         .StencilBufferObjectControlState = GEN7_MOCS,
+         .SurfacePitch = view->stencil_stride - 1,
+         .SurfaceBaseAddress = { view->bo, view->stencil_offset });
+   } else {
       anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_STENCIL_BUFFER);
    }
 
index 57f061b9e8fb7155712c8b1f366816ca7178c80a..0ec0f666ae098d159b621e31ebb004e064148f7b 100644 (file)
@@ -469,17 +469,21 @@ gen8_cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer)
       view = (const struct anv_depth_stencil_view *)aview;
    }
 
+   const bool has_depth = view && view->format->depth_format;
+   const bool has_stencil = view && view->format->has_stencil;
+
    /* FIXME: Implement the PMA stall W/A */
    /* FIXME: Width and Height are wrong */
 
-   if (view) {
+   /* Emit 3DSTATE_DEPTH_BUFFER */
+   if (has_depth) {
       anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DEPTH_BUFFER,
          .SurfaceType = SURFTYPE_2D,
-         .DepthWriteEnable = view->depth_stride > 0,
-         .StencilWriteEnable = view->stencil_stride > 0,
+         .DepthWriteEnable = view->format->depth_format,
+         .StencilWriteEnable = has_stencil,
          .HierarchicalDepthBufferEnable = false,
-         .SurfaceFormat = view->depth_format,
-         .SurfacePitch = view->depth_stride > 0 ? view->depth_stride - 1 : 0,
+         .SurfaceFormat = view->format->depth_format,
+         .SurfacePitch = view->depth_stride - 1,
          .SurfaceBaseAddress = { view->bo,  view->depth_offset },
          .Height = fb->height - 1,
          .Width = fb->width - 1,
@@ -489,13 +493,6 @@ gen8_cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer)
          .DepthBufferObjectControlState = GEN8_MOCS,
          .RenderTargetViewExtent = 1 - 1,
          .SurfaceQPitch = view->depth_qpitch >> 2);
-
-      anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_STENCIL_BUFFER,
-         .StencilBufferEnable = view->stencil_stride > 0,
-         .StencilBufferObjectControlState = GEN8_MOCS,
-         .SurfacePitch = view->stencil_stride > 0 ? view->stencil_stride - 1 : 0,
-         .SurfaceBaseAddress = { view->bo, view->stencil_offset },
-         .SurfaceQPitch = view->stencil_qpitch >> 2);
    } else {
       /* Even when no depth buffer is present, the hardware requires that
        * 3DSTATE_DEPTH_BUFFER be programmed correctly. The Broadwell PRM says:
@@ -511,15 +508,26 @@ gen8_cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer)
        *       3DSTATE_WM_DEPTH_STENCIL.DepthBufferWriteEnable = 0
        *
        * The PRM is wrong, though. The width and height must be programmed to
-       * actual framebuffer's width and height.
+       * actual framebuffer's width and height, even when neither depth buffer
+       * nor stencil buffer is present.
        */
       anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DEPTH_BUFFER,
          .SurfaceType = SURFTYPE_2D,
          .SurfaceFormat = D16_UNORM,
          .Width = fb->width - 1,
-         .Height = fb->height - 1);
+         .Height = fb->height - 1,
+         .StencilWriteEnable = has_stencil);
+   }
 
-      /* Disable the stencil buffer. */
+   /* Emit 3DSTATE_STENCIL_BUFFER */
+   if (has_stencil) {
+      anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_STENCIL_BUFFER,
+         .StencilBufferEnable = true,
+         .StencilBufferObjectControlState = GEN8_MOCS,
+         .SurfacePitch = view->stencil_stride - 1,
+         .SurfaceBaseAddress = { view->bo, view->stencil_offset },
+         .SurfaceQPitch = view->stencil_qpitch >> 2);
+   } else {
       anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_STENCIL_BUFFER);
    }