Пример #1
0
static bool
surface_validate_gen6_buffer(const struct ilo_dev *dev,
                             const struct ilo_state_surface_buffer_info *info)
{
   uint32_t alignment;

   ILO_DEV_ASSERT(dev, 6, 8);

   if (info->offset + info->size > info->vma->vm_size) {
      ilo_warn("invalid buffer range\n");
      return false;
   }

   /*
    * From the Sandy Bridge PRM, volume 4 part 1, page 81:
    *
    *     "For surfaces of type SURFTYPE_BUFFER: [0,2047] -> [1B, 2048B]
    *      For surfaces of type SURFTYPE_STRBUF: [0,2047] -> [1B, 2048B]"
    */
   if (!info->struct_size || info->struct_size > 2048) {
      ilo_warn("invalid buffer struct size\n");
      return false;
   }

   alignment = surface_get_gen6_buffer_offset_alignment(dev, info);
   if (info->offset % alignment || info->vma->vm_alignment % alignment) {
      ilo_warn("bad buffer offset\n");
      return false;
   }

   /* no STRBUF on Gen6 */
   if (info->format == GEN6_FORMAT_RAW && info->struct_size > 1)
      assert(ilo_dev_gen(dev) >= ILO_GEN(7));

   /* SVB writes are Gen6 only */
   if (info->access == ILO_STATE_SURFACE_ACCESS_DP_SVB)
      assert(ilo_dev_gen(dev) == ILO_GEN(6));

   /*
    * From the Ivy Bridge PRM, volume 4 part 1, page 83:
    *
    *     "NOTE: "RAW" is supported only with buffers and structured buffers
    *      accessed via the untyped surface read/write and untyped atomic
    *      operation messages, which do not have a column in the table."
    *
    * From the Ivy Bridge PRM, volume 4 part 1, page 252:
    *
    *     "For untyped messages, the Surface Format must be RAW and the
    *      Surface Type must be SURFTYPE_BUFFER or SURFTYPE_STRBUF."
    */
   assert((info->access == ILO_STATE_SURFACE_ACCESS_DP_UNTYPED) ==
          (info->format == GEN6_FORMAT_RAW));

   return true;
}
Пример #2
0
struct ilo_render *
ilo_render_create(struct ilo_builder *builder)
{
   struct ilo_render *render;

   render = CALLOC_STRUCT(ilo_render);
   if (!render)
      return NULL;

   render->dev = builder->dev;
   render->builder = builder;

   render->workaround_bo = intel_winsys_alloc_bo(builder->winsys,
         "PIPE_CONTROL workaround", 4096, false);
   if (!render->workaround_bo) {
      ilo_warn("failed to allocate PIPE_CONTROL workaround bo\n");
      FREE(render);
      return NULL;
   }

   ilo_state_sample_pattern_init_default(&render->sample_pattern,
         render->dev);

   ilo_render_invalidate_hw(render);
   ilo_render_invalidate_builder(render);

   return render;
}
Пример #3
0
struct ilo_3d_pipeline *
ilo_3d_pipeline_create(struct ilo_cp *cp, const struct ilo_dev_info *dev)
{
   struct ilo_3d_pipeline *p;
   int i;

   p = CALLOC_STRUCT(ilo_3d_pipeline);
   if (!p)
      return NULL;

   p->cp = cp;
   p->dev = dev;

   switch (p->dev->gen) {
   case ILO_GEN(6):
      ilo_3d_pipeline_init_gen6(p);
      break;
   case ILO_GEN(7):
   case ILO_GEN(7.5):
      ilo_3d_pipeline_init_gen7(p);
      break;
   default:
      assert(!"unsupported GEN");
      FREE(p);
      return NULL;
      break;
   }

   p->invalidate_flags = ILO_3D_PIPELINE_INVALIDATE_ALL;

   p->workaround_bo = intel_winsys_alloc_buffer(p->cp->winsys,
         "PIPE_CONTROL workaround", 4096, false);
   if (!p->workaround_bo) {
      ilo_warn("failed to allocate PIPE_CONTROL workaround bo\n");
      FREE(p);
      return NULL;
   }

   p->packed_sample_position_1x =
      sample_position_1x[0].x << 4 |
      sample_position_1x[0].y;

   /* pack into dwords */
   for (i = 0; i < 4; i++) {
      p->packed_sample_position_4x |=
         sample_position_4x[i].x << (8 * i + 4) |
         sample_position_4x[i].y << (8 * i);

      p->packed_sample_position_8x[0] |=
         sample_position_8x[i].x << (8 * i + 4) |
         sample_position_8x[i].y << (8 * i);

      p->packed_sample_position_8x[1] |=
         sample_position_8x[4 + i].x << (8 * i + 4) |
         sample_position_8x[4 + i].y << (8 * i);
   }

   return p;
}
Пример #4
0
static bool
surface_get_gen6_buffer_struct_count(const struct ilo_dev *dev,
                                     const struct ilo_state_surface_buffer_info *info,
                                     uint32_t *count)
{
   uint32_t max_struct, c;

   ILO_DEV_ASSERT(dev, 6, 8);

   c = info->size / info->struct_size;
   if (info->format_size < info->size - info->struct_size * c)
      c++;

   /*
    * 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."
    *
    * 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."
    *
    * 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)."
    */
   max_struct = 1 << 27;
   if (info->format == GEN6_FORMAT_RAW && info->struct_size == 1) {
      if (ilo_dev_gen(dev) >= ILO_GEN(7))
         max_struct = 1 << 30;

      c &= ~3;
   }

   if (!c || c > max_struct) {
      ilo_warn("too many or zero buffer structs\n");
      return false;
   }

   *count = c - 1;

   return true;
}
Пример #5
0
bool
ilo_blitter_pipe_blit(struct ilo_blitter *blitter,
                      const struct pipe_blit_info *info)
{
   struct blitter_context *b = blitter->pipe_blitter;
   struct pipe_blit_info skip_stencil;

   if (util_try_blit_via_copy_region(&blitter->ilo->base, info))
      return true;

   if (!util_blitter_is_blit_supported(b, info)) {
      /* try without stencil */
      if (info->mask & PIPE_MASK_S) {
         skip_stencil = *info;
         skip_stencil.mask = info->mask & ~PIPE_MASK_S;

         if (util_blitter_is_blit_supported(blitter->pipe_blitter,
                                            &skip_stencil)) {
            ilo_warn("ignore stencil buffer blitting\n");
            info = &skip_stencil;
         }
      }

      if (info != &skip_stencil) {
         ilo_warn("failed to blit with pipe blitter\n");
         return false;
      }
   }

   ilo_blitter_pipe_begin(blitter, ILO_BLITTER_PIPE_BLIT,
         info->scissor_enable);
   util_blitter_blit(b, info);
   ilo_blitter_pipe_end(blitter);

   return true;
}
Пример #6
0
static struct pipe_sampler_view *
ilo_create_sampler_view(struct pipe_context *pipe,
                        struct pipe_resource *res,
                        const struct pipe_sampler_view *templ)
{
   const struct ilo_dev_info *dev = ilo_context(pipe)->dev;
   struct ilo_view_cso *view;

   view = MALLOC_STRUCT(ilo_view_cso);
   assert(view);

   view->base = *templ;
   pipe_reference_init(&view->base.reference, 1);
   view->base.texture = NULL;
   pipe_resource_reference(&view->base.texture, res);
   view->base.context = pipe;

   if (res->target == PIPE_BUFFER) {
      const unsigned elem_size = util_format_get_blocksize(templ->format);
      const unsigned first_elem = templ->u.buf.first_element;
      const unsigned num_elems = templ->u.buf.last_element - first_elem + 1;

      ilo_gpe_init_view_surface_for_buffer(dev, ilo_buffer(res),
            first_elem * elem_size, num_elems * elem_size,
            elem_size, templ->format, false, false, &view->surface);
   }
   else {
      struct ilo_texture *tex = ilo_texture(res);

      /* warn about degraded performance because of a missing binding flag */
      if (tex->layout.tiling == INTEL_TILING_NONE &&
          !(tex->base.bind & PIPE_BIND_SAMPLER_VIEW)) {
         ilo_warn("creating sampler view for a resource "
                  "not created for sampling\n");
      }

      ilo_gpe_init_view_surface_for_texture(dev, tex,
            templ->format,
            templ->u.tex.first_level,
            templ->u.tex.last_level - templ->u.tex.first_level + 1,
            templ->u.tex.first_layer,
            templ->u.tex.last_layer - templ->u.tex.first_layer + 1,
            false, &view->surface);
   }

   return &view->base;
}
Пример #7
0
static void
gen6_emit_launch_grid_surface_global(struct ilo_render *r,
                                          const struct ilo_state_vector *vec,
                                          struct ilo_render_launch_grid_session *session)
{
   const struct ilo_shader_state *cs = vec->cs;
   const struct ilo_global_binding_cso *bindings =
      util_dynarray_begin(&vec->global_binding.bindings);
   uint32_t *surface_state = r->state.cs.SURFACE_STATE;
   int base, count, i;

