summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTapani Pälli <tapani.palli@intel.com>2013-02-22 12:13:28 +0200
committerTapani Pälli <tapani.palli@intel.com>2013-03-01 10:59:42 +0200
commitf3c326e3a15df2b1d8e0387ab634ec29dafd7707 (patch)
treef9587d8a165b37a0d7b1dc49e8f7938f25dc2a8d
parent25d22516a6eb0991e1b1ec25d25785daf7100eff (diff)
downloadexternal_drm_gralloc-f3c326e3a15df2b1d8e0387ab634ec29dafd7707.zip
external_drm_gralloc-f3c326e3a15df2b1d8e0387ab634ec29dafd7707.tar.gz
external_drm_gralloc-f3c326e3a15df2b1d8e0387ab634ec29dafd7707.tar.bz2
gralloc: change copy api and fix copy function for intel
Patch extends current copy api, renames it blit and introduces src+dst coordinates to be able to implement partial blits and blits with offsets. Implementation must take care of hw specific restrictions with blits. Patch also fixes issues with the current intel_blit function. Current implementation does not select ring buffer and ends up queuing blit commands to the render ring. Patch starts to use drm_intel_bo_mrb_exec to be able to select blit ring and fixes the checks inside copy function. Change-Id: I05905e0b9c48fc2a55230212b676bfb8813a2b55 Signed-off-by: Tapani Pälli <tapani.palli@intel.com>
-rw-r--r--gralloc_drm_intel.c71
-rw-r--r--gralloc_drm_kms.c10
-rw-r--r--gralloc_drm_pipe.c27
-rw-r--r--gralloc_drm_priv.h9
4 files changed, 74 insertions, 43 deletions
diff --git a/gralloc_drm_intel.c b/gralloc_drm_intel.c
index 725334e..50293b9 100644
--- a/gralloc_drm_intel.c
+++ b/gralloc_drm_intel.c
@@ -130,7 +130,8 @@ batch_flush(struct intel_info *info)
ALOGE("failed to subdata batch");
goto fail;
}
- ret = drm_intel_bo_exec(info->batch_ibo, size, NULL, 0, 0);
+ ret = drm_intel_bo_mrb_exec(info->batch_ibo, size,
+ NULL, 0, 0, I915_EXEC_BLT);
if (ret) {
ALOGE("failed to exec batch");
goto fail;
@@ -236,10 +237,14 @@ static void intel_resolve_format(struct gralloc_drm_drv_t *drv,
}
}
-static void intel_copy(struct gralloc_drm_drv_t *drv,
+
+static void intel_blit(struct gralloc_drm_drv_t *drv,
struct gralloc_drm_bo_t *dst,
struct gralloc_drm_bo_t *src,
- short x1, short y1, short x2, short y2)
+ uint16_t dst_x1, uint16_t dst_y1,
+ uint16_t dst_x2, uint16_t dst_y2,
+ uint16_t src_x1, uint16_t src_y1,
+ uint16_t src_x2, uint16_t src_y2)
{
struct intel_info *info = (struct intel_info *) drv;
struct intel_buffer *dst_ib = (struct intel_buffer *) dst;
@@ -247,26 +252,36 @@ static void intel_copy(struct gralloc_drm_drv_t *drv,
drm_intel_bo *bo_table[3];
uint32_t cmd, br13, dst_pitch, src_pitch;
- if (dst->handle->width != src->handle->width ||
- dst->handle->height != src->handle->height ||
- dst->handle->stride != src->handle->stride ||
- dst->handle->format != src->handle->format) {
- ALOGE("copy between incompatible buffers");
+ /*
+ * XY_SRC_COPY_BLT_CMD does not support scaling,
+ * rectangle dimensions much match
+ */
+ if (src_x2 - src_x1 != dst_x2 - dst_x1 ||
+ src_y2 - src_y1 != dst_y2 - dst_y1) {
+ ALOGE("%s, src and dst rect must match", __func__);
return;
}
- if (x1 < 0)
- x1 = 0;
- if (y1 < 0)
- y1 = 0;
- if (x2 > dst->handle->width)
- x2 = dst->handle->width;
- if (y2 > dst->handle->height)
- y2 = dst->handle->height;
+ if (dst->handle->format != src->handle->format) {
+ ALOGE("%s, src and dst format must match", __func__);
+ return;
+ }
- if (x2 <= x1 || y2 <= y1)
+ /* nothing to blit */
+ if (src_x2 <= src_x1 || src_y2 <= src_y1)
return;
+ /* clamp x2, y2 to surface size */
+ if (src_x2 > src->handle->width)
+ src_x2 = src->handle->width;
+ if (src_y2 > src->handle->height)
+ src_y2 = src->handle->height;
+
+ if (dst_x2 > dst->handle->width)
+ dst_x2 = dst->handle->width;
+ if (dst_y2 > dst->handle->height)
+ dst_y2 = dst->handle->height;
+
bo_table[0] = info->batch_ibo;
bo_table[1] = src_ib->ibo;
bo_table[2] = dst_ib->ibo;
@@ -281,6 +296,14 @@ static void intel_copy(struct gralloc_drm_drv_t *drv,
dst_pitch = dst->handle->stride;
src_pitch = src->handle->stride;
+ /* Blit pitch must be dword-aligned. Otherwise, the hardware appears to
+ * drop the low bits.
+ */
+ if (src_pitch % 4 != 0 || dst_pitch % 4 != 0) {
+ ALOGE("%s, src and dst pitch must be dword aligned", __func__);
+ return;
+ }
+
switch (gralloc_drm_get_bpp(dst->handle->format)) {
case 1:
break;
@@ -292,7 +315,7 @@ static void intel_copy(struct gralloc_drm_drv_t *drv,
cmd |= XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB;
break;
default:
- ALOGE("copy with unsupported format");
+ ALOGE("%s, copy with unsupported format", __func__);
return;
}
@@ -313,12 +336,12 @@ static void intel_copy(struct gralloc_drm_drv_t *drv,
return;
batch_dword(info, cmd);
- batch_dword(info, br13 | dst_pitch);
- batch_dword(info, (y1 << 16) | x1);
- batch_dword(info, (y2 << 16) | x2);
+ batch_dword(info, br13 | (uint16_t)dst_pitch);
+ batch_dword(info, (dst_y1 << 16) | dst_x1);
+ batch_dword(info, (dst_y2 << 16) | dst_x2);
batch_reloc(info, dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER);
- batch_dword(info, (y1 << 16) | x1);
- batch_dword(info, src_pitch);
+ batch_dword(info, (src_y1 << 16) | src_x1);
+ batch_dword(info, (uint16_t)src_pitch);
batch_reloc(info, src, I915_GEM_DOMAIN_RENDER, 0);
if (info->gen >= 60) {
@@ -638,7 +661,7 @@ struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_intel(int fd)
info->base.free = intel_free;
info->base.map = intel_map;
info->base.unmap = intel_unmap;
- info->base.copy = intel_copy;
+ info->base.blit = intel_blit;
info->base.resolve_format = intel_resolve_format;
return &info->base;
diff --git a/gralloc_drm_kms.c b/gralloc_drm_kms.c
index 91e7e63..7c7a903 100644
--- a/gralloc_drm_kms.c
+++ b/gralloc_drm_kms.c
@@ -309,7 +309,10 @@ int gralloc_drm_bo_post(struct gralloc_drm_bo_t *bo)
dst = (drm->next_front) ?
drm->next_front :
drm->current_front;
- drm->drv->copy(drm->drv, dst, bo, 0, 0,
+ drm->drv->blit(drm->drv, dst, bo, 0, 0,
+ bo->handle->width,
+ bo->handle->height,
+ 0, 0,
bo->handle->width,
bo->handle->height);
bo = dst;
@@ -349,9 +352,12 @@ int gralloc_drm_bo_post(struct gralloc_drm_bo_t *bo)
break;
case DRM_SWAP_COPY:
drm_kms_wait_for_post(drm, 0);
- drm->drv->copy(drm->drv, drm->current_front,
+ drm->drv->blit(drm->drv, drm->current_front,
bo, 0, 0,
bo->handle->width,
+ bo->handle->height,
+ 0, 0,
+ bo->handle->width,
bo->handle->height);
if (drm->mode_quirk_vmwgfx)
ret = drmModeDirtyFB(drm->fd, drm->current_front->fb_id, &drm->clip, 1);
diff --git a/gralloc_drm_pipe.c b/gralloc_drm_pipe.c
index ee5c4c0..9987d52 100644
--- a/gralloc_drm_pipe.c
+++ b/gralloc_drm_pipe.c
@@ -285,10 +285,13 @@ static void pipe_unmap(struct gralloc_drm_drv_t *drv,
pthread_mutex_unlock(&pm->mutex);
}
-static void pipe_copy(struct gralloc_drm_drv_t *drv,
+static void pipe_blit(struct gralloc_drm_drv_t *drv,
struct gralloc_drm_bo_t *dst_bo,
struct gralloc_drm_bo_t *src_bo,
- short x1, short y1, short x2, short y2)
+ uint16_t dst_x1, uint16_t dst_y1,
+ uint16_t dst_x2, uint16_t dst_y2,
+ uint16_t src_x1, uint16_t src_y1,
+ uint16_t src_x2, uint16_t src_y2)
{
struct pipe_manager *pm = (struct pipe_manager *) drv;
struct pipe_buffer *dst = (struct pipe_buffer *) dst_bo;
@@ -303,19 +306,15 @@ static void pipe_copy(struct gralloc_drm_drv_t *drv,
return;
}
- if (x1 < 0)
- x1 = 0;
- if (y1 < 0)
- y1 = 0;
- if (x2 > dst_bo->handle->width)
- x2 = dst_bo->handle->width;
- if (y2 > dst_bo->handle->height)
- y2 = dst_bo->handle->height;
+ if (dst_x2 > dst_bo->handle->width)
+ dst_x2 = dst_bo->handle->width;
+ if (dst_y2 > dst_bo->handle->height)
+ dst_y2 = dst_bo->handle->height;
- if (x2 <= x1 || y2 <= y1)
+ if (src_x2 <= src_x1 || src_y2 <= src_y1)
return;
- u_box_2d(x1, y1, x2 - x1, y2 - y1, &src_box);
+ u_box_2d(src_x1, src_y1, src_x2 - src_x1, src_y2 - src_y1, &src_box);
pthread_mutex_lock(&pm->mutex);
@@ -330,7 +329,7 @@ static void pipe_copy(struct gralloc_drm_drv_t *drv,
}
pm->context->resource_copy_region(pm->context,
- dst->resource, 0, x1, y1, 0,
+ dst->resource, 0, dst_x1, dst_y1, 0,
src->resource, 0, &src_box);
pm->context->flush(pm->context, NULL);
@@ -562,7 +561,7 @@ struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_pipe(int fd, const char *na
pm->base.free = pipe_free;
pm->base.map = pipe_map;
pm->base.unmap = pipe_unmap;
- pm->base.copy = pipe_copy;
+ pm->base.blit = pipe_blit;
return &pm->base;
}
diff --git a/gralloc_drm_priv.h b/gralloc_drm_priv.h
index 66c6dbd..0ab4ea5 100644
--- a/gralloc_drm_priv.h
+++ b/gralloc_drm_priv.h
@@ -128,11 +128,14 @@ struct gralloc_drm_drv_t {
void (*unmap)(struct gralloc_drm_drv_t *drv,
struct gralloc_drm_bo_t *bo);
- /* copy between two bo's, used for DRM_SWAP_COPY */
- void (*copy)(struct gralloc_drm_drv_t *drv,
+ /* blit between two bo's, used for DRM_SWAP_COPY and general blitting */
+ void (*blit)(struct gralloc_drm_drv_t *drv,
struct gralloc_drm_bo_t *dst,
struct gralloc_drm_bo_t *src,
- short x1, short y1, short x2, short y2);
+ uint16_t dst_x1, uint16_t dst_y1,
+ uint16_t dst_x2, uint16_t dst_y2,
+ uint16_t src_x1, uint16_t src_y1,
+ uint16_t src_x2, uint16_t src_y2);
/* query component offsets, strides and handles for a format */
void (*resolve_format)(struct gralloc_drm_drv_t *drv,