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