   ILO_DEV_ASSERT(r->dev, 7, 7.5);

   base = ilo_shader_get_kernel_param(cs, ILO_KERNEL_CS_SURFACE_GLOBAL_BASE);
   count = ilo_shader_get_kernel_param(cs, ILO_KERNEL_CS_SURFACE_GLOBAL_COUNT);

   if (!count)
      return;

   if (base + count > Elements(r->state.cs.SURFACE_STATE)) {
      ilo_warn("too many global bindings\n");
      count = Elements(r->state.cs.SURFACE_STATE) - base;
   }

   /* SURFACE_STATEs for global bindings */
   surface_state += base;
   for (i = 0; i < count; i++) {
      if (i < vec->global_binding.count && bindings[i].resource) {
         const struct ilo_buffer *buf = ilo_buffer(bindings[i].resource);
         struct ilo_view_surface view;

         assert(bindings[i].resource->target == PIPE_BUFFER);

         ilo_gpe_init_view_surface_for_buffer(r->dev, buf, 0, buf->bo_size,
               1, PIPE_FORMAT_NONE, true, true, &view);
         surface_state[i] =
            gen6_SURFACE_STATE(r->builder, &view, true);
      } else {
         surface_state[i] = 0;
      }
   }
}
Пример #8
0
/* note that this may force the texture to be linear */
static void
layout_calculate_bo_size(struct ilo_layout *layout,
                         struct ilo_layout_params *params)
{
   assert(params->max_x % layout->block_width == 0);
   assert(params->max_y % layout->block_height == 0);
   assert(layout->layer_height % layout->block_height == 0);

