1/*
2 * Copyright 2011-2013 Maarten Lankhorst, 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 "nv50/nv98_video.h"
24
25#include "util/u_sampler.h"
26#include "util/format/u_format.h"
27
28#include <nvif/class.h>
29
30static void
31nv98_decoder_decode_bitstream(struct pipe_video_codec *decoder,
32                              struct pipe_video_buffer *video_target,
33                              struct pipe_picture_desc *picture,
34                              unsigned num_buffers,
35                              const void *const *data,
36                              const unsigned *num_bytes)
37{
38   struct nouveau_vp3_decoder *dec = (struct nouveau_vp3_decoder *)decoder;
39   struct nouveau_vp3_video_buffer *target = (struct nouveau_vp3_video_buffer *)video_target;
40   uint32_t comm_seq = ++dec->fence_seq;
41   union pipe_desc desc;
42
43   unsigned vp_caps, is_ref;
44   ASSERTED unsigned ret; /* used in debug checks */
45   struct nouveau_vp3_video_buffer *refs[16] = {};
46
47   desc.base = picture;
48
49   assert(target->base.buffer_format == PIPE_FORMAT_NV12);
50
51   ret = nv98_decoder_bsp(dec, desc, target, comm_seq,
52                          num_buffers, data, num_bytes,
53                          &vp_caps, &is_ref, refs);
54
55   /* did we decode bitstream correctly? */
56   assert(ret == 2);
57
58   nv98_decoder_vp(dec, desc, target, comm_seq, vp_caps, is_ref, refs);
59   nv98_decoder_ppp(dec, desc, target, comm_seq);
60}
61
62static const struct nouveau_mclass
63nv98_decoder_msvld[] = {
64   { G98_MSVLD, -1 },
65   { IGT21A_MSVLD, -1 },
66   { GT212_MSVLD, -1 },
67   {}
68};
69
70static const struct nouveau_mclass
71nv98_decoder_mspdec[] = {
72   { G98_MSPDEC, -1 },
73   { GT212_MSPDEC, -1 },
74   {}
75};
76
77static const struct nouveau_mclass
78nv98_decoder_msppp[] = {
79   { G98_MSPPP, -1 },
80   { GT212_MSPPP, -1 },
81   {}
82};
83
84struct pipe_video_codec *
85nv98_create_decoder(struct pipe_context *context,
86                    const struct pipe_video_codec *templ)
87{
88   struct nv50_context *nv50 = nv50_context(context);
89   struct nouveau_screen *screen = &nv50->screen->base;
90   struct nouveau_vp3_decoder *dec;
91   struct nouveau_pushbuf **push;
92   struct nv04_fifo nv04_data = {.vram = 0xbeef0201, .gart = 0xbeef0202};
93
94   int ret, i;
95   uint32_t codec = 1, ppp_codec = 3;
96   uint32_t timeout;
97   u32 tmp_size = 0;
98
99   if (getenv("XVMC_VL"))
100       return vl_create_decoder(context, templ);
101
102   if (templ->entrypoint != PIPE_VIDEO_ENTRYPOINT_BITSTREAM) {
103      debug_printf("%x\n", templ->entrypoint);
104      return NULL;
105   }
106
107   dec = CALLOC_STRUCT(nouveau_vp3_decoder);
108   if (!dec)
109      return NULL;
110   dec->client = nv50->base.client;
111   dec->base = *templ;
112   nouveau_vp3_decoder_init_common(&dec->base);
113
114   dec->bsp_idx = 5;
115   dec->vp_idx = 6;
116   dec->ppp_idx = 7;
117
118   ret = nouveau_object_new(&screen->device->object, 0,
119                            NOUVEAU_FIFO_CHANNEL_CLASS,
120                            &nv04_data, sizeof(nv04_data), &dec->channel[0]);
121
122   if (!ret)
123      ret = nouveau_pushbuf_new(nv50->base.client, dec->channel[0], 4,
124                                32 * 1024, true, &dec->pushbuf[0]);
125
126   for (i = 1; i < 3; ++i) {
127      dec->channel[i] = dec->channel[0];
128      dec->pushbuf[i] = dec->pushbuf[0];
129   }
130   push = dec->pushbuf;
131
132   if (!ret) {
133      ret = nouveau_object_mclass(dec->channel[0], nv98_decoder_msvld);
134      if (ret >= 0) {
135         ret = nouveau_object_new(dec->channel[0], 0xbeef85b1,
136                                  nv98_decoder_msvld[ret].oclass, NULL, 0,
137                                  &dec->bsp);
138      }
139   }
140
141   if (!ret) {
142      ret = nouveau_object_mclass(dec->channel[1], nv98_decoder_mspdec);
143      if (ret >= 0) {
144         ret = nouveau_object_new(dec->channel[1], 0xbeef85b2,
145                                  nv98_decoder_mspdec[ret].oclass, NULL, 0,
146                                  &dec->vp);
147      }
148   }
149
150   if (!ret) {
151      ret = nouveau_object_mclass(dec->channel[2], nv98_decoder_msppp);
152      if (ret >= 0) {
153         ret = nouveau_object_new(dec->channel[2], 0xbeef85b3,
154                                  nv98_decoder_msppp[ret].oclass, NULL, 0,
155                                  &dec->ppp);
156      }
157   }
158
159   if (ret)
160      goto fail;
161
162   BEGIN_NV04(push[0], SUBC_BSP(NV01_SUBCHAN_OBJECT), 1);
163   PUSH_DATA (push[0], dec->bsp->handle);
164
165   BEGIN_NV04(push[0], SUBC_BSP(0x180), 5);
166   for (i = 0; i < 5; i++)
167      PUSH_DATA (push[0], nv04_data.vram);
168
169   BEGIN_NV04(push[1], SUBC_VP(NV01_SUBCHAN_OBJECT), 1);
170   PUSH_DATA (push[1], dec->vp->handle);
171
172   BEGIN_NV04(push[1], SUBC_VP(0x180), 6);
173   for (i = 0; i < 6; i++)
174      PUSH_DATA (push[1], nv04_data.vram);
175
176   BEGIN_NV04(push[2], SUBC_PPP(NV01_SUBCHAN_OBJECT), 1);
177   PUSH_DATA (push[2], dec->ppp->handle);
178
179   BEGIN_NV04(push[2], SUBC_PPP(0x180), 5);
180   for (i = 0; i < 5; i++)
181      PUSH_DATA (push[2], nv04_data.vram);
182
183   dec->base.context = context;
184   dec->base.decode_bitstream = nv98_decoder_decode_bitstream;
185
186   for (i = 0; i < NOUVEAU_VP3_VIDEO_QDEPTH && !ret; ++i)
187      ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM,
188                           0, 1 << 20, NULL, &dec->bsp_bo[i]);
189   if (!ret)
190      ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM,
191                           0x100, 4 << 20, NULL, &dec->inter_bo[0]);
192   if (!ret)
193      nouveau_bo_ref(dec->inter_bo[0], &dec->inter_bo[1]);
194   if (ret)
195      goto fail;
196
197   switch (u_reduce_video_profile(templ->profile)) {
198   case PIPE_VIDEO_FORMAT_MPEG12: {
199      codec = 1;
200      assert(templ->max_references <= 2);
201      break;
202   }
203   case PIPE_VIDEO_FORMAT_MPEG4: {
204      codec = 4;
205      tmp_size = mb(templ->height)*16 * mb(templ->width)*16;
206      assert(templ->max_references <= 2);
207      break;
208   }
209   case PIPE_VIDEO_FORMAT_VC1: {
210      ppp_codec = codec = 2;
211      tmp_size = mb(templ->height)*16 * mb(templ->width)*16;
212      assert(templ->max_references <= 2);
213      break;
214   }
215   case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
216      codec = 3;
217      dec->tmp_stride = 16 * mb_half(templ->width) * nouveau_vp3_video_align(templ->height) * 3 / 2;
218      tmp_size = dec->tmp_stride * (templ->max_references + 1);
219      assert(templ->max_references <= 16);
220      break;
221   }
222   default:
223      fprintf(stderr, "invalid codec\n");
224      goto fail;
225   }
226
227   ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM, 0,
228                           0x4000, NULL, &dec->fw_bo);
229   if (ret)
230      goto fail;
231
232   ret = nouveau_vp3_load_firmware(dec, templ->profile, screen->device->chipset);
233   if (ret)
234      goto fw_fail;
235
236   if (codec != 3) {
237      ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM, 0,
238                           0x400, NULL, &dec->bitplane_bo);
239      if (ret)
240         goto fail;
241   }
242
243   dec->ref_stride = mb(templ->width)*16 * (mb_half(templ->height)*32 + nouveau_vp3_video_align(templ->height)/2);
244   ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM, 0,
245                        dec->ref_stride * (templ->max_references+2) + tmp_size,
246                        NULL, &dec->ref_bo);
247   if (ret)
248      goto fail;
249
250   timeout = 0;
251
252   BEGIN_NV04(push[0], SUBC_BSP(0x200), 2);
253   PUSH_DATA (push[0], codec);
254   PUSH_DATA (push[0], timeout);
255
256   BEGIN_NV04(push[1], SUBC_VP(0x200), 2);
257   PUSH_DATA (push[1], codec);
258   PUSH_DATA (push[1], timeout);
259
260   BEGIN_NV04(push[2], SUBC_PPP(0x200), 2);
261   PUSH_DATA (push[2], ppp_codec);
262   PUSH_DATA (push[2], timeout);
263
264   ++dec->fence_seq;
265
266#if NOUVEAU_VP3_DEBUG_FENCE
267   ret = nouveau_bo_new(screen->device, NOUVEAU_BO_GART|NOUVEAU_BO_MAP,
268                        0, 0x1000, NULL, &dec->fence_bo);
269   if (ret)
270      goto fail;
271
272   nouveau_bo_map(dec->fence_bo, NOUVEAU_BO_RDWR, screen->client);
273   dec->fence_map = dec->fence_bo->map;
274   dec->fence_map[0] = dec->fence_map[4] = dec->fence_map[8] = 0;
275   dec->comm = (struct comm *)(dec->fence_map + (COMM_OFFSET/sizeof(*dec->fence_map)));
276
277   /* So lets test if the fence is working? */
278   nouveau_pushbuf_space(push[0], 16, 1, 0);
279   PUSH_REFN (push[0], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
280   BEGIN_NV04(push[0], SUBC_BSP(0x240), 3);
281   PUSH_DATAh(push[0], dec->fence_bo->offset);
282   PUSH_DATA (push[0], dec->fence_bo->offset);
283   PUSH_DATA (push[0], dec->fence_seq);
284
285   BEGIN_NV04(push[0], SUBC_BSP(0x304), 1);
286   PUSH_DATA (push[0], 0);
287   PUSH_KICK (push[0]);
288
289   nouveau_pushbuf_space(push[1], 16, 1, 0);
290   PUSH_REFN (push[1], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
291   BEGIN_NV04(push[1], SUBC_VP(0x240), 3);
292   PUSH_DATAh(push[1], (dec->fence_bo->offset + 0x10));
293   PUSH_DATA (push[1], (dec->fence_bo->offset + 0x10));
294   PUSH_DATA (push[1], dec->fence_seq);
295
296   BEGIN_NV04(push[1], SUBC_VP(0x304), 1);
297   PUSH_DATA (push[1], 0);
298   PUSH_KICK (push[1]);
299
300   nouveau_pushbuf_space(push[2], 16, 1, 0);
301   PUSH_REFN (push[2], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
302   BEGIN_NV04(push[2], SUBC_PPP(0x240), 3);
303   PUSH_DATAh(push[2], (dec->fence_bo->offset + 0x20));
304   PUSH_DATA (push[2], (dec->fence_bo->offset + 0x20));
305   PUSH_DATA (push[2], dec->fence_seq);
306
307   BEGIN_NV04(push[2], SUBC_PPP(0x304), 1);
308   PUSH_DATA (push[2], 0);
309   PUSH_KICK (push[2]);
310
311   usleep(100);
312   while (dec->fence_seq > dec->fence_map[0] ||
313          dec->fence_seq > dec->fence_map[4] ||
314          dec->fence_seq > dec->fence_map[8]) {
315      debug_printf("%u: %u %u %u\n", dec->fence_seq, dec->fence_map[0], dec->fence_map[4], dec->fence_map[8]);
316      usleep(100);
317   }
318   debug_printf("%u: %u %u %u\n", dec->fence_seq, dec->fence_map[0], dec->fence_map[4], dec->fence_map[8]);
319#endif
320
321   return &dec->base;
322
323fw_fail:
324   debug_printf("Cannot create decoder without firmware..\n");
325   dec->base.destroy(&dec->base);
326   return NULL;
327
328fail:
329   debug_printf("Creation failed: %s (%i)\n", strerror(-ret), ret);
330   dec->base.destroy(&dec->base);
331   return NULL;
332}
333
334struct pipe_video_buffer *
335nv98_video_buffer_create(struct pipe_context *pipe,
336                         const struct pipe_video_buffer *templat)
337{
338   return nouveau_vp3_video_buffer_create(
339         pipe, templat, NV50_RESOURCE_FLAG_VIDEO);
340}
341