diff options
Diffstat (limited to 'src/surface.c')
-rw-r--r-- | src/surface.c | 74 |
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; |