anv: Add initial support for cube maps
[mesa.git] / src / vulkan / gen8_state.c
index d9438127f2a845b95c600d61cc7f92e44dc55855..aa57073c3e842f756bb55bea33c5b6df19da5621 100644 (file)
 
 #include "anv_private.h"
 
+#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
-gen8_fill_buffer_surface_state(void *state, const struct anv_format *format,
-                               uint32_t offset, uint32_t range)
+genX(fill_buffer_surface_state)(void *state, const struct anv_format *format,
+                                uint32_t offset, uint32_t range, uint32_t stride)
 {
-   /* This assumes RGBA float format. */
-   uint32_t stride = 4;
    uint32_t num_elements = range / stride;
 
-   struct GEN8_RENDER_SURFACE_STATE surface_state = {
+   struct GENX(RENDER_SURFACE_STATE) surface_state = {
       .SurfaceType = SURFTYPE_BUFFER,
       .SurfaceArray = false,
       .SurfaceFormat = format->surface_format,
@@ -46,10 +71,10 @@ gen8_fill_buffer_surface_state(void *state, const struct anv_format *format,
       .TileMode = LINEAR,
       .SamplerL2BypassModeDisable = true,
       .RenderCacheReadWriteMode = WriteOnlyCache,
-      .MemoryObjectControlState = GEN8_MOCS,
-      .Height = (num_elements >> 7) & 0x3fff,
-      .Width = num_elements & 0x7f,
-      .Depth = (num_elements >> 21) & 0x3f,
+      .MemoryObjectControlState = GENX(MOCS),
+      .Height = ((num_elements - 1) >> 7) & 0x3fff,
+      .Width = (num_elements - 1) & 0x7f,
+      .Depth = ((num_elements - 1) >> 21) & 0x3f,
       .SurfacePitch = stride - 1,
       .NumberofMultisamples = MULTISAMPLECOUNT_1,
       .ShaderChannelSelectRed = SCS_RED,
@@ -60,31 +85,7 @@ gen8_fill_buffer_surface_state(void *state, const struct anv_format *format,
       .SurfaceBaseAddress = { NULL, offset },
    };
 
-   GEN8_RENDER_SURFACE_STATE_pack(NULL, state, &surface_state);
-}
-
-VkResult gen8_CreateBufferView(
-    VkDevice                                    _device,
-    const VkBufferViewCreateInfo*               pCreateInfo,
-    VkBufferView*                               pView)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   struct anv_buffer_view *bview;
-   VkResult result;
-
-   result = anv_buffer_view_create(device, pCreateInfo, &bview);
-   if (result != VK_SUCCESS)
-      return result;
-
-   const struct anv_format *format =
-      anv_format_for_vk_format(pCreateInfo->format);
-
-   gen8_fill_buffer_surface_state(bview->surface_state.map, format,
-                                  bview->offset, pCreateInfo->range);
-
-   *pView = anv_buffer_view_to_handle(bview);
-
-   return VK_SUCCESS;
+   GENX(RENDER_SURFACE_STATE_pack)(NULL, state, &surface_state);
 }
 
 static const uint8_t anv_halign[] = {
@@ -100,8 +101,8 @@ static const uint8_t anv_valign[] = {
 };
 
 static struct anv_state
-gen8_alloc_surface_state(struct anv_device *device,
-                         struct anv_cmd_buffer *cmd_buffer)
+alloc_surface_state(struct anv_device *device,
+                    struct anv_cmd_buffer *cmd_buffer)
 {
       if (cmd_buffer) {
          return anv_cmd_buffer_alloc_surface_state(cmd_buffer);
@@ -110,11 +111,64 @@ gen8_alloc_surface_state(struct anv_device *device,
       }
 }
 
+static const uint32_t vk_to_gen_swizzle_map[] = {
+   [VK_COMPONENT_SWIZZLE_ZERO]                 = SCS_ZERO,
+   [VK_COMPONENT_SWIZZLE_ONE]                  = SCS_ONE,
+   [VK_COMPONENT_SWIZZLE_R]                    = SCS_RED,
+   [VK_COMPONENT_SWIZZLE_G]                    = SCS_GREEN,
+   [VK_COMPONENT_SWIZZLE_B]                    = SCS_BLUE,
+   [VK_COMPONENT_SWIZZLE_A]                    = SCS_ALPHA
+};
+
+static inline uint32_t
+vk_to_gen_swizzle(VkComponentSwizzle swizzle, VkComponentSwizzle component)
+{
+   if (swizzle == VK_COMPONENT_SWIZZLE_IDENTITY)
+      return vk_to_gen_swizzle_map[component];
+   else
+      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
-gen8_image_view_init(struct anv_image_view *iview,
-                     struct anv_device *device,
-                     const VkImageViewCreateInfo* pCreateInfo,
-                     struct anv_cmd_buffer *cmd_buffer)
+genX(image_view_init)(struct anv_image_view *iview,
+                      struct anv_device *device,
+                      const VkImageViewCreateInfo* pCreateInfo,
+                      struct anv_cmd_buffer *cmd_buffer)
 {
    ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
 
@@ -150,7 +204,7 @@ gen8_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:
        *
@@ -179,27 +233,30 @@ gen8_image_view_init(struct anv_image_view *iview,
       unreachable(!"bad VkImageType");
    }
 
-   static const uint32_t vk_to_gen_swizzle[] = {
-      [VK_CHANNEL_SWIZZLE_ZERO]                 = SCS_ZERO,
-      [VK_CHANNEL_SWIZZLE_ONE]                  = SCS_ONE,
-      [VK_CHANNEL_SWIZZLE_R]                    = SCS_RED,
-      [VK_CHANNEL_SWIZZLE_G]                    = SCS_GREEN,
-      [VK_CHANNEL_SWIZZLE_B]                    = SCS_BLUE,
-      [VK_CHANNEL_SWIZZLE_A]                    = SCS_ALPHA
+   static const uint8_t isl_to_gen_tiling[] = {
+      [ISL_TILING_LINEAR]  = LINEAR,
+      [ISL_TILING_X]       = XMAJOR,
+      [ISL_TILING_Y0]      = YMAJOR,
+      [ISL_TILING_Yf]      = YMAJOR,
+      [ISL_TILING_Ys]      = YMAJOR,
+      [ISL_TILING_W]       = WMAJOR,
    };
 
-   struct GEN8_RENDER_SURFACE_STATE surface_state = {
-      .SurfaceType = image->surface_type,
+   uint32_t halign, valign;
+   get_halign_valign(&surface->isl, &halign, &valign);
+
+   struct GENX(RENDER_SURFACE_STATE) surface_state = {
+      .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 = surface->tile_mode,
+      .SurfaceVerticalAlignment = valign,
+      .SurfaceHorizontalAlignment = halign,
+      .TileMode = isl_to_gen_tiling[surface->isl.tiling],
       .VerticalLineStride = 0,
       .VerticalLineStrideOffset = 0,
       .SamplerL2BypassModeDisable = true,
       .RenderCacheReadWriteMode = WriteOnlyCache,
-      .MemoryObjectControlState = GEN8_MOCS,
+      .MemoryObjectControlState = GENX(MOCS),
 
       /* The driver sets BaseMipLevel in SAMPLER_STATE, not here in
        * RENDER_SURFACE_STATE. The Broadwell PRM says "it is illegal to have
@@ -207,11 +264,11 @@ gen8_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,
@@ -226,32 +283,38 @@ gen8_image_view_init(struct anv_image_view *iview,
       .GreenClearColor = 0,
       .BlueClearColor = 0,
       .AlphaClearColor = 0,
-      .ShaderChannelSelectRed = vk_to_gen_swizzle[pCreateInfo->channels.r],
-      .ShaderChannelSelectGreen = vk_to_gen_swizzle[pCreateInfo->channels.g],
-      .ShaderChannelSelectBlue = vk_to_gen_swizzle[pCreateInfo->channels.b],
-      .ShaderChannelSelectAlpha = vk_to_gen_swizzle[pCreateInfo->channels.a],
+      .ShaderChannelSelectRed = vk_to_gen_swizzle(pCreateInfo->components.r,
+                                                  VK_COMPONENT_SWIZZLE_R),
+      .ShaderChannelSelectGreen = vk_to_gen_swizzle(pCreateInfo->components.g,
+                                                    VK_COMPONENT_SWIZZLE_G),
+      .ShaderChannelSelectBlue = vk_to_gen_swizzle(pCreateInfo->components.b,
+                                                   VK_COMPONENT_SWIZZLE_B),
+      .ShaderChannelSelectAlpha = vk_to_gen_swizzle(pCreateInfo->components.a,
+                                                    VK_COMPONENT_SWIZZLE_A),
       .ResourceMinLOD = 0.0,
       .SurfaceBaseAddress = { NULL, iview->offset },
    };
 
    if (image->needs_nonrt_surface_state) {
       iview->nonrt_surface_state =
-         gen8_alloc_surface_state(device, cmd_buffer);
+         alloc_surface_state(device, cmd_buffer);
 
       /* For non render target surfaces, the hardware interprets field
        * MIPCount/LOD as MIPCount.  The range of levels accessible by the
        * sampler engine is [SurfaceMinLOD, SurfaceMinLOD + MIPCountLOD].
        */
       surface_state.SurfaceMinLOD = range->baseMipLevel;
-      surface_state.MIPCountLOD = range->mipLevels - 1;
+      surface_state.MIPCountLOD = range->levelCount - 1;
 
-      GEN8_RENDER_SURFACE_STATE_pack(NULL, iview->nonrt_surface_state.map,
-                                     &surface_state);
+      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) {
       iview->color_rt_surface_state =
-         gen8_alloc_surface_state(device, cmd_buffer);
+         alloc_surface_state(device, cmd_buffer);
 
       /* For render target surfaces, the hardware interprets field
        * MIPCount/LOD as LOD. The Broadwell PRM says:
@@ -262,14 +325,32 @@ gen8_image_view_init(struct anv_image_view *iview,
       surface_state.MIPCountLOD = range->baseMipLevel;
       surface_state.SurfaceMinLOD = 0;
 
-      GEN8_RENDER_SURFACE_STATE_pack(NULL, iview->color_rt_surface_state.map,
-                                     &surface_state);
+      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 gen8_CreateSampler(
+VkResult genX(CreateSampler)(
     VkDevice                                    _device,
     const VkSamplerCreateInfo*                  pCreateInfo,
+    const VkAllocationCallbacks*                pAllocator,
     VkSampler*                                  pSampler)
 {
    ANV_FROM_HANDLE(anv_device, device, _device);
@@ -278,38 +359,38 @@ VkResult gen8_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);
 
    static const uint32_t vk_to_gen_tex_filter[] = {
-      [VK_TEX_FILTER_NEAREST]                   = MAPFILTER_NEAREST,
-      [VK_TEX_FILTER_LINEAR]                    = MAPFILTER_LINEAR
+      [VK_FILTER_NEAREST]                       = MAPFILTER_NEAREST,
+      [VK_FILTER_LINEAR]                        = MAPFILTER_LINEAR
    };
 
    static const uint32_t vk_to_gen_mipmap_mode[] = {
-      [VK_TEX_MIPMAP_MODE_BASE]                 = MIPFILTER_NONE,
-      [VK_TEX_MIPMAP_MODE_NEAREST]              = MIPFILTER_NEAREST,
-      [VK_TEX_MIPMAP_MODE_LINEAR]               = MIPFILTER_LINEAR
+      [VK_SAMPLER_MIPMAP_MODE_BASE]             = MIPFILTER_NONE,
+      [VK_SAMPLER_MIPMAP_MODE_NEAREST]          = MIPFILTER_NEAREST,
+      [VK_SAMPLER_MIPMAP_MODE_LINEAR]           = MIPFILTER_LINEAR
    };
 
    static const uint32_t vk_to_gen_tex_address[] = {
-      [VK_TEX_ADDRESS_MODE_WRAP]                = TCM_WRAP,
-      [VK_TEX_ADDRESS_MODE_MIRROR]              = TCM_MIRROR,
-      [VK_TEX_ADDRESS_MODE_CLAMP]               = TCM_CLAMP,
-      [VK_TEX_ADDRESS_MODE_MIRROR_ONCE]         = TCM_MIRROR_ONCE,
-      [VK_TEX_ADDRESS_MODE_CLAMP_BORDER]        = TCM_CLAMP_BORDER,
+      [VK_SAMPLER_ADDRESS_MODE_REPEAT]          = TCM_WRAP,
+      [VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT] = TCM_MIRROR,
+      [VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE]   = TCM_CLAMP,
+      [VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE] = TCM_MIRROR_ONCE,
+      [VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER] = TCM_CLAMP_BORDER,
    };
 
    static const uint32_t vk_to_gen_compare_op[] = {
       [VK_COMPARE_OP_NEVER]                     = PREFILTEROPNEVER,
       [VK_COMPARE_OP_LESS]                      = PREFILTEROPLESS,
       [VK_COMPARE_OP_EQUAL]                     = PREFILTEROPEQUAL,
-      [VK_COMPARE_OP_LESS_EQUAL]                = PREFILTEROPLEQUAL,
+      [VK_COMPARE_OP_LESS_OR_EQUAL]             = PREFILTEROPLEQUAL,
       [VK_COMPARE_OP_GREATER]                   = PREFILTEROPGREATER,
       [VK_COMPARE_OP_NOT_EQUAL]                 = PREFILTEROPNOTEQUAL,
-      [VK_COMPARE_OP_GREATER_EQUAL]             = PREFILTEROPGEQUAL,
+      [VK_COMPARE_OP_GREATER_OR_EQUAL]          = PREFILTEROPGEQUAL,
       [VK_COMPARE_OP_ALWAYS]                    = PREFILTEROPALWAYS,
    };
 
@@ -323,18 +404,20 @@ VkResult gen8_CreateSampler(
       max_anisotropy = RATIO21;
    }
 
-   struct GEN8_SAMPLER_STATE sampler_state = {
+   struct GENX(SAMPLER_STATE) sampler_state = {
       .SamplerDisable = false,
       .TextureBorderColorMode = DX10OGL,
       .LODPreClampMode = 0,
+#if ANV_GEN == 8
       .BaseMipLevel = 0.0,
-      .MipModeFilter = vk_to_gen_mipmap_mode[pCreateInfo->mipMode],
+#endif
+      .MipModeFilter = vk_to_gen_mipmap_mode[pCreateInfo->mipmapMode],
       .MagModeFilter = mag_filter,
       .MinModeFilter = min_filter,
-      .TextureLODBias = pCreateInfo->mipLodBias * 256,
+      .TextureLODBias = anv_clamp_f(pCreateInfo->mipLodBias, -16, 15.996),
       .AnisotropicAlgorithm = EWAApproximation,
-      .MinLOD = pCreateInfo->minLod,
-      .MaxLOD = pCreateInfo->maxLod,
+      .MinLOD = anv_clamp_f(pCreateInfo->minLod, 0, 14),
+      .MaxLOD = anv_clamp_f(pCreateInfo->maxLod, 0, 14),
       .ChromaKeyEnable = 0,
       .ChromaKeyIndex = 0,
       .ChromaKeyMode = 0,
@@ -360,7 +443,7 @@ VkResult gen8_CreateSampler(
       .TCZAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressModeW],
    };
 
-   GEN8_SAMPLER_STATE_pack(NULL, sampler->state, &sampler_state);
+   GENX(SAMPLER_STATE_pack)(NULL, sampler->state, &sampler_state);
 
    *pSampler = anv_sampler_to_handle(sampler);