@@ -539,6 +539,11 @@ unsigned long intel_get_fence_pitch(intel_screen_private *intel, unsigned long p
Bool intel_check_display_stride(ScrnInfoPtr scrn, int stride, Bool tiling);
void intel_set_gem_max_sizes(ScrnInfoPtr scrn);
+unsigned int
+intel_compute_size(struct intel_screen_private *intel,
+ int w, int h, int bpp, unsigned usage,
+ uint32_t *tiling, int *stride);
+
drm_intel_bo *intel_allocate_framebuffer(ScrnInfoPtr scrn,
int width, int height, int cpp,
int *out_stride,
@@ -190,3 +190,141 @@ void intel_set_gem_max_sizes(ScrnInfoPtr scrn)
*/
intel->max_bo_size = intel->max_gtt_map_size;
}
+
+unsigned int
+intel_compute_size(struct intel_screen_private *intel,
+ int w, int h, int bpp, unsigned usage,
+ uint32_t *tiling, int *stride)
+{
+ int pitch, size;
+
+ if (*tiling != I915_TILING_NONE) {
+ /* First check whether tiling is necessary. */
+ pitch = (w * bpp + 7) / 8;
+ pitch = ALIGN(pitch, 64);
+ size = pitch * ALIGN (h, 2);
+ if (INTEL_INFO(intel)->gen < 040) {
+ /* Gen 2/3 has a maximum stride for tiling of
+ * 8192 bytes.
+ */
+ if (pitch > KB(8))
+ *tiling = I915_TILING_NONE;
+
+ /* Narrower than half a tile? */
+ if (pitch < 256)
+ *tiling = I915_TILING_NONE;
+
+ /* Older hardware requires fences to be pot size
+ * aligned with a minimum of 1 MiB, so causes
+ * massive overallocation for small textures.
+ */
+ if (size < 1024*1024/2 && !intel->has_relaxed_fencing)
+ *tiling = I915_TILING_NONE;
+ } else if (!(usage & INTEL_CREATE_PIXMAP_DRI2) && size <= 4096) {
+ /* Disable tiling beneath a page size, we will not see
+ * any benefit from reducing TLB misses and instead
+ * just incur extra cost when we require a fence.
+ */
+ *tiling = I915_TILING_NONE;
+ }
+ }
+
+ pitch = (w * bpp + 7) / 8;
+ if (!(usage & INTEL_CREATE_PIXMAP_DRI2) && pitch <= 256)
+ *tiling = I915_TILING_NONE;
+
+ if (*tiling != I915_TILING_NONE) {
+ int aligned_h, tile_height;
+
+ if (IS_GEN2(intel))
+ tile_height = 16;
+ else if (*tiling == I915_TILING_X)
+ tile_height = 8;
+ else
+ tile_height = 32;
+ aligned_h = ALIGN(h, 2*tile_height);
+
+ *stride = intel_get_fence_pitch(intel,
+ ALIGN(pitch, 512),
+ *tiling);
+
+ /* Round the object up to the size of the fence it will live in
+ * if necessary. We could potentially make the kernel allocate
+ * a larger aperture space and just bind the subset of pages in,
+ * but this is easier and also keeps us out of trouble (as much)
+ * with drm_intel_bufmgr_check_aperture().
+ */
+ size = intel_get_fence_size(intel, *stride * aligned_h);
+
+ if (size > intel->max_tiling_size)
+ *tiling = I915_TILING_NONE;
+ }
+
+ if (*tiling == I915_TILING_NONE) {
+ /* We only require a 64 byte alignment for scanouts, but
+ * a 256 byte alignment for sharing with PRIME.
+ */
+ *stride = ALIGN(pitch, 256);
+ /* Round the height up so that the GPU's access to a 2x2 aligned
+ * subspan doesn't address an invalid page offset beyond the
+ * end of the GTT.
+ */
+ size = *stride * ALIGN(h, 2);
+ }
+
+ return size;
+}
+
+drm_intel_bo *intel_allocate_framebuffer(ScrnInfoPtr scrn,
+ int width, int height, int cpp,
+ int *out_stride,
+ uint32_t *out_tiling)
+{
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+ uint32_t tiling;
+ int stride, size;
+ drm_intel_bo *bo;
+
+ intel_set_gem_max_sizes(scrn);
+
+ if (intel->tiling & INTEL_TILING_FB)
+ tiling = I915_TILING_X;
+ else
+ tiling = I915_TILING_NONE;
+
+retry:
+ size = intel_compute_size(intel,
+ width, height,
+ intel->cpp*8, 0,
+ &tiling, &stride);
+ if (!intel_check_display_stride(scrn, stride, tiling)) {
+ if (tiling != I915_TILING_NONE) {
+ tiling = I915_TILING_NONE;
+ goto retry;
+ }
+
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "Front buffer stride %d kB "
+ "exceeds display limit\n", stride / 1024);
+ return NULL;
+ }
+
+ bo = drm_intel_bo_alloc(intel->bufmgr, "front buffer", size, 0);
+ if (bo == NULL)
+ return FALSE;
+
+ if (tiling != I915_TILING_NONE)
+ drm_intel_bo_set_tiling(bo, &tiling, stride);
+
+ xf86DrvMsg(scrn->scrnIndex, X_INFO,
+ "Allocated new frame buffer %dx%d stride %d, %s\n",
+ width, height, stride,
+ tiling == I915_TILING_NONE ? "untiled" : "tiled");
+
+ drm_intel_bo_disable_reuse(bo);
+
+ *out_stride = stride;
+ *out_tiling = tiling;
+ return bo;
+}
+
@@ -155,142 +155,6 @@ intel_get_aperture_space(ScrnInfoPtr scrn, drm_intel_bo ** bo_table,
return TRUE;
}
-static unsigned int
-intel_uxa_compute_size(struct intel_screen_private *intel,
- int w, int h, int bpp, unsigned usage,
- uint32_t *tiling, int *stride)
-{
- int pitch, size;
-
- if (*tiling != I915_TILING_NONE) {
- /* First check whether tiling is necessary. */
- pitch = (w * bpp + 7) / 8;
- pitch = ALIGN(pitch, 64);
- size = pitch * ALIGN (h, 2);
- if (INTEL_INFO(intel)->gen < 040) {
- /* Gen 2/3 has a maximum stride for tiling of
- * 8192 bytes.
- */
- if (pitch > KB(8))
- *tiling = I915_TILING_NONE;
-
- /* Narrower than half a tile? */
- if (pitch < 256)
- *tiling = I915_TILING_NONE;
-
- /* Older hardware requires fences to be pot size
- * aligned with a minimum of 1 MiB, so causes
- * massive overallocation for small textures.
- */
- if (size < 1024*1024/2 && !intel->has_relaxed_fencing)
- *tiling = I915_TILING_NONE;
- } else if (!(usage & INTEL_CREATE_PIXMAP_DRI2) && size <= 4096) {
- /* Disable tiling beneath a page size, we will not see
- * any benefit from reducing TLB misses and instead
- * just incur extra cost when we require a fence.
- */
- *tiling = I915_TILING_NONE;
- }
- }
-
- pitch = (w * bpp + 7) / 8;
- if (!(usage & INTEL_CREATE_PIXMAP_DRI2) && pitch <= 256)
- *tiling = I915_TILING_NONE;
-
- if (*tiling != I915_TILING_NONE) {
- int aligned_h, tile_height;
-
- if (IS_GEN2(intel))
- tile_height = 16;
- else if (*tiling == I915_TILING_X)
- tile_height = 8;
- else
- tile_height = 32;
- aligned_h = ALIGN(h, 2*tile_height);
-
- *stride = intel_get_fence_pitch(intel,
- ALIGN(pitch, 512),
- *tiling);
-
- /* Round the object up to the size of the fence it will live in
- * if necessary. We could potentially make the kernel allocate
- * a larger aperture space and just bind the subset of pages in,
- * but this is easier and also keeps us out of trouble (as much)
- * with drm_intel_bufmgr_check_aperture().
- */
- size = intel_get_fence_size(intel, *stride * aligned_h);
-
- if (size > intel->max_tiling_size)
- *tiling = I915_TILING_NONE;
- }
-
- if (*tiling == I915_TILING_NONE) {
- /* We only require a 64 byte alignment for scanouts, but
- * a 256 byte alignment for sharing with PRIME.
- */
- *stride = ALIGN(pitch, 256);
- /* Round the height up so that the GPU's access to a 2x2 aligned
- * subspan doesn't address an invalid page offset beyond the
- * end of the GTT.
- */
- size = *stride * ALIGN(h, 2);
- }
-
- return size;
-}
-
-drm_intel_bo *intel_allocate_framebuffer(ScrnInfoPtr scrn,
- int width, int height, int cpp,
- int *out_stride,
- uint32_t *out_tiling)
-{
- intel_screen_private *intel = intel_get_screen_private(scrn);
- uint32_t tiling;
- int stride, size;
- drm_intel_bo *bo;
-
- if (intel->tiling & INTEL_TILING_FB)
- tiling = I915_TILING_X;
- else
- tiling = I915_TILING_NONE;
-
-retry:
- size = intel_uxa_compute_size(intel,
- width, height,
- intel->cpp*8, 0,
- &tiling, &stride);
- if (!intel_check_display_stride(scrn, stride, tiling)) {
- if (tiling != I915_TILING_NONE) {
- tiling = I915_TILING_NONE;
- goto retry;
- }
-
- xf86DrvMsg(scrn->scrnIndex, X_ERROR,
- "Front buffer stride %d kB "
- "exceeds display limit\n", stride / 1024);
- return NULL;
- }
-
- bo = drm_intel_bo_alloc(intel->bufmgr, "front buffer", size, 0);
- if (bo == NULL)
- return FALSE;
-
- if (tiling != I915_TILING_NONE)
- drm_intel_bo_set_tiling(bo, &tiling, stride);
-
- xf86DrvMsg(scrn->scrnIndex, X_INFO,
- "Allocated new frame buffer %dx%d stride %d, %s\n",
- width, height, stride,
- tiling == I915_TILING_NONE ? "untiled" : "tiled");
-
- drm_intel_bo_disable_reuse(bo);
-
- intel_set_gem_max_sizes(scrn);
- *out_stride = stride;
- *out_tiling = tiling;
- return bo;
-}
-
static Bool
intel_uxa_check_solid(DrawablePtr drawable, int alu, Pixel planemask)
{
@@ -906,10 +770,10 @@ static Bool intel_uxa_put_image(PixmapPtr pixmap,
dri_bo *bo;
/* Replace busy bo. */
- size = intel_uxa_compute_size(intel,
- w, h,
- pixmap->drawable.bitsPerPixel, pixmap->usage_hint,
- &tiling, &stride);
+ size = intel_compute_size(intel,
+ w, h,
+ pixmap->drawable.bitsPerPixel, pixmap->usage_hint,
+ &tiling, &stride);
if (size > intel->max_gtt_map_size)
return FALSE;
@@ -1169,9 +1033,9 @@ intel_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth,
if (h <= 16 && tiling == I915_TILING_Y)
tiling = I915_TILING_X;
}
- size = intel_uxa_compute_size(intel,
- w, h, pixmap->drawable.bitsPerPixel, usage,
- &tiling, &stride);
+ size = intel_compute_size(intel,
+ w, h, pixmap->drawable.bitsPerPixel, usage,
+ &tiling, &stride);
/* Fail very large allocations. Large BOs will tend to hit SW fallbacks
* frequently, and also will tend to fail to successfully map when doing
@@ -1324,10 +1188,10 @@ intel_uxa_share_pixmap_backing(PixmapPtr ppix, ScreenPtr slave, void **fd_handle
tiling = I915_TILING_NONE;
- size = intel_uxa_compute_size(intel,
- ppix->drawable.width, ppix->drawable.height,
- ppix->drawable.bitsPerPixel, INTEL_CREATE_PIXMAP_DRI2,
- &tiling, &stride);
+ size = intel_compute_size(intel,
+ ppix->drawable.width, ppix->drawable.height,
+ ppix->drawable.bitsPerPixel, INTEL_CREATE_PIXMAP_DRI2,
+ &tiling, &stride);
newbo = drm_intel_bo_alloc_for_render(intel->bufmgr,
"pixmap",
UXA and Glamor both share this function, so move it out of the UXA file. Signed-off-by: Keith Packard <keithp@keithp.com> --- src/uxa/intel.h | 5 ++ src/uxa/intel_memory.c | 138 ++++++++++++++++++++++++++++++++++++++++++ src/uxa/intel_uxa.c | 158 ++++--------------------------------------------- 3 files changed, 154 insertions(+), 147 deletions(-)