Esempio n. 1
0
static bool
tex_create_hiz(struct ilo_texture *tex)
{
   const struct pipe_resource *templ = &tex->base;
   struct ilo_screen *is = ilo_screen(tex->base.screen);
   unsigned lv;

   tex->aux_bo = intel_winsys_alloc_bo(is->winsys, "hiz texture",
         INTEL_TILING_Y, tex->layout.aux_stride, tex->layout.aux_height,
         false);
   if (!tex->aux_bo)
      return false;

   for (lv = 0; lv <= templ->last_level; lv++) {
      if (tex->layout.aux_enables & (1 << lv)) {
         const unsigned num_slices = (templ->target == PIPE_TEXTURE_3D) ?
            u_minify(templ->depth0, lv) : templ->array_size;
         unsigned flags = ILO_TEXTURE_HIZ;

         /* this will trigger a HiZ resolve */
         if (tex->imported)
            flags |= ILO_TEXTURE_CPU_WRITE;

         ilo_texture_set_slice_flags(tex, lv, 0, num_slices, flags, flags);
      }
   }

   return true;
}
Esempio n. 2
0
static bool
tex_init_layout(struct ilo_texture *tex)
{
   struct ilo_screen *is = ilo_screen(tex->base.screen);
   const struct pipe_resource *templ = &tex->base;
   struct ilo_layout *layout = &tex->layout;

   ilo_layout_init(layout, &is->dev, templ);

   if (layout->bo_height > ilo_max_resource_size / layout->bo_stride)
      return false;

   if (templ->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT) {
      /* require on-the-fly tiling/untiling or format conversion */
      if (layout->separate_stencil ||
          layout->format == PIPE_FORMAT_S8_UINT ||
          layout->format != templ->format)
         return false;
   }

   if (!tex_alloc_slices(tex))
      return false;

   return true;
}
Esempio n. 3
0
static uint64_t
ilo_get_timestamp(struct pipe_screen *screen)
{
   struct ilo_screen *is = ilo_screen(screen);
   union {
      uint64_t val;
      uint32_t dw[2];
   } timestamp;

   intel_winsys_read_reg(is->winsys, TIMESTAMP, &timestamp.val);

   /*
    * From the Ivy Bridge PRM, volume 1 part 3, page 107:
    *
    *     "Note: This timestamp register reflects the value of the PCU TSC.
    *      The PCU TSC counts 10ns increments; this timestamp reflects bits
    *      38:3 of the TSC (i.e. 80ns granularity, rolling over every 1.5
    *      hours)."
    *
    * However, it seems dw[0] is garbage and dw[1] contains the lower 32 bits
    * of the timestamp.  We will have to live with a timestamp that rolls over
    * every ~343 seconds.
    *
    * See also brw_get_timestamp().
    */
   return (uint64_t) timestamp.dw[1] * 80;
}
Esempio n. 4
0
static void
tex_layout_init(struct tex_layout *layout,
                struct pipe_screen *screen,
                const struct pipe_resource *templ,
                struct ilo_texture_slice **slices)
{
   struct ilo_screen *is = ilo_screen(screen);

   memset(layout, 0, sizeof(*layout));

   layout->dev = &is->dev;
   layout->templ = templ;

   /* note that there are dependencies between these functions */
   tex_layout_init_hiz(layout);
   tex_layout_init_format(layout);
   tex_layout_init_tiling(layout);
   tex_layout_init_spacing(layout);
   tex_layout_init_levels(layout);
   tex_layout_init_alignments(layout);
   tex_layout_init_qpitch(layout);