   layout->bo_stride =
      (params->max_x / layout->block_width) * layout->block_size;
   layout->bo_height = params->max_y / layout->block_height;

   while (true) {
      unsigned w = layout->bo_stride, h = layout->bo_height;
      unsigned align_w, align_h;

      /*
       * From the Haswell PRM, volume 5, page 163:
       *
       *     "For linear surfaces, additional padding of 64 bytes is required
       *      at the bottom of the surface. This is in addition to the padding
       *      required above."
       */
      if (ilo_dev_gen(params->dev) >= ILO_GEN(7.5) &&
          (params->templ->bind & PIPE_BIND_SAMPLER_VIEW) &&
          layout->tiling == INTEL_TILING_NONE) {
         layout->bo_height +=
            (64 + layout->bo_stride - 1) / layout->bo_stride;
      }

      /*
       * 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.
       *      - For other linear surfaces, the pitch can be any multiple of
       *        bytes.
       *      - For tiled surfaces, the pitch must be a multiple of the tile
       *        width."
       *
       * Different requirements may exist when the bo is used in different
       * places, but our alignments here should be good enough that we do not
       * need to check layout->templ->bind.
       */
      switch (layout->tiling) {
      case INTEL_TILING_X:
         align_w = 512;
         align_h = 8;
         break;
      case INTEL_TILING_Y:
         align_w = 128;
         align_h = 32;
         break;
      default:
         if (layout->format == PIPE_FORMAT_S8_UINT) {
            /*
             * From the Sandy Bridge PRM, volume 1 part 2, page 22:
             *
             *     "A 4KB tile is subdivided into 8-high by 8-wide array of
             *      Blocks for W-Major Tiles (W Tiles). Each Block is 8 rows by 8
             *      bytes."
             *
             * Since we asked for INTEL_TILING_NONE instead of the non-existent
             * INTEL_TILING_W, we want to align to W tiles here.
             */
            align_w = 64;
            align_h = 64;
         } else {
            /* some good enough values */
            align_w = 64;
            align_h = 2;
         }
         break;
      }

      w = align(w, align_w);
      h = align(h, align_h);

      /* make sure the bo is mappable */
      if (layout->tiling != INTEL_TILING_NONE) {
         /*
          * Usually only the first 256MB of the GTT is mappable.
          *
          * See also how intel_context::max_gtt_map_object_size is calculated.
          */
         const size_t mappable_gtt_size = 256 * 1024 * 1024;

         /*
          * Be conservative.  We may be able to switch from VALIGN_4 to
          * VALIGN_2 if the layout was Y-tiled, but let's keep it simple.
          */
         if (mappable_gtt_size / w / 4 < h) {
            if (layout->valid_tilings & LAYOUT_TILING_NONE) {
               layout->tiling = INTEL_TILING_NONE;
               /* MCS support for non-MSRTs is limited to tiled RTs */
               if (layout->aux == ILO_LAYOUT_AUX_MCS &&
                   params->templ->nr_samples <= 1)
                  layout->aux = ILO_LAYOUT_AUX_NONE;

               continue;
            } else {
               ilo_warn("cannot force texture to be linear\n");
            }
         }
      }

      layout->bo_stride = w;
      layout->bo_height = h;
      break;
   }
}
Пример #9
0
static bool
surface_get_gen6_image_levels(const struct ilo_dev *dev,
                              const struct ilo_state_surface_image_info *info,
                              uint8_t *min_lod, uint8_t *mip_count)
{
   uint8_t max_level = (ilo_dev_gen(dev) >= ILO_GEN(7)) ? 15 : 14;

   ILO_DEV_ASSERT(dev, 6, 8);

   assert(info->img->level_count <= max_level);
   max_level = info->img->level_count;

   if (!info->level_count ||
       info->level_base + info->level_count > max_level) {
      ilo_warn("invalid level range\n");
      return false;
   }

   /*
    * From the Sandy Bridge PRM, volume 4 part 1, page 79:
    *
    *     "For Sampling Engine Surfaces:
    *      This field (MIP Count / LOD) indicates the number of MIP levels
    *      allowed to be accessed starting at Surface Min LOD, which must be
    *      less than or equal to the number of MIP levels actually stored in
    *      memory for this surface.
    *
    *      Force the mip map access to be between the mipmap specified by the
    *      integer bits of the Min LOD and the ceiling of the value specified
    *      here.
    *
    *      For Render Target Surfaces:
    *      This field defines the MIP level that is currently being rendered
    *      into. This is the absolute MIP level on the surface and is not
    *      relative to the Surface Min LOD field, which is ignored for render
    *      target surfaces.
    *
    *      For Other Surfaces:
    *      This field is reserved : MBZ"
    *
    * From the Sandy Bridge PRM, volume 4 part 1, page 83:
    *
    *     "For Sampling Engine Surfaces:
    *
    *      This field (Surface Min LOD) indicates the most detailed LOD that
    *      can be accessed as part of this surface.  This field is added to
    *      the delivered LOD (sample_l, ld, or resinfo message types) before
    *      it is used to address the surface.
    *
    *      For Other Surfaces:
    *      This field is ignored."
    *
    * On Gen7+, typed sufaces are treated like sampling engine surfaces.
    */
   if (info->access == ILO_STATE_SURFACE_ACCESS_DP_RENDER) {
      assert(info->level_count == 1);

      *min_lod = 0;
      *mip_count = info->level_base;
   } else {
      *min_lod = info->level_base;
      *mip_count = info->level_count - 1;
   }

   return true;
}
Пример #10
0
static bool
surface_get_gen6_image_slices(const struct ilo_dev *dev,
                              const struct ilo_state_surface_image_info *info,
                              uint16_t *depth, uint16_t *min_array_elem,
                              uint16_t *rt_view_extent)
{
   uint16_t max_slice, d;

   ILO_DEV_ASSERT(dev, 6, 8);

   /*
    * 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."
    *
    * From the Ivy Bridge PRM, volume 4 part 1, page 69:
    *
    *     "This field (Depth) specifies the total number of levels for a
    *      volume texture or the number of array elements allowed to be
    *      accessed starting at the Minimum Array Element for arrayed
    *      surfaces.  If the volume texture is MIP-mapped, this field
    *      specifies the depth of the base MIP level."
    *
    *     "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."
    *
    *     "Errata: For SURFTYPE_CUBE sampling engine surfaces, the range of
    *      this field is limited to [0,85].
    *
    *      Errata: If Surface Array is enabled, and Depth is between 1024 and
    *      2047, an incorrect array slice may be accessed if the requested
    *      array index in the message is greater than or equal to 4096."
    *
    * The errata are for Gen7-specific, and they limit the number of useable
    * layers to (86 * 6), about 512.
    */

   switch (info->type) {
   case GEN6_SURFTYPE_1D:
   case GEN6_SURFTYPE_2D:
   case GEN6_SURFTYPE_CUBE:
      max_slice = (ilo_dev_gen(dev) >= ILO_GEN(7.5)) ? 2048 : 512;

      assert(info->img->array_size <= max_slice);
      max_slice = info->img->array_size;

      d = info->slice_count;
      if (info->type == GEN6_SURFTYPE_CUBE) {
         if (info->access == ILO_STATE_SURFACE_ACCESS_SAMPLER) {
            if (!d || d % 6) {
               ilo_warn("invalid cube slice count\n");
               return false;
            }

            if (ilo_dev_gen(dev) == ILO_GEN(7) && d > 86 * 6) {
               ilo_warn("cube slice count exceeds Gen7 limit\n");
               return false;
            }
         } else {
            /*
             * Minumum Array Element and Depth must be 0; Render Target View
             * Extent is ignored.
             */
            if (info->slice_base || d != 6) {
               ilo_warn("no cube RT array support in data port\n");
               return false;
            }
         }

         d /= 6;
      }

      if (!info->is_array && d > 1) {
         ilo_warn("non-array surface with non-zero depth\n");
         return false;
      }
      break;
   case GEN6_SURFTYPE_3D:
      max_slice = 2048;

      assert(info->img->depth0 <= max_slice);
      max_slice = u_minify(info->img->depth0, info->level_base);

      d = info->img->depth0;

      if (info->is_array) {
         ilo_warn("3D surfaces cannot be arrays\n");
         return false;
      }
      break;
   default:
      assert(!"invalid surface type");
      return false;
      break;
   }

   if (!info->slice_count ||
       info->slice_base + info->slice_count > max_slice) {
      ilo_warn("invalid slice range\n");
      return false;
   }

   assert(d);
   *depth = d - 1;

   /*
    * From the Sandy Bridge PRM, volume 4 part 1, page 84:
    *
    *     "For Sampling Engine and Render Target 1D and 2D Surfaces:
    *      This field (Minimum Array Element) indicates the minimum array
    *      element that can be accessed as part of this surface.  This field
    *      is added to the delivered array index before it is used to address
    *      the surface.
    *
    *      For Render Target 3D Surfaces:
    *      This field indicates the minimum `R' coordinate on the LOD
    *      currently being rendered to.  This field is added to the delivered
    *      array index before it is used to address the surface.
    *
    *      For Sampling Engine Cube Surfaces on [DevSNB+] only:
    *      This field indicates the minimum array element in the underlying 2D
    *      surface array that can be accessed as part of this surface (the
    *      cube array index is multipled by 6 to compute this value, although
    *      this field is not restricted to only multiples of 6). This field is
    *      added to the delivered array index before it is used to address the
    *      surface.
    *
    *      For Other Surfaces:
    *      This field must be set to zero."
    *
    * On Gen7+, typed sufaces are treated like sampling engine 1D and 2D
    * surfaces.
    */
   *min_array_elem = info->slice_base;

   /*
    * From the Sandy Bridge PRM, volume 4 part 1, page 84:
    *
    *     "For Render Target 3D Surfaces:
    *      This field (Render Target View Extent) indicates the extent of the
    *      accessible `R' coordinates minus 1 on the LOD currently being
    *      rendered to.
    *
    *      For Render Target 1D and 2D Surfaces:
    *      This field must be set to the same value as the Depth field.
    *
    *      For Other Surfaces:
    *      This field is ignored."
    */
   *rt_view_extent = info->slice_count - 1;

   return true;
}
Пример #11
0
static bool
surface_validate_gen6_image(const struct ilo_dev *dev,
                            const struct ilo_state_surface_image_info *info)
{
   ILO_DEV_ASSERT(dev, 6, 8);

   switch (info->access) {
   case ILO_STATE_SURFACE_ACCESS_SAMPLER:
   case ILO_STATE_SURFACE_ACCESS_DP_RENDER:
      break;
   case ILO_STATE_SURFACE_ACCESS_DP_TYPED:
      assert(ilo_dev_gen(dev) >= ILO_GEN(7));
      break;
   default:
      assert(!"unsupported surface access");
      break;
   }

   assert(info->img && info->vma);

   if (info->img->tiling != GEN6_TILING_NONE)
      assert(info->vma->vm_alignment % 4096 == 0);

   if (info->aux_vma) {
      assert(ilo_image_can_enable_aux(info->img, info->level_base));
      /* always tiled */
      assert(info->aux_vma->vm_alignment % 4096 == 0);
   }

   /*
    * From the Sandy Bridge PRM, volume 4 part 1, page 78:
    *
    *     "For surface types other than SURFTYPE_BUFFER, the Width specified
    *      by this field must be less than or equal to the surface pitch
    *      (specified in bytes via the Surface Pitch field)."
    */
   assert(info->img->bo_stride && info->img->bo_stride <= 512 * 1024 &&
          info->img->width0 <= info->img->bo_stride);

   if (info->type != info->img->type) {
      assert(info->type == GEN6_SURFTYPE_2D &&
             info->img->type == GEN6_SURFTYPE_CUBE);
   }

   /*
    * From the Sandy Bridge PRM, volume 4 part 1, page 78:
    *
    *     "For cube maps, Width must be set equal to the Height."
    */
   if (info->type == GEN6_SURFTYPE_CUBE)
      assert(info->img->width0 == info->img->height0);

   /*
    * From the Sandy Bridge PRM, volume 4 part 1, page 72:
    *
    *     "Tile Walk TILEWALK_YMAJOR is UNDEFINED for render target formats
    *      that have 128 bits-per-element (BPE)."
    *
    *     "If Number of Multisamples is set to a value other than
    *      MULTISAMPLECOUNT_1, this field cannot be set to the following
    *      formats:
    *
    *      - any format with greater than 64 bits per element
    *      - any compressed texture format (BC*)
    *      - any YCRCB* format"
    *
    * From the Ivy Bridge PRM, volume 4 part 1, page 63:
    *
    *      If Number of Multisamples is set to a value other than
    *      MULTISAMPLECOUNT_1, this field cannot be set to the following
    *      formats: any format with greater than 64 bits per element, if
    *      Number of Multisamples is MULTISAMPLECOUNT_8, any compressed
    *      texture format (BC*), and any YCRCB* format.
    *
    * TODO
    */

   if (ilo_dev_gen(dev) < ILO_GEN(8) && info->img->tiling == GEN8_TILING_W) {
      ilo_warn("tiling W is not supported\n");
      return false;
   }

   return true;
}
Пример #12
0
/**
 * Initialize the \p dev from \p winsys.
 */
