summaryrefslogtreecommitdiff
path: root/src/surface.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/surface.c')
-rw-r--r--src/surface.c74
1 files changed, 66 insertions, 8 deletions
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;