int nvc0_screen_get_driver_query_info(struct pipe_screen *pscreen, unsigned id, struct pipe_driver_query_info *info) { struct nvc0_screen *screen = nvc0_screen(pscreen); int num_sw_queries = 0, num_hw_queries = 0; num_sw_queries = nvc0_sw_get_driver_query_info(screen, 0, NULL); num_hw_queries = nvc0_hw_get_driver_query_info(screen, 0, NULL); if (!info) return num_sw_queries + num_hw_queries; /* Init default values. */ info->name = "this_is_not_the_query_you_are_looking_for"; info->query_type = 0xdeadd01d; info->max_value.u64 = 0; info->type = PIPE_DRIVER_QUERY_TYPE_UINT64; info->group_id = -1; info->flags = 0; #ifdef NOUVEAU_ENABLE_DRIVER_STATISTICS if (id < num_sw_queries) return nvc0_sw_get_driver_query_info(screen, id, info); #endif return nvc0_hw_get_driver_query_info(screen, id - num_sw_queries, info); }
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; nvc0 = CALLOC_STRUCT(nvc0_context); if (!nvc0) return NULL; pipe = &nvc0->base.pipe; nvc0->screen = screen; nvc0->base.screen = &screen->base; nvc0->base.copy_data = nvc0_m2mf_copy_linear; nvc0->base.push_data = nvc0_m2mf_push_linear; nvc0->base.push_cb = nvc0_cb_push; pipe->screen = pscreen; pipe->priv = priv; pipe->destroy = nvc0_destroy; pipe->draw_vbo = nvc0_draw_vbo; pipe->clear = nvc0_clear; pipe->flush = nvc0_flush; pipe->texture_barrier = nvc0_texture_barrier; if (!screen->cur_ctx) screen->cur_ctx = nvc0; screen->base.channel->flush_notify = nvc0_default_flush_notify; nvc0_init_query_functions(nvc0); nvc0_init_surface_functions(nvc0); nvc0_init_state_functions(nvc0); nvc0_init_resource_functions(pipe); nvc0->draw = draw_create(pipe); assert(nvc0->draw); draw_set_rasterize_stage(nvc0->draw, nvc0_draw_render_stage(nvc0)); pipe->create_video_decoder = 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); return pipe; }
struct pipe_context * nvc0_create(struct pipe_screen *pscreen, void *priv) { struct pipe_winsys *pipe_winsys = pscreen->winsys; struct nvc0_screen *screen = nvc0_screen(pscreen); struct nvc0_context *nvc0; struct pipe_context *pipe; nvc0 = CALLOC_STRUCT(nvc0_context); if (!nvc0) return NULL; pipe = &nvc0->base.pipe; nvc0->screen = screen; nvc0->base.screen = &screen->base; nvc0->base.copy_data = nvc0_m2mf_copy_linear; nvc0->base.push_data = nvc0_m2mf_push_linear; pipe->winsys = pipe_winsys; pipe->screen = pscreen; pipe->priv = priv; pipe->destroy = nvc0_destroy; pipe->draw_vbo = nvc0_draw_vbo; pipe->clear = nvc0_clear; pipe->flush = nvc0_flush; pipe->texture_barrier = nvc0_texture_barrier; if (!screen->cur_ctx) screen->cur_ctx = nvc0; screen->base.channel->flush_notify = nvc0_default_flush_notify; nvc0_init_query_functions(nvc0); nvc0_init_surface_functions(nvc0); nvc0_init_state_functions(nvc0); nvc0_init_resource_functions(pipe); nvc0->draw = draw_create(pipe); assert(nvc0->draw); draw_set_rasterize_stage(nvc0->draw, nvc0_draw_render_stage(nvc0)); nouveau_context_init_vdec(&nvc0->base); return pipe; }
static int nvc0_screen_get_compute_param(struct pipe_screen *pscreen, enum pipe_compute_cap param, void *data) { struct nvc0_screen *screen = nvc0_screen(pscreen); const uint16_t obj_class = screen->compute->oclass; #define RET(x) do { \ if (data) \ memcpy(data, x, sizeof(x)); \ return sizeof(x); \ } while (0) switch (param) { case PIPE_COMPUTE_CAP_GRID_DIMENSION: RET((uint64_t []) { 3 }); case PIPE_COMPUTE_CAP_MAX_GRID_SIZE: if (obj_class >= NVE4_COMPUTE_CLASS) { RET(((uint64_t []) { 0x7fffffff, 65535, 65535 })); } else {
int nvc0_screen_get_driver_query_info(struct pipe_screen *pscreen, unsigned id, struct pipe_driver_query_info *info) { struct nvc0_screen *screen = nvc0_screen(pscreen); int count = 0; count += NVC0_QUERY_DRV_STAT_COUNT; if (screen->base.class_3d >= NVE4_3D_CLASS) { if (screen->base.device->drm_version >= 0x01000101) count += NVE4_PM_QUERY_COUNT; } if (!info) return count; #ifdef NOUVEAU_ENABLE_DRIVER_STATISTICS if (id < NVC0_QUERY_DRV_STAT_COUNT) { info->name = nvc0_drv_stat_names[id]; info->query_type = NVC0_QUERY_DRV_STAT(id); info->max_value = ~0ULL; info->uses_byte_units = !!strstr(info->name, "bytes"); return 1; } else #endif if (id < count) { info->name = nve4_pm_query_names[id - NVC0_QUERY_DRV_STAT_COUNT]; info->query_type = NVE4_PM_QUERY(id - NVC0_QUERY_DRV_STAT_COUNT); info->max_value = (id < NVE4_PM_QUERY_METRIC_MP_OCCUPANCY) ? ~0ULL : 100; info->uses_byte_units = FALSE; return 1; } /* user asked for info about non-existing query */ info->name = "this_is_not_the_query_you_are_looking_for"; info->query_type = 0xdeadd01d; info->max_value = 0; info->uses_byte_units = FALSE; return 0; }
int nvc0_screen_get_driver_query_group_info(struct pipe_screen *pscreen, unsigned id, struct pipe_driver_query_group_info *info) { struct nvc0_screen *screen = nvc0_screen(pscreen); int count = 0; #ifdef NOUVEAU_ENABLE_DRIVER_STATISTICS count++; #endif if (screen->base.drm->version >= 0x01000101) { if (screen->compute) { if (screen->base.class_3d <= GM200_3D_CLASS) { count += 2; } } } if (!info) return count; if (id == NVC0_HW_SM_QUERY_GROUP) { if (screen->compute) { info->name = "MP counters"; /* Expose the maximum number of hardware counters available, although * some queries use more than one counter. Expect failures in that * case but as performance counters are for developers, this should * not have a real impact. */ info->max_active_queries = 8; info->num_queries = nvc0_hw_sm_get_num_queries(screen); return 1; } } else if (id == NVC0_HW_METRIC_QUERY_GROUP) { if (screen->compute) { if (screen->base.class_3d <= GM200_3D_CLASS) { info->name = "Performance metrics"; info->max_active_queries = 4; /* A metric uses at least 2 queries */ info->num_queries = nvc0_hw_metric_get_num_queries(screen); return 1; } } } #ifdef NOUVEAU_ENABLE_DRIVER_STATISTICS else if (id == NVC0_SW_QUERY_DRV_STAT_GROUP) { info->name = "Driver statistics"; info->max_active_queries = NVC0_SW_QUERY_DRV_STAT_COUNT; info->num_queries = NVC0_SW_QUERY_DRV_STAT_COUNT; return 1; } #endif /* user asked for info about non-existing query group */ info->name = "this_is_not_the_query_group_you_are_looking_for"; info->max_active_queries = 0; info->num_queries = 0; return 0; }
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; }
int nvc0_screen_get_driver_query_group_info(struct pipe_screen *pscreen, unsigned id, struct pipe_driver_query_group_info *info) { struct nvc0_screen *screen = nvc0_screen(pscreen); int count = 0; #ifdef NOUVEAU_ENABLE_DRIVER_STATISTICS count++; #endif if (screen->base.device->drm_version >= 0x01000101) { if (screen->compute) { if (screen->base.class_3d == NVE4_3D_CLASS) { count += 2; } else if (screen->base.class_3d < NVE4_3D_CLASS) { count += 2; } } } if (!info) return count; if (id == NVC0_HW_SM_QUERY_GROUP) { if (screen->compute) { info->name = "MP counters"; /* Because we can't expose the number of hardware counters needed for * each different query, we don't want to allow more than one active * query simultaneously to avoid failure when the maximum number of * counters is reached. Note that these groups of GPU counters are * currently only used by AMD_performance_monitor. */ info->max_active_queries = 1; if (screen->base.class_3d == NVE4_3D_CLASS) { info->num_queries = NVE4_HW_SM_QUERY_COUNT; return 1; } else if (screen->base.class_3d < NVE4_3D_CLASS) { info->num_queries = NVC0_HW_SM_QUERY_COUNT; return 1; } } } else if (id == NVC0_HW_METRIC_QUERY_GROUP) { if (screen->compute) { if (screen->base.class_3d == NVE4_3D_CLASS) { info->name = "Performance metrics"; info->max_active_queries = 1; info->num_queries = NVE4_HW_METRIC_QUERY_COUNT; return 1; } else if (screen->base.class_3d < NVE4_3D_CLASS) { info->name = "Performance metrics"; info->max_active_queries = 1; info->num_queries = NVC0_HW_METRIC_QUERY_COUNT; return 1; } } } #ifdef NOUVEAU_ENABLE_DRIVER_STATISTICS else if (id == NVC0_SW_QUERY_DRV_STAT_GROUP) { info->name = "Driver statistics"; info->max_active_queries = NVC0_SW_QUERY_DRV_STAT_COUNT; info->num_queries = NVC0_SW_QUERY_DRV_STAT_COUNT; return 1; } #endif /* user asked for info about non-existing query group */ info->name = "this_is_not_the_query_group_you_are_looking_for"; info->max_active_queries = 0; info->num_queries = 0; return 0; }
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; nvc0->base.pushbuf = screen->base.pushbuf; ret = nouveau_bufctx_new(screen->base.client, NVC0_BIND_COUNT, &nvc0->bufctx_3d); if (!ret) nouveau_bufctx_new(screen->base.client, 2, &nvc0->bufctx); 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->flush = nvc0_flush; pipe->texture_barrier = nvc0_texture_barrier; 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); #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 nouveau_context_init_vdec(&nvc0->base); /* 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); 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); nvc0->base.scratch.bo_size = 2 << 20; return pipe; out_err: if (nvc0) { if (nvc0->bufctx_3d) nouveau_bufctx_del(&nvc0->bufctx_3d); if (nvc0->bufctx) nouveau_bufctx_del(&nvc0->bufctx); FREE(nvc0); } return NULL; }