2 * Copyright 2011-2013 Maarten Lankhorst, Ilia Mirkin
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 "nv50/nv98_video.h"
26 nv98_decoder_setup_ppp(struct nouveau_vp3_decoder
*dec
, struct nouveau_vp3_video_buffer
*target
, uint32_t low700
) {
27 struct nouveau_pushbuf
*push
= dec
->pushbuf
[2];
29 uint32_t stride_in
= mb(dec
->base
.width
);
30 uint32_t stride_out
= mb(target
->resources
[0]->width0
);
31 uint32_t dec_h
= mb(dec
->base
.height
);
32 uint32_t dec_w
= mb(dec
->base
.width
);
34 uint32_t y2
, cbcr
, cbcr2
, i
;
35 struct nouveau_pushbuf_refn bo_refs
[] = {
36 { NULL
, NOUVEAU_BO_WR
| NOUVEAU_BO_VRAM
},
37 { NULL
, NOUVEAU_BO_WR
| NOUVEAU_BO_VRAM
},
38 { dec
->ref_bo
, NOUVEAU_BO_RD
| NOUVEAU_BO_VRAM
},
39 #if NOUVEAU_VP3_DEBUG_FENCE
40 { dec
->fence_bo
, NOUVEAU_BO_WR
| NOUVEAU_BO_GART
},
43 unsigned num_refs
= sizeof(bo_refs
)/sizeof(*bo_refs
);
45 for (i
= 0; i
< 2; ++i
) {
46 struct nv50_miptree
*mt
= (struct nv50_miptree
*)target
->resources
[i
];
47 bo_refs
[i
].bo
= mt
->base
.bo
;
50 nouveau_pushbuf_refn(push
, bo_refs
, num_refs
);
51 nouveau_vp3_ycbcr_offsets(dec
, &y2
, &cbcr
, &cbcr2
);
53 BEGIN_NV04(push
, SUBC_PPP(0x700), 10);
54 in_addr
= nouveau_vp3_video_addr(dec
, target
) >> 8;
56 PUSH_DATA (push
, (stride_out
<< 24) | (stride_out
<< 16) | low700
); // 700
57 PUSH_DATA (push
, (stride_in
<< 24) | (stride_in
<< 16) | (dec_h
<< 8) | dec_w
); // 704
58 assert(dec_w
== stride_in
);
61 PUSH_DATA (push
, in_addr
); // 708
62 PUSH_DATA (push
, in_addr
+ y2
); // 70c
63 PUSH_DATA (push
, in_addr
+ cbcr
); // 710
64 PUSH_DATA (push
, in_addr
+ cbcr2
); // 714
66 for (i
= 0; i
< 2; ++i
) {
67 struct nv50_miptree
*mt
= (struct nv50_miptree
*)target
->resources
[i
];
69 PUSH_DATA (push
, mt
->base
.address
>> 8);
70 PUSH_DATA (push
, (mt
->base
.address
+ mt
->total_size
/2) >> 8);
71 mt
->base
.status
|= NOUVEAU_BUFFER_STATUS_GPU_WRITING
;
76 nv98_decoder_vc1_ppp(struct nouveau_vp3_decoder
*dec
, struct pipe_vc1_picture_desc
*desc
, struct nouveau_vp3_video_buffer
*target
) {
77 struct nouveau_pushbuf
*push
= dec
->pushbuf
[2];
79 nv98_decoder_setup_ppp(dec
, target
, 0x1412);
80 assert(!desc
->deblockEnable
);
81 assert(!(dec
->base
.width
& 0xf));
82 assert(!(dec
->base
.height
& 0xf));
84 BEGIN_NV04(push
, SUBC_PPP(0x400), 1);
85 PUSH_DATA (push
, desc
->pquant
<< 11);
92 nv98_decoder_ppp(struct nouveau_vp3_decoder
*dec
, union pipe_desc desc
, struct nouveau_vp3_video_buffer
*target
, unsigned comm_seq
) {
93 enum pipe_video_format codec
= u_reduce_video_profile(dec
->base
.profile
);
94 struct nouveau_pushbuf
*push
= dec
->pushbuf
[2];
95 unsigned ppp_caps
= 0x10;
96 unsigned fence_extra
= 0;
98 #if NOUVEAU_VP3_DEBUG_FENCE
102 nouveau_pushbuf_space(push
, 11 + (codec
== PIPE_VIDEO_FORMAT_VC1
? 2 : 0) + 3 + fence_extra
+ 2, 4, 0);
105 case PIPE_VIDEO_FORMAT_MPEG12
: {
106 unsigned mpeg2
= dec
->base
.profile
!= PIPE_VIDEO_PROFILE_MPEG1
;
107 nv98_decoder_setup_ppp(dec
, target
, 0x1410 | mpeg2
);
110 case PIPE_VIDEO_FORMAT_MPEG4
: nv98_decoder_setup_ppp(dec
, target
, 0x1414); break;
111 case PIPE_VIDEO_FORMAT_VC1
: ppp_caps
= nv98_decoder_vc1_ppp(dec
, desc
.vc1
, target
); break;
112 case PIPE_VIDEO_FORMAT_MPEG4_AVC
: nv98_decoder_setup_ppp(dec
, target
, 0x1413); break;
115 BEGIN_NV04(push
, SUBC_PPP(0x734), 2);
116 PUSH_DATA (push
, comm_seq
);
117 PUSH_DATA (push
, ppp_caps
);
119 #if NOUVEAU_VP3_DEBUG_FENCE
120 BEGIN_NV04(push
, SUBC_PPP(0x240), 3);
121 PUSH_DATAh(push
, (dec
->fence_bo
->offset
+ 0x20));
122 PUSH_DATA (push
, (dec
->fence_bo
->offset
+ 0x20));
123 PUSH_DATA (push
, dec
->fence_seq
);
125 BEGIN_NV04(push
, SUBC_PPP(0x300), 1);
134 if ((spin
++ & 0xff) == 0xff)
135 debug_printf("p%u: %u\n", dec
->fence_seq
, dec
->fence_map
[8]);
136 } while (dec
->fence_seq
> dec
->fence_map
[8]);
139 BEGIN_NV04(push
, SUBC_PPP(0x300), 1);