anv: Add initial support for cube maps
[mesa.git] / src / vulkan / gen8_state.c
index 092e1ae78227e4bb92a5a48a20063ef9bc86ae81..aa57073c3e842f756bb55bea33c5b6df19da5621 100644 (file)
 #include "gen8_pack.h"
 #include "gen9_pack.h"
 
+static const uint8_t
+anv_surftype(const struct anv_image *image, VkImageViewType view_type)
+{
+   switch (view_type) {
+   default:
+      unreachable("bad VkImageViewType");
+   case VK_IMAGE_VIEW_TYPE_1D:
+   case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
+      assert(image->type == VK_IMAGE_TYPE_1D);
+      return SURFTYPE_1D;
+   case VK_IMAGE_VIEW_TYPE_CUBE:
+   case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
+      assert(image->type == VK_IMAGE_TYPE_2D);
+      return SURFTYPE_CUBE;
+   case VK_IMAGE_VIEW_TYPE_2D:
+   case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
+      assert(image->type == VK_IMAGE_TYPE_2D);
+      return SURFTYPE_2D;
+   case VK_IMAGE_VIEW_TYPE_3D:
+      assert(image->type == VK_IMAGE_TYPE_3D);
+      return SURFTYPE_3D;
+   }
+}
+
 void
 genX(fill_buffer_surface_state)(void *state, const struct anv_format *format,
                                 uint32_t offset, uint32_t range, uint32_t stride)
@@ -105,6 +129,41 @@ vk_to_gen_swizzle(VkComponentSwizzle swizzle, VkComponentSwizzle component)
       return vk_to_gen_swizzle_map[swizzle];
 }
 