   if (slices) {
      int lv;

      for (lv = 0; lv <= templ->last_level; lv++)
         layout->levels[lv].slices = slices[lv];
   }
}
Esempio n. 5
0
static void
ilo_screen_destroy(struct pipe_screen *screen)
{
   struct ilo_screen *is = ilo_screen(screen);

   /* as it seems, winsys is owned by the screen */
   intel_winsys_destroy(is->winsys);

   FREE(is);
}
Esempio n. 6
0
static struct pipe_resource *
buf_create(struct pipe_screen *screen, const struct pipe_resource *templ)
{
   const struct ilo_screen *is = ilo_screen(screen);
   struct ilo_buffer *buf;

   buf = CALLOC_STRUCT(ilo_buffer);
   if (!buf)
      return NULL;

   buf->base = *templ;
   buf->base.screen = screen;
   pipe_reference_init(&buf->base.reference, 1);

   buf->bo_size = templ->width0;

   /*
    * From the Sandy Bridge PRM, volume 1 part 1, page 118:
    *
    *     "For buffers, which have no inherent "height," padding requirements
    *      are different. A buffer must be padded to the next multiple of 256
    *      array elements, with an additional 16 bytes added beyond that to
    *      account for the L1 cache line."
    */
   if (templ->bind & PIPE_BIND_SAMPLER_VIEW)
      buf->bo_size = align(buf->bo_size, 256) + 16;

   if ((templ->bind & PIPE_BIND_VERTEX_BUFFER) &&
        ilo_dev_gen(&is->dev) < ILO_GEN(7.5)) {
      /*
       * As noted in ilo_translate_format(), we treat some 3-component formats
       * as 4-component formats to work around hardware limitations.  Imagine
       * the case where the vertex buffer holds a single
       * PIPE_FORMAT_R16G16B16_FLOAT vertex, and buf->bo_size is 6.  The
       * hardware would fail to fetch it at boundary check because the vertex
       * buffer is expected to hold a PIPE_FORMAT_R16G16B16A16_FLOAT vertex
       * and that takes at least 8 bytes.
       *
       * For the workaround to work, we should add 2 to the bo size.  But that
       * would waste a page when the bo size is already page aligned.  Let's
       * round it to page size for now and revisit this when needed.
       */
      buf->bo_size = align(buf->bo_size, 4096);
   }

   if (buf->bo_size < templ->width0 ||
       buf->bo_size > ilo_max_resource_size ||
       !buf_create_bo(buf)) {
      FREE(buf);
      return NULL;
   }

   return &buf->base;
}
Esempio n. 7
0
static bool
tex_get_handle(struct ilo_texture *tex, struct winsys_handle *handle)
{
   struct ilo_screen *is = ilo_screen(tex->base.screen);
   int err;

   err = intel_winsys_export_handle(is->winsys, tex->bo, tex->layout.tiling,
         tex->layout.bo_stride, tex->layout.bo_height, handle);

   return !err;
}
Esempio n. 8
0
static bool
buf_create_bo(struct ilo_buffer *buf)
{
   struct ilo_screen *is = ilo_screen(buf->base.screen);
   const char *name = resource_get_bo_name(&buf->base);
   const bool cpu_init = resource_get_cpu_init(&buf->base);

   buf->bo = intel_winsys_alloc_buffer(is->winsys, name,
         buf->bo_size, cpu_init);

   return (buf->bo != NULL);
}
Esempio n. 9
0
static bool
tex_create_bo(struct ilo_texture *tex)
{
   struct ilo_screen *is = ilo_screen(tex->base.screen);
   const char *name = resource_get_bo_name(&tex->base);
   const bool cpu_init = resource_get_cpu_init(&tex->base);

   tex->bo = intel_winsys_alloc_bo(is->winsys, name, tex->layout.tiling,
         tex->layout.bo_stride, tex->layout.bo_height, cpu_init);

   return (tex->bo != NULL);
}
Esempio n. 10
0
static bool
tex_create_bo(struct ilo_texture *tex)
{
   struct ilo_screen *is = ilo_screen(tex->base.screen);
   const char *name = resource_get_bo_name(&tex->base);
   const enum intel_domain_flag initial_domain =
      resource_get_bo_initial_domain(&tex->base);

   tex->bo = intel_winsys_alloc_bo(is->winsys, name, tex->layout.tiling,
         tex->layout.bo_stride, tex->layout.bo_height, initial_domain);

   return (tex->bo != NULL);
}
Esempio n. 11
0
static bool
buf_create_bo(struct ilo_buffer *buf)
{
   struct ilo_screen *is = ilo_screen(buf->base.screen);
   const char *name = resource_get_bo_name(&buf->base);
   const enum intel_domain_flag initial_domain =
      resource_get_bo_initial_domain(&buf->base);

   buf->bo = intel_winsys_alloc_buffer(is->winsys, name,
         buf->bo_size, initial_domain);

   return (buf->bo != NULL);
}
Esempio n. 12
0
static boolean
ilo_can_create_resource(struct pipe_screen *screen,
                        const struct pipe_resource *templ)
{
   struct ilo_layout layout;

   if (templ->target == PIPE_BUFFER)
      return (templ->width0 <= ilo_max_resource_size);

   memset(&layout, 0, sizeof(layout));
   ilo_layout_init(&layout, &ilo_screen(screen)->dev, templ);

   return (layout.bo_height <= ilo_max_resource_size / layout.bo_stride);
}
Esempio n. 13
0
static bool
tex_create_mcs(struct ilo_texture *tex)
{
   struct ilo_screen *is = ilo_screen(tex->base.screen);

   assert(tex->layout.aux_enables == (1 << (tex->base.last_level + 1)) - 1);

   tex->aux_bo = intel_winsys_alloc_bo(is->winsys, "mcs texture",
         INTEL_TILING_Y, tex->layout.aux_stride, tex->layout.aux_height,
         false);
   if (!tex->aux_bo)
      return false;

   return true;
}
Esempio n. 14
0
static bool
tex_import_handle(struct ilo_texture *tex,
                  const struct winsys_handle *handle)
{
   struct ilo_screen *is = ilo_screen(tex->base.screen);
   const char *name = resource_get_bo_name(&tex->base);
   enum intel_tiling_mode tiling;
   unsigned long pitch;

   tex->bo = intel_winsys_import_handle(is->winsys, name, handle,
         tex->layout.bo_height, &tiling, &pitch);
   if (!tex->bo)
      return false;

   if (!ilo_layout_update_for_imported_bo(&tex->layout, tiling, pitch)) {
      ilo_err("imported handle has incompatible tiling/pitch\n");
      intel_bo_unreference(tex->bo);
      tex->bo = NULL;
      return false;
   }

   return true;
}
Esempio n. 15
0
static bool
tex_alloc_bos(struct ilo_texture *tex,
              const struct winsys_handle *handle)
{
   struct ilo_screen *is = ilo_screen(tex->base.screen);

   if (handle) {
      if (!tex_import_handle(tex, handle))
         return false;
   } else {
      if (!tex_create_bo(tex))
         return false;
   }

   /* allocate separate stencil resource */
   if (tex->layout.separate_stencil && !tex_create_separate_stencil(tex))
      return false;

   switch (tex->layout.aux) {
   case ILO_LAYOUT_AUX_HIZ:
      if (!tex_create_hiz(tex)) {
         /* Separate Stencil Buffer requires HiZ to be enabled */
         if (ilo_dev_gen(&is->dev) == ILO_GEN(6) &&
             tex->layout.separate_stencil)
            return false;
      }
      break;
   case ILO_LAYOUT_AUX_MCS:
      if (!tex_create_mcs(tex))
         return false;
      break;
   default:
      break;
   }

   return true;
}
Esempio n. 16
0
static bool
buf_create_bo(struct ilo_buffer *buf)
{
   struct ilo_screen *is = ilo_screen(buf->base.screen);
   const char *name;
   struct intel_bo *bo;

   switch (buf->base.bind) {
   case PIPE_BIND_VERTEX_BUFFER:
      name = "vertex buffer";
      break;
   case PIPE_BIND_INDEX_BUFFER:
      name = "index buffer";
      break;
   case PIPE_BIND_CONSTANT_BUFFER:
      name = "constant buffer";
      break;
   case PIPE_BIND_STREAM_OUTPUT:
      name = "stream output";
      break;
   default:
      name = "unknown buffer";
      break;
   }

   bo = intel_winsys_alloc_buffer(is->winsys,
         name, buf->bo_size, buf->bo_flags);
   if (!bo)
      return false;

   if (buf->bo)
      intel_bo_unreference(buf->bo);

   buf->bo = bo;

   return true;
}
Esempio n. 17
0
static bool
tex_create_bo(struct ilo_texture *tex,
              const struct winsys_handle *handle)
{
   struct ilo_screen *is = ilo_screen(tex->base.screen);
   const char *name;
   struct intel_bo *bo;
   enum intel_tiling_mode tiling;
   unsigned long pitch;

   switch (tex->base.target) {
   case PIPE_TEXTURE_1D:
      name = "1D texture";
      break;
   case PIPE_TEXTURE_2D:
      name = "2D texture";
      break;
   case PIPE_TEXTURE_3D:
      name = "3D texture";
      break;
   case PIPE_TEXTURE_CUBE:
      name = "cube texture";
      break;
   case PIPE_TEXTURE_RECT:
      name = "rectangle texture";
      break;
   case PIPE_TEXTURE_1D_ARRAY:
      name = "1D array texture";
      break;
   case PIPE_TEXTURE_2D_ARRAY:
      name = "2D array texture";
      break;
   case PIPE_TEXTURE_CUBE_ARRAY:
      name = "cube array texture";
      break;
   default:
      name ="unknown texture";
      break;
   }

   if (handle) {
      bo = intel_winsys_import_handle(is->winsys, name, handle,
            tex->bo_width, tex->bo_height, tex->bo_cpp,
            &tiling, &pitch);
   }
   else {
      bo = intel_winsys_alloc_texture(is->winsys, name,
            tex->bo_width, tex->bo_height, tex->bo_cpp,
            tex->tiling, tex->bo_flags, &pitch);

      tiling = tex->tiling;
   }

   if (!bo)
      return false;

   if (tex->bo)
      intel_bo_unreference(tex->bo);

   tex->bo = bo;
   tex->tiling = tiling;
   tex->bo_stride = pitch;

   return true;
}
Esempio n. 18
0
static struct pipe_context *
ilo_context_create(struct pipe_screen *screen, void *priv)
{
   struct ilo_screen *is = ilo_screen(screen);
   struct ilo_context *ilo;

   ilo = CALLOC_STRUCT(ilo_context);
   if (!ilo)
      return NULL;

   ilo->winsys = is->winsys;
   ilo->dev = &is->dev;

   /*
    * initialize first, otherwise it may not be safe to call
    * ilo_context_destroy() on errors
    */
   util_slab_create(&ilo->transfer_mempool,
         sizeof(struct ilo_transfer), 64, UTIL_SLAB_SINGLETHREADED);

   /* 8192 DWords */
   ilo->cp = ilo_cp_create(ilo->winsys, 8192, is->dev.has_llc);
   ilo->shader_cache = ilo_shader_cache_create();
   if (ilo->cp)
      ilo->hw3d = ilo_3d_create(ilo->cp, ilo->dev);

   if (!ilo->cp || !ilo->shader_cache || !ilo->hw3d) {
      ilo_context_destroy(&ilo->base);
      return NULL;
   }

   ilo_cp_set_flush_callback(ilo->cp,
         ilo_context_cp_flushed, (void *) ilo);

   ilo->base.screen = screen;
   ilo->base.priv = priv;

   ilo->base.destroy = ilo_context_destroy;
   ilo->base.flush = ilo_flush;

   ilo_init_3d_functions(ilo);
   ilo_init_query_functions(ilo);
   ilo_init_state_functions(ilo);
   ilo_init_blit_functions(ilo);
   ilo_init_transfer_functions(ilo);
   ilo_init_video_functions(ilo);
   ilo_init_gpgpu_functions(ilo);

   ilo_init_states(ilo);

   /*
    * These must be called last as u_upload/u_blitter are clients of the pipe
    * context.
    */
   ilo->uploader = u_upload_create(&ilo->base, 1024 * 1024, 16,
         PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_INDEX_BUFFER);
   if (!ilo->uploader) {
      ilo_context_destroy(&ilo->base);
      return NULL;
   }

   ilo->blitter = ilo_blitter_create(ilo);
   if (!ilo->blitter) {
      ilo_context_destroy(&ilo->base);
      return NULL;
   }

   return &ilo->base;
}
Esempio n. 19
0
static const char *
ilo_get_name(struct pipe_screen *screen)
{
   struct ilo_screen *is = ilo_screen(screen);
   const char *chipset;

   /* stolen from classic i965 */
   switch (is->dev.devid) {
   case PCI_CHIP_SANDYBRIDGE_GT1:
   case PCI_CHIP_SANDYBRIDGE_GT2:
   case PCI_CHIP_SANDYBRIDGE_GT2_PLUS:
      chipset = "Intel(R) Sandybridge Desktop";
      break;
   case PCI_CHIP_SANDYBRIDGE_M_GT1:
   case PCI_CHIP_SANDYBRIDGE_M_GT2:
   case PCI_CHIP_SANDYBRIDGE_M_GT2_PLUS:
      chipset = "Intel(R) Sandybridge Mobile";
      break;
   case PCI_CHIP_SANDYBRIDGE_S:
      chipset = "Intel(R) Sandybridge Server";
      break;
   case PCI_CHIP_IVYBRIDGE_GT1:
   case PCI_CHIP_IVYBRIDGE_GT2:
      chipset = "Intel(R) Ivybridge Desktop";
      break;
   case PCI_CHIP_IVYBRIDGE_M_GT1:
   case PCI_CHIP_IVYBRIDGE_M_GT2:
      chipset = "Intel(R) Ivybridge Mobile";
      break;
   case PCI_CHIP_IVYBRIDGE_S_GT1:
   case PCI_CHIP_IVYBRIDGE_S_GT2:
      chipset = "Intel(R) Ivybridge Server";
      break;
   case PCI_CHIP_BAYTRAIL_M_1:
   case PCI_CHIP_BAYTRAIL_M_2:
   case PCI_CHIP_BAYTRAIL_M_3:
   case PCI_CHIP_BAYTRAIL_M_4:
   case PCI_CHIP_BAYTRAIL_D:
      chipset = "Intel(R) Bay Trail";
      break;
   case PCI_CHIP_HASWELL_GT1:
   case PCI_CHIP_HASWELL_GT2:
   case PCI_CHIP_HASWELL_GT3:
   case PCI_CHIP_HASWELL_SDV_GT1:
   case PCI_CHIP_HASWELL_SDV_GT2:
   case PCI_CHIP_HASWELL_SDV_GT3:
   case PCI_CHIP_HASWELL_ULT_GT1:
   case PCI_CHIP_HASWELL_ULT_GT2:
   case PCI_CHIP_HASWELL_ULT_GT3:
   case PCI_CHIP_HASWELL_CRW_GT1:
   case PCI_CHIP_HASWELL_CRW_GT2:
   case PCI_CHIP_HASWELL_CRW_GT3:
      chipset = "Intel(R) Haswell Desktop";
      break;
   case PCI_CHIP_HASWELL_M_GT1:
   case PCI_CHIP_HASWELL_M_GT2:
   case PCI_CHIP_HASWELL_M_GT3:
   case PCI_CHIP_HASWELL_SDV_M_GT1:
   case PCI_CHIP_HASWELL_SDV_M_GT2:
   case PCI_CHIP_HASWELL_SDV_M_GT3:
   case PCI_CHIP_HASWELL_ULT_M_GT1:
   case PCI_CHIP_HASWELL_ULT_M_GT2:
   case PCI_CHIP_HASWELL_ULT_M_GT3:
   case PCI_CHIP_HASWELL_CRW_M_GT1:
   case PCI_CHIP_HASWELL_CRW_M_GT2:
   case PCI_CHIP_HASWELL_CRW_M_GT3:
      chipset = "Intel(R) Haswell Mobile";
      break;
   case PCI_CHIP_HASWELL_S_GT1:
   case PCI_CHIP_HASWELL_S_GT2:
   case PCI_CHIP_HASWELL_S_GT3:
   case PCI_CHIP_HASWELL_SDV_S_GT1:
   case PCI_CHIP_HASWELL_SDV_S_GT2:
   case PCI_CHIP_HASWELL_SDV_S_GT3:
   case PCI_CHIP_HASWELL_ULT_S_GT1:
   case PCI_CHIP_HASWELL_ULT_S_GT2:
   case PCI_CHIP_HASWELL_ULT_S_GT3:
   case PCI_CHIP_HASWELL_CRW_S_GT1:
   case PCI_CHIP_HASWELL_CRW_S_GT2:
   case PCI_CHIP_HASWELL_CRW_S_GT3:
      chipset = "Intel(R) Haswell Server";
      break;
   default:
      chipset = "Unknown Intel Chipset";
      break;
   }

   return chipset;
}
Esempio n. 20
0
static int
ilo_get_param(struct pipe_screen *screen, enum pipe_cap param)
{
   struct ilo_screen *is = ilo_screen(screen);

   switch (param) {
   case PIPE_CAP_NPOT_TEXTURES:
   case PIPE_CAP_TWO_SIDED_STENCIL:
      return true;
   case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
      return 0; /* TODO */
   case PIPE_CAP_ANISOTROPIC_FILTER:
   case PIPE_CAP_POINT_SPRITE:
      return true;
   case PIPE_CAP_MAX_RENDER_TARGETS:
      return ILO_MAX_DRAW_BUFFERS;
   case PIPE_CAP_OCCLUSION_QUERY:
   case PIPE_CAP_QUERY_TIME_ELAPSED:
   case PIPE_CAP_TEXTURE_SHADOW_MAP:
   case PIPE_CAP_TEXTURE_SWIZZLE: /* must be supported for shadow map */
      return true;
   case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
      /*
       * As defined in SURFACE_STATE, we have
       *
       *           Max WxHxD for 2D and CUBE     Max WxHxD for 3D
       *  GEN6           8192x8192x512            2048x2048x2048
       *  GEN7         16384x16384x2048           2048x2048x2048
       *
       * However, when the texutre size is large, things become unstable.  We
       * require the maximum texture size to be 2^30 bytes in
       * screen->can_create_resource().  Since the maximum pixel size is 2^4
       * bytes (PIPE_FORMAT_R32G32B32A32_FLOAT), textures should not have more
       * than 2^26 pixels.
       *
       * For 3D textures, we have to set the maximum number of levels to 9,
       * which has at most 2^24 pixels.  For 2D textures, we set it to 14,
       * which has at most 2^26 pixels.  And for cube textures, we has to set
       * it to 12.
       */
      return 14;
   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
      return 9;
   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
      return 12;
   case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
      return false;
   case PIPE_CAP_BLEND_EQUATION_SEPARATE:
   case PIPE_CAP_SM3:
      return true;
   case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
      if (is->dev.gen >= ILO_GEN(7) && !is->dev.has_gen7_sol_reset)
         return 0;
      return ILO_MAX_SO_BUFFERS;
   case PIPE_CAP_PRIMITIVE_RESTART:
      return true;
   case PIPE_CAP_MAX_COMBINED_SAMPLERS:
      return ILO_MAX_SAMPLERS * 2;
   case PIPE_CAP_INDEP_BLEND_ENABLE:
   case PIPE_CAP_INDEP_BLEND_FUNC:
      return true;
   case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
      return (is->dev.gen >= ILO_GEN(7)) ? 2048 : 512;
   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
   case PIPE_CAP_DEPTH_CLIP_DISABLE:
      return true;
   case PIPE_CAP_SHADER_STENCIL_EXPORT:
      return false;
   case PIPE_CAP_TGSI_INSTANCEID:
   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
      return true;
   case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
      return false;
   case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
      return true;
   case PIPE_CAP_SEAMLESS_CUBE_MAP:
   case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
   case PIPE_CAP_SCALED_RESOLVE:
      return true;
   case PIPE_CAP_MIN_TEXEL_OFFSET:
      return -8;
   case PIPE_CAP_MAX_TEXEL_OFFSET:
      return 7;
   case PIPE_CAP_CONDITIONAL_RENDER:
   case PIPE_CAP_TEXTURE_BARRIER:
      return true;
   case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
      return ILO_MAX_SO_BINDINGS / ILO_MAX_SO_BUFFERS;
   case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
      return ILO_MAX_SO_BINDINGS;
   case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
      if (is->dev.gen >= ILO_GEN(7))
         return is->dev.has_gen7_sol_reset;
      else
         return false; /* TODO */
   case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
      return false;
   case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
      return true;
   case PIPE_CAP_VERTEX_COLOR_CLAMPED:
      return false;
   case PIPE_CAP_GLSL_FEATURE_LEVEL:
      return 140;
   case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
   case PIPE_CAP_USER_VERTEX_BUFFERS:
      return false;
   case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
   case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
   case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
      return false;
   case PIPE_CAP_COMPUTE:
      return false; /* TODO */
   case PIPE_CAP_USER_INDEX_BUFFERS:
   case PIPE_CAP_USER_CONSTANT_BUFFERS:
      return true;
   case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
      /* imposed by OWord (Dual) Block Read */
      return 16;
   case PIPE_CAP_START_INSTANCE:
   case PIPE_CAP_QUERY_TIMESTAMP:
      return true;
   case PIPE_CAP_TEXTURE_MULTISAMPLE:
      return false; /* TODO */
   case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
      return 0;
   case PIPE_CAP_CUBE_MAP_ARRAY:
   case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
      return true;
   case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
      return 1;
   case PIPE_CAP_TGSI_TEXCOORD:
      return false;
   case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
      return true;
   case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
      return false; /* TODO */
   case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
      return 0;
   case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
      /* a BRW_SURFACE_BUFFER can have up to 2^27 elements */
      return 1 << 27;
   case PIPE_CAP_MAX_VIEWPORTS:
      return ILO_MAX_VIEWPORTS;
   case PIPE_CAP_ENDIANNESS:
      return PIPE_ENDIAN_LITTLE;

   default:
      return 0;
   }
}
Esempio n. 21
0
static struct pipe_context *
ilo_context_create(struct pipe_screen *screen, void *priv, unsigned flags)
{
   struct ilo_screen *is = ilo_screen(screen);
   struct ilo_context *ilo;

   ilo = CALLOC_STRUCT(ilo_context);
   if (!ilo)
      return NULL;

   ilo->winsys = is->dev.winsys;
   ilo->dev = &is->dev;

   /*
    * initialize first, otherwise it may not be safe to call
    * ilo_context_destroy() on errors
    */
   slab_create(&ilo->transfer_mempool,
         sizeof(struct ilo_transfer), 64);

   ilo->shader_cache = ilo_shader_cache_create();
   ilo->cp = ilo_cp_create(ilo->dev, ilo->winsys, ilo->shader_cache);
   if (ilo->cp)
      ilo->render = ilo_render_create(&ilo->cp->builder);

   if (!ilo->cp || !ilo->shader_cache || !ilo->render) {
      ilo_context_destroy(&ilo->base);
      return NULL;
   }

   ilo_cp_set_submit_callback(ilo->cp,
         ilo_context_cp_submitted, (void *) ilo);

   ilo->base.screen = screen;
   ilo->base.priv = priv;

   ilo->base.destroy = ilo_context_destroy;
   ilo->base.flush = ilo_flush;
   ilo->base.render_condition = ilo_render_condition;

   ilo_init_draw_functions(ilo);
   ilo_init_query_functions(ilo);
   ilo_init_state_functions(ilo);
   ilo_init_blit_functions(ilo);
   ilo_init_transfer_functions(ilo);
   ilo_init_video_functions(ilo);
   ilo_init_gpgpu_functions(ilo);

   ilo_init_draw(ilo);
   ilo_state_vector_init(ilo->dev, &ilo->state_vector);

   /*
    * These must be called last as u_upload/u_blitter are clients of the pipe
    * context.
    */
   ilo->uploader = u_upload_create(&ilo->base, 1024 * 1024,
         PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_INDEX_BUFFER,
                                   PIPE_USAGE_STREAM);
   if (!ilo->uploader) {
      ilo_context_destroy(&ilo->base);
      return NULL;
   }

   ilo->blitter = ilo_blitter_create(ilo);
   if (!ilo->blitter) {
      ilo_context_destroy(&ilo->base);
      return NULL;
   }

   return &ilo->base;
}
Esempio n. 22
0
static bool
tex_create_hiz(struct ilo_texture *tex, const struct tex_layout *layout)
{
   struct ilo_screen *is = ilo_screen(tex->base.screen);
   const struct pipe_resource *templ = layout->templ;
   const int hz_align_j = 8;
   unsigned hz_width, hz_height, lv;
   unsigned long pitch;

   /*
    * See the Sandy Bridge PRM, volume 2 part 1, page 312, and the Ivy Bridge
    * PRM, volume 2 part 1, page 312-313.
    *
    * It seems HiZ buffer is aligned to 8x8, with every two rows packed into a
    * memory row.
    */

   hz_width = align(layout->levels[0].w, 16);

   if (templ->target == PIPE_TEXTURE_3D) {
      hz_height = 0;

      for (lv = 0; lv <= templ->last_level; lv++) {
         const unsigned h = align(layout->levels[lv].h, hz_align_j);
         hz_height += h * layout->levels[lv].d;
      }

      hz_height /= 2;
   }
   else {
      const unsigned h0 = align(layout->levels[0].h, hz_align_j);
      unsigned hz_qpitch = h0;

      if (layout->array_spacing_full) {
         const unsigned h1 = align(layout->levels[1].h, hz_align_j);
         const unsigned htail =
            ((layout->dev->gen >= ILO_GEN(7)) ? 12 : 11) * hz_align_j;

         hz_qpitch += h1 + htail;
      }

      hz_height = hz_qpitch * templ->array_size / 2;

      if (layout->dev->gen >= ILO_GEN(7))
         hz_height = align(hz_height, 8);
   }

   tex->hiz.bo = intel_winsys_alloc_texture(is->winsys,
         "hiz texture", hz_width, hz_height, 1,
         INTEL_TILING_Y, INTEL_ALLOC_FOR_RENDER, &pitch);
   if (!tex->hiz.bo)
      return false;

   tex->hiz.bo_stride = pitch;

   /*
    * From the Sandy Bridge PRM, volume 2 part 1, page 313-314:
    *
    *     "A rectangle primitive representing the clear area is delivered. The
    *      primitive must adhere to the following restrictions on size:
    *
    *      - If Number of Multisamples is NUMSAMPLES_1, the rectangle must be
    *        aligned to an 8x4 pixel block relative to the upper left corner
    *        of the depth buffer, and contain an integer number of these pixel
    *        blocks, and all 8x4 pixels must be lit.
    *
    *      - If Number of Multisamples is NUMSAMPLES_4, the rectangle must be
    *        aligned to a 4x2 pixel block (8x4 sample block) relative to the
    *        upper left corner of the depth buffer, and contain an integer
    *        number of these pixel blocks, and all samples of the 4x2 pixels
    *        must be lit
    *
    *      - If Number of Multisamples is NUMSAMPLES_8, the rectangle must be
    *        aligned to a 2x2 pixel block (8x4 sample block) relative to the
    *        upper left corner of the depth buffer, and contain an integer
    *        number of these pixel blocks, and all samples of the 2x2 pixels
    *        must be list."
    *
    *     "The following is required when performing a depth buffer resolve:
    *
    *      - A rectangle primitive of the same size as the previous depth
    *        buffer clear operation must be delivered, and depth buffer state
    *        cannot have changed since the previous depth buffer clear
    *        operation."
    *
    * Experiments on Haswell show that depth buffer resolves have the same
    * alignment requirements, and aligning the RECTLIST primitive and
    * 3DSTATE_DRAWING_RECTANGLE alone are not enough.  The mipmap size must be
    * aligned.
    */
   for (lv = 0; lv <= templ->last_level; lv++) {
      unsigned align_w = 8, align_h = 4;

      switch (templ->nr_samples) {
      case 0:
      case 1:
         break;
      case 2:
         align_w /= 2;
         break;
      case 4:
         align_w /= 2;
         align_h /= 2;
         break;
      case 8:
      default:
         align_w /= 4;
         align_h /= 2;
         break;
      }

      if (u_minify(templ->width0, lv) % align_w == 0 &&
          u_minify(templ->height0, lv) % align_h == 0) {
         const unsigned num_slices = (templ->target == PIPE_TEXTURE_3D) ?
            u_minify(templ->depth0, lv) : templ->array_size;

         ilo_texture_set_slice_flags(tex, lv, 0, num_slices,
               ILO_TEXTURE_HIZ, ILO_TEXTURE_HIZ);
      }
   }

   return true;
}