示例#1
0
static void
nouveau_vp3_decoder_destroy(struct pipe_video_codec *decoder)
{
   struct nouveau_vp3_decoder *dec = (struct nouveau_vp3_decoder *)decoder;
   int i;

   nouveau_bo_ref(NULL, &dec->ref_bo);
   nouveau_bo_ref(NULL, &dec->bitplane_bo);
   nouveau_bo_ref(NULL, &dec->inter_bo[0]);
   nouveau_bo_ref(NULL, &dec->inter_bo[1]);
#if NOUVEAU_VP3_DEBUG_FENCE
   nouveau_bo_ref(NULL, &dec->fence_bo);
#endif
   nouveau_bo_ref(NULL, &dec->fw_bo);

   for (i = 0; i < NOUVEAU_VP3_VIDEO_QDEPTH; ++i)
      nouveau_bo_ref(NULL, &dec->bsp_bo[i]);

   nouveau_object_del(&dec->bsp);
   nouveau_object_del(&dec->vp);
   nouveau_object_del(&dec->ppp);

   if (dec->channel[0] != dec->channel[1]) {
      for (i = 0; i < 3; ++i) {
         nouveau_pushbuf_del(&dec->pushbuf[i]);
         nouveau_object_del(&dec->channel[i]);
      }
   } else {
      nouveau_pushbuf_del(dec->pushbuf);
      nouveau_object_del(dec->channel);
   }

   FREE(dec);
}
示例#2
0
static void
nv30_screen_destroy(struct pipe_screen *pscreen)
{
   struct nv30_screen *screen = nv30_screen(pscreen);

   if (screen->base.fence.current &&
       screen->base.fence.current->state >= NOUVEAU_FENCE_STATE_EMITTED) {
      nouveau_fence_wait(screen->base.fence.current);
      nouveau_fence_ref (NULL, &screen->base.fence.current);
   }

   nouveau_object_del(&screen->query);
   nouveau_object_del(&screen->fence);
   nouveau_object_del(&screen->ntfy);

   nouveau_object_del(&screen->sifm);
   nouveau_object_del(&screen->swzsurf);
   nouveau_object_del(&screen->surf2d);
   nouveau_object_del(&screen->m2mf);
   nouveau_object_del(&screen->eng3d);
   nouveau_object_del(&screen->null);

   nouveau_screen_fini(&screen->base);
   FREE(screen);
}
示例#3
0
static void
nv30_screen_destroy(struct pipe_screen *pscreen)
{
   struct nv30_screen *screen = nv30_screen(pscreen);

   if (!nouveau_drm_screen_unref(&screen->base))
      return;

   if (screen->base.fence.current) {
      struct nouveau_fence *current = NULL;

      /* nouveau_fence_wait will create a new current fence, so wait on the
       * _current_ one, and remove both.
       */
      nouveau_fence_ref(screen->base.fence.current, &current);
      nouveau_fence_wait(current);
      nouveau_fence_ref(NULL, &current);
      nouveau_fence_ref(NULL, &screen->base.fence.current);
   }

   nouveau_object_del(&screen->query);
   nouveau_object_del(&screen->fence);
   nouveau_object_del(&screen->ntfy);

   nouveau_object_del(&screen->sifm);
   nouveau_object_del(&screen->swzsurf);
   nouveau_object_del(&screen->surf2d);
   nouveau_object_del(&screen->m2mf);
   nouveau_object_del(&screen->eng3d);
   nouveau_object_del(&screen->null);

   nouveau_screen_fini(&screen->base);
   FREE(screen);
}
示例#4
0
static void
nv50_screen_destroy(struct pipe_screen *pscreen)
{
   struct nv50_screen *screen = nv50_screen(pscreen);

   if (!nouveau_drm_screen_unref(&screen->base))
      return;

   if (screen->base.fence.current) {
      struct nouveau_fence *current = NULL;

      /* nouveau_fence_wait will create a new current fence, so wait on the
       * _current_ one, and remove both.
       */
      nouveau_fence_ref(screen->base.fence.current, &current);
      nouveau_fence_wait(current, NULL);
      nouveau_fence_ref(NULL, &current);
      nouveau_fence_ref(NULL, &screen->base.fence.current);
   }
   if (screen->base.pushbuf)
      screen->base.pushbuf->user_priv = NULL;

   if (screen->blitter)
      nv50_blitter_destroy(screen);
   if (screen->pm.prog) {
      screen->pm.prog->code = NULL; /* hardcoded, don't FREE */
      nv50_program_destroy(NULL, screen->pm.prog);
      FREE(screen->pm.prog);
   }

   nouveau_bo_ref(NULL, &screen->code);
   nouveau_bo_ref(NULL, &screen->tls_bo);
   nouveau_bo_ref(NULL, &screen->stack_bo);
   nouveau_bo_ref(NULL, &screen->txc);
   nouveau_bo_ref(NULL, &screen->uniforms);
   nouveau_bo_ref(NULL, &screen->fence.bo);

   nouveau_heap_destroy(&screen->vp_code_heap);
   nouveau_heap_destroy(&screen->gp_code_heap);
   nouveau_heap_destroy(&screen->fp_code_heap);

   FREE(screen->tic.entries);

   nouveau_object_del(&screen->tesla);
   nouveau_object_del(&screen->eng2d);
   nouveau_object_del(&screen->m2mf);
   nouveau_object_del(&screen->compute);
   nouveau_object_del(&screen->sync);

   nouveau_screen_fini(&screen->base);

   FREE(screen);
}
示例#5
0
static void
nv04_context_destroy(struct gl_context *ctx)
{
	struct nouveau_context *nctx = to_nouveau_context(ctx);

	nv04_surface_takedown(ctx);
	nv04_render_destroy(ctx);
	nouveau_surface_ref(NULL, &to_nv04_context(ctx)->dummy_texture);

	nouveau_object_del(&nctx->hw.eng3d);
	nouveau_object_del(&nctx->hw.eng3dm);
	nouveau_object_del(&nctx->hw.surf3d);

	nouveau_context_deinit(ctx);
	FREE(ctx);
}
示例#6
0
void
nv04_surface_takedown(struct gl_context *ctx)
{
    struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw;

    nouveau_object_del(&hw->swzsurf);
    nouveau_object_del(&hw->sifm);
    nouveau_object_del(&hw->rect);
    nouveau_object_del(&hw->rop);
    nouveau_object_del(&hw->patt);
    nouveau_object_del(&hw->surf2d);
    nouveau_object_del(&hw->m2mf);
    nouveau_object_del(&hw->ntfy);
}
示例#7
0
static void
nv50_screen_destroy(struct pipe_screen *pscreen)
{
   struct nv50_screen *screen = nv50_screen(pscreen);

   if (screen->base.fence.current) {
      nouveau_fence_wait(screen->base.fence.current);
      nouveau_fence_ref (NULL, &screen->base.fence.current);
   }
   if (screen->base.pushbuf)
      screen->base.pushbuf->user_priv = NULL;

   if (screen->blitctx)
      FREE(screen->blitctx);

   nouveau_bo_ref(NULL, &screen->code);
   nouveau_bo_ref(NULL, &screen->tls_bo);
   nouveau_bo_ref(NULL, &screen->stack_bo);
   nouveau_bo_ref(NULL, &screen->txc);
   nouveau_bo_ref(NULL, &screen->uniforms);
   nouveau_bo_ref(NULL, &screen->fence.bo);

   nouveau_heap_destroy(&screen->vp_code_heap);
   nouveau_heap_destroy(&screen->gp_code_heap);
   nouveau_heap_destroy(&screen->fp_code_heap);

   if (screen->tic.entries)
      FREE(screen->tic.entries);

   nouveau_object_del(&screen->tesla);
   nouveau_object_del(&screen->eng2d);
   nouveau_object_del(&screen->m2mf);
   nouveau_object_del(&screen->sync);

   nouveau_screen_fini(&screen->base);

   FREE(screen);
}
static void
nv10_context_destroy(struct gl_context *ctx)
{
	struct nouveau_context *nctx = to_nouveau_context(ctx);

	nv04_surface_takedown(ctx);
	nv10_swtnl_destroy(ctx);
	nv10_vbo_destroy(ctx);

	nouveau_object_del(&nctx->hw.eng3d);

	nouveau_context_deinit(ctx);
	free(ctx);
}
示例#9
0
int
nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
{
	struct pipe_screen *pscreen = &screen->base;
	struct nv04_fifo nv04_data = { .vram = 0xbeef0201, .gart = 0xbeef0202 };
	struct nvc0_fifo nvc0_data = { };
	uint64_t time;
	int size, ret;
	void *data;
	union nouveau_bo_config mm_config;

	char *nv_dbg = getenv("NOUVEAU_MESA_DEBUG");
	if (nv_dbg)
	   nouveau_mesa_debug = atoi(nv_dbg);

	/*
	 * this is initialized to 1 in nouveau_drm_screen_create after screen
	 * is fully constructed and added to the global screen list.
	 */
	screen->refcount = -1;

	if (dev->chipset < 0xc0) {
		data = &nv04_data;
		size = sizeof(nv04_data);
	} else {
		data = &nvc0_data;
		size = sizeof(nvc0_data);
	}

	ret = nouveau_object_new(&dev->object, 0, NOUVEAU_FIFO_CHANNEL_CLASS,
				 data, size, &screen->channel);
	if (ret)
		return ret;
	screen->device = dev;

	ret = nouveau_client_new(screen->device, &screen->client);
	if (ret)
		return ret;
	ret = nouveau_pushbuf_new(screen->client, screen->channel,
				  4, 512 * 1024, 1,
				  &screen->pushbuf);
	if (ret)
		return ret;

        /* getting CPU time first appears to be more accurate */
        screen->cpu_gpu_time_delta = os_time_get();

        ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_PTIMER_TIME, &time);
        if (!ret)
           screen->cpu_gpu_time_delta = time - screen->cpu_gpu_time_delta * 1000;

	pscreen->get_name = nouveau_screen_get_name;
	pscreen->get_vendor = nouveau_screen_get_vendor;
	pscreen->get_device_vendor = nouveau_screen_get_device_vendor;

	pscreen->get_timestamp = nouveau_screen_get_timestamp;

	pscreen->fence_reference = nouveau_screen_fence_ref;
	pscreen->fence_signalled = nouveau_screen_fence_signalled;
	pscreen->fence_finish = nouveau_screen_fence_finish;

	util_format_s3tc_init();

	screen->lowmem_bindings = PIPE_BIND_GLOBAL; /* gallium limit */
	screen->vidmem_bindings =
		PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL |
		PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT |
		PIPE_BIND_CURSOR |
		PIPE_BIND_SAMPLER_VIEW |
		PIPE_BIND_SHADER_RESOURCE | PIPE_BIND_COMPUTE_RESOURCE |
		PIPE_BIND_GLOBAL;
	screen->sysmem_bindings =
		PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_STREAM_OUTPUT |
		PIPE_BIND_COMMAND_ARGS_BUFFER;

	memset(&mm_config, 0, sizeof(mm_config));

	screen->mm_GART = nouveau_mm_create(dev,
					    NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
					    &mm_config);
	screen->mm_VRAM = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, &mm_config);
	return 0;
}

void
nouveau_screen_fini(struct nouveau_screen *screen)
{
	nouveau_mm_destroy(screen->mm_GART);
	nouveau_mm_destroy(screen->mm_VRAM);

	nouveau_pushbuf_del(&screen->pushbuf);

	nouveau_client_del(&screen->client);
	nouveau_object_del(&screen->channel);

	nouveau_device_del(&screen->device);
}
示例#10
0
int
nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
{
   struct pipe_screen *pscreen = &screen->base;
   struct nv04_fifo nv04_data = { .vram = 0xbeef0201, .gart = 0xbeef0202 };
   struct nvc0_fifo nvc0_data = { };
   uint64_t time;
   int size, ret;
   void *data;
   union nouveau_bo_config mm_config;

   char *nv_dbg = getenv("NOUVEAU_MESA_DEBUG");
   if (nv_dbg)
      nouveau_mesa_debug = atoi(nv_dbg);

   screen->prefer_nir = debug_get_bool_option("NV50_PROG_USE_NIR", false);

   /* These must be set before any failure is possible, as the cleanup
    * paths assume they're responsible for deleting them.
    */
   screen->drm = nouveau_drm(&dev->object);
   screen->device = dev;

   /*
    * this is initialized to 1 in nouveau_drm_screen_create after screen
    * is fully constructed and added to the global screen list.
    */
   screen->refcount = -1;

   if (dev->chipset < 0xc0) {
      data = &nv04_data;
      size = sizeof(nv04_data);
   } else {
      data = &nvc0_data;
      size = sizeof(nvc0_data);
   }

   /*
    * Set default VRAM domain if not overridden
    */
   if (!screen->vram_domain) {
      if (dev->vram_size > 0)
         screen->vram_domain = NOUVEAU_BO_VRAM;
      else
         screen->vram_domain = NOUVEAU_BO_GART;
   }

   ret = nouveau_object_new(&dev->object, 0, NOUVEAU_FIFO_CHANNEL_CLASS,
                            data, size, &screen->channel);
   if (ret)
      return ret;

   ret = nouveau_client_new(screen->device, &screen->client);
   if (ret)
      return ret;
   ret = nouveau_pushbuf_new(screen->client, screen->channel,
                             4, 512 * 1024, 1,
                             &screen->pushbuf);
   if (ret)
      return ret;

   /* getting CPU time first appears to be more accurate */
   screen->cpu_gpu_time_delta = os_time_get();

   ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_PTIMER_TIME, &time);
   if (!ret)
      screen->cpu_gpu_time_delta = time - screen->cpu_gpu_time_delta * 1000;

   pscreen->get_name = nouveau_screen_get_name;
   pscreen->get_vendor = nouveau_screen_get_vendor;
   pscreen->get_device_vendor = nouveau_screen_get_device_vendor;
   pscreen->get_disk_shader_cache = nouveau_screen_get_disk_shader_cache;

   pscreen->get_timestamp = nouveau_screen_get_timestamp;

   pscreen->fence_reference = nouveau_screen_fence_ref;
   pscreen->fence_finish = nouveau_screen_fence_finish;

   nouveau_disk_cache_create(screen);

   screen->transfer_pushbuf_threshold = 192;
   screen->lowmem_bindings = PIPE_BIND_GLOBAL; /* gallium limit */
   screen->vidmem_bindings =
      PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL |
      PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT |
      PIPE_BIND_CURSOR |
      PIPE_BIND_SAMPLER_VIEW |
      PIPE_BIND_SHADER_BUFFER | PIPE_BIND_SHADER_IMAGE |
      PIPE_BIND_COMPUTE_RESOURCE |
      PIPE_BIND_GLOBAL;
   screen->sysmem_bindings =
      PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_STREAM_OUTPUT |
      PIPE_BIND_COMMAND_ARGS_BUFFER;

   memset(&mm_config, 0, sizeof(mm_config));

   screen->mm_GART = nouveau_mm_create(dev,
                                       NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
                                       &mm_config);
   screen->mm_VRAM = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, &mm_config);
   return 0;
}

