surface format is nv12, then we need to convert yv12 to nv12 and then
copy
the converted data from image to surface. We can't use the existing
logic
where surface is destroyed and re-created with yv12 format.
v2 (chk): fix some compiler warnings and commit message
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com>
Signed-off-by: Christian König <christian.koe...@amd.com>
---
src/gallium/state_trackers/va/image.c | 34
+++++++++++++++++++++++++++-------
1 file changed, 27 insertions(+), 7 deletions(-)
diff --git a/src/gallium/state_trackers/va/image.c
b/src/gallium/state_trackers/va/image.c
index 1b956e3..0364556 100644
--- a/src/gallium/state_trackers/va/image.c
+++ b/src/gallium/state_trackers/va/image.c
@@ -471,7 +471,9 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID
surface, VAImageID image,
return VA_STATUS_ERROR_OPERATION_FAILED;
}
- if (format != surf->buffer->buffer_format) {
+ if ((format != surf->buffer->buffer_format) &&
+ ((format != PIPE_FORMAT_YV12) ||
(surf->buffer->buffer_format != PIPE_FORMAT_NV12)) &&
+ ((format != PIPE_FORMAT_IYUV) ||
(surf->buffer->buffer_format != PIPE_FORMAT_NV12))) {
struct pipe_video_buffer *tmp_buf;
struct pipe_video_buffer templat = surf->templat;
@@ -513,12 +515,30 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID
surface, VAImageID image,
unsigned width, height;
if (!views[i]) continue;
vlVaVideoSurfaceSize(surf, i, &width, &height);
- for (j = 0; j < views[i]->texture->array_size; ++j) {
- struct pipe_box dst_box = {0, 0, j, width, height, 1};
- drv->pipe->transfer_inline_write(drv->pipe,
views[i]->texture, 0,
- PIPE_TRANSFER_WRITE, &dst_box,
- data[i] + pitches[i] * j,
- pitches[i] * views[i]->texture->array_size, 0);
+ if (((format == PIPE_FORMAT_YV12) || (format ==
PIPE_FORMAT_IYUV)) &&
+ (surf->buffer->buffer_format == PIPE_FORMAT_NV12)) {
+ struct pipe_transfer *transfer = NULL;
+ uint8_t *map = NULL;
+ struct pipe_box dst_box_1 = {0, 0, 0, width, height, 1};
+ map = drv->pipe->transfer_map(drv->pipe,
+ views[i]->texture,
+ 0,
+ PIPE_TRANSFER_DISCARD_RANGE,
+ &dst_box_1, &transfer);
+ if (map == NULL)
+ return VA_STATUS_ERROR_OPERATION_FAILED;
+
+ u_copy_yv12_img_to_nv12_surf ((ubyte * const*)data, map,
width, height,
+ pitches[i], transfer->stride, i);
+ pipe_transfer_unmap(drv->pipe, transfer);
+ } else {
+ for (j = 0; j < views[i]->texture->array_size; ++j) {
+ struct pipe_box dst_box = {0, 0, j, width, height, 1};
+ drv->pipe->transfer_inline_write(drv->pipe, views[i]->texture, 0,
+ PIPE_TRANSFER_WRITE, &dst_box,
+ data[i] + pitches[i] * j,
+ pitches[i] *
views[i]->texture->array_size, 0);
+ }
}
}
pipe_mutex_unlock(drv->mutex);