2 * Mesa 3-D graphics library
4 * Copyright (C) 2012-2013 LunarG, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
25 * Chia-I Wu <olv@lunarg.com>
28 #include "genhw/genhw.h" /* for MI_xxx */
29 #include "intel_winsys.h"
33 /* the size of the private space */
34 static const int ilo_cp_private
= 2;
37 * Dump the contents of the parser bo. This can only be called in the flush
41 ilo_cp_dump(struct ilo_cp
*cp
)
43 ilo_printf("dumping %d bytes\n", cp
->used
* 4);
45 intel_winsys_decode_bo(cp
->winsys
, cp
->bo
, cp
->used
* 4);
49 * Save the command parser state for rewind.
51 * Note that this cannot rewind a flush, and the caller must make sure
52 * that does not happend.
55 ilo_cp_setjmp(struct ilo_cp
*cp
, struct ilo_cp_jmp_buf
*jmp
)
57 jmp
->id
= pointer_to_intptr(cp
->bo
);
61 jmp
->stolen
= cp
->stolen
;
62 /* save reloc count to rewind ilo_cp_write_bo() */
63 jmp
->reloc_count
= intel_bo_get_reloc_count(cp
->bo
);
67 * Rewind to the saved state.
70 ilo_cp_longjmp(struct ilo_cp
*cp
, const struct ilo_cp_jmp_buf
*jmp
)
72 if (jmp
->id
!= pointer_to_intptr(cp
->bo
)) {
73 assert(!"invalid use of CP longjmp");
79 cp
->stolen
= jmp
->stolen
;
80 intel_bo_truncate_relocs(cp
->bo
, jmp
->reloc_count
);
84 * Clear the parser buffer.
87 ilo_cp_clear_buffer(struct ilo_cp
*cp
)
96 * Recalculate cp->size. This is needed not only because cp->stolen is
97 * reset above, but also that ilo_cp_private are added to cp->size in
98 * ilo_cp_end_buffer().
100 cp
->size
= cp
->bo_size
- ilo_cp_private
;
104 * Add MI_BATCH_BUFFER_END to the private space of the parser buffer.
107 ilo_cp_end_buffer(struct ilo_cp
*cp
)
109 /* make the private space available */
110 cp
->size
+= ilo_cp_private
;
112 assert(cp
->used
+ 2 <= cp
->size
);
114 cp
->ptr
[cp
->used
++] = MI_BATCH_BUFFER_END
;
117 * From the Sandy Bridge PRM, volume 1 part 1, page 107:
119 * "The batch buffer must be QWord aligned and a multiple of QWords in
123 cp
->ptr
[cp
->used
++] = MI_NOOP
;
127 * Upload the parser buffer to the bo.
130 ilo_cp_upload_buffer(struct ilo_cp
*cp
)
135 intel_bo_unmap(cp
->bo
);
139 err
= intel_bo_pwrite(cp
->bo
, 0, cp
->used
* 4, cp
->ptr
);
140 if (likely(!err
&& cp
->stolen
)) {
141 const int offset
= cp
->bo_size
- cp
->stolen
;
143 err
= intel_bo_pwrite(cp
->bo
, offset
* 4,
144 cp
->stolen
* 4, &cp
->ptr
[offset
]);
151 * Reallocate the parser bo.
154 ilo_cp_realloc_bo(struct ilo_cp
*cp
)
159 * allocate the new bo before unreferencing the old one so that they
160 * won't point at the same address, which is needed for jmpbuf
162 bo
= intel_winsys_alloc_buffer(cp
->winsys
,
163 "batch buffer", cp
->bo_size
* 4, INTEL_DOMAIN_CPU
);
165 /* reuse the old one */
167 intel_bo_reference(bo
);
171 intel_bo_unreference(cp
->bo
);
175 cp
->ptr
= intel_bo_map(cp
->bo
, true);
179 * Execute the parser bo.
182 ilo_cp_exec_bo(struct ilo_cp
*cp
)
184 const bool do_exec
= !(ilo_debug
& ILO_DEBUG_NOHW
);
187 if (likely(do_exec
)) {
188 err
= intel_winsys_submit_bo(cp
->winsys
, cp
->ring
,
189 cp
->bo
, cp
->used
* 4, cp
->render_ctx
, cp
->one_off_flags
);
195 cp
->one_off_flags
= 0;
201 * Flush the command parser and execute the commands. When the parser buffer
202 * is empty, the callback is not invoked.
205 ilo_cp_flush_internal(struct ilo_cp
*cp
)
209 ilo_cp_set_owner(cp
, NULL
, 0);
212 assert(cp
->bo_size
== cp
->size
+ cp
->stolen
+ ilo_cp_private
);
215 /* return the space stolen and etc. */
216 ilo_cp_clear_buffer(cp
);
221 ilo_cp_end_buffer(cp
);
223 /* upload and execute */
224 err
= ilo_cp_upload_buffer(cp
);
226 err
= ilo_cp_exec_bo(cp
);
228 if (likely(!err
&& cp
->flush_callback
))
229 cp
->flush_callback(cp
, cp
->flush_callback_data
);
231 ilo_cp_clear_buffer(cp
);
232 ilo_cp_realloc_bo(cp
);
236 * Destroy the command parser.
239 ilo_cp_destroy(struct ilo_cp
*cp
)
243 intel_bo_unmap(cp
->bo
);
245 intel_bo_unreference(cp
->bo
);
248 intel_winsys_destroy_context(cp
->winsys
, cp
->render_ctx
);
255 * Create a command parser.
258 ilo_cp_create(struct intel_winsys
*winsys
, int size
, bool direct_map
)
262 cp
= CALLOC_STRUCT(ilo_cp
);
267 cp
->render_ctx
= intel_winsys_create_context(winsys
);
268 if (!cp
->render_ctx
) {
273 cp
->ring
= INTEL_RING_RENDER
;
274 cp
->no_implicit_flush
= false;
279 cp
->sys
= MALLOC(cp
->bo_size
* 4);
288 ilo_cp_realloc_bo(cp
);
295 ilo_cp_clear_buffer(cp
);