2 * Copyright 2011-2013 Maarten Lankhorst
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
23 #include "nvc0/nvc0_video.h"
25 #include "util/u_sampler.h"
26 #include "util/u_format.h"
29 nvc0_decoder_begin_frame(struct pipe_video_codec
*decoder
,
30 struct pipe_video_buffer
*target
,
31 struct pipe_picture_desc
*picture
)
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 */
39 assert(target
->buffer_format
== PIPE_FORMAT_NV12
);
41 ret
= nvc0_decoder_bsp_begin(dec
, comm_seq
);
47 nvc0_decoder_decode_bitstream(struct pipe_video_codec
*decoder
,
48 struct pipe_video_buffer
*video_target
,
49 struct pipe_picture_desc
*picture
,
51 const void *const *data
,
52 const unsigned *num_bytes
)
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 */
60 ret
= nvc0_decoder_bsp_next(dec
, comm_seq
, num_buffers
, data
, num_bytes
);
66 nvc0_decoder_end_frame(struct pipe_video_codec
*decoder
,
67 struct pipe_video_buffer
*video_target
,
68 struct pipe_picture_desc
*picture
)
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
;
75 unsigned vp_caps
, is_ref
;
76 MAYBE_UNUSED
unsigned ret
; /* used in debug checks */
77 struct nouveau_vp3_video_buffer
*refs
[16] = {};
81 ret
= nvc0_decoder_bsp_end(dec
, desc
, target
, comm_seq
, &vp_caps
, &is_ref
, refs
);
83 /* did we decode bitstream correctly? */
86 nvc0_decoder_vp(dec
, desc
, target
, comm_seq
, vp_caps
, is_ref
, refs
);
87 nvc0_decoder_ppp(dec
, desc
, target
, comm_seq
);
90 struct pipe_video_codec
*
91 nvc0_create_decoder(struct pipe_context
*context
,
92 const struct pipe_video_codec
*templ
)
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;
100 cfg
.nvc0
.tile_mode
= 0x10;
101 cfg
.nvc0
.memtype
= 0xfe;
104 uint32_t codec
= 1, ppp_codec
= 3;
108 if (getenv("XVMC_VL"))
109 return vl_create_decoder(context
, templ
);
111 if (templ
->entrypoint
!= PIPE_VIDEO_ENTRYPOINT_BITSTREAM
) {
112 debug_printf("%x\n", templ
->entrypoint
);
116 dec
= CALLOC_STRUCT(nouveau_vp3_decoder
);
119 dec
->client
= screen
->client
;
121 nouveau_vp3_decoder_init_common(&dec
->base
);
133 for (i
= 0; i
< 3; ++i
)
135 dec
->channel
[i
] = dec
->channel
[0];
136 dec
->pushbuf
[i
] = dec
->pushbuf
[0];
140 struct nvc0_fifo nvc0_args
= {};
141 struct nve0_fifo nve0_args
= {};
144 size
= sizeof(nvc0_args
);
147 unsigned engine
[] = {
148 NVE0_FIFO_ENGINE_BSP
,
153 nve0_args
.engine
= engine
[i
];
154 size
= sizeof(nve0_args
);
158 ret
= nouveau_object_new(&screen
->device
->object
, 0,
159 NOUVEAU_FIFO_CHANNEL_CLASS
,
160 data
, size
, &dec
->channel
[i
]);
163 ret
= nouveau_pushbuf_new(screen
->client
, dec
->channel
[i
], 4,
164 32 * 1024, true, &dec
->pushbuf
[i
]);
172 ret
= nouveau_object_new(dec
->channel
[0], 0x390b1, 0x90b1, NULL
, 0, &dec
->bsp
);
174 ret
= nouveau_object_new(dec
->channel
[1], 0x190b2, 0x90b2, NULL
, 0, &dec
->vp
);
176 ret
= nouveau_object_new(dec
->channel
[2], 0x290b3, 0x90b3, NULL
, 0, &dec
->ppp
);
179 ret
= nouveau_object_new(dec
->channel
[0], 0x95b1, 0x95b1, NULL
, 0, &dec
->bsp
);
181 ret
= nouveau_object_new(dec
->channel
[1], 0x95b2, 0x95b2, NULL
, 0, &dec
->vp
);
183 ret
= nouveau_object_new(dec
->channel
[2], 0x90b3, 0x90b3, NULL
, 0, &dec
->ppp
);
188 BEGIN_NVC0(push
[0], SUBC_BSP(NV01_SUBCHAN_OBJECT
), 1);
189 PUSH_DATA (push
[0], dec
->bsp
->handle
);
191 BEGIN_NVC0(push
[1], SUBC_VP(NV01_SUBCHAN_OBJECT
), 1);
192 PUSH_DATA (push
[1], dec
->vp
->handle
);
194 BEGIN_NVC0(push
[2], SUBC_PPP(NV01_SUBCHAN_OBJECT
), 1);
195 PUSH_DATA (push
[2], dec
->ppp
->handle
);
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
;
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
]);
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]);
212 ret
= nouveau_bo_new(screen
->device
, NOUVEAU_BO_VRAM
,
213 0x100, dec
->inter_bo
[0]->size
, &cfg
,
218 switch (u_reduce_video_profile(templ
->profile
)) {
219 case PIPE_VIDEO_FORMAT_MPEG12
: {
221 assert(templ
->max_references
<= 2);
224 case PIPE_VIDEO_FORMAT_MPEG4
: {
226 tmp_size
= mb(templ
->height
)*16 * mb(templ
->width
)*16;
227 assert(templ
->max_references
<= 2);
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);
236 case PIPE_VIDEO_FORMAT_MPEG4_AVC
: {
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);
244 fprintf(stderr
, "invalid codec\n");
248 if (screen
->device
->chipset
< 0xd0) {
249 ret
= nouveau_bo_new(screen
->device
, NOUVEAU_BO_VRAM
, 0,
250 0x4000, &cfg
, &dec
->fw_bo
);
254 ret
= nouveau_vp3_load_firmware(dec
, templ
->profile
, screen
->device
->chipset
);
260 ret
= nouveau_bo_new(screen
->device
, NOUVEAU_BO_VRAM
, 0,
261 0x400, &cfg
, &dec
->bitplane_bo
);
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
,
275 BEGIN_NVC0(push
[0], SUBC_BSP(0x200), 2);
276 PUSH_DATA (push
[0], codec
);
277 PUSH_DATA (push
[0], timeout
);
279 BEGIN_NVC0(push
[1], SUBC_VP(0x200), 2);
280 PUSH_DATA (push
[1], codec
);
281 PUSH_DATA (push
[1], timeout
);
283 BEGIN_NVC0(push
[2], SUBC_PPP(0x200), 2);
284 PUSH_DATA (push
[2], ppp_codec
);
285 PUSH_DATA (push
[2], timeout
);
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
);
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
)));
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
);
308 BEGIN_NVC0(push
[0], SUBC_BSP(0x304), 1);
309 PUSH_DATA (push
[0], 0);
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
);
319 BEGIN_NVC0(push
[1], SUBC_VP(0x304), 1);
320 PUSH_DATA (push
[1], 0);
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
);
330 BEGIN_NVC0(push
[2], SUBC_PPP(0x304), 1);
331 PUSH_DATA (push
[2], 0);
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]);
341 debug_printf("%u: %u %u %u\n", dec
->fence_seq
, dec
->fence_map
[0], dec
->fence_map
[4], dec
->fence_map
[8]);
347 debug_printf("Cannot create decoder without firmware..\n");
348 dec
->base
.destroy(&dec
->base
);
352 debug_printf("Creation failed: %s (%i)\n", strerror(-ret
), ret
);
353 dec
->base
.destroy(&dec
->base
);
357 struct pipe_video_buffer
*
358 nvc0_video_buffer_create(struct pipe_context
*pipe
,
359 const struct pipe_video_buffer
*templat
)
361 return nouveau_vp3_video_buffer_create(
362 pipe
, templat
, NVC0_RESOURCE_FLAG_VIDEO
);