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