Esempio n. 1
0
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;
}
Esempio n. 2
0
struct pipe_context *
nv50_create(struct pipe_screen *pscreen, void *priv)
{
   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, NV50_BIND_COUNT,
                            &nv50->bufctx_3d);
   if (!ret)
      ret = nouveau_bufctx_new(screen->base.client, 2, &nv50->bufctx);
   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->flush = nv50_flush;
   pipe->texture_barrier = nv50_texture_barrier;

   if (!screen->cur_ctx) {
      screen->cur_ctx = nv50;
      nouveau_pushbuf_bufctx(screen->base.pushbuf, nv50->bufctx);
   }

   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;

#ifdef NV50_WITH_DRAW_MODULE
   /* no software fallbacks implemented */
   nv50->draw = draw_create(pipe);
   assert(nv50->draw);
   draw_set_rasterize_stage(nv50->draw, nv50_draw_render_stage(nv50));
#endif

   nouveau_context_init_vdec(&nv50->base);

   flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;

   BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->code);
   BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->uniforms);
   BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->txc);
   BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->stack_bo);

   flags = NOUVEAU_BO_GART | NOUVEAU_BO_WR;

   BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->fence.bo);
   BCTX_REFN_bo(nv50->bufctx, FENCE, flags, screen->fence.bo);

   nv50->base.scratch.bo_size = 2 << 20;

   return pipe;

out_err:
   if (nv50) {
      if (nv50->bufctx_3d)
         nouveau_bufctx_del(&nv50->bufctx_3d);
      if (nv50->bufctx)
         nouveau_bufctx_del(&nv50->bufctx);
      if (nv50->blit)
         FREE(nv50->blit);
      FREE(nv50);
   }
   return NULL;
}
Esempio n. 3
0
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;
}