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