struct pipe_context * fd_context_init(struct fd_context *ctx, struct pipe_screen *pscreen, const uint8_t *primtypes, void *priv) { struct fd_screen *screen = fd_screen(pscreen); struct pipe_context *pctx; int i; ctx->screen = screen; ctx->primtypes = primtypes; ctx->primtype_mask = 0; for (i = 0; i < PIPE_PRIM_MAX; i++) if (primtypes[i]) ctx->primtype_mask |= (1 << i); /* need some sane default in case state tracker doesn't * set some state: */ ctx->sample_mask = 0xffff; pctx = &ctx->base; pctx->screen = pscreen; pctx->priv = priv; pctx->flush = fd_context_flush; for (i = 0; i < ARRAY_SIZE(ctx->rings); i++) { ctx->rings[i] = fd_ringbuffer_new(screen->pipe, 0x100000); if (!ctx->rings[i]) goto fail; } fd_context_next_rb(pctx); fd_reset_wfi(ctx); util_dynarray_init(&ctx->draw_patches); util_slab_create(&ctx->transfer_pool, sizeof(struct pipe_transfer), 16, UTIL_SLAB_SINGLETHREADED); fd_draw_init(pctx); fd_resource_context_init(pctx); fd_query_context_init(pctx); fd_texture_init(pctx); fd_state_init(pctx); ctx->blitter = util_blitter_create(pctx); if (!ctx->blitter) goto fail; ctx->primconvert = util_primconvert_create(pctx, ctx->primtype_mask); if (!ctx->primconvert) goto fail; return pctx; fail: pctx->destroy(pctx); return NULL; }
void ilo_state_vector_init(const struct ilo_dev_info *dev, struct ilo_state_vector *vec) { ilo_gpe_set_scissor_null(dev, &vec->scissor); ilo_gpe_init_zs_surface(dev, NULL, PIPE_FORMAT_NONE, 0, 0, 1, &vec->fb.null_zs); util_dynarray_init(&vec->global_binding.bindings); vec->dirty = ILO_DIRTY_ALL; }
struct pipe_context * fd4_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) { struct fd_screen *screen = fd_screen(pscreen); struct fd4_context *fd4_ctx = CALLOC_STRUCT(fd4_context); struct pipe_context *pctx; if (!fd4_ctx) return NULL; pctx = &fd4_ctx->base.base; fd4_ctx->base.dev = fd_device_ref(screen->dev); fd4_ctx->base.screen = fd_screen(pscreen); pctx->destroy = fd4_context_destroy; pctx->create_blend_state = fd4_blend_state_create; pctx->create_rasterizer_state = fd4_rasterizer_state_create; pctx->create_depth_stencil_alpha_state = fd4_zsa_state_create; fd4_draw_init(pctx); fd4_gmem_init(pctx); fd4_texture_init(pctx); fd4_prog_init(pctx); fd4_emit_init(pctx); pctx = fd_context_init(&fd4_ctx->base, pscreen, primtypes, priv); if (!pctx) return NULL; util_dynarray_init(&fd4_ctx->rbrc_patches); fd4_ctx->vs_pvt_mem = fd_bo_new(screen->dev, 0x2000, DRM_FREEDRENO_GEM_TYPE_KMEM); fd4_ctx->fs_pvt_mem = fd_bo_new(screen->dev, 0x2000, DRM_FREEDRENO_GEM_TYPE_KMEM); fd4_ctx->vsc_size_mem = fd_bo_new(screen->dev, 0x1000, DRM_FREEDRENO_GEM_TYPE_KMEM); fd4_ctx->solid_vbuf = create_solid_vertexbuf(pctx); fd4_ctx->blit_texcoord_vbuf = create_blit_texcoord_vertexbuf(pctx); /* setup solid_vbuf_state: */ fd4_ctx->solid_vbuf_state.vtx = pctx->create_vertex_elements_state( pctx, 1, (struct pipe_vertex_element[]){{ .vertex_buffer_index = 0, .src_offset = 0, .src_format = PIPE_FORMAT_R32G32B32_FLOAT, }});
struct pipe_context * fd3_context_create(struct pipe_screen *pscreen, void *priv) { struct fd_screen *screen = fd_screen(pscreen); struct fd3_context *fd3_ctx = CALLOC_STRUCT(fd3_context); struct pipe_context *pctx; if (!fd3_ctx) return NULL; pctx = &fd3_ctx->base.base; fd3_ctx->base.dev = fd_device_ref(screen->dev); fd3_ctx->base.screen = fd_screen(pscreen); pctx->destroy = fd3_context_destroy; pctx->create_blend_state = fd3_blend_state_create; pctx->create_rasterizer_state = fd3_rasterizer_state_create; pctx->create_depth_stencil_alpha_state = fd3_zsa_state_create; fd3_draw_init(pctx); fd3_gmem_init(pctx); fd3_texture_init(pctx); fd3_prog_init(pctx); pctx = fd_context_init(&fd3_ctx->base, pscreen, primtypes, priv); if (!pctx) return NULL; util_dynarray_init(&fd3_ctx->rbrc_patches); fd3_ctx->vs_pvt_mem = fd_bo_new(screen->dev, 0x2000, DRM_FREEDRENO_GEM_TYPE_KMEM); fd3_ctx->fs_pvt_mem = fd_bo_new(screen->dev, 0x2000, DRM_FREEDRENO_GEM_TYPE_KMEM); fd3_ctx->vsc_size_mem = fd_bo_new(screen->dev, 0x1000, DRM_FREEDRENO_GEM_TYPE_KMEM); fd3_ctx->solid_vbuf = create_solid_vertexbuf(pctx); fd3_ctx->blit_texcoord_vbuf = create_blit_texcoord_vertexbuf(pctx); return pctx; }
VAStatus vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format, unsigned int width, unsigned int height, VASurfaceID *surfaces, unsigned int num_surfaces, VASurfaceAttrib *attrib_list, unsigned int num_attribs) { vlVaDriver *drv; VASurfaceAttribExternalBuffers *memory_attibute; struct pipe_video_buffer templat; struct pipe_screen *pscreen; int i; int memory_type; int expected_fourcc; VAStatus vaStatus; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; if (!(width && height)) return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT; drv = VL_VA_DRIVER(ctx); if (!drv) return VA_STATUS_ERROR_INVALID_CONTEXT; pscreen = VL_VA_PSCREEN(ctx); if (!pscreen) return VA_STATUS_ERROR_INVALID_CONTEXT; /* Default. */ memory_attibute = NULL; memory_type = VA_SURFACE_ATTRIB_MEM_TYPE_VA; expected_fourcc = 0; for (i = 0; i < num_attribs && attrib_list; i++) { if ((attrib_list[i].type == VASurfaceAttribPixelFormat) && (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) { if (attrib_list[i].value.type != VAGenericValueTypeInteger) return VA_STATUS_ERROR_INVALID_PARAMETER; expected_fourcc = attrib_list[i].value.value.i; } if ((attrib_list[i].type == VASurfaceAttribMemoryType) && (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) { if (attrib_list[i].value.type != VAGenericValueTypeInteger) return VA_STATUS_ERROR_INVALID_PARAMETER; switch (attrib_list[i].value.value.i) { case VA_SURFACE_ATTRIB_MEM_TYPE_VA: case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: memory_type = attrib_list[i].value.value.i; break; default: return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE; } } if ((attrib_list[i].type == VASurfaceAttribExternalBufferDescriptor) && (attrib_list[i].flags == VA_SURFACE_ATTRIB_SETTABLE)) { if (attrib_list[i].value.type != VAGenericValueTypePointer) return VA_STATUS_ERROR_INVALID_PARAMETER; memory_attibute = (VASurfaceAttribExternalBuffers *)attrib_list[i].value.value.p; } } if (VA_RT_FORMAT_YUV420 != format && VA_RT_FORMAT_YUV422 != format && VA_RT_FORMAT_YUV444 != format && VA_RT_FORMAT_RGB32 != format) { return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; } switch (memory_type) { case VA_SURFACE_ATTRIB_MEM_TYPE_VA: break; case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: if (!memory_attibute) return VA_STATUS_ERROR_INVALID_PARAMETER; expected_fourcc = memory_attibute->pixel_format; break; default: assert(0); } memset(&templat, 0, sizeof(templat)); if (expected_fourcc) { templat.buffer_format = VaFourccToPipeFormat(expected_fourcc); templat.interlaced = 0; } else { templat.buffer_format = pscreen->get_video_param ( pscreen, PIPE_VIDEO_PROFILE_UNKNOWN, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_PREFERED_FORMAT ); templat.interlaced = pscreen->get_video_param ( pscreen, PIPE_VIDEO_PROFILE_UNKNOWN, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_PREFERS_INTERLACED ); } templat.chroma_format = ChromaToPipe(format); templat.width = width; templat.height = height; memset(surfaces, VA_INVALID_ID, num_surfaces * sizeof(VASurfaceID)); for (i = 0; i < num_surfaces; i++) { vlVaSurface *surf = CALLOC(1, sizeof(vlVaSurface)); if (!surf) goto no_res; surf->templat = templat; switch (memory_type) { case VA_SURFACE_ATTRIB_MEM_TYPE_VA: surf->buffer = drv->pipe->create_video_buffer(drv->pipe, &templat); if (!surf->buffer) goto no_res; util_dynarray_init(&surf->subpics); surfaces[i] = handle_table_add(drv->htab, surf); break; case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: vaStatus = suface_from_external_memory(ctx, surf, memory_attibute, i, surfaces, &templat); if (vaStatus != VA_STATUS_SUCCESS) goto no_res; break; default: assert(0); } } return VA_STATUS_SUCCESS; no_res: if (i) vlVaDestroySurfaces(ctx, surfaces, i); return VA_STATUS_ERROR_ALLOCATION_FAILED; }
static VAStatus suface_from_external_memory(VADriverContextP ctx, vlVaSurface *surface, VASurfaceAttribExternalBuffers *memory_attibute, int index, VASurfaceID *surfaces, struct pipe_video_buffer *templat) { vlVaDriver *drv; struct pipe_screen *pscreen; struct pipe_resource *resource; struct pipe_resource res_templ; struct winsys_handle whandle; struct pipe_resource *resources[VL_NUM_COMPONENTS]; if (!ctx) return VA_STATUS_ERROR_INVALID_PARAMETER; pscreen = VL_VA_PSCREEN(ctx); drv = VL_VA_DRIVER(ctx); if (!memory_attibute || !memory_attibute->buffers || index > memory_attibute->num_buffers) return VA_STATUS_ERROR_INVALID_PARAMETER; if (surface->templat.width != memory_attibute->width || surface->templat.height != memory_attibute->height || memory_attibute->num_planes < 1) return VA_STATUS_ERROR_INVALID_PARAMETER; switch (memory_attibute->pixel_format) { case VA_FOURCC_RGBA: case VA_FOURCC_RGBX: case VA_FOURCC_BGRA: case VA_FOURCC_BGRX: if (memory_attibute->num_planes != 1) return VA_STATUS_ERROR_INVALID_PARAMETER; break; default: return VA_STATUS_ERROR_INVALID_PARAMETER; } memset(&res_templ, 0, sizeof(res_templ)); res_templ.target = PIPE_TEXTURE_2D; res_templ.last_level = 0; res_templ.depth0 = 1; res_templ.array_size = 1; res_templ.width0 = memory_attibute->width; res_templ.height0 = memory_attibute->height; res_templ.format = surface->templat.buffer_format; res_templ.bind = PIPE_BIND_SAMPLER_VIEW; res_templ.usage = PIPE_USAGE_DEFAULT; memset(&whandle, 0, sizeof(struct winsys_handle)); whandle.type = DRM_API_HANDLE_TYPE_FD; whandle.handle = memory_attibute->buffers[index]; whandle.stride = memory_attibute->pitches[index]; resource = pscreen->resource_from_handle(pscreen, &res_templ, &whandle); if (!resource) return VA_STATUS_ERROR_ALLOCATION_FAILED; memset(resources, 0, sizeof resources); resources[0] = resource; surface->buffer = vl_video_buffer_create_ex2(drv->pipe, templat, resources); if (!surface->buffer) return VA_STATUS_ERROR_ALLOCATION_FAILED; util_dynarray_init(&surface->subpics); surfaces[index] = handle_table_add(drv->htab, surface); if (!surfaces[index]) return VA_STATUS_ERROR_ALLOCATION_FAILED; return VA_STATUS_SUCCESS; }
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->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; 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 |= NVC0_NEW_TCTLPROG; /* 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, SCREEN, flags, screen->text); BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->uniform_bo); BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->txc); if (screen->compute) { BCTX_REFN_bo(nvc0->bufctx_cp, CP_SCREEN, flags, screen->text); BCTX_REFN_bo(nvc0->bufctx_cp, CP_SCREEN, flags, screen->txc); BCTX_REFN_bo(nvc0->bufctx_cp, CP_SCREEN, flags, screen->parm); } flags = NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RDWR; if (screen->poly_cache) BCTX_REFN_bo(nvc0->bufctx_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, 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 (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 * nvc0_create(struct pipe_screen *pscreen, void *priv) { 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->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; if (!screen->cur_ctx) { screen->cur_ctx = nvc0; nouveau_pushbuf_bufctx(screen->base.pushbuf, nvc0->bufctx); } screen->base.pushbuf->kick_notify = nvc0_default_kick_notify; 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; #ifdef NVC0_WITH_DRAW_MODULE /* no software fallbacks implemented */ nvc0->draw = draw_create(pipe); assert(nvc0->draw); draw_set_rasterize_stage(nvc0->draw, nvc0_draw_render_stage(nvc0)); #endif 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); /* add permanently resident buffers to bufctxts */ flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD; BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->text); BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->uniform_bo); BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->txc); if (screen->compute) { BCTX_REFN_bo(nvc0->bufctx_cp, CP_SCREEN, flags, screen->text); BCTX_REFN_bo(nvc0->bufctx_cp, CP_SCREEN, flags, screen->txc); BCTX_REFN_bo(nvc0->bufctx_cp, CP_SCREEN, flags, screen->parm); } flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR; if (screen->poly_cache) BCTX_REFN_bo(nvc0->bufctx_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, 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 (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); if (nvc0->blit) 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; /* FIXME: Make it possible to use this again. The problem is that there is * some clever logic in the card that allows for multiple renders to happen * when there are only constbuf changes. However that relies on the * constbuf updates happening to the right constbuf slots. Currently * implementation just makes it go through a separate slot which doesn't * properly update the right constbuf data. nv50->base.push_cb = nv50_cb_push; */ nv50->screen = screen; pipe->screen = pscreen; pipe->priv = priv; 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; 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); return pipe; out_err: 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_screen * etna_screen_create(struct etna_device *dev, struct etna_gpu *gpu, struct renderonly *ro) { struct etna_screen *screen = CALLOC_STRUCT(etna_screen); struct pipe_screen *pscreen; drmVersionPtr version; uint64_t val; if (!screen) return NULL; pscreen = &screen->base; screen->dev = dev; screen->gpu = gpu; screen->ro = renderonly_dup(ro); screen->refcnt = 1; if (!screen->ro) { DBG("could not create renderonly object"); goto fail; } version = drmGetVersion(screen->ro->gpu_fd); screen->drm_version = ETNA_DRM_VERSION(version->version_major, version->version_minor); drmFreeVersion(version); etna_mesa_debug = debug_get_option_etna_mesa_debug(); /* Disable autodisable for correct rendering with TS */ etna_mesa_debug |= ETNA_DBG_NO_AUTODISABLE; screen->pipe = etna_pipe_new(gpu, ETNA_PIPE_3D); if (!screen->pipe) { DBG("could not create 3d pipe"); goto fail; } if (etna_gpu_get_param(screen->gpu, ETNA_GPU_MODEL, &val)) { DBG("could not get ETNA_GPU_MODEL"); goto fail; } screen->model = val; if (etna_gpu_get_param(screen->gpu, ETNA_GPU_REVISION, &val)) { DBG("could not get ETNA_GPU_REVISION"); goto fail; } screen->revision = val; if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_0, &val)) { DBG("could not get ETNA_GPU_FEATURES_0"); goto fail; } screen->features[0] = val; if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_1, &val)) { DBG("could not get ETNA_GPU_FEATURES_1"); goto fail; } screen->features[1] = val; if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_2, &val)) { DBG("could not get ETNA_GPU_FEATURES_2"); goto fail; } screen->features[2] = val; if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_3, &val)) { DBG("could not get ETNA_GPU_FEATURES_3"); goto fail; } screen->features[3] = val; if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_4, &val)) { DBG("could not get ETNA_GPU_FEATURES_4"); goto fail; } screen->features[4] = val; if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_5, &val)) { DBG("could not get ETNA_GPU_FEATURES_5"); goto fail; } screen->features[5] = val; if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_6, &val)) { DBG("could not get ETNA_GPU_FEATURES_6"); goto fail; } screen->features[6] = val; if (!etna_get_specs(screen)) goto fail; /* apply debug options that disable individual features */ if (DBG_ENABLED(ETNA_DBG_NO_EARLY_Z)) screen->features[viv_chipFeatures] |= chipFeatures_NO_EARLY_Z; if (DBG_ENABLED(ETNA_DBG_NO_TS)) screen->features[viv_chipFeatures] &= ~chipFeatures_FAST_CLEAR; if (DBG_ENABLED(ETNA_DBG_NO_AUTODISABLE)) screen->features[viv_chipMinorFeatures1] &= ~chipMinorFeatures1_AUTO_DISABLE; if (DBG_ENABLED(ETNA_DBG_NO_SUPERTILE)) screen->specs.can_supertile = 0; if (DBG_ENABLED(ETNA_DBG_NO_SINGLEBUF)) screen->specs.single_buffer = 0; pscreen->destroy = etna_screen_destroy; pscreen->get_param = etna_screen_get_param; pscreen->get_paramf = etna_screen_get_paramf; pscreen->get_shader_param = etna_screen_get_shader_param; pscreen->get_name = etna_screen_get_name; pscreen->get_vendor = etna_screen_get_vendor; pscreen->get_device_vendor = etna_screen_get_device_vendor; pscreen->get_timestamp = etna_screen_get_timestamp; pscreen->context_create = etna_context_create; pscreen->is_format_supported = etna_screen_is_format_supported; pscreen->query_dmabuf_modifiers = etna_screen_query_dmabuf_modifiers; etna_fence_screen_init(pscreen); etna_query_screen_init(pscreen); etna_resource_screen_init(pscreen); util_dynarray_init(&screen->supported_pm_queries, NULL); slab_create_parent(&screen->transfer_pool, sizeof(struct etna_transfer), 16); if (screen->drm_version >= ETNA_DRM_VERSION_PERFMON) etna_pm_query_setup(screen); return pscreen; fail: etna_screen_destroy(pscreen); 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->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); return pipe; out_err: 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; }
static struct pipe_context *si_create_context(struct pipe_screen *screen, unsigned flags) { struct si_context *sctx = CALLOC_STRUCT(si_context); struct si_screen* sscreen = (struct si_screen *)screen; struct radeon_winsys *ws = sscreen->ws; int shader, i; bool stop_exec_on_failure = (flags & PIPE_CONTEXT_LOSE_CONTEXT_ON_RESET) != 0; if (!sctx) return NULL; sctx->has_graphics = sscreen->info.chip_class == SI || !(flags & PIPE_CONTEXT_COMPUTE_ONLY); if (flags & PIPE_CONTEXT_DEBUG) sscreen->record_llvm_ir = true; /* racy but not critical */ sctx->b.screen = screen; /* this must be set first */ sctx->b.priv = NULL; sctx->b.destroy = si_destroy_context; sctx->screen = sscreen; /* Easy accessing of screen/winsys. */ sctx->is_debug = (flags & PIPE_CONTEXT_DEBUG) != 0; slab_create_child(&sctx->pool_transfers, &sscreen->pool_transfers); slab_create_child(&sctx->pool_transfers_unsync, &sscreen->pool_transfers); sctx->ws = sscreen->ws; sctx->family = sscreen->info.family; sctx->chip_class = sscreen->info.chip_class; if (sscreen->info.has_gpu_reset_counter_query) { sctx->gpu_reset_counter = sctx->ws->query_value(sctx->ws, RADEON_GPU_RESET_COUNTER); } if (sctx->chip_class == CIK || sctx->chip_class == VI || sctx->chip_class == GFX9) { sctx->eop_bug_scratch = si_resource( pipe_buffer_create(&sscreen->b, 0, PIPE_USAGE_DEFAULT, 16 * sscreen->info.num_render_backends)); if (!sctx->eop_bug_scratch) goto fail; } /* Initialize context allocators. */ sctx->allocator_zeroed_memory = u_suballocator_create(&sctx->b, 128 * 1024, 0, PIPE_USAGE_DEFAULT, SI_RESOURCE_FLAG_UNMAPPABLE | SI_RESOURCE_FLAG_CLEAR, false); if (!sctx->allocator_zeroed_memory) goto fail; sctx->b.stream_uploader = u_upload_create(&sctx->b, 1024 * 1024, 0, PIPE_USAGE_STREAM, SI_RESOURCE_FLAG_READ_ONLY); if (!sctx->b.stream_uploader) goto fail; sctx->cached_gtt_allocator = u_upload_create(&sctx->b, 16 * 1024, 0, PIPE_USAGE_STAGING, 0); if (!sctx->cached_gtt_allocator) goto fail; sctx->ctx = sctx->ws->ctx_create(sctx->ws); if (!sctx->ctx) goto fail; if (sscreen->info.num_sdma_rings && !(sscreen->debug_flags & DBG(NO_ASYNC_DMA))) { sctx->dma_cs = sctx->ws->cs_create(sctx->ctx, RING_DMA, (void*)si_flush_dma_cs, sctx, stop_exec_on_failure); } bool use_sdma_upload = sscreen->info.has_dedicated_vram && sctx->dma_cs; sctx->b.const_uploader = u_upload_create(&sctx->b, 256 * 1024, 0, PIPE_USAGE_DEFAULT, SI_RESOURCE_FLAG_32BIT | (use_sdma_upload ? SI_RESOURCE_FLAG_UPLOAD_FLUSH_EXPLICIT_VIA_SDMA : (sscreen->cpdma_prefetch_writes_memory ? 0 : SI_RESOURCE_FLAG_READ_ONLY))); if (!sctx->b.const_uploader) goto fail; if (use_sdma_upload) u_upload_enable_flush_explicit(sctx->b.const_uploader); sctx->gfx_cs = ws->cs_create(sctx->ctx, sctx->has_graphics ? RING_GFX : RING_COMPUTE, (void*)si_flush_gfx_cs, sctx, stop_exec_on_failure); /* Border colors. */ sctx->border_color_table = malloc(SI_MAX_BORDER_COLORS * sizeof(*sctx->border_color_table)); if (!sctx->border_color_table) goto fail; sctx->border_color_buffer = si_resource( pipe_buffer_create(screen, 0, PIPE_USAGE_DEFAULT, SI_MAX_BORDER_COLORS * sizeof(*sctx->border_color_table))); if (!sctx->border_color_buffer) goto fail; sctx->border_color_map = ws->buffer_map(sctx->border_color_buffer->buf, NULL, PIPE_TRANSFER_WRITE); if (!sctx->border_color_map) goto fail; /* Initialize context functions used by graphics and compute. */ sctx->b.emit_string_marker = si_emit_string_marker; sctx->b.set_debug_callback = si_set_debug_callback; sctx->b.set_log_context = si_set_log_context; sctx->b.set_context_param = si_set_context_param; sctx->b.get_device_reset_status = si_get_reset_status; sctx->b.set_device_reset_callback = si_set_device_reset_callback; si_init_all_descriptors(sctx); si_init_buffer_functions(sctx); si_init_clear_functions(sctx); si_init_blit_functions(sctx); si_init_compute_functions(sctx); si_init_compute_blit_functions(sctx); si_init_debug_functions(sctx); si_init_fence_functions(sctx); si_init_state_compute_functions(sctx); if (sscreen->debug_flags & DBG(FORCE_DMA)) sctx->b.resource_copy_region = sctx->dma_copy; /* Initialize graphics-only context functions. */ if (sctx->has_graphics) { si_init_context_texture_functions(sctx); si_init_query_functions(sctx); si_init_msaa_functions(sctx); si_init_shader_functions(sctx); si_init_state_functions(sctx); si_init_streamout_functions(sctx); si_init_viewport_functions(sctx); sctx->blitter = util_blitter_create(&sctx->b); if (sctx->blitter == NULL) goto fail; sctx->blitter->skip_viewport_restore = true; si_init_draw_functions(sctx); } /* Initialize SDMA functions. */ if (sctx->chip_class >= CIK) cik_init_sdma_functions(sctx); else si_init_dma_functions(sctx); sctx->sample_mask = 0xffff; /* Initialize multimedia functions. */ if (sscreen->info.has_hw_decode) { sctx->b.create_video_codec = si_uvd_create_decoder; sctx->b.create_video_buffer = si_video_buffer_create; } else { sctx->b.create_video_codec = vl_create_decoder; sctx->b.create_video_buffer = vl_video_buffer_create; } if (sctx->chip_class >= GFX9) { sctx->wait_mem_scratch = si_resource( pipe_buffer_create(screen, 0, PIPE_USAGE_DEFAULT, 4)); if (!sctx->wait_mem_scratch) goto fail; /* Initialize the memory. */ si_cp_write_data(sctx, sctx->wait_mem_scratch, 0, 4, V_370_MEM, V_370_ME, &sctx->wait_mem_number); } /* CIK cannot unbind a constant buffer (S_BUFFER_LOAD doesn't skip loads * if NUM_RECORDS == 0). We need to use a dummy buffer instead. */ if (sctx->chip_class == CIK) { sctx->null_const_buf.buffer = pipe_aligned_buffer_create(screen, SI_RESOURCE_FLAG_32BIT, PIPE_USAGE_DEFAULT, 16, sctx->screen->info.tcc_cache_line_size); if (!sctx->null_const_buf.buffer) goto fail; sctx->null_const_buf.buffer_size = sctx->null_const_buf.buffer->width0; unsigned start_shader = sctx->has_graphics ? 0 : PIPE_SHADER_COMPUTE; for (shader = start_shader; shader < SI_NUM_SHADERS; shader++) { for (i = 0; i < SI_NUM_CONST_BUFFERS; i++) { sctx->b.set_constant_buffer(&sctx->b, shader, i, &sctx->null_const_buf); } } si_set_rw_buffer(sctx, SI_HS_CONST_DEFAULT_TESS_LEVELS, &sctx->null_const_buf); si_set_rw_buffer(sctx, SI_VS_CONST_INSTANCE_DIVISORS, &sctx->null_const_buf); si_set_rw_buffer(sctx, SI_VS_CONST_CLIP_PLANES, &sctx->null_const_buf); si_set_rw_buffer(sctx, SI_PS_CONST_POLY_STIPPLE, &sctx->null_const_buf); si_set_rw_buffer(sctx, SI_PS_CONST_SAMPLE_POSITIONS, &sctx->null_const_buf); } uint64_t max_threads_per_block; screen->get_compute_param(screen, PIPE_SHADER_IR_TGSI, PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK, &max_threads_per_block); /* The maximum number of scratch waves. Scratch space isn't divided * evenly between CUs. The number is only a function of the number of CUs. * We can decrease the constant to decrease the scratch buffer size. * * sctx->scratch_waves must be >= the maximum posible size of * 1 threadgroup, so that the hw doesn't hang from being unable * to start any. * * The recommended value is 4 per CU at most. Higher numbers don't * bring much benefit, but they still occupy chip resources (think * async compute). I've seen ~2% performance difference between 4 and 32. */ sctx->scratch_waves = MAX2(32 * sscreen->info.num_good_compute_units, max_threads_per_block / 64); si_init_compiler(sscreen, &sctx->compiler); /* Bindless handles. */ sctx->tex_handles = _mesa_hash_table_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal); sctx->img_handles = _mesa_hash_table_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal); util_dynarray_init(&sctx->resident_tex_handles, NULL); util_dynarray_init(&sctx->resident_img_handles, NULL); util_dynarray_init(&sctx->resident_tex_needs_color_decompress, NULL); util_dynarray_init(&sctx->resident_img_needs_color_decompress, NULL); util_dynarray_init(&sctx->resident_tex_needs_depth_decompress, NULL); sctx->sample_pos_buffer = pipe_buffer_create(sctx->b.screen, 0, PIPE_USAGE_DEFAULT, sizeof(sctx->sample_positions)); pipe_buffer_write(&sctx->b, sctx->sample_pos_buffer, 0, sizeof(sctx->sample_positions), &sctx->sample_positions); /* this must be last */ si_begin_new_gfx_cs(sctx); if (sctx->chip_class == CIK) { /* Clear the NULL constant buffer, because loads should return zeros. * Note that this forces CP DMA to be used, because clover deadlocks * for some reason when the compute codepath is used. */ uint32_t clear_value = 0; si_clear_buffer(sctx, sctx->null_const_buf.buffer, 0, sctx->null_const_buf.buffer->width0, &clear_value, 4, SI_COHERENCY_SHADER, true); } return &sctx->b; fail: fprintf(stderr, "radeonsi: Failed to create a context.\n"); si_destroy_context(&sctx->b); return NULL; }