OSDN Git Service

i965_drv_video: add support for H264 on Clarkdale/Arrandale
[android-x86/hardware-intel-common-libva.git] / i965_drv_video / intel_batchbuffer.c
1 /**************************************************************************                                                                                  
2  *                                                                                                                                                           
3  * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.                                                                                                
4  * All Rights Reserved.                                                                                                                                      
5  *                                                                                                                                                           
6  * Permission is hereby granted, free of charge, to any person obtaining a                                                                                   
7  * copy of this software and associated documentation files (the                                                                                             
8  * "Software"), to deal in the Software without restriction, including                                                                                       
9  * without limitation the rights to use, copy, modify, merge, publish,                                                                                       
10  * distribute, sub license, and/or sell copies of the Software, and to                                                                                       
11  * permit persons to whom the Software is furnished to do so, subject to                                                                                     
12  * the following conditions:                                                                                                                                 
13  *                                                                                                                                                           
14  * The above copyright notice and this permission notice (including the                                                                                      
15  * next paragraph) shall be included in all copies or substantial portions                                                                                   
16  * of the Software.                                                                                                                                          
17  *                                                                                                                                                           
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS                                                                                   
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF                                                                                                
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.                                                                                   
21  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR                                                                                    
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,                                                                                  
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE                                                                                         
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                                                                                    
25  *                                                                                                                                                           
26  **************************************************************************/      
27
28 #include <stdlib.h>
29 #include <string.h>
30 #include <assert.h>
31
32 #include <va/va_backend.h>
33
34 #include "intel_batchbuffer.h"
35
36 static void 
37 intel_batchbuffer_reset(struct intel_batchbuffer *batch)
38 {
39     struct intel_driver_data *intel = batch->intel; 
40
41     assert(batch->flag == ON_RENDER_RING ||
42            batch->flag == ON_BSD_RING);
43
44     dri_bo_unreference(batch->buffer);
45     batch->buffer = dri_bo_alloc(intel->bufmgr, 
46                                  batch->flag == ON_RENDER_RING ? "render batch buffer" : "bsd batch buffer", 
47                                  BATCH_SIZE, 0x1000);
48     assert(batch->buffer);
49     dri_bo_map(batch->buffer, 1);
50     assert(batch->buffer->virtual);
51     batch->map = batch->buffer->virtual;
52     batch->size = BATCH_SIZE;
53     batch->ptr = batch->map;
54     batch->atomic = 0;
55 }
56
57 Bool 
58 intel_batchbuffer_init(struct intel_driver_data *intel)
59 {
60     intel->batch = calloc(1, sizeof(*(intel->batch)));
61     assert(intel->batch);
62     intel->batch->intel = intel;
63     intel->batch->flag = ON_RENDER_RING;
64     intel->batch->run = drm_intel_bo_mrb_exec;
65     intel_batchbuffer_reset(intel->batch);
66
67     intel->batch_bcs = calloc(1, sizeof(*(intel->batch_bcs)));
68     assert(intel->batch_bcs);
69     intel->batch_bcs->intel = intel;
70     intel->batch_bcs->flag = ON_BSD_RING;
71     intel->batch_bcs->run = drm_intel_bo_mrb_exec;
72     intel_batchbuffer_reset(intel->batch_bcs);
73
74     return True;
75 }
76
77 Bool
78 intel_batchbuffer_terminate(struct intel_driver_data *intel)
79 {
80     if (intel->batch) {
81         if (intel->batch->map) {
82             dri_bo_unmap(intel->batch->buffer);
83             intel->batch->map = NULL;
84         }
85
86         dri_bo_unreference(intel->batch->buffer);
87         free(intel->batch);
88         intel->batch = NULL;
89     }
90
91     if (intel->batch_bcs) {
92         if (intel->batch_bcs->map) {
93             dri_bo_unmap(intel->batch_bcs->buffer);
94             intel->batch_bcs->map = NULL;
95         }
96
97         dri_bo_unreference(intel->batch_bcs->buffer);
98         free(intel->batch_bcs);
99         intel->batch_bcs = NULL;
100     }
101
102     return True;
103 }
104
105 static Bool
106 intel_batchbuffer_flush_helper(VADriverContextP ctx,
107                                struct intel_batchbuffer *batch)
108 {
109     struct intel_driver_data *intel = batch->intel;
110     unsigned int used = batch->ptr - batch->map;
111     int is_locked = intel->locked;
112
113     if (used == 0) {
114         return True;
115     }
116
117     if ((used & 4) == 0) {
118         *(unsigned int*)batch->ptr = 0;
119         batch->ptr += 4;
120     }
121
122     *(unsigned int*)batch->ptr = MI_BATCH_BUFFER_END;
123     batch->ptr += 4;
124     dri_bo_unmap(batch->buffer);
125     used = batch->ptr - batch->map;
126
127     if (!is_locked)
128         intel_lock_hardware(ctx);
129
130     batch->run(batch->buffer, used, 0, 0, 0, batch->flag);
131
132     if (!is_locked)
133         intel_unlock_hardware(ctx);
134
135     intel_batchbuffer_reset(batch);
136
137     return True;
138 }
139
140 Bool 
141 intel_batchbuffer_flush(VADriverContextP ctx)
142 {
143     struct intel_driver_data *intel = intel_driver_data(ctx);
144     
145     return intel_batchbuffer_flush_helper(ctx, intel->batch);
146 }
147
148 Bool 
149 intel_batchbuffer_flush_bcs(VADriverContextP ctx)
150 {
151     struct intel_driver_data *intel = intel_driver_data(ctx);
152     
153     return intel_batchbuffer_flush_helper(ctx, intel->batch_bcs);
154 }
155
156 static unsigned int
157 intel_batchbuffer_space_helper(struct intel_batchbuffer *batch)
158 {
159     return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map);
160 }
161
162 static void
163 intel_batchbuffer_emit_dword_helper(struct intel_batchbuffer *batch, 
164                                     unsigned int x)
165 {
166     assert(intel_batchbuffer_space_helper(batch) >= 4);
167     *(unsigned int *)batch->ptr = x;
168     batch->ptr += 4;
169 }
170
171 void 
172 intel_batchbuffer_emit_dword(VADriverContextP ctx, unsigned int x)
173 {
174     struct intel_driver_data *intel = intel_driver_data(ctx);
175
176     intel_batchbuffer_emit_dword_helper(intel->batch, x);
177 }
178
179 void 
180 intel_batchbuffer_emit_dword_bcs(VADriverContextP ctx, unsigned int x)
181 {
182     struct intel_driver_data *intel = intel_driver_data(ctx);
183
184     intel_batchbuffer_emit_dword_helper(intel->batch_bcs, x);
185 }
186
187 static void 
188 intel_batchbuffer_emit_reloc_helper(VADriverContextP ctx, 
189                                     struct intel_batchbuffer *batch,
190                                     dri_bo *bo, 
191                                     uint32_t read_domains, uint32_t write_domains, 
192                                     uint32_t delta)
193 {
194     assert(batch->ptr - batch->map < batch->size);
195     dri_bo_emit_reloc(batch->buffer, read_domains, write_domains,
196                       delta, batch->ptr - batch->map, bo);
197     intel_batchbuffer_emit_dword_helper(batch, bo->offset + delta);
198 }
199
200 void 
201 intel_batchbuffer_emit_reloc(VADriverContextP ctx, dri_bo *bo, 
202                              uint32_t read_domains, uint32_t write_domains, 
203                              uint32_t delta)
204 {
205     struct intel_driver_data *intel = intel_driver_data(ctx);
206
207     intel_batchbuffer_emit_reloc_helper(ctx, intel->batch,
208                                         bo, read_domains, write_domains,
209                                         delta);
210 }
211
212 void 
213 intel_batchbuffer_emit_reloc_bcs(VADriverContextP ctx, dri_bo *bo, 
214                                  uint32_t read_domains, uint32_t write_domains, 
215                                  uint32_t delta)
216 {
217     struct intel_driver_data *intel = intel_driver_data(ctx);
218
219     intel_batchbuffer_emit_reloc_helper(ctx, intel->batch_bcs,
220                                         bo, read_domains, write_domains,
221                                         delta);
222 }
223
224 static void 
225 intel_batchbuffer_require_space_helper(VADriverContextP ctx, 
226                                 struct intel_batchbuffer *batch,
227                                 unsigned int size)
228 {
229     assert(size < batch->size - 8);
230
231     if (intel_batchbuffer_space_helper(batch) < size) {
232         intel_batchbuffer_flush_helper(ctx, batch);
233     }
234 }
235
236 void 
237 intel_batchbuffer_require_space(VADriverContextP ctx, unsigned int size)
238 {
239     struct intel_driver_data *intel = intel_driver_data(ctx);
240
241     intel_batchbuffer_require_space_helper(ctx, intel->batch, size);
242 }
243
244 void 
245 intel_batchbuffer_require_space_bcs(VADriverContextP ctx, unsigned int size)
246 {
247     struct intel_driver_data *intel = intel_driver_data(ctx);
248
249     intel_batchbuffer_require_space_helper(ctx, intel->batch_bcs, size);
250 }
251
252 static void 
253 intel_batchbuffer_data_helper(VADriverContextP ctx, 
254                               struct intel_batchbuffer *batch,
255                               void *data,
256                               unsigned int size)
257 {
258     assert((size & 3) == 0);
259     intel_batchbuffer_require_space_helper(ctx, batch, size);
260
261     assert(batch->ptr);
262     memcpy(batch->ptr, data, size);
263     batch->ptr += size;
264 }
265
266 void 
267 intel_batchbuffer_data(VADriverContextP ctx, void *data, unsigned int size)
268 {
269     struct intel_driver_data *intel = intel_driver_data(ctx);
270
271     intel_batchbuffer_data_helper(ctx, intel->batch, data, size);
272 }
273
274 void 
275 intel_batchbuffer_data_bcs(VADriverContextP ctx, void *data, unsigned int size)
276 {
277     struct intel_driver_data *intel = intel_driver_data(ctx);
278
279     intel_batchbuffer_data_helper(ctx, intel->batch_bcs, data, size);
280 }
281
282 static void
283 intel_batchbuffer_emit_mi_flush_helper(VADriverContextP ctx,
284                                        struct intel_batchbuffer *batch)
285 {
286     intel_batchbuffer_require_space_helper(ctx, batch, 4);
287     intel_batchbuffer_emit_dword_helper(batch, 
288                                         MI_FLUSH | STATE_INSTRUCTION_CACHE_INVALIDATE);
289 }
290
291 void
292 intel_batchbuffer_emit_mi_flush(VADriverContextP ctx)
293 {
294     struct intel_driver_data *intel = intel_driver_data(ctx);
295
296     intel_batchbuffer_emit_mi_flush_helper(ctx, intel->batch);
297 }
298
299 void
300 intel_batchbuffer_emit_mi_flush_bcs(VADriverContextP ctx)
301 {
302     struct intel_driver_data *intel = intel_driver_data(ctx);
303
304     intel_batchbuffer_emit_mi_flush_helper(ctx, intel->batch_bcs);
305 }
306
307 void
308 intel_batchbuffer_start_atomic_helper(VADriverContextP ctx, 
309                                       struct intel_batchbuffer *batch,
310                                       unsigned int size)
311 {
312     assert(!batch->atomic);
313     intel_batchbuffer_require_space_helper(ctx, batch, size);
314     batch->atomic = 1;
315 }
316
317 void
318 intel_batchbuffer_start_atomic(VADriverContextP ctx, unsigned int size)
319 {
320     struct intel_driver_data *intel = intel_driver_data(ctx);
321
322     intel_batchbuffer_start_atomic_helper(ctx, intel->batch, size);
323 }
324
325 void
326 intel_batchbuffer_start_atomic_bcs(VADriverContextP ctx, unsigned int size)
327 {
328     struct intel_driver_data *intel = intel_driver_data(ctx);
329     intel_batchbuffer_start_atomic_helper(ctx, intel->batch_bcs, size);
330 }
331
332 void
333 intel_batchbuffer_end_atomic_helper(struct intel_batchbuffer *batch)
334 {
335     assert(batch->atomic);
336     batch->atomic = 0;
337 }
338
339 void
340 intel_batchbuffer_end_atomic(VADriverContextP ctx)
341 {
342     struct intel_driver_data *intel = intel_driver_data(ctx);
343
344     intel_batchbuffer_end_atomic_helper(intel->batch);
345 }
346
347 void
348 intel_batchbuffer_end_atomic_bcs(VADriverContextP ctx)
349 {
350     struct intel_driver_data *intel = intel_driver_data(ctx);
351
352     intel_batchbuffer_end_atomic_helper(intel->batch_bcs);
353 }
354