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