1 2#include "pipe/p_context.h" 3#include "util/u_inlines.h" 4#include "util/format/u_format.h" 5 6#include "nouveau_screen.h" 7 8#include "nv50/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 void 23nv50_resource_destroy(struct pipe_screen *pscreen, struct pipe_resource *res) 24{ 25 if (res->target == PIPE_BUFFER) 26 nouveau_buffer_destroy(pscreen, res); 27 else 28 nv50_miptree_destroy(pscreen, res); 29} 30 31static struct pipe_resource * 32nv50_resource_from_handle(struct pipe_screen * screen, 33 const struct pipe_resource *templ, 34 struct winsys_handle *whandle, 35 unsigned usage) 36{ 37 if (templ->target == PIPE_BUFFER) 38 return NULL; 39 else 40 return nv50_miptree_from_handle(screen, templ, whandle); 41} 42 43struct pipe_surface * 44nv50_surface_from_buffer(struct pipe_context *pipe, 45 struct pipe_resource *pbuf, 46 const struct pipe_surface *templ) 47{ 48 struct nv50_surface *sf = CALLOC_STRUCT(nv50_surface); 49 if (!sf) 50 return NULL; 51 52 pipe_reference_init(&sf->base.reference, 1); 53 pipe_resource_reference(&sf->base.texture, pbuf); 54 55 sf->base.format = templ->format; 56 sf->base.writable = templ->writable; 57 sf->base.u.buf.first_element = templ->u.buf.first_element; 58 sf->base.u.buf.last_element = templ->u.buf.last_element; 59 60 sf->offset = 61 templ->u.buf.first_element * util_format_get_blocksize(sf->base.format); 62 63 sf->offset &= ~0x7f; /* FIXME: RT_ADDRESS requires 128 byte alignment */ 64 65 sf->width = templ->u.buf.last_element - templ->u.buf.first_element + 1; 66 sf->height = 1; 67 sf->depth = 1; 68 69 sf->base.width = sf->width; 70 sf->base.height = sf->height; 71 72 sf->base.context = pipe; 73 return &sf->base; 74} 75 76static struct pipe_surface * 77nv50_surface_create(struct pipe_context *pipe, 78 struct pipe_resource *pres, 79 const struct pipe_surface *templ) 80{ 81 if (unlikely(pres->target == PIPE_BUFFER)) 82 return nv50_surface_from_buffer(pipe, pres, templ); 83 return nv50_miptree_surface_new(pipe, pres, templ); 84} 85 86void 87nv50_surface_destroy(struct pipe_context *pipe, struct pipe_surface *ps) 88{ 89 struct nv50_surface *s = nv50_surface(ps); 90 91 pipe_resource_reference(&ps->texture, NULL); 92 93 FREE(s); 94} 95 96void 97nv50_invalidate_resource(struct pipe_context *pipe, struct pipe_resource *res) 98{ 99 if (res->target == PIPE_BUFFER) 100 nouveau_buffer_invalidate(pipe, res); 101} 102 103void 104nv50_init_resource_functions(struct pipe_context *pcontext) 105{ 106 pcontext->buffer_map = nouveau_buffer_transfer_map; 107 pcontext->texture_map = nv50_miptree_transfer_map; 108 pcontext->transfer_flush_region = nouveau_buffer_transfer_flush_region; 109 pcontext->buffer_unmap = nouveau_buffer_transfer_unmap; 110 pcontext->texture_unmap = nv50_miptree_transfer_unmap; 111 pcontext->buffer_subdata = u_default_buffer_subdata; 112 pcontext->texture_subdata = u_default_texture_subdata; 113 pcontext->create_surface = nv50_surface_create; 114 pcontext->surface_destroy = nv50_surface_destroy; 115 pcontext->invalidate_resource = nv50_invalidate_resource; 116} 117 118void 119nv50_screen_init_resource_functions(struct pipe_screen *pscreen) 120{ 121 pscreen->resource_create = nv50_resource_create; 122 pscreen->resource_from_handle = nv50_resource_from_handle; 123 pscreen->resource_get_handle = nv50_miptree_get_handle; 124 pscreen->resource_destroy = nv50_resource_destroy; 125} 126