Beispiel #1
0
void intel_buf_view_init(const struct intel_dev *dev,
                         const VkBufferViewCreateInfo *info,
                         struct intel_buf_view *view,
                         bool raw)
{
    struct intel_buf *buf = intel_buf(info->buffer);
    /* TODO: Is transfer destination the only shader write operation? */
    const bool will_write = (buf->usage & (VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT |
                             VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
    VkFormat format;
    VkDeviceSize stride;
    uint32_t *cmd;
    int i;

    view->obj.destroy = buf_view_destroy;

    view->buf = buf;

    /*
     * The compiler expects uniform buffers to have pitch of
     * 4 for fragment shaders, but 16 for other stages.  The format
     * must be VK_FORMAT_R32G32B32A32_SFLOAT.
     */
    if (raw) {
        format = VK_FORMAT_R32G32B32A32_SFLOAT;
        stride = 16;
    } else {
        format = info->format;
        stride = icd_format_get_size(format);
    }
    cmd = view->cmd;

    for (i = 0; i < 2; i++) {
        if (intel_gpu_gen(dev->gpu) >= INTEL_GEN(7)) {
            surface_state_buf_gen7(dev->gpu, info->offset,
                    info->range, stride, format,
                    will_write, will_write, cmd);
            view->cmd_len = 8;
        } else {
            surface_state_buf_gen6(dev->gpu, info->offset,
                    info->range, stride, format,
                    will_write, will_write, cmd);
            view->cmd_len = 6;
        }

        /* switch to view->fs_cmd */
        if (raw) {
            cmd = view->fs_cmd;
            stride = 4;
        } else {
            memcpy(view->fs_cmd, view->cmd, sizeof(uint32_t) * view->cmd_len);
            break;
        }
    }
}
Beispiel #2
0
static void
layout_init_size_and_format(struct intel_layout *layout,
                            struct intel_layout_params *params)
{
   const VkImageCreateInfo *info = params->info;
   VkFormat format = info->format;
   bool require_separate_stencil = false;

   layout->width0 = info->extent.width;
   layout->height0 = info->extent.height;

   /*
    * From the Sandy Bridge PRM, volume 2 part 1, page 317:
    *
    *     "This field (Separate Stencil Buffer Enable) must be set to the same
    *      value (enabled or disabled) as Hierarchical Depth Buffer Enable."
    *
    * GEN7+ requires separate stencil buffers.
    */
   if (info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
      if (intel_gpu_gen(params->gpu) >= INTEL_GEN(7))
         require_separate_stencil = true;
      else
         require_separate_stencil = (layout->aux == INTEL_LAYOUT_AUX_HIZ);
   }

   switch (format) {
   case VK_FORMAT_D24_UNORM_S8_UINT:
      if (require_separate_stencil) {
         format = VK_FORMAT_X8_D24_UNORM_PACK32;
         layout->separate_stencil = true;
      }
      break;
   case VK_FORMAT_D32_SFLOAT_S8_UINT:
      if (require_separate_stencil) {
         format = VK_FORMAT_D32_SFLOAT;
         layout->separate_stencil = true;
      }
      break;
   default:
      break;
   }

   layout->format = format;
   layout->block_width = icd_format_get_block_width(format);
   layout->block_height = layout->block_width;
   layout->block_size = icd_format_get_size(format);

   params->compressed = icd_format_is_compressed(format);
}
Beispiel #3
0
static void surface_state_buf_gen7(const struct intel_gpu *gpu,
                                   unsigned offset, unsigned size,
                                   unsigned struct_size,
                                   VkFormat elem_format,
                                   bool is_rt, bool render_cache_rw,
                                   uint32_t dw[8])
{
   const bool typed = !icd_format_is_undef(elem_format);
   const bool structured = (!typed && struct_size > 1);
   const int elem_size = (typed) ?
      icd_format_get_size(elem_format) : 1;
   int width, height, depth, pitch;
   int surface_type, surface_format, num_entries;

   INTEL_GPU_ASSERT(gpu, 7, 7.5);

   surface_type = (structured) ? GEN7_SURFTYPE_STRBUF : GEN6_SURFTYPE_BUFFER;

   surface_format = (typed) ?
      intel_format_translate_color(gpu, elem_format) : GEN6_FORMAT_RAW;

   /*
    * It's possible that the buffer view being used is smaller than
    * the format element size (required to be 16 for non-fragment shaders)
    * Make certain that size is at least struct_size to keep HW happy.
    */
   if (size < struct_size) {
       size = struct_size;
   }

   num_entries = size / struct_size;
   /* see if there is enough space to fit another element */
   if (size % struct_size >= elem_size && !structured)
      num_entries++;

   /*
    * From the Ivy Bridge PRM, volume 4 part 1, page 67:
    *
    *     "For SURFTYPE_BUFFER render targets, this field (Surface Base
    *      Address) specifies the base address of first element of the
    *      surface. The surface is interpreted as a simple array of that
    *      single element type. The address must be naturally-aligned to the
    *      element size (e.g., a buffer containing R32G32B32A32_FLOAT elements
    *      must be 16-byte aligned)
    *
    *      For SURFTYPE_BUFFER non-rendertarget surfaces, this field specifies
    *      the base address of the first element of the surface, computed in
    *      software by adding the surface base address to the byte offset of
    *      the element in the buffer."
    */
   if (is_rt)
      assert(offset % elem_size == 0);

   /*
    * From the Ivy Bridge PRM, volume 4 part 1, page 68:
    *
    *     "For typed buffer and structured buffer surfaces, the number of
    *      entries in the buffer ranges from 1 to 2^27.  For raw buffer
    *      surfaces, the number of entries in the buffer is the number of
    *      bytes which can range from 1 to 2^30."
    */
   assert(num_entries >= 1 &&
          num_entries <= 1 << ((typed || structured) ? 27 : 30));

   /*
    * From the Ivy Bridge PRM, volume 4 part 1, page 69:
    *
    *     "For SURFTYPE_BUFFER: The low two bits of this field (Width) must be
    *      11 if the Surface Format is RAW (the size of the buffer must be a
    *      multiple of 4 bytes)."
    *
    * From the Ivy Bridge PRM, volume 4 part 1, page 70:
    *
    *     "For surfaces of type SURFTYPE_BUFFER and SURFTYPE_STRBUF, this
    *      field (Surface Pitch) indicates the size of the structure."
    *
    *     "For linear surfaces with Surface Type of SURFTYPE_STRBUF, the pitch
    *      must be a multiple of 4 bytes."
    */
   if (structured)
      assert(struct_size % 4 == 0);
   else if (!typed)
      assert(num_entries % 4 == 0);

   pitch = struct_size;

   pitch--;
   num_entries--;
   /* bits [6:0] */
   width  = (num_entries & 0x0000007f);
   /* bits [20:7] */
   height = (num_entries & 0x001fff80) >> 7;
   /* bits [30:21] */
   depth  = (num_entries & 0x7fe00000) >> 21;
   /* limit to [26:21] */
   if (typed || structured)
      depth &= 0x3f;

   dw[0] = surface_type << GEN7_SURFACE_DW0_TYPE__SHIFT |
           surface_format << GEN7_SURFACE_DW0_FORMAT__SHIFT;
   if (render_cache_rw)
      dw[0] |= GEN7_SURFACE_DW0_RENDER_CACHE_RW;

   dw[1] = offset;

   dw[2] = height << GEN7_SURFACE_DW2_HEIGHT__SHIFT |
           width << GEN7_SURFACE_DW2_WIDTH__SHIFT;

   dw[3] = depth << GEN7_SURFACE_DW3_DEPTH__SHIFT |
           pitch;

   dw[4] = 0;
   dw[5] = GEN7_MOCS_L3_WB << GEN7_SURFACE_DW5_MOCS__SHIFT;

   dw[6] = 0;
   dw[7] = 0;

   if (intel_gpu_gen(gpu) >= INTEL_GEN(7.5)) {
      dw[7] |= GEN75_SCS_RED   << GEN75_SURFACE_DW7_SCS_R__SHIFT |
               GEN75_SCS_GREEN << GEN75_SURFACE_DW7_SCS_G__SHIFT |
               GEN75_SCS_BLUE  << GEN75_SURFACE_DW7_SCS_B__SHIFT |
               GEN75_SCS_ALPHA << GEN75_SURFACE_DW7_SCS_A__SHIFT;
   }
}
Beispiel #4
0
static void surface_state_tex_gen6(const struct intel_gpu *gpu,
                                   const struct intel_img *img,
                                   VkImageViewType type,
                                   VkFormat format,
                                   unsigned first_level,
                                   unsigned num_levels,
                                   unsigned first_layer,
                                   unsigned num_layers,
                                   bool is_rt,
                                   uint32_t dw[6])
{
   int surface_type, surface_format;
   int width, height, depth, pitch, lod;

   INTEL_GPU_ASSERT(gpu, 6, 6);

   surface_type = view_type_to_surface_type(type);
   assert(surface_type != GEN6_SURFTYPE_BUFFER);

   surface_format = intel_format_translate_color(gpu, format);
   assert(surface_format >= 0);

   width = img->layout.width0;
   height = img->layout.height0;
   depth = (type == VK_IMAGE_VIEW_TYPE_3D) ?
      img->depth : num_layers;
   pitch = img->layout.bo_stride;

   if (surface_type == GEN6_SURFTYPE_CUBE) {
      /*
       * From the Sandy Bridge PRM, volume 4 part 1, page 81:
       *
       *     "For SURFTYPE_CUBE: [DevSNB+]: for Sampling Engine Surfaces, the
       *      range of this field (Depth) is [0,84], indicating the number of
       *      cube array elements (equal to the number of underlying 2D array
       *      elements divided by 6). For other surfaces, this field must be
       *      zero."
       *
       * When is_rt is true, we treat the texture as a 2D one to avoid the
       * restriction.
       */
      if (is_rt) {
         surface_type = GEN6_SURFTYPE_2D;
      }
      else {
         assert(num_layers % 6 == 0);
         depth = num_layers / 6;
      }
   }

   /* sanity check the size */
   assert(width >= 1 && height >= 1 && depth >= 1 && pitch >= 1);
   switch (surface_type) {
   case GEN6_SURFTYPE_1D:
      assert(width <= 8192 && height == 1 && depth <= 512);
      assert(first_layer < 512 && num_layers <= 512);
      break;
   case GEN6_SURFTYPE_2D:
      assert(width <= 8192 && height <= 8192 && depth <= 512);
      assert(first_layer < 512 && num_layers <= 512);
      break;
   case GEN6_SURFTYPE_3D:
      assert(width <= 2048 && height <= 2048 && depth <= 2048);
      assert(first_layer < 2048 && num_layers <= 512);
      if (!is_rt)
         assert(first_layer == 0);
      break;
   case GEN6_SURFTYPE_CUBE:
      assert(width <= 8192 && height <= 8192 && depth <= 85);
      assert(width == height);
      assert(first_layer < 512 && num_layers <= 512);
      if (is_rt)
         assert(first_layer == 0);
      break;
   default:
      assert(!"unexpected surface type");
      break;
   }

   /* non-full array spacing is supported only on GEN7+ */
   assert(img->layout.walk != INTEL_LAYOUT_WALK_LOD);
   /* non-interleaved samples are supported only on GEN7+ */
   if (img->sample_count > 1)
      assert(img->layout.interleaved_samples);

   if (is_rt) {
      assert(num_levels == 1);
      lod = first_level;
   }
   else {
      lod = num_levels - 1;
   }

   /*
    * From the Sandy Bridge PRM, volume 4 part 1, page 76:
    *
    *     "Linear render target surface base addresses must be element-size
    *      aligned, for non-YUV surface formats, or a multiple of 2
    *      element-sizes for YUV surface formats. Other linear surfaces have
    *      no alignment requirements (byte alignment is sufficient.)"
    *
    * From the Sandy Bridge PRM, volume 4 part 1, page 81:
    *
    *     "For linear render target surfaces, the pitch must be a multiple
    *      of the element size for non-YUV surface formats. Pitch must be a
    *      multiple of 2 * element size for YUV surface formats."
    *
    * From the Sandy Bridge PRM, volume 4 part 1, page 86:
    *
    *     "For linear surfaces, this field (X Offset) must be zero"
    */
   if (img->layout.tiling == GEN6_TILING_NONE) {
      if (is_rt) {
         const int elem_size U_ASSERT_ONLY = icd_format_get_size(format);
         assert(pitch % elem_size == 0);
      }
   }

   dw[0] = surface_type << GEN6_SURFACE_DW0_TYPE__SHIFT |
           surface_format << GEN6_SURFACE_DW0_FORMAT__SHIFT |
           GEN6_SURFACE_DW0_MIPLAYOUT_BELOW;

   if (surface_type == GEN6_SURFTYPE_CUBE && !is_rt) {
      dw[0] |= 1 << 9 |
               GEN6_SURFACE_DW0_CUBE_FACE_ENABLES__MASK;
   }

   if (is_rt)
      dw[0] |= GEN6_SURFACE_DW0_RENDER_CACHE_RW;

   dw[1] = 0;

   dw[2] = (height - 1) << GEN6_SURFACE_DW2_HEIGHT__SHIFT |
           (width - 1) << GEN6_SURFACE_DW2_WIDTH__SHIFT |
           lod << GEN6_SURFACE_DW2_MIP_COUNT_LOD__SHIFT;

   assert(img->layout.tiling != GEN8_TILING_W);
   dw[3] = (depth - 1) << GEN6_SURFACE_DW3_DEPTH__SHIFT |
           (pitch - 1) << GEN6_SURFACE_DW3_PITCH__SHIFT |
           img->layout.tiling;

   dw[4] = first_level << GEN6_SURFACE_DW4_MIN_LOD__SHIFT |
           first_layer << 17 |
           (num_layers - 1) << 8 |
           ((img->sample_count > 1) ? GEN6_SURFACE_DW4_MULTISAMPLECOUNT_4 :
                                      GEN6_SURFACE_DW4_MULTISAMPLECOUNT_1);

   dw[5] = 0;

   assert(img->layout.align_j == 2 || img->layout.align_j == 4);
   if (img->layout.align_j == 4)
      dw[5] |= GEN6_SURFACE_DW5_VALIGN_4;
}
Beispiel #5
0
static void surface_state_buf_gen6(const struct intel_gpu *gpu,
                                   unsigned offset, unsigned size,
                                   unsigned struct_size,
                                   VkFormat elem_format,
                                   bool is_rt, bool render_cache_rw,
                                   uint32_t dw[6])
{
   const bool typed = !icd_format_is_undef(elem_format);
   const int elem_size = icd_format_get_size(elem_format);
   int width, height, depth, pitch;
   int surface_format, num_entries;

   INTEL_GPU_ASSERT(gpu, 6, 6);

   /*
    * For SURFTYPE_BUFFER, a SURFACE_STATE specifies an element of a
    * structure in a buffer.
    */

   surface_format = (typed) ?
       intel_format_translate_color(gpu, elem_format) : GEN6_FORMAT_RAW;

   num_entries = size / struct_size;
   /* see if there is enough space to fit another element */
   if (size % struct_size >= elem_size)
      num_entries++;

   /*
    * From the Sandy Bridge PRM, volume 4 part 1, page 76:
    *
    *     "For SURFTYPE_BUFFER render targets, this field (Surface Base
    *      Address) specifies the base address of first element of the
    *      surface. The surface is interpreted as a simple array of that
    *      single element type. The address must be naturally-aligned to the
    *      element size (e.g., a buffer containing R32G32B32A32_FLOAT elements
    *      must be 16-byte aligned).
    *
    *      For SURFTYPE_BUFFER non-rendertarget surfaces, this field specifies
    *      the base address of the first element of the surface, computed in
    *      software by adding the surface base address to the byte offset of
    *      the element in the buffer."
    */
   if (is_rt)
      assert(offset % elem_size == 0);

   /*
    * From the Sandy Bridge PRM, volume 4 part 1, page 77:
    *
    *     "For buffer surfaces, the number of entries in the buffer ranges
    *      from 1 to 2^27."
    */
   assert(num_entries >= 1 && num_entries <= 1 << 27);

   /*
    * From the Sandy Bridge PRM, volume 4 part 1, page 81:
    *
    *     "For surfaces of type SURFTYPE_BUFFER, this field (Surface Pitch)
    *      indicates the size of the structure."
    */
   pitch = struct_size;

   pitch--;
   num_entries--;
   /* bits [6:0] */
   width  = (num_entries & 0x0000007f);
   /* bits [19:7] */
   height = (num_entries & 0x000fff80) >> 7;
   /* bits [26:20] */
   depth  = (num_entries & 0x07f00000) >> 20;

   dw[0] = GEN6_SURFTYPE_BUFFER << GEN6_SURFACE_DW0_TYPE__SHIFT |
           surface_format << GEN6_SURFACE_DW0_FORMAT__SHIFT;
   if (render_cache_rw)
      dw[0] |= GEN6_SURFACE_DW0_RENDER_CACHE_RW;

   dw[1] = offset;

   dw[2] = height << GEN6_SURFACE_DW2_HEIGHT__SHIFT |
           width << GEN6_SURFACE_DW2_WIDTH__SHIFT;

   dw[3] = depth << GEN6_SURFACE_DW3_DEPTH__SHIFT |
           pitch << GEN6_SURFACE_DW3_PITCH__SHIFT;

   dw[4] = 0;
   dw[5] = 0;
}
Beispiel #6
0
static void surface_state_tex_gen7(const struct intel_gpu *gpu,
                                   const struct intel_img *img,
                                   VkImageViewType type,
                                   VkFormat format,
                                   unsigned first_level,
                                   unsigned num_levels,
                                   unsigned first_layer,
                                   unsigned num_layers,
                                   VkComponentMapping swizzles,
                                   bool is_rt,
                                   uint32_t dw[8])
{
   int surface_type, surface_format;
   int width, height, depth, pitch, lod;

   INTEL_GPU_ASSERT(gpu, 7, 7.5);

   surface_type = view_type_to_surface_type(type);
   assert(surface_type != GEN6_SURFTYPE_BUFFER);

   surface_format = intel_format_translate_color(gpu, format);
   assert(surface_format >= 0);

   width = img->layout.width0;
   height = img->layout.height0;
   depth = (type == VK_IMAGE_VIEW_TYPE_3D) ?
      img->depth : num_layers;
   pitch = img->layout.bo_stride;

   if (surface_type == GEN6_SURFTYPE_CUBE) {
      /*
       * From the Ivy Bridge PRM, volume 4 part 1, page 70:
       *
       *     "For SURFTYPE_CUBE:For Sampling Engine Surfaces, the range of
       *      this field is [0,340], indicating the number of cube array
       *      elements (equal to the number of underlying 2D array elements
       *      divided by 6). For other surfaces, this field must be zero."
       *
       * When is_rt is true, we treat the texture as a 2D one to avoid the
       * restriction.
       */
      if (is_rt) {
         surface_type = GEN6_SURFTYPE_2D;
      }
      else {
         assert(num_layers % 6 == 0);
         depth = num_layers / 6;
      }
   }

   /* sanity check the size */
   assert(width >= 1 && height >= 1 && depth >= 1 && pitch >= 1);
   assert(first_layer < 2048 && num_layers <= 2048);
   switch (surface_type) {
   case GEN6_SURFTYPE_1D:
      assert(width <= 16384 && height == 1 && depth <= 2048);
      break;
   case GEN6_SURFTYPE_2D:
      assert(width <= 16384 && height <= 16384 && depth <= 2048);
      break;
   case GEN6_SURFTYPE_3D:
      assert(width <= 2048 && height <= 2048 && depth <= 2048);
      if (!is_rt)
         assert(first_layer == 0);
      break;
   case GEN6_SURFTYPE_CUBE:
      assert(width <= 16384 && height <= 16384 && depth <= 86);
      assert(width == height);
      if (is_rt)
         assert(first_layer == 0);
      break;
   default:
      assert(!"unexpected surface type");
      break;
   }

   if (is_rt) {
      assert(num_levels == 1);
      lod = first_level;
   }
   else {
      lod = num_levels - 1;
   }

   /*
    * From the Ivy Bridge PRM, volume 4 part 1, page 68:
    *
    *     "The Base Address for linear render target surfaces and surfaces
    *      accessed with the typed surface read/write data port messages must
    *      be element-size aligned, for non-YUV surface formats, or a multiple
    *      of 2 element-sizes for YUV surface formats.  Other linear surfaces
    *      have no alignment requirements (byte alignment is sufficient)."
    *
    * From the Ivy Bridge PRM, volume 4 part 1, page 70:
    *
    *     "For linear render target surfaces and surfaces accessed with the
    *      typed data port messages, the pitch must be a multiple of the
    *      element size for non-YUV surface formats. Pitch must be a multiple
    *      of 2 * element size for YUV surface formats. For linear surfaces
    *      with Surface Type of SURFTYPE_STRBUF, the pitch must be a multiple
    *      of 4 bytes.For other linear surfaces, the pitch can be any multiple
    *      of bytes."
    *
    * From the Ivy Bridge PRM, volume 4 part 1, page 74:
    *
    *     "For linear surfaces, this field (X Offset) must be zero."
    */
   if (img->layout.tiling == GEN6_TILING_NONE) {
      if (is_rt) {
         const int elem_size U_ASSERT_ONLY = icd_format_get_size(format);
         assert(pitch % elem_size == 0);
      }
   }

   assert(img->layout.tiling != GEN8_TILING_W);
   dw[0] = surface_type << GEN7_SURFACE_DW0_TYPE__SHIFT |
           surface_format << GEN7_SURFACE_DW0_FORMAT__SHIFT |
           img->layout.tiling << 13;

   /*
    * From the Ivy Bridge PRM, volume 4 part 1, page 63:
    *
    *     "If this field (Surface Array) is enabled, the Surface Type must be
    *      SURFTYPE_1D, SURFTYPE_2D, or SURFTYPE_CUBE. If this field is
    *      disabled and Surface Type is SURFTYPE_1D, SURFTYPE_2D, or
    *      SURFTYPE_CUBE, the Depth field must be set to zero."
    *
    * For non-3D sampler surfaces, resinfo (the sampler message) always
    * returns zero for the number of layers when this field is not set.
    */
   if (surface_type != GEN6_SURFTYPE_3D) {
      if (num_layers > 1)
         dw[0] |= GEN7_SURFACE_DW0_IS_ARRAY;
      else
         assert(depth == 1);
   }

   assert(img->layout.align_i == 4 || img->layout.align_i == 8);
   assert(img->layout.align_j == 2 || img->layout.align_j == 4);

   if (img->layout.align_j == 4)
      dw[0] |= GEN7_SURFACE_DW0_VALIGN_4;

   if (img->layout.align_i == 8)
      dw[0] |= GEN7_SURFACE_DW0_HALIGN_8;

   if (img->layout.walk == INTEL_LAYOUT_WALK_LOD)
      dw[0] |= GEN7_SURFACE_DW0_ARYSPC_LOD0;
   else
      dw[0] |= GEN7_SURFACE_DW0_ARYSPC_FULL;

   if (is_rt)
      dw[0] |= GEN7_SURFACE_DW0_RENDER_CACHE_RW;

   if (surface_type == GEN6_SURFTYPE_CUBE && !is_rt)
      dw[0] |= GEN7_SURFACE_DW0_CUBE_FACE_ENABLES__MASK;

   dw[1] = 0;

   dw[2] = (height - 1) << GEN7_SURFACE_DW2_HEIGHT__SHIFT |
           (width - 1) << GEN7_SURFACE_DW2_WIDTH__SHIFT;

   dw[3] = (depth - 1) << GEN7_SURFACE_DW3_DEPTH__SHIFT |
           (pitch - 1);

   dw[4] = first_layer << 18 |
           (num_layers - 1) << 7;

   /*
    * MSFMT_MSS means the samples are not interleaved and MSFMT_DEPTH_STENCIL
    * means the samples are interleaved.  The layouts are the same when the
    * number of samples is 1.
    */
   if (img->layout.interleaved_samples && img->sample_count > 1) {
      assert(!is_rt);
      dw[4] |= GEN7_SURFACE_DW4_MSFMT_DEPTH_STENCIL;
   }
   else {
      dw[4] |= GEN7_SURFACE_DW4_MSFMT_MSS;
   }

   if (img->sample_count > 4)
      dw[4] |= GEN7_SURFACE_DW4_MULTISAMPLECOUNT_8;
   else if (img->sample_count > 2)
      dw[4] |= GEN7_SURFACE_DW4_MULTISAMPLECOUNT_4;
   else
      dw[4] |= GEN7_SURFACE_DW4_MULTISAMPLECOUNT_1;

   dw[5] = GEN7_MOCS_L3_WB << GEN7_SURFACE_DW5_MOCS__SHIFT |
           (first_level) << GEN7_SURFACE_DW5_MIN_LOD__SHIFT |
           lod;

   dw[6] = 0;
   dw[7] = 0;

   if (intel_gpu_gen(gpu) >= INTEL_GEN(7.5)) {
      dw[7] |=
         channel_swizzle_to_scs((swizzles.r == VK_COMPONENT_SWIZZLE_IDENTITY) ? VK_COMPONENT_SWIZZLE_R : swizzles.r) << GEN75_SURFACE_DW7_SCS_R__SHIFT |
         channel_swizzle_to_scs((swizzles.g == VK_COMPONENT_SWIZZLE_IDENTITY) ? VK_COMPONENT_SWIZZLE_G : swizzles.g) << GEN75_SURFACE_DW7_SCS_G__SHIFT |
         channel_swizzle_to_scs((swizzles.b == VK_COMPONENT_SWIZZLE_IDENTITY) ? VK_COMPONENT_SWIZZLE_B : swizzles.b) << GEN75_SURFACE_DW7_SCS_B__SHIFT |
         channel_swizzle_to_scs((swizzles.a == VK_COMPONENT_SWIZZLE_IDENTITY) ? VK_COMPONENT_SWIZZLE_A : swizzles.a) << GEN75_SURFACE_DW7_SCS_A__SHIFT;
   } else {
         assert(((swizzles.r == VK_COMPONENT_SWIZZLE_R) || (swizzles.r == VK_COMPONENT_SWIZZLE_IDENTITY)) &&
                ((swizzles.g == VK_COMPONENT_SWIZZLE_G) || (swizzles.g == VK_COMPONENT_SWIZZLE_IDENTITY)) &&
                ((swizzles.b == VK_COMPONENT_SWIZZLE_B) || (swizzles.b == VK_COMPONENT_SWIZZLE_IDENTITY)) &&
                ((swizzles.a == VK_COMPONENT_SWIZZLE_A) || (swizzles.a == VK_COMPONENT_SWIZZLE_IDENTITY)));
   }
}