vk: Set up depth and stencil buffers
authorKristian Høgsberg <kristian.h.kristensen@intel.com>
Sat, 23 May 2015 05:59:12 +0000 (22:59 -0700)
committerKristian Høgsberg <kristian.h.kristensen@intel.com>
Tue, 26 May 2015 03:20:31 +0000 (20:20 -0700)
src/vulkan/device.c
src/vulkan/formats.c
src/vulkan/image.c
src/vulkan/private.h

index 4301739022dfc14727a4cd85f93a96d792c8534d..0c35d503ab089c942770771c43493e37af21c2c7 100644 (file)
@@ -2260,15 +2260,6 @@ VkResult anv_BeginCommandBuffer(
    anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_SBE_SWIZ);
    anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_AA_LINE_PARAMETERS);
 
-   /* Hardcoded state: */
-   anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DEPTH_BUFFER,
-                  .SurfaceType = SURFTYPE_2D,
-                  .Width = 1,
-                  .Height = 1,
-                  .SurfaceFormat = D16_UNORM,
-                  .SurfaceBaseAddress = { NULL, 0 },
-                  .HierarchicalDepthBufferEnable = 0);
-   
    anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_WM_DEPTH_STENCIL,
                   .DepthTestEnable = false,
                   .DepthBufferWriteEnable = false);
@@ -3118,6 +3109,9 @@ VkResult anv_CreateFramebuffer(
    struct anv_device *device = (struct anv_device *) _device;
    struct anv_framebuffer *framebuffer;
 
+   static const struct anv_depth_stencil_view null_view =
+      { .depth_format = D16_UNORM, .depth_stride = 0, .stencil_stride = 0 };
+
    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
 
    framebuffer = anv_device_alloc(device, sizeof(*framebuffer), 8,
@@ -3136,6 +3130,8 @@ VkResult anv_CreateFramebuffer(
    if (pCreateInfo->pDepthStencilAttachment) {
       framebuffer->depth_stencil =
          (struct anv_depth_stencil_view *) pCreateInfo->pDepthStencilAttachment->view;
+   } else {
+      framebuffer->depth_stencil = &null_view;
    }
 
    framebuffer->sample_count = pCreateInfo->sampleCount;
@@ -3211,7 +3207,7 @@ anv_cmd_buffer_fill_render_targets(struct anv_cmd_buffer *cmd_buffer)
    struct anv_bindings *bindings = cmd_buffer->bindings;
 
    for (uint32_t i = 0; i < framebuffer->color_attachment_count; i++) {
-      struct anv_surface_view *view = framebuffer->color_attachments[i];
+      const struct anv_surface_view *view = framebuffer->color_attachments[i];
 
       struct anv_state state =
          anv_cmd_buffer_alloc_surface_state(cmd_buffer, 64, 64);
@@ -3228,6 +3224,46 @@ anv_cmd_buffer_fill_render_targets(struct anv_cmd_buffer *cmd_buffer)
    cmd_buffer->dirty |= ANV_CMD_BUFFER_DESCRIPTOR_SET_DIRTY;
 }
 
+static void
+anv_cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer,
+                                  struct anv_render_pass *pass)
+{
+   const struct anv_depth_stencil_view *view =
+      cmd_buffer->framebuffer->depth_stencil;
+
+   /* FIXME: Implement the PMA stall W/A */
+
+   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 = pass->render_area.extent.height - 1,
+                  .Width = pass->render_area.extent.width - 1,
+                  .LOD = 0,
+                  .Depth = 1 - 1,
+                  .MinimumArrayElement = 0,
+                  .DepthBufferObjectControlState = GEN8_MOCS,
+                  .RenderTargetViewExtent = 1 - 1,
+                  .SurfaceQPitch = 0);
+
+   /* 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 = 0);
+
+   /* Clear the clear params. */
+   anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_CLEAR_PARAMS);
+}
+
 void anv_CmdBeginRenderPass(
     VkCmdBuffer                                 cmdBuffer,
     const VkRenderPassBegin*                    pRenderPassBegin)
