summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2009-06-30 16:24:37 +1000
committerDave Airlie <airlied@redhat.com>2009-06-30 16:32:01 +1000
commite932836691aeaec37794fdaed2dabb22710fd171 (patch)
tree078de611599b48afe5b6cc3d52175004bc8a3662
parentbb04b450ed00ca4b1aa44c33085567d47b33b547 (diff)
radeon: initial preparation for kms patch.
This patch contains most of the changes to the EXA and texture video accel code. It adds a few bits of pixmap support but doesn't actually do anything useful KMS yet. Testing this should not have any regressions over what we have already, biggest worries are r6xx, I've fixed a textured video one, but no idea what other might lurk It won't build against libdrm radeon yet either
-rw-r--r--configure.ac41
-rw-r--r--src/r600_textured_videofuncs.c4
-rw-r--r--src/radeon.h122
-rw-r--r--src/radeon_accel.c174
-rw-r--r--src/radeon_drm.h129
-rw-r--r--src/radeon_dummy_bufmgr.h57
-rw-r--r--src/radeon_exa.c140
-rw-r--r--src/radeon_exa_funcs.c216
-rw-r--r--src/radeon_exa_render.c196
-rw-r--r--src/radeon_macros.h37
-rw-r--r--src/radeon_textured_video.c45
-rw-r--r--src/radeon_textured_videofuncs.c155
-rw-r--r--src/radeon_video.h3
13 files changed, 1084 insertions, 235 deletions
diff --git a/configure.ac b/configure.ac
index a2d7f978..0cf24e66 100644
--- a/configure.ac
+++ b/configure.ac
@@ -31,6 +31,7 @@ AM_CONFIG_HEADER([config.h])
31AC_CONFIG_AUX_DIR(.) 31AC_CONFIG_AUX_DIR(.)
32 32
33AM_INIT_AUTOMAKE([dist-bzip2]) 33AM_INIT_AUTOMAKE([dist-bzip2])
34AC_SYS_LARGEFILE
34 35
35AM_MAINTAINER_MODE 36AM_MAINTAINER_MODE
36 37
@@ -114,6 +115,22 @@ if test "$DRI" = yes; then
114 if test "$have_damage_h" = yes; then 115 if test "$have_damage_h" = yes; then
115 AC_DEFINE(DAMAGE,1,[Use Damage extension]) 116 AC_DEFINE(DAMAGE,1,[Use Damage extension])
116 fi 117 fi
118
119 save_CFLAGS="$CFLAGS"
120 CFLAGS="$XORG_CFLAGS $DRI_CFLAGS $CFLAGS"
121# AC_CHECK_HEADER(xf86drmMode.h,[DRM_MODE=yes],[DRM_MODE=no],[#include <stdint.h>
122 DRM_MODE=no
123#include <stdlib.h>])
124 if test "x$DRM_MODE" = xyes; then
125 PKG_CHECK_MODULES(LIBDRM_RADEON, [xorg-server >= 1.6 libdrm_radeon],
126 [LIBDRM_RADEON=yes], [LIBDRM_RADEON=no])
127
128 if test "x$LIBDRM_RADEON" = xyes; then
129 AC_DEFINE(XF86DRM_MODE,1,[DRM kernel modesetting])
130 AC_DEFINE(DRI2, 1,[Enable DRI2 code])
131 fi
132 fi
133 CFLAGS="$save_CFLAGS"
117fi 134fi
118 135
119save_CFLAGS="$CFLAGS" 136save_CFLAGS="$CFLAGS"
@@ -310,6 +327,8 @@ esac
310 327
311AC_SUBST([XORG_CFLAGS]) 328AC_SUBST([XORG_CFLAGS])
312AC_SUBST([DRI_CFLAGS]) 329AC_SUBST([DRI_CFLAGS])
330AC_SUBST([LIBDRM_RADEON_CFLAGS])
331AC_SUBST([LIBDRM_RADEON_LIBS])
313AC_SUBST([moduledir]) 332AC_SUBST([moduledir])
314 333
315DRIVER_NAME=ati 334DRIVER_NAME=ati
@@ -336,3 +355,25 @@ AC_OUTPUT([
336 src/Makefile 355 src/Makefile
337 man/Makefile 356 man/Makefile
338]) 357])
358
359dnl
360dnl Output some configuration info for the user
361dnl
362echo ""
363echo " prefix: $prefix"
364echo " exec_prefix: $exec_prefix"
365echo " libdir: $libdir"
366echo " includedir: $includedir"
367
368
369echo ""
370echo " Kernel modesetting: $DRM_MODE"
371
372echo ""
373echo " CFLAGS: $CFLAGS"
374echo " CXXFLAGS: $CXXFLAGS"
375echo " Macros: $DEFINES"
376
377echo ""
378echo " Run '${MAKE-make}' to build xf86-video-ati"
379echo ""
diff --git a/src/r600_textured_videofuncs.c b/src/r600_textured_videofuncs.c
index 6af0949c..7c91a06b 100644
--- a/src/r600_textured_videofuncs.c
+++ b/src/r600_textured_videofuncs.c
@@ -297,7 +297,7 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
297 switch(pPriv->id) { 297 switch(pPriv->id) {
298 case FOURCC_YV12: 298 case FOURCC_YV12:
299 case FOURCC_I420: 299 case FOURCC_I420:
300 accel_state->src_mc_addr[0] = pPriv->src_offset; 300 accel_state->src_mc_addr[0] = pPriv->src_offset + info->fbLocation + pScrn->fbOffset;
301 accel_state->src_size[0] = accel_state->src_pitch[0] * pPriv->h; 301 accel_state->src_size[0] = accel_state->src_pitch[0] * pPriv->h;
302 302
303 /* flush texture cache */ 303 /* flush texture cache */
@@ -392,7 +392,7 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
392 case FOURCC_UYVY: 392 case FOURCC_UYVY:
393 case FOURCC_YUY2: 393 case FOURCC_YUY2:
394 default: 394 default:
395 accel_state->src_mc_addr[0] = pPriv->src_offset; 395 accel_state->src_mc_addr[0] = pPriv->src_offset + info->fbLocation + pScrn->fbOffset;
396 accel_state->src_size[0] = accel_state->src_pitch[0] * pPriv->h; 396 accel_state->src_size[0] = accel_state->src_pitch[0] * pPriv->h;
397 397
398 /* flush texture cache */ 398 /* flush texture cache */
diff --git a/src/radeon.h b/src/radeon.h
index 2145de54..0dce081a 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -75,6 +75,7 @@
75#include "dri.h" 75#include "dri.h"
76#include "GL/glxint.h" 76#include "GL/glxint.h"
77#include "xf86drm.h" 77#include "xf86drm.h"
78#include "radeon_drm.h"
78 79
79#ifdef DAMAGE 80#ifdef DAMAGE
80#include "damage.h" 81#include "damage.h"
@@ -85,6 +86,13 @@
85#include "xf86Crtc.h" 86#include "xf86Crtc.h"
86#include "X11/Xatom.h" 87#include "X11/Xatom.h"
87 88
89#ifdef XF86DRM_MODE
90#include "radeon_bo.h"
91#include "radeon_cs.h"
92#else
93#include "radeon_dummy_bufmgr.h"
94#endif
95
88 /* Render support */ 96 /* Render support */
89#ifdef RENDER 97#ifdef RENDER
90#include "picturestr.h" 98#include "picturestr.h"
@@ -450,6 +458,11 @@ typedef struct {
450 458
451typedef struct _atomBiosHandle *atomBiosHandlePtr; 459typedef struct _atomBiosHandle *atomBiosHandlePtr;
452 460
461struct radeon_exa_pixmap_priv {
462 struct radeon_bo *bo;
463 int flags;
464};
465
453typedef struct { 466typedef struct {
454 uint32_t pci_device_id; 467 uint32_t pci_device_id;
455 RADEONChipFamily chip_family; 468 RADEONChipFamily chip_family;
@@ -460,6 +473,25 @@ typedef struct {
460 int singledac; 473 int singledac;
461} RADEONCardInfo; 474} RADEONCardInfo;
462 475
476#define RADEON_2D_EXA_COPY 1
477#define RADEON_2D_EXA_SOLID 2
478
479struct radeon_2d_state {
480 int op; //
481 uint32_t dst_pitch_offset;
482 uint32_t src_pitch_offset;
483 uint32_t dp_gui_master_cntl;
484 uint32_t dp_cntl;
485 uint32_t dp_write_mask;
486 uint32_t dp_brush_frgd_clr;
487 uint32_t dp_brush_bkgd_clr;
488 uint32_t dp_src_frgd_clr;
489 uint32_t dp_src_bkgd_clr;
490 uint32_t default_sc_bottom_right;
491 struct radeon_bo *dst_bo;
492 struct radeon_bo *src_bo;
493};
494
463#ifdef XF86DRI 495#ifdef XF86DRI
464struct radeon_cp { 496struct radeon_cp {
465 Bool CPRuns; /* CP is running */ 497 Bool CPRuns; /* CP is running */
@@ -937,6 +969,18 @@ typedef struct {
937 float igp_ht_link_clk; 969 float igp_ht_link_clk;
938 float igp_ht_link_width; 970 float igp_ht_link_width;
939 971
972 int can_resize;
973 void (*reemit_current2d)(ScrnInfoPtr pScrn, int op); // emit the current 2D state into the IB
974 struct radeon_2d_state state_2d;
975#ifdef XF86DRM_MODE
976 struct radeon_bo_manager *bufmgr;
977 struct radeon_cs_manager *csm;
978 struct radeon_cs *cs;
979#else
980 /* fake bool */
981 Bool cs;
982#endif
983
940} RADEONInfoRec, *RADEONInfoPtr; 984} RADEONInfoRec, *RADEONInfoPtr;
941 985
942#define RADEONWaitForFifo(pScrn, entries) \ 986#define RADEONWaitForFifo(pScrn, entries) \
@@ -1013,11 +1057,13 @@ extern void RADEONWaitForFifoFunction(ScrnInfoPtr pScrn, int entries);
1013#ifdef XF86DRI 1057#ifdef XF86DRI
1014extern drmBufPtr RADEONCPGetBuffer(ScrnInfoPtr pScrn); 1058extern drmBufPtr RADEONCPGetBuffer(ScrnInfoPtr pScrn);
1015extern void RADEONCPFlushIndirect(ScrnInfoPtr pScrn, int discard); 1059extern void RADEONCPFlushIndirect(ScrnInfoPtr pScrn, int discard);
1060extern void radeon_cs_flush_indirect(ScrnInfoPtr pScrn);
1016extern void RADEONCPReleaseIndirect(ScrnInfoPtr pScrn); 1061extern void RADEONCPReleaseIndirect(ScrnInfoPtr pScrn);
1017extern int RADEONCPStop(ScrnInfoPtr pScrn, RADEONInfoPtr info); 1062extern int RADEONCPStop(ScrnInfoPtr pScrn, RADEONInfoPtr info);
1018# ifdef USE_XAA 1063# ifdef USE_XAA
1019extern Bool RADEONSetupMemXAA_DRI(int scrnIndex, ScreenPtr pScreen); 1064extern Bool RADEONSetupMemXAA_DRI(int scrnIndex, ScreenPtr pScreen);
1020# endif 1065# endif
1066uint32_t radeonGetPixmapOffset(PixmapPtr pPix);
1021#endif 1067#endif
1022 1068
1023#ifdef USE_XAA 1069#ifdef USE_XAA
@@ -1202,6 +1248,9 @@ extern void
1202radeon_legacy_free_memory(ScrnInfoPtr pScrn, 1248radeon_legacy_free_memory(ScrnInfoPtr pScrn,
1203 void *mem_struct); 1249 void *mem_struct);
1204 1250
1251struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix);
1252void radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo);
1253
1205#ifdef XF86DRI 1254#ifdef XF86DRI
1206# ifdef USE_XAA 1255# ifdef USE_XAA
1207/* radeon_accelfuncs.c */ 1256/* radeon_accelfuncs.c */
@@ -1220,7 +1269,9 @@ do { \
1220 1269
1221#define RADEONCP_RELEASE(pScrn, info) \ 1270#define RADEONCP_RELEASE(pScrn, info) \
1222do { \ 1271do { \
1223 if (info->cp->CPInUse) { \ 1272 if (info->cs) { \
1273 radeon_cs_flush_indirect(pScrn); \
1274 } else if (info->cp->CPInUse) { \
1224 RADEON_PURGE_CACHE(); \ 1275 RADEON_PURGE_CACHE(); \
1225 RADEON_WAIT_UNTIL_IDLE(); \ 1276 RADEON_WAIT_UNTIL_IDLE(); \
1226 RADEONCPReleaseIndirect(pScrn); \ 1277 RADEONCPReleaseIndirect(pScrn); \
@@ -1255,7 +1306,7 @@ do { \
1255 1306
1256#define RADEONCP_REFRESH(pScrn, info) \ 1307#define RADEONCP_REFRESH(pScrn, info) \
1257do { \ 1308do { \
1258 if (!info->cp->CPInUse) { \ 1309 if (!info->cp->CPInUse && !info->cs) { \
1259 if (info->cp->needCacheFlush) { \ 1310 if (info->cp->needCacheFlush) { \
1260 RADEON_PURGE_CACHE(); \ 1311 RADEON_PURGE_CACHE(); \
1261 RADEON_PURGE_ZCACHE(); \ 1312 RADEON_PURGE_ZCACHE(); \
@@ -1286,54 +1337,59 @@ do { \
1286 xf86DrvMsg(pScrn->scrnIndex, X_INFO, \ 1337 xf86DrvMsg(pScrn->scrnIndex, X_INFO, \
1287 "BEGIN_RING(%d) in %s\n", (unsigned int)n, __FUNCTION__);\ 1338 "BEGIN_RING(%d) in %s\n", (unsigned int)n, __FUNCTION__);\
1288 } \ 1339 } \
1289 if (++info->cp->dma_begin_count != 1) { \ 1340 if (info->cs) radeon_cs_begin(info->cs, n, __FILE__, __func__, __LINE__); else { \
1341 if (++info->cp->dma_begin_count != 1) { \
1290 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ 1342 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \
1291 "BEGIN_RING without end at %s:%d\n", \ 1343 "BEGIN_RING without end at %s:%d\n", \
1292 info->cp->dma_debug_func, info->cp->dma_debug_lineno); \ 1344 info->cp->dma_debug_func, info->cp->dma_debug_lineno); \
1293 info->cp->dma_begin_count = 1; \ 1345 info->cp->dma_begin_count = 1; \
1294 } \ 1346 } \
1295 info->cp->dma_debug_func = __FILE__; \ 1347 info->cp->dma_debug_func = __FILE__; \
1296 info->cp->dma_debug_lineno = __LINE__; \ 1348 info->cp->dma_debug_lineno = __LINE__; \
1297 if (!info->cp->indirectBuffer) { \ 1349 if (!info->cp->indirectBuffer) { \
1298 info->cp->indirectBuffer = RADEONCPGetBuffer(pScrn); \ 1350 info->cp->indirectBuffer = RADEONCPGetBuffer(pScrn); \
1299 info->cp->indirectStart = 0; \ 1351 info->cp->indirectStart = 0; \
1300 } else if (info->cp->indirectBuffer->used + (n) * (int)sizeof(uint32_t) > \ 1352 } else if (info->cp->indirectBuffer->used + (n) * (int)sizeof(uint32_t) > \
1301 info->cp->indirectBuffer->total) { \ 1353 info->cp->indirectBuffer->total) { \
1302 RADEONCPFlushIndirect(pScrn, 1); \ 1354 RADEONCPFlushIndirect(pScrn, 1); \
1355 } \
1356 __expected = n; \
1357 __head = (pointer)((char *)info->cp->indirectBuffer->address + \
1358 info->cp->indirectBuffer->used); \
1359 __count = 0; \
1303 } \ 1360 } \
1304 __expected = n; \
1305 __head = (pointer)((char *)info->cp->indirectBuffer->address + \
1306 info->cp->indirectBuffer->used); \
1307 __count = 0; \
1308} while (0) 1361} while (0)
1309 1362
1310#define ADVANCE_RING() do { \ 1363#define ADVANCE_RING() do { \
1311 if (info->cp->dma_begin_count-- != 1) { \ 1364 if (info->cs) radeon_cs_end(info->cs, __FILE__, __func__, __LINE__); else { \
1365 if (info->cp->dma_begin_count-- != 1) { \
1312 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ 1366 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \
1313 "ADVANCE_RING without begin at %s:%d\n", \ 1367 "ADVANCE_RING without begin at %s:%d\n", \
1314 __FILE__, __LINE__); \ 1368 __FILE__, __LINE__); \
1315 info->cp->dma_begin_count = 0; \ 1369 info->cp->dma_begin_count = 0; \
1316 } \ 1370 } \
1317 if (__count != __expected) { \ 1371 if (__count != __expected) { \
1318 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ 1372 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \
1319 "ADVANCE_RING count != expected (%d vs %d) at %s:%d\n", \ 1373 "ADVANCE_RING count != expected (%d vs %d) at %s:%d\n", \
1320 __count, __expected, __FILE__, __LINE__); \ 1374 __count, __expected, __FILE__, __LINE__); \
1321 } \ 1375 } \
1322 if (RADEON_VERBOSE) { \ 1376 if (RADEON_VERBOSE) { \
1323 xf86DrvMsg(pScrn->scrnIndex, X_INFO, \ 1377 xf86DrvMsg(pScrn->scrnIndex, X_INFO, \
1324 "ADVANCE_RING() start: %d used: %d count: %d\n", \ 1378 "ADVANCE_RING() start: %d used: %d count: %d\n", \
1325 info->cp->indirectStart, \ 1379 info->cp->indirectStart, \
1326 info->cp->indirectBuffer->used, \ 1380 info->cp->indirectBuffer->used, \
1327 __count * (int)sizeof(uint32_t)); \ 1381 __count * (int)sizeof(uint32_t)); \
1382 } \
1383 info->cp->indirectBuffer->used += __count * (int)sizeof(uint32_t); \
1328 } \ 1384 } \
1329 info->cp->indirectBuffer->used += __count * (int)sizeof(uint32_t); \ 1385 } while (0)
1330} while (0)
1331 1386
1332#define OUT_RING(x) do { \ 1387#define OUT_RING(x) do { \
1333 if (RADEON_VERBOSE) { \ 1388 if (RADEON_VERBOSE) { \
1334 xf86DrvMsg(pScrn->scrnIndex, X_INFO, \ 1389 xf86DrvMsg(pScrn->scrnIndex, X_INFO, \
1335 " OUT_RING(0x%08x)\n", (unsigned int)(x)); \ 1390 " OUT_RING(0x%08x)\n", (unsigned int)(x)); \
1336 } \ 1391 } \
1392 if (info->cs) radeon_cs_write_dword(info->cs, (x)); else \
1337 __head[__count++] = (x); \ 1393 __head[__count++] = (x); \
1338} while (0) 1394} while (0)
1339 1395
@@ -1343,12 +1399,22 @@ do { \
1343 OUT_RING(val); \ 1399 OUT_RING(val); \
1344} while (0) 1400} while (0)
1345 1401
1402#define OUT_RING_RELOC(x, read_domains, write_domain) \
1403 do { \
1404 int _ret; \
1405 _ret = radeon_cs_write_reloc(info->cs, x, read_domains, write_domain, 0); \
1406 if (_ret) ErrorF("reloc emit failure %d\n", _ret); \
1407 } while(0)
1408
1409
1346#define FLUSH_RING() \ 1410#define FLUSH_RING() \
1347do { \ 1411do { \
1348 if (RADEON_VERBOSE) \ 1412 if (RADEON_VERBOSE) \
1349 xf86DrvMsg(pScrn->scrnIndex, X_INFO, \ 1413 xf86DrvMsg(pScrn->scrnIndex, X_INFO, \
1350 "FLUSH_RING in %s\n", __FUNCTION__); \ 1414 "FLUSH_RING in %s\n", __FUNCTION__); \
1351 if (info->cp->indirectBuffer) \ 1415 if (info->cs) \
1416 radeon_cs_flush_indirect(pScrn); \
1417 else if (info->cp->indirectBuffer) \
1352 RADEONCPFlushIndirect(pScrn, 0); \ 1418 RADEONCPFlushIndirect(pScrn, 0); \
1353} while (0) 1419} while (0)
1354 1420
@@ -1434,8 +1500,12 @@ do { \
1434 case EXA_ENGINEMODE_2D: \ 1500 case EXA_ENGINEMODE_2D: \
1435 break; \ 1501 break; \
1436 } \ 1502 } \
1437 if (flush && info->directRenderingEnabled) \ 1503 if (flush) { \
1438 RADEONCPFlushIndirect(pScrn, 1); \ 1504 if (info->cs) \
1505 radeon_cs_flush_indirect(pScrn); \
1506 else if (info->directRenderingEnabled) \
1507 RADEONCPFlushIndirect(pScrn, 1); \
1508 } \
1439 info->accel_state->engineMode = EXA_ENGINEMODE_2D; \ 1509 info->accel_state->engineMode = EXA_ENGINEMODE_2D; \
1440} while (0); 1510} while (0);
1441 1511
@@ -1450,7 +1520,9 @@ do { \
1450 break; \ 1520 break; \
1451 } \ 1521 } \
1452 if (flush) { \ 1522 if (flush) { \
1453 if (info->directRenderingEnabled) \ 1523 if (info->cs) \
1524 radeon_cs_flush_indirect(pScrn); \
1525 else if (info->directRenderingEnabled) \
1454 RADEONCPFlushIndirect(pScrn, 1); \ 1526 RADEONCPFlushIndirect(pScrn, 1); \
1455 RADEONInit3DEngine(pScrn); \ 1527 RADEONInit3DEngine(pScrn); \
1456 } \ 1528 } \
diff --git a/src/radeon_accel.c b/src/radeon_accel.c
index f90b3864..e51bffe0 100644
--- a/src/radeon_accel.c
+++ b/src/radeon_accel.c
@@ -375,6 +375,9 @@ void RADEONEngineRestore(ScrnInfoPtr pScrn)
375 RADEONInfoPtr info = RADEONPTR(pScrn); 375 RADEONInfoPtr info = RADEONPTR(pScrn);
376 unsigned char *RADEONMMIO = info->MMIO; 376 unsigned char *RADEONMMIO = info->MMIO;
377 377
378 if (info->cs)
379 return;
380
378 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, 381 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
379 "EngineRestore (%d/%d)\n", 382 "EngineRestore (%d/%d)\n",
380 info->CurrentLayout.pixel_code, 383 info->CurrentLayout.pixel_code,
@@ -421,6 +424,24 @@ void RADEONEngineRestore(ScrnInfoPtr pScrn)
421 info->accel_state->XInited3D = FALSE; 424 info->accel_state->XInited3D = FALSE;
422} 425}
423 426
427static int RADEONDRMGetNumPipes(ScrnInfoPtr pScrn, int *num_pipes)
428{
429 RADEONInfoPtr info = RADEONPTR(pScrn);
430 if (info->dri->pKernelDRMVersion->version_major < 2) {
431 drm_radeon_getparam_t np;
432
433 memset(&np, 0, sizeof(np));
434 np.param = RADEON_PARAM_NUM_GB_PIPES;
435 np.value = num_pipes;
436 return drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_GETPARAM, &np, sizeof(np));
437 } else {
438 struct drm_radeon_info np2;
439 np2.value = (uint64_t)num_pipes;
440 np2.request = RADEON_INFO_NUM_GB_PIPES;
441 return drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_INFO, &np2, sizeof(np2));
442 }
443}
444
424/* Initialize the acceleration hardware */ 445/* Initialize the acceleration hardware */
425void RADEONEngineInit(ScrnInfoPtr pScrn) 446void RADEONEngineInit(ScrnInfoPtr pScrn)
426{ 447{
@@ -436,15 +457,9 @@ void RADEONEngineInit(ScrnInfoPtr pScrn)
436 457
437#ifdef XF86DRI 458#ifdef XF86DRI
438 if (info->directRenderingEnabled && (IS_R300_3D || IS_R500_3D)) { 459 if (info->directRenderingEnabled && (IS_R300_3D || IS_R500_3D)) {
439 drm_radeon_getparam_t np;
440 int num_pipes; 460 int num_pipes;
441 461
442 memset(&np, 0, sizeof(np)); 462 if(RADEONDRMGetNumPipes(pScrn, &num_pipes) < 0) {
443 np.param = RADEON_PARAM_NUM_GB_PIPES;
444 np.value = &num_pipes;
445
446 if (drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_GETPARAM, &np,
447 sizeof(np)) < 0) {
448 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 463 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
449 "Failed to determine num pipes from DRM, falling back to " 464 "Failed to determine num pipes from DRM, falling back to "
450 "manual look-up!\n"); 465 "manual look-up!\n");
@@ -455,64 +470,67 @@ void RADEONEngineInit(ScrnInfoPtr pScrn)
455 } 470 }
456#endif 471#endif
457 472
458 if ((info->ChipFamily == CHIP_FAMILY_RV410) || 473 if (!info->cs) {
459 (info->ChipFamily == CHIP_FAMILY_R420) || 474 if ((info->ChipFamily == CHIP_FAMILY_RV410) ||
460 (info->ChipFamily == CHIP_FAMILY_RS600) || 475 (info->ChipFamily == CHIP_FAMILY_R420) ||
461 (info->ChipFamily == CHIP_FAMILY_RS690) || 476 (info->ChipFamily == CHIP_FAMILY_RS600) ||
462 (info->ChipFamily == CHIP_FAMILY_RS740) || 477 (info->ChipFamily == CHIP_FAMILY_RS690) ||
463 (info->ChipFamily == CHIP_FAMILY_RS400) || 478 (info->ChipFamily == CHIP_FAMILY_RS740) ||
464 (info->ChipFamily == CHIP_FAMILY_RS480) || 479 (info->ChipFamily == CHIP_FAMILY_RS400) ||
465 IS_R500_3D) { 480 (info->ChipFamily == CHIP_FAMILY_RS480) ||
466 if (info->accel_state->num_gb_pipes == 0) { 481 IS_R500_3D) {
467 uint32_t gb_pipe_sel = INREG(R400_GB_PIPE_SELECT); 482 if (info->accel_state->num_gb_pipes == 0) {
468 483 uint32_t gb_pipe_sel = INREG(R400_GB_PIPE_SELECT);
469 info->accel_state->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1; 484
470 if (IS_R500_3D) 485 info->accel_state->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1;
471 OUTPLL(pScrn, R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4)); 486 if (IS_R500_3D)
472 } 487 OUTPLL(pScrn, R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4));
473 } else { 488 }
474 if (info->accel_state->num_gb_pipes == 0) { 489 } else {
475 if ((info->ChipFamily == CHIP_FAMILY_R300) || 490 if (info->accel_state->num_gb_pipes == 0) {
476 (info->ChipFamily == CHIP_FAMILY_R350)) { 491 if ((info->ChipFamily == CHIP_FAMILY_R300) ||
477 /* R3xx chips */ 492 (info->ChipFamily == CHIP_FAMILY_R350)) {
478 info->accel_state->num_gb_pipes = 2; 493 /* R3xx chips */
479 } else { 494 info->accel_state->num_gb_pipes = 2;
480 /* RV3xx chips */ 495 } else {
481 info->accel_state->num_gb_pipes = 1; 496 /* RV3xx chips */
497 info->accel_state->num_gb_pipes = 1;
498 }
482 } 499 }
483 }
484 }
485
486 /* RV410 SE cards only have 1 quadpipe */
487 if ((info->Chipset == PCI_CHIP_RV410_5E4C) ||
488 (info->Chipset == PCI_CHIP_RV410_5E4F))
489 info->accel_state->num_gb_pipes = 1;
490
491 if (IS_R300_3D || IS_R500_3D)
492 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
493 "num quad-pipes is %d\n", info->accel_state->num_gb_pipes);
494
495 if (IS_R300_3D || IS_R500_3D) {
496 uint32_t gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16);
497
498 switch(info->accel_state->num_gb_pipes) {
499 case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break;
500 case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break;
501 case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break;
502 default:
503 case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break;
504 } 500 }
505 501
506 OUTREG(R300_GB_TILE_CONFIG, gb_tile_config); 502 /* RV410 SE cards only have 1 quadpipe */
507 OUTREG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); 503 if ((info->Chipset == PCI_CHIP_RV410_5E4C) ||
508 OUTREG(R300_DST_PIPE_CONFIG, INREG(R300_DST_PIPE_CONFIG) | R300_PIPE_AUTO_CONFIG); 504 (info->Chipset == PCI_CHIP_RV410_5E4F))
509 OUTREG(R300_RB2D_DSTCACHE_MODE, (INREG(R300_RB2D_DSTCACHE_MODE) | 505 info->accel_state->num_gb_pipes = 1;
510 R300_DC_AUTOFLUSH_ENABLE | 506
511 R300_DC_DC_DISABLE_IGNORE_PE)); 507 if (IS_R300_3D || IS_R500_3D)
512 } else 508 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
513 OUTREG(RADEON_RB3D_CNTL, 0); 509 "num quad-pipes is %d\n", info->accel_state->num_gb_pipes);
510
511 if (IS_R300_3D || IS_R500_3D) {
512 uint32_t gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16);
513
514 switch(info->accel_state->num_gb_pipes) {
515 case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break;
516 case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break;
517 case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break;
518 default:
519 case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break;
520 }
514 521
515 RADEONEngineReset(pScrn); 522 OUTREG(R300_GB_TILE_CONFIG, gb_tile_config);
523 OUTREG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
524 if (info->ChipFamily >= CHIP_FAMILY_R420)
525 OUTREG(R300_DST_PIPE_CONFIG, INREG(R300_DST_PIPE_CONFIG) | R300_PIPE_AUTO_CONFIG);
526 OUTREG(R300_RB2D_DSTCACHE_MODE, (INREG(R300_RB2D_DSTCACHE_MODE) |
527 R300_DC_AUTOFLUSH_ENABLE |
528 R300_DC_DC_DISABLE_IGNORE_PE));
529 } else
530 OUTREG(RADEON_RB3D_CNTL, 0);
531
532 RADEONEngineReset(pScrn);
533 }
516 534
517 switch (info->CurrentLayout.pixel_code) { 535 switch (info->CurrentLayout.pixel_code) {
518 case 8: datatype = 2; break; 536 case 8: datatype = 2; break;
@@ -536,6 +554,24 @@ void RADEONEngineInit(ScrnInfoPtr pScrn)
536 RADEONEngineRestore(pScrn); 554 RADEONEngineRestore(pScrn);
537} 555}
538 556
557uint32_t radeonGetPixmapOffset(PixmapPtr pPix)
558{
559 ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
560 RADEONInfoPtr info = RADEONPTR(pScrn);
561 uint32_t offset = 0;
562 if (info->cs)
563 return 0;
564#ifdef USE_EXA
565 if (info->useEXA) {
566 offset = exaGetPixmapOffset(pPix);
567 } else
568#endif
569 {
570 offset = pPix->devPrivate.ptr - info->FB;
571 }
572 offset += info->fbLocation + pScrn->fbOffset;
573 return offset;
574}
539 575
540#define ACCEL_MMIO 576#define ACCEL_MMIO
541#define ACCEL_PREAMBLE() unsigned char *RADEONMMIO = info->MMIO 577#define ACCEL_PREAMBLE() unsigned char *RADEONMMIO = info->MMIO
@@ -620,6 +656,20 @@ int RADEONCPStop(ScrnInfoPtr pScrn, RADEONInfoPtr info)
620 } 656 }
621} 657}
622 658
659#define RADEON_IB_RESERVE (16 * sizeof(uint32_t))
660
661void radeon_cs_flush_indirect(ScrnInfoPtr pScrn)
662{
663#ifdef XF86DRM_MODE
664 RADEONInfoPtr info = RADEONPTR(pScrn);
665
666 if (!info->cs->cdw)
667 return;
668 radeon_cs_emit(info->cs);
669 radeon_cs_erase(info->cs);
670#endif
671}
672
623/* Get an indirect buffer for the CP 2D acceleration commands */ 673/* Get an indirect buffer for the CP 2D acceleration commands */
624drmBufPtr RADEONCPGetBuffer(ScrnInfoPtr pScrn) 674drmBufPtr RADEONCPGetBuffer(ScrnInfoPtr pScrn)
625{ 675{
@@ -696,6 +746,7 @@ void RADEONCPFlushIndirect(ScrnInfoPtr pScrn, int discard)
696 int start = info->cp->indirectStart; 746 int start = info->cp->indirectStart;
697 drm_radeon_indirect_t indirect; 747 drm_radeon_indirect_t indirect;
698 748
749 assert(!info->cs);
699 if (!buffer) return; 750 if (!buffer) return;
700 if (start == buffer->used && !discard) return; 751 if (start == buffer->used && !discard) return;
701 752
@@ -745,6 +796,7 @@ void RADEONCPReleaseIndirect(ScrnInfoPtr pScrn)
745 int start = info->cp->indirectStart; 796 int start = info->cp->indirectStart;
746 drm_radeon_indirect_t indirect; 797 drm_radeon_indirect_t indirect;
747 798
799 assert(!info->cs);
748 if (info->ChipFamily >= CHIP_FAMILY_R600) { 800 if (info->ChipFamily >= CHIP_FAMILY_R600) {
749 if (buffer && (buffer->used & 0x3c)) { 801 if (buffer && (buffer->used & 0x3c)) {
750 RING_LOCALS; 802 RING_LOCALS;
diff --git a/src/radeon_drm.h b/src/radeon_drm.h
index 54bc2345..dd0087aa 100644
--- a/src/radeon_drm.h
+++ b/src/radeon_drm.h
@@ -493,6 +493,16 @@ typedef struct {
493#define DRM_RADEON_SETPARAM 0x19 493#define DRM_RADEON_SETPARAM 0x19
494#define DRM_RADEON_SURF_ALLOC 0x1a 494#define DRM_RADEON_SURF_ALLOC 0x1a
495#define DRM_RADEON_SURF_FREE 0x1b 495#define DRM_RADEON_SURF_FREE 0x1b
496/* KMS ioctl */
497#define DRM_RADEON_GEM_INFO 0x1c
498#define DRM_RADEON_GEM_CREATE 0x1d
499#define DRM_RADEON_GEM_MMAP 0x1e
500#define DRM_RADEON_GEM_PREAD 0x21
501#define DRM_RADEON_GEM_PWRITE 0x22
502#define DRM_RADEON_GEM_SET_DOMAIN 0x23
503#define DRM_RADEON_GEM_WAIT_IDLE 0x24
504#define DRM_RADEON_CS 0x26
505#define DRM_RADEON_INFO 0x27
496 506
497#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t) 507#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t)
498#define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START) 508#define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START)
@@ -521,6 +531,17 @@ typedef struct {
521#define DRM_IOCTL_RADEON_SETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SETPARAM, drm_radeon_setparam_t) 531#define DRM_IOCTL_RADEON_SETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SETPARAM, drm_radeon_setparam_t)
522#define DRM_IOCTL_RADEON_SURF_ALLOC DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_ALLOC, drm_radeon_surface_alloc_t) 532#define DRM_IOCTL_RADEON_SURF_ALLOC DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_ALLOC, drm_radeon_surface_alloc_t)
523#define DRM_IOCTL_RADEON_SURF_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_FREE, drm_radeon_surface_free_t) 533#define DRM_IOCTL_RADEON_SURF_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_FREE, drm_radeon_surface_free_t)
534/* KMS */
535#define DRM_IOCTL_RADEON_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INFO, struct drm_radeon_gem_info)
536#define DRM_IOCTL_RADEON_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_CREATE, struct drm_radeon_gem_create)
537#define DRM_IOCTL_RADEON_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_MMAP, struct drm_radeon_gem_mmap)
538#define DRM_IOCTL_RADEON_GEM_PREAD DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PREAD, struct drm_radeon_gem_pread)
539#define DRM_IOCTL_RADEON_GEM_PWRITE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PWRITE, struct drm_radeon_gem_pwrite)
540#define DRM_IOCTL_RADEON_GEM_SET_DOMAIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_DOMAIN, struct drm_radeon_gem_set_domain)
541#define DRM_IOCTL_RADEON_GEM_WAIT_IDLE DRM_IOW(DRM_COMMAND_BASE + DRM_RADEON_GEM_WAIT_IDLE, struct drm_radeon_gem_wait_idle)
542#define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs)
543#define DRM_IOCTL_RADEON_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_INFO, struct drm_radeon_info)
544
524 545
525typedef struct drm_radeon_init { 546typedef struct drm_radeon_init {
526 enum { 547 enum {
@@ -753,4 +774,112 @@ typedef struct drm_radeon_surface_free {
753#define DRM_RADEON_VBLANK_CRTC1 1 774#define DRM_RADEON_VBLANK_CRTC1 1
754#define DRM_RADEON_VBLANK_CRTC2 2 775#define DRM_RADEON_VBLANK_CRTC2 2
755 776
777/*
778 * Kernel modesetting world below.
779 */
780#define RADEON_GEM_DOMAIN_CPU 0x1
781#define RADEON_GEM_DOMAIN_GTT 0x2
782#define RADEON_GEM_DOMAIN_VRAM 0x4
783
784struct drm_radeon_gem_info {
785 uint64_t gart_size;
786 uint64_t vram_size;
787 uint64_t vram_visible;
788};
789
790#define RADEON_GEM_NO_BACKING_STORE 1
791
792struct drm_radeon_gem_create {
793 uint64_t size;
794 uint64_t alignment;
795 uint32_t handle;
796 uint32_t initial_domain;
797 uint32_t flags;
798};
799
800struct drm_radeon_gem_mmap {
801 uint32_t handle;
802 uint32_t pad;
803 uint64_t offset;
804 uint64_t size;
805 uint64_t addr_ptr;
806};
807
808struct drm_radeon_gem_set_domain {
809 uint32_t handle;
810 uint32_t read_domains;
811 uint32_t write_domain;
812};
813
814struct drm_radeon_gem_wait_idle {
815 uint32_t handle;
816 uint32_t pad;
817};
818
819struct drm_radeon_gem_busy {
820 uint32_t handle;
821 uint32_t busy;
822};
823
824struct drm_radeon_gem_pread {
825 /** Handle for the object being read. */
826 uint32_t handle;
827 uint32_t pad;
828 /** Offset into the object to read from */
829 uint64_t offset;
830 /** Length of data to read */
831 uint64_t size;
832 /** Pointer to write the data into. */
833 /* void *, but pointers are not 32/64 compatible */
834 uint64_t data_ptr;
835};
836
837struct drm_radeon_gem_pwrite {
838 /** Handle for the object being written to. */
839 uint32_t handle;
840 uint32_t pad;
841 /** Offset into the object to write to */
842 uint64_t offset;
843 /** Length of data to write */
844 uint64_t size;
845 /** Pointer to read the data from. */
846 /* void *, but pointers are not 32/64 compatible */
847 uint64_t data_ptr;
848};
849
850#define RADEON_CHUNK_ID_RELOCS 0x01
851#define RADEON_CHUNK_ID_IB 0x02
852
853struct drm_radeon_cs_chunk {
854 uint32_t chunk_id;
855 uint32_t length_dw;
856 uint64_t chunk_data;
857};
858
859struct drm_radeon_cs_reloc {
860 uint32_t handle;
861 uint32_t read_domains;
862 uint32_t write_domain;
863 uint32_t flags;
864};
865
866struct drm_radeon_cs {
867 uint32_t num_chunks;
868 uint32_t cs_id;
869 /* this points to uint64_t * which point to cs chunks */
870 uint64_t chunks;
871 /* updates to the limits after this CS ioctl */
872 uint64_t gart_limit;
873 uint64_t vram_limit;
874};
875
876#define RADEON_INFO_DEVICE_ID 0x00
877#define RADEON_INFO_NUM_GB_PIPES 0x01
878
879struct drm_radeon_info {
880 uint32_t request;
881 uint32_t pad;
882 uint64_t value;
883};
884
756#endif 885#endif
diff --git a/src/radeon_dummy_bufmgr.h b/src/radeon_dummy_bufmgr.h
new file mode 100644
index 00000000..bf89292c
--- /dev/null
+++ b/src/radeon_dummy_bufmgr.h
@@ -0,0 +1,57 @@
1
2#ifndef RADEON_DUMMY_BUFMGR_H
3#define RADEON_DUMMY_BUFMGR_H
4/* when we don't have modesetting but we still need these functions */
5
6struct radeon_bo {
7 int dummy;
8 void *ptr;
9};
10
11static inline int radeon_cs_begin(Bool dummy, int d2, const char *file,
12 const char *func, int line)
13{
14 return 0;
15}
16
17static inline int radeon_cs_end(Bool dummy, const char *file,
18 const char *func, int line)
19{
20 return 0;
21}
22
23static inline void radeon_cs_write_dword(Bool cs, uint32_t dword)
24{
25}
26
27static inline int radeon_cs_write_reloc(Bool cs,
28 struct radeon_bo *bo,
29 uint32_t read_domain,
30 uint32_t write_domain,
31 uint32_t flags)
32{
33 return 0;
34}
35
36static inline int radeon_bo_map(struct radeon_bo *bo, int write) {return 0;}
37static inline void radeon_bo_ref(struct radeon_bo *bo) {return;}
38static inline struct radeon_bo *radeon_bo_unref(struct radeon_bo *bo) {return NULL;}
39static inline void radeon_bo_unmap(struct radeon_bo *bo) {return;}
40static inline int radeon_bo_wait(struct radeon_bo *bo) {return 0;}
41
42
43struct radeon_cs_space_check {
44 struct radeon_bo *bo;
45 int read_domains;
46 int write_domain;
47 int new_accounted;
48};
49
50static inline int radeon_cs_space_check(Bool cs, struct radeon_cs_space_check *bos, int num)
51{
52 return 0;
53}
54#define RADEON_CS_SPACE_OP_TO_BIG 0
55#define RADEON_CS_SPACE_FLUSH 1
56
57#endif
diff --git a/src/radeon_exa.c b/src/radeon_exa.c
index ae681462..5b20ecab 100644
--- a/src/radeon_exa.c
+++ b/src/radeon_exa.c
@@ -120,6 +120,15 @@ static __inline__ uint32_t F_TO_DW(float val)
120 return tmp.l; 120 return tmp.l;
121} 121}
122 122
123static inline void radeon_add_pixmap(struct radeon_cs_space_check *bos, int index, PixmapPtr pPix, int read_domains, int write_domain)
124{
125 struct radeon_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(pPix);
126 bos[index].bo = driver_priv->bo;
127 bos[index].read_domains = read_domains;
128 bos[index].write_domain = write_domain;
129 bos[index].new_accounted = 0;
130}
131
123/* Assumes that depth 15 and 16 can be used as depth 16, which is okay since we 132/* Assumes that depth 15 and 16 can be used as depth 16, which is okay since we
124 * require src and dest datatypes to be equal. 133 * require src and dest datatypes to be equal.
125 */ 134 */
@@ -179,7 +188,6 @@ static Bool RADEONGetOffsetPitch(PixmapPtr pPix, int bpp, uint32_t *pitch_offset
179 188
180Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix, uint32_t *pitch_offset) 189Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix, uint32_t *pitch_offset)
181{ 190{
182 RINFO_FROM_SCREEN(pPix->drawable.pScreen);
183 uint32_t pitch, offset; 191 uint32_t pitch, offset;
184 int bpp; 192 int bpp;
185 193
@@ -187,7 +195,7 @@ Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix, uint32_t *pitch_offset)
187 if (bpp == 24) 195 if (bpp == 24)
188 bpp = 8; 196 bpp = 8;
189 197
190 offset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset; 198 offset = radeonGetPixmapOffset(pPix);
191 pitch = exaGetPixmapPitch(pPix); 199 pitch = exaGetPixmapPitch(pPix);
192 200
193 return RADEONGetOffsetPitch(pPix, bpp, pitch_offset, offset, pitch); 201 return RADEONGetOffsetPitch(pPix, bpp, pitch_offset, offset, pitch);
@@ -224,7 +232,7 @@ int RADEONBiggerCrtcArea(PixmapPtr pPix)
224 232
225static unsigned long swapper_surfaces[6]; 233static unsigned long swapper_surfaces[6];
226 234
227static Bool RADEONPrepareAccess(PixmapPtr pPix, int index) 235static Bool RADEONPrepareAccess_BE(PixmapPtr pPix, int index)
228{ 236{
229 RINFO_FROM_SCREEN(pPix->drawable.pScreen); 237 RINFO_FROM_SCREEN(pPix->drawable.pScreen);
230 unsigned char *RADEONMMIO = info->MMIO; 238 unsigned char *RADEONMMIO = info->MMIO;
@@ -290,7 +298,7 @@ static Bool RADEONPrepareAccess(PixmapPtr pPix, int index)
290 return TRUE; 298 return TRUE;
291} 299}
292 300
293static void RADEONFinishAccess(PixmapPtr pPix, int index) 301static void RADEONFinishAccess_BE(PixmapPtr pPix, int index)
294{ 302{
295 RINFO_FROM_SCREEN(pPix->drawable.pScreen); 303 RINFO_FROM_SCREEN(pPix->drawable.pScreen);
296 unsigned char *RADEONMMIO = info->MMIO; 304 unsigned char *RADEONMMIO = info->MMIO;
@@ -323,6 +331,123 @@ static void RADEONFinishAccess(PixmapPtr pPix, int index)
323 331
324#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */ 332#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */
325 333
334#ifdef XF86DRM_MODE
335static Bool RADEONPrepareAccess_CS(PixmapPtr pPix, int index)
336{
337 RINFO_FROM_SCREEN(pPix->drawable.pScreen);
338 struct radeon_exa_pixmap_priv *driver_priv;
339 int ret;
340
341 driver_priv = exaGetPixmapDriverPrivate(pPix);
342 if (!driver_priv)
343 return FALSE;
344
345 /* if we have more refs than just the BO then flush */
346 if (driver_priv->bo->cref > 1)
347 RADEONCPFlushIndirect(pScrn, 0);
348
349 radeon_bo_wait(driver_priv->bo);
350
351 /* flush IB */
352 ret = radeon_bo_map(driver_priv->bo, 1);
353 if (ret) {
354 FatalError("failed to map pixmap %d\n", ret);
355 return FALSE;
356 }
357
358 pPix->devPrivate.ptr = driver_priv->bo->ptr;
359
360 return TRUE;
361}
362
363static void RADEONFinishAccess_CS(PixmapPtr pPix, int index)
364{
365 struct radeon_exa_pixmap_priv *driver_priv;
366
367 driver_priv = exaGetPixmapDriverPrivate(pPix);
368 if (!driver_priv)
369 return;
370
371 radeon_bo_unmap(driver_priv->bo);
372 pPix->devPrivate.ptr = NULL;
373}
374
375
376void *RADEONEXACreatePixmap(ScreenPtr pScreen, int size, int align)
377{
378 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
379 RADEONInfoPtr info = RADEONPTR(pScrn);
380 struct radeon_exa_pixmap_priv *new_priv;
381
382 new_priv = xcalloc(1, sizeof(struct radeon_exa_pixmap_priv));
383 if (!new_priv)
384 return NULL;
385
386 if (size == 0)
387 return new_priv;
388
389 new_priv->bo = radeon_bo_open(info->bufmgr, 0, size,
390 align, 0, 0);
391 if (!new_priv->bo) {
392 xfree(new_priv);
393 ErrorF("Failed to alloc memory\n");
394 return NULL;
395 }
396
397 return new_priv;
398
399}
400
401static void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv)
402{
403 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
404 RADEONInfoPtr info = RADEONPTR(pScrn);
405 struct radeon_exa_pixmap_priv *driver_priv = driverPriv;
406
407 radeon_bo_unref(driver_priv->bo);
408 xfree(driverPriv);
409}
410
411struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix)
412{
413 ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
414 RADEONInfoPtr info = RADEONPTR(pScrn);
415 struct radeon_exa_pixmap_priv *driver_priv;
416 driver_priv = exaGetPixmapDriverPrivate(pPix);
417 return driver_priv->bo;
418}
419
420void radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo)
421{
422 ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
423 RADEONInfoPtr info = RADEONPTR(pScrn);
424
425 struct radeon_exa_pixmap_priv *driver_priv;
426
427 driver_priv = exaGetPixmapDriverPrivate(pPix);
428 if (driver_priv) {
429 if (driver_priv->bo)
430 radeon_bo_unref(driver_priv->bo);
431
432 radeon_bo_ref(bo);
433 driver_priv->bo = bo;
434 }
435}
436
437static Bool RADEONEXAPixmapIsOffscreen(PixmapPtr pPix)
438{
439 struct radeon_exa_pixmap_priv *driver_priv;
440
441 driver_priv = exaGetPixmapDriverPrivate(pPix);
442
443 if (!driver_priv)
444 return FALSE;
445 if (driver_priv->bo)
446 return TRUE;
447 return FALSE;
448}
449#endif
450
326#define ENTER_DRAW(x) TRACE 451#define ENTER_DRAW(x) TRACE
327#define LEAVE_DRAW(x) TRACE 452#define LEAVE_DRAW(x) TRACE
328/***********************************************************************/ 453/***********************************************************************/
@@ -332,6 +457,7 @@ static void RADEONFinishAccess(PixmapPtr pPix, int index)
332#define BEGIN_ACCEL(n) RADEONWaitForFifo(pScrn, (n)) 457#define BEGIN_ACCEL(n) RADEONWaitForFifo(pScrn, (n))
333#define OUT_ACCEL_REG(reg, val) OUTREG(reg, val) 458#define OUT_ACCEL_REG(reg, val) OUTREG(reg, val)
334#define OUT_ACCEL_REG_F(reg, val) OUTREG(reg, F_TO_DW(val)) 459#define OUT_ACCEL_REG_F(reg, val) OUTREG(reg, F_TO_DW(val))
460#define OUT_RELOC(x, read, write) do {} while(0)
335#define FINISH_ACCEL() 461#define FINISH_ACCEL()
336 462
337#ifdef RENDER 463#ifdef RENDER
@@ -345,6 +471,7 @@ static void RADEONFinishAccess(PixmapPtr pPix, int index)
345#undef OUT_ACCEL_REG 471#undef OUT_ACCEL_REG
346#undef OUT_ACCEL_REG_F 472#undef OUT_ACCEL_REG_F
347#undef FINISH_ACCEL 473#undef FINISH_ACCEL
474#undef OUT_RELOC
348 475
349#ifdef XF86DRI 476#ifdef XF86DRI
350 477
@@ -355,6 +482,7 @@ static void RADEONFinishAccess(PixmapPtr pPix, int index)
355#define BEGIN_ACCEL(n) BEGIN_RING(2*(n)) 482#define BEGIN_ACCEL(n) BEGIN_RING(2*(n))
356#define OUT_ACCEL_REG(reg, val) OUT_RING_REG(reg, val) 483#define OUT_ACCEL_REG(reg, val) OUT_RING_REG(reg, val)
357#define FINISH_ACCEL() ADVANCE_RING() 484#define FINISH_ACCEL() ADVANCE_RING()
485#define OUT_RELOC(x, read, write) OUT_RING_RELOC(x, read, write)
358 486
359#define OUT_RING_F(x) OUT_RING(F_TO_DW(x)) 487#define OUT_RING_F(x) OUT_RING(F_TO_DW(x))
360 488
@@ -523,6 +651,10 @@ RADEONTexOffsetStart(PixmapPtr pPix)
523{ 651{
524 RINFO_FROM_SCREEN(pPix->drawable.pScreen); 652 RINFO_FROM_SCREEN(pPix->drawable.pScreen);
525 unsigned long long offset; 653 unsigned long long offset;
654
655 if (exaGetPixmapDriverPrivate(pPix))
656 return -1;
657
526 exaMoveInPixmap(pPix); 658 exaMoveInPixmap(pPix);
527 ExaOffscreenMarkUsed(pPix); 659 ExaOffscreenMarkUsed(pPix);
528 660
diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c
index ac82952b..c47dfb4b 100644
--- a/src/radeon_exa_funcs.c
+++ b/src/radeon_exa_funcs.c
@@ -74,6 +74,9 @@ FUNC_NAME(RADEONSync)(ScreenPtr pScreen, int marker)
74 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 74 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
75 RADEONInfoPtr info = RADEONPTR(pScrn); 75 RADEONInfoPtr info = RADEONPTR(pScrn);
76 76
77 if (info->cs)
78 return;
79
77 TRACE; 80 TRACE;
78 81
79 if (info->accel_state->exaMarkerSynced != marker) { 82 if (info->accel_state->exaMarkerSynced != marker) {
@@ -84,11 +87,60 @@ FUNC_NAME(RADEONSync)(ScreenPtr pScreen, int marker)
84 RADEONPTR(pScrn)->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN; 87 RADEONPTR(pScrn)->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
85} 88}
86 89
90static void FUNC_NAME(Emit2DState)(ScrnInfoPtr pScrn, int op)
91{
92 RADEONInfoPtr info = RADEONPTR(pScrn);
93 int has_src;
94 ACCEL_PREAMBLE();
95
96 /* don't emit if no operation in progress */
97 if (info->state_2d.op == 0 && op == 0)
98 return;
99
100 has_src = info->state_2d.src_pitch_offset || (info->cs && info->state_2d.src_bo);
101
102 if (has_src) {
103 BEGIN_ACCEL_RELOC(10, 2);
104 } else {
105 BEGIN_ACCEL_RELOC(9, 1);
106 }
107 OUT_ACCEL_REG(RADEON_DEFAULT_SC_BOTTOM_RIGHT, info->state_2d.default_sc_bottom_right);
108 OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, info->state_2d.dp_gui_master_cntl);
109 OUT_ACCEL_REG(RADEON_DP_BRUSH_FRGD_CLR, info->state_2d.dp_brush_frgd_clr);
110 OUT_ACCEL_REG(RADEON_DP_BRUSH_BKGD_CLR, info->state_2d.dp_brush_bkgd_clr);
111 OUT_ACCEL_REG(RADEON_DP_SRC_FRGD_CLR, info->state_2d.dp_src_frgd_clr);
112 OUT_ACCEL_REG(RADEON_DP_SRC_BKGD_CLR, info->state_2d.dp_src_bkgd_clr);
113 OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, info->state_2d.dp_write_mask);
114 OUT_ACCEL_REG(RADEON_DP_CNTL, info->state_2d.dp_cntl);
115
116 OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, info->state_2d.dst_pitch_offset);
117 if (info->cs)
118 OUT_RELOC(info->state_2d.dst_bo, 0, RADEON_GEM_DOMAIN_VRAM);
119
120 if (has_src) {
121 OUT_ACCEL_REG(RADEON_SRC_PITCH_OFFSET, info->state_2d.src_pitch_offset);
122 if (info->cs)
123 OUT_RELOC(info->state_2d.src_bo, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0);
124
125 }
126 FINISH_ACCEL();
127
128 if (op)
129 info->state_2d.op = op;
130 if (info->cs)
131 info->reemit_current2d = FUNC_NAME(Emit2DState);
132}
133
87static Bool 134static Bool
88FUNC_NAME(RADEONPrepareSolid)(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) 135FUNC_NAME(RADEONPrepareSolid)(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
89{ 136{
90 RINFO_FROM_SCREEN(pPix->drawable.pScreen); 137 RINFO_FROM_SCREEN(pPix->drawable.pScreen);
91 uint32_t datatype, dst_pitch_offset; 138 uint32_t datatype, dst_pitch_offset;
139 struct radeon_exa_pixmap_priv *driver_priv;
140 int ret;
141 int retry_count = 0;
142 struct radeon_cs_space_check bos[1];
143 int i;
92 ACCEL_PREAMBLE(); 144 ACCEL_PREAMBLE();
93 145
94 TRACE; 146 TRACE;
@@ -101,21 +153,54 @@ FUNC_NAME(RADEONPrepareSolid)(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
101 RADEON_FALLBACK(("RADEONGetPixmapOffsetPitch failed\n")); 153 RADEON_FALLBACK(("RADEONGetPixmapOffsetPitch failed\n"));
102 154
103 RADEON_SWITCH_TO_2D(); 155 RADEON_SWITCH_TO_2D();
156 retry:
157 if (info->cs) {
158
159 i = 0;
160 driver_priv = exaGetPixmapDriverPrivate(pPix);
161 bos[i].bo = driver_priv->bo;
162 bos[i].read_domains = 0;
163 bos[i].write_domain = RADEON_GEM_DOMAIN_VRAM;;
164 bos[i].new_accounted = 0;
165 i++;
166
167 ret = radeon_cs_space_check(info->cs, bos, i);
168 if (ret == RADEON_CS_SPACE_OP_TO_BIG) {
169 RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n"));
170 }
171 if (ret == RADEON_CS_SPACE_FLUSH) {
172 radeon_cs_flush_indirect(pScrn);
173 retry_count++;
174 if (retry_count == 2)
175 RADEON_FALLBACK(("Not enough Video RAM for src\n"));
176 goto retry;
177 }
178 }
104 179
105 BEGIN_ACCEL(5); 180
106 OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, 181 info->state_2d.default_sc_bottom_right = (RADEON_DEFAULT_SC_RIGHT_MAX |
107 RADEON_GMC_DST_PITCH_OFFSET_CNTL | 182 RADEON_DEFAULT_SC_BOTTOM_MAX);
108 RADEON_GMC_BRUSH_SOLID_COLOR | 183 info->state_2d.dp_brush_bkgd_clr = 0x00000000;
109 (datatype << 8) | 184 info->state_2d.dp_src_frgd_clr = 0xffffffff;
110 RADEON_GMC_SRC_DATATYPE_COLOR | 185 info->state_2d.dp_src_bkgd_clr = 0x00000000;
111 RADEON_ROP[alu].pattern | 186 info->state_2d.dp_gui_master_cntl = (RADEON_GMC_DST_PITCH_OFFSET_CNTL |
112 RADEON_GMC_CLR_CMP_CNTL_DIS); 187 RADEON_GMC_BRUSH_SOLID_COLOR |
113 OUT_ACCEL_REG(RADEON_DP_BRUSH_FRGD_CLR, fg); 188 (datatype << 8) |
114 OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, pm); 189 RADEON_GMC_SRC_DATATYPE_COLOR |
115 OUT_ACCEL_REG(RADEON_DP_CNTL, 190 RADEON_ROP[alu].pattern |
116 (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM)); 191 RADEON_GMC_CLR_CMP_CNTL_DIS);
117 OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, dst_pitch_offset); 192 info->state_2d.dp_brush_frgd_clr = fg;
118 FINISH_ACCEL(); 193 info->state_2d.dp_cntl = (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM);
194 info->state_2d.dp_write_mask = pm;
195 info->state_2d.dst_pitch_offset = dst_pitch_offset;
196 info->state_2d.src_pitch_offset = 0;
197 info->state_2d.src_bo = NULL;
198
199 driver_priv = exaGetPixmapDriverPrivate(pPix);
200 if (driver_priv)
201 info->state_2d.dst_bo = driver_priv->bo;
202
203 FUNC_NAME(Emit2DState)(pScrn, RADEON_2D_EXA_SOLID);
119 204
120 return TRUE; 205 return TRUE;
121} 206}
@@ -146,6 +231,7 @@ FUNC_NAME(RADEONDone2D)(PixmapPtr pPix)
146 231
147 TRACE; 232 TRACE;
148 233
234 info->state_2d.op = 0;
149 BEGIN_ACCEL(2); 235 BEGIN_ACCEL(2);
150 OUT_ACCEL_REG(RADEON_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL); 236 OUT_ACCEL_REG(RADEON_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL);
151 OUT_ACCEL_REG(RADEON_WAIT_UNTIL, 237 OUT_ACCEL_REG(RADEON_WAIT_UNTIL,
@@ -161,25 +247,28 @@ FUNC_NAME(RADEONDoPrepareCopy)(ScrnInfoPtr pScrn, uint32_t src_pitch_offset,
161 RADEONInfoPtr info = RADEONPTR(pScrn); 247 RADEONInfoPtr info = RADEONPTR(pScrn);
162 ACCEL_PREAMBLE(); 248 ACCEL_PREAMBLE();
163 249
164 RADEON_SWITCH_TO_2D(); 250 /* setup 2D state */
165 251 info->state_2d.dp_gui_master_cntl = (RADEON_GMC_DST_PITCH_OFFSET_CNTL |
166 BEGIN_ACCEL(5); 252 RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
167 OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, 253 RADEON_GMC_BRUSH_NONE |
168 RADEON_GMC_DST_PITCH_OFFSET_CNTL | 254 (datatype << 8) |
169 RADEON_GMC_SRC_PITCH_OFFSET_CNTL | 255 RADEON_GMC_SRC_DATATYPE_COLOR |
170 RADEON_GMC_BRUSH_NONE | 256 RADEON_ROP[rop].rop |
171 (datatype << 8) | 257 RADEON_DP_SRC_SOURCE_MEMORY |
172 RADEON_GMC_SRC_DATATYPE_COLOR | 258 RADEON_GMC_CLR_CMP_CNTL_DIS);
173 RADEON_ROP[rop].rop | 259 info->state_2d.dp_cntl = ((info->accel_state->xdir >= 0 ? RADEON_DST_X_LEFT_TO_RIGHT : 0) |
174 RADEON_DP_SRC_SOURCE_MEMORY | 260 (info->accel_state->ydir >= 0 ? RADEON_DST_Y_TOP_TO_BOTTOM : 0));
175 RADEON_GMC_CLR_CMP_CNTL_DIS); 261 info->state_2d.dp_brush_frgd_clr = 0xffffffff;
176 OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, planemask); 262 info->state_2d.dp_brush_bkgd_clr = 0x00000000;
177 OUT_ACCEL_REG(RADEON_DP_CNTL, 263 info->state_2d.dp_src_frgd_clr = 0xffffffff;
178 ((info->accel_state->xdir >= 0 ? RADEON_DST_X_LEFT_TO_RIGHT : 0) | 264 info->state_2d.dp_src_bkgd_clr = 0x00000000;
179 (info->accel_state->ydir >= 0 ? RADEON_DST_Y_TOP_TO_BOTTOM : 0))); 265 info->state_2d.dp_write_mask = planemask;
180 OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, dst_pitch_offset); 266 info->state_2d.dst_pitch_offset = dst_pitch_offset;
181 OUT_ACCEL_REG(RADEON_SRC_PITCH_OFFSET, src_pitch_offset); 267 info->state_2d.src_pitch_offset = src_pitch_offset;
182 FINISH_ACCEL(); 268 info->state_2d.default_sc_bottom_right = (RADEON_DEFAULT_SC_RIGHT_MAX
269 | RADEON_DEFAULT_SC_BOTTOM_MAX);
270
271 FUNC_NAME(Emit2DState)(pScrn, RADEON_2D_EXA_COPY);
183} 272}
184 273
185static Bool 274static Bool
@@ -190,9 +279,42 @@ FUNC_NAME(RADEONPrepareCopy)(PixmapPtr pSrc, PixmapPtr pDst,
190{ 279{
191 RINFO_FROM_SCREEN(pDst->drawable.pScreen); 280 RINFO_FROM_SCREEN(pDst->drawable.pScreen);
192 uint32_t datatype, src_pitch_offset, dst_pitch_offset; 281 uint32_t datatype, src_pitch_offset, dst_pitch_offset;
193 282 struct radeon_exa_pixmap_priv *driver_priv;
283 int ret;
284 int retry_count = 0;
285 struct radeon_cs_space_check bos[2];
286 int i;
194 TRACE; 287 TRACE;
195 288
289 RADEON_SWITCH_TO_2D();
290retry:
291 if (info->cs) {
292
293 driver_priv = exaGetPixmapDriverPrivate(pSrc);
294 info->state_2d.src_bo = driver_priv->bo;
295
296 driver_priv = exaGetPixmapDriverPrivate(pDst);
297 info->state_2d.dst_bo = driver_priv->bo;
298
299 i = 0;
300 radeon_add_pixmap(bos, i++, pSrc, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
301
302 radeon_add_pixmap(bos, i++, pDst, 0, RADEON_GEM_DOMAIN_VRAM);
303
304 ret = radeon_cs_space_check(info->cs, bos, i);
305 if (ret == RADEON_CS_SPACE_OP_TO_BIG) {
306 RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n"));
307 }
308 if (ret == RADEON_CS_SPACE_FLUSH) {
309 radeon_cs_flush_indirect(pScrn);
310 retry_count++;
311 if (retry_count == 2)
312 RADEON_FALLBACK(("Not enough Video RAM for src\n"));
313 goto retry;
314 }
315 }
316
317
196 info->accel_state->xdir = xdir; 318 info->accel_state->xdir = xdir;
197 info->accel_state->ydir = ydir; 319 info->accel_state->ydir = ydir;
198 320
@@ -256,6 +378,9 @@ RADEONUploadToScreenCP(PixmapPtr pDst, int x, int y, int w, int h,
256 378
257 TRACE; 379 TRACE;
258 380
381 if (info->cs)
382 return FALSE;
383
259 if (bpp < 8) 384 if (bpp < 8)
260 return FALSE; 385 return FALSE;
261 386
@@ -458,9 +583,9 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
458#endif 583#endif
459 584
460#if X_BYTE_ORDER == X_BIG_ENDIAN 585#if X_BYTE_ORDER == X_BIG_ENDIAN
461 info->accel_state->exa->PrepareAccess = RADEONPrepareAccess; 586 info->accel_state->exa->PrepareAccess = RADEONPrepareAccess_BE;
462 info->accel_state->exa->FinishAccess = RADEONFinishAccess; 587 info->accel_state->exa->FinishAccess = RADEONFinishAccess_BE;
463#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */ 588#endif
464 589
465 info->accel_state->exa->flags = EXA_OFFSCREEN_PIXMAPS; 590 info->accel_state->exa->flags = EXA_OFFSCREEN_PIXMAPS;
466#ifdef EXA_SUPPORTS_PREPARE_AUX 591#ifdef EXA_SUPPORTS_PREPARE_AUX
@@ -473,6 +598,10 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
473 info->accel_state->exa->pixmapOffsetAlign = RADEON_BUFFER_ALIGN + 1; 598 info->accel_state->exa->pixmapOffsetAlign = RADEON_BUFFER_ALIGN + 1;
474 info->accel_state->exa->pixmapPitchAlign = 64; 599 info->accel_state->exa->pixmapPitchAlign = 64;
475 600
601 if (info->cs)
602 info->accel_state->exa->flags |= EXA_HANDLES_PIXMAPS;
603
604
476#ifdef RENDER 605#ifdef RENDER
477 if (info->RenderAccel) { 606 if (info->RenderAccel) {
478 if (IS_R300_3D || IS_R500_3D) { 607 if (IS_R300_3D || IS_R500_3D) {
@@ -510,6 +639,19 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
510 } 639 }
511#endif 640#endif
512 641
642#ifdef XF86DRM_MODE
643#if (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 4)
644 if (info->cs) {
645 info->accel_state->exa->CreatePixmap = RADEONEXACreatePixmap;
646 info->accel_state->exa->DestroyPixmap = RADEONEXADestroyPixmap;
647 info->accel_state->exa->PixmapIsOffscreen = RADEONEXAPixmapIsOffscreen;
648 info->accel_state->exa->PrepareAccess = RADEONPrepareAccess_CS;
649 info->accel_state->exa->FinishAccess = RADEONFinishAccess_CS;
650 }
651#endif
652#endif
653
654
513#if EXA_VERSION_MAJOR > 2 || (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 3) 655#if EXA_VERSION_MAJOR > 2 || (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 3)
514 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting EXA maxPitchBytes\n"); 656 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting EXA maxPitchBytes\n");
515 657
diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c
index e2742056..60c40a23 100644
--- a/src/radeon_exa_render.c
+++ b/src/radeon_exa_render.c
@@ -365,13 +365,14 @@ static Bool FUNC_NAME(R100TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
365 Bool repeat = pPict->repeat && pPict->repeatType != RepeatPad && 365 Bool repeat = pPict->repeat && pPict->repeatType != RepeatPad &&
366 !(unit == 0 && (info->accel_state->need_src_tile_x || info->accel_state->need_src_tile_y)); 366 !(unit == 0 && (info->accel_state->need_src_tile_x || info->accel_state->need_src_tile_y));
367 int i; 367 int i;
368 struct radeon_exa_pixmap_priv *driver_priv;
368 ACCEL_PREAMBLE(); 369 ACCEL_PREAMBLE();
369 370
370 txpitch = exaGetPixmapPitch(pPix); 371 txpitch = exaGetPixmapPitch(pPix);
371 txoffset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset; 372 txoffset = 0;
373
374 CHECK_OFFSET(pPix, 0x1f, "texture");
372 375
373 if ((txoffset & 0x1f) != 0)
374 RADEON_FALLBACK(("Bad texture offset 0x%x\n", (int)txoffset));
375 if ((txpitch & 0x1f) != 0) 376 if ((txpitch & 0x1f) != 0)
376 RADEON_FALLBACK(("Bad texture pitch 0x%x\n", (int)txpitch)); 377 RADEON_FALLBACK(("Bad texture pitch 0x%x\n", (int)txpitch));
377 378
@@ -426,23 +427,27 @@ static Bool FUNC_NAME(R100TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
426 } 427 }
427 } 428 }
428 429
429 BEGIN_ACCEL(5); 430 BEGIN_ACCEL_RELOC(5, 1);
430 if (unit == 0) { 431 if (unit == 0) {
431 OUT_ACCEL_REG(RADEON_PP_TXFILTER_0, txfilter); 432 OUT_ACCEL_REG(RADEON_PP_TXFILTER_0, txfilter);
432 OUT_ACCEL_REG(RADEON_PP_TXFORMAT_0, txformat); 433 OUT_ACCEL_REG(RADEON_PP_TXFORMAT_0, txformat);
433 OUT_ACCEL_REG(RADEON_PP_TXOFFSET_0, txoffset);
434 OUT_ACCEL_REG(RADEON_PP_TEX_SIZE_0, 434 OUT_ACCEL_REG(RADEON_PP_TEX_SIZE_0,
435 (pPix->drawable.width - 1) | 435 (pPix->drawable.width - 1) |
436 ((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT)); 436 ((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT));
437 OUT_ACCEL_REG(RADEON_PP_TEX_PITCH_0, txpitch - 32); 437 OUT_ACCEL_REG(RADEON_PP_TEX_PITCH_0, txpitch - 32);
438
439 EMIT_READ_OFFSET(RADEON_PP_TXOFFSET_0, txoffset, pPix);
440 /* emit a texture relocation */
438 } else { 441 } else {
439 OUT_ACCEL_REG(RADEON_PP_TXFILTER_1, txfilter); 442 OUT_ACCEL_REG(RADEON_PP_TXFILTER_1, txfilter);
440 OUT_ACCEL_REG(RADEON_PP_TXFORMAT_1, txformat); 443 OUT_ACCEL_REG(RADEON_PP_TXFORMAT_1, txformat);
441 OUT_ACCEL_REG(RADEON_PP_TXOFFSET_1, txoffset); 444
442 OUT_ACCEL_REG(RADEON_PP_TEX_SIZE_1, 445 OUT_ACCEL_REG(RADEON_PP_TEX_SIZE_1,
443 (pPix->drawable.width - 1) | 446 (pPix->drawable.width - 1) |
444 ((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT)); 447 ((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT));
445 OUT_ACCEL_REG(RADEON_PP_TEX_PITCH_1, txpitch - 32); 448 OUT_ACCEL_REG(RADEON_PP_TEX_PITCH_1, txpitch - 32);
449 EMIT_READ_OFFSET(RADEON_PP_TXOFFSET_1, txoffset, pPix);
450 /* emit a texture relocation */
446 } 451 }
447 FINISH_ACCEL(); 452 FINISH_ACCEL();
448 453
@@ -548,9 +553,13 @@ static Bool FUNC_NAME(R100PrepareComposite)(int op,
548 PixmapPtr pDst) 553 PixmapPtr pDst)
549{ 554{
550 RINFO_FROM_SCREEN(pDst->drawable.pScreen); 555 RINFO_FROM_SCREEN(pDst->drawable.pScreen);
551 uint32_t dst_format, dst_offset, dst_pitch, colorpitch; 556 uint32_t dst_format, dst_pitch, colorpitch;
552 uint32_t pp_cntl, blendcntl, cblend, ablend; 557 uint32_t pp_cntl, blendcntl, cblend, ablend;
553 int pixel_shift; 558 int pixel_shift;
559 struct radeon_exa_pixmap_priv *driver_priv;
560 int retry_count = 0;
561 struct radeon_cs_space_check bos[3];
562 int i, ret;
554 ACCEL_PREAMBLE(); 563 ACCEL_PREAMBLE();
555 564
556 TRACE; 565 TRACE;
@@ -568,24 +577,45 @@ static Bool FUNC_NAME(R100PrepareComposite)(int op,
568 577
569 pixel_shift = pDst->drawable.bitsPerPixel >> 4; 578 pixel_shift = pDst->drawable.bitsPerPixel >> 4;
570 579
571 dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset;
572 dst_pitch = exaGetPixmapPitch(pDst); 580 dst_pitch = exaGetPixmapPitch(pDst);
573 colorpitch = dst_pitch >> pixel_shift; 581 colorpitch = dst_pitch >> pixel_shift;
574 if (RADEONPixmapIsColortiled(pDst)) 582 if (RADEONPixmapIsColortiled(pDst))
575 colorpitch |= RADEON_COLOR_TILE_ENABLE; 583 colorpitch |= RADEON_COLOR_TILE_ENABLE;
576 584
577 dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset; 585 CHECK_OFFSET(pDst, 0x0f, "destination");
578 dst_pitch = exaGetPixmapPitch(pDst); 586
579 if ((dst_offset & 0x0f) != 0)
580 RADEON_FALLBACK(("Bad destination offset 0x%x\n", (int)dst_offset));
581 if (((dst_pitch >> pixel_shift) & 0x7) != 0) 587 if (((dst_pitch >> pixel_shift) & 0x7) != 0)
582 RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch)); 588 RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch));
583 589
590 /* switch to 3D before doing buffer space checks as it may flush */
591 RADEON_SWITCH_TO_3D();
592 retry:
593 if (info->cs) {
594
595 i = 0;
596 radeon_add_pixmap(bos, i++, pSrc, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
597
598 if (pMask)
599 radeon_add_pixmap(bos, i++, pMask, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
600
601 radeon_add_pixmap(bos, i++, pDst, 0, RADEON_GEM_DOMAIN_VRAM);
602
603 ret = radeon_cs_space_check(info->cs, bos, i);
604 if (ret == RADEON_CS_SPACE_OP_TO_BIG) {
605 RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n"));
606 }
607 if (ret == RADEON_CS_SPACE_FLUSH) {
608 radeon_cs_flush_indirect(pScrn);
609 retry_count++;
610 if (retry_count == 2)
611 RADEON_FALLBACK(("Not enough Video RAM for src\n"));
612 goto retry;
613 }
614 }
615
584 if (!RADEONSetupSourceTile(pSrcPicture, pSrc, FALSE, TRUE)) 616 if (!RADEONSetupSourceTile(pSrcPicture, pSrc, FALSE, TRUE))
585 return FALSE; 617 return FALSE;
586 618
587 RADEON_SWITCH_TO_3D();
588
589 if (!FUNC_NAME(R100TextureSetup)(pSrcPicture, pSrc, 0)) 619 if (!FUNC_NAME(R100TextureSetup)(pSrcPicture, pSrc, 0))
590 return FALSE; 620 return FALSE;
591 pp_cntl = RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE; 621 pp_cntl = RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE;
@@ -598,10 +628,10 @@ static Bool FUNC_NAME(R100PrepareComposite)(int op,
598 info->accel_state->is_transform[1] = FALSE; 628 info->accel_state->is_transform[1] = FALSE;
599 } 629 }
600 630
601 BEGIN_ACCEL(10); 631 BEGIN_ACCEL_RELOC(10, 1);
602 OUT_ACCEL_REG(RADEON_PP_CNTL, pp_cntl); 632 OUT_ACCEL_REG(RADEON_PP_CNTL, pp_cntl);
603 OUT_ACCEL_REG(RADEON_RB3D_CNTL, dst_format | RADEON_ALPHA_BLEND_ENABLE); 633 OUT_ACCEL_REG(RADEON_RB3D_CNTL, dst_format | RADEON_ALPHA_BLEND_ENABLE);
604 OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset); 634 EMIT_WRITE_OFFSET(RADEON_RB3D_COLOROFFSET, 0, pDst);
605 OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, colorpitch); 635 OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, colorpitch);
606 636
607 /* IN operator: Multiply src by mask components or mask alpha. 637 /* IN operator: Multiply src by mask components or mask alpha.
@@ -705,13 +735,14 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
705 Bool repeat = pPict->repeat && pPict->repeatType != RepeatPad && 735 Bool repeat = pPict->repeat && pPict->repeatType != RepeatPad &&
706 !(unit == 0 && (info->accel_state->need_src_tile_x || info->accel_state->need_src_tile_y)); 736 !(unit == 0 && (info->accel_state->need_src_tile_x || info->accel_state->need_src_tile_y));
707 int i; 737 int i;
738 struct radeon_exa_pixmap_priv *driver_priv;
708 ACCEL_PREAMBLE(); 739 ACCEL_PREAMBLE();
709 740
710 txpitch = exaGetPixmapPitch(pPix); 741 txpitch = exaGetPixmapPitch(pPix);
711 txoffset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset;
712 742
713 if ((txoffset & 0x1f) != 0) 743 txoffset = 0;
714 RADEON_FALLBACK(("Bad texture offset 0x%x\n", (int)txoffset)); 744 CHECK_OFFSET(pPix, 0x1f, "texture");
745
715 if ((txpitch & 0x1f) != 0) 746 if ((txpitch & 0x1f) != 0)
716 RADEON_FALLBACK(("Bad texture pitch 0x%x\n", (int)txpitch)); 747 RADEON_FALLBACK(("Bad texture pitch 0x%x\n", (int)txpitch));
717 748
@@ -768,7 +799,7 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
768 } 799 }
769 } 800 }
770 801
771 BEGIN_ACCEL(6); 802 BEGIN_ACCEL_RELOC(6, 1);
772 if (unit == 0) { 803 if (unit == 0) {
773 OUT_ACCEL_REG(R200_PP_TXFILTER_0, txfilter); 804 OUT_ACCEL_REG(R200_PP_TXFILTER_0, txfilter);
774 OUT_ACCEL_REG(R200_PP_TXFORMAT_0, txformat); 805 OUT_ACCEL_REG(R200_PP_TXFORMAT_0, txformat);
@@ -776,7 +807,7 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
776 OUT_ACCEL_REG(R200_PP_TXSIZE_0, (pPix->drawable.width - 1) | 807 OUT_ACCEL_REG(R200_PP_TXSIZE_0, (pPix->drawable.width - 1) |
777 ((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT)); 808 ((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT));
778 OUT_ACCEL_REG(R200_PP_TXPITCH_0, txpitch - 32); 809 OUT_ACCEL_REG(R200_PP_TXPITCH_0, txpitch - 32);
779 OUT_ACCEL_REG(R200_PP_TXOFFSET_0, txoffset); 810 EMIT_READ_OFFSET(R200_PP_TXOFFSET_0, txoffset, pPix);
780 } else { 811 } else {
781 OUT_ACCEL_REG(R200_PP_TXFILTER_1, txfilter); 812 OUT_ACCEL_REG(R200_PP_TXFILTER_1, txfilter);
782 OUT_ACCEL_REG(R200_PP_TXFORMAT_1, txformat); 813 OUT_ACCEL_REG(R200_PP_TXFORMAT_1, txformat);
@@ -784,7 +815,8 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
784 OUT_ACCEL_REG(R200_PP_TXSIZE_1, (pPix->drawable.width - 1) | 815 OUT_ACCEL_REG(R200_PP_TXSIZE_1, (pPix->drawable.width - 1) |
785 ((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT)); 816 ((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT));
786 OUT_ACCEL_REG(R200_PP_TXPITCH_1, txpitch - 32); 817 OUT_ACCEL_REG(R200_PP_TXPITCH_1, txpitch - 32);
787 OUT_ACCEL_REG(R200_PP_TXOFFSET_1, txoffset); 818 EMIT_READ_OFFSET(R200_PP_TXOFFSET_1, txoffset, pPix);
819 /* emit a texture relocation */
788 } 820 }
789 FINISH_ACCEL(); 821 FINISH_ACCEL();
790 822
@@ -878,9 +910,13 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture,
878 PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) 910 PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
879{ 911{
880 RINFO_FROM_SCREEN(pDst->drawable.pScreen); 912 RINFO_FROM_SCREEN(pDst->drawable.pScreen);
881 uint32_t dst_format, dst_offset, dst_pitch; 913 uint32_t dst_format, dst_pitch;
882 uint32_t pp_cntl, blendcntl, cblend, ablend, colorpitch; 914 uint32_t pp_cntl, blendcntl, cblend, ablend, colorpitch;
883 int pixel_shift; 915 int pixel_shift;
916 struct radeon_exa_pixmap_priv *driver_priv;
917 int retry_count = 0;
918 struct radeon_cs_space_check bos[3];
919 int i, ret;
884 ACCEL_PREAMBLE(); 920 ACCEL_PREAMBLE();
885 921
886 TRACE; 922 TRACE;
@@ -898,22 +934,45 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture,
898 934
899 pixel_shift = pDst->drawable.bitsPerPixel >> 4; 935 pixel_shift = pDst->drawable.bitsPerPixel >> 4;
900 936
901 dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset;
902 dst_pitch = exaGetPixmapPitch(pDst); 937 dst_pitch = exaGetPixmapPitch(pDst);
903 colorpitch = dst_pitch >> pixel_shift; 938 colorpitch = dst_pitch >> pixel_shift;
904 if (RADEONPixmapIsColortiled(pDst)) 939 if (RADEONPixmapIsColortiled(pDst))
905 colorpitch |= RADEON_COLOR_TILE_ENABLE; 940 colorpitch |= RADEON_COLOR_TILE_ENABLE;
906 941
907 if ((dst_offset & 0x0f) != 0) 942 CHECK_OFFSET(pDst, 0xf, "destination");
908 RADEON_FALLBACK(("Bad destination offset 0x%x\n", (int)dst_offset)); 943
909 if (((dst_pitch >> pixel_shift) & 0x7) != 0) 944 if (((dst_pitch >> pixel_shift) & 0x7) != 0)
910 RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch)); 945 RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch));
911 946
947 /* switch to 3D before doing buffer space checks as it may flush */
948 RADEON_SWITCH_TO_3D();
949
950 retry:
951 if (info->cs) {
952
953 i = 0;
954 radeon_add_pixmap(bos, i++, pSrc, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
955
956 if (pMask)
957 radeon_add_pixmap(bos, i++, pMask, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
958
959 radeon_add_pixmap(bos, i++, pDst, 0, RADEON_GEM_DOMAIN_VRAM);
960
961 ret = radeon_cs_space_check(info->cs, bos, i);
962 if (ret == RADEON_CS_SPACE_OP_TO_BIG) {
963 RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n"));
964 }
965 if (ret == RADEON_CS_SPACE_FLUSH) {
966 radeon_cs_flush_indirect(pScrn);
967 retry_count++;
968 if (retry_count == 2)
969 RADEON_FALLBACK(("Not enough Video RAM for src\n"));
970 goto retry;
971 }
972 }
912 if (!RADEONSetupSourceTile(pSrcPicture, pSrc, FALSE, TRUE)) 973 if (!RADEONSetupSourceTile(pSrcPicture, pSrc, FALSE, TRUE))
913 return FALSE; 974 return FALSE;
914 975
915 RADEON_SWITCH_TO_3D();
916
917 if (!FUNC_NAME(R200TextureSetup)(pSrcPicture, pSrc, 0)) 976 if (!FUNC_NAME(R200TextureSetup)(pSrcPicture, pSrc, 0))
918 return FALSE; 977 return FALSE;
919 pp_cntl = RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE; 978 pp_cntl = RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE;
@@ -926,11 +985,12 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture,
926 info->accel_state->is_transform[1] = FALSE; 985 info->accel_state->is_transform[1] = FALSE;
927 } 986 }
928 987
929 BEGIN_ACCEL(13); 988 BEGIN_ACCEL_RELOC(13, 1);
930 989
931 OUT_ACCEL_REG(RADEON_PP_CNTL, pp_cntl); 990 OUT_ACCEL_REG(RADEON_PP_CNTL, pp_cntl);
932 OUT_ACCEL_REG(RADEON_RB3D_CNTL, dst_format | RADEON_ALPHA_BLEND_ENABLE); 991 OUT_ACCEL_REG(RADEON_RB3D_CNTL, dst_format | RADEON_ALPHA_BLEND_ENABLE);
933 OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset); 992
993 EMIT_WRITE_OFFSET(RADEON_RB3D_COLOROFFSET, 0, pDst);
934 994
935 OUT_ACCEL_REG(R200_SE_VTX_FMT_0, R200_VTX_XY); 995 OUT_ACCEL_REG(R200_SE_VTX_FMT_0, R200_VTX_XY);
936 if (pMask) 996 if (pMask)
@@ -1004,6 +1064,10 @@ static Bool R300CheckCompositeTexture(PicturePtr pPict,
1004 int unit, 1064 int unit,
1005 Bool is_r500) 1065 Bool is_r500)
1006{ 1066{
1067 ScreenPtr pScreen = pDstPict->pDrawable->pScreen;
1068 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1069 RADEONInfoPtr info = RADEONPTR(pScrn);
1070
1007 int w = pPict->pDrawable->width; 1071 int w = pPict->pDrawable->width;
1008 int h = pPict->pDrawable->height; 1072 int h = pPict->pDrawable->height;
1009 int i; 1073 int i;
@@ -1029,8 +1093,17 @@ static Bool R300CheckCompositeTexture(PicturePtr pPict,
1029 RADEON_FALLBACK(("Unsupported picture format 0x%x\n", 1093 RADEON_FALLBACK(("Unsupported picture format 0x%x\n",
1030 (int)pPict->format)); 1094 (int)pPict->format));
1031 1095
1032 if (!RADEONCheckTexturePOT(pPict, unit == 0)) 1096 if (!RADEONCheckTexturePOT(pPict, unit == 0)) {
1097 if (info->cs) {
1098 struct radeon_exa_pixmap_priv *driver_priv;
1099 PixmapPtr pPix;
1100
1101 pPix = RADEONGetDrawablePixmap(pPict->pDrawable);
1102 driver_priv = exaGetPixmapDriverPrivate(pPix);
1103 //TODOradeon_bufmgr_gem_force_gtt(driver_priv->bo);
1104 }
1033 return FALSE; 1105 return FALSE;
1106 }
1034 1107
1035 if (pPict->filter != PictFilterNearest && 1108 if (pPict->filter != PictFilterNearest &&
1036 pPict->filter != PictFilterBilinear) 1109 pPict->filter != PictFilterBilinear)
@@ -1062,15 +1135,16 @@ static Bool FUNC_NAME(R300TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
1062 int w = pPict->pDrawable->width; 1135 int w = pPict->pDrawable->width;
1063 int h = pPict->pDrawable->height; 1136 int h = pPict->pDrawable->height;
1064 int i, pixel_shift; 1137 int i, pixel_shift;
1138 struct radeon_exa_pixmap_priv *driver_priv;
1065 ACCEL_PREAMBLE(); 1139 ACCEL_PREAMBLE();
1066 1140
1067 TRACE; 1141 TRACE;
1068 1142
1069 txpitch = exaGetPixmapPitch(pPix); 1143 txpitch = exaGetPixmapPitch(pPix);
1070 txoffset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset; 1144 txoffset = 0;
1145
1146 CHECK_OFFSET(pPix, 0x1f, "texture");
1071 1147
1072 if ((txoffset & 0x1f) != 0)
1073 RADEON_FALLBACK(("Bad texture offset 0x%x\n", (int)txoffset));
1074 if ((txpitch & 0x1f) != 0) 1148 if ((txpitch & 0x1f) != 0)
1075 RADEON_FALLBACK(("Bad texture pitch 0x%x\n", (int)txpitch)); 1149 RADEON_FALLBACK(("Bad texture pitch 0x%x\n", (int)txpitch));
1076 1150
@@ -1156,13 +1230,15 @@ static Bool FUNC_NAME(R300TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
1156 RADEON_FALLBACK(("Bad filter 0x%x\n", pPict->filter)); 1230 RADEON_FALLBACK(("Bad filter 0x%x\n", pPict->filter));
1157 } 1231 }
1158 1232
1159 BEGIN_ACCEL(pPict->repeat ? 6 : 7); 1233 BEGIN_ACCEL_RELOC(pPict->repeat ? 6 : 7, 1);
1160 OUT_ACCEL_REG(R300_TX_FILTER0_0 + (unit * 4), txfilter); 1234 OUT_ACCEL_REG(R300_TX_FILTER0_0 + (unit * 4), txfilter);
1161 OUT_ACCEL_REG(R300_TX_FILTER1_0 + (unit * 4), 0); 1235 OUT_ACCEL_REG(R300_TX_FILTER1_0 + (unit * 4), 0);
1162 OUT_ACCEL_REG(R300_TX_FORMAT0_0 + (unit * 4), txformat0); 1236 OUT_ACCEL_REG(R300_TX_FORMAT0_0 + (unit * 4), txformat0);
1163 OUT_ACCEL_REG(R300_TX_FORMAT1_0 + (unit * 4), txformat1); 1237 OUT_ACCEL_REG(R300_TX_FORMAT1_0 + (unit * 4), txformat1);
1164 OUT_ACCEL_REG(R300_TX_FORMAT2_0 + (unit * 4), txpitch); 1238 OUT_ACCEL_REG(R300_TX_FORMAT2_0 + (unit * 4), txpitch);
1165 OUT_ACCEL_REG(R300_TX_OFFSET_0 + (unit * 4), txoffset); 1239
1240 EMIT_READ_OFFSET((R300_TX_OFFSET_0 + (unit * 4)), txoffset, pPix);
1241
1166 if (!pPict->repeat) 1242 if (!pPict->repeat)
1167 OUT_ACCEL_REG(R300_TX_BORDER_COLOR_0 + (unit * 4), 0); 1243 OUT_ACCEL_REG(R300_TX_BORDER_COLOR_0 + (unit * 4), 0);
1168 FINISH_ACCEL(); 1244 FINISH_ACCEL();
@@ -1321,14 +1397,18 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
1321 PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) 1397 PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
1322{ 1398{
1323 RINFO_FROM_SCREEN(pDst->drawable.pScreen); 1399 RINFO_FROM_SCREEN(pDst->drawable.pScreen);
1324 uint32_t dst_format, dst_offset, dst_pitch; 1400 uint32_t dst_format, dst_pitch;
1325 uint32_t txenable, colorpitch; 1401 uint32_t txenable, colorpitch;
1326 uint32_t blendcntl, output_fmt; 1402 uint32_t blendcntl, output_fmt;
1327 uint32_t src_color, src_alpha; 1403 uint32_t src_color, src_alpha;
1328 uint32_t mask_color, mask_alpha; 1404 uint32_t mask_color, mask_alpha;
1329 int pixel_shift; 1405 int pixel_shift;
1406 int ret;
1407 int retry_count = 0;
1408 struct radeon_exa_pixmap_priv *driver_priv;
1409 struct radeon_cs_space_check bos[3];
1410 int i;
1330 ACCEL_PREAMBLE(); 1411 ACCEL_PREAMBLE();
1331
1332 TRACE; 1412 TRACE;
1333 1413
1334 if (!R300GetDestFormat(pDstPicture, &dst_format)) 1414 if (!R300GetDestFormat(pDstPicture, &dst_format))
@@ -1341,7 +1421,6 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
1341 1421
1342 pixel_shift = pDst->drawable.bitsPerPixel >> 4; 1422 pixel_shift = pDst->drawable.bitsPerPixel >> 4;
1343 1423
1344 dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset;
1345 dst_pitch = exaGetPixmapPitch(pDst); 1424 dst_pitch = exaGetPixmapPitch(pDst);
1346 colorpitch = dst_pitch >> pixel_shift; 1425 colorpitch = dst_pitch >> pixel_shift;
1347 1426
@@ -1350,16 +1429,41 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
1350 1429
1351 colorpitch |= dst_format; 1430 colorpitch |= dst_format;
1352 1431
1353 if ((dst_offset & 0x0f) != 0) 1432 CHECK_OFFSET(pDst, 0x0f, "destination");
1354 RADEON_FALLBACK(("Bad destination offset 0x%x\n", (int)dst_offset)); 1433
1355 if (((dst_pitch >> pixel_shift) & 0x7) != 0) 1434 if (((dst_pitch >> pixel_shift) & 0x7) != 0)
1356 RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch)); 1435 RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch));
1357 1436
1437 /* have to execute switch before doing buffer sizing check as it flushes */
1438 RADEON_SWITCH_TO_3D();
1439 retry:
1440 if (info->cs) {
1441
1442 i = 0;
1443 driver_priv = exaGetPixmapDriverPrivate(pSrc);
1444 radeon_add_pixmap(bos, i++, pSrc, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
1445
1446 if (pMask)
1447 radeon_add_pixmap(bos, i++, pMask, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
1448
1449 radeon_add_pixmap(bos, i++, pDst, 0, RADEON_GEM_DOMAIN_VRAM);
1450
1451 ret = radeon_cs_space_check(info->cs, bos, i);
1452 if (ret == RADEON_CS_SPACE_OP_TO_BIG) {
1453 RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n"));
1454 }
1455 if (ret == RADEON_CS_SPACE_FLUSH) {
1456 radeon_cs_flush_indirect(pScrn);
1457 retry_count++;
1458 if (retry_count == 2)
1459 RADEON_FALLBACK(("Not enough Video RAM - this really shouldn't happen\nm"));
1460 goto retry;
1461 }
1462 }
1463
1358 if (!RADEONSetupSourceTile(pSrcPicture, pSrc, TRUE, FALSE)) 1464 if (!RADEONSetupSourceTile(pSrcPicture, pSrc, TRUE, FALSE))
1359 return FALSE; 1465 return FALSE;
1360 1466
1361 RADEON_SWITCH_TO_3D();
1362
1363 if (!FUNC_NAME(R300TextureSetup)(pSrcPicture, pSrc, 0)) 1467 if (!FUNC_NAME(R300TextureSetup)(pSrcPicture, pSrc, 0))
1364 return FALSE; 1468 return FALSE;
1365 txenable = R300_TEX_0_ENABLE; 1469 txenable = R300_TEX_0_ENABLE;
@@ -1945,9 +2049,9 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
1945 } 2049 }
1946 FINISH_ACCEL(); 2050 FINISH_ACCEL();
1947 2051
1948 BEGIN_ACCEL(3); 2052
1949 2053 BEGIN_ACCEL_RELOC(3, 1);
1950 OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset); 2054 EMIT_WRITE_OFFSET(R300_RB3D_COLOROFFSET0, 0, pDst);
1951 OUT_ACCEL_REG(R300_RB3D_COLORPITCH0, colorpitch); 2055 OUT_ACCEL_REG(R300_RB3D_COLORPITCH0, colorpitch);
1952 2056
1953 blendcntl = RADEONGetBlendCntl(op, pMaskPicture, pDstPicture->format); 2057 blendcntl = RADEONGetBlendCntl(op, pMaskPicture, pDstPicture->format);
diff --git a/src/radeon_macros.h b/src/radeon_macros.h
index 8575884c..15d9d73a 100644
--- a/src/radeon_macros.h
+++ b/src/radeon_macros.h
@@ -160,4 +160,41 @@ do { \
160#define INPCIE_P(pScrn, addr) R600INPCIE_PORT(pScrn, addr) 160#define INPCIE_P(pScrn, addr) R600INPCIE_PORT(pScrn, addr)
161#define OUTPCIE_P(pScrn, addr, val) R600OUTPCIE_PORT(pScrn, addr, val) 161#define OUTPCIE_P(pScrn, addr, val) R600OUTPCIE_PORT(pScrn, addr, val)
162 162
163#define BEGIN_ACCEL_RELOC(n, r) do { \
164 int _nqw = (n) + (info->cs ? (r) : 0); \
165 BEGIN_ACCEL(_nqw); \
166 } while (0)
167
168#define CHECK_OFFSET(pPix, mask, type) do { \
169 if (!info->cs) { \
170 uint32_t _pix_offset = radeonGetPixmapOffset(pPix); \
171 if ((_pix_offset & mask) != 0) \
172 RADEON_FALLBACK(("Bad %s offset 0x%x\n", type, (int)pix_offset)); \
173 } \
174 } while(0)
175
176#define EMIT_OFFSET(reg, value, pPix, rd, wd) do { \
177 if (info->cs) { \
178 driver_priv = exaGetPixmapDriverPrivate(pPix); \
179 OUT_ACCEL_REG((reg), 0); \
180 OUT_RELOC(driver_priv->bo, (rd), (wd)); \
181 } else { \
182 uint32_t _pix_offset; \
183 _pix_offset = radeonGetPixmapOffset(pPix); \
184 OUT_ACCEL_REG((reg), _pix_offset | value); \
185 } \
186 } while(0)
187
188#define EMIT_READ_OFFSET(reg, value, pPix) EMIT_OFFSET(reg, value, pPix, (RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT), 0)
189#define EMIT_WRITE_OFFSET(reg, value, pPix) EMIT_OFFSET(reg, value, pPix, 0, RADEON_GEM_DOMAIN_VRAM)
190
191#define OUT_TEXTURE_REG(reg, offset, bo) do { \
192 if (info->cs) { \
193 OUT_ACCEL_REG((reg), (offset)); \
194 OUT_RELOC((bo), RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); \
195 } else { \
196 OUT_ACCEL_REG((reg), (offset) + info->fbLocation + pScrn->fbOffset);} \
197 } while(0)
198
199
163#endif 200#endif
diff --git a/src/radeon_textured_video.c b/src/radeon_textured_video.c
index ab743beb..10414b91 100644
--- a/src/radeon_textured_video.c
+++ b/src/radeon_textured_video.c
@@ -142,6 +142,7 @@ static REF_TRANSFORM trans[2] =
142#define BEGIN_ACCEL(n) RADEONWaitForFifo(pScrn, (n)) 142#define BEGIN_ACCEL(n) RADEONWaitForFifo(pScrn, (n))
143#define OUT_ACCEL_REG(reg, val) OUTREG(reg, val) 143#define OUT_ACCEL_REG(reg, val) OUTREG(reg, val)
144#define OUT_ACCEL_REG_F(reg, val) OUTREG(reg, F_TO_DW(val)) 144#define OUT_ACCEL_REG_F(reg, val) OUTREG(reg, F_TO_DW(val))
145#define OUT_RELOC(x, read, write) do {} while(0)
145#define FINISH_ACCEL() 146#define FINISH_ACCEL()
146 147
147#include "radeon_textured_videofuncs.c" 148#include "radeon_textured_videofuncs.c"
@@ -151,6 +152,7 @@ static REF_TRANSFORM trans[2] =
151#undef BEGIN_ACCEL 152#undef BEGIN_ACCEL
152#undef OUT_ACCEL_REG 153#undef OUT_ACCEL_REG
153#undef OUT_ACCEL_REG_F 154#undef OUT_ACCEL_REG_F
155#undef OUT_RELOC
154#undef FINISH_ACCEL 156#undef FINISH_ACCEL
155 157
156#ifdef XF86DRI 158#ifdef XF86DRI
@@ -164,6 +166,7 @@ static REF_TRANSFORM trans[2] =
164#define OUT_ACCEL_REG_F(reg, val) OUT_ACCEL_REG(reg, F_TO_DW(val)) 166#define OUT_ACCEL_REG_F(reg, val) OUT_ACCEL_REG(reg, F_TO_DW(val))
165#define FINISH_ACCEL() ADVANCE_RING() 167#define FINISH_ACCEL() ADVANCE_RING()
166#define OUT_RING_F(x) OUT_RING(F_TO_DW(x)) 168#define OUT_RING_F(x) OUT_RING(F_TO_DW(x))
169#define OUT_RELOC(x, read, write) OUT_RING_RELOC(x, read, write)
167 170
168#include "radeon_textured_videofuncs.c" 171#include "radeon_textured_videofuncs.c"
169 172
@@ -323,6 +326,9 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn,
323 size * 2, 64); 326 size * 2, 64);
324 if (pPriv->video_offset == 0) 327 if (pPriv->video_offset == 0)
325 return BadAlloc; 328 return BadAlloc;
329
330 if (info->cs)
331 pPriv->src_bo = pPriv->video_memory;
326 } 332 }
327 333
328 /* Bicubic filter loading */ 334 /* Bicubic filter loading */
@@ -333,6 +339,9 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn,
333 pPriv->bicubic_src_offset = pPriv->bicubic_offset + info->fbLocation + pScrn->fbOffset; 339 pPriv->bicubic_src_offset = pPriv->bicubic_offset + info->fbLocation + pScrn->fbOffset;
334 if (pPriv->bicubic_offset == 0) 340 if (pPriv->bicubic_offset == 0)
335 pPriv->bicubic_enabled = FALSE; 341 pPriv->bicubic_enabled = FALSE;
342
343 if (info->cs)
344 pPriv->bicubic_bo = pPriv->bicubic_memory;
336 } 345 }
337 346
338 if (pDraw->type == DRAWABLE_WINDOW) 347 if (pDraw->type == DRAWABLE_WINDOW)
@@ -361,8 +370,18 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn,
361 top = (y1 >> 16) & ~1; 370 top = (y1 >> 16) & ~1;
362 nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top; 371 nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
363 372
364 pPriv->src_offset = pPriv->video_offset + info->fbLocation + pScrn->fbOffset; 373 pPriv->src_offset = pPriv->video_offset;
365 pPriv->src_addr = (uint8_t *)(info->FB + pPriv->video_offset); 374 if (info->cs) {
375 int ret;
376 radeon_bo_wait(pPriv->src_bo);
377 ret = radeon_bo_map(pPriv->src_bo, 1);
378 if (ret)
379 return BadAlloc;
380
381 pPriv->src_addr = pPriv->src_bo->ptr;
382 } else {
383 pPriv->src_addr = (uint8_t *)(info->FB + pPriv->video_offset);
384 }
366 pPriv->src_pitch = dstPitch; 385 pPriv->src_pitch = dstPitch;
367 386
368 pPriv->planeu_offset = dstPitch * dst_height; 387 pPriv->planeu_offset = dstPitch * dst_height;
@@ -431,9 +450,23 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn,
431 450
432 /* Upload bicubic filter tex */ 451 /* Upload bicubic filter tex */
433 if (pPriv->bicubic_enabled) { 452 if (pPriv->bicubic_enabled) {
434 if (info->ChipFamily < CHIP_FAMILY_R600) 453 if (info->ChipFamily < CHIP_FAMILY_R600) {
435 RADEONCopyData(pScrn, (uint8_t *)bicubic_tex_512, 454 uint8_t *bicubic_addr;
436 (uint8_t *)(info->FB + pPriv->bicubic_offset), 1024, 1024, 1, 512, 2); 455 int ret;
456 if (info->cs) {
457 radeon_bo_wait(pPriv->bicubic_bo);
458 ret = radeon_bo_map(pPriv->bicubic_bo, 1);
459 if (ret)
460 return BadAlloc;
461
462 bicubic_addr = pPriv->bicubic_bo->ptr;
463 } else
464 bicubic_addr = (uint8_t *)(info->FB + pPriv->bicubic_offset);
465
466 RADEONCopyData(pScrn, (uint8_t *)bicubic_tex_512, bicubic_addr, 1024, 1024, 1, 512, 2);
467 if (info->cs)
468 radeon_bo_unmap(pPriv->bicubic_bo);
469 }
437 } 470 }
438 471
439 /* update cliplist */ 472 /* update cliplist */
@@ -453,6 +486,8 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn,
453 pPriv->w = width; 486 pPriv->w = width;
454 pPriv->h = height; 487 pPriv->h = height;
455 488
489 if (info->cs)
490 radeon_bo_unmap(pPriv->src_bo);
456#ifdef XF86DRI 491#ifdef XF86DRI
457 if (info->directRenderingEnabled) { 492 if (info->directRenderingEnabled) {
458 if (IS_R600_3D) 493 if (IS_R600_3D)
diff --git a/src/radeon_textured_videofuncs.c b/src/radeon_textured_videofuncs.c
index 47878fcc..b9930c7a 100644
--- a/src/radeon_textured_videofuncs.c
+++ b/src/radeon_textured_videofuncs.c
@@ -92,27 +92,69 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
92{ 92{
93 RADEONInfoPtr info = RADEONPTR(pScrn); 93 RADEONInfoPtr info = RADEONPTR(pScrn);
94 PixmapPtr pPixmap = pPriv->pPixmap; 94 PixmapPtr pPixmap = pPriv->pPixmap;
95 uint32_t txformat, txsize, txpitch; 95 struct radeon_exa_pixmap_priv *driver_priv;
96 uint32_t dst_offset, dst_pitch, dst_format; 96 struct radeon_cs_space_check bos[3];
97 uint32_t txformat, txsize, txpitch, txoffset;
98 uint32_t dst_pitch, dst_format;
97 uint32_t colorpitch; 99 uint32_t colorpitch;
98 Bool isplanar = FALSE; 100 Bool isplanar = FALSE;
99 int dstxoff, dstyoff, pixel_shift, vtx_count; 101 int dstxoff, dstyoff, pixel_shift, vtx_count;
100 BoxPtr pBox = REGION_RECTS(&pPriv->clip); 102 BoxPtr pBox = REGION_RECTS(&pPriv->clip);
101 int nBox = REGION_NUM_RECTS(&pPriv->clip); 103 int nBox = REGION_NUM_RECTS(&pPriv->clip);
104 int i, ret, retry_count = 0;
102 ACCEL_PREAMBLE(); 105 ACCEL_PREAMBLE();
103 106
107 retry:
108 if (info->cs) {
109
110 i = 0;
111 bos[i].bo = pPriv->src_bo;
112 bos[i].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
113 bos[i].write_domain = 0;
114 bos[i].new_accounted = 0;
115 i++;
116
117 if (pPriv->bicubic_enabled) {
118 bos[i].bo = pPriv->bicubic_bo;
119 bos[i].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
120 bos[i].write_domain = 0;
121 bos[i].new_accounted = 0;
122 i++;
123 }
124
125 driver_priv = exaGetPixmapDriverPrivate(pPixmap);
126 bos[i].bo = driver_priv->bo;
127 bos[i].read_domains = 0;
128 bos[i].write_domain = RADEON_GEM_DOMAIN_VRAM;
129 bos[i].new_accounted = 0;
130 i++;
131
132 ret = radeon_cs_space_check(info->cs, bos, i);
133 if (ret == RADEON_CS_SPACE_OP_TO_BIG) {
134 ErrorF("Not enough RAM to hw accel composite operation\n");
135 return;
136 }
137 if (ret == RADEON_CS_SPACE_FLUSH) {
138 radeon_cs_flush_indirect(pScrn);
139 retry_count++;
140 if (retry_count == 2) {
141 ErrorF("Not enough RAM to hw accel composite operation\n");
142 return;
143 }
144 goto retry;
145 }
146 }
147
104 pixel_shift = pPixmap->drawable.bitsPerPixel >> 4; 148 pixel_shift = pPixmap->drawable.bitsPerPixel >> 4;
105 149
150
106#ifdef USE_EXA 151#ifdef USE_EXA
107 if (info->useEXA) { 152 if (info->useEXA) {
108 dst_offset = exaGetPixmapOffset(pPixmap) + info->fbLocation + pScrn->fbOffset;
109 dst_pitch = exaGetPixmapPitch(pPixmap); 153 dst_pitch = exaGetPixmapPitch(pPixmap);
110 } else 154 } else
111#endif 155#endif
112 { 156 {
113 dst_offset = (pPixmap->devPrivate.ptr - info->FB) + 157 dst_pitch = pPixmap->devKind;
114 info->fbLocation + pScrn->fbOffset;
115 dst_pitch = pPixmap->devKind;
116 } 158 }
117 159
118#ifdef COMPOSITE 160#ifdef COMPOSITE
@@ -175,10 +217,12 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
175 if (RADEONTilingEnabled(pScrn, pPixmap)) 217 if (RADEONTilingEnabled(pScrn, pPixmap))
176 colorpitch |= RADEON_COLOR_TILE_ENABLE; 218 colorpitch |= RADEON_COLOR_TILE_ENABLE;
177 219
178 BEGIN_ACCEL(4); 220 txoffset = info->cs ? 0 : pPriv->src_offset;
221
222 BEGIN_ACCEL_RELOC(4,1);
179 223
180 OUT_ACCEL_REG(RADEON_RB3D_CNTL, dst_format); 224 OUT_ACCEL_REG(RADEON_RB3D_CNTL, dst_format);
181 OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset); 225 EMIT_WRITE_OFFSET(RADEON_RB3D_COLOROFFSET, 0, pPixmap);
182 OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, colorpitch); 226 OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, colorpitch);
183 OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL, 227 OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL,
184 RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO); 228 RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO);
@@ -215,7 +259,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
215 RADEON_CLAMP_T_CLAMP_LAST | 259 RADEON_CLAMP_T_CLAMP_LAST |
216 RADEON_YUV_TO_RGB); 260 RADEON_YUV_TO_RGB);
217 OUT_ACCEL_REG(RADEON_PP_TXFORMAT_0, txformat | RADEON_TXFORMAT_ST_ROUTE_STQ0); 261 OUT_ACCEL_REG(RADEON_PP_TXFORMAT_0, txformat | RADEON_TXFORMAT_ST_ROUTE_STQ0);
218 OUT_ACCEL_REG(RADEON_PP_TXOFFSET_0, pPriv->src_offset); 262 OUT_TEXTURE_REG(R200_PP_TXOFFSET_0, txoffset, pPriv->src_bo);
219 OUT_ACCEL_REG(RADEON_PP_TXCBLEND_0, 263 OUT_ACCEL_REG(RADEON_PP_TXCBLEND_0,
220 RADEON_COLOR_ARG_A_ZERO | 264 RADEON_COLOR_ARG_A_ZERO |
221 RADEON_COLOR_ARG_B_ZERO | 265 RADEON_COLOR_ARG_B_ZERO |
@@ -242,7 +286,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
242 RADEON_CLAMP_S_CLAMP_LAST | 286 RADEON_CLAMP_S_CLAMP_LAST |
243 RADEON_CLAMP_T_CLAMP_LAST); 287 RADEON_CLAMP_T_CLAMP_LAST);
244 OUT_ACCEL_REG(RADEON_PP_TXFORMAT_1, txformat | RADEON_TXFORMAT_ST_ROUTE_STQ1); 288 OUT_ACCEL_REG(RADEON_PP_TXFORMAT_1, txformat | RADEON_TXFORMAT_ST_ROUTE_STQ1);
245 OUT_ACCEL_REG(RADEON_PP_TXOFFSET_1, pPriv->src_offset + pPriv->planeu_offset); 289 OUT_TEXTURE_REG(R200_PP_TXOFFSET_1, txoffset + pPriv->planeu_offset, pPriv->src_bo);
246 OUT_ACCEL_REG(RADEON_PP_TXCBLEND_1, 290 OUT_ACCEL_REG(RADEON_PP_TXCBLEND_1,
247 RADEON_COLOR_ARG_A_ZERO | 291 RADEON_COLOR_ARG_A_ZERO |
248 RADEON_COLOR_ARG_B_ZERO | 292 RADEON_COLOR_ARG_B_ZERO |
@@ -266,7 +310,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
266 RADEON_CLAMP_S_CLAMP_LAST | 310 RADEON_CLAMP_S_CLAMP_LAST |
267 RADEON_CLAMP_T_CLAMP_LAST); 311 RADEON_CLAMP_T_CLAMP_LAST);
268 OUT_ACCEL_REG(RADEON_PP_TXFORMAT_2, txformat | RADEON_TXFORMAT_ST_ROUTE_STQ1); 312 OUT_ACCEL_REG(RADEON_PP_TXFORMAT_2, txformat | RADEON_TXFORMAT_ST_ROUTE_STQ1);
269 OUT_ACCEL_REG(RADEON_PP_TXOFFSET_2, pPriv->src_offset + pPriv->planev_offset); 313 OUT_TEXTURE_REG(R200_PP_TXOFFSET_2, txoffset + pPriv->planev_offset, pPriv->src_bo);
270 OUT_ACCEL_REG(RADEON_PP_TXCBLEND_2, 314 OUT_ACCEL_REG(RADEON_PP_TXCBLEND_2,
271 RADEON_COLOR_ARG_A_ZERO | 315 RADEON_COLOR_ARG_A_ZERO |
272 RADEON_COLOR_ARG_B_ZERO | 316 RADEON_COLOR_ARG_B_ZERO |
@@ -299,7 +343,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
299 RADEON_CLAMP_T_CLAMP_LAST | 343 RADEON_CLAMP_T_CLAMP_LAST |
300 RADEON_YUV_TO_RGB); 344 RADEON_YUV_TO_RGB);
301 OUT_ACCEL_REG(RADEON_PP_TXFORMAT_0, txformat | RADEON_TXFORMAT_ST_ROUTE_STQ0); 345 OUT_ACCEL_REG(RADEON_PP_TXFORMAT_0, txformat | RADEON_TXFORMAT_ST_ROUTE_STQ0);
302 OUT_ACCEL_REG(RADEON_PP_TXOFFSET_0, pPriv->src_offset); 346 OUT_TEXTURE_REG(RADEON_PP_TXOFFSET_0, txoffset, pPriv->src_bo);
303 OUT_ACCEL_REG(RADEON_PP_TXCBLEND_0, 347 OUT_ACCEL_REG(RADEON_PP_TXCBLEND_0,
304 RADEON_COLOR_ARG_A_ZERO | 348 RADEON_COLOR_ARG_A_ZERO |
305 RADEON_COLOR_ARG_B_ZERO | 349 RADEON_COLOR_ARG_B_ZERO |
@@ -448,9 +492,10 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
448{ 492{
449 RADEONInfoPtr info = RADEONPTR(pScrn); 493 RADEONInfoPtr info = RADEONPTR(pScrn);
450 PixmapPtr pPixmap = pPriv->pPixmap; 494 PixmapPtr pPixmap = pPriv->pPixmap;
495 struct radeon_exa_pixmap_priv *driver_priv;
451 uint32_t txformat; 496 uint32_t txformat;
452 uint32_t txfilter, txsize, txpitch; 497 uint32_t txfilter, txsize, txpitch, txoffset;
453 uint32_t dst_offset, dst_pitch, dst_format; 498 uint32_t dst_pitch, dst_format;
454 uint32_t colorpitch; 499 uint32_t colorpitch;
455 Bool isplanar = FALSE; 500 Bool isplanar = FALSE;
456 int dstxoff, dstyoff, pixel_shift, vtx_count; 501 int dstxoff, dstyoff, pixel_shift, vtx_count;
@@ -473,15 +518,12 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
473 518
474#ifdef USE_EXA 519#ifdef USE_EXA
475 if (info->useEXA) { 520 if (info->useEXA) {
476 dst_offset = exaGetPixmapOffset(pPixmap) + info->fbLocation + pScrn->fbOffset;
477 dst_pitch = exaGetPixmapPitch(pPixmap); 521 dst_pitch = exaGetPixmapPitch(pPixmap);
478 } else 522 } else
479#endif 523#endif
480 { 524 {
481 dst_offset = (pPixmap->devPrivate.ptr - info->FB) + 525 dst_pitch = pPixmap->devKind;
482 info->fbLocation + pScrn->fbOffset; 526 }
483 dst_pitch = pPixmap->devKind;
484 }
485 527
486#ifdef COMPOSITE 528#ifdef COMPOSITE
487 dstxoff = -pPixmap->screen_x + pPixmap->drawable.x; 529 dstxoff = -pPixmap->screen_x + pPixmap->drawable.x;
@@ -546,7 +588,7 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
546 BEGIN_ACCEL(4); 588 BEGIN_ACCEL(4);
547 589
548 OUT_ACCEL_REG(RADEON_RB3D_CNTL, dst_format); 590 OUT_ACCEL_REG(RADEON_RB3D_CNTL, dst_format);
549 OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset); 591 EMIT_WRITE_OFFSET(RADEON_RB3D_COLOROFFSET, 0, pPixmap);
550 OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, colorpitch); 592 OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, colorpitch);
551 593
552 OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL, 594 OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL,
@@ -590,6 +632,8 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
590 vcscale = 0.125; 632 vcscale = 0.125;
591 } 633 }
592 634
635 txoffset = info->cs ? 0 : pPriv->src_offset;
636
593 if (isplanar) { 637 if (isplanar) {
594 /* need 2 texcoord sets (even though they are identical) due 638 /* need 2 texcoord sets (even though they are identical) due
595 to denormalization! hw apparently can't premultiply 639 to denormalization! hw apparently can't premultiply
@@ -621,21 +665,21 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
621 (pPriv->w - 1) | 665 (pPriv->w - 1) |
622 ((pPriv->h - 1) << RADEON_TEX_VSIZE_SHIFT)); 666 ((pPriv->h - 1) << RADEON_TEX_VSIZE_SHIFT));
623 OUT_ACCEL_REG(R200_PP_TXPITCH_0, pPriv->src_pitch - 32); 667 OUT_ACCEL_REG(R200_PP_TXPITCH_0, pPriv->src_pitch - 32);
624 OUT_ACCEL_REG(R200_PP_TXOFFSET_0, pPriv->src_offset); 668 OUT_TEXTURE_REG(R200_PP_TXOFFSET_0, txoffset, pPriv->src_bo);
625 669
626 OUT_ACCEL_REG(R200_PP_TXFILTER_1, txfilter); 670 OUT_ACCEL_REG(R200_PP_TXFILTER_1, txfilter);
627 OUT_ACCEL_REG(R200_PP_TXFORMAT_1, txformat | R200_TXFORMAT_ST_ROUTE_STQ1); 671 OUT_ACCEL_REG(R200_PP_TXFORMAT_1, txformat | R200_TXFORMAT_ST_ROUTE_STQ1);
628 OUT_ACCEL_REG(R200_PP_TXFORMAT_X_1, 0); 672 OUT_ACCEL_REG(R200_PP_TXFORMAT_X_1, 0);
629 OUT_ACCEL_REG(R200_PP_TXSIZE_1, txsize); 673 OUT_ACCEL_REG(R200_PP_TXSIZE_1, txsize);
630 OUT_ACCEL_REG(R200_PP_TXPITCH_1, txpitch); 674 OUT_ACCEL_REG(R200_PP_TXPITCH_1, txpitch);
631 OUT_ACCEL_REG(R200_PP_TXOFFSET_1, pPriv->src_offset + pPriv->planeu_offset); 675 OUT_TEXTURE_REG(R200_PP_TXOFFSET_1, txoffset + pPriv->planeu_offset, pPriv->src_bo);
632 676
633 OUT_ACCEL_REG(R200_PP_TXFILTER_2, txfilter); 677 OUT_ACCEL_REG(R200_PP_TXFILTER_2, txfilter);
634 OUT_ACCEL_REG(R200_PP_TXFORMAT_2, txformat | R200_TXFORMAT_ST_ROUTE_STQ1); 678 OUT_ACCEL_REG(R200_PP_TXFORMAT_2, txformat | R200_TXFORMAT_ST_ROUTE_STQ1);
635 OUT_ACCEL_REG(R200_PP_TXFORMAT_X_2, 0); 679 OUT_ACCEL_REG(R200_PP_TXFORMAT_X_2, 0);
636 OUT_ACCEL_REG(R200_PP_TXSIZE_2, txsize); 680 OUT_ACCEL_REG(R200_PP_TXSIZE_2, txsize);
637 OUT_ACCEL_REG(R200_PP_TXPITCH_2, txpitch); 681 OUT_ACCEL_REG(R200_PP_TXPITCH_2, txpitch);
638 OUT_ACCEL_REG(R200_PP_TXOFFSET_2, pPriv->src_offset + pPriv->planev_offset); 682 OUT_TEXTURE_REG(R200_PP_TXOFFSET_2, txoffset + pPriv->planev_offset, pPriv->src_bo);
639 683
640 /* similar to r300 code. Note the big problem is that hardware constants 684 /* similar to r300 code. Note the big problem is that hardware constants
641 * are 8 bits only, representing 0.0-1.0. We can get that up (using bias 685 * are 8 bits only, representing 0.0-1.0. We can get that up (using bias
@@ -777,7 +821,7 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
777 (pPriv->w - 1) | 821 (pPriv->w - 1) |
778 ((pPriv->h - 1) << RADEON_TEX_VSIZE_SHIFT)); 822 ((pPriv->h - 1) << RADEON_TEX_VSIZE_SHIFT));
779 OUT_ACCEL_REG(R200_PP_TXPITCH_0, pPriv->src_pitch - 32); 823 OUT_ACCEL_REG(R200_PP_TXPITCH_0, pPriv->src_pitch - 32);
780 OUT_ACCEL_REG(R200_PP_TXOFFSET_0, pPriv->src_offset); 824 OUT_TEXTURE_REG(R200_PP_TXOFFSET_0, txoffset, pPriv->src_bo);
781 825
782 /* MAD temp1 / 2, const0.a * 2, temp0.ggg, -const0.rgb */ 826 /* MAD temp1 / 2, const0.a * 2, temp0.ggg, -const0.rgb */
783 OUT_ACCEL_REG(R200_PP_TXCBLEND_0, 827 OUT_ACCEL_REG(R200_PP_TXCBLEND_0,
@@ -980,9 +1024,10 @@ FUNC_NAME(R300DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
980{ 1024{
981 RADEONInfoPtr info = RADEONPTR(pScrn); 1025 RADEONInfoPtr info = RADEONPTR(pScrn);
982 PixmapPtr pPixmap = pPriv->pPixmap; 1026 PixmapPtr pPixmap = pPriv->pPixmap;
1027 struct radeon_exa_pixmap_priv *driver_priv;
983 uint32_t txfilter, txformat0, txformat1, txoffset, txpitch; 1028 uint32_t txfilter, txformat0, txformat1, txoffset, txpitch;
984 uint32_t dst_offset, dst_pitch, dst_format; 1029 uint32_t dst_pitch, dst_format;
985 uint32_t txenable, colorpitch; 1030 uint32_t txenable, colorpitch, bicubic_offset;
986 uint32_t output_fmt; 1031 uint32_t output_fmt;
987 Bool isplanar = FALSE; 1032 Bool isplanar = FALSE;
988 int dstxoff, dstyoff, pixel_shift, vtx_count; 1033 int dstxoff, dstyoff, pixel_shift, vtx_count;
@@ -994,15 +1039,12 @@ FUNC_NAME(R300DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
994 1039
995#ifdef USE_EXA 1040#ifdef USE_EXA
996 if (info->useEXA) { 1041 if (info->useEXA) {
997 dst_offset = exaGetPixmapOffset(pPixmap) + info->fbLocation + pScrn->fbOffset;
998 dst_pitch = exaGetPixmapPitch(pPixmap); 1042 dst_pitch = exaGetPixmapPitch(pPixmap);
999 } else 1043 } else
1000#endif 1044#endif
1001 { 1045 {
1002 dst_offset = (pPixmap->devPrivate.ptr - info->FB) + 1046 dst_pitch = pPixmap->devKind;
1003 info->fbLocation + pScrn->fbOffset; 1047 }
1004 dst_pitch = pPixmap->devKind;
1005 }
1006 1048
1007#ifdef COMPOSITE 1049#ifdef COMPOSITE
1008 dstxoff = -pPixmap->screen_x + pPixmap->drawable.x; 1050 dstxoff = -pPixmap->screen_x + pPixmap->drawable.x;
@@ -1095,9 +1137,9 @@ FUNC_NAME(R300DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
1095 R300_TX_MIN_FILTER_LINEAR | 1137 R300_TX_MIN_FILTER_LINEAR |
1096 (0 << R300_TX_ID_SHIFT)); 1138 (0 << R300_TX_ID_SHIFT));
1097 1139
1098 txoffset = pPriv->src_offset; 1140 txoffset = info->cs ? 0 : pPriv->src_offset;
1099 1141
1100 BEGIN_ACCEL(6); 1142 BEGIN_ACCEL_RELOC(6, 1);
1101 OUT_ACCEL_REG(R300_TX_FILTER0_0, txfilter); 1143 OUT_ACCEL_REG(R300_TX_FILTER0_0, txfilter);
1102 OUT_ACCEL_REG(R300_TX_FILTER1_0, 0); 1144 OUT_ACCEL_REG(R300_TX_FILTER1_0, 0);
1103 OUT_ACCEL_REG(R300_TX_FORMAT0_0, txformat0); 1145 OUT_ACCEL_REG(R300_TX_FORMAT0_0, txformat0);
@@ -1106,7 +1148,7 @@ FUNC_NAME(R300DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
1106 else 1148 else
1107 OUT_ACCEL_REG(R300_TX_FORMAT1_0, txformat1); 1149 OUT_ACCEL_REG(R300_TX_FORMAT1_0, txformat1);
1108 OUT_ACCEL_REG(R300_TX_FORMAT2_0, txpitch); 1150 OUT_ACCEL_REG(R300_TX_FORMAT2_0, txpitch);
1109 OUT_ACCEL_REG(R300_TX_OFFSET_0, txoffset); 1151 OUT_TEXTURE_REG(R300_TX_OFFSET_0, txoffset, pPriv->src_bo);
1110 FINISH_ACCEL(); 1152 FINISH_ACCEL();
1111 1153
1112 txenable = R300_TEX_0_ENABLE; 1154 txenable = R300_TEX_0_ENABLE;
@@ -1122,19 +1164,19 @@ FUNC_NAME(R300DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
1122 R300_TX_MIN_FILTER_LINEAR | 1164 R300_TX_MIN_FILTER_LINEAR |
1123 R300_TX_MAG_FILTER_LINEAR); 1165 R300_TX_MAG_FILTER_LINEAR);
1124 1166
1125 BEGIN_ACCEL(12); 1167 BEGIN_ACCEL_RELOC(12, 2);
1126 OUT_ACCEL_REG(R300_TX_FILTER0_1, txfilter | (1 << R300_TX_ID_SHIFT)); 1168 OUT_ACCEL_REG(R300_TX_FILTER0_1, txfilter | (1 << R300_TX_ID_SHIFT));
1127 OUT_ACCEL_REG(R300_TX_FILTER1_1, 0); 1169 OUT_ACCEL_REG(R300_TX_FILTER1_1, 0);
1128 OUT_ACCEL_REG(R300_TX_FORMAT0_1, txformat0); 1170 OUT_ACCEL_REG(R300_TX_FORMAT0_1, txformat0);
1129 OUT_ACCEL_REG(R300_TX_FORMAT1_1, R300_TX_FORMAT_X8 | R300_TX_FORMAT_CACHE_FOURTH_REGION_2); 1171 OUT_ACCEL_REG(R300_TX_FORMAT1_1, R300_TX_FORMAT_X8 | R300_TX_FORMAT_CACHE_FOURTH_REGION_2);
1130 OUT_ACCEL_REG(R300_TX_FORMAT2_1, txpitch); 1172 OUT_ACCEL_REG(R300_TX_FORMAT2_1, txpitch);
1131 OUT_ACCEL_REG(R300_TX_OFFSET_1, txoffset + pPriv->planeu_offset); 1173 OUT_TEXTURE_REG(R300_TX_OFFSET_1, txoffset + pPriv->planeu_offset, pPriv->src_bo);
1132 OUT_ACCEL_REG(R300_TX_FILTER0_2, txfilter | (2 << R300_TX_ID_SHIFT)); 1174 OUT_ACCEL_REG(R300_TX_FILTER0_2, txfilter | (2 << R300_TX_ID_SHIFT));
1133 OUT_ACCEL_REG(R300_TX_FILTER1_2, 0); 1175 OUT_ACCEL_REG(R300_TX_FILTER1_2, 0);
1134 OUT_ACCEL_REG(R300_TX_FORMAT0_2, txformat0); 1176 OUT_ACCEL_REG(R300_TX_FORMAT0_2, txformat0);
1135 OUT_ACCEL_REG(R300_TX_FORMAT1_2, R300_TX_FORMAT_X8 | R300_TX_FORMAT_CACHE_FOURTH_REGION_3); 1177 OUT_ACCEL_REG(R300_TX_FORMAT1_2, R300_TX_FORMAT_X8 | R300_TX_FORMAT_CACHE_FOURTH_REGION_3);
1136 OUT_ACCEL_REG(R300_TX_FORMAT2_2, txpitch); 1178 OUT_ACCEL_REG(R300_TX_FORMAT2_2, txpitch);
1137 OUT_ACCEL_REG(R300_TX_OFFSET_2, txoffset + pPriv->planev_offset); 1179 OUT_TEXTURE_REG(R300_TX_OFFSET_2, txoffset + pPriv->planev_offset, pPriv->src_bo);
1138 FINISH_ACCEL(); 1180 FINISH_ACCEL();
1139 txenable |= R300_TEX_1_ENABLE | R300_TEX_2_ENABLE; 1181 txenable |= R300_TEX_1_ENABLE | R300_TEX_2_ENABLE;
1140 } 1182 }
@@ -1155,13 +1197,18 @@ FUNC_NAME(R300DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
1155 R300_TX_MAG_FILTER_NEAREST | 1197 R300_TX_MAG_FILTER_NEAREST |
1156 (1 << R300_TX_ID_SHIFT)); 1198 (1 << R300_TX_ID_SHIFT));
1157 1199
1158 BEGIN_ACCEL(6); 1200 if (info->cs)
1201 bicubic_offset = 0;
1202 else
1203 bicubic_offset = pPriv->bicubic_src_offset;
1204
1205 BEGIN_ACCEL_RELOC(6, 1);
1159 OUT_ACCEL_REG(R300_TX_FILTER0_1, txfilter); 1206 OUT_ACCEL_REG(R300_TX_FILTER0_1, txfilter);
1160 OUT_ACCEL_REG(R300_TX_FILTER1_1, 0); 1207 OUT_ACCEL_REG(R300_TX_FILTER1_1, 0);
1161 OUT_ACCEL_REG(R300_TX_FORMAT0_1, txformat0); 1208 OUT_ACCEL_REG(R300_TX_FORMAT0_1, txformat0);
1162 OUT_ACCEL_REG(R300_TX_FORMAT1_1, txformat1); 1209 OUT_ACCEL_REG(R300_TX_FORMAT1_1, txformat1);
1163 OUT_ACCEL_REG(R300_TX_FORMAT2_1, txpitch); 1210 OUT_ACCEL_REG(R300_TX_FORMAT2_1, txpitch);
1164 OUT_ACCEL_REG(R300_TX_OFFSET_1, pPriv->bicubic_src_offset); 1211 OUT_TEXTURE_REG(R300_TX_OFFSET_1, bicubic_offset, pPriv->bicubic_bo);
1165 FINISH_ACCEL(); 1212 FINISH_ACCEL();
1166 1213
1167 /* Enable tex 1 */ 1214 /* Enable tex 1 */
@@ -2205,11 +2252,11 @@ FUNC_NAME(R300DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
2205 FINISH_ACCEL(); 2252 FINISH_ACCEL();
2206 } 2253 }
2207 2254
2208 BEGIN_ACCEL(6); 2255 BEGIN_ACCEL_RELOC(6, 1);
2209 OUT_ACCEL_REG(R300_TX_INVALTAGS, 0); 2256 OUT_ACCEL_REG(R300_TX_INVALTAGS, 0);
2210 OUT_ACCEL_REG(R300_TX_ENABLE, txenable); 2257 OUT_ACCEL_REG(R300_TX_ENABLE, txenable);
2211 2258
2212 OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset); 2259 EMIT_WRITE_OFFSET(R300_RB3D_COLOROFFSET0, 0, pPixmap);
2213 OUT_ACCEL_REG(R300_RB3D_COLORPITCH0, colorpitch); 2260 OUT_ACCEL_REG(R300_RB3D_COLORPITCH0, colorpitch);
2214 2261
2215 /* no need to enable blending */ 2262 /* no need to enable blending */
@@ -2407,8 +2454,9 @@ FUNC_NAME(R500DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
2407{ 2454{
2408 RADEONInfoPtr info = RADEONPTR(pScrn); 2455 RADEONInfoPtr info = RADEONPTR(pScrn);
2409 PixmapPtr pPixmap = pPriv->pPixmap; 2456 PixmapPtr pPixmap = pPriv->pPixmap;
2457 struct radeon_exa_pixmap_priv *driver_priv;
2410 uint32_t txfilter, txformat0, txformat1, txoffset, txpitch; 2458 uint32_t txfilter, txformat0, txformat1, txoffset, txpitch;
2411 uint32_t dst_offset, dst_pitch, dst_format; 2459 uint32_t dst_pitch, dst_format;
2412 uint32_t txenable, colorpitch; 2460 uint32_t txenable, colorpitch;
2413 uint32_t output_fmt; 2461 uint32_t output_fmt;
2414 Bool isplanar = FALSE; 2462 Bool isplanar = FALSE;
@@ -2421,15 +2469,12 @@ FUNC_NAME(R500DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
2421 2469
2422#ifdef USE_EXA 2470#ifdef USE_EXA
2423 if (info->useEXA) { 2471 if (info->useEXA) {
2424 dst_offset = exaGetPixmapOffset(pPixmap) + info->fbLocation + pScrn->fbOffset;
2425 dst_pitch = exaGetPixmapPitch(pPixmap); 2472 dst_pitch = exaGetPixmapPitch(pPixmap);
2426 } else 2473 } else
2427#endif 2474#endif
2428 { 2475 {
2429 dst_offset = (pPixmap->devPrivate.ptr - info->FB) + 2476 dst_pitch = pPixmap->devKind;
2430 info->fbLocation + pScrn->fbOffset; 2477 }
2431 dst_pitch = pPixmap->devKind;
2432 }
2433 2478
2434#ifdef COMPOSITE 2479#ifdef COMPOSITE
2435 dstxoff = -pPixmap->screen_x + pPixmap->drawable.x; 2480 dstxoff = -pPixmap->screen_x + pPixmap->drawable.x;
@@ -2528,15 +2573,15 @@ FUNC_NAME(R500DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
2528 if ((pPriv->h - 1) & 0x800) 2573 if ((pPriv->h - 1) & 0x800)
2529 txpitch |= R500_TXHEIGHT_11; 2574 txpitch |= R500_TXHEIGHT_11;
2530 2575
2531 txoffset = pPriv->src_offset; 2576 txoffset = info->cs ? 0 : pPriv->src_offset;
2532 2577
2533 BEGIN_ACCEL(6); 2578 BEGIN_ACCEL_RELOC(6, 1);
2534 OUT_ACCEL_REG(R300_TX_FILTER0_0, txfilter); 2579 OUT_ACCEL_REG(R300_TX_FILTER0_0, txfilter);
2535 OUT_ACCEL_REG(R300_TX_FILTER1_0, 0); 2580 OUT_ACCEL_REG(R300_TX_FILTER1_0, 0);
2536 OUT_ACCEL_REG(R300_TX_FORMAT0_0, txformat0); 2581 OUT_ACCEL_REG(R300_TX_FORMAT0_0, txformat0);
2537 OUT_ACCEL_REG(R300_TX_FORMAT1_0, txformat1); 2582 OUT_ACCEL_REG(R300_TX_FORMAT1_0, txformat1);
2538 OUT_ACCEL_REG(R300_TX_FORMAT2_0, txpitch); 2583 OUT_ACCEL_REG(R300_TX_FORMAT2_0, txpitch);
2539 OUT_ACCEL_REG(R300_TX_OFFSET_0, txoffset); 2584 OUT_TEXTURE_REG(R300_TX_OFFSET_0, txoffset, pPriv->src_bo);
2540 FINISH_ACCEL(); 2585 FINISH_ACCEL();
2541 2586
2542 txenable = R300_TEX_0_ENABLE; 2587 txenable = R300_TEX_0_ENABLE;
@@ -3758,11 +3803,11 @@ FUNC_NAME(R500DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
3758 FINISH_ACCEL(); 3803 FINISH_ACCEL();
3759 } 3804 }
3760 3805
3761 BEGIN_ACCEL(6); 3806 BEGIN_ACCEL_RELOC(6, 1);
3762 OUT_ACCEL_REG(R300_TX_INVALTAGS, 0); 3807 OUT_ACCEL_REG(R300_TX_INVALTAGS, 0);
3763 OUT_ACCEL_REG(R300_TX_ENABLE, txenable); 3808 OUT_ACCEL_REG(R300_TX_ENABLE, txenable);
3764 3809
3765 OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset); 3810 EMIT_WRITE_OFFSET(R300_RB3D_COLOROFFSET0, 0, pPixmap);
3766 OUT_ACCEL_REG(R300_RB3D_COLORPITCH0, colorpitch); 3811 OUT_ACCEL_REG(R300_RB3D_COLORPITCH0, colorpitch);
3767 3812
3768 /* no need to enable blending */ 3813 /* no need to enable blending */
diff --git a/src/radeon_video.h b/src/radeon_video.h
index 0cf8168b..aeb6441f 100644
--- a/src/radeon_video.h
+++ b/src/radeon_video.h
@@ -120,6 +120,9 @@ typedef struct {
120 int drw_x, drw_y; 120 int drw_x, drw_y;
121 int src_x, src_y; 121 int src_x, src_y;
122 int vsync; 122 int vsync;
123
124 struct radeon_bo *src_bo;
125 struct radeon_bo *bicubic_bo;
123} RADEONPortPrivRec, *RADEONPortPrivPtr; 126} RADEONPortPrivRec, *RADEONPortPrivPtr;
124 127
125/* Reference color space transform data */ 128/* Reference color space transform data */