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