OSDN Git Service

172d80c44c29c6758650205b3ed614248252ab0f
[android-x86/external-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 <sys/stat.h>
25 #include <stdio.h>
26 #include <fcntl.h>
27
28 #include "nouveau_screen.h"
29 #include "nouveau_context.h"
30 #include "nouveau_vp3_video.h"
31
32 #include "util/u_video.h"
33 #include "util/u_format.h"
34 #include "util/u_sampler.h"
35
36 static struct pipe_sampler_view **
37 nouveau_vp3_video_buffer_sampler_view_planes(struct pipe_video_buffer *buffer)
38 {
39    struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer;
40    return buf->sampler_view_planes;
41 }
42
43 static struct pipe_sampler_view **
44 nouveau_vp3_video_buffer_sampler_view_components(struct pipe_video_buffer *buffer)
45 {
46    struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer;
47    return buf->sampler_view_components;
48 }
49
50 static struct pipe_surface **
51 nouveau_vp3_video_buffer_surfaces(struct pipe_video_buffer *buffer)
52 {
53    struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer;
54    return buf->surfaces;
55 }
56
57 static void
58 nouveau_vp3_video_buffer_destroy(struct pipe_video_buffer *buffer)
59 {
60    struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer;
61    unsigned i;
62
63    assert(buf);
64
65    for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
66       pipe_resource_reference(&buf->resources[i], NULL);
67       pipe_sampler_view_reference(&buf->sampler_view_planes[i], NULL);
68       pipe_sampler_view_reference(&buf->sampler_view_components[i], NULL);
69       pipe_surface_reference(&buf->surfaces[i * 2], NULL);
70       pipe_surface_reference(&buf->surfaces[i * 2 + 1], NULL);
71    }
72    FREE(buffer);
73 }
74
75 struct pipe_video_buffer *
76 nouveau_vp3_video_buffer_create(struct pipe_context *pipe,
77                          const struct pipe_video_buffer *templat,
78                          int flags)
79 {
80    struct nouveau_vp3_video_buffer *buffer;
81    struct pipe_resource templ;
82    unsigned i, j, component;
83    struct pipe_sampler_view sv_templ;
84    struct pipe_surface surf_templ;
85
86    if (getenv("XVMC_VL") || templat->buffer_format != PIPE_FORMAT_NV12)
87       return vl_video_buffer_create(pipe, templat);
88
89    assert(templat->interlaced);
90    assert(templat->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
91
92    buffer = CALLOC_STRUCT(nouveau_vp3_video_buffer);
93    if (!buffer)
94       return NULL;
95
96    buffer->base.buffer_format = templat->buffer_format;
97    buffer->base.context = pipe;
98    buffer->base.destroy = nouveau_vp3_video_buffer_destroy;
99    buffer->base.chroma_format = templat->chroma_format;
100    buffer->base.width = templat->width;
101    buffer->base.height = templat->height;
102    buffer->base.get_sampler_view_planes = nouveau_vp3_video_buffer_sampler_view_planes;
103    buffer->base.get_sampler_view_components = nouveau_vp3_video_buffer_sampler_view_components;
104    buffer->base.get_surfaces = nouveau_vp3_video_buffer_surfaces;
105    buffer->base.interlaced = true;
106
107    memset(&templ, 0, sizeof(templ));
108    templ.target = PIPE_TEXTURE_2D_ARRAY;
109    templ.depth0 = 1;
110    templ.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
111    templ.format = PIPE_FORMAT_R8_UNORM;
112    templ.width0 = buffer->base.width;
113    templ.height0 = (buffer->base.height + 1)/2;
114    templ.flags = flags;
115    templ.array_size = 2;
116
117    buffer->resources[0] = pipe->screen->resource_create(pipe->screen, &templ);
118    if (!buffer->resources[0])
119       goto error;
120
121    templ.format = PIPE_FORMAT_R8G8_UNORM;
122    buffer->num_planes = 2;
123    templ.width0 = (templ.width0 + 1) / 2;
124    templ.height0 = (templ.height0 + 1) / 2;
125    for (i = 1; i < buffer->num_planes; ++i) {
126       buffer->resources[i] = pipe->screen->resource_create(pipe->screen, &templ);
127       if (!buffer->resources[i])
128          goto error;
129    }
130
131    memset(&sv_templ, 0, sizeof(sv_templ));
132    for (component = 0, i = 0; i < buffer->num_planes; ++i ) {
133       struct pipe_resource *res = buffer->resources[i];
134       unsigned nr_components = util_format_get_nr_components(res->format);
135
136       u_sampler_view_default_template(&sv_templ, res, res->format);
137       buffer->sampler_view_planes[i] = pipe->create_sampler_view(pipe, res, &sv_templ);
138       if (!buffer->sampler_view_planes[i])
139          goto error;
140
141       for (j = 0; j < nr_components; ++j, ++component) {
142          sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = PIPE_SWIZZLE_X + j;
143          sv_templ.swizzle_a = PIPE_SWIZZLE_1;
144
145          buffer->sampler_view_components[component] = pipe->create_sampler_view(pipe, res, &sv_templ);
146          if (!buffer->sampler_view_components[component])
147             goto error;
148       }
149   }
150
151    memset(&surf_templ, 0, sizeof(surf_templ));
152    for (j = 0; j < buffer->num_planes; ++j) {
153       surf_templ.format = buffer->resources[j]->format;
154       surf_templ.u.tex.first_layer = surf_templ.u.tex.last_layer = 0;
155       buffer->surfaces[j * 2] = pipe->create_surface(pipe, buffer->resources[j], &surf_templ);
156       if (!buffer->surfaces[j * 2])
157          goto error;
158
159       surf_templ.u.tex.first_layer = surf_templ.u.tex.last_layer = 1;
160       buffer->surfaces[j * 2 + 1] = pipe->create_surface(pipe, buffer->resources[j], &surf_templ);
161       if (!buffer->surfaces[j * 2 + 1])
162          goto error;
163    }
164
165    return &buffer->base;
166
167 error:
168    nouveau_vp3_video_buffer_destroy(&buffer->base);
169    return NULL;
170 }
171
172 static void
173 nouveau_vp3_decoder_flush(struct pipe_video_codec *decoder)
174 {
175 }
176
177 static void
178 nouveau_vp3_decoder_begin_frame(struct pipe_video_codec *decoder,
179                                 struct pipe_video_buffer *target,
180                                 struct pipe_picture_desc *picture)
181 {
182 }
183
184 static void
185 nouveau_vp3_decoder_end_frame(struct pipe_video_codec *decoder,
186                               struct pipe_video_buffer *target,
187                               struct pipe_picture_desc *picture)
188 {
189 }
190
191 static void
192 nouveau_vp3_decoder_destroy(struct pipe_video_codec *decoder)
193 {
194    struct nouveau_vp3_decoder *dec = (struct nouveau_vp3_decoder *)decoder;
195    int i;
196
197    nouveau_bo_ref(NULL, &dec->ref_bo);
198    nouveau_bo_ref(NULL, &dec->bitplane_bo);
199    nouveau_bo_ref(NULL, &dec->inter_bo[0]);
200    nouveau_bo_ref(NULL, &dec->inter_bo[1]);
201 #if NOUVEAU_VP3_DEBUG_FENCE
202    nouveau_bo_ref(NULL, &dec->fence_bo);
203 #endif
204    nouveau_bo_ref(NULL, &dec->fw_bo);
205
206    for (i = 0; i < NOUVEAU_VP3_VIDEO_QDEPTH; ++i)
207       nouveau_bo_ref(NULL, &dec->bsp_bo[i]);
208
209    nouveau_object_del(&dec->bsp);
210    nouveau_object_del(&dec->vp);
211    nouveau_object_del(&dec->ppp);
212
213    if (dec->channel[0] != dec->channel[1]) {
214       for (i = 0; i < 3; ++i) {
215          nouveau_pushbuf_del(&dec->pushbuf[i]);
216          nouveau_object_del(&dec->channel[i]);
217       }
218    } else {
219       nouveau_pushbuf_del(dec->pushbuf);
220       nouveau_object_del(dec->channel);
221    }
222
223    FREE(dec);
224 }
225
226 void
227 nouveau_vp3_decoder_init_common(struct pipe_video_codec *dec)
228 {
229    dec->destroy = nouveau_vp3_decoder_destroy;
230    dec->flush = nouveau_vp3_decoder_flush;
231    dec->begin_frame = nouveau_vp3_decoder_begin_frame;
232    dec->end_frame = nouveau_vp3_decoder_end_frame;
233 }
234
235 static void vp3_getpath(enum pipe_video_profile profile, char *path)
236 {
237    switch (u_reduce_video_profile(profile)) {
238       case PIPE_VIDEO_FORMAT_MPEG12: {
239          sprintf(path, "/lib/firmware/nouveau/vuc-vp3-mpeg12-0");
240          break;
241       }
242       case PIPE_VIDEO_FORMAT_VC1: {
243          sprintf(path, "/lib/firmware/nouveau/vuc-vp3-vc1-0");
244          break;
245       }
246       case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
247          sprintf(path, "/lib/firmware/nouveau/vuc-vp3-h264-0");
248          break;
249       }
250       default: assert(0);
251    }
252 }
253
254 static void vp4_getpath(enum pipe_video_profile profile, char *path)
255 {
256    switch (u_reduce_video_profile(profile)) {
257       case PIPE_VIDEO_FORMAT_MPEG12: {
258          sprintf(path, "/lib/firmware/nouveau/vuc-mpeg12-0");
259          break;
260       }
261       case PIPE_VIDEO_FORMAT_MPEG4: {
262          sprintf(path, "/lib/firmware/nouveau/vuc-mpeg4-0");
263          break;
264       }
265       case PIPE_VIDEO_FORMAT_VC1: {
266          sprintf(path, "/lib/firmware/nouveau/vuc-vc1-0");
267          break;
268       }
269       case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
270          sprintf(path, "/lib/firmware/nouveau/vuc-h264-0");
271          break;
272       }
273       default: assert(0);
274    }
275 }
276
277 int
278 nouveau_vp3_load_firmware(struct nouveau_vp3_decoder *dec,
279                           enum pipe_video_profile profile,
280                           unsigned chipset)
281 {
282    int fd;
283    char path[PATH_MAX];
284    ssize_t r;
285    uint32_t *end, endval;
286
287    if (chipset >= 0xa3 && chipset != 0xaa && chipset != 0xac)
288       vp4_getpath(profile, path);
289    else
290       vp3_getpath(profile, path);
291
292    if (nouveau_bo_map(dec->fw_bo, NOUVEAU_BO_WR, dec->client))
293       return 1;
294
295    fd = open(path, O_RDONLY | O_CLOEXEC);
296    if (fd < 0) {
297       fprintf(stderr, "opening firmware file %s failed: %m\n", path);
298       return 1;
299    }
300    r = read(fd, dec->fw_bo->map, 0x4000);
301    close(fd);
302
303    if (r < 0) {
304       fprintf(stderr, "reading firmware file %s failed: %m\n", path);
305       return 1;
306    }
307
308    if (r == 0x4000) {
309       fprintf(stderr, "firmware file %s too large!\n", path);
310       return 1;
311    }
312
313    if (r & 0xff) {
314       fprintf(stderr, "firmware file %s wrong size!\n", path);
315       return 1;
316    }
317
318    end = dec->fw_bo->map + r - 4;
319    endval = *end;
320    while (endval == *end)
321       end--;
322
323    r = (intptr_t)end - (intptr_t)dec->fw_bo->map + 4;
324
325    switch (u_reduce_video_profile(profile)) {
326       case PIPE_VIDEO_FORMAT_MPEG12: {
327          assert((r & 0xff) == 0xe0);
328          dec->fw_sizes = (0x2e0<<16) | (r - 0x2e0);
329          break;
330       }
331       case PIPE_VIDEO_FORMAT_MPEG4: {
332          assert((r & 0xff) == 0xe0);
333          dec->fw_sizes = (0x2e0<<16) | (r - 0x2e0);
334          break;
335       }
336       case PIPE_VIDEO_FORMAT_VC1: {
337          assert((r & 0xff) == 0xac);
338          dec->fw_sizes = (0x3ac<<16) | (r - 0x3ac);
339          break;
340       }
341       case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
342          assert((r & 0xff) == 0x70);
343          dec->fw_sizes = (0x370<<16) | (r - 0x370);
344          break;
345       }
346       default:
347          return 1;
348    }
349    munmap(dec->fw_bo->map, dec->fw_bo->size);
350    dec->fw_bo->map = NULL;
351    return 0;
352 }
353
354 static int
355 firmware_present(struct pipe_screen *pscreen, enum pipe_video_profile profile)
356 {
357    struct nouveau_screen *screen = nouveau_screen(pscreen);
358    int chipset = screen->device->chipset;
359    int vp3 = chipset < 0xa3 || chipset == 0xaa || chipset == 0xac;
360    int vp5 = chipset >= 0xd0;
361    int ret;
362
363    /* For all chipsets, try to create a BSP objects. Assume that if firmware
364     * is present for it, firmware is also present for VP/PPP */
365    if (!(screen->firmware_info.profiles_checked & 1)) {
366       struct nouveau_object *channel = NULL, *bsp = NULL;
367       struct nv04_fifo nv04_data = {.vram = 0xbeef0201, .gart = 0xbeef0202};
368       struct nvc0_fifo nvc0_args = {};
369       struct nve0_fifo nve0_args = {.engine = NVE0_FIFO_ENGINE_BSP};
370       void *data = NULL;
371       int size, oclass;
372       if (chipset < 0xc0)
373          oclass = 0x85b1;
374       else if (chipset < 0xe0)
375          oclass = 0x90b1;
376       else
377          oclass = 0x95b1;
378
379       if (chipset < 0xc0) {
380          data = &nv04_data;
381          size = sizeof(nv04_data);
382       } else if (chipset < 0xe0) {
383          data = &nvc0_args;
384          size = sizeof(nvc0_args);
385       } else {
386          data = &nve0_args;
387          size = sizeof(nve0_args);
388       }
389
390       /* kepler must have its own channel, so just do this for everyone */
391       nouveau_object_new(&screen->device->object, 0,
392                          NOUVEAU_FIFO_CHANNEL_CLASS,
393                          data, size, &channel);
394
395       if (channel) {
396          nouveau_object_new(channel, 0, oclass, NULL, 0, &bsp);
397          if (bsp)
398             screen->firmware_info.profiles_present |= 1;
399          nouveau_object_del(&bsp);
400          nouveau_object_del(&channel);
401       }
402       screen->firmware_info.profiles_checked |= 1;
403    }
404
405    if (!(screen->firmware_info.profiles_present & 1))
406       return 0;
407
408    /* For vp3/vp4 chipsets, make sure that the relevant firmware is present */
409    if (!vp5 && !(screen->firmware_info.profiles_checked & (1 << profile))) {
410       char path[PATH_MAX];
411       struct stat s;
412       if (vp3)
413          vp3_getpath(profile, path);
414       else
415          vp4_getpath(profile, path);
416       ret = stat(path, &s);
417       if (!ret && s.st_size > 1000)
418          screen->firmware_info.profiles_present |= (1 << profile);
419       screen->firmware_info.profiles_checked |= (1 << profile);
420    }
421
422    return vp5 || (screen->firmware_info.profiles_present & (1 << profile));
423 }
424
425 int
426 nouveau_vp3_screen_get_video_param(struct pipe_screen *pscreen,
427                                    enum pipe_video_profile profile,
428                                    enum pipe_video_entrypoint entrypoint,
429                                    enum pipe_video_cap param)
430 {
431    int chipset = nouveau_screen(pscreen)->device->chipset;
432    int vp3 = chipset < 0xa3 || chipset == 0xaa || chipset == 0xac;
433    int vp5 = chipset >= 0xd0;
434    enum pipe_video_format codec = u_reduce_video_profile(profile);
435    switch (param) {
436    case PIPE_VIDEO_CAP_SUPPORTED:
437       /* VP3 does not support MPEG4, VP4+ do. */
438       return entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM &&
439          profile >= PIPE_VIDEO_PROFILE_MPEG1 &&
440          profile < PIPE_VIDEO_PROFILE_HEVC_MAIN &&
441          (!vp3 || codec != PIPE_VIDEO_FORMAT_MPEG4) &&
442          firmware_present(pscreen, profile);
443    case PIPE_VIDEO_CAP_NPOT_TEXTURES:
444       return 1;
445    case PIPE_VIDEO_CAP_MAX_WIDTH:
446    case PIPE_VIDEO_CAP_MAX_HEIGHT:
447       return vp5 ? 4096 : 2048;
448    case PIPE_VIDEO_CAP_PREFERED_FORMAT:
449       return PIPE_FORMAT_NV12;
450    case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED:
451    case PIPE_VIDEO_CAP_PREFERS_INTERLACED:
452       return true;
453    case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE:
454       return false;
455    case PIPE_VIDEO_CAP_MAX_LEVEL:
456       switch (profile) {
457       case PIPE_VIDEO_PROFILE_MPEG1:
458          return 0;
459       case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE:
460       case PIPE_VIDEO_PROFILE_MPEG2_MAIN:
461          return 3;
462       case PIPE_VIDEO_PROFILE_MPEG4_SIMPLE:
463          return 3;
464       case PIPE_VIDEO_PROFILE_MPEG4_ADVANCED_SIMPLE:
465          return 5;
466       case PIPE_VIDEO_PROFILE_VC1_SIMPLE:
467          return 1;
468       case PIPE_VIDEO_PROFILE_VC1_MAIN:
469          return 2;
470       case PIPE_VIDEO_PROFILE_VC1_ADVANCED:
471          return 4;
472       case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE:
473       case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN:
474       case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH:
475          return 41;
476       default:
477          debug_printf("unknown video profile: %d\n", profile);
478          return 0;
479       }
480    default:
481       debug_printf("unknown video param: %d\n", param);
482       return 0;
483    }
484 }
485
486 boolean
487 nouveau_vp3_screen_video_supported(struct pipe_screen *screen,
488                                    enum pipe_format format,
489                                    enum pipe_video_profile profile,
490                                    enum pipe_video_entrypoint entrypoint)
491 {
492    if (profile != PIPE_VIDEO_PROFILE_UNKNOWN)
493       return format == PIPE_FORMAT_NV12;
494
495    return vl_video_buffer_is_format_supported(screen, format, profile, entrypoint);
496 }