+/**
+ * Get the values to pack into RENDER_SUFFACE_STATE.SurfaceHorizontalAlignment
+ * and SurfaceVerticalAlignment.
+ */
+static void
+get_halign_valign(const struct isl_surf *surf, uint32_t *halign, uint32_t *valign)
+{
+   #if ANV_GENx10 >= 90
+      /* In Skylake, RENDER_SUFFACE_STATE.SurfaceVerticalAlignment is in units
+       * of surface elements (not pixels nor samples). For compressed formats,
+       * a "surface element" is defined as a compression block.  For example,
+       * if SurfaceVerticalAlignment is VALIGN_4 and SurfaceFormat is an ETC2
+       * format (ETC2 has a block height of 4), then the vertical alignment is
+       * 4 compression blocks or, equivalently, 16 pixels.
+       */
+      struct isl_extent3d image_align_el
+         = isl_surf_get_image_alignment_el(surf);
+
+      *halign = anv_halign[image_align_el.width];
+      *valign = anv_valign[image_align_el.height];
+   #else
+      /* Pre-Skylake, RENDER_SUFFACE_STATE.SurfaceVerticalAlignment is in
+       * units of surface samples.  For example, if SurfaceVerticalAlignment
+       * is VALIGN_4 and the surface is singlesampled, then for any surface
+       * format (compressed or not) the vertical alignment is
+       * 4 pixels.
+       */
+      struct isl_extent3d image_align_sa
+         = isl_surf_get_image_alignment_sa(surf);
+
+      *halign = anv_halign[image_align_sa.width];
+      *valign = anv_valign[image_align_sa.height];
+   #endif
+}
+
 void
 genX(image_view_init)(struct anv_image_view *iview,
                       struct anv_device *device,
@@ -145,7 +204,7 @@ genX(image_view_init)(struct anv_image_view *iview,
        *    example, if Minimum Array Element is set to 1024 on a 2D surface,
        *    the range of this field is reduced to [0,1023].
        */
-      depth = range->arraySize;
+      depth = range->layerCount;
 
       /* From the Broadwell PRM >> RENDER_SURFACE_STATE::RenderTargetViewExtent:
        *
@@ -177,19 +236,22 @@ genX(image_view_init)(struct anv_image_view *iview,
    static const uint8_t isl_to_gen_tiling[] = {
       [ISL_TILING_LINEAR]  = LINEAR,
       [ISL_TILING_X]       = XMAJOR,
-      [ISL_TILING_Y      = YMAJOR,
+      [ISL_TILING_Y0]      = YMAJOR,
       [ISL_TILING_Yf]      = YMAJOR,
       [ISL_TILING_Ys]      = YMAJOR,
       [ISL_TILING_W]       = WMAJOR,
    };
 
+   uint32_t halign, valign;
+   get_halign_valign(&surface->isl, &halign, &valign);
+
    struct GENX(RENDER_SURFACE_STATE) surface_state = {
-      .SurfaceType = image->surface_type,
+      .SurfaceType = anv_surftype(image, pCreateInfo->viewType),
       .SurfaceArray = image->array_size > 1,
       .SurfaceFormat = format_info->surface_format,
-      .SurfaceVerticalAlignment = anv_valign[surface->v_align],
-      .SurfaceHorizontalAlignment = anv_halign[surface->h_align],
-      .TileMode = isl_to_gen_tiling[surface->tiling],
+      .SurfaceVerticalAlignment = valign,
+      .SurfaceHorizontalAlignment = halign,
+      .TileMode = isl_to_gen_tiling[surface->isl.tiling],
       .VerticalLineStride = 0,
       .VerticalLineStrideOffset = 0,
       .SamplerL2BypassModeDisable = true,
@@ -202,11 +264,11 @@ genX(image_view_init)(struct anv_image_view *iview,
        */
       .BaseMipLevel = 0.0,
 
-      .SurfaceQPitch = surface->qpitch >> 2,
+      .SurfaceQPitch = isl_surf_get_array_pitch_el_rows(&surface->isl) >> 2,
       .Height = image->extent.height - 1,
       .Width = image->extent.width - 1,
       .Depth = depth - 1,
-      .SurfacePitch = surface->stride - 1,
+      .SurfacePitch = surface->isl.row_pitch - 1,
       .RenderTargetViewExtent = rt_view_extent - 1,
       .MinimumArrayElement = range->baseArrayLayer,
       .NumberofMultisamples = MULTISAMPLECOUNT_1,
@@ -242,10 +304,12 @@ genX(image_view_init)(struct anv_image_view *iview,
        * sampler engine is [SurfaceMinLOD, SurfaceMinLOD + MIPCountLOD].
        */
       surface_state.SurfaceMinLOD = range->baseMipLevel;
-      surface_state.MIPCountLOD = range->mipLevels - 1;
+      surface_state.MIPCountLOD = range->levelCount - 1;
 
       GENX(RENDER_SURFACE_STATE_pack)(NULL, iview->nonrt_surface_state.map,
                                       &surface_state);
+      if (!device->info.has_llc)
+         anv_state_clflush(iview->nonrt_surface_state);
    }
 
    if (image->needs_color_rt_surface_state) {
@@ -263,12 +327,30 @@ genX(image_view_init)(struct anv_image_view *iview,
 
       GENX(RENDER_SURFACE_STATE_pack)(NULL, iview->color_rt_surface_state.map,
                                       &surface_state);
+      if (!device->info.has_llc)
+         anv_state_clflush(iview->color_rt_surface_state);
+   }
+
+   if (image->needs_storage_surface_state) {
+      iview->storage_surface_state =
+         alloc_surface_state(device, cmd_buffer);
+
+      surface_state.SurfaceFormat =
+         isl_lower_storage_image_format(&device->isl_dev,
+                                        format_info->surface_format);
+
+      surface_state.SurfaceMinLOD = range->baseMipLevel;
+      surface_state.MIPCountLOD = range->levelCount - 1;
+
+      GENX(RENDER_SURFACE_STATE_pack)(NULL, iview->storage_surface_state.map,
+                                      &surface_state);
    }
 }
 
 VkResult genX(CreateSampler)(
     VkDevice                                    _device,
     const VkSamplerCreateInfo*                  pCreateInfo,
+    const VkAllocationCallbacks*                pAllocator,
     VkSampler*                                  pSampler)
 {
    ANV_FROM_HANDLE(anv_device, device, _device);
@@ -277,8 +359,8 @@ VkResult genX(CreateSampler)(
 
    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
 
-   sampler = anv_device_alloc(device, sizeof(*sampler), 8,
-                              VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   sampler = anv_alloc2(&device->alloc, pAllocator, sizeof(*sampler), 8,
+                        VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
    if (!sampler)
       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);