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_video.h"
26 nvc0_decoder_setup_ppp(struct nvc0_decoder
*dec
, struct nvc0_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 #ifdef NVC0_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 nvc0_decoder_ycbcr_offsets(dec
, &y2
, &cbcr
, &cbcr2
);
53 BEGIN_NVC0(push
, SUBC_PPP(0x700), 10);
54 in_addr
= nvc0_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
65 assert(target
->resources
[0]->width0
>= 16 * dec_w
);
66 assert(target
->resources
[0]->height0
>= dec
->base
.height
/2);
68 for (i
= 0; i
< 2; ++i
) {
69 struct nv50_miptree
*mt
= (struct nv50_miptree
*)target
->resources
[i
];
71 PUSH_DATA (push
, mt
->base
.address
>> 8);
72 PUSH_DATA (push
, (mt
->base
.address
+ mt
->total_size
/2/mt
->base
.base
.array_size
) >> 8);
73 mt
->base
.status
|= NOUVEAU_BUFFER_STATUS_GPU_WRITING
;
78 nvc0_decoder_vc1_ppp(struct nvc0_decoder
*dec
, struct pipe_vc1_picture_desc
*desc
, struct nvc0_video_buffer
*target
) {
79 struct nouveau_pushbuf
*push
= dec
->pushbuf
[2];
81 nvc0_decoder_setup_ppp(dec
, target
, 0x1412);
82 assert(!desc
->deblockEnable
);
83 assert(!(dec
->base
.width
& 0xf));
84 assert(!(dec
->base
.height
& 0xf));
86 BEGIN_NVC0(push
, SUBC_PPP(0x400), 1);
87 PUSH_DATA (push
, desc
->pquant
<< 11);
94 nvc0_decoder_ppp(struct nvc0_decoder
*dec
, union pipe_desc desc
, struct nvc0_video_buffer
*target
, unsigned comm_seq
) {
95 enum pipe_video_codec codec
= u_reduce_video_profile(dec
->base
.profile
);
96 struct nouveau_pushbuf
*push
= dec
->pushbuf
[2];
97 unsigned ppp_caps
= 0x10;
98 unsigned fence_extra
= 0;
104 PUSH_SPACE(push
, 11 + (codec
== PIPE_VIDEO_CODEC_VC1
? 2 : 0) + 3 + fence_extra
+ 2);
107 case PIPE_VIDEO_CODEC_MPEG12
: {
108 unsigned mpeg2
= dec
->base
.profile
!= PIPE_VIDEO_PROFILE_MPEG1
;
109 nvc0_decoder_setup_ppp(dec
, target
, 0x1410 | mpeg2
);
112 case PIPE_VIDEO_CODEC_MPEG4
: nvc0_decoder_setup_ppp(dec
, target
, 0x1414); break;
113 case PIPE_VIDEO_CODEC_VC1
: ppp_caps
= nvc0_decoder_vc1_ppp(dec
, desc
.vc1
, target
); break;
114 case PIPE_VIDEO_CODEC_MPEG4_AVC
: nvc0_decoder_setup_ppp(dec
, target
, 0x1413); break;
117 BEGIN_NVC0(push
, SUBC_PPP(0x734), 2);
118 PUSH_DATA (push
, comm_seq
);
119 PUSH_DATA (push
, ppp_caps
);
122 BEGIN_NVC0(push
, SUBC_PPP(0x240), 3);
123 PUSH_DATAh(push
, (dec
->fence_bo
->offset
+ 0x20));
124 PUSH_DATA (push
, (dec
->fence_bo
->offset
+ 0x20));
125 PUSH_DATA (push
, dec
->fence_seq
);
127 BEGIN_NVC0(push
, SUBC_PPP(0x300), 1);
136 if ((spin
++ & 0xff) == 0xff)
137 debug_printf("ppp%u: %u\n", dec
->fence_seq
, dec
->fence_map
[8]);
138 } while (dec
->fence_seq
> dec
->fence_map
[8]);
141 BEGIN_NVC0(push
, SUBC_PPP(0x300), 1);