nv50: enable h264 and mpeg4 for nv98+ (vp3, vp4.0)
[mesa.git] / src / gallium / drivers / nouveau / nouveau_vp3_video.c
1 /*
2 * Copyright 2011-2013 Maarten Lankhorst
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22
23 #include <sys/mman.h>
24 #include <stdio.h>
25 #include <fcntl.h>
26
27 #include "nouveau_screen.h"
28 #include "nouveau_context.h"
29 #include "nouveau_vp3_video.h"
30
31 #include "util/u_video.h"
32 #include "util/u_format.h"
33 #include "util/u_sampler.h"
34
35 static struct pipe_sampler_view **
36 nouveau_vp3_video_buffer_sampler_view_planes(struct pipe_video_buffer *buffer)
37 {
38 struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer;
39 return buf->sampler_view_planes;
40 }
41
42 static struct pipe_sampler_view **
43 nouveau_vp3_video_buffer_sampler_view_components(struct pipe_video_buffer *buffer)
44 {
45 struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer;
46 return buf->sampler_view_components;
47 }
48
49 static struct pipe_surface **
50 nouveau_vp3_video_buffer_surfaces(struct pipe_video_buffer *buffer)
51 {
52 struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer;
53 return buf->surfaces;
54 }
55
56 static void
57 nouveau_vp3_video_buffer_destroy(struct pipe_video_buffer *buffer)
58 {
59 struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer;
60 unsigned i;
61
62 assert(buf);
63
64 for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
65 pipe_resource_reference(&buf->resources[i], NULL);
66 pipe_sampler_view_reference(&buf->sampler_view_planes[i], NULL);
67 pipe_sampler_view_reference(&buf->sampler_view_components[i], NULL);
68 pipe_surface_reference(&buf->surfaces[i * 2], NULL);
69 pipe_surface_reference(&buf->surfaces[i * 2 + 1], NULL);
70 }
71 FREE(buffer);
72 }
73
74 struct pipe_video_buffer *
75 nouveau_vp3_video_buffer_create(struct pipe_context *pipe,
76 const struct pipe_video_buffer *templat,
77 int flags)
78 {
79 struct nouveau_vp3_video_buffer *buffer;
80 struct pipe_resource templ;
81 unsigned i, j, component;
82 struct pipe_sampler_view sv_templ;
83 struct pipe_surface surf_templ;
84
85 assert(templat->interlaced);
86 if (getenv("XVMC_VL") || templat->buffer_format != PIPE_FORMAT_NV12)
87 return vl_video_buffer_create(pipe, templat);
88
89 assert(templat->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
90
91 buffer = CALLOC_STRUCT(nouveau_vp3_video_buffer);
92 if (!buffer)
93 return NULL;
94
95 buffer->base.buffer_format = templat->buffer_format;
96 buffer->base.context = pipe;
97 buffer->base.destroy = nouveau_vp3_video_buffer_destroy;
98 buffer->base.chroma_format = templat->chroma_format;
99 buffer->base.width = templat->width;
100 buffer->base.height = templat->height;
101 buffer->base.get_sampler_view_planes = nouveau_vp3_video_buffer_sampler_view_planes;
102 buffer->base.get_sampler_view_components = nouveau_vp3_video_buffer_sampler_view_components;
103 buffer->base.get_surfaces = nouveau_vp3_video_buffer_surfaces;
104 buffer->base.interlaced = true;
105
106 memset(&templ, 0, sizeof(templ));
107 templ.target = PIPE_TEXTURE_2D_ARRAY;
108 templ.depth0 = 1;
109 templ.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
110 templ.format = PIPE_FORMAT_R8_UNORM;
111 templ.width0 = buffer->base.width;
112 templ.height0 = (buffer->base.height + 1)/2;
113 templ.flags = flags;
114 templ.array_size = 2;
115
116 buffer->resources[0] = pipe->screen->resource_create(pipe->screen, &templ);
117 if (!buffer->resources[0])
118 goto error;
119
120 templ.format = PIPE_FORMAT_R8G8_UNORM;
121 buffer->num_planes = 2;
122 templ.width0 = (templ.width0 + 1) / 2;
123 templ.height0 = (templ.height0 + 1) / 2;
124 for (i = 1; i < buffer->num_planes; ++i) {
125 buffer->resources[i] = pipe->screen->resource_create(pipe->screen, &templ);
126 if (!buffer->resources[i])
127 goto error;
128 }
129
130 memset(&sv_templ, 0, sizeof(sv_templ));
131 for (component = 0, i = 0; i < buffer->num_planes; ++i ) {
132 struct pipe_resource *res = buffer->resources[i];
133 unsigned nr_components = util_format_get_nr_components(res->format);
134
135 u_sampler_view_default_template(&sv_templ, res, res->format);
136 buffer->sampler_view_planes[i] = pipe->create_sampler_view(pipe, res, &sv_templ);
137 if (!buffer->sampler_view_planes[i])
138 goto error;
139
140 for (j = 0; j < nr_components; ++j, ++component) {
141 sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = PIPE_SWIZZLE_RED + j;
142 sv_templ.swizzle_a = PIPE_SWIZZLE_ONE;
143
144 buffer->sampler_view_components[component] = pipe->create_sampler_view(pipe, res, &sv_templ);
145 if (!buffer->sampler_view_components[component])
146 goto error;
147 }
148 }
149
150 memset(&surf_templ, 0, sizeof(surf_templ));
151 for (j = 0; j < buffer->num_planes; ++j) {
152 surf_templ.format = buffer->resources[j]->format;
153 surf_templ.u.tex.first_layer = surf_templ.u.tex.last_layer = 0;
154 buffer->surfaces[j * 2] = pipe->create_surface(pipe, buffer->resources[j], &surf_templ);
155 if (!buffer->surfaces[j * 2])
156 goto error;
157
158 surf_templ.u.tex.first_layer = surf_templ.u.tex.last_layer = 1;
159 buffer->surfaces[j * 2 + 1] = pipe->create_surface(pipe, buffer->resources[j], &surf_templ);
160 if (!buffer->surfaces[j * 2 + 1])
161 goto error;
162 }
163
164 return &buffer->base;
165
166 error:
167 nouveau_vp3_video_buffer_destroy(&buffer->base);
168 return NULL;
169 }
170
171 static void
172 nouveau_vp3_decoder_flush(struct pipe_video_codec *decoder)
173 {
174 }
175
176 static void
177 nouveau_vp3_decoder_begin_frame(struct pipe_video_codec *decoder,
178 struct pipe_video_buffer *target,
179 struct pipe_picture_desc *picture)
180 {
181 }
182
183 static void
184 nouveau_vp3_decoder_end_frame(struct pipe_video_codec *decoder,
185 struct pipe_video_buffer *target,
186 struct pipe_picture_desc *picture)
187 {
188 }
189
190 static void
191 nouveau_vp3_decoder_destroy(struct pipe_video_codec *decoder)
192 {
193 struct nouveau_vp3_decoder *dec = (struct nouveau_vp3_decoder *)decoder;
194 int i;
195
196 nouveau_bo_ref(NULL, &dec->ref_bo);
197 nouveau_bo_ref(NULL, &dec->bitplane_bo);
198 nouveau_bo_ref(NULL, &dec->inter_bo[0]);
199 nouveau_bo_ref(NULL, &dec->inter_bo[1]);
200 #if NOUVEAU_VP3_DEBUG_FENCE
201 nouveau_bo_ref(NULL, &dec->fence_bo);
202 #endif
203 nouveau_bo_ref(NULL, &dec->fw_bo);
204
205 for (i = 0; i < NOUVEAU_VP3_VIDEO_QDEPTH; ++i)
206 nouveau_bo_ref(NULL, &dec->bsp_bo[i]);
207
208 nouveau_object_del(&dec->bsp);
209 nouveau_object_del(&dec->vp);
210 nouveau_object_del(&dec->ppp);
211
212 if (dec->channel[0] != dec->channel[1]) {
213 for (i = 0; i < 3; ++i) {
214 nouveau_pushbuf_del(&dec->pushbuf[i]);
215 nouveau_object_del(&dec->channel[i]);
216 }
217 } else {
218 nouveau_pushbuf_del(dec->pushbuf);
219 nouveau_object_del(dec->channel);
220 }
221
222 FREE(dec);
223 }
224
225 void
226 nouveau_vp3_decoder_init_common(struct pipe_video_codec *dec)
227 {
228 dec->destroy = nouveau_vp3_decoder_destroy;
229 dec->flush = nouveau_vp3_decoder_flush;
230 dec->begin_frame = nouveau_vp3_decoder_begin_frame;
231 dec->end_frame = nouveau_vp3_decoder_end_frame;
232 }
233
234 static void vp3_getpath(enum pipe_video_profile profile, char *path)
235 {
236 switch (u_reduce_video_profile(profile)) {
237 case PIPE_VIDEO_FORMAT_MPEG12: {
238 sprintf(path, "/lib/firmware/nouveau/vuc-vp3-mpeg12-0");
239 break;
240 }
241 case PIPE_VIDEO_FORMAT_VC1: {
242 sprintf(path, "/lib/firmware/nouveau/vuc-vp3-vc1-0");
243 break;
244 }
245 case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
246 sprintf(path, "/lib/firmware/nouveau/vuc-vp3-h264-0");
247 break;
248 }
249 default: assert(0);
250 }
251 }
252
253 static void vp4_getpath(enum pipe_video_profile profile, char *path)
254 {
255 switch (u_reduce_video_profile(profile)) {
256 case PIPE_VIDEO_FORMAT_MPEG12: {
257 sprintf(path, "/lib/firmware/nouveau/vuc-mpeg12-0");
258 break;
259 }
260 case PIPE_VIDEO_FORMAT_MPEG4: {
261 sprintf(path, "/lib/firmware/nouveau/vuc-mpeg4-0");
262 break;
263 }
264 case PIPE_VIDEO_FORMAT_VC1: {
265 sprintf(path, "/lib/firmware/nouveau/vuc-vc1-0");
266 break;
267 }
268 case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
269 sprintf(path, "/lib/firmware/nouveau/vuc-h264-0");
270 break;
271 }
272 default: assert(0);
273 }
274 }
275
276 int
277 nouveau_vp3_load_firmware(struct nouveau_vp3_decoder *dec,
278 enum pipe_video_profile profile,
279 unsigned chipset)
280 {
281 int fd;
282 char path[PATH_MAX];
283 ssize_t r;
284 uint32_t *end, endval;
285
286 if (chipset >= 0xa3 && chipset != 0xaa && chipset != 0xac)
287 vp4_getpath(profile, path);
288 else
289 vp3_getpath(profile, path);
290
291 if (nouveau_bo_map(dec->fw_bo, NOUVEAU_BO_WR, dec->client))
292 return 1;
293
294 fd = open(path, O_RDONLY | O_CLOEXEC);
295 if (fd < 0) {
296 fprintf(stderr, "opening firmware file %s failed: %m\n", path);
297 return 1;
298 }
299 r = read(fd, dec->fw_bo->map, 0x4000);
300 close(fd);
301
302 if (r < 0) {
303 fprintf(stderr, "reading firmware file %s failed: %m\n", path);
304 return 1;
305 }
306
307 if (r == 0x4000) {
308 fprintf(stderr, "firmware file %s too large!\n", path);
309 return 1;
310 }
311
312 if (r & 0xff) {
313 fprintf(stderr, "firmware file %s wrong size!\n", path);
314 return 1;
315 }
316
317 end = dec->fw_bo->map + r - 4;
318 endval = *end;
319 while (endval == *end)
320 end--;
321
322 r = (intptr_t)end - (intptr_t)dec->fw_bo->map + 4;
323
324 switch (u_reduce_video_profile(profile)) {
325 case PIPE_VIDEO_FORMAT_MPEG12: {
326 assert((r & 0xff) == 0xe0);
327 dec->fw_sizes = (0x2e0<<16) | (r - 0x2e0);
328 break;
329 }
330 case PIPE_VIDEO_FORMAT_MPEG4: {
331 assert((r & 0xff) == 0xe0);
332 dec->fw_sizes = (0x2e0<<16) | (r - 0x2e0);
333 break;
334 }
335 case PIPE_VIDEO_FORMAT_VC1: {
336 assert((r & 0xff) == 0xac);
337 dec->fw_sizes = (0x3ac<<16) | (r - 0x3ac);
338 break;
339 }
340 case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
341 assert((r & 0xff) == 0x70);
342 dec->fw_sizes = (0x370<<16) | (r - 0x370);
343 break;
344 }
345 default:
346 return 1;
347 }
348 munmap(dec->fw_bo->map, dec->fw_bo->size);
349 dec->fw_bo->map = NULL;
350 return 0;
351 }
352
353 int
354 nouveau_vp3_screen_get_video_param(struct pipe_screen *pscreen,
355 enum pipe_video_profile profile,
356 enum pipe_video_entrypoint entrypoint,
357 enum pipe_video_cap param)
358 {
359 int chipset = nouveau_screen(pscreen)->device->chipset;
360 int vp3 = chipset < 0xa3 || chipset == 0xaa || chipset == 0xac;
361 int vp5 = chipset >= 0xd0;
362 enum pipe_video_format codec = u_reduce_video_profile(profile);
363 switch (param) {
364 case PIPE_VIDEO_CAP_SUPPORTED:
365 /* VP3 does not support MPEG4, VP4+ do. */
366 return profile >= PIPE_VIDEO_PROFILE_MPEG1 && (
367 !vp3 || codec != PIPE_VIDEO_FORMAT_MPEG4);
368 case PIPE_VIDEO_CAP_NPOT_TEXTURES:
369 return 1;
370 case PIPE_VIDEO_CAP_MAX_WIDTH:
371 case PIPE_VIDEO_CAP_MAX_HEIGHT:
372 return vp5 ? 4096 : 2048;
373 case PIPE_VIDEO_CAP_PREFERED_FORMAT:
374 return PIPE_FORMAT_NV12;
375 case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED:
376 case PIPE_VIDEO_CAP_PREFERS_INTERLACED:
377 return true;
378 case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE:
379 return false;
380 case PIPE_VIDEO_CAP_MAX_LEVEL:
381 switch (profile) {
382 case PIPE_VIDEO_PROFILE_MPEG1:
383 return 0;
384 case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE:
385 case PIPE_VIDEO_PROFILE_MPEG2_MAIN:
386 return 3;
387 case PIPE_VIDEO_PROFILE_MPEG4_SIMPLE:
388 return 3;
389 case PIPE_VIDEO_PROFILE_MPEG4_ADVANCED_SIMPLE:
390 return 5;
391 case PIPE_VIDEO_PROFILE_VC1_SIMPLE:
392 return 1;
393 case PIPE_VIDEO_PROFILE_VC1_MAIN:
394 return 2;
395 case PIPE_VIDEO_PROFILE_VC1_ADVANCED:
396 return 4;
397 case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE:
398 case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN:
399 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH:
400 return 41;
401 default:
402 debug_printf("unknown video profile: %d\n", profile);
403 return 0;
404 }
405 default:
406 debug_printf("unknown video param: %d\n", param);
407 return 0;
408 }
409 }
410
411 boolean
412 nouveau_vp3_screen_video_supported(struct pipe_screen *screen,
413 enum pipe_format format,
414 enum pipe_video_profile profile,
415 enum pipe_video_entrypoint entrypoint)
416 {
417 if (profile != PIPE_VIDEO_PROFILE_UNKNOWN)
418 return format == PIPE_FORMAT_NV12;
419
420 return vl_video_buffer_is_format_supported(screen, format, profile, entrypoint);
421 }