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
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 (pipe_format_to_chroma_format(template->buffer_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.width = template->width;
642 buffer->base.height = template->height;
643 buffer->base.get_sampler_view_planes = nv84_video_buffer_sampler_view_planes;
644 buffer->base.get_sampler_view_components = nv84_video_buffer_sampler_view_components;
645 buffer->base.get_surfaces = nv84_video_buffer_surfaces;
646 buffer->base.interlaced = true;
647
648 memset(&templ, 0, sizeof(templ));
649 templ.target = PIPE_TEXTURE_2D_ARRAY;
650 templ.depth0 = 1;
651 templ.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
652 templ.format = PIPE_FORMAT_R8_UNORM;
653 templ.width0 = align(template->width, 2);
654 templ.height0 = align(template->height, 4) / 2;
655 templ.flags = NV50_RESOURCE_FLAG_VIDEO | NV50_RESOURCE_FLAG_NOALLOC;
656 templ.array_size = 2;
657
658 cfg.nv50.tile_mode = 0x20;
659 cfg.nv50.memtype = 0x70;
660
661 buffer->resources[0] = pipe->screen->resource_create(pipe->screen, &templ);
662 if (!buffer->resources[0])
663 goto error;
664
665 templ.format = PIPE_FORMAT_R8G8_UNORM;
666 templ.width0 /= 2;
667 templ.height0 /= 2;
668 buffer->resources[1] = pipe->screen->resource_create(pipe->screen, &templ);
669 if (!buffer->resources[1])
670 goto error;
671
672 mt0 = nv50_miptree(buffer->resources[0]);
673 mt1 = nv50_miptree(buffer->resources[1]);
674
675 bo_size = mt0->total_size + mt1->total_size;
676 if (nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM | NOUVEAU_BO_NOSNOOP, 0,
677 bo_size, &cfg, &buffer->interlaced))
678 goto error;
679 /* XXX Change reference frame management so that this is only allocated in
680 * the decoder when necessary. */
681 if (nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM | NOUVEAU_BO_NOSNOOP, 0,
682 bo_size, &cfg, &buffer->full))
683 goto error;
684
685 nouveau_bo_ref(buffer->interlaced, &mt0->base.bo);
686 mt0->base.domain = NOUVEAU_BO_VRAM;
687 mt0->base.address = buffer->interlaced->offset;
688
689 nouveau_bo_ref(buffer->interlaced, &mt1->base.bo);
690 mt1->base.domain = NOUVEAU_BO_VRAM;
691 mt1->base.offset = mt0->total_size;
692 mt1->base.address = buffer->interlaced->offset + mt0->total_size;
693
694 memset(&sv_templ, 0, sizeof(sv_templ));
695 for (component = 0, i = 0; i < 2; ++i ) {
696 struct pipe_resource *res = buffer->resources[i];
697 unsigned nr_components = util_format_get_nr_components(res->format);
698
699 u_sampler_view_default_template(&sv_templ, res, res->format);
700 buffer->sampler_view_planes[i] =
701 pipe->create_sampler_view(pipe, res, &sv_templ);
702 if (!buffer->sampler_view_planes[i])
703 goto error;
704
705 for (j = 0; j < nr_components; ++j, ++component) {
706 sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b =
707 PIPE_SWIZZLE_X + j;
708 sv_templ.swizzle_a = PIPE_SWIZZLE_1;
709
710 buffer->sampler_view_components[component] =
711 pipe->create_sampler_view(pipe, res, &sv_templ);
712 if (!buffer->sampler_view_components[component])
713 goto error;
714 }
715 }
716
717 memset(&surf_templ, 0, sizeof(surf_templ));
718 for (j = 0; j < 2; ++j) {
719 surf_templ.format = buffer->resources[j]->format;
720 surf_templ.u.tex.first_layer = surf_templ.u.tex.last_layer = 0;
721 buffer->surfaces[j * 2] =
722 pipe->create_surface(pipe, buffer->resources[j], &surf_templ);
723 if (!buffer->surfaces[j * 2])
724 goto error;
725
726 surf_templ.u.tex.first_layer = surf_templ.u.tex.last_layer = 1;
727 buffer->surfaces[j * 2 + 1] =
728 pipe->create_surface(pipe, buffer->resources[j], &surf_templ);
729 if (!buffer->surfaces[j * 2 + 1])
730 goto error;
731 }
732
733 return &buffer->base;
734
735 error:
736 nv84_video_buffer_destroy(&buffer->base);
737 return NULL;
738 }
739
740 #define FIRMWARE_BSP_KERN 0x01
741 #define FIRMWARE_VP_KERN 0x02
742 #define FIRMWARE_BSP_H264 0x04
743 #define FIRMWARE_VP_MPEG2 0x08
744 #define FIRMWARE_VP_H264_1 0x10
745 #define FIRMWARE_VP_H264_2 0x20
746 #define FIRMWARE_PRESENT(val, fw) (val & FIRMWARE_ ## fw)
747
748 static int
firmware_present(struct pipe_screen * pscreen,enum pipe_video_format codec)749 firmware_present(struct pipe_screen *pscreen, enum pipe_video_format codec)
750 {
751 struct nouveau_screen *screen = nouveau_screen(pscreen);
752 struct nouveau_object *obj = NULL;
753 struct stat s;
754 int checked = screen->firmware_info.profiles_checked;
755 int present, ret;
756
757 if (!FIRMWARE_PRESENT(checked, VP_KERN)) {
758 ret = nouveau_object_new(screen->channel, 0, 0x7476, NULL, 0, &obj);
759 if (!ret)
760 screen->firmware_info.profiles_present |= FIRMWARE_VP_KERN;
761 nouveau_object_del(&obj);
762 screen->firmware_info.profiles_checked |= FIRMWARE_VP_KERN;
763 }
764
765 if (codec == PIPE_VIDEO_FORMAT_MPEG4_AVC) {
766 if (!FIRMWARE_PRESENT(checked, BSP_KERN)) {
767 ret = nouveau_object_new(screen->channel, 0, 0x74b0, NULL, 0, &obj);
768 if (!ret)
769 screen->firmware_info.profiles_present |= FIRMWARE_BSP_KERN;
770 nouveau_object_del(&obj);
771 screen->firmware_info.profiles_checked |= FIRMWARE_BSP_KERN;
772 }
773
774 if (!FIRMWARE_PRESENT(checked, VP_H264_1)) {
775 ret = stat("/lib/firmware/nouveau/nv84_vp-h264-1", &s);
776 if (!ret && s.st_size > 1000)
777 screen->firmware_info.profiles_present |= FIRMWARE_VP_H264_1;
778 screen->firmware_info.profiles_checked |= FIRMWARE_VP_H264_1;
779 }
780
781 /* should probably check the others, but assume that 1 means all */
782
783 present = screen->firmware_info.profiles_present;
784 return FIRMWARE_PRESENT(present, VP_KERN) &&
785 FIRMWARE_PRESENT(present, BSP_KERN) &&
786 FIRMWARE_PRESENT(present, VP_H264_1);
787 } else {
788 if (!FIRMWARE_PRESENT(checked, VP_MPEG2)) {
789 ret = stat("/lib/firmware/nouveau/nv84_vp-mpeg12", &s);
790 if (!ret && s.st_size > 1000)
791 screen->firmware_info.profiles_present |= FIRMWARE_VP_MPEG2;
792 screen->firmware_info.profiles_checked |= FIRMWARE_VP_MPEG2;
793 }
794 present = screen->firmware_info.profiles_present;
795 return FIRMWARE_PRESENT(present, VP_KERN) &&
796 FIRMWARE_PRESENT(present, VP_MPEG2);
797 }
798 }
799
800 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)801 nv84_screen_get_video_param(struct pipe_screen *pscreen,
802 enum pipe_video_profile profile,
803 enum pipe_video_entrypoint entrypoint,
804 enum pipe_video_cap param)
805 {
806 enum pipe_video_format codec;
807
808 switch (param) {
809 case PIPE_VIDEO_CAP_SUPPORTED:
810 codec = u_reduce_video_profile(profile);
811 return (codec == PIPE_VIDEO_FORMAT_MPEG4_AVC ||
812 codec == PIPE_VIDEO_FORMAT_MPEG12) &&
813 firmware_present(pscreen, codec);
814 case PIPE_VIDEO_CAP_NPOT_TEXTURES:
815 return 1;
816 case PIPE_VIDEO_CAP_MAX_WIDTH:
817 case PIPE_VIDEO_CAP_MAX_HEIGHT:
818 return 2048;
819 case PIPE_VIDEO_CAP_PREFERED_FORMAT:
820 return PIPE_FORMAT_NV12;
821 case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED:
822 case PIPE_VIDEO_CAP_PREFERS_INTERLACED:
823 return true;
824 case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE:
825 return false;
826 case PIPE_VIDEO_CAP_MAX_LEVEL:
827 switch (profile) {
828 case PIPE_VIDEO_PROFILE_MPEG1:
829 return 0;
830 case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE:
831 case PIPE_VIDEO_PROFILE_MPEG2_MAIN:
832 return 3;
833 case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE:
834 case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN:
835 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH:
836 return 41;
837 default:
838 debug_printf("unknown video profile: %d\n", profile);
839 return 0;
840 }
841 case PIPE_VIDEO_CAP_MAX_MACROBLOCKS:
842 return 8192; /* vc-1 actually has 8190, but this is not supported */
843 default:
844 debug_printf("unknown video param: %d\n", param);
845 return 0;
846 }
847 }
848
849 bool
nv84_screen_video_supported(struct pipe_screen * screen,enum pipe_format format,enum pipe_video_profile profile,enum pipe_video_entrypoint entrypoint)850 nv84_screen_video_supported(struct pipe_screen *screen,
851 enum pipe_format format,
852 enum pipe_video_profile profile,
853 enum pipe_video_entrypoint entrypoint)
854 {
855 if (profile != PIPE_VIDEO_PROFILE_UNKNOWN)
856 return format == PIPE_FORMAT_NV12;
857
858 return vl_video_buffer_is_format_supported(screen, format, profile, entrypoint);
859 }
860