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); }
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); }
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, ¤t); nouveau_fence_wait(current); nouveau_fence_ref(NULL, ¤t); 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); }
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, ¤t); nouveau_fence_wait(current, NULL); nouveau_fence_ref(NULL, ¤t); 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); }
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); }
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); }
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); }
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); }
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); }
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; } }