@@ -3251,6 +3287,8 @@ void anv_CmdBeginRenderPass(
 
    anv_cmd_buffer_fill_render_targets(cmd_buffer);
 
+   anv_cmd_buffer_emit_depth_stencil(cmd_buffer, pass);
+
    anv_cmd_buffer_clear(cmd_buffer, pass);
 }
 
index 13ae1ed75389d41987e870f39d0ddff9799d801f..66208f23ea91e80d6f1f73123806d6342bc4f308 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "private.h"
 
-#define UNSUPPORTED ~0U
+#define UNSUPPORTED 0xffff
 
 static const struct anv_format anv_formats[] = {
    [VK_FORMAT_UNDEFINED] = { .format = RAW, .cpp = 1, .channels = 1 },
@@ -116,13 +116,17 @@ static const struct anv_format anv_formats[] = {
    [VK_FORMAT_R11G11B10_UFLOAT] = { .format = R11G11B10_FLOAT, .cpp = 4, .channels = 3 },
    [VK_FORMAT_R9G9B9E5_UFLOAT] = { .format = R9G9B9E5_SHAREDEXP, .cpp = 4, .channels = 3 },
 
-   [VK_FORMAT_D16_UNORM] = { .format = UNSUPPORTED },
-   [VK_FORMAT_D24_UNORM] = { .format = UNSUPPORTED },
-   [VK_FORMAT_D32_SFLOAT] = { .format = UNSUPPORTED },
-   [VK_FORMAT_S8_UINT] = { .format = UNSUPPORTED },
-   [VK_FORMAT_D16_UNORM_S8_UINT] = { .format = UNSUPPORTED },
-   [VK_FORMAT_D24_UNORM_S8_UINT] = { .format = UNSUPPORTED },
-   [VK_FORMAT_D32_SFLOAT_S8_UINT] = { .format = UNSUPPORTED },
+   /* For depth/stencil formats, the .format and .cpp fields describe the
+    * depth format. The field .has_stencil indicates whether or not there's a
+    * stencil buffer.
+    */
+   [VK_FORMAT_D16_UNORM] = { .format = D16_UNORM, .cpp = 2, .channels = 1 },
+   [VK_FORMAT_D24_UNORM] = { .format = D24_UNORM_X8_UINT, .cpp = 4, .channels = 1 },
+   [VK_FORMAT_D32_SFLOAT] = { .format = D32_FLOAT, .cpp = 4, .channels = 1 },
+   [VK_FORMAT_S8_UINT] = { .format = UNSUPPORTED, .cpp = 0, .channels = 1, .has_stencil = true },
+   [VK_FORMAT_D16_UNORM_S8_UINT] = { .format = D16_UNORM, .cpp = 2, .channels = 2, .has_stencil = true },
+   [VK_FORMAT_D24_UNORM_S8_UINT] = { .format = D24_UNORM_X8_UINT, .cpp = 4, .channels = 2, .has_stencil = true },
+   [VK_FORMAT_D32_SFLOAT_S8_UINT] = { .format = D32_FLOAT, .cpp = 4, .channels = 2, .has_stencil = true },
 
    [VK_FORMAT_BC1_RGB_UNORM] = { .format = UNSUPPORTED },
    [VK_FORMAT_BC1_RGB_SRGB] = { .format = UNSUPPORTED },
index 109a248b9a03f7cba186d4ee66ca30d83339ec54..99542f1b538c5ec918f3b6596ea60639011a3058 100644 (file)
@@ -49,8 +49,9 @@ VkResult anv_image_create(
 {
    struct anv_device *device = (struct anv_device *) _device;
    struct anv_image *image;
-   const struct anv_format *format;
+   const struct anv_format *info;
    int32_t aligned_height;
+   uint32_t stencil_size;
 
    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
 
@@ -93,13 +94,32 @@ VkResult anv_image_create(
       image->alignment = 4096;
    }
 
-   format = anv_format_for_vk_format(pCreateInfo->format);
-   assert(format->cpp > 0);
-   image->stride = ALIGN_I32(image->extent.width * format->cpp,
-                             tile_mode_info[image->tile_mode].tile_width);
-   aligned_height = ALIGN_I32(image->extent.height,
-                              tile_mode_info[image->tile_mode].tile_height);
-   image->size = image->stride * aligned_height;
+   info = anv_format_for_vk_format(pCreateInfo->format);
+   assert(info->cpp > 0 || info->has_stencil);
+
+   if (info->cpp > 0) {
+      image->stride = ALIGN_I32(image->extent.width * info->cpp,
+                                tile_mode_info[image->tile_mode].tile_width);
+      aligned_height = ALIGN_I32(image->extent.height,
+                                 tile_mode_info[image->tile_mode].tile_height);
+      image->size = image->stride * aligned_height;
+   } else {
+      image->size = 0;
+      image->stride = 0;
+   }
+
+   if (info->has_stencil) {
+      image->stencil_offset = ALIGN_U32(image->size, 4096);
+      image->stencil_stride = ALIGN_I32(image->extent.width,
+                                        tile_mode_info[WMAJOR].tile_width);
+      aligned_height = ALIGN_I32(image->extent.height,
+                                 tile_mode_info[WMAJOR].tile_height);
+      stencil_size = image->stencil_stride * aligned_height;
+      image->size = image->stencil_offset + stencil_size;
+   } else {
+      image->stencil_offset = 0;
+      image->stencil_stride = 0;
+   }
 
    *pImage = (VkImage) image;
 
@@ -125,14 +145,13 @@ VkResult anv_GetImageSubresourceInfo(
    stub_return(VK_UNSUPPORTED);
 }
 
-// Image view functions
-
 static struct anv_state
 create_surface_state(struct anv_device *device,
-                     struct anv_image *image, const struct anv_format *format,
-                     struct anv_cmd_buffer *cmd_buffer)
+                     struct anv_image *image, uint32_t format, uint32_t tile_mode,
+                     uint32_t offset, struct anv_cmd_buffer *cmd_buffer)
 {
    struct anv_state state;
+
    if (cmd_buffer)
       state = anv_state_stream_alloc(&cmd_buffer->surface_state_stream, 64, 64);
    else
@@ -141,10 +160,10 @@ create_surface_state(struct anv_device *device,
    struct GEN8_RENDER_SURFACE_STATE surface_state = {
       .SurfaceType = SURFTYPE_2D,
       .SurfaceArray = false,
-      .SurfaceFormat = format->format,
+      .SurfaceFormat = format,
       .SurfaceVerticalAlignment = VALIGN4,
       .SurfaceHorizontalAlignment = HALIGN4,
-      .TileMode = image->tile_mode,
+      .TileMode = tile_mode,
       .VerticalLineStride = 0,
       .VerticalLineStrideOffset = 0,
       .SamplerL2BypassModeDisable = true,
@@ -172,8 +191,7 @@ create_surface_state(struct anv_device *device,
       .ShaderChannelSelectBlue = SCS_BLUE,
       .ShaderChannelSelectAlpha = SCS_ALPHA,
       .ResourceMinLOD = 0,
-      /* FIXME: We assume that the image must be bound at this time. */
-      .SurfaceBaseAddress = { NULL, image->offset },
+      .SurfaceBaseAddress = { NULL, offset },
    };
 
    GEN8_RENDER_SURFACE_STATE_pack(NULL, state.map, &surface_state);
@@ -188,17 +206,33 @@ anv_image_view_init(struct anv_surface_view *view,
                     struct anv_cmd_buffer *cmd_buffer)
 {
    struct anv_image *image = (struct anv_image *) pCreateInfo->image;
-   const struct anv_format *format =
+   const struct anv_format *info =
       anv_format_for_vk_format(pCreateInfo->format);
+   uint32_t tile_mode, format;
 
    view->bo = image->bo;
-   view->offset = image->offset;
-   view->surface_state = create_surface_state(device, image, format,
-                                              cmd_buffer);
-   view->format = pCreateInfo->format;
+   switch (pCreateInfo->subresourceRange.aspect) {
+   case VK_IMAGE_ASPECT_STENCIL:
+      /* FIXME: How is stencil texturing formed? */
+      view->offset = image->offset + image->stencil_offset;
+      tile_mode = WMAJOR;
+      format = R8_UINT;
+      break;
+   case VK_IMAGE_ASPECT_DEPTH:
+   case VK_IMAGE_ASPECT_COLOR:
+      view->offset = image->offset;
+      tile_mode = image->tile_mode;
+      format = info->format;
+      break;
+   default:
+      assert(0);
+      break;
+   }
 
    /* TODO: Miplevels */
    view->extent = image->extent;
+   view->surface_state =
+      create_surface_state(device, image, format, tile_mode, view->offset, cmd_buffer);
 }
 
 VkResult anv_CreateImageView(
@@ -235,10 +269,11 @@ anv_color_attachment_view_init(struct anv_surface_view *view,
 
    view->bo = image->bo;
    view->offset = image->offset;
-   view->surface_state = create_surface_state(device, image, format,
-                                              cmd_buffer);
    view->extent = image->extent;
    view->format = pCreateInfo->format;
+   view->surface_state =
+      create_surface_state(device, image,
+                           format->format, image->tile_mode, view->offset, cmd_buffer);
 }
 
 VkResult anv_CreateColorAttachmentView(
@@ -264,9 +299,33 @@ VkResult anv_CreateColorAttachmentView(
 }
 
 VkResult anv_CreateDepthStencilView(
-    VkDevice                                    device,
+    VkDevice                                    _device,
     const VkDepthStencilViewCreateInfo*         pCreateInfo,
     VkDepthStencilView*                         pView)
 {
-   stub_return(VK_UNSUPPORTED);
+   struct anv_device *device = (struct anv_device *) _device;
+   struct anv_depth_stencil_view *view;
+   struct anv_image *image = (struct anv_image *) pCreateInfo->image;
+   const struct anv_format *format =
+      anv_format_for_vk_format(image->format);
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO);
+
+   view = anv_device_alloc(device, sizeof(*view), 8,
+                           VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (view == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   view->bo = image->bo;
+
+   view->depth_stride = image->stride;
+   view->depth_offset = image->offset;
+   view->depth_format = format->format;
+
+   view->stencil_stride = image->stencil_stride;
+   view->stencil_offset = image->offset + image->stencil_offset;
+
+   *pView = (VkDepthStencilView) view;
+
+   return VK_SUCCESS;
 }
index e3e5bd52a64b65e754d2df578f43ae76789ea37c..f75e03c85984d54d61feb4b34ef0f5eb2a95f406 100644 (file)
@@ -659,9 +659,10 @@ int anv_compiler_run(struct anv_compiler *compiler, struct anv_pipeline *pipelin
 void anv_compiler_free(struct anv_pipeline *pipeline);
 
 struct anv_format {
-   uint32_t                                     format;
-   uint32_t                                     cpp;
-   uint32_t                                     channels;
+   uint16_t                                     format;
+   uint8_t                                      cpp;
+   uint8_t                                      channels;
+   bool                                         has_stencil;
 };
 
 const struct anv_format *
@@ -669,12 +670,15 @@ anv_format_for_vk_format(VkFormat format);
 
 struct anv_image {
    VkImageType                                  type;
-   VkFormat                                     format;
    VkExtent3D                                   extent;
+   VkFormat                                     format;
    uint32_t                                     tile_mode;
    VkDeviceSize                                 size;
    uint32_t                                     alignment;
-   int32_t                                      stride;
+   uint32_t                                     stride;
+
+   uint32_t                                     stencil_offset;
+   uint32_t                                     stencil_stride;
 
    /* Set when bound */
    struct anv_bo *                              bo;
@@ -715,13 +719,21 @@ struct anv_sampler {
 };
 
 struct anv_depth_stencil_view {
+   struct anv_bo *                              bo;
+
+   uint32_t                                     depth_offset;
+   uint32_t                                     depth_stride;
+   uint32_t                                     depth_format;
+
+   uint32_t                                     stencil_offset;
+   uint32_t                                     stencil_stride;
 };
 
 struct anv_framebuffer {
    struct anv_object                            base;
    uint32_t                                     color_attachment_count;
-   struct anv_surface_view *                    color_attachments[MAX_RTS];
-   struct anv_depth_stencil_view *              depth_stencil;
+   const struct anv_surface_view *              color_attachments[MAX_RTS];
+   const struct anv_depth_stencil_view *        depth_stencil;
 
    uint32_t                                     sample_count;
    uint32_t                                     width;