OSDN Git Service

i965_drv_video: Eanble VAAPI on IGDNG
[android-x86/hardware-intel-common-libva.git] / i965_drv_video / i965_media.c
1 /*
2  * Copyright © 2009 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sub license, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial portions
14  * of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors:
25  *    Xiang Haihao <haihao.xiang@intel.com>
26  *    Zou Nan hai <nanhai.zou@intel.com>
27  *
28  */
29
30 #include <stdio.h>
31 #include <string.h>
32 #include <assert.h>
33
34 #include "va_backend.h"
35
36 #include "intel_batchbuffer.h"
37 #include "intel_driver.h"
38
39 #include "i965_defines.h"
40 #include "i965_media_mpeg2.h"
41 #include "i965_media.h"
42 #include "i965_drv_video.h"
43
44 static void
45 i965_media_pipeline_select(VADriverContextP ctx)
46 {
47     BEGIN_BATCH(ctx, 1);
48     OUT_BATCH(ctx, CMD_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA);
49     ADVANCE_BATCH(ctx);
50 }
51
52 static void
53 i965_media_urb_layout(VADriverContextP ctx)
54 {
55     struct i965_driver_data *i965 = i965_driver_data(ctx);
56     struct i965_media_state *media_state = &i965->media_state;
57     unsigned int vfe_fence, cs_fence;
58
59     vfe_fence = media_state->urb.cs_start;
60     cs_fence = URB_SIZE((&i965->intel));
61
62     BEGIN_BATCH(ctx, 3);
63     OUT_BATCH(ctx, CMD_URB_FENCE | UF0_VFE_REALLOC | UF0_CS_REALLOC | 1);
64     OUT_BATCH(ctx, 0);
65     OUT_BATCH(ctx, 
66               (vfe_fence << UF2_VFE_FENCE_SHIFT) |      /* VFE_SIZE */
67               (cs_fence << UF2_CS_FENCE_SHIFT));        /* CS_SIZE */
68     ADVANCE_BATCH(ctx);
69 }
70
71 static void
72 i965_media_state_base_address(VADriverContextP ctx)
73 {
74     struct i965_driver_data *i965 = i965_driver_data(ctx); 
75
76     if (IS_IGDNG(i965->intel.device_id)) {
77         BEGIN_BATCH(ctx, 8);
78         OUT_BATCH(ctx, CMD_STATE_BASE_ADDRESS | 6);
79         OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY);
80         OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY);
81         OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY);
82         OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY);
83         OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY);
84         OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY);
85         OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY);
86         ADVANCE_BATCH(ctx);
87     } else {
88         BEGIN_BATCH(ctx, 6);
89         OUT_BATCH(ctx, CMD_STATE_BASE_ADDRESS | 4);
90         OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY);
91         OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY);
92         OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY);
93         OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY);
94         OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY);
95         ADVANCE_BATCH(ctx);
96     }
97 }
98
99 static void
100 i965_media_state_pointers(VADriverContextP ctx)
101 {
102     struct i965_driver_data *i965 = i965_driver_data(ctx);
103     struct i965_media_state *media_state = &i965->media_state;
104
105     BEGIN_BATCH(ctx, 3);
106     OUT_BATCH(ctx, CMD_MEDIA_STATE_POINTERS | 1);
107
108     if (media_state->extended_state.enabled)
109         OUT_RELOC(ctx, media_state->extended_state.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1);
110     else
111         OUT_BATCH(ctx, 0);
112
113     OUT_RELOC(ctx, media_state->vfe_state.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
114     ADVANCE_BATCH(ctx);
115 }
116
117 static void 
118 i965_media_cs_urb_layout(VADriverContextP ctx)
119 {
120     struct i965_driver_data *i965 = i965_driver_data(ctx);
121     struct i965_media_state *media_state = &i965->media_state;
122
123     BEGIN_BATCH(ctx, 2);
124     OUT_BATCH(ctx, CMD_CS_URB_STATE | 0);
125     OUT_BATCH(ctx,
126               ((media_state->urb.size_cs_entry - 1) << 4) |     /* URB Entry Allocation Size */
127               (media_state->urb.num_cs_entries << 0));          /* Number of URB Entries */
128     ADVANCE_BATCH(ctx);
129 }
130
131 static void 
132 i965_media_pipeline_state(VADriverContextP ctx)
133 {
134     i965_media_state_base_address(ctx);
135     i965_media_state_pointers(ctx);
136     i965_media_cs_urb_layout(ctx);
137 }
138
139 static void
140 i965_media_constant_buffer(VADriverContextP ctx, struct decode_state *decode_state)
141 {
142     struct i965_driver_data *i965 = i965_driver_data(ctx);
143     struct i965_media_state *media_state = &i965->media_state;
144
145     BEGIN_BATCH(ctx, 2);
146     OUT_BATCH(ctx, CMD_CONSTANT_BUFFER | (1 << 8) | (2 - 2));
147     OUT_RELOC(ctx, media_state->curbe.bo,
148               I915_GEM_DOMAIN_INSTRUCTION, 0,
149               media_state->urb.size_cs_entry - 1);
150     ADVANCE_BATCH(ctx);    
151 }
152
153 static void
154 i965_media_pipeline_setup(VADriverContextP ctx, struct decode_state *decode_state)
155 {
156     struct i965_driver_data *i965 = i965_driver_data(ctx);
157     struct i965_media_state *media_state = &i965->media_state;
158
159     intel_batchbuffer_start_atomic(ctx, 0x1000);
160     intel_batchbuffer_emit_mi_flush(ctx);                       /* step 1 */
161     i965_media_pipeline_select(ctx);                            /* step 2 */
162     i965_media_urb_layout(ctx);                                 /* step 3 */
163     i965_media_pipeline_state(ctx);                             /* step 4 */
164     i965_media_constant_buffer(ctx, decode_state);              /* step 5 */
165     assert(media_state->media_objects);
166     media_state->media_objects(ctx, decode_state);              /* step 6 */
167     intel_batchbuffer_end_atomic(ctx);
168 }
169
170 static void 
171 i965_media_decode_init(VADriverContextP ctx, VAProfile profile)
172 {
173     int i;
174     struct i965_driver_data *i965 = i965_driver_data(ctx);
175     struct i965_media_state *media_state = &i965->media_state;
176     dri_bo *bo;
177
178     /* constant buffer */
179     dri_bo_unreference(media_state->curbe.bo);
180     bo = dri_bo_alloc(i965->intel.bufmgr,
181                       "constant buffer",
182                       4096, 64);
183     assert(bo);
184     media_state->curbe.bo = bo;
185
186     /* surface state */
187     for (i = 0; i < MAX_MEDIA_SURFACES; i++) {
188         dri_bo_unreference(media_state->surface_state[i].bo);
189         media_state->surface_state[i].bo = NULL;
190     }
191
192     /* binding table */
193     dri_bo_unreference(media_state->binding_table.bo);
194     bo = dri_bo_alloc(i965->intel.bufmgr, 
195                       "binding table",
196                       MAX_MEDIA_SURFACES * sizeof(unsigned int), 32);
197     assert(bo);
198     media_state->binding_table.bo = bo;
199
200     /* interface descriptor remapping table */
201     dri_bo_unreference(media_state->idrt.bo);
202     bo = dri_bo_alloc(i965->intel.bufmgr, 
203                       "interface discriptor", 
204                       MAX_INTERFACE_DESC * sizeof(struct i965_interface_descriptor), 16);
205     assert(bo);
206     media_state->idrt.bo = bo;
207
208     /* vfe state */
209     dri_bo_unreference(media_state->vfe_state.bo);
210     bo = dri_bo_alloc(i965->intel.bufmgr, 
211                       "vfe state", 
212                       sizeof(struct i965_vfe_state), 32);
213     assert(bo);
214     media_state->vfe_state.bo = bo;
215
216     /* extended state */
217     media_state->extended_state.enabled = 0;
218
219     switch (profile) {
220     case VAProfileMPEG2Simple:
221     case VAProfileMPEG2Main:
222         i965_media_mpeg2_decode_init(ctx);
223         break;
224
225     default:
226         assert(0);
227         break;
228     }
229 }
230
231 void 
232 i965_media_decode_picture(VADriverContextP ctx, 
233                           VAProfile profile, 
234                           struct decode_state *decode_state)
235 {
236     struct i965_driver_data *i965 = i965_driver_data(ctx);
237     struct i965_media_state *media_state = &i965->media_state;
238
239     i965_media_decode_init(ctx, profile);
240     assert(media_state->states_setup);
241     media_state->states_setup(ctx, decode_state);
242     i965_media_pipeline_setup(ctx, decode_state);
243     intel_batchbuffer_flush(ctx);
244 }
245
246 Bool 
247 i965_media_init(VADriverContextP ctx)
248 {
249     i965_media_mpeg2_init(ctx);
250     return True;
251 }
252
253 Bool 
254 i965_media_terminate(VADriverContextP ctx)
255 {
256     struct i965_driver_data *i965 = i965_driver_data(ctx);
257     struct i965_media_state *media_state = &i965->media_state;
258     int i;
259
260     for (i = 0; i < MAX_MEDIA_SURFACES; i++) {
261         dri_bo_unreference(media_state->surface_state[i].bo);
262         media_state->surface_state[i].bo = NULL;
263     }
264     
265     dri_bo_unreference(media_state->extended_state.bo);
266     media_state->extended_state.bo = NULL;
267
268     dri_bo_unreference(media_state->vfe_state.bo);
269     media_state->vfe_state.bo = NULL;
270
271     dri_bo_unreference(media_state->idrt.bo);
272     media_state->idrt.bo = NULL;
273
274     dri_bo_unreference(media_state->binding_table.bo);
275     media_state->binding_table.bo = NULL;
276
277     dri_bo_unreference(media_state->curbe.bo);
278     media_state->curbe.bo = NULL;
279
280     i965_media_mpeg2_ternimate(ctx);
281     return True;
282 }
283