21e57199dd20be0f298dd614024e62888b6614c4
[profile/ivi/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 <string.h>
29 #include <assert.h>
30
31 #include <va/va_backend.h>
32
33 #include "intel_batchbuffer.h"
34
35 static void 
36 intel_batchbuffer_reset(struct intel_batchbuffer *batch)
37 {
38     struct intel_driver_data *intel = batch->intel; 
39
40     if (batch->buffer != NULL) {
41         dri_bo_unreference(batch->buffer);
42         batch->buffer = NULL;
43     }
44
45     batch->buffer = dri_bo_alloc(intel->bufmgr, "batch buffer", 
46                                  BATCH_SIZE, 0x1000);
47
48     assert(batch->buffer);
49     dri_bo_map(batch->buffer, 1);
50     batch->map = batch->buffer->virtual;
51     batch->size = BATCH_SIZE;
52     batch->ptr = batch->map;
53     batch->atomic = 0;
54 }
55
56 Bool 
57 intel_batchbuffer_init(struct intel_driver_data *intel)
58 {
59     intel->batch = calloc(1, sizeof(*(intel->batch)));
60
61     assert(intel->batch);
62     intel->batch->intel = intel;
63     intel_batchbuffer_reset(intel->batch);
64
65     return True;
66 }
67
68 Bool
69 intel_batchbuffer_terminate(struct intel_driver_data *intel)
70 {
71     if (intel->batch) {
72         if (intel->batch->map) {
73             dri_bo_unmap(intel->batch->buffer);
74             intel->batch->map = NULL;
75         }
76
77         dri_bo_unreference(intel->batch->buffer);
78         free(intel->batch);
79         intel->batch = NULL;
80     }
81
82     return True;
83 }
84
85 Bool 
86 intel_batchbuffer_flush(VADriverContextP ctx)
87 {
88     struct intel_driver_data *intel = intel_driver_data(ctx);
89     struct intel_batchbuffer *batch = intel->batch;
90     unsigned int used = batch->ptr - batch->map;
91     int is_locked = intel->locked;
92
93     if (used == 0) {
94         return True;
95     }
96
97     if ((used & 4) == 0) {
98         *(unsigned int*)batch->ptr = 0;
99         batch->ptr += 4;
100     }
101
102     *(unsigned int*)batch->ptr = MI_BATCH_BUFFER_END;
103     batch->ptr += 4;
104     dri_bo_unmap(batch->buffer);
105     used = batch->ptr - batch->map;
106
107     if (!is_locked)
108         intel_lock_hardware(ctx);
109
110     dri_bo_exec(batch->buffer, used, 0, 0, 0);
111
112     if (!is_locked)
113         intel_unlock_hardware(ctx);
114
115     intel_batchbuffer_reset(intel->batch);
116
117     return True;
118 }
119
120 static unsigned int
121 intel_batchbuffer_space(struct intel_batchbuffer *batch)
122 {
123     return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map);
124 }
125
126 void 
127 intel_batchbuffer_emit_dword(VADriverContextP ctx, unsigned int x)
128 {
129     struct intel_driver_data *intel = intel_driver_data(ctx);
130     struct intel_batchbuffer *batch = intel->batch;
131
132     assert(intel_batchbuffer_space(batch) >= 4);
133     *(unsigned int*)batch->ptr = x;
134     batch->ptr += 4;
135 }
136
137 void 
138 intel_batchbuffer_emit_reloc(VADriverContextP ctx, dri_bo *bo, 
139                              uint32_t read_domains, uint32_t write_domains, 
140                              uint32_t delta)
141 {
142     struct intel_driver_data *intel = intel_driver_data(ctx);
143     struct intel_batchbuffer *batch = intel->batch;
144
145     assert(batch->ptr - batch->map < batch->size);
146     dri_bo_emit_reloc(batch->buffer, read_domains, write_domains,
147                       delta, batch->ptr - batch->map, bo);
148     intel_batchbuffer_emit_dword(ctx, bo->offset + delta);
149 }
150
151 void 
152 intel_batchbuffer_require_space(VADriverContextP ctx, unsigned int size)
153 {
154     struct intel_driver_data *intel = intel_driver_data(ctx);
155     struct intel_batchbuffer *batch = intel->batch;
156
157     assert(size < batch->size - 8);
158
159     if (intel_batchbuffer_space(batch) < size) {
160         intel_batchbuffer_flush(ctx);
161     }
162 }
163
164 void 
165 intel_batchbuffer_data(VADriverContextP ctx, void *data, unsigned int size)
166 {
167     struct intel_driver_data *intel = intel_driver_data(ctx);
168     struct intel_batchbuffer *batch = intel->batch;
169
170     assert((size & 3) == 0);
171     intel_batchbuffer_require_space(ctx, size);
172
173     assert(batch->ptr);
174     memcpy(batch->ptr, data, size);
175     batch->ptr += size;
176 }
177
178 void
179 intel_batchbuffer_emit_mi_flush(VADriverContextP ctx)
180 {
181     intel_batchbuffer_require_space(ctx, 4);
182     intel_batchbuffer_emit_dword(ctx, MI_FLUSH | STATE_INSTRUCTION_CACHE_INVALIDATE);
183 }
184
185 void
186 intel_batchbuffer_start_atomic(VADriverContextP ctx, unsigned int size)
187 {
188     struct intel_driver_data *intel = intel_driver_data(ctx);
189     struct intel_batchbuffer *batch = intel->batch;
190
191     assert(!batch->atomic);
192     intel_batchbuffer_require_space(ctx, size);
193     batch->atomic = 1;
194 }
195
196 void
197 intel_batchbuffer_end_atomic(VADriverContextP ctx)
198 {
199     struct intel_driver_data *intel = intel_driver_data(ctx);
200     struct intel_batchbuffer *batch = intel->batch;
201
202     assert(batch->atomic);
203     batch->atomic = 0;
204 }