gen6_common.h revision 428d7b3d
1/*
2 * Copyright © 2011-2013 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Authors:
24 *    Chris Wilson <chris@chris-wilson.co.uk>
25 *
26 */
27
28#ifndef GEN6_COMMON_H
29#define GEN6_COMMON_H
30
31#include "sna.h"
32
33#define NO_RING_SWITCH 0
34#define PREFER_RENDER 0
35
36static inline bool is_uncached(struct sna *sna,
37			       struct kgem_bo *bo)
38{
39	return bo->io || (bo->scanout && !sna->kgem.has_wt);
40}
41
42inline static bool can_switch_to_blt(struct sna *sna,
43				     struct kgem_bo *bo,
44				     unsigned flags)
45{
46	if (sna->kgem.ring != KGEM_RENDER)
47		return true;
48
49	if (NO_RING_SWITCH)
50		return false;
51
52	if (!sna->kgem.has_semaphores)
53		return false;
54
55	if (flags & COPY_LAST)
56		return true;
57
58	if (bo && RQ_IS_BLT(bo->rq))
59		return true;
60
61	if (sna->render_state.gt < 2)
62		return true;
63
64	return kgem_ring_is_idle(&sna->kgem, KGEM_BLT);
65}
66
67inline static bool can_switch_to_render(struct sna *sna,
68					struct kgem_bo *bo)
69{
70	if (sna->kgem.ring == KGEM_RENDER)
71		return true;
72
73	if (NO_RING_SWITCH)
74		return false;
75
76	if (!sna->kgem.has_semaphores)
77		return false;
78
79	if (bo && !RQ_IS_BLT(bo->rq) && !is_uncached(sna, bo))
80		return true;
81
82	return !kgem_ring_is_idle(&sna->kgem, KGEM_RENDER);
83}
84
85static inline bool untiled_tlb_miss(struct kgem_bo *bo)
86{
87	if (kgem_bo_is_render(bo))
88		return false;
89
90	return bo->tiling == I915_TILING_NONE && bo->pitch >= 4096;
91}
92
93static int prefer_blt_bo(struct sna *sna, struct kgem_bo *bo)
94{
95	if (PREFER_RENDER)
96		return PREFER_RENDER < 0;
97
98	if (bo->rq)
99		return RQ_IS_BLT(bo->rq);
100
101	if (sna->flags & SNA_POWERSAVE)
102		return true;
103
104	return bo->tiling == I915_TILING_NONE || is_uncached(sna, bo);
105}
106
107inline static bool force_blt_ring(struct sna *sna)
108{
109	if (sna->flags & SNA_POWERSAVE)
110		return true;
111
112	if (sna->kgem.mode == KGEM_RENDER)
113		return false;
114
115	if (sna->render_state.gt < 2)
116		return true;
117
118	return false;
119}
120
121inline static bool prefer_blt_ring(struct sna *sna,
122				   struct kgem_bo *bo,
123				   unsigned flags)
124{
125	if (PREFER_RENDER)
126		return PREFER_RENDER < 0;
127
128	assert(!force_blt_ring(sna));
129	assert(!kgem_bo_is_render(bo));
130
131	return can_switch_to_blt(sna, bo, flags);
132}
133
134inline static bool prefer_render_ring(struct sna *sna,
135				      struct kgem_bo *bo)
136{
137	if (sna->flags & SNA_POWERSAVE)
138		return false;
139
140	if (sna->render_state.gt < 2)
141		return false;
142
143	return can_switch_to_render(sna, bo);
144}
145
146inline static bool
147prefer_blt_composite(struct sna *sna, struct sna_composite_op *tmp)
148{
149	if (PREFER_RENDER)
150		return PREFER_RENDER < 0;
151
152	if (untiled_tlb_miss(tmp->dst.bo) ||
153	    untiled_tlb_miss(tmp->src.bo))
154		return true;
155
156	if (force_blt_ring(sna))
157		return true;
158
159	if (kgem_bo_is_render(tmp->dst.bo) ||
160	    kgem_bo_is_render(tmp->src.bo))
161		return false;
162
163	if (prefer_render_ring(sna, tmp->dst.bo))
164		return false;
165
166	if (!prefer_blt_ring(sna, tmp->dst.bo, 0))
167		return false;
168
169	return prefer_blt_bo(sna, tmp->dst.bo) || prefer_blt_bo(sna, tmp->src.bo);
170}
171
172static inline bool prefer_blt_fill(struct sna *sna,
173				   struct kgem_bo *bo,
174				   unsigned flags)
175{
176	if (PREFER_RENDER)
177		return PREFER_RENDER < 0;
178
179	if (untiled_tlb_miss(bo))
180		return true;
181
182	if (force_blt_ring(sna))
183		return true;
184
185	if ((flags & (FILL_POINTS | FILL_SPANS)) == 0) {
186		if (kgem_bo_is_render(bo))
187			return false;
188
189		if (prefer_render_ring(sna, bo))
190			return false;
191
192		if (!prefer_blt_ring(sna, bo, 0))
193			return false;
194	} else {
195	    if (can_switch_to_blt(sna, bo, 0))
196		    return true;
197	}
198
199	return prefer_blt_bo(sna, bo);
200}
201
202void gen6_render_context_switch(struct kgem *kgem, int new_mode);
203void gen6_render_retire(struct kgem *kgem);
204
205#endif /* GEN6_COMMON_H */
206