summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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,