• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2013 Ilia Mirkin
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 <sys/types.h>
26 #include <fcntl.h>
27 
28 #include "util/u_format.h"
29 #include "util/u_sampler.h"
30 #include "vl/vl_zscan.h"
31 
32 #include "nv50/nv84_video.h"
33 
34 static int
nv84_copy_firmware(const char * path,void * dest,ssize_t len)35 nv84_copy_firmware(const char *path, void *dest, ssize_t len)
36 {
37    int fd = open(path, O_RDONLY | O_CLOEXEC);
38    ssize_t r;
39    if (fd < 0) {
40       fprintf(stderr, "opening firmware file %s failed: %m\n", path);
41       return 1;
42    }
43    r = read(fd, dest, len);
44    close(fd);
45 
46    if (r != len) {
47       fprintf(stderr, "reading firwmare file %s failed: %m\n", path);
48       return 1;
49    }
50 
51    return 0;
52 }
53 
54 static int
filesize(const char * path)55 filesize(const char *path)
56 {
57    int ret;
58    struct stat statbuf;
59 
60    ret = stat(path, &statbuf);
61    if (ret)
62       return ret;
63    return statbuf.st_size;
64 }
65 
66 static struct nouveau_bo *
nv84_load_firmwares(struct nouveau_device * dev,struct nv84_decoder * dec,const char * fw1,const char * fw2)67 nv84_load_firmwares(struct nouveau_device *dev, struct nv84_decoder *dec,
68                     const char *fw1, const char *fw2)
69 {
70    int ret, size1, size2 = 0;
71    struct nouveau_bo *fw;
72 
73    size1 = filesize(fw1);
74    if (fw2)
75       size2 = filesize(fw2);
76    if (size1 < 0 || size2 < 0)
77       return NULL;
78 
79    dec->vp_fw2_offset = align(size1, 0x100);
80 
81    ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, dec->vp_fw2_offset + size2, NULL, &fw);
82    if (ret)
83       return NULL;
84    ret = nouveau_bo_map(fw, NOUVEAU_BO_WR, dec->client);
85    if (ret)
86       goto error;
87 
88    ret = nv84_copy_firmware(fw1, fw->map, size1);
89    if (fw2 && !ret)
90       ret = nv84_copy_firmware(fw2, fw->map + dec->vp_fw2_offset, size2);
91    munmap(fw->map, fw->size);
92    fw->map = NULL;
93    if (!ret)
94       return fw;
95 error:
96    nouveau_bo_ref(NULL, &fw);
97    return NULL;
98 }
99 
100 static struct nouveau_bo *
nv84_load_bsp_firmware(struct nouveau_device * dev,struct nv84_decoder * dec)101 nv84_load_bsp_firmware(struct nouveau_device *dev, struct nv84_decoder *dec)
102 {
103    return nv84_load_firmwares(
104          dev, dec, "/lib/firmware/nouveau/nv84_bsp-h264", NULL);
105 }
106 
107 static struct nouveau_bo *
nv84_load_vp_firmware(struct nouveau_device * dev,struct nv84_decoder * dec)108 nv84_load_vp_firmware(struct nouveau_device *dev, struct nv84_decoder *dec)
109 {
110    return nv84_load_firmwares(
111          dev, dec,
112          "/lib/firmware/nouveau/nv84_vp-h264-1",
113          "/lib/firmware/nouveau/nv84_vp-h264-2");
114 }
115 
116 static struct nouveau_bo *
nv84_load_vp_firmware_mpeg(struct nouveau_device * dev,struct nv84_decoder * dec)117 nv84_load_vp_firmware_mpeg(struct nouveau_device *dev, struct nv84_decoder *dec)
118 {
119    return nv84_load_firmwares(
120          dev, dec, "/lib/firmware/nouveau/nv84_vp-mpeg12", NULL);
121 }
122 
123 static void
nv84_decoder_decode_bitstream_h264(struct pipe_video_codec * decoder,struct pipe_video_buffer * video_target,struct pipe_picture_desc * picture,unsigned num_buffers,const void * const * data,const unsigned * num_bytes)124 nv84_decoder_decode_bitstream_h264(struct pipe_video_codec *decoder,
125                                    struct pipe_video_buffer *video_target,
126                                    struct pipe_picture_desc *picture,
127                                    unsigned num_buffers,
128                                    const void *const *data,
129                                    const unsigned *num_bytes)
130 {
131    struct nv84_decoder *dec = (struct nv84_decoder *)decoder;
132    struct nv84_video_buffer *target = (struct nv84_video_buffer *)video_target;
133 
134    struct pipe_h264_picture_desc *desc = (struct pipe_h264_picture_desc *)picture;
135 
136    assert(target->base.buffer_format == PIPE_FORMAT_NV12);
137 
138    nv84_decoder_bsp(dec, desc, num_buffers, data, num_bytes, target);
139    nv84_decoder_vp_h264(dec, desc, target);
140 }
141 
142 static void
nv84_decoder_flush(struct pipe_video_codec * decoder)143 nv84_decoder_flush(struct pipe_video_codec *decoder)
144 {
145 }
146 
147 static void
nv84_decoder_begin_frame_h264(struct pipe_video_codec * decoder,struct pipe_video_buffer * target,struct pipe_picture_desc * picture)148 nv84_decoder_begin_frame_h264(struct pipe_video_codec *decoder,
149                               struct pipe_video_buffer *target,
150                               struct pipe_picture_desc *picture)
151 {
152 }
153 
154 static void
nv84_decoder_end_frame_h264(struct pipe_video_codec * decoder,struct pipe_video_buffer * target,struct pipe_picture_desc * picture)155 nv84_decoder_end_frame_h264(struct pipe_video_codec *decoder,
156                             struct pipe_video_buffer *target,
157                             struct pipe_picture_desc *picture)
158 {
159 }
160 
161 static void
nv84_decoder_decode_bitstream_mpeg12(struct pipe_video_codec * decoder,struct pipe_video_buffer * video_target,struct pipe_picture_desc * picture,unsigned num_buffers,const void * const * data,const unsigned * num_bytes)162 nv84_decoder_decode_bitstream_mpeg12(struct pipe_video_codec *decoder,
163                                      struct pipe_video_buffer *video_target,
164                                      struct pipe_picture_desc *picture,
165                                      unsigned num_buffers,
166                                      const void *const *data,
167                                      const unsigned *num_bytes)
168 {
169    struct nv84_decoder *dec = (struct nv84_decoder *)decoder;
170 
171    assert(video_target->buffer_format == PIPE_FORMAT_NV12);
172 
173    vl_mpg12_bs_decode(dec->mpeg12_bs,
174                       video_target,
175                       (struct pipe_mpeg12_picture_desc *)picture,
176                       num_buffers,
177                       data,
178                       num_bytes);
179 }
180 
181 static void
nv84_decoder_begin_frame_mpeg12(struct pipe_video_codec * decoder,struct pipe_video_buffer * target,struct pipe_picture_desc * picture)182 nv84_decoder_begin_frame_mpeg12(struct pipe_video_codec *decoder,
183                               struct pipe_video_buffer *target,
184                               struct pipe_picture_desc *picture)
185 {
186    struct nv84_decoder *dec = (struct nv84_decoder *)decoder;
187    struct pipe_mpeg12_picture_desc *desc = (struct pipe_mpeg12_picture_desc *)picture;
188    int i;
189 
190    nouveau_bo_wait(dec->mpeg12_bo, NOUVEAU_BO_RDWR, dec->client);
191    dec->mpeg12_mb_info = dec->mpeg12_bo->map + 0x100;
192    dec->mpeg12_data = dec->mpeg12_bo->map + 0x100 +
193       align(0x20 * mb(dec->base.width) * mb(dec->base.height), 0x100);
194    if (desc->intra_matrix) {
195       dec->zscan = desc->alternate_scan ? vl_zscan_alternate : vl_zscan_normal;
196       for (i = 0; i < 64; i++) {
197          dec->mpeg12_intra_matrix[i] = desc->intra_matrix[dec->zscan[i]];
198          dec->mpeg12_non_intra_matrix[i] = desc->non_intra_matrix[dec->zscan[i]];
199       }
200       dec->mpeg12_intra_matrix[0] = 1 << (7 - desc->intra_dc_precision);
201    }
202 }
203 
204 static void
nv84_decoder_end_frame_mpeg12(struct pipe_video_codec * decoder,struct pipe_video_buffer * target,struct pipe_picture_desc * picture)205 nv84_decoder_end_frame_mpeg12(struct pipe_video_codec *decoder,
206                               struct pipe_video_buffer *target,
207                               struct pipe_picture_desc *picture)
208 {
209    nv84_decoder_vp_mpeg12(
210          (struct nv84_decoder *)decoder,
211          (struct pipe_mpeg12_picture_desc *)picture,
212          (struct nv84_video_buffer *)target);
213 }
214 
215 static void
nv84_decoder_decode_macroblock(struct pipe_video_codec * decoder,struct pipe_video_buffer * target,struct pipe_picture_desc * picture,const struct pipe_macroblock * macroblocks,unsigned num_macroblocks)216 nv84_decoder_decode_macroblock(struct pipe_video_codec *decoder,
217                                struct pipe_video_buffer *target,
218                                struct pipe_picture_desc *picture,
219                                const struct pipe_macroblock *macroblocks,
220                                unsigned num_macroblocks)
221 {
222    const struct pipe_mpeg12_macroblock *mb = (const struct pipe_mpeg12_macroblock *)macroblocks;
223    for (int i = 0; i < num_macroblocks; i++, mb++) {
224       nv84_decoder_vp_mpeg12_mb(
225             (struct nv84_decoder *)decoder,
226             (struct pipe_mpeg12_picture_desc *)picture,
227             mb);
228    }
229 }
230 
231 static void
nv84_decoder_destroy(struct pipe_video_codec * decoder)232 nv84_decoder_destroy(struct pipe_video_codec *decoder)
233 {
234    struct nv84_decoder *dec = (struct nv84_decoder *)decoder;
235 
236    nouveau_bo_ref(NULL, &dec->bsp_fw);
237    nouveau_bo_ref(NULL, &dec->bsp_data);
238    nouveau_bo_ref(NULL, &dec->vp_fw);
239    nouveau_bo_ref(NULL, &dec->vp_data);
240    nouveau_bo_ref(NULL, &dec->mbring);
241    nouveau_bo_ref(NULL, &dec->vpring);
242    nouveau_bo_ref(NULL, &dec->bitstream);
243    nouveau_bo_ref(NULL, &dec->vp_params);
244    nouveau_bo_ref(NULL, &dec->fence);
245 
246    nouveau_object_del(&dec->bsp);
247    nouveau_object_del(&dec->vp);
248 
249    nouveau_bufctx_del(&dec->bsp_bufctx);
250    nouveau_pushbuf_del(&dec->bsp_pushbuf);
251    nouveau_object_del(&dec->bsp_channel);
252 
253    nouveau_bufctx_del(&dec->vp_bufctx);
254    nouveau_pushbuf_del(&dec->vp_pushbuf);
255    nouveau_object_del(&dec->vp_channel);
256 
257    nouveau_client_del(&dec->client);
258 
259    FREE(dec->mpeg12_bs);
260    FREE(dec);
261 }
262 
263 struct pipe_video_codec *
nv84_create_decoder(struct pipe_context * context,const struct pipe_video_codec * templ)264 nv84_create_decoder(struct pipe_context *context,
265                     const struct pipe_video_codec *templ)
266 {
267    struct nv50_context *nv50 = (struct nv50_context *)context;
268    struct nouveau_screen *screen = &nv50->screen->base;
269    struct nv84_decoder *dec;
270    struct nouveau_pushbuf *bsp_push, *vp_push;
271    struct nv50_surface surf;
272    struct nv50_miptree mip;
273    union pipe_color_union color;
274    struct nv04_fifo nv04_data = { .vram = 0xbeef0201, .gart = 0xbeef0202 };
275    int ret, i;
276    int is_h264 = u_reduce_video_profile(templ->profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC;
277    int is_mpeg12 = u_reduce_video_profile(templ->profile) == PIPE_VIDEO_FORMAT_MPEG12;
278 
279    if (getenv("XVMC_VL"))
280       return vl_create_decoder(context, templ);
281 
282    if ((is_h264 && templ->entrypoint != PIPE_VIDEO_ENTRYPOINT_BITSTREAM) ||
283        (is_mpeg12 && templ->entrypoint > PIPE_VIDEO_ENTRYPOINT_IDCT)) {
284       debug_printf("%x\n", templ->entrypoint);
285       return NULL;
286    }
287 
288    if (!is_h264 && !is_mpeg12) {
289       debug_printf("invalid profile: %x\n", templ->profile);
290       return NULL;
291    }
292 
293    dec = CALLOC_STRUCT(nv84_decoder);
294    if (!dec)
295       return NULL;
296 
297    dec->base = *templ;
298    dec->base.context = context;
299    dec->base.destroy = nv84_decoder_destroy;
300    dec->base.flush = nv84_decoder_flush;
301    if (is_h264) {
302       dec->base.decode_bitstream = nv84_decoder_decode_bitstream_h264;
303       dec->base.begin_frame = nv84_decoder_begin_frame_h264;
304       dec->base.end_frame = nv84_decoder_end_frame_h264;
305 
306       dec->frame_mbs = mb(dec->base.width) * mb_half(dec->base.height) * 2;
307       dec->frame_size = dec->frame_mbs << 8;
308       dec->vpring_deblock = align(0x30 * dec->frame_mbs, 0x100);
309       dec->vpring_residual = 0x2000 + MAX2(0x32000, 0x600 * dec->frame_mbs);
310       dec->vpring_ctrl = MAX2(0x10000, align(0x1080 + 0x144 * dec->frame_mbs, 0x100));
311    } else if (is_mpeg12) {
312       dec->base.decode_macroblock = nv84_decoder_decode_macroblock;
313       dec->base.begin_frame = nv84_decoder_begin_frame_mpeg12;
314       dec->base.end_frame = nv84_decoder_end_frame_mpeg12;
315 
316       if (templ->entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM) {
317          dec->mpeg12_bs = CALLOC_STRUCT(vl_mpg12_bs);
318          if (!dec->mpeg12_bs)
319             goto fail;
320          vl_mpg12_bs_init(dec->mpeg12_bs, &dec->base);
321          dec->base.decode_bitstream = nv84_decoder_decode_bitstream_mpeg12;
322       }
323    } else {
324       goto fail;
325    }
326 
327    ret = nouveau_client_new(screen->device, &dec->client);
328    if (ret)
329       goto fail;
330 
331    if (is_h264) {
332       ret = nouveau_object_new(&screen->device->object, 0,
333                                NOUVEAU_FIFO_CHANNEL_CLASS,
334                                &nv04_data, sizeof(nv04_data), &dec->bsp_channel);
335       if (ret)
336          goto fail;
337 
338       ret = nouveau_pushbuf_new(dec->client, dec->bsp_channel, 4,
339                                 32 * 1024, true, &dec->bsp_pushbuf);
340       if (ret)
341          goto fail;
342 
343       ret = nouveau_bufctx_new(dec->client, 1, &dec->bsp_bufctx);
344       if (ret)
345          goto fail;
346    }
347 
348    ret = nouveau_object_new(&screen->device->object, 0,
349                             NOUVEAU_FIFO_CHANNEL_CLASS,
350                             &nv04_data, sizeof(nv04_data), &dec->vp_channel);
351    if (ret)
352       goto fail;
353    ret = nouveau_pushbuf_new(dec->client, dec->vp_channel, 4,
354                              32 * 1024, true, &dec->vp_pushbuf);
355    if (ret)
356       goto fail;
357 
358    ret = nouveau_bufctx_new(dec->client, 1, &dec->vp_bufctx);
359    if (ret)
360       goto fail;
361 
362    bsp_push = dec->bsp_pushbuf;
363    vp_push = dec->vp_pushbuf;
364 
365    if (is_h264) {
366       dec->bsp_fw = nv84_load_bsp_firmware(screen->device, dec);
367       dec->vp_fw = nv84_load_vp_firmware(screen->device, dec);
368       if (!dec->bsp_fw || !dec->vp_fw)
369          goto fail;
370    }
371    if (is_mpeg12) {
372       dec->vp_fw = nv84_load_vp_firmware_mpeg(screen->device, dec);
373       if (!dec->vp_fw)
374          goto fail;
375    }
376 
377    if (is_h264) {
378       ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM | NOUVEAU_BO_NOSNOOP,
379                            0, 0x40000, NULL, &dec->bsp_data);
380       if (ret)
381          goto fail;
382    }
383    ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM | NOUVEAU_BO_NOSNOOP,
384                         0, 0x40000, NULL, &dec->vp_data);
385    if (ret)
386       goto fail;
387    if (is_h264) {
388       ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM | NOUVEAU_BO_NOSNOOP,
389                            0,
390                            2 * (dec->vpring_deblock +
391                                 dec->vpring_residual +
392                                 dec->vpring_ctrl +
393                                 0x1000),
394                            NULL, &dec->vpring);
395       if (ret)
396          goto fail;
397       ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM | NOUVEAU_BO_NOSNOOP,
398                            0,
399                            (templ->max_references + 1) * dec->frame_mbs * 0x40 +
400                            dec->frame_size + 0x2000,
401                            NULL, &dec->mbring);
402       if (ret)
403          goto fail;
404       ret = nouveau_bo_new(screen->device, NOUVEAU_BO_GART,
405                            0, 2 * (0x700 + MAX2(0x40000, 0x800 + 0x180 * dec->frame_mbs)),
406                            NULL, &dec->bitstream);
407       if (ret)
408          goto fail;
409       ret = nouveau_bo_map(dec->bitstream, NOUVEAU_BO_WR, dec->client);
410       if (ret)
411          goto fail;
412       ret = nouveau_bo_new(screen->device, NOUVEAU_BO_GART,
413                            0, 0x2000, NULL, &dec->vp_params);
414       if (ret)
415          goto fail;
416       ret = nouveau_bo_map(dec->vp_params, NOUVEAU_BO_WR, dec->client);
417       if (ret)
418          goto fail;
419    }
420    if (is_mpeg12) {
421       ret = nouveau_bo_new(screen->device, NOUVEAU_BO_GART,
422                            0,
423                            align(0x20 * mb(templ->width) * mb(templ->height), 0x100) +
424                            (6 * 64 * 8) * mb(templ->width) * mb(templ->height) + 0x100,
425                            NULL, &dec->mpeg12_bo);
426       if (ret)
427          goto fail;
428       ret = nouveau_bo_map(dec->mpeg12_bo, NOUVEAU_BO_WR, dec->client);
429       if (ret)
430          goto fail;
431    }
432 
433    ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM,
434                         0, 0x1000, NULL, &dec->fence);
435    if (ret)
436       goto fail;
437    ret = nouveau_bo_map(dec->fence, NOUVEAU_BO_WR, dec->client);
438    if (ret)
439       goto fail;
440    *(uint32_t *)dec->fence->map = 0;
441 
442    if (is_h264) {
443       nouveau_pushbuf_bufctx(bsp_push, dec->bsp_bufctx);
444       nouveau_bufctx_refn(dec->bsp_bufctx, 0,
445                           dec->bsp_fw, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
446       nouveau_bufctx_refn(dec->bsp_bufctx, 0,
447                           dec->bsp_data, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
448    }
449 
450    nouveau_pushbuf_bufctx(vp_push, dec->vp_bufctx);
451    nouveau_bufctx_refn(dec->vp_bufctx, 0, dec->vp_fw,
452                        NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
453    nouveau_bufctx_refn(dec->vp_bufctx, 0, dec->vp_data,
454                        NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
455 
456    if (is_h264 && !ret)
457       ret = nouveau_object_new(dec->bsp_channel, 0xbeef74b0, 0x74b0,
458                                NULL, 0, &dec->bsp);
459 
460    if (!ret)
461       ret = nouveau_object_new(dec->vp_channel, 0xbeef7476, 0x7476,
462                                NULL, 0, &dec->vp);
463 
464    if (ret)
465       goto fail;
466 
467 
468    if (is_h264) {
469       /* Zero out some parts of mbring/vpring. there's gotta be some cleaner way
470        * of doing this... perhaps makes sense to just copy the relevant logic
471        * here. */
472       color.f[0] = color.f[1] = color.f[2] = color.f[3] = 0;
473       surf.offset = dec->frame_size;
474       surf.width = 64;
475       surf.height = (templ->max_references + 1) * dec->frame_mbs / 4;
476       surf.depth = 1;
477       surf.base.format = PIPE_FORMAT_B8G8R8A8_UNORM;
478       surf.base.u.tex.level = 0;
479       surf.base.texture = &mip.base.base;
480       mip.level[0].tile_mode = 0;
481       mip.level[0].pitch = surf.width * 4;
482       mip.base.domain = NOUVEAU_BO_VRAM;
483       mip.base.bo = dec->mbring;
484       mip.base.address = dec->mbring->offset;
485       context->clear_render_target(context, &surf.base, &color, 0, 0, 64, 4760, false);
486       surf.offset = dec->vpring->size / 2 - 0x1000;
487       surf.width = 1024;
488       surf.height = 1;
489       mip.level[0].pitch = surf.width * 4;
490       mip.base.bo = dec->vpring;
491       mip.base.address = dec->vpring->offset;
492       context->clear_render_target(context, &surf.base, &color, 0, 0, 1024, 1, false);
493       surf.offset = dec->vpring->size - 0x1000;
494       context->clear_render_target(context, &surf.base, &color, 0, 0, 1024, 1, false);
495 
496       PUSH_SPACE(screen->pushbuf, 5);
497       PUSH_REFN(screen->pushbuf, dec->fence, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
498       /* The clear_render_target is done via 3D engine, so use it to write to a
499        * sempahore to indicate that it's done.
500        */
501       BEGIN_NV04(screen->pushbuf, NV50_3D(QUERY_ADDRESS_HIGH), 4);
502       PUSH_DATAh(screen->pushbuf, dec->fence->offset);
503       PUSH_DATA (screen->pushbuf, dec->fence->offset);
504       PUSH_DATA (screen->pushbuf, 1);
505       PUSH_DATA (screen->pushbuf, 0xf010);
506       PUSH_KICK (screen->pushbuf);
507 
508       PUSH_SPACE(bsp_push, 2 + 12 + 2 + 4 + 3);
509 
510       BEGIN_NV04(bsp_push, SUBC_BSP(NV01_SUBCHAN_OBJECT), 1);
511       PUSH_DATA (bsp_push, dec->bsp->handle);
512 
513       BEGIN_NV04(bsp_push, SUBC_BSP(0x180), 11);
514       for (i = 0; i < 11; i++)
515          PUSH_DATA(bsp_push, nv04_data.vram);
516       BEGIN_NV04(bsp_push, SUBC_BSP(0x1b8), 1);
517       PUSH_DATA (bsp_push, nv04_data.vram);
518 
519       BEGIN_NV04(bsp_push, SUBC_BSP(0x600), 3);
520       PUSH_DATAh(bsp_push, dec->bsp_fw->offset);
521       PUSH_DATA (bsp_push, dec->bsp_fw->offset);
522       PUSH_DATA (bsp_push, dec->bsp_fw->size);
523 
524       BEGIN_NV04(bsp_push, SUBC_BSP(0x628), 2);
525       PUSH_DATA (bsp_push, dec->bsp_data->offset >> 8);
526       PUSH_DATA (bsp_push, dec->bsp_data->size);
527       PUSH_KICK (bsp_push);
528    }
529 
530    PUSH_SPACE(vp_push, 2 + 12 + 2 + 4 + 3);
531 
532    BEGIN_NV04(vp_push, SUBC_VP(NV01_SUBCHAN_OBJECT), 1);
533    PUSH_DATA (vp_push, dec->vp->handle);
534 
535    BEGIN_NV04(vp_push, SUBC_VP(0x180), 11);
536    for (i = 0; i < 11; i++)
537       PUSH_DATA(vp_push, nv04_data.vram);
538 
539    BEGIN_NV04(vp_push, SUBC_VP(0x1b8), 1);
540    PUSH_DATA (vp_push, nv04_data.vram);
541 
542    BEGIN_NV04(vp_push, SUBC_VP(0x600), 3);
543    PUSH_DATAh(vp_push, dec->vp_fw->offset);
544    PUSH_DATA (vp_push, dec->vp_fw->offset);
545    PUSH_DATA (vp_push, dec->vp_fw->size);
546 
547    BEGIN_NV04(vp_push, SUBC_VP(0x628), 2);
548    PUSH_DATA (vp_push, dec->vp_data->offset >> 8);
549    PUSH_DATA (vp_push, dec->vp_data->size);
550    PUSH_KICK (vp_push);
551 
552    return &dec->base;
553 fail:
554    nv84_decoder_destroy(&dec->base);
555    return NULL;
556 }
557 
558 static struct pipe_sampler_view **
nv84_video_buffer_sampler_view_planes(struct pipe_video_buffer * buffer)559 nv84_video_buffer_sampler_view_planes(struct pipe_video_buffer *buffer)
560 {
561    struct nv84_video_buffer *buf = (struct nv84_video_buffer *)buffer;
562    return buf->sampler_view_planes;
563 }
564 
565 static struct pipe_sampler_view **
nv84_video_buffer_sampler_view_components(struct pipe_video_buffer * buffer)566 nv84_video_buffer_sampler_view_components(struct pipe_video_buffer *buffer)
567 {
568    struct nv84_video_buffer *buf = (struct nv84_video_buffer *)buffer;
569    return buf->sampler_view_components;
570 }
571 
572 static struct pipe_surface **
nv84_video_buffer_surfaces(struct pipe_video_buffer * buffer)573 nv84_video_buffer_surfaces(struct pipe_video_buffer *buffer)
574 {
575    struct nv84_video_buffer *buf = (struct nv84_video_buffer *)buffer;
576    return buf->surfaces;
577 }
578 
579 static void
nv84_video_buffer_destroy(struct pipe_video_buffer * buffer)580 nv84_video_buffer_destroy(struct pipe_video_buffer *buffer)
581 {
582    struct nv84_video_buffer *buf = (struct nv84_video_buffer *)buffer;
583    unsigned i;
584 
585    assert(buf);
586 
587    for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
588       pipe_resource_reference(&buf->resources[i], NULL);
589       pipe_sampler_view_reference(&buf->sampler_view_planes[i], NULL);
590       pipe_sampler_view_reference(&buf->sampler_view_components[i], NULL);
591       pipe_surface_reference(&buf->surfaces[i * 2], NULL);
592       pipe_surface_reference(&buf->surfaces[i * 2 + 1], NULL);
593    }
594 
595    nouveau_bo_ref(NULL, &buf->interlaced);
596    nouveau_bo_ref(NULL, &buf->full);
597 
598    FREE(buffer);
599 }
600 
601 struct pipe_video_buffer *
nv84_video_buffer_create(struct pipe_context * pipe,const struct pipe_video_buffer * template)602 nv84_video_buffer_create(struct pipe_context *pipe,
603                          const struct pipe_video_buffer *template)
604 {
605    struct nv84_video_buffer *buffer;
606    struct pipe_resource templ;
607    unsigned i, j, component;
608    struct pipe_sampler_view sv_templ;
609    struct pipe_surface surf_templ;
610    struct nv50_miptree *mt0, *mt1;
611    struct nouveau_screen *screen = &((struct nv50_context *)pipe)->screen->base;
612    union nouveau_bo_config cfg;
613    unsigned bo_size;
614 
615    if (getenv("XVMC_VL") || template->buffer_format != PIPE_FORMAT_NV12)
616       return vl_video_buffer_create(pipe, template);
617 
618    if (!template->interlaced) {
619       debug_printf("Require interlaced video buffers\n");
620       return NULL;
621    }
622    if (template->chroma_format != PIPE_VIDEO_CHROMA_FORMAT_420) {
623       debug_printf("Must use 4:2:0 format\n");
624       return NULL;
625    }
626 
627    /*
628     * Note that there are always going to be exactly two planes, one for Y,
629     * and one for UV. These are also the resources. VP expects these to be
630     * adjacent, so they need to belong to the same BO.
631     */
632 
633    buffer = CALLOC_STRUCT(nv84_video_buffer);
634    if (!buffer) return NULL;
635 
636    buffer->mvidx = -1;
637 
638    buffer->base.buffer_format = template->buffer_format;
639    buffer->base.context = pipe;
640    buffer->base.destroy = nv84_video_buffer_destroy;
641    buffer->base.chroma_format = template->chroma_format;
642    buffer->base.width = template->width;
643    buffer->base.height = template->height;
644    buffer->base.get_sampler_view_planes = nv84_video_buffer_sampler_view_planes;
645    buffer->base.get_sampler_view_components = nv84_video_buffer_sampler_view_components;
646    buffer->base.get_surfaces = nv84_video_buffer_surfaces;
647    buffer->base.interlaced = true;
648 
649    memset(&templ, 0, sizeof(templ));
650    templ.target = PIPE_TEXTURE_2D_ARRAY;
651    templ.depth0 = 1;
652    templ.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
653    templ.format = PIPE_FORMAT_R8_UNORM;
654    templ.width0 = align(template->width, 2);
655    templ.height0 = align(template->height, 4) / 2;
656    templ.flags = NV50_RESOURCE_FLAG_VIDEO | NV50_RESOURCE_FLAG_NOALLOC;
657    templ.array_size = 2;
658 
659    cfg.nv50.tile_mode = 0x20;
660    cfg.nv50.memtype = 0x70;
661 
662    buffer->resources[0] = pipe->screen->resource_create(pipe->screen, &templ);
663    if (!buffer->resources[0])
664       goto error;
665 
666    templ.format = PIPE_FORMAT_R8G8_UNORM;
667    templ.width0 /= 2;
668    templ.height0 /= 2;
669    buffer->resources[1] = pipe->screen->resource_create(pipe->screen, &templ);
670    if (!buffer->resources[1])
671       goto error;
672 
673    mt0 = nv50_miptree(buffer->resources[0]);
674    mt1 = nv50_miptree(buffer->resources[1]);
675 
676    bo_size = mt0->total_size + mt1->total_size;
677    if (nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM | NOUVEAU_BO_NOSNOOP, 0,
678                       bo_size, &cfg, &buffer->interlaced))
679       goto error;
680    /* XXX Change reference frame management so that this is only allocated in
681     * the decoder when necessary. */
682    if (nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM | NOUVEAU_BO_NOSNOOP, 0,
683                       bo_size, &cfg, &buffer->full))
684       goto error;
685 
686    nouveau_bo_ref(buffer->interlaced, &mt0->base.bo);
687    mt0->base.domain = NOUVEAU_BO_VRAM;
688    mt0->base.address = buffer->interlaced->offset;
689 
690    nouveau_bo_ref(buffer->interlaced, &mt1->base.bo);
691    mt1->base.domain = NOUVEAU_BO_VRAM;
692    mt1->base.offset = mt0->total_size;
693    mt1->base.address = buffer->interlaced->offset + mt0->total_size;
694 
695    memset(&sv_templ, 0, sizeof(sv_templ));
696    for (component = 0, i = 0; i < 2; ++i ) {
697       struct pipe_resource *res = buffer->resources[i];
698       unsigned nr_components = util_format_get_nr_components(res->format);
699 
700       u_sampler_view_default_template(&sv_templ, res, res->format);
701       buffer->sampler_view_planes[i] =
702          pipe->create_sampler_view(pipe, res, &sv_templ);
703       if (!buffer->sampler_view_planes[i])
704          goto error;
705 
706       for (j = 0; j < nr_components; ++j, ++component) {
707          sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b =
708             PIPE_SWIZZLE_X + j;
709          sv_templ.swizzle_a = PIPE_SWIZZLE_1;
710 
711          buffer->sampler_view_components[component] =
712             pipe->create_sampler_view(pipe, res, &sv_templ);
713          if (!buffer->sampler_view_components[component])
714             goto error;
715       }
716    }
717 
718    memset(&surf_templ, 0, sizeof(surf_templ));
719    for (j = 0; j < 2; ++j) {
720       surf_templ.format = buffer->resources[j]->format;
721       surf_templ.u.tex.first_layer = surf_templ.u.tex.last_layer = 0;
722       buffer->surfaces[j * 2] =
723          pipe->create_surface(pipe, buffer->resources[j], &surf_templ);
724       if (!buffer->surfaces[j * 2])
725          goto error;
726 
727       surf_templ.u.tex.first_layer = surf_templ.u.tex.last_layer = 1;
728       buffer->surfaces[j * 2 + 1] =
729          pipe->create_surface(pipe, buffer->resources[j], &surf_templ);
730       if (!buffer->surfaces[j * 2 + 1])
731          goto error;
732    }
733 
734    return &buffer->base;
735 
736 error:
737    nv84_video_buffer_destroy(&buffer->base);
738    return NULL;
739 }
740 
741 #define FIRMWARE_BSP_KERN  0x01
742 #define FIRMWARE_VP_KERN   0x02
743 #define FIRMWARE_BSP_H264  0x04
744 #define FIRMWARE_VP_MPEG2  0x08
745 #define FIRMWARE_VP_H264_1 0x10
746 #define FIRMWARE_VP_H264_2 0x20
747 #define FIRMWARE_PRESENT(val, fw) (val & FIRMWARE_ ## fw)
748 
749 static int
firmware_present(struct pipe_screen * pscreen,enum pipe_video_format codec)750 firmware_present(struct pipe_screen *pscreen, enum pipe_video_format codec)
751 {
752    struct nouveau_screen *screen = nouveau_screen(pscreen);
753    struct nouveau_object *obj = NULL;
754    struct stat s;
755    int checked = screen->firmware_info.profiles_checked;
756    int present, ret;
757 
758    if (!FIRMWARE_PRESENT(checked, VP_KERN)) {
759       ret = nouveau_object_new(screen->channel, 0, 0x7476, NULL, 0, &obj);
760       if (!ret)
761          screen->firmware_info.profiles_present |= FIRMWARE_VP_KERN;
762       nouveau_object_del(&obj);
763       screen->firmware_info.profiles_checked |= FIRMWARE_VP_KERN;
764    }
765 
766    if (codec == PIPE_VIDEO_FORMAT_MPEG4_AVC) {
767       if (!FIRMWARE_PRESENT(checked, BSP_KERN)) {
768          ret = nouveau_object_new(screen->channel, 0, 0x74b0, NULL, 0, &obj);
769          if (!ret)
770             screen->firmware_info.profiles_present |= FIRMWARE_BSP_KERN;
771          nouveau_object_del(&obj);
772          screen->firmware_info.profiles_checked |= FIRMWARE_BSP_KERN;
773       }
774 
775       if (!FIRMWARE_PRESENT(checked, VP_H264_1)) {
776          ret = stat("/lib/firmware/nouveau/nv84_vp-h264-1", &s);
777          if (!ret && s.st_size > 1000)
778             screen->firmware_info.profiles_present |= FIRMWARE_VP_H264_1;
779          screen->firmware_info.profiles_checked |= FIRMWARE_VP_H264_1;
780       }
781 
782       /* should probably check the others, but assume that 1 means all */
783 
784       present = screen->firmware_info.profiles_present;
785       return FIRMWARE_PRESENT(present, VP_KERN) &&
786          FIRMWARE_PRESENT(present, BSP_KERN) &&
787          FIRMWARE_PRESENT(present, VP_H264_1);
788    } else {
789       if (!FIRMWARE_PRESENT(checked, VP_MPEG2)) {
790          ret = stat("/lib/firmware/nouveau/nv84_vp-mpeg12", &s);
791          if (!ret && s.st_size > 1000)
792             screen->firmware_info.profiles_present |= FIRMWARE_VP_MPEG2;
793          screen->firmware_info.profiles_checked |= FIRMWARE_VP_MPEG2;
794       }
795       present = screen->firmware_info.profiles_present;
796       return FIRMWARE_PRESENT(present, VP_KERN) &&
797          FIRMWARE_PRESENT(present, VP_MPEG2);
798    }
799 }
800 
801 int
nv84_screen_get_video_param(struct pipe_screen * pscreen,enum pipe_video_profile profile,enum pipe_video_entrypoint entrypoint,enum pipe_video_cap param)802 nv84_screen_get_video_param(struct pipe_screen *pscreen,
803                             enum pipe_video_profile profile,
804                             enum pipe_video_entrypoint entrypoint,
805                             enum pipe_video_cap param)
806 {
807    enum pipe_video_format codec;
808 
809    switch (param) {
810    case PIPE_VIDEO_CAP_SUPPORTED:
811       codec = u_reduce_video_profile(profile);
812       return (codec == PIPE_VIDEO_FORMAT_MPEG4_AVC ||
813               codec == PIPE_VIDEO_FORMAT_MPEG12) &&
814          firmware_present(pscreen, codec);
815    case PIPE_VIDEO_CAP_NPOT_TEXTURES:
816       return 1;
817    case PIPE_VIDEO_CAP_MAX_WIDTH:
818    case PIPE_VIDEO_CAP_MAX_HEIGHT:
819       return 2048;
820    case PIPE_VIDEO_CAP_PREFERED_FORMAT:
821       return PIPE_FORMAT_NV12;
822    case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED:
823    case PIPE_VIDEO_CAP_PREFERS_INTERLACED:
824       return true;
825    case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE:
826       return false;
827    case PIPE_VIDEO_CAP_MAX_LEVEL:
828       switch (profile) {
829       case PIPE_VIDEO_PROFILE_MPEG1:
830          return 0;
831       case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE:
832       case PIPE_VIDEO_PROFILE_MPEG2_MAIN:
833          return 3;
834       case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE:
835       case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN:
836       case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH:
837          return 41;
838       default:
839          debug_printf("unknown video profile: %d\n", profile);
840          return 0;
841       }
842    default:
843       debug_printf("unknown video param: %d\n", param);
844       return 0;
845    }
846 }
847 
848 boolean
nv84_screen_video_supported(struct pipe_screen * screen,enum pipe_format format,enum pipe_video_profile profile,enum pipe_video_entrypoint entrypoint)849 nv84_screen_video_supported(struct pipe_screen *screen,
850                             enum pipe_format format,
851                             enum pipe_video_profile profile,
852                             enum pipe_video_entrypoint entrypoint)
853 {
854    if (profile != PIPE_VIDEO_PROFILE_UNKNOWN)
855       return format == PIPE_FORMAT_NV12;
856 
857    return vl_video_buffer_is_format_supported(screen, format, profile, entrypoint);
858 }
859