Home | History | Annotate | Download | only in nv50
      1 
      2 #include "pipe/p_context.h"
      3 #include "util/u_inlines.h"
      4 #include "util/u_format.h"
      5 
      6 #include "nouveau/nouveau_screen.h"
      7 
      8 #include "nv50_resource.h"
      9 
     10 static struct pipe_resource *
     11 nv50_resource_create(struct pipe_screen *screen,
     12                      const struct pipe_resource *templ)
     13 {
     14    switch (templ->target) {
     15    case PIPE_BUFFER:
     16       return nouveau_buffer_create(screen, templ);
     17    default:
     18       return nv50_miptree_create(screen, templ);
     19    }
     20 }
     21 
     22 static struct pipe_resource *
     23 nv50_resource_from_handle(struct pipe_screen * screen,
     24                           const struct pipe_resource *templ,
     25                           struct winsys_handle *whandle)
     26 {
     27    if (templ->target == PIPE_BUFFER)
     28       return NULL;
     29    else
     30       return nv50_miptree_from_handle(screen, templ, whandle);
     31 }
     32 
     33 struct pipe_surface *
     34 nv50_surface_from_buffer(struct pipe_context *pipe,
     35 			 struct pipe_resource *pbuf,
     36 			 const struct pipe_surface *templ)
     37 {
     38    struct nv50_surface *sf = CALLOC_STRUCT(nv50_surface);
     39    if (!sf)
     40       return NULL;
     41 
     42    pipe_reference_init(&sf->base.reference, 1);
     43    pipe_resource_reference(&sf->base.texture, pbuf);
     44 
     45    sf->base.format = templ->format;
     46    sf->base.usage = templ->usage;
     47    sf->base.u.buf.first_element = templ->u.buf.first_element;
     48    sf->base.u.buf.last_element = templ->u.buf.last_element;
     49 
     50    sf->offset =
     51       templ->u.buf.first_element * util_format_get_blocksize(sf->base.format);
     52 
     53    sf->offset &= ~0x7f; /* FIXME: RT_ADDRESS requires 128 byte alignment */
     54 
     55    sf->width = templ->u.buf.last_element - templ->u.buf.first_element + 1;
     56    sf->height = 1;
     57    sf->depth = 1;
     58 
     59    sf->base.width = sf->width;
     60    sf->base.height = sf->height;
     61 
     62    sf->base.context = pipe;
     63    return &sf->base;
     64 }
     65 
     66 static struct pipe_surface *
     67 nv50_surface_create(struct pipe_context *pipe,
     68 		    struct pipe_resource *pres,
     69 		    const struct pipe_surface *templ)
     70 {
     71    if (unlikely(pres->target == PIPE_BUFFER))
     72       return nv50_surface_from_buffer(pipe, pres, templ);
     73    return nv50_miptree_surface_new(pipe, pres, templ);
     74 }
     75 
     76 void
     77 nv50_surface_destroy(struct pipe_context *pipe, struct pipe_surface *ps)
     78 {
     79    struct nv50_surface *s = nv50_surface(ps);
     80 
     81    pipe_resource_reference(&ps->texture, NULL);
     82 
     83    FREE(s);
     84 }
     85 
     86 void
     87 nv50_init_resource_functions(struct pipe_context *pcontext)
     88 {
     89    pcontext->get_transfer = u_get_transfer_vtbl;
     90    pcontext->transfer_map = u_transfer_map_vtbl;
     91    pcontext->transfer_flush_region = u_transfer_flush_region_vtbl;
     92    pcontext->transfer_unmap = u_transfer_unmap_vtbl;
     93    pcontext->transfer_destroy = u_transfer_destroy_vtbl;
     94    pcontext->transfer_inline_write = u_transfer_inline_write_vtbl;
     95    pcontext->create_surface = nv50_surface_create;
     96    pcontext->surface_destroy = nv50_surface_destroy;
     97 }
     98 
     99 void
    100 nv50_screen_init_resource_functions(struct pipe_screen *pscreen)
    101 {
    102    pscreen->resource_create = nv50_resource_create;
    103    pscreen->resource_from_handle = nv50_resource_from_handle;
    104    pscreen->resource_get_handle = u_resource_get_handle_vtbl;
    105    pscreen->resource_destroy = u_resource_destroy_vtbl;
    106 }
    107