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.
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 *
struct anv_depth_stencil_view {
struct anv_attachment_view base;
+ const struct anv_format *format; /**< VkAttachmentViewCreateInfo::format */
struct anv_bo *bo;
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,
.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:
* 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);
}
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,
.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:
* 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);
}