Advertisement
Guest User

r128_exa.c

a guest
May 6th, 2012
208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 44.87 KB | None | 0 0
  1. /*
  2.  * Copyright 2003 Eric Anholt
  3.  * Copyright 2003 Anders Carlsson
  4.  * Copyright 2006 Joseph Garvin
  5.  * Copyright 2012 Connor Behan
  6.  * All Rights Reserved.
  7.  *
  8.  * Permission is hereby granted, free of charge, to any person obtaining a
  9.  * copy of this software and associated documentation files (the "Software"),
  10.  * to deal in the Software without restriction, including without limitation
  11.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  12.  * and/or sell copies of the Software, and to permit persons to whom the
  13.  * Software is furnished to do so, subject to the following conditions:
  14.  *
  15.  * The above copyright notice and this permission notice (including the next
  16.  * paragraph) shall be included in all copies or substantial portions of the
  17.  * Software.
  18.  *
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  25.  * SOFTWARE.
  26.  *
  27.  * Authors:
  28.  *    Eric Anholt <anholt@FreeBSD.org>
  29.  *    Anders Carlsson <andersca@gnome.org>
  30.  *    Joseph Garvin <joseph.h.garvin@gmail.com>
  31.  *    Connor Behan <connor.behan@gmail.com>
  32.  *
  33.  */
  34.  
  35. #ifdef HAVE_CONFIG_H
  36. #include "config.h"
  37. #endif
  38.  
  39. #include "r128.h"
  40. #include "exa.h"
  41.  
  42. #include "r128_reg.h"
  43.  
  44. #include "xf86.h"
  45.  
  46. static struct {
  47.     int rop;
  48.     int pattern;
  49. } R128_ROP[] = {
  50.     { R128_ROP3_ZERO, R128_ROP3_ZERO }, /* GXclear        */
  51.     { R128_ROP3_DSa,  R128_ROP3_DPa  }, /* Gxand          */
  52.     { R128_ROP3_SDna, R128_ROP3_PDna }, /* GXandReverse   */
  53.     { R128_ROP3_S,    R128_ROP3_P    }, /* GXcopy         */
  54.     { R128_ROP3_DSna, R128_ROP3_DPna }, /* GXandInverted  */
  55.     { R128_ROP3_D,    R128_ROP3_D    }, /* GXnoop         */
  56.     { R128_ROP3_DSx,  R128_ROP3_DPx  }, /* GXxor          */
  57.     { R128_ROP3_DSo,  R128_ROP3_DPo  }, /* GXor           */
  58.     { R128_ROP3_DSon, R128_ROP3_DPon }, /* GXnor          */
  59.     { R128_ROP3_DSxn, R128_ROP3_PDxn }, /* GXequiv        */
  60.     { R128_ROP3_Dn,   R128_ROP3_Dn   }, /* GXinvert       */
  61.     { R128_ROP3_SDno, R128_ROP3_PDno }, /* GXorReverse    */
  62.     { R128_ROP3_Sn,   R128_ROP3_Pn   }, /* GXcopyInverted */
  63.     { R128_ROP3_DSno, R128_ROP3_DPno }, /* GXorInverted   */
  64.     { R128_ROP3_DSan, R128_ROP3_DPan }, /* GXnand         */
  65.     { R128_ROP3_ONE,  R128_ROP3_ONE  }  /* GXset          */
  66. };
  67.  
  68. #ifdef RENDER
  69. static struct {
  70.     Bool dst_alpha;
  71.     Bool src_alpha;
  72.     CARD32 blendctl;
  73. } R128BlendOp[] = {
  74.     /* Clear */
  75.     {0, 0, R128_SBLEND_ZERO          | R128_DBLEND_ZERO},
  76.     /* Src */
  77.     {0, 0, R128_SBLEND_ONE           | R128_DBLEND_ZERO},
  78.     /* Dst */
  79.     {0, 0, R128_SBLEND_ZERO          | R128_DBLEND_ONE},
  80.     /* Over */
  81.     {0, 1, R128_SBLEND_ONE           | R128_DBLEND_INV_SRC_ALPHA},
  82.     /* OverReverse */
  83.     {1, 0, R128_SBLEND_INV_DST_ALPHA | R128_DBLEND_ONE},
  84.     /* In */
  85.     {1, 0, R128_SBLEND_DST_ALPHA     | R128_DBLEND_ZERO},
  86.     /* InReverse */
  87.     {0, 1, R128_SBLEND_ZERO          | R128_DBLEND_SRC_ALPHA},
  88.     /* Out */
  89.     {1, 0, R128_SBLEND_INV_DST_ALPHA | R128_DBLEND_ZERO},
  90.     /* OutReverse */
  91.     {0, 1, R128_SBLEND_ZERO          | R128_DBLEND_INV_SRC_ALPHA},
  92.     /* Atop */
  93.     {1, 1, R128_SBLEND_DST_ALPHA     | R128_DBLEND_INV_SRC_ALPHA},
  94.     /* AtopReverse */
  95.     {1, 1, R128_SBLEND_INV_DST_ALPHA | R128_DBLEND_SRC_ALPHA},
  96.     /* Xor */
  97.     {1, 1, R128_SBLEND_INV_DST_ALPHA | R128_DBLEND_INV_SRC_ALPHA},
  98.     /* Add */
  99.     {0, 0, R128_SBLEND_ONE           | R128_DBLEND_ONE},
  100. };
  101.  
  102. static int widths[2] = {1,1};
  103. static int heights[2] = {1,1};
  104. static Bool is_transform[2];
  105. static PictTransform *transform[2];
  106.  
  107. typedef union { float f; CARD32 i; } fi_type;
  108.  
  109. /* If it was okay to not be paranoid about a simple cast, I guess they wouldn't have made this. */
  110. static inline CARD32
  111. R128FloatAsInt(float val)
  112. {
  113.     fi_type fi;
  114.  
  115.     fi.f = val;
  116.     return fi.i;
  117. }
  118.  
  119. #define VTX_RING_COUNT 8
  120.  
  121. #define VTX_OUT(_dstX, _dstY, _srcX, _srcY, _maskX, _maskY)     \
  122. do {                                        \
  123.     OUTREG(0, R128FloatAsInt(_dstX));                   \
  124.     OUTREG(0, R128FloatAsInt(((float)(_dstY)) + 0.125));        \
  125.     OUTREG(0, R128FloatAsInt(0.0));                 \
  126.     OUTREG(0, R128FloatAsInt(1.0));                 \
  127.     OUTREG(0, R128FloatAsInt((((float)(_srcX)) + 0.5) / (widths[0])));  \
  128.     OUTREG(0, R128FloatAsInt((((float)(_srcY)) + 0.5) / (heights[0]))); \
  129.     OUTREG(0, R128FloatAsInt((((float)(_maskX)) + 0.5) / (widths[1]))); \
  130.     OUTREG(0, R128FloatAsInt((((float)(_maskY)) + 0.5) / (heights[1])));\
  131. } while (0)
  132.  
  133. #define VTX_CCE_OUT(_dstX, _dstY, _srcX, _srcY, _maskX, _maskY)     \
  134. do {                                        \
  135.     OUT_RING(R128FloatAsInt(_dstX));                    \
  136.     OUT_RING(R128FloatAsInt(((float)(_dstY)) + 0.125));         \
  137.     OUT_RING(R128FloatAsInt(0.0));                  \
  138.     OUT_RING(R128FloatAsInt(1.0));                  \
  139.     OUT_RING(R128FloatAsInt((((float)(_srcX)) + 0.5) / (widths[0])));   \
  140.     OUT_RING(R128FloatAsInt((((float)(_srcY)) + 0.5) / (heights[0])));  \
  141.     OUT_RING(R128FloatAsInt((((float)(_maskX)) + 0.5) / (widths[1])));  \
  142.     OUT_RING(R128FloatAsInt((((float)(_maskY)) + 0.5) / (heights[1]))); \
  143. } while (0)
  144.  
  145. static Bool
  146. R128TransformAffineOrScaled(PictTransformPtr t)
  147. {
  148.     if (t == NULL) return TRUE;
  149.    
  150.     /* the shaders don't handle scaling either */
  151.     return t->matrix[2][0] == 0 && t->matrix[2][1] == 0 && t->matrix[2][2] == IntToxFixed(1);
  152. }
  153.  
  154. static PixmapPtr
  155. R128GetDrawablePixmap(DrawablePtr pDrawable)
  156. {
  157.     if (pDrawable->type == DRAWABLE_WINDOW)
  158.     return pDrawable->pScreen->GetWindowPixmap((WindowPtr)pDrawable);
  159.     else
  160.     return (PixmapPtr)pDrawable;
  161. }
  162.  
  163. static PixmapPtr
  164. R128SolidPixmap(ScreenPtr pScreen, uint32_t solid)
  165. {
  166.     ScrnInfoPtr   pScrn     = xf86Screens[pScreen->myNum];
  167.     R128InfoPtr   info      = R128PTR(pScrn);
  168.     PixmapPtr pPix = pScreen->CreatePixmap(pScreen, 1, 1, 32, 0);
  169.    
  170.     exaMoveInPixmap(pPix);
  171.     if (!exaDrawableIsOffscreen(&pPix->drawable)) {
  172.         pScreen->DestroyPixmap(pPix);
  173.     return NULL;
  174.     }
  175.     memcpy(info->ExaDriver->memoryBase + exaGetPixmapOffset(pPix), &solid, 4);
  176.    
  177.     return pPix;
  178. }
  179.  
  180. /* XXX: Extra rejection criteria to make tests pass -- possibly card specific! */
  181. static Bool
  182. R128Quirks(PicturePtr pMaskPicture, PicturePtr pSrcPicture, int op)
  183. {
  184.     if (pMaskPicture->format == PICT_r5g6b5 && pSrcPicture->format == PICT_r5g6b5) {
  185.         switch (op) {
  186.     case PictOpClear:
  187.     case PictOpSrc:
  188.     case PictOpIn:
  189.     case PictOpOut:
  190.     case PictOpOutReverse:
  191.     case PictOpOver:
  192.     case PictOpAtop:
  193.     case PictOpAdd:
  194.     case PictOpXor:
  195.         return FALSE;
  196.     default:
  197.         return TRUE;
  198.         }
  199.     }
  200.    
  201.     return TRUE;
  202. }
  203.  
  204. /* Sometimes one list is supported, sometimes the other list is */
  205. static Bool
  206. R128GetDatatypePict1(uint32_t format, uint32_t *type)
  207. {
  208.     switch(format) {
  209.     case PICT_r5g6b5:
  210.     *type = R128_DATATYPE_RGB565;
  211.     return TRUE;
  212.     case PICT_a1r5g5b5:
  213.     case PICT_x1r5g5b5:
  214.     *type = R128_DATATYPE_ARGB1555;
  215.     return TRUE;
  216.     case PICT_x8r8g8b8:
  217.     *type = R128_DATATYPE_ARGB8888;
  218.     return TRUE;
  219.     default:
  220.         return FALSE;
  221.     }
  222. }
  223.  
  224. static Bool
  225. R128GetDatatypePict2(uint32_t format, uint32_t *type)
  226. {
  227.     switch(format) {
  228.     case PICT_r5g6b5:
  229.     *type = R128_DATATYPE_RGB565;
  230.     return TRUE;
  231.     case PICT_a1r5g5b5:
  232.     *type = R128_DATATYPE_ARGB1555;
  233.     return TRUE;
  234.     case PICT_a4r4g4b4:
  235.     *type = R128_DATATYPE_ARGB4444;
  236.     return TRUE;
  237.     default:
  238.         return FALSE;
  239.     }
  240. }
  241. #endif
  242.  
  243. /* Assumes that depth 15 and 16 can be used as depth 16, which is okay since we
  244.  * require src and dest datatypes to be equal.
  245.  */
  246. Bool R128GetDatatypeBpp(int bpp, uint32_t *type)
  247. {
  248.     switch (bpp) {
  249.     case 8:
  250.         *type = R128_DATATYPE_CI8;
  251.         return TRUE;
  252.     case 16:
  253.         *type = R128_DATATYPE_RGB565;
  254.         return TRUE;
  255.     case 24:
  256.         *type = R128_DATATYPE_CI8;
  257.         return TRUE;
  258.     case 32:
  259.         *type = R128_DATATYPE_ARGB8888;
  260.         return TRUE;
  261.     default:
  262.         return FALSE;
  263.     }
  264. }
  265.  
  266. static Bool R128GetOffsetPitch(PixmapPtr pPix, int bpp, uint32_t *pitch_offset,
  267.                  unsigned int offset, unsigned int pitch)
  268. {
  269.     ScreenPtr     pScreen   = pPix->drawable.pScreen;
  270.     ScrnInfoPtr   pScrn     = xf86Screens[pScreen->myNum];
  271.     R128InfoPtr   info      = R128PTR(pScrn);
  272.  
  273.     if (pitch > 16320 || pitch % info->ExaDriver->pixmapPitchAlign != 0) {
  274.         R128TRACE(("Bad pitch 0x%08x\n", pitch));
  275.     return FALSE;
  276.     }
  277.  
  278.     if (offset % info->ExaDriver->pixmapOffsetAlign != 0) {
  279.         R128TRACE(("Bad offset 0x%08x\n", offset));
  280.     return FALSE;
  281.     }
  282.  
  283.     *pitch_offset = ((pitch / bpp) << 21) | (offset >> 5);
  284.  
  285.     return TRUE;
  286. }
  287.  
  288. Bool R128GetPixmapOffsetPitch(PixmapPtr pPix, uint32_t *pitch_offset)
  289. {
  290.     uint32_t pitch, offset;
  291.     int bpp;
  292.  
  293.     bpp = pPix->drawable.bitsPerPixel;
  294.     if (bpp == 24)
  295.         bpp = 8;
  296.  
  297.     offset = exaGetPixmapOffset(pPix);
  298.     pitch = exaGetPixmapPitch(pPix);
  299.  
  300.     return R128GetOffsetPitch(pPix, bpp, pitch_offset, offset, pitch);
  301. }
  302.  
  303. static void Emit2DState(ScrnInfoPtr pScrn)
  304. {
  305.     R128InfoPtr   info      = R128PTR(pScrn);
  306.     int has_src         = info->state_2d.src_pitch_offset;
  307.     unsigned char *R128MMIO = info->MMIO;
  308.    
  309.     R128WaitForFifo(pScrn, (has_src ? 10 : 9));
  310.    
  311.     OUTREG(R128_DEFAULT_SC_BOTTOM_RIGHT, info->state_2d.default_sc_bottom_right);
  312.     OUTREG(R128_DP_GUI_MASTER_CNTL, info->state_2d.dp_gui_master_cntl);
  313.     OUTREG(R128_DP_BRUSH_FRGD_CLR, info->state_2d.dp_brush_frgd_clr);
  314.     OUTREG(R128_DP_BRUSH_BKGD_CLR, info->state_2d.dp_brush_bkgd_clr);
  315.     OUTREG(R128_DP_SRC_FRGD_CLR,   info->state_2d.dp_src_frgd_clr);
  316.     OUTREG(R128_DP_SRC_BKGD_CLR,   info->state_2d.dp_src_bkgd_clr);
  317.     OUTREG(R128_DP_WRITE_MASK, info->state_2d.dp_write_mask);
  318.     OUTREG(R128_DP_CNTL, info->state_2d.dp_cntl);
  319.  
  320.     OUTREG(R128_DST_PITCH_OFFSET, info->state_2d.dst_pitch_offset);
  321.     if (has_src) OUTREG(R128_SRC_PITCH_OFFSET, info->state_2d.src_pitch_offset);
  322. }
  323.  
  324. static void EmitCCE2DState(ScrnInfoPtr pScrn)
  325. {
  326.     R128InfoPtr   info      = R128PTR(pScrn);
  327.     int has_src         = info->state_2d.src_pitch_offset;
  328.     RING_LOCALS;
  329.    
  330.     R128CCE_REFRESH( pScrn, info );
  331.    
  332.     BEGIN_RING( (has_src ? 20 : 18) );
  333.    
  334.     OUT_RING_REG( R128_DEFAULT_SC_BOTTOM_RIGHT, info->state_2d.default_sc_bottom_right );
  335.     OUT_RING_REG( R128_DP_GUI_MASTER_CNTL, info->state_2d.dp_gui_master_cntl );
  336.     OUT_RING_REG( R128_DP_BRUSH_FRGD_CLR, info->state_2d.dp_brush_frgd_clr );
  337.     OUT_RING_REG( R128_DP_BRUSH_BKGD_CLR, info->state_2d.dp_brush_bkgd_clr );
  338.     OUT_RING_REG( R128_DP_SRC_FRGD_CLR,   info->state_2d.dp_src_frgd_clr );
  339.     OUT_RING_REG( R128_DP_SRC_BKGD_CLR,   info->state_2d.dp_src_bkgd_clr );
  340.     OUT_RING_REG( R128_DP_WRITE_MASK, info->state_2d.dp_write_mask );
  341.     OUT_RING_REG( R128_DP_CNTL, info->state_2d.dp_cntl );
  342.  
  343.     OUT_RING_REG( R128_DST_PITCH_OFFSET, info->state_2d.dst_pitch_offset );
  344.     if (has_src) OUT_RING_REG( R128_SRC_PITCH_OFFSET, info->state_2d.src_pitch_offset );
  345.    
  346.     ADVANCE_RING();
  347. }
  348.  
  349. /* EXA Callbacks */
  350.  
  351. static Bool
  352. R128PrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
  353. {
  354.     ScreenPtr     pScreen   = pPixmap->drawable.pScreen;
  355.     ScrnInfoPtr   pScrn     = xf86Screens[pScreen->myNum];
  356.     R128InfoPtr   info      = R128PTR(pScrn);
  357.    
  358.     int bpp = pPixmap->drawable.bitsPerPixel;
  359.     uint32_t datatype, dst_pitch_offset;
  360.    
  361.     if (!R128GetDatatypeBpp(bpp, &datatype)) {
  362.         R128TRACE(("R128GetDatatypeBpp failed\n"));
  363.     return FALSE;
  364.     }
  365.     if (!R128GetPixmapOffsetPitch(pPixmap, &dst_pitch_offset)) {
  366.         R128TRACE(("R128GetPixmapOffsetPitch failed\n"));
  367.     return FALSE;
  368.     }  
  369.     if (info->state_2d.in_use) return FALSE;
  370.    
  371.     info->state_2d.in_use = TRUE;
  372.     info->state_2d.default_sc_bottom_right = (R128_DEFAULT_SC_RIGHT_MAX | R128_DEFAULT_SC_BOTTOM_MAX);
  373.     info->state_2d.dp_brush_bkgd_clr = 0x00000000;
  374.     info->state_2d.dp_src_frgd_clr = 0xffffffff;
  375.     info->state_2d.dp_src_bkgd_clr = 0x00000000;
  376.     info->state_2d.dp_gui_master_cntl = (R128_GMC_DST_PITCH_OFFSET_CNTL |
  377.                       R128_GMC_BRUSH_SOLID_COLOR |
  378.                       (datatype >> 8) |
  379.                       R128_GMC_SRC_DATATYPE_COLOR |
  380.                       R128_ROP[alu].pattern |
  381.                       R128_GMC_CLR_CMP_CNTL_DIS);
  382.     info->state_2d.dp_brush_frgd_clr = fg;
  383.     info->state_2d.dp_cntl = (R128_DST_X_LEFT_TO_RIGHT | R128_DST_Y_TOP_TO_BOTTOM);
  384.     info->state_2d.dp_write_mask = planemask;
  385.     info->state_2d.dst_pitch_offset = dst_pitch_offset;
  386.     info->state_2d.src_pitch_offset = 0;
  387.    
  388. #ifdef R128DRI
  389.     if (info->directRenderingEnabled) {
  390.         EmitCCE2DState(pScrn);
  391.     } else
  392. #endif
  393.     {
  394.         Emit2DState(pScrn);
  395.     }
  396.     return TRUE;
  397. }
  398.  
  399. static void
  400. R128Solid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
  401. {
  402.     ScreenPtr     pScreen   = pPixmap->drawable.pScreen;
  403.     ScrnInfoPtr   pScrn     = xf86Screens[pScreen->myNum];
  404.     R128InfoPtr   info      = R128PTR(pScrn);
  405.     unsigned char *R128MMIO = info->MMIO;
  406.  
  407.     R128WaitForFifo(pScrn, 2);
  408.     OUTREG(R128_DST_Y_X,          (y1 << 16) | x1);
  409.     OUTREG(R128_DST_WIDTH_HEIGHT, ((x2-x1) << 16) | (y2-y1));
  410. }
  411.  
  412. #define R128DoneSolid R128Done
  413.  
  414. void
  415. R128DoPrepareCopy(ScrnInfoPtr pScrn, uint32_t src_pitch_offset,
  416.             uint32_t dst_pitch_offset, uint32_t datatype, int alu, Pixel planemask)
  417. {
  418.     R128InfoPtr   info      = R128PTR(pScrn);
  419.    
  420.     info->state_2d.in_use = TRUE;
  421.     info->state_2d.dp_gui_master_cntl = (R128_GMC_DST_PITCH_OFFSET_CNTL |
  422.                       R128_GMC_SRC_PITCH_OFFSET_CNTL |
  423.                       R128_GMC_BRUSH_NONE |
  424.                       (datatype >> 8) |
  425.                       R128_GMC_SRC_DATATYPE_COLOR |
  426.                       R128_ROP[alu].rop |
  427.                       R128_DP_SRC_SOURCE_MEMORY |
  428.                       R128_GMC_CLR_CMP_CNTL_DIS);
  429.     info->state_2d.dp_cntl = ((info->xdir >= 0 ? R128_DST_X_LEFT_TO_RIGHT : 0) |
  430.                    (info->ydir >= 0 ? R128_DST_Y_TOP_TO_BOTTOM : 0));
  431.     info->state_2d.dp_brush_frgd_clr = 0xffffffff;
  432.     info->state_2d.dp_brush_bkgd_clr = 0x00000000;
  433.     info->state_2d.dp_src_frgd_clr = 0xffffffff;
  434.     info->state_2d.dp_src_bkgd_clr = 0x00000000;
  435.     info->state_2d.dp_write_mask = planemask;
  436.     info->state_2d.dst_pitch_offset = dst_pitch_offset;
  437.     info->state_2d.src_pitch_offset = src_pitch_offset;
  438.     info->state_2d.default_sc_bottom_right = (R128_DEFAULT_SC_RIGHT_MAX | R128_DEFAULT_SC_BOTTOM_MAX);
  439.    
  440. #ifdef R128DRI
  441.     if (info->directRenderingEnabled) {
  442.         EmitCCE2DState(pScrn);
  443.     } else
  444. #endif
  445.     {
  446.         Emit2DState(pScrn);
  447.     }
  448. }
  449.  
  450. static Bool
  451. R128PrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir, int alu, Pixel planemask)
  452. {
  453.     ScreenPtr     pScreen   = pSrcPixmap->drawable.pScreen;
  454.     ScrnInfoPtr   pScrn     = xf86Screens[pScreen->myNum];
  455.     R128InfoPtr   info      = R128PTR(pScrn);
  456.    
  457.     int bpp = pDstPixmap->drawable.bitsPerPixel;
  458.     uint32_t datatype, src_pitch_offset, dst_pitch_offset;
  459.    
  460.     if (!R128GetDatatypeBpp(bpp, &datatype)) {
  461.         R128TRACE(("R128GetDatatypeBpp failed\n"));
  462.     return FALSE;
  463.     }
  464.     if (!R128GetPixmapOffsetPitch(pSrcPixmap, &src_pitch_offset)) {
  465.         R128TRACE(("R128GetPixmapOffsetPitch source failed\n"));
  466.     return FALSE;
  467.     }  
  468.     if (!R128GetPixmapOffsetPitch(pDstPixmap, &dst_pitch_offset)) {
  469.         R128TRACE(("R128GetPixmapOffsetPitch dest failed\n"));
  470.     return FALSE;
  471.     }  
  472.     if (info->state_2d.in_use) return FALSE;
  473.  
  474.     info->xdir = xdir;
  475.     info->ydir = ydir;
  476.    
  477.     R128DoPrepareCopy(pScrn, src_pitch_offset, dst_pitch_offset, datatype, alu, planemask);
  478.    
  479.     return TRUE;
  480. }
  481.  
  482. static void
  483. R128Copy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height)
  484. {
  485.     ScreenPtr     pScreen   = pDstPixmap->drawable.pScreen;
  486.     ScrnInfoPtr   pScrn     = xf86Screens[pScreen->myNum];
  487.     R128InfoPtr   info      = R128PTR(pScrn);
  488.     unsigned char *R128MMIO = info->MMIO;
  489.  
  490.     if (info->xdir < 0) srcX += width - 1, dstX += width - 1;
  491.     if (info->ydir < 0) srcY += height - 1, dstY += height - 1;
  492.  
  493.     R128WaitForFifo(pScrn, 3);
  494.     OUTREG(R128_SRC_Y_X,          (srcY << 16) | srcX);
  495.     OUTREG(R128_DST_Y_X,          (dstY << 16) | dstX);
  496.     OUTREG(R128_DST_HEIGHT_WIDTH, (height << 16) | width);
  497. }
  498.  
  499. #define R128DoneCopy R128Done
  500.  
  501. #ifdef RENDER
  502. static Bool
  503. R128CheckCompositeTexture(PicturePtr pPict, PicturePtr pDstPict, int op, Bool trying_solid)
  504. {
  505.     ScreenPtr     pScreen   = pDstPict->pDrawable->pScreen;
  506.     ScrnInfoPtr   pScrn     = xf86Screens[pScreen->myNum];
  507.     R128InfoPtr   info      = R128PTR(pScrn);
  508.    
  509.     int w, h;
  510.     unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone;
  511.     uint32_t tmp1;
  512.    
  513.     if (!trying_solid || !(pPict->format == PICT_a8 || pPict->format == PICT_a8r8g8b8)) {
  514.         if (!R128GetDatatypePict2(pPict->format, &tmp1)) return FALSE;
  515.     }
  516.    
  517.     if (pPict->pDrawable) {
  518.         w = pPict->pDrawable->width;
  519.         h = pPict->pDrawable->height;
  520.    
  521.         if (pPict->repeat && ((w & (w - 1)) != 0 || (h & (h - 1)) != 0)) {
  522.             R128TRACE(("NPOT repeat unsupported (%dx%d)\n", w, h));
  523.         return FALSE;
  524.         }
  525.     }
  526.    
  527.     if (pPict->filter != PictFilterNearest && pPict->filter != PictFilterBilinear) {
  528.     R128TRACE(("Unsupported filter 0x%x\n", pPict->filter));
  529.     return FALSE;
  530.     }
  531.    
  532.     /* The radeon driver has a long explanation about this part that I don't really understand */
  533.     if (pPict->transform != 0 && repeatType == RepeatNone && PICT_FORMAT_A(pPict->format) == 0) {
  534.     if (!(((op == PictOpSrc) || (op == PictOpClear)) && (PICT_FORMAT_A(pDstPict->format) == 0))) {
  535.         R128TRACE(("REPEAT_NONE unsupported for transformed xRGB source\n"));
  536.         return FALSE;
  537.     }
  538.     }
  539.     if (!R128TransformAffineOrScaled(pPict->transform)) {
  540.     R128TRACE(("Non-affine transforms not supported\n"));
  541.     return FALSE;
  542.     }
  543.    
  544.     return TRUE;
  545. }
  546.  
  547. static Bool
  548. R128CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture)
  549. {
  550.     ScreenPtr     pScreen   = pDstPicture->pDrawable->pScreen;
  551.     ScrnInfoPtr   pScrn     = xf86Screens[pScreen->myNum];
  552.     R128InfoPtr   info      = R128PTR(pScrn);
  553.    
  554.     PixmapPtr pSrcPixmap, pDstPixmap;
  555.     uint32_t tmp1;
  556.     Bool trying_solid = FALSE;
  557.  
  558.     /* Check for unsupported compositing operations. */
  559.     if (op >= sizeof(R128BlendOp) / sizeof(R128BlendOp[0])) {
  560.     R128TRACE(("Unsupported Composite op 0x%x\n", op));
  561.     return FALSE;
  562.     }
  563.    
  564.     /* The radeon driver says that a bug requires 2047 instead of 2048 and r128 uses 1024 so... */
  565.     pDstPixmap = R128GetDrawablePixmap(pDstPicture->pDrawable);
  566.     if (pDstPixmap->drawable.width > 1023 || pDstPixmap->drawable.height > 1023) {
  567.     R128TRACE(("Dest w/h too large (%d,%d).\n", pDstPixmap->drawable.width, pDstPixmap->drawable.height));
  568.     return FALSE;
  569.     }
  570.    
  571.     if (pSrcPicture->pDrawable) {
  572.         pSrcPixmap = R128GetDrawablePixmap(pSrcPicture->pDrawable);
  573.         if (pSrcPixmap->drawable.width > 1023 || pSrcPixmap->drawable.height > 1023) {
  574.         R128TRACE(("Source w/h too large (%d,%d).\n", pSrcPixmap->drawable.width, pSrcPixmap->drawable.height));
  575.         return FALSE;
  576.         }
  577.     } else if (pSrcPicture->pSourcePict->type != SourcePictTypeSolidFill) {
  578.         R128TRACE(("Gradient pictures not supported yet\n"));
  579.     return FALSE;
  580.     } else {
  581.     R128TRACE(("One of those\n"));
  582.     trying_solid = TRUE;
  583.     }
  584.    
  585.     if (pDstPicture->format == PICT_a8) {
  586.         if (R128BlendOp[op].src_alpha || R128BlendOp[op].dst_alpha || pMaskPicture != NULL) {
  587.         R128TRACE(("Alpha blending unsupported with A8 dst?\n"));
  588.         return FALSE;
  589.     }
  590.     } else {
  591.         if (!R128GetDatatypePict1(pDstPicture->format, &tmp1)) return FALSE;
  592.     }
  593.    
  594.     if (pMaskPicture) {
  595.         PixmapPtr pMaskPixmap;
  596.    
  597.     if (pMaskPicture->pDrawable) {
  598.         pMaskPixmap = R128GetDrawablePixmap(pMaskPicture->pDrawable);
  599.             if (pMaskPixmap->drawable.width > 1023 || pMaskPixmap->drawable.height > 1023) {
  600.             R128TRACE(("Mask w/h too large (%d,%d).\n", pMaskPixmap->drawable.width, pMaskPixmap->drawable.height));
  601.             return FALSE;
  602.             }
  603.     } else if (pMaskPicture->pSourcePict->type != SourcePictTypeSolidFill) {
  604.         R128TRACE(("Gradient pictures not supported yet\n"));
  605.         return FALSE;
  606.     }
  607.    
  608.     if (pMaskPicture->componentAlpha && R128BlendOp[op].src_alpha) {
  609.         R128TRACE(("Component alpha not supported with source alpha blending\n"));
  610.         return FALSE;
  611.     }
  612.    
  613.     if (!R128Quirks(pMaskPicture, pSrcPicture, op)) return FALSE;
  614.     if (!R128CheckCompositeTexture(pMaskPicture, pDstPicture, op, trying_solid)) return FALSE;
  615.     }
  616.    
  617.     if (!R128CheckCompositeTexture(pSrcPicture, pDstPicture, op, trying_solid)) return FALSE;
  618.    
  619.     return TRUE;
  620. }
  621.  
  622. static Bool
  623. R128TextureSetup(PicturePtr pPict, PixmapPtr pPix, int unit, uint32_t *txsize, uint32_t *tex_cntl_c, Bool trying_solid)
  624. {
  625.     ScreenPtr     pScreen   = pPix->drawable.pScreen;
  626.     ScrnInfoPtr   pScrn     = xf86Screens[pScreen->myNum];
  627.     R128InfoPtr   info      = R128PTR(pScrn);
  628.    
  629.     int w, h;
  630.     int bytepp, shift, l2w, l2h, l2p, pitch;
  631.    
  632.     if (pPict->pDrawable) {
  633.     w = pPict->pDrawable->width;
  634.     h = pPict->pDrawable->height;
  635.     } else {
  636.     w = h = 1;
  637.     }
  638.    
  639.     pitch = exaGetPixmapPitch(pPix);
  640.     if ((pitch & (pitch - 1)) != 0) {
  641.         R128TRACE(("NPOT pitch 0x%x unsupported\n", pitch));
  642.     return FALSE;
  643.     }
  644.    
  645.     if (trying_solid && pPict->format == PICT_a8r8g8b8) {
  646.         *tex_cntl_c = R128_DATATYPE_RGB8;
  647.     } else if (trying_solid && pPict->format == PICT_a8) {
  648.         *tex_cntl_c = R128_DATATYPE_Y8;
  649.     } else {
  650.         if (!R128GetDatatypePict2(pPict->format, tex_cntl_c)) return FALSE;
  651.     }
  652.    
  653.     bytepp = PICT_FORMAT_BPP(pPict->format) / 8;
  654.  
  655.     *tex_cntl_c |= R128_MIP_MAP_DISABLE;
  656.  
  657.     if (pPict->filter == PictFilterBilinear) {
  658.         *tex_cntl_c |= R128_MIN_BLEND_LINEAR | R128_MAG_BLEND_LINEAR;
  659.     } else if (pPict->filter == PictFilterNearest) {
  660.     *tex_cntl_c |= R128_MIN_BLEND_NEAREST | R128_MAG_BLEND_NEAREST;
  661.     } else {
  662.     R128TRACE(("Bad filter 0x%x\n", pPict->filter));
  663.     return FALSE;
  664.     }
  665.  
  666.     if (unit == 0)
  667.         shift = 0;
  668.     else {
  669.         shift = 16;
  670.         *tex_cntl_c |= R128_SEC_SELECT_SEC_ST;
  671.     }
  672.  
  673.     /* R128MinBits returns -1 for value of 0 */
  674.     l2w = R128MinBits(w - 1) + 1;
  675.     l2h = R128MinBits(h - 1) + 1;
  676.     l2p = R128MinBits(pitch / bytepp);
  677.  
  678.     if (pPict->repeat && w == 1 && h == 1)
  679.         l2p = 0;
  680.     else if (pPict->repeat && l2p != l2w) {
  681.         R128TRACE(("Repeat not supported for pitch != width\n"));
  682.     return FALSE;
  683.     }
  684.     l2w = l2p;
  685.  
  686.     widths[unit] = 1 << l2w;
  687.     heights[unit] = 1 << l2h;
  688.     *txsize |= l2p << (R128_TEX_PITCH_SHIFT + shift);
  689.     *txsize |= ((l2w > l2h) ? l2w : l2h) << (R128_TEX_SIZE_SHIFT + shift);
  690.     *txsize |= l2h << (R128_TEX_HEIGHT_SHIFT + shift);
  691.  
  692.     if (pPict->transform != 0) {
  693.         is_transform[unit] = TRUE;
  694.         transform[unit] = pPict->transform;
  695.     } else {
  696.         is_transform[unit] = FALSE;
  697.     }
  698.  
  699.     return TRUE;
  700. }
  701.  
  702. static Bool
  703. R128PrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
  704.     PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
  705. {
  706.     ScreenPtr     pScreen   = pDst->drawable.pScreen;
  707.     ScrnInfoPtr   pScrn     = xf86Screens[pScreen->myNum];
  708.     R128InfoPtr   info      = R128PTR(pScrn);
  709.     unsigned char *R128MMIO = info->MMIO;
  710.    
  711.     Bool add_src = FALSE;
  712.     Bool add_msk = FALSE;
  713.     uint32_t txsize = 0, prim_tex_cntl_c, sec_tex_cntl_c = 0, dstDatatype;
  714.     uint32_t dst_pitch_offset, color_factor, in_color_factor, alpha_comb;
  715.     uint32_t blend_cntl;
  716.     int i;
  717.    
  718.     if (pDstPicture->format == PICT_a8) {
  719.         if (R128BlendOp[op].dst_alpha) {
  720.         R128TRACE(("Can't dst alpha blend A8\n"));
  721.         return FALSE;
  722.         }
  723.         dstDatatype = R128_DATATYPE_Y8;
  724.     } else {
  725.         if (!R128GetDatatypePict1(pDstPicture->format, &dstDatatype)) return FALSE;
  726.     }
  727.    
  728.     if (!pSrc) {
  729.     pSrc = R128SolidPixmap(pScreen, cpu_to_le32(pSrcPicture->pSourcePict->solidFill.color));
  730.     if (!pSrc) {
  731.         R128TRACE(("Failed to create solid scratch pixmap\n"));
  732.         return FALSE;
  733.     }
  734.     add_src = TRUE;
  735.     }
  736.     if (pMaskPicture && !pMask) {
  737.     pMask = R128SolidPixmap(pScreen, cpu_to_le32(pMaskPicture->pSourcePict->solidFill.color));
  738.     if (!pMask) {
  739.         if (!pSrcPicture->pDrawable)
  740.         pScreen->DestroyPixmap(pSrc);
  741.         R128TRACE(("Failed to create solid scratch pixmap\n"));
  742.         return FALSE;
  743.     }
  744.     add_msk = TRUE;
  745.     }
  746.    
  747.     if (!R128TextureSetup(pSrcPicture, pSrc, 0, &txsize, &prim_tex_cntl_c, add_src)) return FALSE;
  748.    
  749.     if (pMask != NULL) {
  750.         if (!R128TextureSetup(pMaskPicture, pMask, 1, &txsize, &sec_tex_cntl_c, add_src)) return FALSE;
  751.     } else {
  752.     is_transform[1] = FALSE;
  753.     }
  754.    
  755.     if (!R128GetPixmapOffsetPitch(pDst, &dst_pitch_offset)) return FALSE;
  756.    
  757.     info->state_2d.in_use = TRUE;
  758.     if (add_src) info->state_2d.src_pix = pSrc;
  759.     if (add_msk) info->state_2d.msk_pix = pMask;
  760.     blend_cntl = R128BlendOp[op].blendctl;
  761.     if (PICT_FORMAT_A(pDstPicture->format) == 0 && R128BlendOp[op].dst_alpha) {
  762.         if ((blend_cntl & R128_SBLEND_MASK) == R128_SBLEND_DST_ALPHA)
  763.             blend_cntl = (blend_cntl & ~R128_SBLEND_MASK) | R128_SBLEND_ONE;
  764.         else if ((blend_cntl & R128_SBLEND_MASK) == R128_SBLEND_INV_DST_ALPHA)
  765.             blend_cntl = (blend_cntl & ~R128_SBLEND_MASK) | R128_SBLEND_ZERO;
  766.     }
  767.  
  768.     R128WaitForFifo(pScrn, 21);
  769.    
  770.     OUTREG(R128_SCALE_3D_CNTL,
  771.         R128_SCALE_3D_TEXMAP_SHADE |
  772.         R128_SCALE_PIX_REPLICATE |
  773.         R128_TEX_CACHE_SPLIT |
  774.         R128_TEX_MAP_ALPHA_IN_TEXTURE |
  775.         R128_TEX_CACHE_LINE_SIZE_4QW);
  776.     OUTREG(R128_DST_PITCH_OFFSET, dst_pitch_offset);
  777.     OUTREG(R128_DP_GUI_MASTER_CNTL,
  778.         R128_GMC_DST_PITCH_OFFSET_CNTL |
  779.         R128_GMC_BRUSH_SOLID_COLOR |
  780.         (dstDatatype >> 8) |
  781.         R128_GMC_SRC_DATATYPE_COLOR |
  782.         (R128_ROP[3].rop << 16) |
  783.         R128_DP_SRC_SOURCE_MEMORY |
  784.         R128_GMC_3D_FCN_EN |
  785.         R128_GMC_CLR_CMP_CNTL_DIS |
  786.         R128_GMC_AUX_CLIP_DIS |
  787.         R128_GMC_WR_MSK_DIS);
  788.     OUTREG(R128_MISC_3D_STATE_CNTL_REG,
  789.         R128_MISC_SCALE_3D_TEXMAP_SHADE |
  790.         R128_MISC_SCALE_PIX_REPLICATE |
  791.         R128_ALPHA_COMB_ADD_CLAMP |
  792.         blend_cntl);
  793.     OUTREG(R128_TEX_CNTL_C,
  794.         R128_TEXMAP_ENABLE |
  795.         ((pMask != NULL) ? R128_SEC_TEXMAP_ENABLE : 0) |
  796.         R128_ALPHA_ENABLE |
  797.         R128_TEX_CACHE_FLUSH);
  798.     OUTREG(R128_PC_GUI_CTLSTAT, R128_PC_FLUSH_GUI);
  799.  
  800.     /* IN operator: Without a mask, only the first texture unit is enabled.
  801.      * With a mask, we put the source in the first unit and have it pass
  802.      * through as input to the 2nd.  The 2nd unit takes the incoming source
  803.      * pixel and modulates it with either the alpha or each of the channels
  804.      * in the mask, depending on componentAlpha.
  805.      */
  806.     OUTREG(0, CCE_PACKET0(R128_PRIM_TEX_CNTL_C, 13));
  807.     OUTREG(0, prim_tex_cntl_c);
  808.  
  809.     /* If this is the only stage and the dest is a8, route the alpha result
  810.      * to the color (red channel, in particular), too.  Otherwise, be sure
  811.      * to zero out color channels of an a8 source.
  812.      */
  813.     if (pMaskPicture == NULL && pDstPicture->format == PICT_a8)
  814.         color_factor = R128_COLOR_FACTOR_ALPHA;
  815.     else if (pSrcPicture->format == PICT_a8)
  816.         color_factor = R128_COLOR_FACTOR_CONST_COLOR;
  817.     else
  818.         color_factor = R128_COLOR_FACTOR_TEX;
  819.  
  820.     if (PICT_FORMAT_A(pSrcPicture->format) == 0)
  821.         alpha_comb = R128_COMB_ALPHA_COPY_INP;
  822.     else
  823.         alpha_comb = R128_COMB_ALPHA_DIS;
  824.  
  825.     OUTREG(0, R128_COMB_COPY |
  826.         color_factor |
  827.         R128_INPUT_FACTOR_INT_COLOR |
  828.         alpha_comb |
  829.         R128_ALPHA_FACTOR_TEX_ALPHA |
  830.         R128_INP_FACTOR_A_CONST_ALPHA);
  831.     OUTREG(0, txsize);
  832.     /* We could save some output by only writing the offset register that
  833.      * will actually be used.  On the other hand, this is easy.
  834.      */
  835.     for (i = 0; i <= 10; i++)
  836.         OUTREG(0, ((CARD8 *)pSrc->devPrivate.ptr - info->ExaDriver->memoryBase));
  837.  
  838.     if (pMask != NULL) {
  839.         R128WaitForFifo(pScrn, 14);
  840.    
  841.         OUTREG(0, CCE_PACKET0(R128_SEC_TEX_CNTL_C, 12));
  842.         OUTREG(0, sec_tex_cntl_c);
  843.  
  844.         if (pDstPicture->format == PICT_a8) {
  845.             color_factor = R128_COLOR_FACTOR_ALPHA;
  846.             in_color_factor = R128_INPUT_FACTOR_PREV_ALPHA;
  847.         } else if (pMaskPicture->componentAlpha) {
  848.             color_factor = R128_COLOR_FACTOR_TEX;
  849.             in_color_factor = R128_INPUT_FACTOR_PREV_COLOR;
  850.         } else {
  851.             color_factor = R128_COLOR_FACTOR_ALPHA;
  852.             in_color_factor = R128_INPUT_FACTOR_PREV_COLOR;
  853.         }
  854.  
  855.         OUTREG(0, R128_COMB_MODULATE |
  856.             color_factor |
  857.             in_color_factor |
  858.             R128_COMB_ALPHA_MODULATE |
  859.             R128_ALPHA_FACTOR_TEX_ALPHA |
  860.             R128_INP_FACTOR_A_PREV_ALPHA);
  861.         for (i = 0; i <= 10; i++)
  862.             OUTREG(0, ((CARD8 *)pMask->devPrivate.ptr - info->ExaDriver->memoryBase));
  863.     }
  864.  
  865.     return TRUE;
  866. }
  867.  
  868. static void
  869. R128Composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h)
  870. {
  871.     ScreenPtr     pScreen   = pDst->drawable.pScreen;
  872.     ScrnInfoPtr   pScrn     = xf86Screens[pScreen->myNum];
  873.     R128InfoPtr   info      = R128PTR(pScrn);
  874.     unsigned char *R128MMIO = info->MMIO;
  875.    
  876.     int srcXend, srcYend, maskXend, maskYend;
  877.     PictVector v;
  878.    
  879.     srcXend = srcX + w;
  880.     srcYend = srcY + h;
  881.     maskXend = maskX + w;
  882.     maskYend = maskY + h;
  883.     if (is_transform[0]) {
  884.         v.vector[0] = IntToxFixed(srcX);
  885.         v.vector[1] = IntToxFixed(srcY);
  886.         v.vector[2] = xFixed1;
  887.         PictureTransformPoint(transform[0], &v);
  888.         srcX = xFixedToInt(v.vector[0]);
  889.         srcY = xFixedToInt(v.vector[1]);
  890.         v.vector[0] = IntToxFixed(srcXend);
  891.         v.vector[1] = IntToxFixed(srcYend);
  892.         v.vector[2] = xFixed1;
  893.         PictureTransformPoint(transform[0], &v);
  894.         srcXend = xFixedToInt(v.vector[0]);
  895.         srcYend = xFixedToInt(v.vector[1]);
  896.     }
  897.     if (is_transform[1]) {
  898.         v.vector[0] = IntToxFixed(maskX);
  899.         v.vector[1] = IntToxFixed(maskY);
  900.         v.vector[2] = xFixed1;
  901.         PictureTransformPoint(transform[1], &v);
  902.         maskX = xFixedToInt(v.vector[0]);
  903.         maskY = xFixedToInt(v.vector[1]);
  904.         v.vector[0] = IntToxFixed(maskXend);
  905.         v.vector[1] = IntToxFixed(maskYend);
  906.         v.vector[2] = xFixed1;
  907.         PictureTransformPoint(transform[1], &v);
  908.         maskXend = xFixedToInt(v.vector[0]);
  909.         maskYend = xFixedToInt(v.vector[1]);
  910.     }
  911.  
  912.     R128WaitForFifo(pScrn, 3 + 4 * VTX_RING_COUNT);
  913.    
  914.     OUTREG(0, CCE_PACKET3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 2 + 4 * VTX_RING_COUNT - 1));
  915.     OUTREG(0, R128_CCE_VC_FRMT_RHW |
  916.         R128_CCE_VC_FRMT_S_T |
  917.         R128_CCE_VC_FRMT_S2_T2);
  918.     OUTREG(0, R128_CCE_VC_CNTL_PRIM_TYPE_TRI_FAN |
  919.         R128_CCE_VC_CNTL_PRIM_WALK_RING |
  920.         (4 << R128_CCE_VC_CNTL_NUM_SHIFT));
  921.  
  922.     VTX_OUT(dstX,     dstY,     srcX,    srcY,    maskX,    maskY);
  923.     VTX_OUT(dstX,     dstY + h, srcX,    srcYend, maskX,    maskYend);
  924.     VTX_OUT(dstX + w, dstY + h, srcXend, srcYend, maskXend, maskYend);
  925.     VTX_OUT(dstX + w, dstY,     srcXend, srcY,    maskXend, maskY);
  926. }
  927.  
  928. #define R128DoneComposite R128Done
  929. #endif
  930.  
  931. static void
  932. R128Sync(ScreenPtr pScreen, int marker)
  933. {
  934.     R128WaitForIdle(xf86Screens[pScreen->myNum]);
  935. }
  936.  
  937. static void
  938. R128Done(PixmapPtr pPixmap)
  939. {
  940.     ScreenPtr     pScreen   = pPixmap->drawable.pScreen;
  941.     ScrnInfoPtr   pScrn     = xf86Screens[pScreen->myNum];
  942.     R128InfoPtr   info      = R128PTR(pScrn);
  943.    
  944.     info->state_2d.in_use = FALSE;
  945. #ifdef RENDER
  946.     if (info->state_2d.src_pix) {
  947.         pScreen->DestroyPixmap(info->state_2d.src_pix);
  948.     info->state_2d.src_pix = NULL;
  949.     R128TRACE(("Did it\n"));
  950.     }
  951.     if (info->state_2d.msk_pix) {
  952.         pScreen->DestroyPixmap(info->state_2d.msk_pix);
  953.     info->state_2d.msk_pix = NULL;
  954.     }
  955. #endif
  956. }
  957.  
  958. #ifdef R128DRI
  959.  
  960. #define R128CCEPrepareSolid R128PrepareSolid
  961.  
  962. static void
  963. R128CCESolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
  964. {
  965.     ScreenPtr     pScreen   = pPixmap->drawable.pScreen;
  966.     ScrnInfoPtr   pScrn     = xf86Screens[pScreen->myNum];
  967.     R128InfoPtr   info      = R128PTR(pScrn);
  968.     RING_LOCALS;
  969.  
  970.     R128CCE_REFRESH( pScrn, info );
  971.  
  972.     BEGIN_RING( 4 );
  973.  
  974.     OUT_RING_REG( R128_DST_Y_X,          (y1 << 16) | x1 );
  975.     OUT_RING_REG( R128_DST_WIDTH_HEIGHT, ((x2-x1) << 16) | (y2-y1) );
  976.  
  977.     ADVANCE_RING();
  978. }
  979.  
  980. #define R128CCEDoneSolid R128Done
  981.  
  982. #define R128CCEPrepareCopy R128PrepareCopy
  983.  
  984. static void
  985. R128CCECopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
  986.      int width, int height)
  987. {
  988.     ScreenPtr     pScreen   = pDstPixmap->drawable.pScreen;
  989.     ScrnInfoPtr   pScrn     = xf86Screens[pScreen->myNum];
  990.     R128InfoPtr   info      = R128PTR(pScrn);
  991.     RING_LOCALS;
  992.    
  993.     R128CCE_REFRESH( pScrn, info );
  994.  
  995.     if (info->xdir < 0) srcX += width - 1, dstX += width - 1;
  996.     if (info->ydir < 0) srcY += height - 1, dstY += height - 1;
  997.  
  998.     BEGIN_RING( 6 );
  999.  
  1000.     OUT_RING_REG( R128_SRC_Y_X,          (srcY << 16) | srcX );
  1001.     OUT_RING_REG( R128_DST_Y_X,          (dstY << 16) | dstX );
  1002.     OUT_RING_REG( R128_DST_HEIGHT_WIDTH, (height << 16) | width );
  1003.  
  1004.     ADVANCE_RING();
  1005. }
  1006.  
  1007. #define R128CCEDoneCopy R128Done
  1008.  
  1009. #ifdef RENDER
  1010. #define R128CCECheckComposite R128CheckComposite
  1011.  
  1012. static Bool
  1013. R128CCEPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
  1014.     PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
  1015. {
  1016.     ScreenPtr     pScreen   = pDst->drawable.pScreen;
  1017.     ScrnInfoPtr   pScrn     = xf86Screens[pScreen->myNum];
  1018.     R128InfoPtr   info      = R128PTR(pScrn);
  1019.     RING_LOCALS;
  1020.    
  1021.     Bool add_src = FALSE;
  1022.     Bool add_msk = FALSE;
  1023.     uint32_t txsize = 0, prim_tex_cntl_c, sec_tex_cntl_c = 0, dstDatatype;
  1024.     uint32_t dst_pitch_offset, color_factor, in_color_factor, alpha_comb;
  1025.     uint32_t blend_cntl;
  1026.     int i;
  1027.    
  1028.     if (pDstPicture->format == PICT_a8) {
  1029.         if (R128BlendOp[op].dst_alpha) {
  1030.         R128TRACE(("Can't dst alpha blend A8\n"));
  1031.         return FALSE;
  1032.         }
  1033.         dstDatatype = R128_DATATYPE_Y8;
  1034.     } else {
  1035.         if (!R128GetDatatypePict1(pDstPicture->format, &dstDatatype)) return FALSE;
  1036.     }
  1037.    
  1038.     if (!pSrc) {
  1039.     pSrc = R128SolidPixmap(pScreen, cpu_to_le32(pSrcPicture->pSourcePict->solidFill.color));
  1040.     if (!pSrc) {
  1041.         R128TRACE(("Failed to create solid scratch pixmap\n"));
  1042.         return FALSE;
  1043.     }
  1044.     add_src = TRUE;
  1045.         R128TRACE(("Doing it, %d\n", op));
  1046.     }
  1047.     if (pMaskPicture && !pMask) {
  1048.     pMask = R128SolidPixmap(pScreen, cpu_to_le32(pMaskPicture->pSourcePict->solidFill.color));
  1049.     if (!pMask) {
  1050.         if (!pSrcPicture->pDrawable)
  1051.         pScreen->DestroyPixmap(pSrc);
  1052.         R128TRACE(("Failed to create solid scratch pixmap\n"));
  1053.         return FALSE;
  1054.     }
  1055.     add_msk = TRUE;
  1056.     }
  1057.    
  1058.     if (!R128TextureSetup(pSrcPicture, pSrc, 0, &txsize, &prim_tex_cntl_c, add_src)) return FALSE;
  1059.    
  1060.     if (pMask != NULL) {
  1061.         if (!R128TextureSetup(pMaskPicture, pMask, 1, &txsize, &sec_tex_cntl_c, add_src)) return FALSE;
  1062.     } else {
  1063.     is_transform[1] = FALSE;
  1064.     }
  1065.    
  1066.     if (!R128GetPixmapOffsetPitch(pDst, &dst_pitch_offset)) return FALSE;
  1067.    
  1068.     info->state_2d.in_use = TRUE;
  1069.     if (add_src) info->state_2d.src_pix = pSrc;
  1070.     if (add_msk) info->state_2d.msk_pix = pMask;
  1071.     blend_cntl = R128BlendOp[op].blendctl;
  1072.     if (PICT_FORMAT_A(pDstPicture->format) == 0 && R128BlendOp[op].dst_alpha) {
  1073.         if ((blend_cntl & R128_SBLEND_MASK) == R128_SBLEND_DST_ALPHA)
  1074.             blend_cntl = (blend_cntl & ~R128_SBLEND_MASK) | R128_SBLEND_ONE;
  1075.         else if ((blend_cntl & R128_SBLEND_MASK) == R128_SBLEND_INV_DST_ALPHA)
  1076.             blend_cntl = (blend_cntl & ~R128_SBLEND_MASK) | R128_SBLEND_ZERO;
  1077.     }
  1078.  
  1079.     R128CCE_REFRESH( pScrn, info );
  1080.     BEGIN_RING( 12 );
  1081.    
  1082.     OUT_RING_REG(R128_SCALE_3D_CNTL,
  1083.         R128_SCALE_3D_TEXMAP_SHADE |
  1084.         R128_SCALE_PIX_REPLICATE |
  1085.         R128_TEX_CACHE_SPLIT |
  1086.         R128_TEX_MAP_ALPHA_IN_TEXTURE |
  1087.         R128_TEX_CACHE_LINE_SIZE_4QW);
  1088.     OUT_RING_REG(R128_DST_PITCH_OFFSET, dst_pitch_offset);
  1089.     OUT_RING_REG(R128_DP_GUI_MASTER_CNTL,
  1090.         R128_GMC_DST_PITCH_OFFSET_CNTL |
  1091.         R128_GMC_BRUSH_SOLID_COLOR |
  1092.         (dstDatatype >> 8) |
  1093.         R128_GMC_SRC_DATATYPE_COLOR |
  1094.         (R128_ROP[3].rop << 16) |
  1095.         R128_DP_SRC_SOURCE_MEMORY |
  1096.         R128_GMC_3D_FCN_EN |
  1097.         R128_GMC_CLR_CMP_CNTL_DIS |
  1098.         R128_GMC_AUX_CLIP_DIS |
  1099.         R128_GMC_WR_MSK_DIS);
  1100.     OUT_RING_REG(R128_MISC_3D_STATE_CNTL_REG,
  1101.         R128_MISC_SCALE_3D_TEXMAP_SHADE |
  1102.         R128_MISC_SCALE_PIX_REPLICATE |
  1103.         R128_ALPHA_COMB_ADD_CLAMP |
  1104.         blend_cntl);
  1105.     OUT_RING_REG(R128_TEX_CNTL_C,
  1106.         R128_TEXMAP_ENABLE |
  1107.         ((pMask != NULL) ? R128_SEC_TEXMAP_ENABLE : 0) |
  1108.         R128_ALPHA_ENABLE |
  1109.         R128_TEX_CACHE_FLUSH);
  1110.     OUT_RING_REG(R128_PC_GUI_CTLSTAT, R128_PC_FLUSH_GUI);
  1111.     ADVANCE_RING();
  1112.  
  1113.     /* IN operator: Without a mask, only the first texture unit is enabled.
  1114.      * With a mask, we put the source in the first unit and have it pass
  1115.      * through as input to the 2nd.  The 2nd unit takes the incoming source
  1116.      * pixel and modulates it with either the alpha or each of the channels
  1117.      * in the mask, depending on componentAlpha.
  1118.      */
  1119.     BEGIN_RING( 15 );
  1120.     /* R128_REG_PRIM_TEX_CNTL_C,
  1121.      * R128_REG_PRIM_TEXTURE_COMBINE_CNTL_C,
  1122.      * R128_REG_TEX_SIZE_PITCH_C,
  1123.      * R128_REG_PRIM_TEX_0_OFFSET_C - R128_REG_PRIM_TEX_10_OFFSET_C
  1124.      */
  1125.     OUT_RING(CCE_PACKET0(R128_PRIM_TEX_CNTL_C, 13));
  1126.     OUT_RING(prim_tex_cntl_c);
  1127.  
  1128.     /* If this is the only stage and the dest is a8, route the alpha result
  1129.      * to the color (red channel, in particular), too.  Otherwise, be sure
  1130.      * to zero out color channels of an a8 source.
  1131.      */
  1132.     if (pMaskPicture == NULL && pDstPicture->format == PICT_a8)
  1133.         color_factor = R128_COLOR_FACTOR_ALPHA;
  1134.     else if (pSrcPicture->format == PICT_a8)
  1135.         color_factor = R128_COLOR_FACTOR_CONST_COLOR;
  1136.     else
  1137.         color_factor = R128_COLOR_FACTOR_TEX;
  1138.  
  1139.     if (PICT_FORMAT_A(pSrcPicture->format) == 0)
  1140.         alpha_comb = R128_COMB_ALPHA_COPY_INP;
  1141.     else
  1142.         alpha_comb = R128_COMB_ALPHA_DIS;
  1143.  
  1144.     OUT_RING(R128_COMB_COPY |
  1145.         color_factor |
  1146.         R128_INPUT_FACTOR_INT_COLOR |
  1147.         alpha_comb |
  1148.         R128_ALPHA_FACTOR_TEX_ALPHA |
  1149.         R128_INP_FACTOR_A_CONST_ALPHA);
  1150.     OUT_RING(txsize);
  1151.     /* We could save some output by only writing the offset register that
  1152.      * will actually be used.  On the other hand, this is easy.
  1153.      */
  1154.     for (i = 0; i <= 10; i++)
  1155.         OUT_RING(((CARD8 *)pSrc->devPrivate.ptr - info->ExaDriver->memoryBase));
  1156.     ADVANCE_RING();
  1157.  
  1158.     if (pMask != NULL) {
  1159.         BEGIN_RING( 14 );
  1160.     /* R128_REG_SEC_TEX_CNTL_C,
  1161.      * R128_REG_SEC_TEXTURE_COMBINE_CNTL_C,
  1162.      * R128_REG_SEC_TEX_0_OFFSET_C - R128_REG_SEC_TEX_10_OFFSET_C
  1163.      */
  1164.    
  1165.         OUT_RING(CCE_PACKET0(R128_SEC_TEX_CNTL_C, 12));
  1166.         OUT_RING(sec_tex_cntl_c);
  1167.  
  1168.         if (pDstPicture->format == PICT_a8) {
  1169.             color_factor = R128_COLOR_FACTOR_ALPHA;
  1170.             in_color_factor = R128_INPUT_FACTOR_PREV_ALPHA;
  1171.         } else if (pMaskPicture->componentAlpha) {
  1172.             color_factor = R128_COLOR_FACTOR_TEX;
  1173.             in_color_factor = R128_INPUT_FACTOR_PREV_COLOR;
  1174.         } else {
  1175.             color_factor = R128_COLOR_FACTOR_ALPHA;
  1176.             in_color_factor = R128_INPUT_FACTOR_PREV_COLOR;
  1177.         }
  1178.  
  1179.         OUT_RING(R128_COMB_MODULATE |
  1180.             color_factor |
  1181.             in_color_factor |
  1182.             R128_COMB_ALPHA_MODULATE |
  1183.             R128_ALPHA_FACTOR_TEX_ALPHA |
  1184.             R128_INP_FACTOR_A_PREV_ALPHA);
  1185.         for (i = 0; i <= 10; i++)
  1186.             OUT_RING(((CARD8 *)pMask->devPrivate.ptr - info->ExaDriver->memoryBase));
  1187.    
  1188.     ADVANCE_RING();
  1189.     }
  1190.  
  1191.     return TRUE;
  1192. }
  1193.  
  1194. static void
  1195. R128CCEComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h)
  1196. {
  1197.     ScreenPtr     pScreen   = pDst->drawable.pScreen;
  1198.     ScrnInfoPtr   pScrn     = xf86Screens[pScreen->myNum];
  1199.     R128InfoPtr   info      = R128PTR(pScrn);
  1200.     RING_LOCALS;
  1201.    
  1202.     int srcXend, srcYend, maskXend, maskYend;
  1203.     PictVector v;
  1204.    
  1205.     srcXend = srcX + w;
  1206.     srcYend = srcY + h;
  1207.     maskXend = maskX + w;
  1208.     maskYend = maskY + h;
  1209.     if (is_transform[0]) {
  1210.         v.vector[0] = IntToxFixed(srcX);
  1211.         v.vector[1] = IntToxFixed(srcY);
  1212.         v.vector[2] = xFixed1;
  1213.         PictureTransformPoint(transform[0], &v);
  1214.         srcX = xFixedToInt(v.vector[0]);
  1215.         srcY = xFixedToInt(v.vector[1]);
  1216.         v.vector[0] = IntToxFixed(srcXend);
  1217.         v.vector[1] = IntToxFixed(srcYend);
  1218.         v.vector[2] = xFixed1;
  1219.         PictureTransformPoint(transform[0], &v);
  1220.         srcXend = xFixedToInt(v.vector[0]);
  1221.         srcYend = xFixedToInt(v.vector[1]);
  1222.     }
  1223.     if (is_transform[1]) {
  1224.         v.vector[0] = IntToxFixed(maskX);
  1225.         v.vector[1] = IntToxFixed(maskY);
  1226.         v.vector[2] = xFixed1;
  1227.         PictureTransformPoint(transform[1], &v);
  1228.         maskX = xFixedToInt(v.vector[0]);
  1229.         maskY = xFixedToInt(v.vector[1]);
  1230.         v.vector[0] = IntToxFixed(maskXend);
  1231.         v.vector[1] = IntToxFixed(maskYend);
  1232.         v.vector[2] = xFixed1;
  1233.         PictureTransformPoint(transform[1], &v);
  1234.         maskXend = xFixedToInt(v.vector[0]);
  1235.         maskYend = xFixedToInt(v.vector[1]);
  1236.     }
  1237.  
  1238.     R128CCE_REFRESH( pScrn, info );
  1239.     BEGIN_RING( 3 + 4 * VTX_RING_COUNT );
  1240.    
  1241.     OUT_RING(CCE_PACKET3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 2 + 4 * VTX_RING_COUNT - 1));
  1242.     OUT_RING(R128_CCE_VC_FRMT_RHW |
  1243.         R128_CCE_VC_FRMT_S_T |
  1244.         R128_CCE_VC_FRMT_S2_T2);
  1245.     OUT_RING(R128_CCE_VC_CNTL_PRIM_TYPE_TRI_FAN |
  1246.         R128_CCE_VC_CNTL_PRIM_WALK_RING |
  1247.         (4 << R128_CCE_VC_CNTL_NUM_SHIFT));
  1248.  
  1249.     VTX_CCE_OUT(dstX,     dstY,     srcX,    srcY,    maskX,    maskY);
  1250.     VTX_CCE_OUT(dstX,     dstY + h, srcX,    srcYend, maskX,    maskYend);
  1251.     VTX_CCE_OUT(dstX + w, dstY + h, srcXend, srcYend, maskXend, maskYend);
  1252.     VTX_CCE_OUT(dstX + w, dstY,     srcXend, srcY,    maskXend, maskY);
  1253.    
  1254.     ADVANCE_RING();
  1255. }
  1256.  
  1257. #define R128CCEDoneComposite R128Done
  1258. #endif
  1259.  
  1260. static void
  1261. R128CCESync(ScreenPtr pScreen, int marker)
  1262. {
  1263.     R128CCEWaitForIdle(xf86Screens[pScreen->myNum]);
  1264. }
  1265. #endif
  1266.  
  1267. Bool
  1268. R128EXAInit(ScreenPtr pScreen)
  1269. {
  1270.     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
  1271.     R128InfoPtr info = R128PTR(pScrn);
  1272.  
  1273.     info->ExaDriver->exa_major = EXA_VERSION_MAJOR;
  1274.     info->ExaDriver->exa_minor = EXA_VERSION_MINOR;
  1275.    
  1276.     info->ExaDriver->memoryBase = info->FB + pScrn->fbOffset;
  1277.     info->ExaDriver->flags = EXA_OFFSCREEN_PIXMAPS | EXA_OFFSCREEN_ALIGN_POT;
  1278.  
  1279. #if EXA_VERSION_MAJOR > 2 || (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 3)
  1280.     info->ExaDriver->maxPitchBytes = 16320;
  1281. #endif
  1282.     /* Pitch alignment is in sets of 8 pixels, and we need to cover 32bpp, so it's 32 bytes */
  1283.     info->ExaDriver->pixmapPitchAlign = 32;
  1284.     info->ExaDriver->pixmapOffsetAlign = 32;
  1285.     info->ExaDriver->maxX = 2048;
  1286.     info->ExaDriver->maxY = 2048;
  1287.  
  1288.     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
  1289.            "Setting up EXA callbacks\n");
  1290.  
  1291. #ifdef R128DRI
  1292.     if (info->directRenderingEnabled) {
  1293.     info->ExaDriver->PrepareSolid = R128CCEPrepareSolid;
  1294.     info->ExaDriver->Solid = R128CCESolid;
  1295.     info->ExaDriver->DoneSolid = R128CCEDoneSolid;
  1296.  
  1297.     info->ExaDriver->PrepareCopy = R128CCEPrepareCopy;
  1298.     info->ExaDriver->Copy = R128CCECopy;
  1299.     info->ExaDriver->DoneCopy = R128CCEDoneCopy;
  1300.  
  1301. #ifdef RENDER
  1302.     info->ExaDriver->CheckComposite = R128CCECheckComposite;
  1303.     info->ExaDriver->PrepareComposite = R128CCEPrepareComposite;
  1304.     info->ExaDriver->Composite = R128CCEComposite;
  1305.     info->ExaDriver->DoneComposite = R128CCEDoneComposite;
  1306. #endif
  1307.  
  1308.     info->ExaDriver->WaitMarker = R128CCESync;
  1309.     } else
  1310. #endif
  1311.     {
  1312.     info->ExaDriver->PrepareSolid = R128PrepareSolid;
  1313.     info->ExaDriver->Solid = R128Solid;
  1314.     info->ExaDriver->DoneSolid = R128DoneSolid;
  1315.    
  1316.     info->ExaDriver->PrepareCopy = R128PrepareCopy;
  1317.     info->ExaDriver->Copy = R128Copy;
  1318.     info->ExaDriver->DoneCopy = R128DoneCopy;
  1319.  
  1320. #ifdef RENDER
  1321.     info->ExaDriver->CheckComposite = R128CheckComposite;
  1322.     info->ExaDriver->PrepareComposite = R128PrepareComposite;
  1323.     info->ExaDriver->Composite = R128Composite;
  1324.     info->ExaDriver->DoneComposite = R128DoneComposite;
  1325. #endif
  1326.  
  1327.     info->ExaDriver->WaitMarker = R128Sync;
  1328.     }
  1329.  
  1330.     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
  1331.            "Initalizing 2D acceleration engine...\n");
  1332.  
  1333.     R128EngineInit(pScrn);
  1334.  
  1335.     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
  1336.            "Initializing EXA driver...\n");
  1337.  
  1338.     if (!exaDriverInit(pScreen, info->ExaDriver)) {
  1339.         free(info->ExaDriver);
  1340.     return FALSE;
  1341.     }
  1342.     exaMarkSync(pScreen);
  1343.    
  1344.     return TRUE;
  1345. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement