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