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