From b2ee317e24d9d236d0050b2a6188df379e913c45 Mon Sep 17 00:00:00 2001 From: Chad Versace Date: Fri, 28 Aug 2015 07:44:32 -0700 Subject: [PATCH] vk: Fix format of anv_depth_stencil_view 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 | 30 ++++++++++++++++++++-------- src/vulkan/anv_private.h | 1 + src/vulkan/gen7_cmd_buffer.c | 34 ++++++++++++++++++++------------ src/vulkan/gen8_cmd_buffer.c | 38 ++++++++++++++++++++++-------------- 4 files changed, 67 insertions(+), 36 deletions(-) diff --git a/src/vulkan/anv_image.c b/src/vulkan/anv_image.c index 198f4a40212..6ab541e5bce 100644 --- a/src/vulkan/anv_image.c +++ b/src/vulkan/anv_image.c @@ -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 * diff --git a/src/vulkan/anv_private.h b/src/vulkan/anv_private.h index 2d037b4cbb3..594b4fedc6c 100644 --- a/src/vulkan/anv_private.h +++ b/src/vulkan/anv_private.h @@ -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; diff --git a/src/vulkan/gen7_cmd_buffer.c b/src/vulkan/gen7_cmd_buffer.c index d9644e2a06a..1028b6dae22 100644 --- a/src/vulkan/gen7_cmd_buffer.c +++ b/src/vulkan/gen7_cmd_buffer.c @@ -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); } diff --git a/src/vulkan/gen8_cmd_buffer.c b/src/vulkan/gen8_cmd_buffer.c index 57f061b9e8f..0ec0f666ae0 100644 --- a/src/vulkan/gen8_cmd_buffer.c +++ b/src/vulkan/gen8_cmd_buffer.c @@ -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); } -- 2.30.2