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 10static struct pipe_resource * 11nv50_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 22static struct pipe_resource * 23nv50_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 33struct pipe_surface * 34nv50_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 66static struct pipe_surface * 67nv50_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 76void 77nv50_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 86void 87nv50_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 99void 100nv50_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