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(sna) (!(sna)->kgem.has_semaphores) 34#define PREFER_RENDER 0 /* -1 -> BLT, 1 -> RENDER */ 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 (bo && RQ_IS_BLT(bo->rq)) 50 return true; 51 52 if (bo && bo->tiling == I915_TILING_Y) 53 return false; 54 55 if (bo && !kgem_bo_can_blt(&sna->kgem, bo)) 56 return false; 57 58 if (sna->render_state.gt < 2) 59 return true; 60 61 if (bo && RQ_IS_RENDER(bo->rq)) 62 return false; 63 64 if (NO_RING_SWITCH(sna)) 65 return false; 66 67 if (flags & COPY_LAST) 68 return true; 69 70 return kgem_ring_is_idle(&sna->kgem, KGEM_BLT); 71} 72 73static inline bool untiled_tlb_miss(struct kgem_bo *bo) 74{ 75 if (kgem_bo_is_render(bo)) 76 return false; 77 78 return bo->tiling == I915_TILING_NONE && bo->pitch >= 4096; 79} 80 81static int prefer_blt_bo(struct sna *sna, 82 struct kgem_bo *src, 83 struct kgem_bo *dst) 84{ 85 assert(dst != NULL); 86 87 if (PREFER_RENDER) 88 return PREFER_RENDER < 0; 89 90 if (dst->rq) 91 return RQ_IS_BLT(dst->rq); 92 93 if (sna->flags & SNA_POWERSAVE) 94 return true; 95 96 if (src) { 97 if (sna->render_state.gt > 1) 98 return false; 99 100 if (src->rq) 101 return RQ_IS_BLT(src->rq); 102 103 if (src->tiling == I915_TILING_Y) 104 return false; 105 } else { 106 if (sna->render_state.gt > 2) 107 return false; 108 } 109 110 if (sna->render_state.gt < 2) 111 return true; 112 113 return dst->tiling == I915_TILING_NONE || is_uncached(sna, dst); 114} 115 116inline static bool force_blt_ring(struct sna *sna, struct kgem_bo *bo) 117{ 118 if (sna->kgem.mode == KGEM_RENDER) 119 return false; 120 121 if (NO_RING_SWITCH(sna)) 122 return sna->kgem.ring == KGEM_BLT; 123 124 if (bo->tiling == I915_TILING_Y) 125 return false; 126 127 if (sna->flags & SNA_POWERSAVE) 128 return true; 129 130 if (sna->render_state.gt < 2) 131 return true; 132 133 return false; 134} 135 136nonnull inline static bool 137prefer_blt_ring(struct sna *sna, struct kgem_bo *bo, unsigned flags) 138{ 139 if (PREFER_RENDER) 140 return PREFER_RENDER < 0; 141 142 assert(!force_blt_ring(sna, bo)); 143 assert(!kgem_bo_is_render(bo) || NO_RING_SWITCH(sna)); 144 145 if (kgem_bo_is_blt(bo)) 146 return true; 147 148 return can_switch_to_blt(sna, bo, flags); 149} 150 151nonnull inline static bool 152prefer_render_ring(struct sna *sna, struct kgem_bo *bo) 153{ 154 if (sna->kgem.ring == KGEM_RENDER) 155 return true; 156 157 if (sna->kgem.ring != KGEM_NONE && NO_RING_SWITCH(sna)) 158 return false; 159 160 if (kgem_bo_is_render(bo)) 161 return true; 162 163 if (sna->flags & SNA_POWERSAVE) 164 return false; 165 166 if (!prefer_blt_bo(sna, NULL, bo)) 167 return true; 168 169 return !kgem_ring_is_idle(&sna->kgem, KGEM_RENDER); 170} 171 172inline static bool 173prefer_blt_composite(struct sna *sna, struct sna_composite_op *tmp) 174{ 175 if (PREFER_RENDER) 176 return PREFER_RENDER < 0; 177 178 if (untiled_tlb_miss(tmp->dst.bo) || 179 untiled_tlb_miss(tmp->src.bo)) 180 return true; 181 182 if (force_blt_ring(sna, tmp->dst.bo)) 183 return true; 184 185 if (prefer_render_ring(sna, tmp->dst.bo)) 186 return false; 187 188 if (!prefer_blt_ring(sna, tmp->dst.bo, 0)) 189 return false; 190 191 return prefer_blt_bo(sna, tmp->src.bo, tmp->dst.bo); 192} 193 194nonnull static inline bool 195prefer_blt_fill(struct sna *sna, struct kgem_bo *bo, unsigned flags) 196{ 197 if (PREFER_RENDER) 198 return PREFER_RENDER < 0; 199 200 if (untiled_tlb_miss(bo)) 201 return true; 202 203 if (force_blt_ring(sna, bo)) 204 return true; 205 206 if ((flags & (FILL_POINTS | FILL_SPANS)) == 0) { 207 if (prefer_render_ring(sna, bo)) 208 return false; 209 210 if (!prefer_blt_ring(sna, bo, 0)) 211 return false; 212 } else { 213 if (can_switch_to_blt(sna, bo, COPY_LAST)) 214 return true; 215 } 216 217 return prefer_blt_bo(sna, NULL, bo); 218} 219 220void gen6_render_context_switch(struct kgem *kgem, int new_mode); 221void gen6_render_retire(struct kgem *kgem); 222 223#endif /* GEN6_COMMON_H */ 224