/** * Create a context. * * This is where each context begins. */ struct pipe_context * iris_create_context(struct pipe_screen *pscreen, void *priv, unsigned flags) { struct iris_screen *screen = (struct iris_screen*)pscreen; const struct gen_device_info *devinfo = &screen->devinfo; struct iris_context *ice = rzalloc(NULL, struct iris_context); if (!ice) return NULL; struct pipe_context *ctx = &ice->ctx; ctx->screen = pscreen; ctx->priv = priv; ctx->stream_uploader = u_upload_create_default(ctx); if (!ctx->stream_uploader) { free(ctx); return NULL; } ctx->const_uploader = ctx->stream_uploader; ctx->destroy = iris_destroy_context; ctx->set_debug_callback = iris_set_debug_callback; ctx->set_device_reset_callback = iris_set_device_reset_callback; ctx->get_device_reset_status = iris_get_device_reset_status; ctx->get_sample_position = iris_get_sample_position; ice->shaders.urb_size = devinfo->urb.size; iris_init_context_fence_functions(ctx); iris_init_blit_functions(ctx); iris_init_clear_functions(ctx); iris_init_program_functions(ctx); iris_init_resource_functions(ctx); iris_init_query_functions(ctx); iris_init_flush_functions(ctx); iris_init_program_cache(ice); iris_init_border_color_pool(ice); iris_init_binder(ice); slab_create_child(&ice->transfer_pool, &screen->transfer_pool); ice->state.surface_uploader = u_upload_create(ctx, 16384, PIPE_BIND_CUSTOM, PIPE_USAGE_IMMUTABLE, IRIS_RESOURCE_FLAG_SURFACE_MEMZONE); ice->state.dynamic_uploader = u_upload_create(ctx, 16384, PIPE_BIND_CUSTOM, PIPE_USAGE_IMMUTABLE, IRIS_RESOURCE_FLAG_DYNAMIC_MEMZONE); ice->query_buffer_uploader = u_upload_create(ctx, 4096, PIPE_BIND_CUSTOM, PIPE_USAGE_STAGING, 0); genX_call(devinfo, init_state, ice); genX_call(devinfo, init_blorp, ice); int priority = 0; if (flags & PIPE_CONTEXT_HIGH_PRIORITY) priority = GEN_CONTEXT_HIGH_PRIORITY; if (flags & PIPE_CONTEXT_LOW_PRIORITY) priority = GEN_CONTEXT_LOW_PRIORITY; if (unlikely(INTEL_DEBUG & DEBUG_BATCH)) ice->state.sizes = _mesa_hash_table_u64_create(ice); for (int i = 0; i < IRIS_BATCH_COUNT; i++) { iris_init_batch(&ice->batches[i], screen, &ice->vtbl, &ice->dbg, &ice->reset, ice->state.sizes, ice->batches, (enum iris_batch_name) i, I915_EXEC_RENDER, priority); } ice->vtbl.init_render_context(screen, &ice->batches[IRIS_BATCH_RENDER], &ice->vtbl, &ice->dbg); ice->vtbl.init_compute_context(screen, &ice->batches[IRIS_BATCH_COMPUTE], &ice->vtbl, &ice->dbg); return ctx; }
struct pipe_context * nvc0_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags) { struct nvc0_screen *screen = nvc0_screen(pscreen); struct nvc0_context *nvc0; struct pipe_context *pipe; int ret; uint32_t flags; nvc0 = CALLOC_STRUCT(nvc0_context); if (!nvc0) return NULL; pipe = &nvc0->base.pipe; if (!nvc0_blitctx_create(nvc0)) goto out_err; nvc0->base.pushbuf = screen->base.pushbuf; nvc0->base.client = screen->base.client; ret = nouveau_bufctx_new(screen->base.client, 2, &nvc0->bufctx); if (!ret) ret = nouveau_bufctx_new(screen->base.client, NVC0_BIND_3D_COUNT, &nvc0->bufctx_3d); if (!ret) ret = nouveau_bufctx_new(screen->base.client, NVC0_BIND_CP_COUNT, &nvc0->bufctx_cp); if (ret) goto out_err; nvc0->screen = screen; nvc0->base.screen = &screen->base; pipe->screen = pscreen; pipe->priv = priv; pipe->stream_uploader = u_upload_create_default(pipe); if (!pipe->stream_uploader) goto out_err; pipe->const_uploader = pipe->stream_uploader; pipe->destroy = nvc0_destroy; pipe->draw_vbo = nvc0_draw_vbo; pipe->clear = nvc0_clear; pipe->launch_grid = (nvc0->screen->base.class_3d >= NVE4_3D_CLASS) ? nve4_launch_grid : nvc0_launch_grid; pipe->flush = nvc0_flush; pipe->texture_barrier = nvc0_texture_barrier; pipe->memory_barrier = nvc0_memory_barrier; pipe->get_sample_position = nvc0_context_get_sample_position; pipe->emit_string_marker = nvc0_emit_string_marker; nouveau_context_init(&nvc0->base); nvc0_init_query_functions(nvc0); nvc0_init_surface_functions(nvc0); nvc0_init_state_functions(nvc0); nvc0_init_transfer_functions(nvc0); nvc0_init_resource_functions(pipe); nvc0->base.invalidate_resource_storage = nvc0_invalidate_resource_storage; pipe->create_video_codec = nvc0_create_decoder; pipe->create_video_buffer = nvc0_video_buffer_create; /* shader builtin library is per-screen, but we need a context for m2mf */ nvc0_program_library_upload(nvc0); nvc0_program_init_tcp_empty(nvc0); if (!nvc0->tcp_empty) goto out_err; /* set the empty tctl prog on next draw in case one is never set */ nvc0->dirty_3d |= NVC0_NEW_3D_TCTLPROG; /* Do not bind the COMPUTE driver constbuf at screen initialization because * CBs are aliased between 3D and COMPUTE, but make sure it will be bound if * a grid is launched later. */ nvc0->dirty_cp |= NVC0_NEW_CP_DRIVERCONST; /* now that there are no more opportunities for errors, set the current * context if there isn't already one. */ if (!screen->cur_ctx) { nvc0->state = screen->save_state; screen->cur_ctx = nvc0; nouveau_pushbuf_bufctx(screen->base.pushbuf, nvc0->bufctx); } screen->base.pushbuf->kick_notify = nvc0_default_kick_notify; /* add permanently resident buffers to bufctxts */ flags = NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RD; BCTX_REFN_bo(nvc0->bufctx_3d, 3D_TEXT, flags, screen->text); BCTX_REFN_bo(nvc0->bufctx_3d, 3D_SCREEN, flags, screen->uniform_bo); BCTX_REFN_bo(nvc0->bufctx_3d, 3D_SCREEN, flags, screen->txc); if (screen->compute) { BCTX_REFN_bo(nvc0->bufctx_cp, CP_TEXT, flags, screen->text); BCTX_REFN_bo(nvc0->bufctx_cp, CP_SCREEN, flags, screen->uniform_bo); BCTX_REFN_bo(nvc0->bufctx_cp, CP_SCREEN, flags, screen->txc); } flags = NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RDWR; if (screen->poly_cache) BCTX_REFN_bo(nvc0->bufctx_3d, 3D_SCREEN, flags, screen->poly_cache); if (screen->compute) BCTX_REFN_bo(nvc0->bufctx_cp, CP_SCREEN, flags, screen->tls); flags = NOUVEAU_BO_GART | NOUVEAU_BO_WR; BCTX_REFN_bo(nvc0->bufctx_3d, 3D_SCREEN, flags, screen->fence.bo); BCTX_REFN_bo(nvc0->bufctx, FENCE, flags, screen->fence.bo); if (screen->compute) BCTX_REFN_bo(nvc0->bufctx_cp, CP_SCREEN, flags, screen->fence.bo); nvc0->base.scratch.bo_size = 2 << 20; memset(nvc0->tex_handles, ~0, sizeof(nvc0->tex_handles)); util_dynarray_init(&nvc0->global_residents); return pipe; out_err: if (nvc0) { if (pipe->stream_uploader) u_upload_destroy(pipe->stream_uploader); if (nvc0->bufctx_3d) nouveau_bufctx_del(&nvc0->bufctx_3d); if (nvc0->bufctx_cp) nouveau_bufctx_del(&nvc0->bufctx_cp); if (nvc0->bufctx) nouveau_bufctx_del(&nvc0->bufctx); FREE(nvc0->blit); FREE(nvc0); } return NULL; }
struct pipe_context * nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags) { struct nv50_screen *screen = nv50_screen(pscreen); struct nv50_context *nv50; struct pipe_context *pipe; int ret; uint32_t flags; nv50 = CALLOC_STRUCT(nv50_context); if (!nv50) return NULL; pipe = &nv50->base.pipe; if (!nv50_blitctx_create(nv50)) goto out_err; nv50->base.pushbuf = screen->base.pushbuf; nv50->base.client = screen->base.client; ret = nouveau_bufctx_new(screen->base.client, 2, &nv50->bufctx); if (!ret) ret = nouveau_bufctx_new(screen->base.client, NV50_BIND_3D_COUNT, &nv50->bufctx_3d); if (!ret) ret = nouveau_bufctx_new(screen->base.client, NV50_BIND_CP_COUNT, &nv50->bufctx_cp); if (ret) goto out_err; nv50->base.screen = &screen->base; nv50->base.copy_data = nv50_m2mf_copy_linear; nv50->base.push_data = nv50_sifc_linear_u8; nv50->base.push_cb = nv50_cb_push; nv50->screen = screen; pipe->screen = pscreen; pipe->priv = priv; pipe->stream_uploader = u_upload_create_default(pipe); if (!pipe->stream_uploader) goto out_err; pipe->const_uploader = pipe->stream_uploader; pipe->destroy = nv50_destroy; pipe->draw_vbo = nv50_draw_vbo; pipe->clear = nv50_clear; pipe->launch_grid = nv50_launch_grid; pipe->flush = nv50_flush; pipe->texture_barrier = nv50_texture_barrier; pipe->memory_barrier = nv50_memory_barrier; pipe->get_sample_position = nv50_context_get_sample_position; pipe->emit_string_marker = nv50_emit_string_marker; if (!screen->cur_ctx) { /* Restore the last context's state here, normally handled during * context switch */ nv50->state = screen->save_state; screen->cur_ctx = nv50; nouveau_pushbuf_bufctx(screen->base.pushbuf, nv50->bufctx); } nv50->base.pushbuf->kick_notify = nv50_default_kick_notify; nouveau_context_init(&nv50->base); nv50_init_query_functions(nv50); nv50_init_surface_functions(nv50); nv50_init_state_functions(nv50); nv50_init_resource_functions(pipe); nv50->base.invalidate_resource_storage = nv50_invalidate_resource_storage; if (screen->base.device->chipset < 0x84 || debug_get_bool_option("NOUVEAU_PMPEG", false)) { /* PMPEG */ nouveau_context_init_vdec(&nv50->base); } else if (screen->base.device->chipset < 0x98 || screen->base.device->chipset == 0xa0) { /* VP2 */ pipe->create_video_codec = nv84_create_decoder; pipe->create_video_buffer = nv84_video_buffer_create; } else { /* VP3/4 */ pipe->create_video_codec = nv98_create_decoder; pipe->create_video_buffer = nv98_video_buffer_create; } flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD; BCTX_REFN_bo(nv50->bufctx_3d, 3D_SCREEN, flags, screen->code); BCTX_REFN_bo(nv50->bufctx_3d, 3D_SCREEN, flags, screen->uniforms); BCTX_REFN_bo(nv50->bufctx_3d, 3D_SCREEN, flags, screen->txc); BCTX_REFN_bo(nv50->bufctx_3d, 3D_SCREEN, flags, screen->stack_bo); if (screen->compute) { BCTX_REFN_bo(nv50->bufctx_cp, CP_SCREEN, flags, screen->code); BCTX_REFN_bo(nv50->bufctx_cp, CP_SCREEN, flags, screen->txc); BCTX_REFN_bo(nv50->bufctx_cp, CP_SCREEN, flags, screen->stack_bo); } flags = NOUVEAU_BO_GART | NOUVEAU_BO_WR; BCTX_REFN_bo(nv50->bufctx_3d, 3D_SCREEN, flags, screen->fence.bo); BCTX_REFN_bo(nv50->bufctx, FENCE, flags, screen->fence.bo); if (screen->compute) BCTX_REFN_bo(nv50->bufctx_cp, CP_SCREEN, flags, screen->fence.bo); nv50->base.scratch.bo_size = 2 << 20; util_dynarray_init(&nv50->global_residents, NULL); return pipe; out_err: if (pipe->stream_uploader) u_upload_destroy(pipe->stream_uploader); if (nv50->bufctx_3d) nouveau_bufctx_del(&nv50->bufctx_3d); if (nv50->bufctx_cp) nouveau_bufctx_del(&nv50->bufctx_cp); if (nv50->bufctx) nouveau_bufctx_del(&nv50->bufctx); FREE(nv50->blit); FREE(nv50); return NULL; }
struct pipe_context * swr_create_context(struct pipe_screen *p_screen, void *priv, unsigned flags) { struct swr_context *ctx = (struct swr_context *) AlignedMalloc(sizeof(struct swr_context), KNOB_SIMD_BYTES); memset(ctx, 0, sizeof(struct swr_context)); swr_screen(p_screen)->pfnSwrGetInterface(ctx->api); ctx->swrDC.pAPI = &ctx->api; ctx->blendJIT = new std::unordered_map<BLEND_COMPILE_STATE, PFN_BLEND_JIT_FUNC>; ctx->max_draws_in_flight = KNOB_MAX_DRAWS_IN_FLIGHT; SWR_CREATECONTEXT_INFO createInfo; memset(&createInfo, 0, sizeof(createInfo)); createInfo.privateStateSize = sizeof(swr_draw_context); createInfo.pfnLoadTile = swr_LoadHotTile; createInfo.pfnStoreTile = swr_StoreHotTile; createInfo.pfnClearTile = swr_StoreHotTileClear; createInfo.pfnUpdateStats = swr_UpdateStats; createInfo.pfnUpdateStatsFE = swr_UpdateStatsFE; SWR_THREADING_INFO threadingInfo {0}; threadingInfo.MAX_WORKER_THREADS = KNOB_MAX_WORKER_THREADS; threadingInfo.MAX_NUMA_NODES = KNOB_MAX_NUMA_NODES; threadingInfo.MAX_CORES_PER_NUMA_NODE = KNOB_MAX_CORES_PER_NUMA_NODE; threadingInfo.MAX_THREADS_PER_CORE = KNOB_MAX_THREADS_PER_CORE; threadingInfo.SINGLE_THREADED = KNOB_SINGLE_THREADED; // Use non-standard settings for KNL if (swr_screen(p_screen)->is_knl) { if (nullptr == getenv("KNOB_MAX_THREADS_PER_CORE")) threadingInfo.MAX_THREADS_PER_CORE = 2; if (nullptr == getenv("KNOB_MAX_DRAWS_IN_FLIGHT")) { ctx->max_draws_in_flight = 2048; createInfo.MAX_DRAWS_IN_FLIGHT = ctx->max_draws_in_flight; } } createInfo.pThreadInfo = &threadingInfo; ctx->swrContext = ctx->api.pfnSwrCreateContext(&createInfo); ctx->api.pfnSwrInit(); if (ctx->swrContext == NULL) goto fail; ctx->pipe.screen = p_screen; ctx->pipe.destroy = swr_destroy; ctx->pipe.priv = priv; ctx->pipe.create_surface = swr_create_surface; ctx->pipe.surface_destroy = swr_surface_destroy; ctx->pipe.transfer_map = swr_transfer_map; ctx->pipe.transfer_unmap = swr_transfer_unmap; ctx->pipe.transfer_flush_region = swr_transfer_flush_region; ctx->pipe.buffer_subdata = u_default_buffer_subdata; ctx->pipe.texture_subdata = u_default_texture_subdata; ctx->pipe.clear_texture = util_clear_texture; ctx->pipe.resource_copy_region = swr_resource_copy; ctx->pipe.render_condition = swr_render_condition; swr_state_init(&ctx->pipe); swr_clear_init(&ctx->pipe); swr_draw_init(&ctx->pipe); swr_query_init(&ctx->pipe); ctx->pipe.stream_uploader = u_upload_create_default(&ctx->pipe); if (!ctx->pipe.stream_uploader) goto fail; ctx->pipe.const_uploader = ctx->pipe.stream_uploader; ctx->pipe.blit = swr_blit; ctx->blitter = util_blitter_create(&ctx->pipe); if (!ctx->blitter) goto fail; swr_init_scratch_buffers(ctx); return &ctx->pipe; fail: /* Should really validate the init steps and fail gracefully */ swr_destroy(&ctx->pipe); return NULL; }
struct pipe_context * swr_create_context(struct pipe_screen *p_screen, void *priv, unsigned flags) { struct swr_context *ctx = (struct swr_context *) AlignedMalloc(sizeof(struct swr_context), KNOB_SIMD_BYTES); memset(ctx, 0, sizeof(struct swr_context)); swr_screen(p_screen)->pfnSwrGetInterface(ctx->api); ctx->swrDC.pAPI = &ctx->api; ctx->blendJIT = new std::unordered_map<BLEND_COMPILE_STATE, PFN_BLEND_JIT_FUNC>; SWR_CREATECONTEXT_INFO createInfo; memset(&createInfo, 0, sizeof(createInfo)); createInfo.privateStateSize = sizeof(swr_draw_context); createInfo.pfnLoadTile = swr_LoadHotTile; createInfo.pfnStoreTile = swr_StoreHotTile; createInfo.pfnClearTile = swr_StoreHotTileClear; createInfo.pfnUpdateStats = swr_UpdateStats; createInfo.pfnUpdateStatsFE = swr_UpdateStatsFE; ctx->swrContext = ctx->api.pfnSwrCreateContext(&createInfo); ctx->api.pfnSwrInit(); if (ctx->swrContext == NULL) goto fail; ctx->pipe.screen = p_screen; ctx->pipe.destroy = swr_destroy; ctx->pipe.priv = priv; ctx->pipe.create_surface = swr_create_surface; ctx->pipe.surface_destroy = swr_surface_destroy; ctx->pipe.transfer_map = swr_transfer_map; ctx->pipe.transfer_unmap = swr_transfer_unmap; ctx->pipe.transfer_flush_region = swr_transfer_flush_region; ctx->pipe.buffer_subdata = u_default_buffer_subdata; ctx->pipe.texture_subdata = u_default_texture_subdata; ctx->pipe.clear_texture = util_clear_texture; ctx->pipe.resource_copy_region = swr_resource_copy; ctx->pipe.render_condition = swr_render_condition; swr_state_init(&ctx->pipe); swr_clear_init(&ctx->pipe); swr_draw_init(&ctx->pipe); swr_query_init(&ctx->pipe); ctx->pipe.stream_uploader = u_upload_create_default(&ctx->pipe); if (!ctx->pipe.stream_uploader) goto fail; ctx->pipe.const_uploader = ctx->pipe.stream_uploader; ctx->pipe.blit = swr_blit; ctx->blitter = util_blitter_create(&ctx->pipe); if (!ctx->blitter) goto fail; swr_init_scratch_buffers(ctx); return &ctx->pipe; fail: /* Should really validate the init steps and fail gracefully */ swr_destroy(&ctx->pipe); return NULL; }