gen6_common.h revision 428d7b3d
1428d7b3dSmrg/*
2428d7b3dSmrg * Copyright © 2011-2013 Intel Corporation
3428d7b3dSmrg *
4428d7b3dSmrg * Permission is hereby granted, free of charge, to any person obtaining a
5428d7b3dSmrg * copy of this software and associated documentation files (the "Software"),
6428d7b3dSmrg * to deal in the Software without restriction, including without limitation
7428d7b3dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8428d7b3dSmrg * and/or sell copies of the Software, and to permit persons to whom the
9428d7b3dSmrg * Software is furnished to do so, subject to the following conditions:
10428d7b3dSmrg *
11428d7b3dSmrg * The above copyright notice and this permission notice (including the next
12428d7b3dSmrg * paragraph) shall be included in all copies or substantial portions of the
13428d7b3dSmrg * Software.
14428d7b3dSmrg *
15428d7b3dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16428d7b3dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17428d7b3dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18428d7b3dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19428d7b3dSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20428d7b3dSmrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21428d7b3dSmrg * SOFTWARE.
22428d7b3dSmrg *
23428d7b3dSmrg * Authors:
24428d7b3dSmrg *    Chris Wilson <chris@chris-wilson.co.uk>
25428d7b3dSmrg *
26428d7b3dSmrg */
27428d7b3dSmrg
28428d7b3dSmrg#ifndef GEN6_COMMON_H
29428d7b3dSmrg#define GEN6_COMMON_H
30428d7b3dSmrg
31428d7b3dSmrg#include "sna.h"
32428d7b3dSmrg
33428d7b3dSmrg#define NO_RING_SWITCH 0
34428d7b3dSmrg#define PREFER_RENDER 0
35428d7b3dSmrg
36428d7b3dSmrgstatic inline bool is_uncached(struct sna *sna,
37428d7b3dSmrg			       struct kgem_bo *bo)
38428d7b3dSmrg{
39428d7b3dSmrg	return bo->io || (bo->scanout && !sna->kgem.has_wt);
40428d7b3dSmrg}
41428d7b3dSmrg
42428d7b3dSmrginline static bool can_switch_to_blt(struct sna *sna,
43428d7b3dSmrg				     struct kgem_bo *bo,
44428d7b3dSmrg				     unsigned flags)
45428d7b3dSmrg{
46428d7b3dSmrg	if (sna->kgem.ring != KGEM_RENDER)
47428d7b3dSmrg		return true;
48428d7b3dSmrg
49428d7b3dSmrg	if (NO_RING_SWITCH)
50428d7b3dSmrg		return false;
51428d7b3dSmrg
52428d7b3dSmrg	if (!sna->kgem.has_semaphores)
53428d7b3dSmrg		return false;
54428d7b3dSmrg
55428d7b3dSmrg	if (flags & COPY_LAST)
56428d7b3dSmrg		return true;
57428d7b3dSmrg
58428d7b3dSmrg	if (bo && RQ_IS_BLT(bo->rq))
59428d7b3dSmrg		return true;
60428d7b3dSmrg
61428d7b3dSmrg	if (sna->render_state.gt < 2)
62428d7b3dSmrg		return true;
63428d7b3dSmrg
64428d7b3dSmrg	return kgem_ring_is_idle(&sna->kgem, KGEM_BLT);
65428d7b3dSmrg}
66428d7b3dSmrg
67428d7b3dSmrginline static bool can_switch_to_render(struct sna *sna,
68428d7b3dSmrg					struct kgem_bo *bo)
69428d7b3dSmrg{
70428d7b3dSmrg	if (sna->kgem.ring == KGEM_RENDER)
71428d7b3dSmrg		return true;
72428d7b3dSmrg
73428d7b3dSmrg	if (NO_RING_SWITCH)
74428d7b3dSmrg		return false;
75428d7b3dSmrg
76428d7b3dSmrg	if (!sna->kgem.has_semaphores)
77428d7b3dSmrg		return false;
78428d7b3dSmrg
79428d7b3dSmrg	if (bo && !RQ_IS_BLT(bo->rq) && !is_uncached(sna, bo))
80428d7b3dSmrg		return true;
81428d7b3dSmrg
82428d7b3dSmrg	return !kgem_ring_is_idle(&sna->kgem, KGEM_RENDER);
83428d7b3dSmrg}
84428d7b3dSmrg
85428d7b3dSmrgstatic inline bool untiled_tlb_miss(struct kgem_bo *bo)
86428d7b3dSmrg{
87428d7b3dSmrg	if (kgem_bo_is_render(bo))
88428d7b3dSmrg		return false;
89428d7b3dSmrg
90428d7b3dSmrg	return bo->tiling == I915_TILING_NONE && bo->pitch >= 4096;
91428d7b3dSmrg}
92428d7b3dSmrg
93428d7b3dSmrgstatic int prefer_blt_bo(struct sna *sna, struct kgem_bo *bo)
94428d7b3dSmrg{
95428d7b3dSmrg	if (PREFER_RENDER)
96428d7b3dSmrg		return PREFER_RENDER < 0;
97428d7b3dSmrg
98428d7b3dSmrg	if (bo->rq)
99428d7b3dSmrg		return RQ_IS_BLT(bo->rq);
100428d7b3dSmrg
101428d7b3dSmrg	if (sna->flags & SNA_POWERSAVE)
102428d7b3dSmrg		return true;
103428d7b3dSmrg
104428d7b3dSmrg	return bo->tiling == I915_TILING_NONE || is_uncached(sna, bo);
105428d7b3dSmrg}
106428d7b3dSmrg
107428d7b3dSmrginline static bool force_blt_ring(struct sna *sna)
108428d7b3dSmrg{
109428d7b3dSmrg	if (sna->flags & SNA_POWERSAVE)
110428d7b3dSmrg		return true;
111428d7b3dSmrg
112428d7b3dSmrg	if (sna->kgem.mode == KGEM_RENDER)
113428d7b3dSmrg		return false;
114428d7b3dSmrg
115428d7b3dSmrg	if (sna->render_state.gt < 2)
116428d7b3dSmrg		return true;
117428d7b3dSmrg
118428d7b3dSmrg	return false;
119428d7b3dSmrg}
120428d7b3dSmrg
121428d7b3dSmrginline static bool prefer_blt_ring(struct sna *sna,
122428d7b3dSmrg				   struct kgem_bo *bo,
123428d7b3dSmrg				   unsigned flags)
124428d7b3dSmrg{
125428d7b3dSmrg	if (PREFER_RENDER)
126428d7b3dSmrg		return PREFER_RENDER < 0;
127428d7b3dSmrg
128428d7b3dSmrg	assert(!force_blt_ring(sna));
129428d7b3dSmrg	assert(!kgem_bo_is_render(bo));
130428d7b3dSmrg
131428d7b3dSmrg	return can_switch_to_blt(sna, bo, flags);
132428d7b3dSmrg}
133428d7b3dSmrg
134428d7b3dSmrginline static bool prefer_render_ring(struct sna *sna,
135428d7b3dSmrg				      struct kgem_bo *bo)
136428d7b3dSmrg{
137428d7b3dSmrg	if (sna->flags & SNA_POWERSAVE)
138428d7b3dSmrg		return false;
139428d7b3dSmrg
140428d7b3dSmrg	if (sna->render_state.gt < 2)
141428d7b3dSmrg		return false;
142428d7b3dSmrg
143428d7b3dSmrg	return can_switch_to_render(sna, bo);
144428d7b3dSmrg}
145428d7b3dSmrg
146428d7b3dSmrginline static bool
147428d7b3dSmrgprefer_blt_composite(struct sna *sna, struct sna_composite_op *tmp)
148428d7b3dSmrg{
149428d7b3dSmrg	if (PREFER_RENDER)
150428d7b3dSmrg		return PREFER_RENDER < 0;
151428d7b3dSmrg
152428d7b3dSmrg	if (untiled_tlb_miss(tmp->dst.bo) ||
153428d7b3dSmrg	    untiled_tlb_miss(tmp->src.bo))
154428d7b3dSmrg		return true;
155428d7b3dSmrg
156428d7b3dSmrg	if (force_blt_ring(sna))
157428d7b3dSmrg		return true;
158428d7b3dSmrg
159428d7b3dSmrg	if (kgem_bo_is_render(tmp->dst.bo) ||
160428d7b3dSmrg	    kgem_bo_is_render(tmp->src.bo))
161428d7b3dSmrg		return false;
162428d7b3dSmrg
163428d7b3dSmrg	if (prefer_render_ring(sna, tmp->dst.bo))
164428d7b3dSmrg		return false;
165428d7b3dSmrg
166428d7b3dSmrg	if (!prefer_blt_ring(sna, tmp->dst.bo, 0))
167428d7b3dSmrg		return false;
168428d7b3dSmrg
169428d7b3dSmrg	return prefer_blt_bo(sna, tmp->dst.bo) || prefer_blt_bo(sna, tmp->src.bo);
170428d7b3dSmrg}
171428d7b3dSmrg
172428d7b3dSmrgstatic inline bool prefer_blt_fill(struct sna *sna,
173428d7b3dSmrg				   struct kgem_bo *bo,
174428d7b3dSmrg				   unsigned flags)
175428d7b3dSmrg{
176428d7b3dSmrg	if (PREFER_RENDER)
177428d7b3dSmrg		return PREFER_RENDER < 0;
178428d7b3dSmrg
179428d7b3dSmrg	if (untiled_tlb_miss(bo))
180428d7b3dSmrg		return true;
181428d7b3dSmrg
182428d7b3dSmrg	if (force_blt_ring(sna))
183428d7b3dSmrg		return true;
184428d7b3dSmrg
185428d7b3dSmrg	if ((flags & (FILL_POINTS | FILL_SPANS)) == 0) {
186428d7b3dSmrg		if (kgem_bo_is_render(bo))
187428d7b3dSmrg			return false;
188428d7b3dSmrg
189428d7b3dSmrg		if (prefer_render_ring(sna, bo))
190428d7b3dSmrg			return false;
191428d7b3dSmrg
192428d7b3dSmrg		if (!prefer_blt_ring(sna, bo, 0))
193428d7b3dSmrg			return false;
194428d7b3dSmrg	} else {
195428d7b3dSmrg	    if (can_switch_to_blt(sna, bo, 0))
196428d7b3dSmrg		    return true;
197428d7b3dSmrg	}
198428d7b3dSmrg
199428d7b3dSmrg	return prefer_blt_bo(sna, bo);
200428d7b3dSmrg}
201428d7b3dSmrg
202428d7b3dSmrgvoid gen6_render_context_switch(struct kgem *kgem, int new_mode);
203428d7b3dSmrgvoid gen6_render_retire(struct kgem *kgem);
204428d7b3dSmrg
205428d7b3dSmrg#endif /* GEN6_COMMON_H */
206