1 #include "drm-uapi/drm_fourcc.h"
2
3 #include "pipe/p_context.h"
4 #include "nvc0/nvc0_resource.h"
5 #include "nouveau_screen.h"
6
7
8 static struct pipe_resource *
nvc0_resource_create(struct pipe_screen * screen,const struct pipe_resource * templ)9 nvc0_resource_create(struct pipe_screen *screen,
10 const struct pipe_resource *templ)
11 {
12 switch (templ->target) {
13 case PIPE_BUFFER:
14 return nouveau_buffer_create(screen, templ);
15 default:
16 return nvc0_miptree_create(screen, templ, NULL, 0);
17 }
18 }
19
20 static struct pipe_resource *
nvc0_resource_create_with_modifiers(struct pipe_screen * screen,const struct pipe_resource * templ,const uint64_t * modifiers,int count)21 nvc0_resource_create_with_modifiers(struct pipe_screen *screen,
22 const struct pipe_resource *templ,
23 const uint64_t *modifiers, int count)
24 {
25 switch (templ->target) {
26 case PIPE_BUFFER:
27 return nouveau_buffer_create(screen, templ);
28 default:
29 return nvc0_miptree_create(screen, templ, modifiers, count);
30 }
31 }
32
33 static void
nvc0_resource_destroy(struct pipe_screen * pscreen,struct pipe_resource * res)34 nvc0_resource_destroy(struct pipe_screen *pscreen, struct pipe_resource *res)
35 {
36 if (res->target == PIPE_BUFFER)
37 nouveau_buffer_destroy(pscreen, res);
38 else
39 nv50_miptree_destroy(pscreen, res);
40 }
41
42 static void
nvc0_query_dmabuf_modifiers(struct pipe_screen * screen,enum pipe_format format,int max,uint64_t * modifiers,unsigned int * external_only,int * count)43 nvc0_query_dmabuf_modifiers(struct pipe_screen *screen,
44 enum pipe_format format, int max,
45 uint64_t *modifiers, unsigned int *external_only,
46 int *count)
47 {
48 const int s = nouveau_screen(screen)->tegra_sector_layout ? 0 : 1;
49 const uint32_t uc_kind =
50 nvc0_choose_tiled_storage_type(screen, format, 0, false);
51 const uint32_t num_uc = uc_kind ? 6 : 0; /* max block height = 32 GOBs */
52 const int num_supported = num_uc + 1; /* LINEAR is always supported */
53 const uint32_t kind_gen = nvc0_get_kind_generation(screen);
54 int i, num = 0;
55
56 if (max > num_supported)
57 max = num_supported;
58
59 if (!max) {
60 max = num_supported;
61 external_only = NULL;
62 modifiers = NULL;
63 }
64
65 #define NVC0_ADD_MOD(m) do { \
66 if (modifiers) modifiers[num] = m; \
67 if (external_only) external_only[num] = 0; \
68 num++; \
69 } while (0)
70
71 for (i = 0; i < max && i < num_uc; i++)
72 NVC0_ADD_MOD(DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, s, kind_gen,
73 uc_kind, 5 - i));
74
75 if (i < max)
76 NVC0_ADD_MOD(DRM_FORMAT_MOD_LINEAR);
77
78 #undef NVC0_ADD_MOD
79
80 *count = num;
81 }
82
83 static bool
nvc0_is_dmabuf_modifier_supported(struct pipe_screen * screen,uint64_t modifier,enum pipe_format format,bool * external_only)84 nvc0_is_dmabuf_modifier_supported(struct pipe_screen *screen,
85 uint64_t modifier, enum pipe_format format,
86 bool *external_only)
87 {
88 const int s = nouveau_screen(screen)->tegra_sector_layout ? 0 : 1;
89 const uint32_t uc_kind =
90 nvc0_choose_tiled_storage_type(screen, format, 0, false);
91 const uint32_t num_uc = uc_kind ? 6 : 0; /* max block height = 32 GOBs */
92 const uint32_t kind_gen = nvc0_get_kind_generation(screen);
93 int i;
94
95 if (modifier == DRM_FORMAT_MOD_LINEAR) {
96 if (external_only)
97 *external_only = false;
98
99 return true;
100 }
101
102 for (i = 0; i < num_uc; i++) {
103 if (DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, s, kind_gen, uc_kind, i) == modifier) {
104 if (external_only)
105 *external_only = false;
106
107 return true;
108 }
109 }
110
111 return false;
112 }
113
114 static struct pipe_resource *
nvc0_resource_from_handle(struct pipe_screen * screen,const struct pipe_resource * templ,struct winsys_handle * whandle,unsigned usage)115 nvc0_resource_from_handle(struct pipe_screen * screen,
116 const struct pipe_resource *templ,
117 struct winsys_handle *whandle,
118 unsigned usage)
119 {
120 if (templ->target == PIPE_BUFFER) {
121 return NULL;
122 } else {
123 struct pipe_resource *res = nv50_miptree_from_handle(screen,
124 templ, whandle);
125 return res;
126 }
127 }
128
129 static struct pipe_surface *
nvc0_surface_create(struct pipe_context * pipe,struct pipe_resource * pres,const struct pipe_surface * templ)130 nvc0_surface_create(struct pipe_context *pipe,
131 struct pipe_resource *pres,
132 const struct pipe_surface *templ)
133 {
134 if (unlikely(pres->target == PIPE_BUFFER))
135 return nv50_surface_from_buffer(pipe, pres, templ);
136 return nvc0_miptree_surface_new(pipe, pres, templ);
137 }
138
139 static struct pipe_resource *
nvc0_resource_from_user_memory(struct pipe_screen * pipe,const struct pipe_resource * templ,void * user_memory)140 nvc0_resource_from_user_memory(struct pipe_screen *pipe,
141 const struct pipe_resource *templ,
142 void *user_memory)
143 {
144 ASSERTED struct nouveau_screen *screen = nouveau_screen(pipe);
145
146 assert(screen->has_svm);
147 assert(templ->target == PIPE_BUFFER);
148
149 return nouveau_buffer_create_from_user(pipe, templ, user_memory);
150 }
151
152 void
nvc0_init_resource_functions(struct pipe_context * pcontext)153 nvc0_init_resource_functions(struct pipe_context *pcontext)
154 {
155 pcontext->buffer_map = nouveau_buffer_transfer_map;
156 pcontext->texture_map = nvc0_miptree_transfer_map;
157 pcontext->transfer_flush_region = nouveau_buffer_transfer_flush_region;
158 pcontext->buffer_unmap = nouveau_buffer_transfer_unmap;
159 pcontext->texture_unmap = nvc0_miptree_transfer_unmap;
160 pcontext->buffer_subdata = u_default_buffer_subdata;
161 pcontext->texture_subdata = u_default_texture_subdata;
162 pcontext->create_surface = nvc0_surface_create;
163 pcontext->surface_destroy = nv50_surface_destroy;
164 pcontext->invalidate_resource = nv50_invalidate_resource;
165 }
166
167 void
nvc0_screen_init_resource_functions(struct pipe_screen * pscreen)168 nvc0_screen_init_resource_functions(struct pipe_screen *pscreen)
169 {
170 pscreen->resource_create = nvc0_resource_create;
171 pscreen->resource_create_with_modifiers = nvc0_resource_create_with_modifiers;
172 pscreen->query_dmabuf_modifiers = nvc0_query_dmabuf_modifiers;
173 pscreen->is_dmabuf_modifier_supported = nvc0_is_dmabuf_modifier_supported;
174 pscreen->resource_from_handle = nvc0_resource_from_handle;
175 pscreen->resource_get_handle = nvc0_miptree_get_handle;
176 pscreen->resource_destroy = nvc0_resource_destroy;
177 pscreen->resource_from_user_memory = nvc0_resource_from_user_memory;
178 }
179