void
nouveau_screen_fini(struct nouveau_screen *screen)
{
   int fd = screen->drm->fd;

   nouveau_mm_destroy(screen->mm_GART);
   nouveau_mm_destroy(screen->mm_VRAM);

   nouveau_pushbuf_del(&screen->pushbuf);

   nouveau_client_del(&screen->client);
   nouveau_object_del(&screen->channel);

   nouveau_device_del(&screen->device);
   nouveau_drm_del(&screen->drm);
   close(fd);

   disk_cache_destroy(screen->disk_shader_cache);
}
示例#11
0
static int
firmware_present(struct pipe_screen *pscreen, enum pipe_video_profile profile)
{
   struct nouveau_screen *screen = nouveau_screen(pscreen);
   int chipset = screen->device->chipset;
   int vp3 = chipset < 0xa3 || chipset == 0xaa || chipset == 0xac;
   int vp5 = chipset >= 0xd0;
   int ret;

   /* For all chipsets, try to create a BSP objects. Assume that if firmware
    * is present for it, firmware is also present for VP/PPP */
   if (!(screen->firmware_info.profiles_checked & 1)) {
      struct nouveau_object *channel = NULL, *bsp = NULL;
      struct nv04_fifo nv04_data = {.vram = 0xbeef0201, .gart = 0xbeef0202};
      struct nvc0_fifo nvc0_args = {};
      struct nve0_fifo nve0_args = {.engine = NVE0_FIFO_ENGINE_BSP};
      void *data = NULL;
      int size, oclass;
      if (chipset < 0xc0)
         oclass = 0x85b1;
      else if (vp5)
         oclass = 0x95b1;
      else
         oclass = 0x90b1;

      if (chipset < 0xc0) {
         data = &nv04_data;
         size = sizeof(nv04_data);
      } else if (chipset < 0xe0) {
         data = &nvc0_args;
         size = sizeof(nvc0_args);
      } else {
         data = &nve0_args;
         size = sizeof(nve0_args);
      }

      /* kepler must have its own channel, so just do this for everyone */
      nouveau_object_new(&screen->device->object, 0,
                         NOUVEAU_FIFO_CHANNEL_CLASS,
                         data, size, &channel);

      if (channel) {
         nouveau_object_new(channel, 0, oclass, NULL, 0, &bsp);
         if (bsp)
            screen->firmware_info.profiles_present |= 1;
         nouveau_object_del(&bsp);
         nouveau_object_del(&channel);
      }
      screen->firmware_info.profiles_checked |= 1;
   }

   if (!(screen->firmware_info.profiles_present & 1))
      return 0;

   /* For vp3/vp4 chipsets, make sure that the relevant firmware is present */
   if (!vp5 && !(screen->firmware_info.profiles_checked & (1 << profile))) {
      char path[PATH_MAX];
      struct stat s;
      if (vp3)
         vp3_getpath(profile, path);
      else
         vp4_getpath(profile, path);
      ret = stat(path, &s);
      if (!ret && s.st_size > 1000)
         screen->firmware_info.profiles_present |= (1 << profile);
      screen->firmware_info.profiles_checked |= (1 << profile);
   }

   return vp5 || (screen->firmware_info.profiles_present & (1 << profile));
}