bool
ilo_dev_init(struct ilo_dev *dev, struct intel_winsys *winsys)
{
   const struct intel_winsys_info *info;

   assert(ilo_is_zeroed(dev, sizeof(*dev)));

   info = intel_winsys_get_info(winsys);

   dev->winsys = winsys;
   dev->devid = info->devid;
   dev->aperture_total = info->aperture_total;
   dev->aperture_mappable = info->aperture_mappable;
   dev->has_llc = info->has_llc;
   dev->has_address_swizzling = info->has_address_swizzling;
   dev->has_logical_context = info->has_logical_context;
   dev->has_ppgtt = info->has_ppgtt;
   dev->has_timestamp = info->has_timestamp;
   dev->has_gen7_sol_reset = info->has_gen7_sol_reset;

   if (!dev->has_logical_context) {
      ilo_err("missing hardware logical context support\n");
      return false;
   }

   /*
    * PIPE_CONTROL and MI_* use PPGTT writes on GEN7+ and privileged GGTT
    * writes on GEN6.
    *
    * From the Sandy Bridge PRM, volume 1 part 3, page 101:
    *
    *     "[DevSNB] When Per-Process GTT Enable is set, it is assumed that all
    *      code is in a secure environment, independent of address space.
    *      Under this condition, this bit only specifies the address space
    *      (GGTT or PPGTT). All commands are executed "as-is""
    *
    * We need PPGTT to be enabled on GEN6 too.
    */
   if (!dev->has_ppgtt) {
      /* experiments show that it does not really matter... */
      ilo_warn("PPGTT disabled\n");
   }

   if (gen_is_bdw(info->devid) || gen_is_chv(info->devid)) {
      dev->gen_opaque = ILO_GEN(8);
      dev->gt = (gen_is_bdw(info->devid)) ? gen_get_bdw_gt(info->devid) : 1;
      /* XXX random values */
      if (dev->gt == 3) {
         dev->eu_count = 48;
         dev->thread_count = 336;
         dev->urb_size = 384 * 1024;
      } else if (dev->gt == 2) {
         dev->eu_count = 24;
         dev->thread_count = 168;
         dev->urb_size = 384 * 1024;
      } else {
         dev->eu_count = 12;
         dev->thread_count = 84;
         dev->urb_size = 192 * 1024;
      }
   } else if (gen_is_hsw(info->devid)) {
      /*
       * From the Haswell PRM, volume 4, page 8:
       *
       *     "Description                    GT3      GT2      GT1.5    GT1
       *      (...)
       *      EUs (Total)                    40       20       12       10
       *      Threads (Total)                280      140      84       70
       *      (...)
       *      URB Size (max, within L3$)     512KB    256KB    256KB    128KB
       */
      dev->gen_opaque = ILO_GEN(7.5);
      dev->gt = gen_get_hsw_gt(info->devid);
      if (dev->gt == 3) {
         dev->eu_count = 40;
         dev->thread_count = 280;
         dev->urb_size = 512 * 1024;
      } else if (dev->gt == 2) {
         dev->eu_count = 20;
         dev->thread_count = 140;
         dev->urb_size = 256 * 1024;
      } else {
         dev->eu_count = 10;
         dev->thread_count = 70;
         dev->urb_size = 128 * 1024;
      }
   } else if (gen_is_ivb(info->devid) || gen_is_vlv(info->devid)) {
      /*
       * From the Ivy Bridge PRM, volume 1 part 1, page 18:
       *
       *     "Device             # of EUs        #Threads/EU
       *      Ivy Bridge (GT2)   16              8
       *      Ivy Bridge (GT1)   6               6"
       *
       * From the Ivy Bridge PRM, volume 4 part 2, page 17:
       *
       *     "URB Size    URB Rows    URB Rows when SLM Enabled
       *      128k        4096        2048
       *      256k        8096        4096"
       */
      dev->gen_opaque = ILO_GEN(7);
      dev->gt = (gen_is_ivb(info->devid)) ? gen_get_ivb_gt(info->devid) : 1;
      if (dev->gt == 2) {
         dev->eu_count = 16;
         dev->thread_count = 128;
         dev->urb_size = 256 * 1024;
      } else {
         dev->eu_count = 6;
         dev->thread_count = 36;
         dev->urb_size = 128 * 1024;
      }
   } else if (gen_is_snb(info->devid)) {
      /*
       * From the Sandy Bridge PRM, volume 1 part 1, page 22:
       *
       *     "Device             # of EUs        #Threads/EU
       *      SNB GT2            12              5
       *      SNB GT1            6               4"
       *
       * From the Sandy Bridge PRM, volume 4 part 2, page 18:
       *
       *     "[DevSNB]: The GT1 product's URB provides 32KB of storage,
       *      arranged as 1024 256-bit rows. The GT2 product's URB provides
       *      64KB of storage, arranged as 2048 256-bit rows. A row
       *      corresponds in size to an EU GRF register. Read/write access to
       *      the URB is generally supported on a row-granular basis."
       */
      dev->gen_opaque = ILO_GEN(6);
      dev->gt = gen_get_snb_gt(info->devid);
      if (dev->gt == 2) {
         dev->eu_count = 12;
         dev->thread_count = 60;
         dev->urb_size = 64 * 1024;
      } else {
         dev->eu_count = 6;
         dev->thread_count = 24;
         dev->urb_size = 32 * 1024;
      }
   } else {
      ilo_err("unknown GPU generation\n");
      return false;
   }

   return true;
}