summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
12 files changed, 1043 insertions, 235 deletions
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)
switch(pPriv->id) {
case FOURCC_YV12:
case FOURCC_I420:
- accel_state->src_mc_addr[0] = pPriv->src_offset;
+ accel_state->src_mc_addr[0] = pPriv->src_offset + info->fbLocation + pScrn->fbOffset;
accel_state->src_size[0] = accel_state->src_pitch[0] * pPriv->h;
/* flush texture cache */
@@ -392,7 +392,7 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
case FOURCC_UYVY:
case FOURCC_YUY2:
default:
- accel_state->src_mc_addr[0] = pPriv->src_offset;
+ accel_state->src_mc_addr[0] = pPriv->src_offset + info->fbLocation + pScrn->fbOffset;
accel_state->src_size[0] = accel_state->src_pitch[0] * pPriv->h;
/* 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 @@
#include "dri.h"
#include "GL/glxint.h"
#include "xf86drm.h"
+#include "radeon_drm.h"
#ifdef DAMAGE
#include "damage.h"
@@ -85,6 +86,13 @@
#include "xf86Crtc.h"
#include "X11/Xatom.h"
+#ifdef XF86DRM_MODE
+#include "radeon_bo.h"
+#include "radeon_cs.h"
+#else
+#include "radeon_dummy_bufmgr.h"
+#endif
+
/* Render support */
#ifdef RENDER
#include "picturestr.h"
@@ -450,6 +458,11 @@ typedef struct {
typedef struct _atomBiosHandle *atomBiosHandlePtr;
+struct radeon_exa_pixmap_priv {
+ struct radeon_bo *bo;
+ int flags;
+};
+
typedef struct {
uint32_t pci_device_id;
RADEONChipFamily chip_family;
@@ -460,6 +473,25 @@ typedef struct {
int singledac;
} RADEONCardInfo;
+#define RADEON_2D_EXA_COPY 1
+#define RADEON_2D_EXA_SOLID 2
+
+struct radeon_2d_state {
+ int op; //
+ uint32_t dst_pitch_offset;
+ uint32_t src_pitch_offset;
+ uint32_t dp_gui_master_cntl;
+ uint32_t dp_cntl;
+ uint32_t dp_write_mask;
+ uint32_t dp_brush_frgd_clr;
+ uint32_t dp_brush_bkgd_clr;
+ uint32_t dp_src_frgd_clr;
+ uint32_t dp_src_bkgd_clr;
+ uint32_t default_sc_bottom_right;
+ struct radeon_bo *dst_bo;
+ struct radeon_bo *src_bo;
+};
+
#ifdef XF86DRI
struct radeon_cp {
Bool CPRuns; /* CP is running */
@@ -937,6 +969,18 @@ typedef struct {
float igp_ht_link_clk;
float igp_ht_link_width;
+ int can_resize;
+ void (*reemit_current2d)(ScrnInfoPtr pScrn, int op); // emit the current 2D state into the IB
+ struct radeon_2d_state state_2d;
+#ifdef XF86DRM_MODE
+ struct radeon_bo_manager *bufmgr;
+ struct radeon_cs_manager *csm;
+ struct radeon_cs *cs;
+#else
+ /* fake bool */
+ Bool cs;
+#endif
+
} RADEONInfoRec, *RADEONInfoPtr;
#define RADEONWaitForFifo(pScrn, entries) \
@@ -1013,11 +1057,13 @@ extern void RADEONWaitForFifoFunction(ScrnInfoPtr pScrn, int entries);
#ifdef XF86DRI
extern drmBufPtr RADEONCPGetBuffer(ScrnInfoPtr pScrn);
extern void RADEONCPFlushIndirect(ScrnInfoPtr pScrn, int discard);
+extern void radeon_cs_flush_indirect(ScrnInfoPtr pScrn);
extern void RADEONCPReleaseIndirect(ScrnInfoPtr pScrn);
extern int RADEONCPStop(ScrnInfoPtr pScrn, RADEONInfoPtr info);
# ifdef USE_XAA
extern Bool RADEONSetupMemXAA_DRI(int scrnIndex, ScreenPtr pScreen);
# endif
+uint32_t radeonGetPixmapOffset(PixmapPtr pPix);
#endif
#ifdef USE_XAA
@@ -1202,6 +1248,9 @@ extern void
radeon_legacy_free_memory(ScrnInfoPtr pScrn,
void *mem_struct);
+struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix);
+void radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo);
+
#ifdef XF86DRI
# ifdef USE_XAA
/* radeon_accelfuncs.c */
@@ -1220,7 +1269,9 @@ do { \
#define RADEONCP_RELEASE(pScrn, info) \
do { \
- if (info->cp->CPInUse) { \
+ if (info->cs) { \
+ radeon_cs_flush_indirect(pScrn); \
+ } else if (info->cp->CPInUse) { \
RADEON_PURGE_CACHE(); \
RADEON_WAIT_UNTIL_IDLE(); \
RADEONCPReleaseIndirect(pScrn); \
@@ -1255,7 +1306,7 @@ do { \
#define RADEONCP_REFRESH(pScrn, info) \
do { \
- if (!info->cp->CPInUse) { \
+ if (!info->cp->CPInUse && !info->cs) { \
if (info->cp->needCacheFlush) { \
RADEON_PURGE_CACHE(); \
RADEON_PURGE_ZCACHE(); \
@@ -1286,54 +1337,59 @@ do { \
xf86DrvMsg(pScrn->scrnIndex, X_INFO, \
"BEGIN_RING(%d) in %s\n", (unsigned int)n, __FUNCTION__);\
} \
- if (++info->cp->dma_begin_count != 1) { \
+ if (info->cs) radeon_cs_begin(info->cs, n, __FILE__, __func__, __LINE__); else { \
+ if (++info->cp->dma_begin_count != 1) { \
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \
"BEGIN_RING without end at %s:%d\n", \
- info->cp->dma_debug_func, info->cp->dma_debug_lineno); \
+ info->cp->dma_debug_func, info->cp->dma_debug_lineno); \
info->cp->dma_begin_count = 1; \
- } \
- info->cp->dma_debug_func = __FILE__; \
- info->cp->dma_debug_lineno = __LINE__; \
- if (!info->cp->indirectBuffer) { \
+ } \
+ info->cp->dma_debug_func = __FILE__; \
+ info->cp->dma_debug_lineno = __LINE__; \
+ if (!info->cp->indirectBuffer) { \
info->cp->indirectBuffer = RADEONCPGetBuffer(pScrn); \
info->cp->indirectStart = 0; \
- } else if (info->cp->indirectBuffer->used + (n) * (int)sizeof(uint32_t) > \
- info->cp->indirectBuffer->total) { \
+ } else if (info->cp->indirectBuffer->used + (n) * (int)sizeof(uint32_t) > \
+ info->cp->indirectBuffer->total) { \
RADEONCPFlushIndirect(pScrn, 1); \
+ } \
+ __expected = n; \
+ __head = (pointer)((char *)info->cp->indirectBuffer->address + \
+ info->cp->indirectBuffer->used); \
+ __count = 0; \
} \
- __expected = n; \
- __head = (pointer)((char *)info->cp->indirectBuffer->address + \
- info->cp->indirectBuffer->used); \
- __count = 0; \
} while (0)
#define ADVANCE_RING() do { \
- if (info->cp->dma_begin_count-- != 1) { \
+ if (info->cs) radeon_cs_end(info->cs, __FILE__, __func__, __LINE__); else { \
+ if (info->cp->dma_begin_count-- != 1) { \
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \
"ADVANCE_RING without begin at %s:%d\n", \
__FILE__, __LINE__); \
info->cp->dma_begin_count = 0; \
- } \
- if (__count != __expected) { \
+ } \
+ if (__count != __expected) { \
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \
"ADVANCE_RING count != expected (%d vs %d) at %s:%d\n", \
__count, __expected, __FILE__, __LINE__); \
- } \
- if (RADEON_VERBOSE) { \
+ } \
+ if (RADEON_VERBOSE) { \
xf86DrvMsg(pScrn->scrnIndex, X_INFO, \
"ADVANCE_RING() start: %d used: %d count: %d\n", \
info->cp->indirectStart, \
info->cp->indirectBuffer->used, \
__count * (int)sizeof(uint32_t)); \
+ } \
+ info->cp->indirectBuffer->used += __count * (int)sizeof(uint32_t); \
} \
- info->cp->indirectBuffer->used += __count * (int)sizeof(uint32_t); \
-} while (0)
+ } while (0)
#define OUT_RING(x) do { \
if (RADEON_VERBOSE) { \
xf86DrvMsg(pScrn->scrnIndex, X_INFO, \
" OUT_RING(0x%08x)\n", (unsigned int)(x)); \
} \
+ if (info->cs) radeon_cs_write_dword(info->cs, (x)); else \
__head[__count++] = (x); \
} while (0)
@@ -1343,12 +1399,22 @@ do { \
OUT_RING(val); \
} while (0)
+#define OUT_RING_RELOC(x, read_domains, write_domain) \
+ do { \
+ int _ret; \
+ _ret = radeon_cs_write_reloc(info->cs, x, read_domains, write_domain, 0); \
+ if (_ret) ErrorF("reloc emit failure %d\n", _ret); \
+ } while(0)
+
+
#define FLUSH_RING() \
do { \
if (RADEON_VERBOSE) \
xf86DrvMsg(pScrn->scrnIndex, X_INFO, \
"FLUSH_RING in %s\n", __FUNCTION__); \
- if (info->cp->indirectBuffer) \
+ if (info->cs) \
+ radeon_cs_flush_indirect(pScrn); \
+ else if (info->cp->indirectBuffer) \
RADEONCPFlushIndirect(pScrn, 0); \
} while (0)
@@ -1434,8 +1500,12 @@ do { \
case EXA_ENGINEMODE_2D: \
break; \
} \
- if (flush && info->directRenderingEnabled) \
- RADEONCPFlushIndirect(pScrn, 1); \
+ if (flush) { \
+ if (info->cs) \
+ radeon_cs_flush_indirect(pScrn); \
+ else if (info->directRenderingEnabled) \
+ RADEONCPFlushIndirect(pScrn, 1); \
+ } \
info->accel_state->engineMode = EXA_ENGINEMODE_2D; \
} while (0);
@@ -1450,7 +1520,9 @@ do { \
break; \
} \
if (flush) { \
- if (info->directRenderingEnabled) \
+ if (info->cs) \
+ radeon_cs_flush_indirect(pScrn); \
+ else if (info->directRenderingEnabled) \
RADEONCPFlushIndirect(pScrn, 1); \
RADEONInit3DEngine(pScrn); \
} \
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)
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
+ if (info->cs)
+ return;
+
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
"EngineRestore (%d/%d)\n",
info->CurrentLayout.pixel_code,
@@ -421,6 +424,24 @@ void RADEONEngineRestore(ScrnInfoPtr pScrn)
info->accel_state->XInited3D = FALSE;
}
+static int RADEONDRMGetNumPipes(ScrnInfoPtr pScrn, int *num_pipes)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ if (info->dri->pKernelDRMVersion->version_major < 2) {
+ drm_radeon_getparam_t np;
+
+ memset(&np, 0, sizeof(np));
+ np.param = RADEON_PARAM_NUM_GB_PIPES;
+ np.value = num_pipes;
+ return drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_GETPARAM, &np, sizeof(np));
+ } else {
+ struct drm_radeon_info np2;
+ np2.value = (uint64_t)num_pipes;
+ np2.request = RADEON_INFO_NUM_GB_PIPES;
+ return drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_INFO, &np2, sizeof(np2));
+ }
+}
+
/* Initialize the acceleration hardware */
void RADEONEngineInit(ScrnInfoPtr pScrn)
{
@@ -436,15 +457,9 @@ void RADEONEngineInit(ScrnInfoPtr pScrn)
#ifdef XF86DRI
if (info->directRenderingEnabled && (IS_R300_3D || IS_R500_3D)) {
- drm_radeon_getparam_t np;
int num_pipes;
- memset(&np, 0, sizeof(np));
- np.param = RADEON_PARAM_NUM_GB_PIPES;
- np.value = &num_pipes;
-
- if (drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_GETPARAM, &np,
- sizeof(np)) < 0) {
+ if(RADEONDRMGetNumPipes(pScrn, &num_pipes) < 0) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Failed to determine num pipes from DRM, falling back to "
"manual look-up!\n");
@@ -455,64 +470,67 @@ void RADEONEngineInit(ScrnInfoPtr pScrn)
}
#endif
- if ((info->ChipFamily == CHIP_FAMILY_RV410) ||
- (info->ChipFamily == CHIP_FAMILY_R420) ||
- (info->ChipFamily == CHIP_FAMILY_RS600) ||
- (info->ChipFamily == CHIP_FAMILY_RS690) ||
- (info->ChipFamily == CHIP_FAMILY_RS740) ||
- (info->ChipFamily == CHIP_FAMILY_RS400) ||
- (info->ChipFamily == CHIP_FAMILY_RS480) ||
- IS_R500_3D) {
- if (info->accel_state->num_gb_pipes == 0) {
- uint32_t gb_pipe_sel = INREG(R400_GB_PIPE_SELECT);
-
- info->accel_state->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1;
- if (IS_R500_3D)
- OUTPLL(pScrn, R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4));
- }
- } else {
- if (info->accel_state->num_gb_pipes == 0) {
- if ((info->ChipFamily == CHIP_FAMILY_R300) ||
- (info->ChipFamily == CHIP_FAMILY_R350)) {
- /* R3xx chips */
- info->accel_state->num_gb_pipes = 2;
- } else {
- /* RV3xx chips */
- info->accel_state->num_gb_pipes = 1;
+ if (!info->cs) {
+ if ((info->ChipFamily == CHIP_FAMILY_RV410) ||
+ (info->ChipFamily == CHIP_FAMILY_R420) ||
+ (info->ChipFamily == CHIP_FAMILY_RS600) ||
+ (info->ChipFamily == CHIP_FAMILY_RS690) ||
+ (info->ChipFamily == CHIP_FAMILY_RS740) ||
+ (info->ChipFamily == CHIP_FAMILY_RS400) ||
+ (info->ChipFamily == CHIP_FAMILY_RS480) ||
+ IS_R500_3D) {
+ if (info->accel_state->num_gb_pipes == 0) {
+ uint32_t gb_pipe_sel = INREG(R400_GB_PIPE_SELECT);
+
+ info->accel_state->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1;
+ if (IS_R500_3D)
+ OUTPLL(pScrn, R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4));
+ }
+ } else {
+ if (info->accel_state->num_gb_pipes == 0) {
+ if ((info->ChipFamily == CHIP_FAMILY_R300) ||
+ (info->ChipFamily == CHIP_FAMILY_R350)) {
+ /* R3xx chips */
+ info->accel_state->num_gb_pipes = 2;
+ } else {
+ /* RV3xx chips */
+ info->accel_state->num_gb_pipes = 1;
+ }
}
- }
- }
-
- /* RV410 SE cards only have 1 quadpipe */
- if ((info->Chipset == PCI_CHIP_RV410_5E4C) ||
- (info->Chipset == PCI_CHIP_RV410_5E4F))
- info->accel_state->num_gb_pipes = 1;
-
- if (IS_R300_3D || IS_R500_3D)
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "num quad-pipes is %d\n", info->accel_state->num_gb_pipes);
-
- if (IS_R300_3D || IS_R500_3D) {
- uint32_t gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16);
-
- switch(info->accel_state->num_gb_pipes) {
- case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break;
- case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break;
- case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break;
- default:
- case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break;
}
- OUTREG(R300_GB_TILE_CONFIG, gb_tile_config);
- OUTREG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
- OUTREG(R300_DST_PIPE_CONFIG, INREG(R300_DST_PIPE_CONFIG) | R300_PIPE_AUTO_CONFIG);
- OUTREG(R300_RB2D_DSTCACHE_MODE, (INREG(R300_RB2D_DSTCACHE_MODE) |
- R300_DC_AUTOFLUSH_ENABLE |
- R300_DC_DC_DISABLE_IGNORE_PE));
- } else
- OUTREG(RADEON_RB3D_CNTL, 0);
+ /* RV410 SE cards only have 1 quadpipe */
+ if ((info->Chipset == PCI_CHIP_RV410_5E4C) ||
+ (info->Chipset == PCI_CHIP_RV410_5E4F))
+ info->accel_state->num_gb_pipes = 1;
+
+ if (IS_R300_3D || IS_R500_3D)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "num quad-pipes is %d\n", info->accel_state->num_gb_pipes);
+
+ if (IS_R300_3D || IS_R500_3D) {
+ uint32_t gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16);
+
+ switch(info->accel_state->num_gb_pipes) {
+ case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break;
+ case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break;
+ case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break;
+ default:
+ case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break;
+ }
- RADEONEngineReset(pScrn);
+ OUTREG(R300_GB_TILE_CONFIG, gb_tile_config);
+ OUTREG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
+ if (info->ChipFamily >= CHIP_FAMILY_R420)
+ OUTREG(R300_DST_PIPE_CONFIG, INREG(R300_DST_PIPE_CONFIG) | R300_PIPE_AUTO_CONFIG);
+ OUTREG(R300_RB2D_DSTCACHE_MODE, (INREG(R300_RB2D_DSTCACHE_MODE) |
+ R300_DC_AUTOFLUSH_ENABLE |
+ R300_DC_DC_DISABLE_IGNORE_PE));
+ } else
+ OUTREG(RADEON_RB3D_CNTL, 0);
+
+ RADEONEngineReset(pScrn);
+ }
switch (info->CurrentLayout.pixel_code) {
case 8: datatype = 2; break;
@@ -536,6 +554,24 @@ void RADEONEngineInit(ScrnInfoPtr pScrn)
RADEONEngineRestore(pScrn);
}
+uint32_t radeonGetPixmapOffset(PixmapPtr pPix)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ uint32_t offset = 0;
+ if (info->cs)
+ return 0;
+#ifdef USE_EXA
+ if (info->useEXA) {
+ offset = exaGetPixmapOffset(pPix);
+ } else
+#endif
+ {
+ offset = pPix->devPrivate.ptr - info->FB;
+ }
+ offset += info->fbLocation + pScrn->fbOffset;
+ return offset;
+}
#define ACCEL_MMIO
#define ACCEL_PREAMBLE() unsigned char *RADEONMMIO = info->MMIO
@@ -620,6 +656,20 @@ int RADEONCPStop(ScrnInfoPtr pScrn, RADEONInfoPtr info)
}
}
+#define RADEON_IB_RESERVE (16 * sizeof(uint32_t))
+
+void radeon_cs_flush_indirect(ScrnInfoPtr pScrn)
+{
+#ifdef XF86DRM_MODE
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ if (!info->cs->cdw)
+ return;
+ radeon_cs_emit(info->cs);
+ radeon_cs_erase(info->cs);
+#endif
+}
+
/* Get an indirect buffer for the CP 2D acceleration commands */
drmBufPtr RADEONCPGetBuffer(ScrnInfoPtr pScrn)
{
@@ -696,6 +746,7 @@ void RADEONCPFlushIndirect(ScrnInfoPtr pScrn, int discard)
int start = info->cp->indirectStart;
drm_radeon_indirect_t indirect;
+ assert(!info->cs);
if (!buffer) return;
if (start == buffer->used && !discard) return;
@@ -745,6 +796,7 @@ void RADEONCPReleaseIndirect(ScrnInfoPtr pScrn)
int start = info->cp->indirectStart;
drm_radeon_indirect_t indirect;
+ assert(!info->cs);
if (info->ChipFamily >= CHIP_FAMILY_R600) {
if (buffer && (buffer->used & 0x3c)) {
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 {
#define DRM_RADEON_SETPARAM 0x19
#define DRM_RADEON_SURF_ALLOC 0x1a
#define DRM_RADEON_SURF_FREE 0x1b
+/* KMS ioctl */
+#define DRM_RADEON_GEM_INFO 0x1c
+#define DRM_RADEON_GEM_CREATE 0x1d
+#define DRM_RADEON_GEM_MMAP 0x1e
+#define DRM_RADEON_GEM_PREAD 0x21
+#define DRM_RADEON_GEM_PWRITE 0x22
+#define DRM_RADEON_GEM_SET_DOMAIN 0x23
+#define DRM_RADEON_GEM_WAIT_IDLE 0x24
+#define DRM_RADEON_CS 0x26
+#define DRM_RADEON_INFO 0x27
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t)
#define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START)
@@ -521,6 +531,17 @@ typedef struct {
#define DRM_IOCTL_RADEON_SETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SETPARAM, drm_radeon_setparam_t)
#define DRM_IOCTL_RADEON_SURF_ALLOC DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_ALLOC, drm_radeon_surface_alloc_t)
#define DRM_IOCTL_RADEON_SURF_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_FREE, drm_radeon_surface_free_t)
+/* KMS */
+#define DRM_IOCTL_RADEON_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INFO, struct drm_radeon_gem_info)
+#define DRM_IOCTL_RADEON_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_CREATE, struct drm_radeon_gem_create)
+#define DRM_IOCTL_RADEON_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_MMAP, struct drm_radeon_gem_mmap)
+#define DRM_IOCTL_RADEON_GEM_PREAD DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PREAD, struct drm_radeon_gem_pread)
+#define DRM_IOCTL_RADEON_GEM_PWRITE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PWRITE, struct drm_radeon_gem_pwrite)
+#define DRM_IOCTL_RADEON_GEM_SET_DOMAIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_DOMAIN, struct drm_radeon_gem_set_domain)
+#define DRM_IOCTL_RADEON_GEM_WAIT_IDLE DRM_IOW(DRM_COMMAND_BASE + DRM_RADEON_GEM_WAIT_IDLE, struct drm_radeon_gem_wait_idle)
+#define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs)
+#define DRM_IOCTL_RADEON_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_INFO, struct drm_radeon_info)
+
typedef struct drm_radeon_init {
enum {
@@ -753,4 +774,112 @@ typedef struct drm_radeon_surface_free {
#define DRM_RADEON_VBLANK_CRTC1 1
#define DRM_RADEON_VBLANK_CRTC2 2
+/*
+ * Kernel modesetting world below.
+ */
+#define RADEON_GEM_DOMAIN_CPU 0x1
+#define RADEON_GEM_DOMAIN_GTT 0x2
+#define RADEON_GEM_DOMAIN_VRAM 0x4
+
+struct drm_radeon_gem_info {
+ uint64_t gart_size;
+ uint64_t vram_size;
+ uint64_t vram_visible;
+};
+
+#define RADEON_GEM_NO_BACKING_STORE 1
+
+struct drm_radeon_gem_create {
+ uint64_t size;
+ uint64_t alignment;
+ uint32_t handle;
+ uint32_t initial_domain;
+ uint32_t flags;
+};
+
+struct drm_radeon_gem_mmap {
+ uint32_t handle;
+ uint32_t pad;
+ uint64_t offset;
+ uint64_t size;
+ uint64_t addr_ptr;
+};
+
+struct drm_radeon_gem_set_domain {
+ uint32_t handle;
+ uint32_t read_domains;
+ uint32_t write_domain;
+};
+
+struct drm_radeon_gem_wait_idle {
+ uint32_t handle;
+ uint32_t pad;
+};
+
+struct drm_radeon_gem_busy {
+ uint32_t handle;
+ uint32_t busy;
+};
+
+struct drm_radeon_gem_pread {
+ /** Handle for the object being read. */
+ uint32_t handle;
+ uint32_t pad;
+ /** Offset into the object to read from */
+ uint64_t offset;
+ /** Length of data to read */
+ uint64_t size;
+ /** Pointer to write the data into. */
+ /* void *, but pointers are not 32/64 compatible */
+ uint64_t data_ptr;
+};
+
+struct drm_radeon_gem_pwrite {
+ /** Handle for the object being written to. */
+ uint32_t handle;
+ uint32_t pad;
+ /** Offset into the object to write to */
+ uint64_t offset;
+ /** Length of data to write */
+ uint64_t size;
+ /** Pointer to read the data from. */
+ /* void *, but pointers are not 32/64 compatible */
+ uint64_t data_ptr;
+};
+
+#define RADEON_CHUNK_ID_RELOCS 0x01
+#define RADEON_CHUNK_ID_IB 0x02
+
+struct drm_radeon_cs_chunk {
+ uint32_t chunk_id;
+ uint32_t length_dw;
+ uint64_t chunk_data;
+};
+
+struct drm_radeon_cs_reloc {
+ uint32_t handle;
+ uint32_t read_domains;
+ uint32_t write_domain;
+ uint32_t flags;
+};
+
+struct drm_radeon_cs {
+ uint32_t num_chunks;
+ uint32_t cs_id;
+ /* this points to uint64_t * which point to cs chunks */
+ uint64_t chunks;
+ /* updates to the limits after this CS ioctl */
+ uint64_t gart_limit;
+ uint64_t vram_limit;
+};
+
+#define RADEON_INFO_DEVICE_ID 0x00
+#define RADEON_INFO_NUM_GB_PIPES 0x01
+
+struct drm_radeon_info {
+ uint32_t request;
+ uint32_t pad;
+ uint64_t value;
+};
+
#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 @@
+
+#ifndef RADEON_DUMMY_BUFMGR_H
+#define RADEON_DUMMY_BUFMGR_H
+/* when we don't have modesetting but we still need these functions */
+
+struct radeon_bo {
+ int dummy;
+ void *ptr;
+};
+
+static inline int radeon_cs_begin(Bool dummy, int d2, const char *file,
+ const char *func, int line)
+{
+ return 0;
+}
+
+static inline int radeon_cs_end(Bool dummy, const char *file,
+ const char *func, int line)
+{
+ return 0;
+}
+
+static inline void radeon_cs_write_dword(Bool cs, uint32_t dword)
+{
+}
+
+static inline int radeon_cs_write_reloc(Bool cs,
+ struct radeon_bo *bo,
+ uint32_t read_domain,
+ uint32_t write_domain,
+ uint32_t flags)
+{
+ return 0;
+}
+
+static inline int radeon_bo_map(struct radeon_bo *bo, int write) {return 0;}
+static inline void radeon_bo_ref(struct radeon_bo *bo) {return;}
+static inline struct radeon_bo *radeon_bo_unref(struct radeon_bo *bo) {return NULL;}
+static inline void radeon_bo_unmap(struct radeon_bo *bo) {return;}
+static inline int radeon_bo_wait(struct radeon_bo *bo) {return 0;}
+
+
+struct radeon_cs_space_check {
+ struct radeon_bo *bo;
+ int read_domains;
+ int write_domain;
+ int new_accounted;
+};
+
+static inline int radeon_cs_space_check(Bool cs, struct radeon_cs_space_check *bos, int num)
+{
+ return 0;
+}
+#define RADEON_CS_SPACE_OP_TO_BIG 0
+#define RADEON_CS_SPACE_FLUSH 1
+
+#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)
return tmp.l;
}
+static inline void radeon_add_pixmap(struct radeon_cs_space_check *bos, int index, PixmapPtr pPix, int read_domains, int write_domain)
+{
+ struct radeon_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(pPix);
+ bos[index].bo = driver_priv->bo;
+ bos[index].read_domains = read_domains;
+ bos[index].write_domain = write_domain;
+ bos[index].new_accounted = 0;
+}
+
/* Assumes that depth 15 and 16 can be used as depth 16, which is okay since we
* require src and dest datatypes to be equal.
*/
@@ -179,7 +188,6 @@ static Bool RADEONGetOffsetPitch(PixmapPtr pPix, int bpp, uint32_t *pitch_offset
Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix, uint32_t *pitch_offset)
{
- RINFO_FROM_SCREEN(pPix->drawable.pScreen);
uint32_t pitch, offset;
int bpp;
@@ -187,7 +195,7 @@ Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix, uint32_t *pitch_offset)
if (bpp == 24)
bpp = 8;
- offset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset;
+ offset = radeonGetPixmapOffset(pPix);
pitch = exaGetPixmapPitch(pPix);
return RADEONGetOffsetPitch(pPix, bpp, pitch_offset, offset, pitch);
@@ -224,7 +232,7 @@ int RADEONBiggerCrtcArea(PixmapPtr pPix)
static unsigned long swapper_surfaces[6];
-static Bool RADEONPrepareAccess(PixmapPtr pPix, int index)
+static Bool RADEONPrepareAccess_BE(PixmapPtr pPix, int index)
{
RINFO_FROM_SCREEN(pPix->drawable.pScreen);
unsigned char *RADEONMMIO = info->MMIO;
@@ -290,7 +298,7 @@ static Bool RADEONPrepareAccess(PixmapPtr pPix, int index)
return TRUE;
}
-static void RADEONFinishAccess(PixmapPtr pPix, int index)
+static void RADEONFinishAccess_BE(PixmapPtr pPix, int index)
{
RINFO_FROM_SCREEN(pPix->drawable.pScreen);
unsigned char *RADEONMMIO = info->MMIO;
@@ -323,6 +331,123 @@ static void RADEONFinishAccess(PixmapPtr pPix, int index)
#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */
+#ifdef XF86DRM_MODE
+static Bool RADEONPrepareAccess_CS(PixmapPtr pPix, int index)
+{
+ RINFO_FROM_SCREEN(pPix->drawable.pScreen);
+ struct radeon_exa_pixmap_priv *driver_priv;
+ int ret;
+
+ driver_priv = exaGetPixmapDriverPrivate(pPix);
+ if (!driver_priv)
+ return FALSE;
+
+ /* if we have more refs than just the BO then flush */
+ if (driver_priv->bo->cref > 1)
+ RADEONCPFlushIndirect(pScrn, 0);
+
+ radeon_bo_wait(driver_priv->bo);
+
+ /* flush IB */
+ ret = radeon_bo_map(driver_priv->bo, 1);
+ if (ret) {
+ FatalError("failed to map pixmap %d\n", ret);
+ return FALSE;
+ }
+
+ pPix->devPrivate.ptr = driver_priv->bo->ptr;
+
+ return TRUE;
+}
+
+static void RADEONFinishAccess_CS(PixmapPtr pPix, int index)
+{
+ struct radeon_exa_pixmap_priv *driver_priv;
+
+ driver_priv = exaGetPixmapDriverPrivate(pPix);
+ if (!driver_priv)
+ return;
+
+ radeon_bo_unmap(driver_priv->bo);
+ pPix->devPrivate.ptr = NULL;
+}
+
+
+void *RADEONEXACreatePixmap(ScreenPtr pScreen, int size, int align)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_exa_pixmap_priv *new_priv;
+
+ new_priv = xcalloc(1, sizeof(struct radeon_exa_pixmap_priv));
+ if (!new_priv)
+ return NULL;
+
+ if (size == 0)
+ return new_priv;
+
+ new_priv->bo = radeon_bo_open(info->bufmgr, 0, size,
+ align, 0, 0);
+ if (!new_priv->bo) {
+ xfree(new_priv);
+ ErrorF("Failed to alloc memory\n");
+ return NULL;
+ }
+
+ return new_priv;
+
+}
+
+static void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_exa_pixmap_priv *driver_priv = driverPriv;
+
+ radeon_bo_unref(driver_priv->bo);
+ xfree(driverPriv);
+}
+
+struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_exa_pixmap_priv *driver_priv;
+ driver_priv = exaGetPixmapDriverPrivate(pPix);
+ return driver_priv->bo;
+}
+
+void radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ struct radeon_exa_pixmap_priv *driver_priv;
+
+ driver_priv = exaGetPixmapDriverPrivate(pPix);
+ if (driver_priv) {
+ if (driver_priv->bo)
+ radeon_bo_unref(driver_priv->bo);
+
+ radeon_bo_ref(bo);
+ driver_priv->bo = bo;
+ }
+}
+
+static Bool RADEONEXAPixmapIsOffscreen(PixmapPtr pPix)
+{
+ struct radeon_exa_pixmap_priv *driver_priv;
+
+ driver_priv = exaGetPixmapDriverPrivate(pPix);
+
+ if (!driver_priv)
+ return FALSE;
+ if (driver_priv->bo)
+ return TRUE;
+ return FALSE;
+}
+#endif
+
#define ENTER_DRAW(x) TRACE
#define LEAVE_DRAW(x) TRACE
/***********************************************************************/
@@ -332,6 +457,7 @@ static void RADEONFinishAccess(PixmapPtr pPix, int index)
#define BEGIN_ACCEL(n) RADEONWaitForFifo(pScrn, (n))
#define OUT_ACCEL_REG(reg, val) OUTREG(reg, val)
#define OUT_ACCEL_REG_F(reg, val) OUTREG(reg, F_TO_DW(val))
+#define OUT_RELOC(x, read, write) do {} while(0)
#define FINISH_ACCEL()
#ifdef RENDER
@@ -345,6 +471,7 @@ static void RADEONFinishAccess(PixmapPtr pPix, int index)
#undef OUT_ACCEL_REG
#undef OUT_ACCEL_REG_F
#undef FINISH_ACCEL
+#undef OUT_RELOC
#ifdef XF86DRI
@@ -355,6 +482,7 @@ static void RADEONFinishAccess(PixmapPtr pPix, int index)
#define BEGIN_ACCEL(n) BEGIN_RING(2*(n))
#define OUT_ACCEL_REG(reg, val) OUT_RING_REG(reg, val)
#define FINISH_ACCEL() ADVANCE_RING()
+#define OUT_RELOC(x, read, write) OUT_RING_RELOC(x, read, write)
#define OUT_RING_F(x) OUT_RING(F_TO_DW(x))
@@ -523,6 +651,10 @@ RADEONTexOffsetStart(PixmapPtr pPix)
{
RINFO_FROM_SCREEN(pPix->drawable.pScreen);
unsigned long long offset;
+
+ if (exaGetPixmapDriverPrivate(pPix))
+ return -1;
+
exaMoveInPixmap(pPix);
ExaOffscreenMarkUsed(pPix);
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)
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
RADEONInfoPtr info = RADEONPTR(pScrn);
+ if (info->cs)
+ return;
+
TRACE;
if (info->accel_state->exaMarkerSynced != marker) {
@@ -84,11 +87,60 @@ FUNC_NAME(RADEONSync)(ScreenPtr pScreen, int marker)
RADEONPTR(pScrn)->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
}
+static void FUNC_NAME(Emit2DState)(ScrnInfoPtr pScrn, int op)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ int has_src;
+ ACCEL_PREAMBLE();
+
+ /* don't emit if no operation in progress */
+ if (info->state_2d.op == 0 && op == 0)
+ return;
+
+ has_src = info->state_2d.src_pitch_offset || (info->cs && info->state_2d.src_bo);
+
+ if (has_src) {
+ BEGIN_ACCEL_RELOC(10, 2);
+ } else {
+ BEGIN_ACCEL_RELOC(9, 1);
+ }
+ OUT_ACCEL_REG(RADEON_DEFAULT_SC_BOTTOM_RIGHT, info->state_2d.default_sc_bottom_right);
+ OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, info->state_2d.dp_gui_master_cntl);
+ OUT_ACCEL_REG(RADEON_DP_BRUSH_FRGD_CLR, info->state_2d.dp_brush_frgd_clr);
+ OUT_ACCEL_REG(RADEON_DP_BRUSH_BKGD_CLR, info->state_2d.dp_brush_bkgd_clr);
+ OUT_ACCEL_REG(RADEON_DP_SRC_FRGD_CLR, info->state_2d.dp_src_frgd_clr);
+ OUT_ACCEL_REG(RADEON_DP_SRC_BKGD_CLR, info->state_2d.dp_src_bkgd_clr);
+ OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, info->state_2d.dp_write_mask);
+ OUT_ACCEL_REG(RADEON_DP_CNTL, info->state_2d.dp_cntl);
+
+ OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, info->state_2d.dst_pitch_offset);
+ if (info->cs)
+ OUT_RELOC(info->state_2d.dst_bo, 0, RADEON_GEM_DOMAIN_VRAM);
+
+ if (has_src) {
+ OUT_ACCEL_REG(RADEON_SRC_PITCH_OFFSET, info->state_2d.src_pitch_offset);
+ if (info->cs)
+ OUT_RELOC(info->state_2d.src_bo, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0);
+
+ }
+ FINISH_ACCEL();
+
+ if (op)
+ info->state_2d.op = op;
+ if (info->cs)
+ info->reemit_current2d = FUNC_NAME(Emit2DState);
+}
+
static Bool
FUNC_NAME(RADEONPrepareSolid)(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
{
RINFO_FROM_SCREEN(pPix->drawable.pScreen);
uint32_t datatype, dst_pitch_offset;
+ struct radeon_exa_pixmap_priv *driver_priv;
+ int ret;
+ int retry_count = 0;
+ struct radeon_cs_space_check bos[1];
+ int i;
ACCEL_PREAMBLE();
TRACE;
@@ -101,21 +153,54 @@ FUNC_NAME(RADEONPrepareSolid)(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
RADEON_FALLBACK(("RADEONGetPixmapOffsetPitch failed\n"));
RADEON_SWITCH_TO_2D();
+ retry:
+ if (info->cs) {
+
+ i = 0;
+ driver_priv = exaGetPixmapDriverPrivate(pPix);
+ bos[i].bo = driver_priv->bo;
+ bos[i].read_domains = 0;
+ bos[i].write_domain = RADEON_GEM_DOMAIN_VRAM;;
+ bos[i].new_accounted = 0;
+ i++;
+
+ ret = radeon_cs_space_check(info->cs, bos, i);
+ if (ret == RADEON_CS_SPACE_OP_TO_BIG) {
+ RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n"));
+ }
+ if (ret == RADEON_CS_SPACE_FLUSH) {
+ radeon_cs_flush_indirect(pScrn);
+ retry_count++;
+ if (retry_count == 2)
+ RADEON_FALLBACK(("Not enough Video RAM for src\n"));
+ goto retry;
+ }
+ }
- BEGIN_ACCEL(5);
- OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL,
- RADEON_GMC_DST_PITCH_OFFSET_CNTL |
- RADEON_GMC_BRUSH_SOLID_COLOR |
- (datatype << 8) |
- RADEON_GMC_SRC_DATATYPE_COLOR |
- RADEON_ROP[alu].pattern |
- RADEON_GMC_CLR_CMP_CNTL_DIS);
- OUT_ACCEL_REG(RADEON_DP_BRUSH_FRGD_CLR, fg);
- OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, pm);
- OUT_ACCEL_REG(RADEON_DP_CNTL,
- (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM));
- OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, dst_pitch_offset);
- FINISH_ACCEL();
+
+ info->state_2d.default_sc_bottom_right = (RADEON_DEFAULT_SC_RIGHT_MAX |
+ RADEON_DEFAULT_SC_BOTTOM_MAX);
+ info->state_2d.dp_brush_bkgd_clr = 0x00000000;
+ info->state_2d.dp_src_frgd_clr = 0xffffffff;
+ info->state_2d.dp_src_bkgd_clr = 0x00000000;
+ info->state_2d.dp_gui_master_cntl = (RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+ RADEON_GMC_BRUSH_SOLID_COLOR |
+ (datatype << 8) |
+ RADEON_GMC_SRC_DATATYPE_COLOR |
+ RADEON_ROP[alu].pattern |
+ RADEON_GMC_CLR_CMP_CNTL_DIS);
+ info->state_2d.dp_brush_frgd_clr = fg;
+ info->state_2d.dp_cntl = (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM);
+ info->state_2d.dp_write_mask = pm;
+ info->state_2d.dst_pitch_offset = dst_pitch_offset;
+ info->state_2d.src_pitch_offset = 0;
+ info->state_2d.src_bo = NULL;
+
+ driver_priv = exaGetPixmapDriverPrivate(pPix);
+ if (driver_priv)
+ info->state_2d.dst_bo = driver_priv->bo;
+
+ FUNC_NAME(Emit2DState)(pScrn, RADEON_2D_EXA_SOLID);
return TRUE;
}
@@ -146,6 +231,7 @@ FUNC_NAME(RADEONDone2D)(PixmapPtr pPix)
TRACE;
+ info->state_2d.op = 0;
BEGIN_ACCEL(2);
OUT_ACCEL_REG(RADEON_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL);
OUT_ACCEL_REG(RADEON_WAIT_UNTIL,
@@ -161,25 +247,28 @@ FUNC_NAME(RADEONDoPrepareCopy)(ScrnInfoPtr pScrn, uint32_t src_pitch_offset,
RADEONInfoPtr info = RADEONPTR(pScrn);
ACCEL_PREAMBLE();
- RADEON_SWITCH_TO_2D();
-
- BEGIN_ACCEL(5);
- OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL,
- RADEON_GMC_DST_PITCH_OFFSET_CNTL |
- RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
- RADEON_GMC_BRUSH_NONE |
- (datatype << 8) |
- RADEON_GMC_SRC_DATATYPE_COLOR |
- RADEON_ROP[rop].rop |
- RADEON_DP_SRC_SOURCE_MEMORY |
- RADEON_GMC_CLR_CMP_CNTL_DIS);
- OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, planemask);
- OUT_ACCEL_REG(RADEON_DP_CNTL,
- ((info->accel_state->xdir >= 0 ? RADEON_DST_X_LEFT_TO_RIGHT : 0) |
- (info->accel_state->ydir >= 0 ? RADEON_DST_Y_TOP_TO_BOTTOM : 0)));
- OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, dst_pitch_offset);
- OUT_ACCEL_REG(RADEON_SRC_PITCH_OFFSET, src_pitch_offset);
- FINISH_ACCEL();
+ /* setup 2D state */
+ info->state_2d.dp_gui_master_cntl = (RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+ RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
+ RADEON_GMC_BRUSH_NONE |
+ (datatype << 8) |
+ RADEON_GMC_SRC_DATATYPE_COLOR |
+ RADEON_ROP[rop].rop |
+ RADEON_DP_SRC_SOURCE_MEMORY |
+ RADEON_GMC_CLR_CMP_CNTL_DIS);
+ info->state_2d.dp_cntl = ((info->accel_state->xdir >= 0 ? RADEON_DST_X_LEFT_TO_RIGHT : 0) |
+ (info->accel_state->ydir >= 0 ? RADEON_DST_Y_TOP_TO_BOTTOM : 0));
+ info->state_2d.dp_brush_frgd_clr = 0xffffffff;
+ info->state_2d.dp_brush_bkgd_clr = 0x00000000;
+ info->state_2d.dp_src_frgd_clr = 0xffffffff;
+ info->state_2d.dp_src_bkgd_clr = 0x00000000;
+ info->state_2d.dp_write_mask = planemask;
+ info->state_2d.dst_pitch_offset = dst_pitch_offset;
+ info->state_2d.src_pitch_offset = src_pitch_offset;
+ info->state_2d.default_sc_bottom_right = (RADEON_DEFAULT_SC_RIGHT_MAX
+ | RADEON_DEFAULT_SC_BOTTOM_MAX);
+
+ FUNC_NAME(Emit2DState)(pScrn, RADEON_2D_EXA_COPY);
}
static Bool
@@ -190,9 +279,42 @@ FUNC_NAME(RADEONPrepareCopy)(PixmapPtr pSrc, PixmapPtr pDst,
{
RINFO_FROM_SCREEN(pDst->drawable.pScreen);
uint32_t datatype, src_pitch_offset, dst_pitch_offset;
-
+ struct radeon_exa_pixmap_priv *driver_priv;
+ int ret;
+ int retry_count = 0;
+ struct radeon_cs_space_check bos[2];
+ int i;
TRACE;
+ RADEON_SWITCH_TO_2D();
+retry:
+ if (info->cs) {
+
+ driver_priv = exaGetPixmapDriverPrivate(pSrc);
+ info->state_2d.src_bo = driver_priv->bo;
+
+ driver_priv = exaGetPixmapDriverPrivate(pDst);
+ info->state_2d.dst_bo = driver_priv->bo;
+
+ i = 0;
+ radeon_add_pixmap(bos, i++, pSrc, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
+
+ radeon_add_pixmap(bos, i++, pDst, 0, RADEON_GEM_DOMAIN_VRAM);
+
+ ret = radeon_cs_space_check(info->cs, bos, i);
+ if (ret == RADEON_CS_SPACE_OP_TO_BIG) {
+ RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n"));
+ }
+ if (ret == RADEON_CS_SPACE_FLUSH) {
+ radeon_cs_flush_indirect(pScrn);
+ retry_count++;
+ if (retry_count == 2)
+ RADEON_FALLBACK(("Not enough Video RAM for src\n"));
+ goto retry;
+ }
+ }
+
+
info->accel_state->xdir = xdir;
info->accel_state->ydir = ydir;
@@ -256,6 +378,9 @@ RADEONUploadToScreenCP(PixmapPtr pDst, int x, int y, int w, int h,
TRACE;
+ if (info->cs)
+ return FALSE;
+
if (bpp < 8)
return FALSE;
@@ -458,9 +583,9 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
#endif
#if X_BYTE_ORDER == X_BIG_ENDIAN
- info->accel_state->exa->PrepareAccess = RADEONPrepareAccess;
- info->accel_state->exa->FinishAccess = RADEONFinishAccess;
-#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */
+ info->accel_state->exa->PrepareAccess = RADEONPrepareAccess_BE;
+ info->accel_state->exa->FinishAccess = RADEONFinishAccess_BE;
+#endif
info->accel_state->exa->flags = EXA_OFFSCREEN_PIXMAPS;
#ifdef EXA_SUPPORTS_PREPARE_AUX
@@ -473,6 +598,10 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
info->accel_state->exa->pixmapOffsetAlign = RADEON_BUFFER_ALIGN + 1;
info->accel_state->exa->pixmapPitchAlign = 64;
+ if (info->cs)
+ info->accel_state->exa->flags |= EXA_HANDLES_PIXMAPS;
+
+
#ifdef RENDER
if (info->RenderAccel) {
if (IS_R300_3D || IS_R500_3D) {
@@ -510,6 +639,19 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
}
#endif
+#ifdef XF86DRM_MODE
+#if (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 4)
+ if (info->cs) {
+ info->accel_state->exa->CreatePixmap = RADEONEXACreatePixmap;
+ info->accel_state->exa->DestroyPixmap = RADEONEXADestroyPixmap;
+ info->accel_state->exa->PixmapIsOffscreen = RADEONEXAPixmapIsOffscreen;
+ info->accel_state->exa->PrepareAccess = RADEONPrepareAccess_CS;
+ info->accel_state->exa->FinishAccess = RADEONFinishAccess_CS;
+ }
+#endif
+#endif
+
+
#if EXA_VERSION_MAJOR > 2 || (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 3)
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting EXA maxPitchBytes\n");
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,
Bool repeat = pPict->repeat && pPict->repeatType != RepeatPad &&
!(unit == 0 && (info->accel_state->need_src_tile_x || info->accel_state->need_src_tile_y));
int i;
+ struct radeon_exa_pixmap_priv *driver_priv;
ACCEL_PREAMBLE();
txpitch = exaGetPixmapPitch(pPix);
- txoffset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset;
+ txoffset = 0;
+
+ CHECK_OFFSET(pPix, 0x1f, "texture");
- if ((txoffset & 0x1f) != 0)
- RADEON_FALLBACK(("Bad texture offset 0x%x\n", (int)txoffset));
if ((txpitch & 0x1f) != 0)
RADEON_FALLBACK(("Bad texture pitch 0x%x\n", (int)txpitch));
@@ -426,23 +427,27 @@ static Bool FUNC_NAME(R100TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
}
}
- BEGIN_ACCEL(5);
+ BEGIN_ACCEL_RELOC(5, 1);
if (unit == 0) {
OUT_ACCEL_REG(RADEON_PP_TXFILTER_0, txfilter);
OUT_ACCEL_REG(RADEON_PP_TXFORMAT_0, txformat);
- OUT_ACCEL_REG(RADEON_PP_TXOFFSET_0, txoffset);
OUT_ACCEL_REG(RADEON_PP_TEX_SIZE_0,
(pPix->drawable.width - 1) |
((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT));
OUT_ACCEL_REG(RADEON_PP_TEX_PITCH_0, txpitch - 32);
+
+ EMIT_READ_OFFSET(RADEON_PP_TXOFFSET_0, txoffset, pPix);
+ /* emit a texture relocation */
} else {
OUT_ACCEL_REG(RADEON_PP_TXFILTER_1, txfilter);
OUT_ACCEL_REG(RADEON_PP_TXFORMAT_1, txformat);
- OUT_ACCEL_REG(RADEON_PP_TXOFFSET_1, txoffset);
+
OUT_ACCEL_REG(RADEON_PP_TEX_SIZE_1,
(pPix->drawable.width - 1) |
((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT));
OUT_ACCEL_REG(RADEON_PP_TEX_PITCH_1, txpitch - 32);
+ EMIT_READ_OFFSET(RADEON_PP_TXOFFSET_1, txoffset, pPix);
+ /* emit a texture relocation */
}
FINISH_ACCEL();
@@ -548,9 +553,13 @@ static Bool FUNC_NAME(R100PrepareComposite)(int op,
PixmapPtr pDst)
{
RINFO_FROM_SCREEN(pDst->drawable.pScreen);
- uint32_t dst_format, dst_offset, dst_pitch, colorpitch;
+ uint32_t dst_format, dst_pitch, colorpitch;
uint32_t pp_cntl, blendcntl, cblend, ablend;
int pixel_shift;
+ struct radeon_exa_pixmap_priv *driver_priv;
+ int retry_count = 0;
+ struct radeon_cs_space_check bos[3];
+ int i, ret;
ACCEL_PREAMBLE();
TRACE;
@@ -568,24 +577,45 @@ static Bool FUNC_NAME(R100PrepareComposite)(int op,
pixel_shift = pDst->drawable.bitsPerPixel >> 4;
- dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset;
dst_pitch = exaGetPixmapPitch(pDst);
colorpitch = dst_pitch >> pixel_shift;
if (RADEONPixmapIsColortiled(pDst))
colorpitch |= RADEON_COLOR_TILE_ENABLE;
- dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset;
- dst_pitch = exaGetPixmapPitch(pDst);
- if ((dst_offset & 0x0f) != 0)
- RADEON_FALLBACK(("Bad destination offset 0x%x\n", (int)dst_offset));
+ CHECK_OFFSET(pDst, 0x0f, "destination");
+
if (((dst_pitch >> pixel_shift) & 0x7) != 0)
RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch));
+ /* switch to 3D before doing buffer space checks as it may flush */
+ RADEON_SWITCH_TO_3D();
+ retry:
+ if (info->cs) {
+
+ i = 0;
+ radeon_add_pixmap(bos, i++, pSrc, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
+
+ if (pMask)
+ radeon_add_pixmap(bos, i++, pMask, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
+
+ radeon_add_pixmap(bos, i++, pDst, 0, RADEON_GEM_DOMAIN_VRAM);
+
+ ret = radeon_cs_space_check(info->cs, bos, i);
+ if (ret == RADEON_CS_SPACE_OP_TO_BIG) {
+ RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n"));
+ }
+ if (ret == RADEON_CS_SPACE_FLUSH) {
+ radeon_cs_flush_indirect(pScrn);
+ retry_count++;
+ if (retry_count == 2)
+ RADEON_FALLBACK(("Not enough Video RAM for src\n"));
+ goto retry;
+ }
+ }
+
if (!RADEONSetupSourceTile(pSrcPicture, pSrc, FALSE, TRUE))
return FALSE;
- RADEON_SWITCH_TO_3D();
-
if (!FUNC_NAME(R100TextureSetup)(pSrcPicture, pSrc, 0))
return FALSE;
pp_cntl = RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE;
@@ -598,10 +628,10 @@ static Bool FUNC_NAME(R100PrepareComposite)(int op,
info->accel_state->is_transform[1] = FALSE;
}
- BEGIN_ACCEL(10);
+ BEGIN_ACCEL_RELOC(10, 1);
OUT_ACCEL_REG(RADEON_PP_CNTL, pp_cntl);
OUT_ACCEL_REG(RADEON_RB3D_CNTL, dst_format | RADEON_ALPHA_BLEND_ENABLE);
- OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset);
+ EMIT_WRITE_OFFSET(RADEON_RB3D_COLOROFFSET, 0, pDst);
OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, colorpitch);
/* IN operator: Multiply src by mask components or mask alpha.
@@ -705,13 +735,14 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
Bool repeat = pPict->repeat && pPict->repeatType != RepeatPad &&
!(unit == 0 && (info->accel_state->need_src_tile_x || info->accel_state->need_src_tile_y));
int i;
+ struct radeon_exa_pixmap_priv *driver_priv;
ACCEL_PREAMBLE();
txpitch = exaGetPixmapPitch(pPix);
- txoffset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset;
- if ((txoffset & 0x1f) != 0)
- RADEON_FALLBACK(("Bad texture offset 0x%x\n", (int)txoffset));
+ txoffset = 0;
+ CHECK_OFFSET(pPix, 0x1f, "texture");
+
if ((txpitch & 0x1f) != 0)
RADEON_FALLBACK(("Bad texture pitch 0x%x\n", (int)txpitch));
@@ -768,7 +799,7 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
}
}
- BEGIN_ACCEL(6);
+ BEGIN_ACCEL_RELOC(6, 1);
if (unit == 0) {
OUT_ACCEL_REG(R200_PP_TXFILTER_0, txfilter);
OUT_ACCEL_REG(R200_PP_TXFORMAT_0, txformat);
@@ -776,7 +807,7 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
OUT_ACCEL_REG(R200_PP_TXSIZE_0, (pPix->drawable.width - 1) |
((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT));
OUT_ACCEL_REG(R200_PP_TXPITCH_0, txpitch - 32);
- OUT_ACCEL_REG(R200_PP_TXOFFSET_0, txoffset);
+ EMIT_READ_OFFSET(R200_PP_TXOFFSET_0, txoffset, pPix);
} else {
OUT_ACCEL_REG(R200_PP_TXFILTER_1, txfilter);
OUT_ACCEL_REG(R200_PP_TXFORMAT_1, txformat);
@@ -784,7 +815,8 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
OUT_ACCEL_REG(R200_PP_TXSIZE_1, (pPix->drawable.width - 1) |
((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT));
OUT_ACCEL_REG(R200_PP_TXPITCH_1, txpitch - 32);
- OUT_ACCEL_REG(R200_PP_TXOFFSET_1, txoffset);
+ EMIT_READ_OFFSET(R200_PP_TXOFFSET_1, txoffset, pPix);
+ /* emit a texture relocation */
}
FINISH_ACCEL();
@@ -878,9 +910,13 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture,
PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
{
RINFO_FROM_SCREEN(pDst->drawable.pScreen);
- uint32_t dst_format, dst_offset, dst_pitch;
+ uint32_t dst_format, dst_pitch;
uint32_t pp_cntl, blendcntl, cblend, ablend, colorpitch;
int pixel_shift;
+ struct radeon_exa_pixmap_priv *driver_priv;
+ int retry_count = 0;
+ struct radeon_cs_space_check bos[3];
+ int i, ret;
ACCEL_PREAMBLE();
TRACE;
@@ -898,22 +934,45 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture,
pixel_shift = pDst->drawable.bitsPerPixel >> 4;
- dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset;
dst_pitch = exaGetPixmapPitch(pDst);
colorpitch = dst_pitch >> pixel_shift;
if (RADEONPixmapIsColortiled(pDst))
colorpitch |= RADEON_COLOR_TILE_ENABLE;
- if ((dst_offset & 0x0f) != 0)
- RADEON_FALLBACK(("Bad destination offset 0x%x\n", (int)dst_offset));
+ CHECK_OFFSET(pDst, 0xf, "destination");
+
if (((dst_pitch >> pixel_shift) & 0x7) != 0)
RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch));
+ /* switch to 3D before doing buffer space checks as it may flush */
+ RADEON_SWITCH_TO_3D();
+
+ retry:
+ if (info->cs) {
+
+ i = 0;
+ radeon_add_pixmap(bos, i++, pSrc, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
+
+ if (pMask)
+ radeon_add_pixmap(bos, i++, pMask, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
+
+ radeon_add_pixmap(bos, i++, pDst, 0, RADEON_GEM_DOMAIN_VRAM);
+
+ ret = radeon_cs_space_check(info->cs, bos, i);
+ if (ret == RADEON_CS_SPACE_OP_TO_BIG) {
+ RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n"));
+ }
+ if (ret == RADEON_CS_SPACE_FLUSH) {
+ radeon_cs_flush_indirect(pScrn);
+ retry_count++;
+ if (retry_count == 2)
+ RADEON_FALLBACK(("Not enough Video RAM for src\n"));
+ goto retry;
+ }
+ }
if (!RADEONSetupSourceTile(pSrcPicture, pSrc, FALSE, TRUE))
return FALSE;
- RADEON_SWITCH_TO_3D();
-
if (!FUNC_NAME(R200TextureSetup)(pSrcPicture, pSrc, 0))
return FALSE;
pp_cntl = RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE;
@@ -926,11 +985,12 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture,
info->accel_state->is_transform[1] = FALSE;
}
- BEGIN_ACCEL(13);
+ BEGIN_ACCEL_RELOC(13, 1);
OUT_ACCEL_REG(RADEON_PP_CNTL, pp_cntl);
OUT_ACCEL_REG(RADEON_RB3D_CNTL, dst_format | RADEON_ALPHA_BLEND_ENABLE);
- OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset);
+
+ EMIT_WRITE_OFFSET(RADEON_RB3D_COLOROFFSET, 0, pDst);
OUT_ACCEL_REG(R200_SE_VTX_FMT_0, R200_VTX_XY);
if (pMask)
@@ -1004,6 +1064,10 @@ static Bool R300CheckCompositeTexture(PicturePtr pPict,
int unit,
Bool is_r500)
{
+ ScreenPtr pScreen = pDstPict->pDrawable->pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
int w = pPict->pDrawable->width;
int h = pPict->pDrawable->height;
int i;
@@ -1029,8 +1093,17 @@ static Bool R300CheckCompositeTexture(PicturePtr pPict,
RADEON_FALLBACK(("Unsupported picture format 0x%x\n",
(int)pPict->format));
- if (!RADEONCheckTexturePOT(pPict, unit == 0))
+ if (!RADEONCheckTexturePOT(pPict, unit == 0)) {
+ if (info->cs) {
+ struct radeon_exa_pixmap_priv *driver_priv;
+ PixmapPtr pPix;
+
+ pPix = RADEONGetDrawablePixmap(pPict->pDrawable);
+ driver_priv = exaGetPixmapDriverPrivate(pPix);
+ //TODOradeon_bufmgr_gem_force_gtt(driver_priv->bo);
+ }
return FALSE;
+ }
if (pPict->filter != PictFilterNearest &&
pPict->filter != PictFilterBilinear)
@@ -1062,15 +1135,16 @@ static Bool FUNC_NAME(R300TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
int w = pPict->pDrawable->width;
int h = pPict->pDrawable->height;
int i, pixel_shift;
+ struct radeon_exa_pixmap_priv *driver_priv;
ACCEL_PREAMBLE();
TRACE;
txpitch = exaGetPixmapPitch(pPix);
- txoffset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset;
+ txoffset = 0;
+
+ CHECK_OFFSET(pPix, 0x1f, "texture");
- if ((txoffset & 0x1f) != 0)
- RADEON_FALLBACK(("Bad texture offset 0x%x\n", (int)txoffset));
if ((txpitch & 0x1f) != 0)
RADEON_FALLBACK(("Bad texture pitch 0x%x\n", (int)txpitch));
@@ -1156,13 +1230,15 @@ static Bool FUNC_NAME(R300TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
RADEON_FALLBACK(("Bad filter 0x%x\n", pPict->filter));
}
- BEGIN_ACCEL(pPict->repeat ? 6 : 7);
+ BEGIN_ACCEL_RELOC(pPict->repeat ? 6 : 7, 1);
OUT_ACCEL_REG(R300_TX_FILTER0_0 + (unit * 4), txfilter);
OUT_ACCEL_REG(R300_TX_FILTER1_0 + (unit * 4), 0);
OUT_ACCEL_REG(R300_TX_FORMAT0_0 + (unit * 4), txformat0);
OUT_ACCEL_REG(R300_TX_FORMAT1_0 + (unit * 4), txformat1);
OUT_ACCEL_REG(R300_TX_FORMAT2_0 + (unit * 4), txpitch);
- OUT_ACCEL_REG(R300_TX_OFFSET_0 + (unit * 4), txoffset);
+
+ EMIT_READ_OFFSET((R300_TX_OFFSET_0 + (unit * 4)), txoffset, pPix);
+
if (!pPict->repeat)
OUT_ACCEL_REG(R300_TX_BORDER_COLOR_0 + (unit * 4), 0);
FINISH_ACCEL();
@@ -1321,14 +1397,18 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
{
RINFO_FROM_SCREEN(pDst->drawable.pScreen);
- uint32_t dst_format, dst_offset, dst_pitch;
+ uint32_t dst_format, dst_pitch;
uint32_t txenable, colorpitch;
uint32_t blendcntl, output_fmt;
uint32_t src_color, src_alpha;
uint32_t mask_color, mask_alpha;
int pixel_shift;
+ int ret;
+ int retry_count = 0;
+ struct radeon_exa_pixmap_priv *driver_priv;
+ struct radeon_cs_space_check bos[3];
+ int i;
ACCEL_PREAMBLE();
-
TRACE;
if (!R300GetDestFormat(pDstPicture, &dst_format))
@@ -1341,7 +1421,6 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
pixel_shift = pDst->drawable.bitsPerPixel >> 4;
- dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset;
dst_pitch = exaGetPixmapPitch(pDst);
colorpitch = dst_pitch >> pixel_shift;
@@ -1350,16 +1429,41 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
colorpitch |= dst_format;
- if ((dst_offset & 0x0f) != 0)
- RADEON_FALLBACK(("Bad destination offset 0x%x\n", (int)dst_offset));
+ CHECK_OFFSET(pDst, 0x0f, "destination");
+
if (((dst_pitch >> pixel_shift) & 0x7) != 0)
RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch));
+ /* have to execute switch before doing buffer sizing check as it flushes */
+ RADEON_SWITCH_TO_3D();
+ retry:
+ if (info->cs) {
+
+ i = 0;
+ driver_priv = exaGetPixmapDriverPrivate(pSrc);
+ radeon_add_pixmap(bos, i++, pSrc, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
+
+ if (pMask)
+ radeon_add_pixmap(bos, i++, pMask, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
+
+ radeon_add_pixmap(bos, i++, pDst, 0, RADEON_GEM_DOMAIN_VRAM);
+
+ ret = radeon_cs_space_check(info->cs, bos, i);
+ if (ret == RADEON_CS_SPACE_OP_TO_BIG) {
+ RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n"));
+ }
+ if (ret == RADEON_CS_SPACE_FLUSH) {
+ radeon_cs_flush_indirect(pScrn);
+ retry_count++;
+ if (retry_count == 2)
+ RADEON_FALLBACK(("Not enough Video RAM - this really shouldn't happen\nm"));
+ goto retry;
+ }
+ }
+
if (!RADEONSetupSourceTile(pSrcPicture, pSrc, TRUE, FALSE))
return FALSE;
- RADEON_SWITCH_TO_3D();
-
if (!FUNC_NAME(R300TextureSetup)(pSrcPicture, pSrc, 0))
return FALSE;
txenable = R300_TEX_0_ENABLE;
@@ -1945,9 +2049,9 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
}
FINISH_ACCEL();
- BEGIN_ACCEL(3);
-
- OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset);
+
+ BEGIN_ACCEL_RELOC(3, 1);
+ EMIT_WRITE_OFFSET(R300_RB3D_COLOROFFSET0, 0, pDst);
OUT_ACCEL_REG(R300_RB3D_COLORPITCH0, colorpitch);
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 { \
#define INPCIE_P(pScrn, addr) R600INPCIE_PORT(pScrn, addr)
#define OUTPCIE_P(pScrn, addr, val) R600OUTPCIE_PORT(pScrn, addr, val)
+#define BEGIN_ACCEL_RELOC(n, r) do { \
+ int _nqw = (n) + (info->cs ? (r) : 0); \
+ BEGIN_ACCEL(_nqw); \
+ } while (0)
+
+#define CHECK_OFFSET(pPix, mask, type) do { \
+ if (!info->cs) { \
+ uint32_t _pix_offset = radeonGetPixmapOffset(pPix); \
+ if ((_pix_offset & mask) != 0) \
+ RADEON_FALLBACK(("Bad %s offset 0x%x\n", type, (int)pix_offset)); \
+ } \
+ } while(0)
+
+#define EMIT_OFFSET(reg, value, pPix, rd, wd) do { \
+ if (info->cs) { \
+ driver_priv = exaGetPixmapDriverPrivate(pPix); \
+ OUT_ACCEL_REG((reg), 0); \
+ OUT_RELOC(driver_priv->bo, (rd), (wd)); \
+ } else { \
+ uint32_t _pix_offset; \
+ _pix_offset = radeonGetPixmapOffset(pPix); \
+ OUT_ACCEL_REG((reg), _pix_offset | value); \
+ } \
+ } while(0)
+
+#define EMIT_READ_OFFSET(reg, value, pPix) EMIT_OFFSET(reg, value, pPix, (RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT), 0)
+#define EMIT_WRITE_OFFSET(reg, value, pPix) EMIT_OFFSET(reg, value, pPix, 0, RADEON_GEM_DOMAIN_VRAM)
+
+#define OUT_TEXTURE_REG(reg, offset, bo) do { \
+ if (info->cs) { \
+ OUT_ACCEL_REG((reg), (offset)); \
+ OUT_RELOC((bo), RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); \
+ } else { \
+ OUT_ACCEL_REG((reg), (offset) + info->fbLocation + pScrn->fbOffset);} \
+ } while(0)
+
+
#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] =
#define BEGIN_ACCEL(n) RADEONWaitForFifo(pScrn, (n))
#define OUT_ACCEL_REG(reg, val) OUTREG(reg, val)
#define OUT_ACCEL_REG_F(reg, val) OUTREG(reg, F_TO_DW(val))
+#define OUT_RELOC(x, read, write) do {} while(0)
#define FINISH_ACCEL()
#include "radeon_textured_videofuncs.c"
@@ -151,6 +152,7 @@ static REF_TRANSFORM trans[2] =
#undef BEGIN_ACCEL
#undef OUT_ACCEL_REG
#undef OUT_ACCEL_REG_F
+#undef OUT_RELOC
#undef FINISH_ACCEL
#ifdef XF86DRI
@@ -164,6 +166,7 @@ static REF_TRANSFORM trans[2] =
#define OUT_ACCEL_REG_F(reg, val) OUT_ACCEL_REG(reg, F_TO_DW(val))
#define FINISH_ACCEL() ADVANCE_RING()
#define OUT_RING_F(x) OUT_RING(F_TO_DW(x))
+#define OUT_RELOC(x, read, write) OUT_RING_RELOC(x, read, write)
#include "radeon_textured_videofuncs.c"
@@ -323,6 +326,9 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn,
size * 2, 64);
if (pPriv->video_offset == 0)
return BadAlloc;
+
+ if (info->cs)
+ pPriv->src_bo = pPriv->video_memory;
}
/* Bicubic filter loading */
@@ -333,6 +339,9 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn,
pPriv->bicubic_src_offset = pPriv->bicubic_offset + info->fbLocation + pScrn->fbOffset;
if (pPriv->bicubic_offset == 0)
pPriv->bicubic_enabled = FALSE;
+
+ if (info->cs)
+ pPriv->bicubic_bo = pPriv->bicubic_memory;
}
if (pDraw->type == DRAWABLE_WINDOW)
@@ -361,8 +370,18 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn,
top = (y1 >> 16) & ~1;
nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
- pPriv->src_offset = pPriv->video_offset + info->fbLocation + pScrn->fbOffset;
- pPriv->src_addr = (uint8_t *)(info->FB + pPriv->video_offset);
+ pPriv->src_offset = pPriv->video_offset;
+ if (info->cs) {
+ int ret;
+ radeon_bo_wait(pPriv->src_bo);
+ ret = radeon_bo_map(pPriv->src_bo, 1);
+ if (ret)
+ return BadAlloc;
+
+ pPriv->src_addr = pPriv->src_bo->ptr;
+ } else {
+ pPriv->src_addr = (uint8_t *)(info->FB + pPriv->video_offset);
+ }
pPriv->src_pitch = dstPitch;
pPriv->planeu_offset = dstPitch * dst_height;
@@ -431,9 +450,23 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn,
/* Upload bicubic filter tex */
if (pPriv->bicubic_enabled) {
- if (info->ChipFamily < CHIP_FAMILY_R600)
- RADEONCopyData(pScrn, (uint8_t *)bicubic_tex_512,
- (uint8_t *)(info->FB + pPriv->bicubic_offset), 1024, 1024, 1, 512, 2);
+ if (info->ChipFamily < CHIP_FAMILY_R600) {
+ uint8_t *bicubic_addr;
+ int ret;
+ if (info->cs) {
+ radeon_bo_wait(pPriv->bicubic_bo);
+ ret = radeon_bo_map(pPriv->bicubic_bo, 1);
+ if (ret)
+ return BadAlloc;
+
+ bicubic_addr = pPriv->bicubic_bo->ptr;
+ } else
+ bicubic_addr = (uint8_t *)(info->FB + pPriv->bicubic_offset);
+
+ RADEONCopyData(pScrn, (uint8_t *)bicubic_tex_512, bicubic_addr, 1024, 1024, 1, 512, 2);
+ if (info->cs)
+ radeon_bo_unmap(pPriv->bicubic_bo);
+ }
}
/* update cliplist */
@@ -453,6 +486,8 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn,
pPriv->w = width;
pPriv->h = height;
+ if (info->cs)
+ radeon_bo_unmap(pPriv->src_bo);
#ifdef XF86DRI
if (info->directRenderingEnabled) {
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
{
RADEONInfoPtr info = RADEONPTR(pScrn);
PixmapPtr pPixmap = pPriv->pPixmap;
- uint32_t txformat, txsize, txpitch;
- uint32_t dst_offset, dst_pitch, dst_format;
+ struct radeon_exa_pixmap_priv *driver_priv;
+ struct radeon_cs_space_check bos[3];
+ uint32_t txformat, txsize, txpitch, txoffset;
+ uint32_t dst_pitch, dst_format;
uint32_t colorpitch;
Bool isplanar = FALSE;
int dstxoff, dstyoff, pixel_shift, vtx_count;
BoxPtr pBox = REGION_RECTS(&pPriv->clip);
int nBox = REGION_NUM_RECTS(&pPriv->clip);
+ int i, ret, retry_count = 0;
ACCEL_PREAMBLE();
+ retry:
+ if (info->cs) {
+
+ i = 0;
+ bos[i].bo = pPriv->src_bo;
+ bos[i].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
+ bos[i].write_domain = 0;
+ bos[i].new_accounted = 0;
+ i++;
+
+ if (pPriv->bicubic_enabled) {
+ bos[i].bo = pPriv->bicubic_bo;
+ bos[i].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
+ bos[i].write_domain = 0;
+ bos[i].new_accounted = 0;
+ i++;
+ }
+
+ driver_priv = exaGetPixmapDriverPrivate(pPixmap);
+ bos[i].bo = driver_priv->bo;
+ bos[i].read_domains = 0;
+ bos[i].write_domain = RADEON_GEM_DOMAIN_VRAM;
+ bos[i].new_accounted = 0;
+ i++;
+
+ ret = radeon_cs_space_check(info->cs, bos, i);
+ if (ret == RADEON_CS_SPACE_OP_TO_BIG) {
+ ErrorF("Not enough RAM to hw accel composite operation\n");
+ return;
+ }
+ if (ret == RADEON_CS_SPACE_FLUSH) {
+ radeon_cs_flush_indirect(pScrn);
+ retry_count++;
+ if (retry_count == 2) {
+ ErrorF("Not enough RAM to hw accel composite operation\n");
+ return;
+ }
+ goto retry;
+ }
+ }
+
pixel_shift = pPixmap->drawable.bitsPerPixel >> 4;
+
#ifdef USE_EXA
if (info->useEXA) {
- dst_offset = exaGetPixmapOffset(pPixmap) + info->fbLocation + pScrn->fbOffset;
dst_pitch = exaGetPixmapPitch(pPixmap);
} else
#endif
{
- dst_offset = (pPixmap->devPrivate.ptr - info->FB) +
- info->fbLocation + pScrn->fbOffset;
- dst_pitch = pPixmap->devKind;
+ dst_pitch = pPixmap->devKind;
}
#ifdef COMPOSITE
@@ -175,10 +217,12 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
if (RADEONTilingEnabled(pScrn, pPixmap))
colorpitch |= RADEON_COLOR_TILE_ENABLE;
- BEGIN_ACCEL(4);
+ txoffset = info->cs ? 0 : pPriv->src_offset;
+
+ BEGIN_ACCEL_RELOC(4,1);
OUT_ACCEL_REG(RADEON_RB3D_CNTL, dst_format);
- OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset);
+ EMIT_WRITE_OFFSET(RADEON_RB3D_COLOROFFSET, 0, pPixmap);
OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, colorpitch);
OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL,
RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO);
@@ -215,7 +259,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
RADEON_CLAMP_T_CLAMP_LAST |
RADEON_YUV_TO_RGB);
OUT_ACCEL_REG(RADEON_PP_TXFORMAT_0, txformat | RADEON_TXFORMAT_ST_ROUTE_STQ0);
- OUT_ACCEL_REG(RADEON_PP_TXOFFSET_0, pPriv->src_offset);
+ OUT_TEXTURE_REG(R200_PP_TXOFFSET_0, txoffset, pPriv->src_bo);
OUT_ACCEL_REG(RADEON_PP_TXCBLEND_0,
RADEON_COLOR_ARG_A_ZERO |
RADEON_COLOR_ARG_B_ZERO |
@@ -242,7 +286,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
RADEON_CLAMP_S_CLAMP_LAST |
RADEON_CLAMP_T_CLAMP_LAST);
OUT_ACCEL_REG(RADEON_PP_TXFORMAT_1, txformat | RADEON_TXFORMAT_ST_ROUTE_STQ1);
- OUT_ACCEL_REG(RADEON_PP_TXOFFSET_1, pPriv->src_offset + pPriv->planeu_offset);
+ OUT_TEXTURE_REG(R200_PP_TXOFFSET_1, txoffset + pPriv->planeu_offset, pPriv->src_bo);
OUT_ACCEL_REG(RADEON_PP_TXCBLEND_1,
RADEON_COLOR_ARG_A_ZERO |
RADEON_COLOR_ARG_B_ZERO |
@@ -266,7 +310,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
RADEON_CLAMP_S_CLAMP_LAST |
RADEON_CLAMP_T_CLAMP_LAST);
OUT_ACCEL_REG(RADEON_PP_TXFORMAT_2, txformat | RADEON_TXFORMAT_ST_ROUTE_STQ1);
- OUT_ACCEL_REG(RADEON_PP_TXOFFSET_2, pPriv->src_offset + pPriv->planev_offset);
+ OUT_TEXTURE_REG(R200_PP_TXOFFSET_2, txoffset + pPriv->planev_offset, pPriv->src_bo);
OUT_ACCEL_REG(RADEON_PP_TXCBLEND_2,
RADEON_COLOR_ARG_A_ZERO |
RADEON_COLOR_ARG_B_ZERO |
@@ -299,7 +343,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
RADEON_CLAMP_T_CLAMP_LAST |
RADEON_YUV_TO_RGB);
OUT_ACCEL_REG(RADEON_PP_TXFORMAT_0, txformat | RADEON_TXFORMAT_ST_ROUTE_STQ0);
- OUT_ACCEL_REG(RADEON_PP_TXOFFSET_0, pPriv->src_offset);
+ OUT_TEXTURE_REG(RADEON_PP_TXOFFSET_0, txoffset, pPriv->src_bo);
OUT_ACCEL_REG(RADEON_PP_TXCBLEND_0,
RADEON_COLOR_ARG_A_ZERO |
RADEON_COLOR_ARG_B_ZERO |
@@ -448,9 +492,10 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
PixmapPtr pPixmap = pPriv->pPixmap;
+ struct radeon_exa_pixmap_priv *driver_priv;
uint32_t txformat;
- uint32_t txfilter, txsize, txpitch;
- uint32_t dst_offset, dst_pitch, dst_format;
+ uint32_t txfilter, txsize, txpitch, txoffset;
+ uint32_t dst_pitch, dst_format;
uint32_t colorpitch;
Bool isplanar = FALSE;
int dstxoff, dstyoff, pixel_shift, vtx_count;
@@ -473,15 +518,12 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
#ifdef USE_EXA
if (info->useEXA) {
- dst_offset = exaGetPixmapOffset(pPixmap) + info->fbLocation + pScrn->fbOffset;
dst_pitch = exaGetPixmapPitch(pPixmap);
} else
#endif
- {
- dst_offset = (pPixmap->devPrivate.ptr - info->FB) +
- info->fbLocation + pScrn->fbOffset;
- dst_pitch = pPixmap->devKind;
- }
+ {
+ dst_pitch = pPixmap->devKind;
+ }
#ifdef COMPOSITE
dstxoff = -pPixmap->screen_x + pPixmap->drawable.x;
@@ -546,7 +588,7 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
BEGIN_ACCEL(4);
OUT_ACCEL_REG(RADEON_RB3D_CNTL, dst_format);
- OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset);
+ EMIT_WRITE_OFFSET(RADEON_RB3D_COLOROFFSET, 0, pPixmap);
OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, colorpitch);
OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL,
@@ -590,6 +632,8 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
vcscale = 0.125;
}
+ txoffset = info->cs ? 0 : pPriv->src_offset;
+
if (isplanar) {
/* need 2 texcoord sets (even though they are identical) due
to denormalization! hw apparently can't premultiply
@@ -621,21 +665,21 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
(pPriv->w - 1) |
((pPriv->h - 1) << RADEON_TEX_VSIZE_SHIFT));
OUT_ACCEL_REG(R200_PP_TXPITCH_0, pPriv->src_pitch - 32);
- OUT_ACCEL_REG(R200_PP_TXOFFSET_0, pPriv->src_offset);
+ OUT_TEXTURE_REG(R200_PP_TXOFFSET_0, txoffset, pPriv->src_bo);
OUT_ACCEL_REG(R200_PP_TXFILTER_1, txfilter);
OUT_ACCEL_REG(R200_PP_TXFORMAT_1, txformat | R200_TXFORMAT_ST_ROUTE_STQ1);
OUT_ACCEL_REG(R200_PP_TXFORMAT_X_1, 0);
OUT_ACCEL_REG(R200_PP_TXSIZE_1, txsize);
OUT_ACCEL_REG(R200_PP_TXPITCH_1, txpitch);
- OUT_ACCEL_REG(R200_PP_TXOFFSET_1, pPriv->src_offset + pPriv->planeu_offset);
+ OUT_TEXTURE_REG(R200_PP_TXOFFSET_1, txoffset + pPriv->planeu_offset, pPriv->src_bo);
OUT_ACCEL_REG(R200_PP_TXFILTER_2, txfilter);
OUT_ACCEL_REG(R200_PP_TXFORMAT_2, txformat | R200_TXFORMAT_ST_ROUTE_STQ1);
OUT_ACCEL_REG(R200_PP_TXFORMAT_X_2, 0);
OUT_ACCEL_REG(R200_PP_TXSIZE_2, txsize);
OUT_ACCEL_REG(R200_PP_TXPITCH_2, txpitch);
- OUT_ACCEL_REG(R200_PP_TXOFFSET_2, pPriv->src_offset + pPriv->planev_offset);
+ OUT_TEXTURE_REG(R200_PP_TXOFFSET_2, txoffset + pPriv->planev_offset, pPriv->src_bo);
/* similar to r300 code. Note the big problem is that hardware constants
* 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)
(pPriv->w - 1) |
((pPriv->h - 1) << RADEON_TEX_VSIZE_SHIFT));
OUT_ACCEL_REG(R200_PP_TXPITCH_0, pPriv->src_pitch - 32);
- OUT_ACCEL_REG(R200_PP_TXOFFSET_0, pPriv->src_offset);
+ OUT_TEXTURE_REG(R200_PP_TXOFFSET_0, txoffset, pPriv->src_bo);
/* MAD temp1 / 2, const0.a * 2, temp0.ggg, -const0.rgb */
OUT_ACCEL_REG(R200_PP_TXCBLEND_0,
@@ -980,9 +1024,10 @@ FUNC_NAME(R300DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
PixmapPtr pPixmap = pPriv->pPixmap;
+ struct radeon_exa_pixmap_priv *driver_priv;
uint32_t txfilter, txformat0, txformat1, txoffset, txpitch;
- uint32_t dst_offset, dst_pitch, dst_format;
- uint32_t txenable, colorpitch;
+ uint32_t dst_pitch, dst_format;
+ uint32_t txenable, colorpitch, bicubic_offset;
uint32_t output_fmt;
Bool isplanar = FALSE;
int dstxoff, dstyoff, pixel_shift, vtx_count;
@@ -994,15 +1039,12 @@ FUNC_NAME(R300DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
#ifdef USE_EXA
if (info->useEXA) {
- dst_offset = exaGetPixmapOffset(pPixmap) + info->fbLocation + pScrn->fbOffset;
dst_pitch = exaGetPixmapPitch(pPixmap);
} else
#endif
- {
- dst_offset = (pPixmap->devPrivate.ptr - info->FB) +
- info->fbLocation + pScrn->fbOffset;
- dst_pitch = pPixmap->devKind;
- }
+ {
+ dst_pitch = pPixmap->devKind;
+ }
#ifdef COMPOSITE
dstxoff = -pPixmap->screen_x + pPixmap->drawable.x;
@@ -1095,9 +1137,9 @@ FUNC_NAME(R300DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
R300_TX_MIN_FILTER_LINEAR |
(0 << R300_TX_ID_SHIFT));
- txoffset = pPriv->src_offset;
+ txoffset = info->cs ? 0 : pPriv->src_offset;
- BEGIN_ACCEL(6);
+ BEGIN_ACCEL_RELOC(6, 1);
OUT_ACCEL_REG(R300_TX_FILTER0_0, txfilter);
OUT_ACCEL_REG(R300_TX_FILTER1_0, 0);
OUT_ACCEL_REG(R300_TX_FORMAT0_0, txformat0);
@@ -1106,7 +1148,7 @@ FUNC_NAME(R300DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
else
OUT_ACCEL_REG(R300_TX_FORMAT1_0, txformat1);
OUT_ACCEL_REG(R300_TX_FORMAT2_0, txpitch);
- OUT_ACCEL_REG(R300_TX_OFFSET_0, txoffset);
+ OUT_TEXTURE_REG(R300_TX_OFFSET_0, txoffset, pPriv->src_bo);
FINISH_ACCEL();
txenable = R300_TEX_0_ENABLE;
@@ -1122,19 +1164,19 @@ FUNC_NAME(R300DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
R300_TX_MIN_FILTER_LINEAR |
R300_TX_MAG_FILTER_LINEAR);
- BEGIN_ACCEL(12);
+ BEGIN_ACCEL_RELOC(12, 2);
OUT_ACCEL_REG(R300_TX_FILTER0_1, txfilter | (1 << R300_TX_ID_SHIFT));
OUT_ACCEL_REG(R300_TX_FILTER1_1, 0);
OUT_ACCEL_REG(R300_TX_FORMAT0_1, txformat0);
OUT_ACCEL_REG(R300_TX_FORMAT1_1, R300_TX_FORMAT_X8 | R300_TX_FORMAT_CACHE_FOURTH_REGION_2);
OUT_ACCEL_REG(R300_TX_FORMAT2_1, txpitch);
- OUT_ACCEL_REG(R300_TX_OFFSET_1, txoffset + pPriv->planeu_offset);
+ OUT_TEXTURE_REG(R300_TX_OFFSET_1, txoffset + pPriv->planeu_offset, pPriv->src_bo);
OUT_ACCEL_REG(R300_TX_FILTER0_2, txfilter | (2 << R300_TX_ID_SHIFT));
OUT_ACCEL_REG(R300_TX_FILTER1_2, 0);
OUT_ACCEL_REG(R300_TX_FORMAT0_2, txformat0);
OUT_ACCEL_REG(R300_TX_FORMAT1_2, R300_TX_FORMAT_X8 | R300_TX_FORMAT_CACHE_FOURTH_REGION_3);
OUT_ACCEL_REG(R300_TX_FORMAT2_2, txpitch);
- OUT_ACCEL_REG(R300_TX_OFFSET_2, txoffset + pPriv->planev_offset);
+ OUT_TEXTURE_REG(R300_TX_OFFSET_2, txoffset + pPriv->planev_offset, pPriv->src_bo);
FINISH_ACCEL();
txenable |= R300_TEX_1_ENABLE | R300_TEX_2_ENABLE;
}
@@ -1155,13 +1197,18 @@ FUNC_NAME(R300DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
R300_TX_MAG_FILTER_NEAREST |
(1 << R300_TX_ID_SHIFT));
- BEGIN_ACCEL(6);
+ if (info->cs)
+ bicubic_offset = 0;
+ else
+ bicubic_offset = pPriv->bicubic_src_offset;
+
+ BEGIN_ACCEL_RELOC(6, 1);
OUT_ACCEL_REG(R300_TX_FILTER0_1, txfilter);
OUT_ACCEL_REG(R300_TX_FILTER1_1, 0);
OUT_ACCEL_REG(R300_TX_FORMAT0_1, txformat0);
OUT_ACCEL_REG(R300_TX_FORMAT1_1, txformat1);
OUT_ACCEL_REG(R300_TX_FORMAT2_1, txpitch);
- OUT_ACCEL_REG(R300_TX_OFFSET_1, pPriv->bicubic_src_offset);
+ OUT_TEXTURE_REG(R300_TX_OFFSET_1, bicubic_offset, pPriv->bicubic_bo);
FINISH_ACCEL();
/* Enable tex 1 */
@@ -2205,11 +2252,11 @@ FUNC_NAME(R300DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
FINISH_ACCEL();
}
- BEGIN_ACCEL(6);
+ BEGIN_ACCEL_RELOC(6, 1);
OUT_ACCEL_REG(R300_TX_INVALTAGS, 0);
OUT_ACCEL_REG(R300_TX_ENABLE, txenable);
- OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset);
+ EMIT_WRITE_OFFSET(R300_RB3D_COLOROFFSET0, 0, pPixmap);
OUT_ACCEL_REG(R300_RB3D_COLORPITCH0, colorpitch);
/* no need to enable blending */
@@ -2407,8 +2454,9 @@ FUNC_NAME(R500DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
PixmapPtr pPixmap = pPriv->pPixmap;
+ struct radeon_exa_pixmap_priv *driver_priv;
uint32_t txfilter, txformat0, txformat1, txoffset, txpitch;
- uint32_t dst_offset, dst_pitch, dst_format;
+ uint32_t dst_pitch, dst_format;
uint32_t txenable, colorpitch;
uint32_t output_fmt;
Bool isplanar = FALSE;
@@ -2421,15 +2469,12 @@ FUNC_NAME(R500DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
#ifdef USE_EXA
if (info->useEXA) {
- dst_offset = exaGetPixmapOffset(pPixmap) + info->fbLocation + pScrn->fbOffset;
dst_pitch = exaGetPixmapPitch(pPixmap);
} else
#endif
- {
- dst_offset = (pPixmap->devPrivate.ptr - info->FB) +
- info->fbLocation + pScrn->fbOffset;
- dst_pitch = pPixmap->devKind;
- }
+ {
+ dst_pitch = pPixmap->devKind;
+ }
#ifdef COMPOSITE
dstxoff = -pPixmap->screen_x + pPixmap->drawable.x;
@@ -2528,15 +2573,15 @@ FUNC_NAME(R500DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
if ((pPriv->h - 1) & 0x800)
txpitch |= R500_TXHEIGHT_11;
- txoffset = pPriv->src_offset;
+ txoffset = info->cs ? 0 : pPriv->src_offset;
- BEGIN_ACCEL(6);
+ BEGIN_ACCEL_RELOC(6, 1);
OUT_ACCEL_REG(R300_TX_FILTER0_0, txfilter);
OUT_ACCEL_REG(R300_TX_FILTER1_0, 0);
OUT_ACCEL_REG(R300_TX_FORMAT0_0, txformat0);
OUT_ACCEL_REG(R300_TX_FORMAT1_0, txformat1);
OUT_ACCEL_REG(R300_TX_FORMAT2_0, txpitch);
- OUT_ACCEL_REG(R300_TX_OFFSET_0, txoffset);
+ OUT_TEXTURE_REG(R300_TX_OFFSET_0, txoffset, pPriv->src_bo);
FINISH_ACCEL();
txenable = R300_TEX_0_ENABLE;
@@ -3758,11 +3803,11 @@ FUNC_NAME(R500DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
FINISH_ACCEL();
}
- BEGIN_ACCEL(6);
+ BEGIN_ACCEL_RELOC(6, 1);
OUT_ACCEL_REG(R300_TX_INVALTAGS, 0);
OUT_ACCEL_REG(R300_TX_ENABLE, txenable);
- OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset);
+ EMIT_WRITE_OFFSET(R300_RB3D_COLOROFFSET0, 0, pPixmap);
OUT_ACCEL_REG(R300_RB3D_COLORPITCH0, colorpitch);
/* 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 {
int drw_x, drw_y;
int src_x, src_y;
int vsync;
+
+ struct radeon_bo *src_bo;
+ struct radeon_bo *bicubic_bo;
} RADEONPortPrivRec, *RADEONPortPrivPtr;
/* Reference color space transform data */