diff --git a/src/vulkan/gen7_cmd_buffer.c b/src/vulkan/gen7_cmd_buffer.c index 74fc60fa84c..6eb5d48c039 100644 --- a/src/vulkan/gen7_cmd_buffer.c +++ b/src/vulkan/gen7_cmd_buffer.c @@ -529,11 +529,8 @@ void gen7_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer, struct anv_subpass *subpass) { - static const struct anv_depth_stencil_view null_view = - { .depth_format = D16_UNORM, .depth_stride = 0, .stencil_stride = 0 }; - struct anv_framebuffer *fb = cmd_buffer->state.framebuffer; - const struct anv_depth_stencil_view *view; + const struct anv_depth_stencil_view *view = NULL; cmd_buffer->state.subpass = subpass; @@ -544,34 +541,59 @@ gen7_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer, fb->attachments[subpass->depth_stencil_attachment]; assert(aview->attachment_type == ANV_ATTACHMENT_VIEW_TYPE_DEPTH_STENCIL); view = (const struct anv_depth_stencil_view *)aview; - } else { - view = &null_view; } - anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_DEPTH_BUFFER, - .SurfaceType = SURFTYPE_2D, - .DepthWriteEnable = view->depth_stride > 0, - .StencilWriteEnable = view->stencil_stride > 0, - .HierarchicalDepthBufferEnable = false, - .SurfaceFormat = view->depth_format, - .SurfacePitch = view->depth_stride > 0 ? view->depth_stride - 1 : 0, - .SurfaceBaseAddress = { view->bo, view->depth_offset }, - .Height = cmd_buffer->state.framebuffer->height - 1, - .Width = cmd_buffer->state.framebuffer->width - 1, - .LOD = 0, - .Depth = 1 - 1, - .MinimumArrayElement = 0, - .DepthBufferObjectControlState = GEN7_MOCS, - .RenderTargetViewExtent = 1 - 1); + if (view) { + anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_DEPTH_BUFFER, + .SurfaceType = SURFTYPE_2D, + .DepthWriteEnable = view->depth_stride > 0, + .StencilWriteEnable = view->stencil_stride > 0, + .HierarchicalDepthBufferEnable = false, + .SurfaceFormat = view->depth_format, + .SurfacePitch = view->depth_stride > 0 ? view->depth_stride - 1 : 0, + .SurfaceBaseAddress = { view->bo, view->depth_offset }, + .Height = fb->height - 1, + .Width = fb->width - 1, + .LOD = 0, + .Depth = 1 - 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: + * + * If a null depth buffer is bound, the driver must instead bind depth as: + * 3DSTATE_DEPTH.SurfaceType = SURFTYPE_2D + * 3DSTATE_DEPTH.Width = 1 + * 3DSTATE_DEPTH.Height = 1 + * 3DSTATE_DEPTH.SuraceFormat = D16_UNORM + * 3DSTATE_DEPTH.SurfaceBaseAddress = 0 + * 3DSTATE_DEPTH.HierarchicalDepthBufferEnable = 0 + * 3DSTATE_WM_DEPTH_STENCIL.DepthTestEnable = 0 + * 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. + */ + anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_DEPTH_BUFFER, + .SurfaceType = SURFTYPE_2D, + .SurfaceFormat = D16_UNORM, + .Width = fb->width - 1, + .Height = fb->height - 1); + + /* Disable the stencil buffer. */ + anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_STENCIL_BUFFER); + } /* Disable hierarchial depth buffers. */ anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_HIER_DEPTH_BUFFER); - 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 }); - /* Clear the clear params. */ anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_CLEAR_PARAMS); } diff --git a/src/vulkan/gen8_cmd_buffer.c b/src/vulkan/gen8_cmd_buffer.c index 37a53c00156..57f061b9e8f 100644 --- a/src/vulkan/gen8_cmd_buffer.c +++ b/src/vulkan/gen8_cmd_buffer.c @@ -460,50 +460,72 @@ gen8_cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer) { struct anv_subpass *subpass = cmd_buffer->state.subpass; struct anv_framebuffer *fb = cmd_buffer->state.framebuffer; - const struct anv_depth_stencil_view *view; - - static const struct anv_depth_stencil_view null_view = - { .depth_format = D16_UNORM, .depth_stride = 0, .stencil_stride = 0 }; + const struct anv_depth_stencil_view *view = NULL; if (subpass->depth_stencil_attachment != VK_ATTACHMENT_UNUSED) { const struct anv_attachment_view *aview = fb->attachments[subpass->depth_stencil_attachment]; assert(aview->attachment_type == ANV_ATTACHMENT_VIEW_TYPE_DEPTH_STENCIL); view = (const struct anv_depth_stencil_view *)aview; - } else { - view = &null_view; } /* FIXME: Implement the PMA stall W/A */ /* FIXME: Width and Height are wrong */ - anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DEPTH_BUFFER, - .SurfaceType = SURFTYPE_2D, - .DepthWriteEnable = view->depth_stride > 0, - .StencilWriteEnable = view->stencil_stride > 0, - .HierarchicalDepthBufferEnable = false, - .SurfaceFormat = view->depth_format, - .SurfacePitch = view->depth_stride > 0 ? view->depth_stride - 1 : 0, - .SurfaceBaseAddress = { view->bo, view->depth_offset }, - .Height = cmd_buffer->state.framebuffer->height - 1, - .Width = cmd_buffer->state.framebuffer->width - 1, - .LOD = 0, - .Depth = 1 - 1, - .MinimumArrayElement = 0, - .DepthBufferObjectControlState = GEN8_MOCS, - .RenderTargetViewExtent = 1 - 1, - .SurfaceQPitch = view->depth_qpitch >> 2); + if (view) { + anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DEPTH_BUFFER, + .SurfaceType = SURFTYPE_2D, + .DepthWriteEnable = view->depth_stride > 0, + .StencilWriteEnable = view->stencil_stride > 0, + .HierarchicalDepthBufferEnable = false, + .SurfaceFormat = view->depth_format, + .SurfacePitch = view->depth_stride > 0 ? view->depth_stride - 1 : 0, + .SurfaceBaseAddress = { view->bo, view->depth_offset }, + .Height = fb->height - 1, + .Width = fb->width - 1, + .LOD = 0, + .Depth = 1 - 1, + .MinimumArrayElement = 0, + .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: + * + * If a null depth buffer is bound, the driver must instead bind depth as: + * 3DSTATE_DEPTH.SurfaceType = SURFTYPE_2D + * 3DSTATE_DEPTH.Width = 1 + * 3DSTATE_DEPTH.Height = 1 + * 3DSTATE_DEPTH.SuraceFormat = D16_UNORM + * 3DSTATE_DEPTH.SurfaceBaseAddress = 0 + * 3DSTATE_DEPTH.HierarchicalDepthBufferEnable = 0 + * 3DSTATE_WM_DEPTH_STENCIL.DepthTestEnable = 0 + * 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. + */ + anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DEPTH_BUFFER, + .SurfaceType = SURFTYPE_2D, + .SurfaceFormat = D16_UNORM, + .Width = fb->width - 1, + .Height = fb->height - 1); + + /* Disable the stencil buffer. */ + anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_STENCIL_BUFFER); + } /* Disable hierarchial depth buffers. */ anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_HIER_DEPTH_BUFFER); - 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); - /* Clear the clear params. */ anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_CLEAR_PARAMS); }