int
nouveau_vp3_screen_get_video_param(struct pipe_screen *pscreen,
                                   enum pipe_video_profile profile,
                                   enum pipe_video_entrypoint entrypoint,
                                   enum pipe_video_cap param)
{
   int chipset = nouveau_screen(pscreen)->device->chipset;
   int vp3 = chipset < 0xa3 || chipset == 0xaa || chipset == 0xac;
   int vp5 = chipset >= 0xd0;
   enum pipe_video_format codec = u_reduce_video_profile(profile);
   switch (param) {
   case PIPE_VIDEO_CAP_SUPPORTED:
      /* VP3 does not support MPEG4, VP4+ do. */
      return entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM &&
         profile >= PIPE_VIDEO_PROFILE_MPEG1 &&
         (!vp3 || codec != PIPE_VIDEO_FORMAT_MPEG4) &&
         firmware_present(pscreen, profile);
   case PIPE_VIDEO_CAP_NPOT_TEXTURES:
      return 1;
   case PIPE_VIDEO_CAP_MAX_WIDTH:
   case PIPE_VIDEO_CAP_MAX_HEIGHT:
      return vp5 ? 4096 : 2048;
   case PIPE_VIDEO_CAP_PREFERED_FORMAT:
      return PIPE_FORMAT_NV12;
   case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED:
   case PIPE_VIDEO_CAP_PREFERS_INTERLACED:
      return true;
   case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE:
      return false;
   case PIPE_VIDEO_CAP_MAX_LEVEL:
      switch (profile) {
      case PIPE_VIDEO_PROFILE_MPEG1:
         return 0;
      case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE:
      case PIPE_VIDEO_PROFILE_MPEG2_MAIN:
         return 3;
      case PIPE_VIDEO_PROFILE_MPEG4_SIMPLE:
         return 3;
      case PIPE_VIDEO_PROFILE_MPEG4_ADVANCED_SIMPLE:
         return 5;
      case PIPE_VIDEO_PROFILE_VC1_SIMPLE:
         return 1;
      case PIPE_VIDEO_PROFILE_VC1_MAIN:
         return 2;
      case PIPE_VIDEO_PROFILE_VC1_ADVANCED:
         return 4;
      case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE:
      case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN:
      case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH:
         return 41;
      default:
         debug_printf("unknown video profile: %d\n", profile);
         return 0;
      }
   default:
      debug_printf("unknown video param: %d\n", param);
      return 0;
   }
}