summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac3
-rw-r--r--src/decoder.c48
-rw-r--r--src/host1x-pixelbuffer.c20
-rw-r--r--src/host1x.h6
-rw-r--r--src/presentation_queue_target.c5
-rw-r--r--src/surface.c74
-rw-r--r--src/surface_shared.c42
-rw-r--r--src/tegra_stream.c11
-rw-r--r--src/uapi/tegra-vde.h4
-rw-r--r--src/vdpau_tegra.h2
10 files changed, 189 insertions, 26 deletions
diff --git a/configure.ac b/configure.ac
index 03b5de6..1157598 100644
--- a/configure.ac
+++ b/configure.ac
@@ -9,6 +9,9 @@ AC_CONFIG_AUX_DIR(.)
AM_INIT_AUTOMAKE([foreign subdir-objects])
+# enable quiet compiles on automake 1.11
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
AM_DISABLE_STATIC
# Checks for programs.
diff --git a/src/decoder.c b/src/decoder.c
index 78f90a2..f27ec7e 100644
--- a/src/decoder.c
+++ b/src/decoder.c
@@ -53,7 +53,7 @@ static struct drm_tegra_bo *alloc_data(tegra_decoder *dec, void **map,
struct drm_tegra_bo *bo;
int ret;
- ret = drm_tegra_bo_new(&bo, dec->dev->drm, 0, size);
+ ret = drm_tegra_bo_new(&bo, dec->dev->drm, DRM_TEGRA_GEM_CONTIGUOUS, size);
if (ret < 0) {
return NULL;
@@ -66,13 +66,15 @@ static struct drm_tegra_bo *alloc_data(tegra_decoder *dec, void **map,
return NULL;
}
- ret = drm_tegra_bo_to_dmabuf(bo, (uint32_t *) dmabuf_fd);
+ ret = drm_tegra_bo_export(bo, 0);
if (ret < 0) {
drm_tegra_bo_unref(bo);
return NULL;
}
+ *dmabuf_fd = ret;
+
return bo;
}
@@ -174,6 +176,28 @@ static VdpStatus copy_bitstream_to_dmabuf(tegra_decoder *dec,
return VDP_STATUS_ERROR;
}
+static int setup_secure_data(tegra_decoder *dec, struct drm_tegra_bo **bop,
+ int *fdp)
+{
+ struct drm_tegra_bo *bo;
+ int err, fd;
+
+ err = drm_tegra_bo_new(&bo, dec->dev->drm, DRM_TEGRA_GEM_CONTIGUOUS, 4096);
+ if (err < 0)
+ return err;
+
+ fd = drm_tegra_bo_export(bo, 0);
+ if (fd < 0) {
+ drm_tegra_bo_unref(bo);
+ return fd;
+ }
+
+ *bop = bo;
+ *fdp = fd;
+
+ return 0;
+}
+
static int get_refs_sorted(struct tegra_vde_h264_frame *dpb_frames,
VdpReferenceFrameH264 const *referenceFrames,
int frame_num_wrap, int32_t max_frame_num,
@@ -371,7 +395,7 @@ static int get_slice_type(bitstream_reader *reader)
static VdpStatus tegra_decode_h264(tegra_decoder *dec, tegra_surface *surf,
VdpPictureInfoH264 const *info,
- int bitstream_data_fd,
+ int bitstream_data_fd, int secure_fd,
bitstream_reader *reader)
{
struct tegra_vde_h264_decoder_ctx ctx;
@@ -436,6 +460,8 @@ static VdpStatus tegra_decode_h264(tegra_decoder *dec, tegra_surface *surf,
ctx.bitstream_data_fd = bitstream_data_fd;
ctx.bitstream_data_offset = 0;
+ ctx.secure_fd = secure_fd;
+ ctx.secure_offset = 0;
ctx.dpb_frames_nb = 1 + refs_num;
ctx.dpb_frames_ptr = (uintptr_t) dpb_frames;
ctx.dpb_ref_frames_with_earlier_poc_nb = ref_frames_with_earlier_poc_num;
@@ -612,9 +638,9 @@ VdpStatus vdp_decoder_render(VdpDecoder decoder,
{
tegra_decoder *dec = get_decoder(decoder);
tegra_surface *orig, *surf = get_surface(target);
- struct drm_tegra_bo *bitstream_bo;
+ struct drm_tegra_bo *bitstream_bo, *secure_bo = NULL;
bitstream_reader bitstream_reader;
- int bitstream_data_fd;
+ int bitstream_data_fd, secure_fd = -1;
VdpStatus ret;
if (dec == NULL || surf == NULL) {
@@ -633,6 +659,14 @@ VdpStatus vdp_decoder_render(VdpDecoder decoder,
return ret;
}
+ ret = setup_secure_data(dec, &secure_bo, &secure_fd);
+ if (ret < 0) {
+ free_data(bitstream_bo, bitstream_data_fd);
+ put_surface(surf);
+ put_decoder(dec);
+ return VDP_STATUS_ERROR;
+ }
+
orig = surf;
surf = shared_surface_swap_video(surf);
@@ -642,9 +676,11 @@ VdpStatus vdp_decoder_render(VdpDecoder decoder,
}
ret = tegra_decode_h264(dec, surf, picture_info,
- bitstream_data_fd, &bitstream_reader);
+ bitstream_data_fd, secure_fd,
+ &bitstream_reader);
free_data(bitstream_bo, bitstream_data_fd);
+ free_data(secure_bo, secure_fd);
if (ret != VDP_STATUS_OK) {
put_surface(surf);
diff --git a/src/host1x-pixelbuffer.c b/src/host1x-pixelbuffer.c
index a201bd6..19bdf37 100644
--- a/src/host1x-pixelbuffer.c
+++ b/src/host1x-pixelbuffer.c
@@ -38,7 +38,7 @@ struct host1x_pixelbuffer *host1x_pixelbuffer_create(struct drm_tegra *drm,
enum layout_format layout)
{
struct host1x_pixelbuffer *pixbuf;
- uint32_t flags = 0;
+ uint32_t flags = DRM_TEGRA_GEM_CONTIGUOUS;
uint32_t y_size;
uint32_t uv_size;
uint32_t bo_size;
@@ -75,6 +75,24 @@ struct host1x_pixelbuffer *host1x_pixelbuffer_create(struct drm_tegra *drm,
if (layout == PIX_BUF_LAYOUT_TILED_16x16)
height = ALIGN(height, 16);
+ if (layout == PIX_BUF_LAYOUT_BLOCK_16BX2_ONE_GOB)
+ height = ALIGN(height, 16);
+
+ if (layout == PIX_BUF_LAYOUT_BLOCK_16BX2_TWO_GOB)
+ height = ALIGN(height, 32);
+
+ if (layout == PIX_BUF_LAYOUT_BLOCK_16BX2_FOUR_GOB)
+ height = ALIGN(height, 64);
+
+ if (layout == PIX_BUF_LAYOUT_BLOCK_16BX2_EIGHT_GOB)
+ height = ALIGN(height, 128);
+
+ if (layout == PIX_BUF_LAYOUT_BLOCK_16BX2_SIXTEEN_GOB)
+ height = ALIGN(height, 256);
+
+ if (layout == PIX_BUF_LAYOUT_BLOCK_16BX2_THIRTYTWO_GOB)
+ height = ALIGN(height, 512);
+
y_size = pitch * height;
uv_size = pitch_uv * height / 2;
diff --git a/src/host1x.h b/src/host1x.h
index 27d3839..26803f0 100644
--- a/src/host1x.h
+++ b/src/host1x.h
@@ -88,6 +88,12 @@ enum pixel_format {
enum layout_format {
PIX_BUF_LAYOUT_LINEAR,
PIX_BUF_LAYOUT_TILED_16x16,
+ PIX_BUF_LAYOUT_BLOCK_16BX2_ONE_GOB,
+ PIX_BUF_LAYOUT_BLOCK_16BX2_TWO_GOB,
+ PIX_BUF_LAYOUT_BLOCK_16BX2_FOUR_GOB,
+ PIX_BUF_LAYOUT_BLOCK_16BX2_EIGHT_GOB,
+ PIX_BUF_LAYOUT_BLOCK_16BX2_SIXTEEN_GOB,
+ PIX_BUF_LAYOUT_BLOCK_16BX2_THIRTYTWO_GOB,
};
struct host1x_csc_params {
diff --git a/src/presentation_queue_target.c b/src/presentation_queue_target.c
index 5240b6f..c946f87 100644
--- a/src/presentation_queue_target.c
+++ b/src/presentation_queue_target.c
@@ -74,16 +74,19 @@ static void pqt_update_dri_pixbuf(tegra_pqt *pqt)
DebugMsg("width %d height %d\n", width, height);
- err = drm_tegra_bo_from_name(&bo, dev->drm, buf[0].names[0], 0);
+ err = drm_tegra_bo_open(&bo, dev->drm, buf[0].names[0], 0);
if (err) {
return;
}
+ /* XXX */
+ /*
err = drm_tegra_bo_forbid_caching(bo);
if (err) {
drm_tegra_bo_unref(bo);
return;
}
+ */
pqt->dri_pixbuf = host1x_pixelbuffer_wrap(&bo, width, height,
buf[0].pitch[0], 0,
diff --git a/src/surface.c b/src/surface.c
index 69c4404..a8c6ddf 100644
--- a/src/surface.c
+++ b/src/surface.c
@@ -17,6 +17,8 @@
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include <drm_fourcc.h>
+
#include "vdpau_tegra.h"
static uint32_t get_unused_surface_id(void)
@@ -88,6 +90,9 @@ int alloc_surface_data(tegra_surface *surf)
uint32_t stride = ALIGN(width * 4, 16);
uint32_t *bo_flinks = NULL;
uint32_t *pitches = NULL;
+ uint32_t *offsets = NULL;
+ uint64_t *modifiers = NULL;
+ uint64_t modifier = DRM_FORMAT_MOD_LINEAR;
int ret;
if (!video) {
@@ -136,8 +141,39 @@ int alloc_surface_data(tegra_surface *surf)
}
if (video) {
+ enum layout_format layout = PIX_BUF_LAYOUT_LINEAR;
+
frame = surf->frame;
+ /* anything without gr2d supports block linear layout */
+ if (!dev->gr2d) {
+ if (height % 512 == 0) {
+ modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_THIRTYTWO_GOB;
+ layout = PIX_BUF_LAYOUT_BLOCK_16BX2_THIRTYTWO_GOB;
+ frame->block_height = 5;
+ } else if (height % 256 == 0) {
+ modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_SIXTEEN_GOB;
+ layout = PIX_BUF_LAYOUT_BLOCK_16BX2_SIXTEEN_GOB;
+ frame->block_height = 4;
+ } else if (height % 128 == 0) {
+ modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_EIGHT_GOB;
+ layout = PIX_BUF_LAYOUT_BLOCK_16BX2_EIGHT_GOB;
+ frame->block_height = 3;
+ } else if (height % 64 == 0) {
+ modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_FOUR_GOB;
+ layout = PIX_BUF_LAYOUT_BLOCK_16BX2_FOUR_GOB;
+ frame->block_height = 2;
+ } else if (height % 32 == 0) {
+ modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_TWO_GOB;
+ layout = PIX_BUF_LAYOUT_BLOCK_16BX2_TWO_GOB;
+ frame->block_height = 1;
+ } else {
+ modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_ONE_GOB;
+ layout = PIX_BUF_LAYOUT_BLOCK_16BX2_ONE_GOB;
+ frame->block_height = 0;
+ }
+ }
+
frame->y_fd = -1;
frame->cb_fd = -1;
frame->cr_fd = -1;
@@ -148,7 +184,7 @@ int alloc_surface_data(tegra_surface *surf)
ALIGN(width, 16),
ALIGN(width, 32) / 2,
PIX_BUF_FMT_YV12,
- PIX_BUF_LAYOUT_LINEAR);
+ layout);
if (pixbuf == NULL) {
ret = -ENOMEM;
goto err_cleanup;
@@ -160,12 +196,14 @@ int alloc_surface_data(tegra_surface *surf)
/* luma plane */
- ret = drm_tegra_bo_to_dmabuf(surf->y_bo, (uint32_t *) &frame->y_fd);
+ ret = drm_tegra_bo_export(surf->y_bo, 0);
if (ret < 0) {
goto err_cleanup;
}
+ frame->y_fd = ret;
+
ret = drm_tegra_bo_map(surf->y_bo, &surf->y_data);
if (ret < 0) {
@@ -174,12 +212,14 @@ int alloc_surface_data(tegra_surface *surf)
/* blue plane */
- ret = drm_tegra_bo_to_dmabuf(surf->cb_bo, (uint32_t *) &frame->cb_fd);
+ ret = drm_tegra_bo_export(surf->cb_bo, 0);
if (ret < 0) {
goto err_cleanup;
}
+ frame->cb_fd = ret;
+
ret = drm_tegra_bo_map(surf->cb_bo, &surf->cb_data);
if (ret < 0) {
@@ -191,12 +231,14 @@ int alloc_surface_data(tegra_surface *surf)
/* red plane */
- ret = drm_tegra_bo_to_dmabuf(surf->cr_bo, (uint32_t *) &frame->cr_fd);
+ ret = drm_tegra_bo_export(surf->cr_bo, 0);
if (ret < 0) {
goto err_cleanup;
}
+ frame->cr_fd = ret;
+
ret = drm_tegra_bo_map(surf->cr_bo, &surf->cr_data);
if (ret < 0) {
@@ -208,17 +250,19 @@ int alloc_surface_data(tegra_surface *surf)
/* aux stuff */
- ret = drm_tegra_bo_new(&surf->aux_bo, dev->drm, 0,
+ ret = drm_tegra_bo_new(&surf->aux_bo, dev->drm, DRM_TEGRA_GEM_CONTIGUOUS,
ALIGN(width, 16) * ALIGN(height, 16) / 4);
if (ret < 0) {
goto err_cleanup;
}
- ret = drm_tegra_bo_to_dmabuf(surf->aux_bo, (uint32_t *) &frame->aux_fd);
+ ret = drm_tegra_bo_export(surf->aux_bo, 0);
if (ret < 0) {
goto err_cleanup;
}
+
+ frame->aux_fd = ret;
}
if (output && !tegra_vdpau_force_dri) {
@@ -263,9 +307,23 @@ int alloc_surface_data(tegra_surface *surf)
goto err_cleanup;
}
- pitches = (uint32_t *) (xv_img->data + 12);
-
+ pitches = (uint32_t *)(xv_img->data + 16);
pitches[0] = pixbuf->pitch;
+ pitches[1] = 0;
+ pitches[2] = 0;
+ pitches[3] = 0;
+
+ offsets = (uint32_t *)(xv_img->data + 32);
+ offsets[0] = pixbuf->bo_offset[0];
+ offsets[1] = 0;
+ offsets[2] = 0;
+ offsets[3] = 0;
+
+ modifiers = (uint64_t *)(xv_img->data + 48);
+ modifiers[0] = modifier;
+ modifiers[1] = 0;
+ modifiers[2] = 0;
+ modifiers[3] = 0;
}
surf->pix = pix;
diff --git a/src/surface_shared.c b/src/surface_shared.c
index adc5741..89270a7 100644
--- a/src/surface_shared.c
+++ b/src/surface_shared.c
@@ -17,16 +17,20 @@
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include <drm_fourcc.h>
+
#include "vdpau_tegra.h"
static pthread_mutex_t shared_lock = PTHREAD_MUTEX_INITIALIZER;
static XvImage * create_video_xv(tegra_surface *video)
{
+ struct tegra_vde_h264_frame *frame = video->frame;
XvImage *xv_img;
uint32_t *bo_flinks;
uint32_t *pitches;
uint32_t *offsets;
+ uint64_t *modifiers, modifier;
if (tegra_vdpau_force_dri) {
return NULL;
@@ -39,6 +43,31 @@ static XvImage * create_video_xv(tegra_surface *video)
return NULL;
}
+ /* anything without gr2d supports block linear layout */
+ if (!video->dev->gr2d) {
+ if (video->height % 512 == 0) {
+ modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_THIRTYTWO_GOB;
+ frame->block_height = 5;
+ } else if (video->height % 256 == 0) {
+ modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_SIXTEEN_GOB;
+ frame->block_height = 4;
+ } else if (video->height % 128 == 0) {
+ modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_EIGHT_GOB;
+ frame->block_height = 3;
+ } else if (video->height % 64 == 0) {
+ modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_FOUR_GOB;
+ frame->block_height = 2;
+ } else if (video->height % 32 == 0) {
+ modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_TWO_GOB;
+ frame->block_height = 1;
+ } else {
+ modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_ONE_GOB;
+ frame->block_height = 0;
+ }
+ } else {
+ modifier = DRM_FORMAT_MOD_LINEAR;
+ }
+
xv_img->data = calloc(1, xv_img->data_size);
if (!xv_img->data) {
@@ -47,20 +76,29 @@ static XvImage * create_video_xv(tegra_surface *video)
}
bo_flinks = (uint32_t*) (xv_img->data + 0);
- pitches = (uint32_t*) (xv_img->data + 12);
- offsets = (uint32_t*) (xv_img->data + 24);
+ pitches = (uint32_t*) (xv_img->data + 16);
+ offsets = (uint32_t*) (xv_img->data + 32);
+ modifiers = (uint64_t*) (xv_img->data + 48);
drm_tegra_bo_get_name(video->y_bo, &bo_flinks[0]);
drm_tegra_bo_get_name(video->cb_bo, &bo_flinks[1]);
drm_tegra_bo_get_name(video->cr_bo, &bo_flinks[2]);
+ bo_flinks[3] = 0;
pitches[0] = video->pixbuf->pitch;
pitches[1] = video->pixbuf->pitch_uv;
pitches[2] = video->pixbuf->pitch_uv;
+ pitches[3] = 0;
offsets[0] = video->pixbuf->bo_offset[0];
offsets[1] = video->pixbuf->bo_offset[1];
offsets[2] = video->pixbuf->bo_offset[2];
+ offsets[3] = 0;
+
+ modifiers[0] = modifier;
+ modifiers[1] = modifier;
+ modifiers[2] = modifier;
+ modifiers[3] = 0;
return xv_img;
}
diff --git a/src/tegra_stream.c b/src/tegra_stream.c
index a623fa3..03b4f29 100644
--- a/src/tegra_stream.c
+++ b/src/tegra_stream.c
@@ -73,7 +73,6 @@ void tegra_stream_destroy(struct tegra_stream *stream)
int tegra_stream_flush(struct tegra_stream *stream)
{
- struct drm_tegra_fence *fence;
int result = 0;
if (!stream)
@@ -89,21 +88,19 @@ int tegra_stream_flush(struct tegra_stream *stream)
goto cleanup;
}
- result = drm_tegra_job_submit(stream->job, &fence);
+ result = drm_tegra_job_submit(stream->job, 1000);
if (result != 0) {
ErrorMsg("drm_tegra_job_submit() failed %d\n", result);
result = -1;
goto cleanup;
}
- result = drm_tegra_fence_wait_timeout(fence, 1000);
+ result = drm_tegra_job_wait(stream->job);
if (result != 0) {
ErrorMsg("drm_tegra_fence_wait_timeout() failed %d\n", result);
result = -1;
}
- drm_tegra_fence_free(fence);
-
cleanup:
drm_tegra_job_free(stream->job);
@@ -265,8 +262,8 @@ int tegra_stream_end(struct tegra_stream *stream)
return -1;
}
- ret = drm_tegra_pushbuf_sync(stream->buffer.pushbuf,
- DRM_TEGRA_SYNCPT_COND_OP_DONE);
+ ret = drm_tegra_pushbuf_sync(stream->buffer.pushbuf, 0, 1,
+ DRM_TEGRA_SYNC_COND_OP_DONE);
if (ret != 0) {
stream->status = TEGRADRM_STREAM_CONSTRUCTION_FAILED;
ErrorMsg("drm_tegra_pushbuf_sync() failed %d\n", ret);
diff --git a/src/uapi/tegra-vde.h b/src/uapi/tegra-vde.h
index 8502032..7ddb684 100644
--- a/src/uapi/tegra-vde.h
+++ b/src/uapi/tegra-vde.h
@@ -46,6 +46,7 @@ struct tegra_vde_h264_frame {
__u32 aux_offset;
__u32 frame_num;
__u32 flags;
+ __u32 block_height;
__u32 reserved;
} __attribute__((packed));
@@ -54,6 +55,9 @@ struct tegra_vde_h264_decoder_ctx {
__s32 bitstream_data_fd;
__u32 bitstream_data_offset;
+ __s32 secure_fd;
+ __u32 secure_offset;
+
__u64 dpb_frames_ptr;
__u8 dpb_frames_nb;
__u8 dpb_ref_frames_with_earlier_poc_nb;
diff --git a/src/vdpau_tegra.h b/src/vdpau_tegra.h
index c524eae..b0571b3 100644
--- a/src/vdpau_tegra.h
+++ b/src/vdpau_tegra.h
@@ -88,7 +88,7 @@
#define SURFACE_DATA_NEEDS_SYNC (1 << 2)
#define SURFACE_OUTPUT (1 << 3)
-#define PASSTHROUGH_DATA_SIZE 36
+#define PASSTHROUGH_DATA_SIZE 80
#define FOURCC_PASSTHROUGH_YV12 (('1' << 24) + ('2' << 16) + ('V' << 8) + 'Y')
#define FOURCC_PASSTHROUGH_XRGB565 (('1' << 24) + ('B' << 16) + ('G' << 8) + 'R')