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