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>
31 #include "intel_winsys.h"
33 #include "ilo_common.h"
45 ILO_CP_HOOK_NEW_BATCH
,
46 ILO_CP_HOOK_PRE_FLUSH
,
47 ILO_CP_HOOK_POST_FLUSH
,
52 typedef void (*ilo_cp_hook_func
)(struct ilo_cp
*cp
, void *data
);
58 struct intel_winsys
*winsys
;
59 struct intel_context
*hw_ctx
;
61 enum ilo_cp_ring ring
;
62 bool no_implicit_flush
;
63 int reserve_for_pre_flush
;
66 ilo_cp_hook_func func
;
68 } hooks
[ILO_CP_HOOK_COUNT
];
75 int size
, used
, stolen
;
81 * Jump buffer to save command parser state for rewind.
83 struct ilo_cp_jmp_buf
{
85 int size
, used
, stolen
;
90 ilo_cp_create(struct intel_winsys
*winsys
, bool direct_map
);
93 ilo_cp_destroy(struct ilo_cp
*cp
);
96 ilo_cp_flush(struct ilo_cp
*cp
);
99 ilo_cp_dump(struct ilo_cp
*cp
);
102 ilo_cp_setjmp(struct ilo_cp
*cp
, struct ilo_cp_jmp_buf
*jmp
);
105 ilo_cp_longjmp(struct ilo_cp
*cp
, const struct ilo_cp_jmp_buf
*jmp
);
108 * Return true if the parser buffer is empty.
111 ilo_cp_empty(struct ilo_cp
*cp
)
117 * Return the remaining space (in dwords) in the parser buffer.
120 ilo_cp_space(struct ilo_cp
*cp
)
122 return cp
->size
- cp
->used
;
126 * Internal function called by functions that flush implicitly.
129 ilo_cp_implicit_flush(struct ilo_cp
*cp
)
131 if (cp
->no_implicit_flush
) {
132 assert(!"unexpected command parser flush");
133 /* discard the commands */
141 * Set the ring buffer.
144 ilo_cp_set_ring(struct ilo_cp
*cp
, enum ilo_cp_ring ring
)
146 if (cp
->ring
!= ring
) {
147 ilo_cp_implicit_flush(cp
);
153 * Assert that no function should flush implicitly.
156 ilo_cp_assert_no_implicit_flush(struct ilo_cp
*cp
, bool enable
)
158 cp
->no_implicit_flush
= enable
;
162 * Reserve the given size of space from the parser buffer. The reserved space
163 * will be made available temporarily for the pre-flush hook.
165 * \param reserve size in dwords to reserve. It may be negative.
168 ilo_cp_reserve_for_pre_flush(struct ilo_cp
*cp
, int reserve
)
170 assert(cp
->reserve_for_pre_flush
+ reserve
>= 0);
172 if (cp
->used
> cp
->size
- reserve
) {
173 ilo_cp_implicit_flush(cp
);
174 assert(cp
->used
<= cp
->size
- reserve
);
178 cp
->reserve_for_pre_flush
+= reserve
;
182 * Set a command parser hook.
185 ilo_cp_set_hook(struct ilo_cp
*cp
, enum ilo_cp_hook hook
,
186 ilo_cp_hook_func func
, void *data
)
188 cp
->hooks
[hook
].func
= func
;
189 cp
->hooks
[hook
].data
= data
;
193 * Begin writing a command.
196 ilo_cp_begin(struct ilo_cp
*cp
, int cmd_size
)
198 if (cp
->used
+ cmd_size
> cp
->size
) {
199 ilo_cp_implicit_flush(cp
);
200 assert(cp
->used
+ cmd_size
<= cp
->size
);
203 assert(cp
->cmd_cur
== cp
->cmd_end
);
204 cp
->cmd_cur
= cp
->used
;
205 cp
->cmd_end
= cp
->cmd_cur
+ cmd_size
;
206 cp
->used
= cp
->cmd_end
;
210 * Begin writing data to a space stolen from the top of the parser buffer.
212 * \param desc informative description of the data to be written
213 * \param data_size in dwords
214 * \param align in dwords
215 * \param bo_offset in bytes to the stolen space
218 ilo_cp_steal(struct ilo_cp
*cp
, const char *desc
,
219 int data_size
, int align
, uint32_t *bo_offset
)
226 pad
= (cp
->bo_size
- cp
->stolen
- data_size
) % align
;
227 steal
= data_size
+ pad
;
229 /* flush if there is not enough space after stealing */
230 if (cp
->used
> cp
->size
- steal
) {
231 ilo_cp_implicit_flush(cp
);
233 pad
= (cp
->bo_size
- cp
->stolen
- data_size
) % align
;
234 steal
= data_size
+ steal
;
236 assert(cp
->used
<= cp
->size
- steal
);
242 assert(cp
->cmd_cur
== cp
->cmd_end
);
243 cp
->cmd_cur
= cp
->bo_size
- cp
->stolen
;
244 cp
->cmd_end
= cp
->cmd_cur
+ data_size
;
246 /* offset in cp->bo */
248 *bo_offset
= cp
->cmd_cur
* 4;
252 * Write a dword to the parser buffer. This function must be enclosed by
253 * ilo_cp_begin()/ilo_cp_steal() and ilo_cp_end().
256 ilo_cp_write(struct ilo_cp
*cp
, uint32_t val
)
258 assert(cp
->cmd_cur
< cp
->cmd_end
);
259 cp
->ptr
[cp
->cmd_cur
++] = val
;
263 * Write multiple dwords to the parser buffer.
266 ilo_cp_write_multi(struct ilo_cp
*cp
, const void *vals
, int num_vals
)
268 assert(cp
->cmd_cur
+ num_vals
<= cp
->cmd_end
);
269 memcpy(cp
->ptr
+ cp
->cmd_cur
, vals
, num_vals
* 4);
270 cp
->cmd_cur
+= num_vals
;
274 * Write a bo to the parser buffer. In addition to writing the offset of the
275 * bo to the buffer, it also emits a relocation.
278 ilo_cp_write_bo(struct ilo_cp
*cp
, uint32_t val
, struct intel_bo
*bo
,
279 uint32_t read_domains
, uint32_t write_domain
)
282 cp
->bo
->emit_reloc(cp
->bo
, cp
->cmd_cur
* 4,
283 bo
, val
, read_domains
, write_domain
);
285 ilo_cp_write(cp
, val
+ bo
->get_offset(bo
));
288 ilo_cp_write(cp
, val
);
293 * End a command. Every ilo_cp_begin() or ilo_cp_steal() must have a
294 * matching ilo_cp_end().
297 ilo_cp_end(struct ilo_cp
*cp
)
299 assert(cp
->cmd_cur
== cp
->cmd_end
);
303 * A variant of ilo_cp_steal() where the data are written via the returned
306 * \return ptr pointer where the data are written to. It is valid until any
307 * change is made to the parser.
310 ilo_cp_steal_ptr(struct ilo_cp
*cp
, const char *desc
,
311 int data_size
, int align
, uint32_t *bo_offset
)
315 ilo_cp_steal(cp
, desc
, data_size
, align
, bo_offset
);
317 ptr
= &cp
->ptr
[cp
->cmd_cur
];
318 cp
->cmd_cur
= cp
->cmd_end
;
325 #endif /* ILO_CP_H */