summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2018-05-04 17:58:42 +0200
committerThierry Reding <treding@nvidia.com>2018-05-04 17:58:42 +0200
commit09b01bee078e4ac287c673dfa2b365d3de158213 (patch)
treeb2b9d231ae3467d04b09d3a36043f85eb9ae2cfc
parent7a2aff8cfd90ceda583fbce8d79a65a76289d99d (diff)
Add support for Tegra124tegra124
Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--src/dri2.c2
-rw-r--r--src/drm_plane.c81
-rw-r--r--src/drm_plane.h3
-rw-r--r--src/drmmode_display.h4
-rw-r--r--src/exa.c54
-rw-r--r--src/gr3d.c4
-rw-r--r--src/tegra_stream.c91
-rw-r--r--src/tegra_stream.h16
-rw-r--r--src/xv.c28
-rw-r--r--src/xv.h2
10 files changed, 174 insertions, 111 deletions
diff --git a/src/dri2.c b/src/dri2.c
index c734dc7..b2f3dc6 100644
--- a/src/dri2.c
+++ b/src/dri2.c
@@ -183,7 +183,9 @@ tegra_dri2_create_buffer(DrawablePtr drawable, unsigned int attachment,
return NULL;
}
+ /*
drm_tegra_bo_forbid_caching(tegra->bo);
+ */
buffer->pitch = pixmap->devKind;
buffer->driverPrivate = private;
diff --git a/src/drm_plane.c b/src/drm_plane.c
index 0e57853..9de5214 100644
--- a/src/drm_plane.c
+++ b/src/drm_plane.c
@@ -24,8 +24,6 @@
#include "driver.h"
-#define FD_INVALID UINT32_MAX
-
#define MUNMAP_VERBOSE(PTR, SIZE) \
if (PTR && munmap(PTR, page_align(SIZE)) != 0) \
FatalError("%s: " #PTR " munmap failed: %s\n", \
@@ -158,7 +156,7 @@ static uint32_t create_gem(int drm_fd, uint32_t size)
if (ret) {
ErrorMsg("Failed to create GEM[0]: %s\n", strerror(-ret));
- return FD_INVALID;
+ return 0;
}
return gem.handle;
@@ -178,70 +176,84 @@ static void close_gem(int drm_fd, uint32_t handle)
static drm_overlay_fb * drm_create_fb_internal(int drm_fd, uint32_t drm_format,
uint32_t width, uint32_t height,
- uint32_t *bo_handles,
+ uint32_t *handles,
uint32_t *pitches,
- uint32_t *offsets)
+ uint32_t *offsets,
+ uint64_t *modifiers)
{
drm_overlay_fb *fb = NULL;
- uint32_t fb_id = FD_INVALID;
+ uint32_t fb_id = 0;
Bool from_handle;
+ unsigned int i;
int ret;
if (width == 0 || height == 0)
return NULL;
- from_handle = !!(bo_handles);
+ from_handle = !!handles;
if (from_handle)
goto create_framebuffer;
- bo_handles = alloca(sizeof(uint32_t) * 3);
- if (!bo_handles)
+ handles = alloca(sizeof(uint32_t) * 4);
+ if (!handles)
return NULL;
- pitches = alloca(sizeof(uint32_t) * 3);
+ pitches = alloca(sizeof(uint32_t) * 4);
if (!pitches)
return NULL;
- offsets = alloca(sizeof(uint32_t) * 3);
+ offsets = alloca(sizeof(uint32_t) * 4);
if (!offsets)
return NULL;
pitches[0] = fb_pitch(drm_format, width);
pitches[1] = fb_pitch_c(drm_format, width);
pitches[2] = fb_pitch_c(drm_format, width);
+ pitches[3] = 0;
offsets[0] = 0;
offsets[1] = 0;
offsets[2] = 0;
+ offsets[3] = 0;
- bo_handles[1] = FD_INVALID;
- bo_handles[2] = FD_INVALID;
+ handles[0] = 0;
+ handles[1] = 0;
+ handles[2] = 0;
+ handles[3] = 0;
/* Allocate PLANE[0] */
- bo_handles[0] = create_gem(drm_fd, fb_size(drm_format, width, height));
+ handles[0] = create_gem(drm_fd, fb_size(drm_format, width, height));
- if (bo_handles[0] == FD_INVALID)
+ if (!handles[0])
goto error_cleanup;
if (!format_planar(drm_format))
goto create_framebuffer;
/* Allocate PLANE[1] */
- bo_handles[1] = create_gem(drm_fd, fb_size_c(drm_format, width, height));
+ handles[1] = create_gem(drm_fd, fb_size_c(drm_format, width, height));
- if (bo_handles[1] == FD_INVALID)
+ if (!handles[1])
goto error_cleanup;
/* Allocate PLANE[2] */
- bo_handles[2] = create_gem(drm_fd, fb_size_c(drm_format, width, height));
+ handles[2] = create_gem(drm_fd, fb_size_c(drm_format, width, height));
- if (bo_handles[2] == FD_INVALID)
+ if (!handles[2])
goto error_cleanup;
create_framebuffer:
- ret = drmModeAddFB2(drm_fd, width, height, drm_format,
- bo_handles, pitches, offsets, &fb_id, 0);
+ if (modifiers) {
+ ret = drmModeAddFB2WithModifiers(drm_fd, width, height, drm_format,
+ handles, pitches, offsets,
+ modifiers, &fb_id,
+ DRM_MODE_FB_MODIFIERS);
+ } else {
+ ret = drmModeAddFB2(drm_fd, width, height, drm_format, handles,
+ pitches, offsets, &fb_id, 0);
+ }
+
if (ret) {
ErrorMsg("Failed to create DRM framebuffer: %s\n", strerror(-ret));
goto error_cleanup;
@@ -253,9 +265,9 @@ create_framebuffer:
fb->format = drm_format;
fb->width = width;
fb->height = height;
- fb->bo_y_id = bo_handles[0];
- fb->bo_cb_id = bo_handles[1];
- fb->bo_cr_id = bo_handles[2];
+ fb->bo_y_id = handles[0];
+ fb->bo_cb_id = handles[1];
+ fb->bo_cr_id = handles[2];
if (from_handle)
return fb;
@@ -318,17 +330,13 @@ error_cleanup:
free(fb);
}
- if (fb_id != FD_INVALID)
+ if (fb_id)
drmModeRmFB(drm_fd, fb_id);
- if (bo_handles[2] != FD_INVALID)
- close_gem(drm_fd, bo_handles[2]);
-
- if (bo_handles[1] != FD_INVALID)
- close_gem(drm_fd, bo_handles[1]);
-
- if (bo_handles[0] != FD_INVALID)
- close_gem(drm_fd, bo_handles[0]);
+ for (i = 0; i < 3; i++) {
+ if (handles[2 - i])
+ close_gem(drm_fd, handles[i]);
+ }
return NULL;
}
@@ -337,17 +345,18 @@ drm_overlay_fb * drm_create_fb(int drm_fd, uint32_t drm_format,
uint32_t width, uint32_t height)
{
return drm_create_fb_internal(drm_fd, drm_format, width, height,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
}
drm_overlay_fb * drm_create_fb_from_handle(int drm_fd, uint32_t drm_format,
uint32_t width, uint32_t height,
uint32_t *bo_handles,
uint32_t *pitches,
- uint32_t *offsets)
+ uint32_t *offsets,
+ uint64_t *modifiers)
{
return drm_create_fb_internal(drm_fd, drm_format, width, height,
- bo_handles, pitches, offsets);
+ bo_handles, pitches, offsets, modifiers);
}
void drm_free_overlay_fb(int drm_fd, drm_overlay_fb *fb)
diff --git a/src/drm_plane.h b/src/drm_plane.h
index 1d61c53..35b345f 100644
--- a/src/drm_plane.h
+++ b/src/drm_plane.h
@@ -51,7 +51,8 @@ drm_overlay_fb * drm_create_fb_from_handle(int drm_fd, uint32_t drm_format,
uint32_t width, uint32_t height,
uint32_t *bo_handles,
uint32_t *pitches,
- uint32_t *offsets);
+ uint32_t *offsets,
+ uint64_t *modifiers);
void drm_free_overlay_fb(int drm_fd, drm_overlay_fb *fb);
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index 2aca7f6..2c552e5 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -37,6 +37,10 @@
# endif
#endif
+#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,14,99,2,0)
+# define DamageUnregister(d, dd) DamageUnregister(dd)
+#endif
+
struct dumb_bo {
struct drm_tegra_bo *bo;
uint32_t handle;
diff --git a/src/exa.c b/src/exa.c
index be22404..85a4b63 100644
--- a/src/exa.c
+++ b/src/exa.c
@@ -354,9 +354,9 @@ unsigned int TegraEXAPitch(unsigned int width, unsigned int height,
return TEGRA_PITCH_ALIGN(width, bpp, alignment);
}
-static void TegraEXAWaitFence(struct tegra_fence *fence)
+static void TegraEXAWaitFence(TegraEXAPtr tegra, struct tegra_fence *fence)
{
- if (tegra_stream_wait_fence(fence) && !fence->gr2d) {
+ if (tegra_stream_wait_fence(&tegra->cmds, fence) && !fence->gr2d) {
/*
* XXX: A bit more optimal would be to release buffers
* right after submitting the job, but then BO reservation
@@ -384,7 +384,7 @@ static int TegraEXAMarkSync(ScreenPtr pScreen)
* EXA may take marker multiple times, but it waits only for the
* lastly taken marker, so we release the previous marker-fence here.
*/
- tegra_stream_put_fence(tegra->scratch.marker);
+ tegra_stream_put_fence(&tegra->cmds, tegra->scratch.marker);
tegra->scratch.marker = data.fence;
return data.marker;
@@ -401,8 +401,8 @@ static void TegraEXAWaitMarker(ScreenPtr pScreen, int marker)
data.marker = marker;
- TegraEXAWaitFence(data.fence);
- tegra_stream_put_fence(data.fence);
+ TegraEXAWaitFence(tegra, data.fence);
+ tegra_stream_put_fence(&tegra->cmds, data.fence);
/* if it was a lastly-taken marker, then we've just released it */
if (data.fence == tegra->scratch.marker)
@@ -489,7 +489,7 @@ static Bool TegraEXAAllocateMem(TegraPixmapPtr pixmap, unsigned int size)
return pixmap->fallback != NULL;
}
-static void TegraEXAReleasePixmapData(TegraPixmapPtr priv)
+static void TegraEXAReleasePixmapData(TegraEXAPtr tegra, TegraPixmapPtr priv)
{
/*
* We have to await the fence to avoid BO re-use while job is in progress,
@@ -497,8 +497,8 @@ static void TegraEXAReleasePixmapData(TegraPixmapPtr priv)
* by kernel driver.
*/
if (priv->fence) {
- TegraEXAWaitFence(priv->fence);
- tegra_stream_put_fence(priv->fence);
+ TegraEXAWaitFence(tegra, priv->fence);
+ tegra_stream_put_fence(&tegra->cmds, priv->fence);
priv->fence = NULL;
}
@@ -568,9 +568,11 @@ static void *TegraEXACreatePixmap2(ScreenPtr pScreen, int width, int height,
static void TegraEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv)
{
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+ TegraEXAPtr tegra = TegraPTR(pScrn)->exa;
TegraPixmapPtr priv = driverPriv;
- TegraEXAReleasePixmapData(priv);
+ TegraEXAReleasePixmapData(tegra, priv);
free(priv);
}
@@ -590,7 +592,7 @@ static Bool TegraEXAModifyPixmapHeader(PixmapPtr pPixmap, int width,
return FALSE;
if (pPixData) {
- TegraEXAReleasePixmapData(priv);
+ TegraEXAReleasePixmapData(tegra->exa, priv);
if (pPixData == drmmode_map_front_bo(&tegra->drmmode)) {
scanout = drmmode_get_front_bo(&tegra->drmmode);
@@ -674,7 +676,7 @@ static void TegraEXASolid(PixmapPtr pPixmap,
tegra_stream_push(&tegra->cmds, HOST1X_OPCODE_MASK(0x38, 0x5));
tegra_stream_push(&tegra->cmds, (py2 - py1) << 16 | (px2 - px1));
tegra_stream_push(&tegra->cmds, py1 << 16 | px1);
- tegra_stream_sync(&tegra->cmds, DRM_TEGRA_SYNCPT_COND_OP_DONE);
+ tegra_stream_sync(&tegra->cmds, DRM_TEGRA_SYNC_COND_OP_DONE);
tegra->scratch.ops++;
}
@@ -688,13 +690,13 @@ static void TegraEXADoneSolid(PixmapPtr pPixmap)
if (tegra->scratch.ops && tegra->cmds.status == TEGRADRM_STREAM_CONSTRUCT) {
if (priv->fence && !priv->fence->gr2d)
- TegraEXAWaitFence(priv->fence);
+ TegraEXAWaitFence(tegra, priv->fence);
tegra_stream_end(&tegra->cmds);
fence = tegra_stream_submit(&tegra->cmds, true);
if (priv->fence != fence) {
- tegra_stream_put_fence(priv->fence);
+ tegra_stream_put_fence(&tegra->cmds, priv->fence);
priv->fence = tegra_stream_ref_fence(fence, &tegra->scratch);
}
} else {
@@ -808,7 +810,7 @@ static void TegraEXACopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX,
tegra_stream_push(&tegra->cmds, height << 16 | width); /* dstsize */
tegra_stream_push(&tegra->cmds, srcY << 16 | srcX); /* srcps */
tegra_stream_push(&tegra->cmds, dstY << 16 | dstX); /* dstps */
- tegra_stream_sync(&tegra->cmds, DRM_TEGRA_SYNCPT_COND_OP_DONE);
+ tegra_stream_sync(&tegra->cmds, DRM_TEGRA_SYNC_COND_OP_DONE);
tegra->scratch.ops++;
}
@@ -825,22 +827,22 @@ static void TegraEXADoneCopy(PixmapPtr pDstPixmap)
priv = exaGetPixmapDriverPrivate(tegra->scratch.pSrc);
if (priv->fence && !priv->fence->gr2d) {
- TegraEXAWaitFence(priv->fence);
+ TegraEXAWaitFence(tegra, priv->fence);
- tegra_stream_put_fence(priv->fence);
+ tegra_stream_put_fence(&tegra->cmds, priv->fence);
priv->fence = NULL;
}
}
priv = exaGetPixmapDriverPrivate(pDstPixmap);
if (priv->fence && !priv->fence->gr2d)
- TegraEXAWaitFence(priv->fence);
+ TegraEXAWaitFence(tegra, priv->fence);
tegra_stream_end(&tegra->cmds);
fence = tegra_stream_submit(&tegra->cmds, true);
if (priv->fence != fence) {
- tegra_stream_put_fence(priv->fence);
+ tegra_stream_put_fence(&tegra->cmds, priv->fence);
priv->fence = tegra_stream_ref_fence(fence, &tegra->scratch);
}
} else {
@@ -1443,9 +1445,9 @@ static void TegraEXADoneComposite(PixmapPtr pDst)
priv = exaGetPixmapDriverPrivate(tegra->scratch.pSrc);
if (priv->fence && priv->fence->gr2d) {
- TegraEXAWaitFence(priv->fence);
+ TegraEXAWaitFence(tegra, priv->fence);
- tegra_stream_put_fence(priv->fence);
+ tegra_stream_put_fence(&tegra->cmds, priv->fence);
priv->fence = NULL;
}
}
@@ -1454,16 +1456,16 @@ static void TegraEXADoneComposite(PixmapPtr pDst)
priv = exaGetPixmapDriverPrivate(tegra->scratch.pMask);
if (priv->fence && priv->fence->gr2d) {
- TegraEXAWaitFence(priv->fence);
+ TegraEXAWaitFence(tegra, priv->fence);
- tegra_stream_put_fence(priv->fence);
+ tegra_stream_put_fence(&tegra->cmds, priv->fence);
priv->fence = NULL;
}
}
priv = exaGetPixmapDriverPrivate(pDst);
if (priv->fence && priv->fence->gr2d)
- TegraEXAWaitFence(priv->fence);
+ TegraEXAWaitFence(tegra, priv->fence);
tegra_stream_end(&tegra->cmds);
fence = tegra_stream_submit(&tegra->cmds, false);
@@ -1480,7 +1482,7 @@ static void TegraEXADoneComposite(PixmapPtr pDst)
* See TegraGR3D_DrawPrimitives() in gr3d.c
*/
if (priv->fence != fence) {
- tegra_stream_put_fence(priv->fence);
+ tegra_stream_put_fence(&tegra->cmds, priv->fence);
priv->fence = tegra_stream_ref_fence(fence, &tegra->scratch);
}
} else {
@@ -1489,7 +1491,7 @@ static void TegraEXADoneComposite(PixmapPtr pDst)
/* buffer reallocation could fail, cleanup it now */
if (tegra->scratch.attribs_alloc_err) {
- tegra_stream_wait_fence(fence);
+ tegra_stream_wait_fence(&tegra->cmds, fence);
TegraCompositeReleaseAttribBuffers(&tegra->scratch);
tegra->scratch.attribs_alloc_err = FALSE;
}
@@ -1542,7 +1544,7 @@ void TegraEXAScreenInit(ScreenPtr pScreen)
goto close_gr2d;
}
- err = tegra_stream_create(&priv->cmds);
+ err = tegra_stream_create(&priv->cmds, tegra->drm);
if (err < 0) {
ErrorMsg("failed to create command stream: %d\n", err);
goto close_gr3d;
diff --git a/src/gr3d.c b/src/gr3d.c
index 9e8912d..29f2157 100644
--- a/src/gr3d.c
+++ b/src/gr3d.c
@@ -501,7 +501,7 @@ void TegraGR3D_DrawPrimitives(struct tegra_stream *cmds,
* XXX: This requires proper waitcheck barrier, expect graphical
* glitches due to not properly prefetched vertex / tex data.
*/
- tegra_stream_sync(cmds, DRM_TEGRA_SYNCPT_COND_RD_DONE);
+ tegra_stream_sync(cmds, DRM_TEGRA_SYNC_COND_RD_DONE);
tegra_stream_prep(cmds, 2);
@@ -511,7 +511,7 @@ void TegraGR3D_DrawPrimitives(struct tegra_stream *cmds,
tegra_stream_push(cmds, HOST1X_OPCODE_INCR(TGR3D_DRAW_PRIMITIVES, 1));
tegra_stream_push(cmds, value);
- tegra_stream_sync(cmds, DRM_TEGRA_SYNCPT_COND_OP_DONE);
+ tegra_stream_sync(cmds, DRM_TEGRA_SYNC_COND_OP_DONE);
}
static void TegraGR3D_UploadProgram(struct tegra_stream *cmds,
diff --git a/src/tegra_stream.c b/src/tegra_stream.c
index 92e5e6f..7f9b58f 100644
--- a/src/tegra_stream.c
+++ b/src/tegra_stream.c
@@ -25,6 +25,11 @@
* Arto Merilainen <amerilainen@nvidia.com>
*/
+#include <errno.h>
+#include <unistd.h>
+
+#include <sys/ioctl.h>
+
#include "xorg-server.h"
#include "xf86.h"
@@ -44,9 +49,10 @@
* tegra_stream_push().
*/
-int tegra_stream_create(struct tegra_stream *stream)
+int tegra_stream_create(struct tegra_stream *stream, struct drm_tegra *drm)
{
stream->status = TEGRADRM_STREAM_FREE;
+ stream->drm = drm;
return 0;
}
@@ -62,8 +68,8 @@ void tegra_stream_destroy(struct tegra_stream *stream)
if (!stream)
return;
- tegra_stream_wait_fence(stream->last_fence);
- tegra_stream_put_fence(stream->last_fence);
+ tegra_stream_wait_fence(stream, stream->last_fence);
+ tegra_stream_put_fence(stream, stream->last_fence);
drm_tegra_job_free(stream->job);
}
@@ -91,14 +97,13 @@ int tegra_stream_cleanup(struct tegra_stream *stream)
int tegra_stream_flush(struct tegra_stream *stream)
{
- struct drm_tegra_fence *fence;
int result = 0;
if (!stream)
return -1;
- tegra_stream_wait_fence(stream->last_fence);
- tegra_stream_put_fence(stream->last_fence);
+ tegra_stream_wait_fence(stream, stream->last_fence);
+ tegra_stream_put_fence(stream, stream->last_fence);
stream->last_fence = NULL;
/* Reflushing is fine */
@@ -111,21 +116,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);
+ ErrorMsg("drm_tegra_job_wait() failed %d\n", result);
result = -1;
}
- drm_tegra_fence_free(fence);
-
cleanup:
tegra_stream_cleanup(stream);
@@ -134,7 +137,6 @@ cleanup:
struct tegra_fence * tegra_stream_submit(struct tegra_stream *stream, bool gr2d)
{
- struct drm_tegra_fence *fence;
struct tegra_fence *f;
int result;
@@ -153,13 +155,39 @@ struct tegra_fence * tegra_stream_submit(struct tegra_stream *stream, bool gr2d)
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;
} else {
- f = tegra_stream_create_fence(fence, gr2d);
- tegra_stream_put_fence(stream->last_fence);
+ unsigned int num_fences, count;
+ struct drm_fence *fences;
+
+ num_fences = drm_tegra_job_get_fences(stream->job, NULL, 0);
+ if (num_fences == 0) {
+ result = -1;
+ goto cleanup;
+ }
+
+ fences = calloc(num_fences, sizeof(*fences));
+ if (!fences) {
+ result = -1;
+ goto cleanup;
+ }
+
+ count = drm_tegra_job_get_fences(stream->job, fences, num_fences);
+ if (count != num_fences) {
+ result = -1;
+ goto cleanup;
+ }
+
+ f = tegra_stream_create_fence(fences, num_fences, gr2d);
+ if (!f) {
+ result = -1;
+ goto cleanup;
+ }
+
+ tegra_stream_put_fence(stream, stream->last_fence);
stream->last_fence = f;
}
@@ -191,42 +219,43 @@ struct tegra_fence * tegra_stream_get_last_fence(struct tegra_stream *stream)
return NULL;
}
-struct tegra_fence * tegra_stream_create_fence(struct drm_tegra_fence *fence,
+struct tegra_fence * tegra_stream_create_fence(struct drm_fence *fences,
+ unsigned int num_fences,
bool gr2d)
{
struct tegra_fence *f = calloc(1, sizeof(*f));
if (f) {
- f->fence = fence;
+ f->num_fences = num_fences;
+ f->fences = fences;
f->gr2d = gr2d;
}
return f;
}
-bool tegra_stream_wait_fence(struct tegra_fence *f)
+bool tegra_stream_wait_fence(struct tegra_stream *stream, struct tegra_fence *f)
{
int result;
- if (f && f->fence) {
- result = drm_tegra_fence_wait_timeout(f->fence, 1000);
+ if (f && f->num_fences > 0) {
+ result = drm_tegra_wait_fences(stream->drm, f->fences, f->num_fences);
if (result != 0) {
- ErrorMsg("drm_tegra_fence_wait_timeout() failed %d\n", result);
+ ErrorMsg("drm_tegra_wait_fences() failed: %d\n", result);
+ return false;
}
- drm_tegra_fence_free(f->fence);
- f->fence = NULL;
-
return true;
}
return false;
}
-void tegra_stream_put_fence(struct tegra_fence *f)
+void tegra_stream_put_fence(struct tegra_stream *stream, struct tegra_fence *f)
{
if (f && --f->refcnt < 0) {
- drm_tegra_fence_free(f->fence);
+ drm_tegra_put_fences(stream->drm, f->fences, f->num_fences);
+ free(f->fences);
free(f);
}
}
@@ -369,8 +398,8 @@ int tegra_stream_end(struct tegra_stream *stream)
if (stream->op_done_synced)
goto ready;
- 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);
@@ -480,7 +509,7 @@ int tegra_stream_prep(struct tegra_stream *stream, uint32_t words)
}
int tegra_stream_sync(struct tegra_stream *stream,
- enum drm_tegra_syncpt_cond cond)
+ enum drm_tegra_sync_cond cond)
{
int ret;
@@ -489,14 +518,14 @@ int tegra_stream_sync(struct tegra_stream *stream,
return -1;
}
- ret = drm_tegra_pushbuf_sync(stream->buffer.pushbuf, cond);
+ ret = drm_tegra_pushbuf_sync(stream->buffer.pushbuf, 0, 1, cond);
if (ret != 0) {
stream->status = TEGRADRM_STREAM_CONSTRUCTION_FAILED;
ErrorMsg("drm_tegra_pushbuf_sync() failed %d\n", ret);
return -1;
}
- if (cond == DRM_TEGRA_SYNCPT_COND_OP_DONE)
+ if (cond == DRM_TEGRA_SYNC_COND_OP_DONE)
stream->op_done_synced = true;
return 0;
diff --git a/src/tegra_stream.h b/src/tegra_stream.h
index dc16b2c..0b60c5d 100644
--- a/src/tegra_stream.h
+++ b/src/tegra_stream.h
@@ -44,13 +44,16 @@ struct tegra_command_buffer {
};
struct tegra_fence {
- struct drm_tegra_fence *fence;
+ struct drm_fence *fences;
+ unsigned int num_fences;
void *opaque;
int refcnt;
bool gr2d;
};
struct tegra_stream {
+ struct drm_tegra *drm;
+
enum tegra_stream_status status;
struct drm_tegra_job *job;
@@ -70,7 +73,7 @@ struct tegra_reloc {
};
/* Stream operations */
-int tegra_stream_create(struct tegra_stream *stream);
+int tegra_stream_create(struct tegra_stream *stream, struct drm_tegra *drm);
void tegra_stream_destroy(struct tegra_stream *stream);
int tegra_stream_begin(struct tegra_stream *stream,
struct drm_tegra_channel *channel);
@@ -80,10 +83,11 @@ int tegra_stream_flush(struct tegra_stream *stream);
struct tegra_fence * tegra_stream_submit(struct tegra_stream *stream, bool gr2d);
struct tegra_fence * tegra_stream_ref_fence(struct tegra_fence *f, void *opaque);
struct tegra_fence * tegra_stream_get_last_fence(struct tegra_stream *stream);
-struct tegra_fence * tegra_stream_create_fence(struct drm_tegra_fence *fence,
+struct tegra_fence * tegra_stream_create_fence(struct drm_fence *fences,
+ unsigned int num_fences,
bool gr2d);
-bool tegra_stream_wait_fence(struct tegra_fence *f);
-void tegra_stream_put_fence(struct tegra_fence *f);
+bool tegra_stream_wait_fence(struct tegra_stream *stream, struct tegra_fence *f);
+void tegra_stream_put_fence(struct tegra_stream *stream, struct tegra_fence *f);
int tegra_stream_push(struct tegra_stream *stream, uint32_t word);
int tegra_stream_push_setclass(struct tegra_stream *stream, unsigned class_id);
int tegra_stream_push_reloc(struct tegra_stream *stream,
@@ -94,7 +98,7 @@ int tegra_stream_push_words(struct tegra_stream *stream, const void *addr,
unsigned words, int num_relocs, ...);
int tegra_stream_prep(struct tegra_stream *stream, uint32_t words);
int tegra_stream_sync(struct tegra_stream *stream,
- enum drm_tegra_syncpt_cond cond);
+ enum drm_tegra_sync_cond cond);
int tegra_stream_pushf(struct tegra_stream *stream, float f);
#endif
diff --git a/src/xv.c b/src/xv.c
index 725f445..3bc93b5 100644
--- a/src/xv.c
+++ b/src/xv.c
@@ -283,11 +283,12 @@ static Bool TegraVideoOverlayCreateFB(TegraVideoPtr priv, ScrnInfoPtr scrn,
{
TegraPtr tegra = TegraPTR(scrn);
uint32_t *flinks = (uint32_t*) (passthrough_data + 0);
- uint32_t *pitches = (uint32_t*) (passthrough_data + 12);
- uint32_t *offsets = (uint32_t*) (passthrough_data + 24);
- uint32_t bo_handles[3];
+ uint32_t pitches[4];
+ uint32_t offsets[4];
+ uint32_t handles[4];
+ uint64_t modifiers[4];
drm_overlay_fb *fb;
- int i = 0;
+ unsigned int i;
if (priv->fb &&
priv->fb->format == drm_format &&
@@ -304,21 +305,32 @@ static Bool TegraVideoOverlayCreateFB(TegraVideoPtr priv, ScrnInfoPtr scrn,
}
if (passthrough) {
+ for (i = 0; i < 3; i++) {
+ pitches[i] = ((uint32_t *)(passthrough_data + 16))[i];
+ offsets[i] = ((uint32_t *)(passthrough_data + 32))[i];
+ modifiers[i] = ((uint64_t *)(passthrough_data + 48))[i];
+ }
+
+ pitches[3] = offsets[3] = modifiers[3] = 0;
+
switch (drm_format) {
case DRM_FORMAT_YUV420:
i = 3;
break;
default:
i = 1;
+ break;
}
for (; i > 0; i--) {
- if (!TegraImportBo(scrn, flinks[i - 1], &bo_handles[i - 1]))
+ if (!TegraImportBo(scrn, flinks[i - 1], &handles[i - 1]))
goto fail;
}
+ handles[3] = 0;
+
fb = drm_create_fb_from_handle(tegra->fd, drm_format, width, height,
- bo_handles, pitches, offsets);
+ handles, pitches, offsets, modifiers);
} else {
fb = drm_create_fb(tegra->fd, drm_format, width, height);
}
@@ -341,8 +353,8 @@ static Bool TegraVideoOverlayCreateFB(TegraVideoPtr priv, ScrnInfoPtr scrn,
fail:
ErrorMsg("Failed to create framebuffer\n");
- for (; i < TEGRA_ARRAY_SIZE(bo_handles) && i > 0; i--) {
- TegraCloseBo(scrn, bo_handles[i - 1]);
+ for (; i < TEGRA_ARRAY_SIZE(handles) && i > 0; i--) {
+ TegraCloseBo(scrn, handles[i - 1]);
}
return FALSE;
diff --git a/src/xv.h b/src/xv.h
index 02af31e..347a479 100644
--- a/src/xv.h
+++ b/src/xv.h
@@ -28,7 +28,7 @@
#define TEGRA_VIDEO_OVERLAY_MAX_WIDTH 4096
#define TEGRA_VIDEO_OVERLAY_MAX_HEIGHT 4096
-#define PASSTHROUGH_DATA_SIZE 36
+#define PASSTHROUGH_DATA_SIZE 80
#define FOURCC_PASSTHROUGH_YV12 (('1' << 24) + ('2' << 16) + ('V' << 8) + 'Y')
#define FOURCC_PASSTHROUGH_RGB565 (('1' << 24) + ('B' << 16) + ('G' << 8) + 'R')