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 "core/ilo_builder_mi.h"
29 #include "core/intel_winsys.h"
31 #include "ilo_shader.h"
34 static const struct ilo_cp_owner ilo_cp_default_owner
;
37 ilo_cp_release_owner(struct ilo_cp
*cp
)
39 if (cp
->owner
!= &ilo_cp_default_owner
) {
40 const struct ilo_cp_owner
*owner
= cp
->owner
;
42 cp
->owner
= &ilo_cp_default_owner
;
44 assert(ilo_cp_space(cp
) >= owner
->reserve
);
45 owner
->release(cp
, owner
->data
);
50 * Set the parser owner. If this is a new owner or a new ring, the old owner
51 * is released and the new owner's own() is called. The parser may implicitly
52 * submit if there is a ring change.
54 * own() is called before \p owner owns the parser. It must make sure there
55 * is more space than \p owner->reserve when it returns. Calling
56 * ilo_cp_submit() is allowed.
58 * release() will be called after \p owner loses the parser. That may happen
59 * just before the parser submits and ilo_cp_submit() is not allowed.
62 ilo_cp_set_owner(struct ilo_cp
*cp
, enum intel_ring_type ring
,
63 const struct ilo_cp_owner
*owner
)
66 owner
= &ilo_cp_default_owner
;
68 if (cp
->ring
!= ring
) {
69 ilo_cp_submit(cp
, "ring change");
73 if (cp
->owner
!= owner
) {
74 ilo_cp_release_owner(cp
);
76 owner
->own(cp
, owner
->data
);
78 assert(ilo_cp_space(cp
) >= owner
->reserve
);
83 static struct intel_bo
*
84 ilo_cp_end_batch(struct ilo_cp
*cp
, unsigned *used
)
88 ilo_cp_release_owner(cp
);
90 if (!ilo_builder_batch_used(&cp
->builder
)) {
91 ilo_builder_batch_discard(&cp
->builder
);
95 /* see ilo_cp_space() */
96 assert(ilo_builder_batch_space(&cp
->builder
) >= 2);
97 gen6_mi_batch_buffer_end(&cp
->builder
);
99 bo
= ilo_builder_end(&cp
->builder
, used
);
101 /* we have to assume that kernel uploads also failed */
103 ilo_shader_cache_invalidate(cp
->shader_cache
);
109 ilo_cp_detect_hang(struct ilo_cp
*cp
)
111 uint32_t active_lost
, pending_lost
;
114 if (likely(!(ilo_debug
& ILO_DEBUG_HANG
)))
117 /* wait and get reset stats */
118 if (intel_bo_wait(cp
->last_submitted_bo
, -1) ||
119 intel_winsys_get_reset_stats(cp
->winsys
, cp
->render_ctx
,
120 &active_lost
, &pending_lost
))
123 if (cp
->active_lost
!= active_lost
) {
124 ilo_err("GPU hang caused by bo %p\n", cp
->last_submitted_bo
);
125 cp
->active_lost
= active_lost
;
129 if (cp
->pending_lost
!= pending_lost
) {
130 ilo_err("GPU hang detected\n");
131 cp
->pending_lost
= pending_lost
;
138 * Flush the command parser and execute the commands. When the parser buffer
139 * is empty, the callback is not invoked.
142 ilo_cp_submit_internal(struct ilo_cp
*cp
)
144 const bool do_exec
= !(ilo_debug
& ILO_DEBUG_NOHW
);
149 bo
= ilo_cp_end_batch(cp
, &used
);
153 if (likely(do_exec
)) {
154 err
= intel_winsys_submit_bo(cp
->winsys
, cp
->ring
,
155 bo
, used
, cp
->render_ctx
, cp
->one_off_flags
);
161 cp
->one_off_flags
= 0;
166 intel_bo_unref(cp
->last_submitted_bo
);
167 cp
->last_submitted_bo
= intel_bo_ref(bo
);
169 guilty
= ilo_cp_detect_hang(cp
);
171 if (unlikely((ilo_debug
& ILO_DEBUG_BATCH
) || guilty
)) {
172 ilo_builder_decode(&cp
->builder
);
177 if (cp
->submit_callback
)
178 cp
->submit_callback(cp
, cp
->submit_callback_data
);
181 ilo_builder_begin(&cp
->builder
);
185 * Destroy the command parser.
188 ilo_cp_destroy(struct ilo_cp
*cp
)
190 ilo_builder_reset(&cp
->builder
);
192 intel_winsys_destroy_context(cp
->winsys
, cp
->render_ctx
);
197 * Create a command parser.
200 ilo_cp_create(const struct ilo_dev
*dev
,
201 struct intel_winsys
*winsys
,
202 struct ilo_shader_cache
*shc
)
206 cp
= CALLOC_STRUCT(ilo_cp
);
211 cp
->shader_cache
= shc
;
212 cp
->render_ctx
= intel_winsys_create_context(winsys
);
213 if (!cp
->render_ctx
) {
218 cp
->ring
= INTEL_RING_RENDER
;
219 cp
->owner
= &ilo_cp_default_owner
;
221 ilo_builder_init(&cp
->builder
, dev
, winsys
);
223 if (!ilo_builder_begin(&cp
->builder
)) {