sna: Allow CPU access to scanouts if WT cached
On Iris, we may store the framebuffer in the eLLC/LLC and mark it as being Write-Through cached. This means that we can treat it as being cached for read accesses (either by the GPU or CPU), but must be careful to still not write directly to the scanout with the CPU (only the GPU writes are cached and coherent with the display). Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
cdbc097796
commit
493763301e
10
configure.ac
10
configure.ac
|
|
@ -362,6 +362,16 @@ if test "x$ASYNC_SWAP" = xyes; then
|
|||
AC_DEFINE(USE_ASYNC_SWAP,1,[Assume asynchronous swap support])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(wt,
|
||||
AS_HELP_STRING([--enable-wt],
|
||||
[Enable use of WT cacheing (experimental) [default=no]]),
|
||||
[WT="$enableval"],
|
||||
[WT=no])
|
||||
AM_CONDITIONAL(USE_WT, test x$WT = xyes)
|
||||
if test "x$WT" = xyes; then
|
||||
AC_DEFINE(USE_WT,1,[Assume WriteThrough cacheing support])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
AS_HELP_STRING([--enable-debug],
|
||||
[Enables internal debugging [default=no]]),
|
||||
|
|
|
|||
|
|
@ -2133,7 +2133,7 @@ static int prefer_blt_bo(struct sna *sna, struct kgem_bo *bo)
|
|||
if (bo->rq)
|
||||
return RQ_IS_BLT(bo->rq) ? 1 : -1;
|
||||
|
||||
return bo->tiling == I915_TILING_NONE || bo->scanout;
|
||||
return bo->tiling == I915_TILING_NONE || (bo->scanout && !sna->kgem.has_wt);
|
||||
}
|
||||
|
||||
inline static bool prefer_blt_ring(struct sna *sna,
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
|
|||
#define DBG_NO_PINNED_BATCHES 0
|
||||
#define DBG_NO_FAST_RELOC 0
|
||||
#define DBG_NO_HANDLE_LUT 0
|
||||
#define DBG_NO_WT 0
|
||||
#define DBG_DUMP 0
|
||||
|
||||
#define FORCE_MMAP_SYNC 0 /* ((1 << DOMAIN_CPU) | (1 << DOMAIN_GTT)) */
|
||||
|
|
@ -124,6 +125,7 @@ search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
|
|||
#define LOCAL_I915_PARAM_HAS_PINNED_BATCHES 24
|
||||
#define LOCAL_I915_PARAM_HAS_NO_RELOC 25
|
||||
#define LOCAL_I915_PARAM_HAS_HANDLE_LUT 26
|
||||
#define LOCAL_I915_PARAM_HAS_WT 27
|
||||
|
||||
#define LOCAL_I915_EXEC_IS_PINNED (1<<10)
|
||||
#define LOCAL_I915_EXEC_NO_RELOC (1<<11)
|
||||
|
|
@ -818,6 +820,18 @@ static bool test_has_handle_lut(struct kgem *kgem)
|
|||
return gem_param(kgem, LOCAL_I915_PARAM_HAS_HANDLE_LUT) > 0;
|
||||
}
|
||||
|
||||
static bool test_has_wt(struct kgem *kgem)
|
||||
{
|
||||
#if defined(USE_WT)
|
||||
if (DBG_NO_WT)
|
||||
return false;
|
||||
|
||||
return gem_param(kgem, LOCAL_I915_PARAM_HAS_WT) > 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool test_has_semaphores_enabled(struct kgem *kgem)
|
||||
{
|
||||
FILE *file;
|
||||
|
|
@ -1156,6 +1170,10 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen)
|
|||
DBG(("%s: has shared last-level-cache? %d\n", __FUNCTION__,
|
||||
kgem->has_llc));
|
||||
|
||||
kgem->has_wt = test_has_wt(kgem);
|
||||
DBG(("%s: has write-through cacheing for scanouts? %d\n", __FUNCTION__,
|
||||
kgem->has_wt));
|
||||
|
||||
kgem->has_cacheing = test_has_cacheing(kgem);
|
||||
DBG(("%s: has set-cache-level? %d\n", __FUNCTION__,
|
||||
kgem->has_cacheing));
|
||||
|
|
@ -4998,7 +5016,7 @@ void *kgem_bo_map__cpu(struct kgem *kgem, struct kgem_bo *bo)
|
|||
__FUNCTION__, bo->handle, bytes(bo), (int)__MAP_TYPE(bo->map)));
|
||||
assert(!bo->purged);
|
||||
assert(list_is_empty(&bo->list));
|
||||
assert(!bo->scanout);
|
||||
assert(!bo->scanout || kgem->has_wt);
|
||||
assert(bo->proxy == NULL);
|
||||
|
||||
if (IS_CPU_MAP(bo->map))
|
||||
|
|
@ -5047,6 +5065,7 @@ void *__kgem_bo_map__cpu(struct kgem *kgem, struct kgem_bo *bo)
|
|||
assert(!bo->purged);
|
||||
assert(list_is_empty(&bo->list));
|
||||
assert(bo->proxy == NULL);
|
||||
assert(!bo->scanout || kgem->has_wt);
|
||||
|
||||
if (IS_CPU_MAP(bo->map))
|
||||
return MAP(bo->map);
|
||||
|
|
@ -5186,6 +5205,7 @@ struct kgem_bo *kgem_create_map(struct kgem *kgem,
|
|||
void kgem_bo_sync__cpu(struct kgem *kgem, struct kgem_bo *bo)
|
||||
{
|
||||
DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
|
||||
assert(!bo->scanout);
|
||||
kgem_bo_submit(kgem, bo);
|
||||
|
||||
/* SHM pixmaps use proxies for subpage offsets */
|
||||
|
|
@ -5217,6 +5237,7 @@ void kgem_bo_sync__cpu(struct kgem *kgem, struct kgem_bo *bo)
|
|||
void kgem_bo_sync__cpu_full(struct kgem *kgem, struct kgem_bo *bo, bool write)
|
||||
{
|
||||
DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
|
||||
assert(!bo->scanout || (kgem->has_wt && !write));
|
||||
|
||||
if (write || bo->needs_flush)
|
||||
kgem_bo_submit(kgem, bo);
|
||||
|
|
|
|||
|
|
@ -179,6 +179,7 @@ struct kgem {
|
|||
uint32_t has_pinned_batches :1;
|
||||
uint32_t has_cacheing :1;
|
||||
uint32_t has_llc :1;
|
||||
uint32_t has_wt :1;
|
||||
uint32_t has_no_reloc :1;
|
||||
uint32_t has_handle_lut :1;
|
||||
|
||||
|
|
@ -577,7 +578,7 @@ static inline bool kgem_bo_can_map__cpu(struct kgem *kgem,
|
|||
struct kgem_bo *bo,
|
||||
bool write)
|
||||
{
|
||||
if (bo->scanout)
|
||||
if (bo->scanout && (!kgem->has_wt || write))
|
||||
return false;
|
||||
|
||||
if (kgem->has_llc)
|
||||
|
|
|
|||
|
|
@ -1412,7 +1412,7 @@ static inline bool has_coherent_map(struct sna *sna,
|
|||
if (!IS_CPU_MAP(bo->map))
|
||||
return true;
|
||||
|
||||
if (bo->tiling != I915_TILING_NONE)
|
||||
if (bo->tiling == I915_TILING_Y)
|
||||
return false;
|
||||
|
||||
return kgem_bo_can_map__cpu(&sna->kgem, bo, flags & MOVE_WRITE);
|
||||
|
|
@ -2183,7 +2183,8 @@ static inline bool region_inplace(struct sna *sna,
|
|||
}
|
||||
|
||||
if (priv->mapped) {
|
||||
DBG(("%s: yes, already mapped, continuiung\n", __FUNCTION__));
|
||||
DBG(("%s: %s, already mapped, continuing\n", __FUNCTION__,
|
||||
has_coherent_map(sna, priv->gpu_bo, flags) ? "yes" : "no"));
|
||||
return has_coherent_map(sna, priv->gpu_bo, flags);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue