Subversion Repositories Kolibri OS

Rev

Rev 885 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1.  
  2. struct blendinfo {
  3.     Bool dst_alpha;
  4.     Bool src_alpha;
  5.     u32_t blend_cntl;
  6. };
  7.  
  8. static struct blendinfo RadeonBlendOp[] = {
  9.     /* 0 - Clear */
  10.     {0, 0, RADEON_SRC_BLEND_GL_ZERO                | RADEON_DST_BLEND_GL_ZERO},
  11.     /* 1 - Src */
  12.     {0, 0, RADEON_SRC_BLEND_GL_ONE                 | RADEON_DST_BLEND_GL_ZERO},
  13.     /* 2 - Dst */
  14.     {0, 0, RADEON_SRC_BLEND_GL_ZERO                | RADEON_DST_BLEND_GL_ONE},
  15.     /* 3 - Over */
  16.     {0, 1, RADEON_SRC_BLEND_GL_ONE                 | RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA},
  17.     /* 4 - OverReverse */
  18.     {1, 0, RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA | RADEON_DST_BLEND_GL_ONE},
  19.     /* 5 - In */
  20.     {1, 0, RADEON_SRC_BLEND_GL_DST_ALPHA           | RADEON_DST_BLEND_GL_ZERO},
  21.     /* 6 - InReverse */
  22.     {0, 1, RADEON_SRC_BLEND_GL_ZERO                | RADEON_DST_BLEND_GL_SRC_ALPHA},
  23.     /* 7 - Out */
  24.     {1, 0, RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA | RADEON_DST_BLEND_GL_ZERO},
  25.     /* 8 - OutReverse */
  26.     {0, 1, RADEON_SRC_BLEND_GL_ZERO                | RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA},
  27.     /* 9 - Atop */
  28.     {1, 1, RADEON_SRC_BLEND_GL_DST_ALPHA           | RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA},
  29.     /* 10- AtopReverse */
  30.     {1, 1, RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA | RADEON_DST_BLEND_GL_SRC_ALPHA},
  31.     /* 11 - Xor */
  32.     {1, 1, RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA | RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA},
  33.     /* 12 - Add */
  34.     {0, 0, RADEON_SRC_BLEND_GL_ONE                 | RADEON_DST_BLEND_GL_ONE},
  35. };
  36.  
  37. static Bool R200PrepareComposite(local_pixmap_t *dstpix, int dstX, int dstY,
  38.                                  local_pixmap_t *srcpix, int srcX, int srcY,
  39.                                  int w, int h, int alpha)
  40. {
  41.     u32_t tex_size = 0, txformat, blend_cntl;
  42.     int dst_pitch;
  43.  
  44.     if ((w > 2048) || (h > 2048))
  45.         return FALSE;
  46.  
  47.     txformat = RADEON_TXFORMAT_ARGB8888      |
  48.                RADEON_TXFORMAT_ALPHA_IN_MAP  |
  49.                RADEON_TXFORMAT_NON_POWER2;
  50.  
  51.     blend_cntl = RADEON_SRC_BLEND_GL_SRC_ALPHA |
  52.                  RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA;
  53.  
  54.     tex_size = ((h - 1) << 16) | (w - 1);
  55.     {
  56.         u32_t *ring;
  57.         u32_t ifl  = safe_cli();
  58.  
  59.         BEGIN_ACCEL(168);
  60.         OUT_ACCEL_REG(R200_PP_TXFORMAT_0, txformat);
  61.         OUT_ACCEL_REG(R200_PP_TXFORMAT_X_0, 0);
  62.         OUT_ACCEL_REG(R200_PP_TXSIZE_0, tex_size);
  63.         OUT_ACCEL_REG(R200_PP_TXPITCH_0, srcpix->pitch - 32);
  64.         OUT_ACCEL_REG(R200_PP_TXOFFSET_0, (u32_t)srcpix->local);
  65.         OUT_ACCEL_REG(R200_PP_TXFILTER_0, R200_MAG_FILTER_NEAREST |
  66.                                       R200_MIN_FILTER_NEAREST |
  67.                                       R200_CLAMP_S_WRAP |
  68.                                       R200_CLAMP_T_WRAP);
  69.  
  70.         OUT_ACCEL_REG(RADEON_RB3D_CNTL, RADEON_COLOR_FORMAT_ARGB8888 |
  71.                                         RADEON_ALPHA_BLEND_ENABLE);
  72.         OUT_ACCEL_REG(RADEON_PP_CNTL, RADEON_TEX_0_ENABLE |
  73.                                       RADEON_TEX_BLEND_0_ENABLE);
  74.         OUT_ACCEL_REG(R200_PP_TFACTOR_0, alpha << 24);
  75.         OUT_ACCEL_REG(R200_PP_TXCBLEND_0, R200_TXC_ARG_A_TFACTOR_COLOR |
  76.                                           R200_TXC_ARG_B_R0_ALPHA);
  77.         OUT_ACCEL_REG(R200_PP_TXCBLEND2_0,R200_TXC_OUTPUT_REG_R0);
  78.         OUT_ACCEL_REG(R200_PP_TXABLEND_0, R200_TXA_ARG_A_TFACTOR_ALPHA |
  79.                                           R200_TXA_ARG_B_R0_ALPHA);
  80.         OUT_ACCEL_REG(R200_PP_TXABLEND2_0, R200_TXA_OUTPUT_REG_R0);
  81.         OUT_ACCEL_REG(R200_SE_VTX_FMT_0, 0);
  82.         OUT_ACCEL_REG(R200_SE_VTX_FMT_1, (2 << R200_VTX_TEX0_COMP_CNT_SHIFT));
  83.         OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL, blend_cntl);
  84.  
  85.         OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, dstpix->pitch >> 2);
  86.         OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, (u32_t)dstpix->local);
  87.  
  88.         COMMIT_RING();
  89.         safe_sti(ifl);
  90.     };
  91.  
  92.     return TRUE;
  93. }
  94.  
  95. static Bool R300TextureSetup(RHDPtr info,local_pixmap_t *srcpix, int w, int h, int unit)
  96. {
  97.     u32_t txfilter, txformat0, txformat1, txoffset, txpitch;
  98.  //   int w = pPict->pDrawable->width;
  99.  //   int h = pPict->pDrawable->height;
  100.     int i, pixel_shift;
  101.  
  102.  
  103.     txpitch = srcpix->pitch;
  104.     txoffset = (u32_t)srcpix->local;
  105.  
  106.     if ((txoffset & 0x1f) != 0)
  107.         dbgprintf("Bad texture offset 0x%x\n", (int)txoffset);
  108.     if ((txpitch & 0x1f) != 0)
  109.         dbgprintf("Bad texture pitch 0x%x\n", (int)txpitch);
  110.  
  111.     /* TXPITCH = pixels (texels) per line - 1 */
  112.     pixel_shift = 32 >> 4;
  113.     txpitch >>= pixel_shift;
  114.     txpitch -= 1;
  115.  
  116.   //  if (RADEONPixmapIsColortiled(pPix))
  117.   //      txoffset |= R300_MACRO_TILE;
  118.  
  119.  //   for (i = 0; i < sizeof(R300TexFormats) / sizeof(R300TexFormats[0]); i++)
  120.  //   {
  121.  //       if (R300TexFormats[i].fmt == pPict->format)
  122.  //           break;
  123.  //   }
  124.  
  125.     //txformat1 = R300TexFormats[i].card_fmt;
  126.  
  127.     txformat1 = R300_TX_FORMAT_A8R8G8B8;
  128.  
  129.     txformat0 = ((((w - 1) & 0x7ff) << R300_TXWIDTH_SHIFT) |
  130.                  (((h - 1) & 0x7ff) << R300_TXHEIGHT_SHIFT));
  131.  
  132.     if (IS_R500_3D && ((w - 1) & 0x800))
  133.         txpitch |= R500_TXWIDTH_11;
  134.  
  135.     if (IS_R500_3D && ((h - 1) & 0x800))
  136.         txpitch |= R500_TXHEIGHT_11;
  137.  
  138.     /* Use TXPITCH instead of TXWIDTH for address computations: we could
  139.      * omit this if there is no padding, but there is no apparent advantage
  140.      * in doing so.
  141.      */
  142.     txformat0 |= R300_TXPITCH_EN;
  143.  
  144.   //  info->texW[unit] = w;
  145.   //  info->texH[unit] = h;
  146.  
  147.   //  if (pPict->repeat && !(unit == 0 && need_src_tile_x))
  148.   //    txfilter = R300_TX_CLAMP_S(R300_TX_CLAMP_WRAP);
  149.   //  else
  150.       txfilter = R300_TX_CLAMP_S(R300_TX_CLAMP_CLAMP_GL);
  151.  
  152.   //  if (pPict->repeat && !(unit == 0 && need_src_tile_y))
  153.   //    txfilter |= R300_TX_CLAMP_T(R300_TX_CLAMP_WRAP);
  154.   //  else
  155.       txfilter |= R300_TX_CLAMP_T(R300_TX_CLAMP_CLAMP_GL);
  156.  
  157.     txfilter |= (unit << R300_TX_ID_SHIFT);
  158.  
  159. //    switch (pPict->filter) {
  160. //    case PictFilterNearest:
  161.         txfilter |= (R300_TX_MAG_FILTER_NEAREST | R300_TX_MIN_FILTER_NEAREST);
  162. //        break;
  163. //    case PictFilterBilinear:
  164. //        txfilter |= (R300_TX_MAG_FILTER_LINEAR | R300_TX_MIN_FILTER_LINEAR);
  165. //        break;
  166. //    default:
  167. //        RADEON_FALLBACK(("Bad filter 0x%x\n", pPict->filter));
  168. //    }
  169.  
  170.     {
  171.         u32_t *ring;
  172.         u32_t ifl  = safe_cli();
  173.  
  174.         BEGIN_ACCEL(7);
  175.  
  176.         OUT_ACCEL_REG(R300_TX_FILTER0_0 + (unit * 4), txfilter);
  177.         OUT_ACCEL_REG(R300_TX_FILTER1_0 + (unit * 4), 0);
  178.         OUT_ACCEL_REG(R300_TX_FORMAT0_0 + (unit * 4), txformat0);
  179.         OUT_ACCEL_REG(R300_TX_FORMAT1_0 + (unit * 4), txformat1);
  180.         OUT_ACCEL_REG(R300_TX_FORMAT2_0 + (unit * 4), txpitch);
  181.         OUT_ACCEL_REG(R300_TX_OFFSET_0 + (unit * 4), txoffset);
  182. //    if (!pPict->repeat)
  183.         OUT_ACCEL_REG(R300_TX_BORDER_COLOR_0 + (unit * 4), 0);
  184.  
  185.         COMMIT_RING();
  186.         safe_sti(ifl);
  187.     }
  188. //    if (pPict->transform != 0) {
  189. //        is_transform[unit] = TRUE;
  190. //        transform[unit] = pPict->transform;
  191. //    } else {
  192. //        is_transform[unit] = FALSE;
  193. //    }
  194.  
  195.     return TRUE;
  196. }
  197.  
  198. static u32_t RADEONGetBlendCntl(int op, u32_t dst_format)
  199. {
  200.     u32_t sblend, dblend;
  201.  
  202.    // sblend = RadeonBlendOp[op].blend_cntl & RADEON_SRC_BLEND_MASK;
  203.    // dblend = RadeonBlendOp[op].blend_cntl & RADEON_DST_BLEND_MASK;
  204.  
  205.     /* If there's no dst alpha channel, adjust the blend op so that we'll treat
  206.      * it as always 1.
  207.      */
  208.   //  if ( RadeonBlendOp[op].dst_alpha) {
  209.   //      if (sblend == RADEON_SRC_BLEND_GL_DST_ALPHA)
  210.   //          sblend = RADEON_SRC_BLEND_GL_ONE;
  211.   //      else if (sblend == RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA)
  212.   //          sblend = RADEON_SRC_BLEND_GL_ZERO;
  213.   //  }
  214.  
  215.     //return sblend | dblend;
  216.  
  217.     return RADEON_SRC_BLEND_GL_SRC_ALPHA | RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA;
  218. }
  219.  
  220.  
  221. Bool R300PrepareComposite(local_pixmap_t *dstpix, int dstX, int dstY,
  222.                           local_pixmap_t *srcpix, int srcX, int srcY,
  223.                           int w, int h, int op)
  224. {
  225.   //  RINFO_FROM_SCREEN(pDst->drawable.pScreen);
  226.     u32_t dst_format, dst_offset, dst_pitch;
  227.     u32_t txenable, colorpitch;
  228.     u32_t blendcntl;
  229.     int pixel_shift;
  230.     u32_t *ring;
  231.  
  232.     u32_t ifl;
  233.  
  234.     RHDPtr info = &rhd;
  235.  
  236.     dst_format = R300_COLORFORMAT_ARGB8888;
  237.  
  238.     dst_offset = (u32_t)dstpix->local;
  239.  
  240.     dst_pitch = dstpix->pitch;
  241.  
  242.     pixel_shift = 32 >> 4;
  243.  
  244.     colorpitch = dst_pitch >> pixel_shift;
  245.  
  246.   //  if (RADEONPixmapIsColortiled(pDst))
  247.   //      colorpitch |= R300_COLORTILE;
  248.  
  249.     colorpitch |= dst_format;
  250.  
  251.     if ((dst_offset & 0x0f) != 0)
  252.         dbgprintf("Bad destination offset 0x%x\n", (int)dst_offset);
  253.     if (((dst_pitch >> pixel_shift) & 0x7) != 0)
  254.         dbgprintf("Bad destination pitch 0x%x\n", (int)dst_pitch);
  255.  
  256.   //  if (!RADEONSetupSourceTile(pSrcPicture, pSrc, TRUE, FALSE))
  257.   //      return FALSE;
  258.  
  259.     if (!R300TextureSetup(&rhd, srcpix, w, h, 0))
  260.         return FALSE;
  261.  
  262.     txenable = R300_TEX_0_ENABLE;
  263.  
  264.   //  RADEON_SWITCH_TO_3D();
  265.  
  266.     /* setup the VAP */
  267.  
  268.     ifl = safe_cli();
  269.  
  270.     BEGIN_RING(32*2);
  271.  
  272.     OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_HOST_IDLECLEAN |
  273.                                      RADEON_WAIT_3D_IDLECLEAN);
  274.  
  275.     /* These registers define the number, type, and location of data submitted
  276.      * to the PVS unit of GA input (when PVS is disabled)
  277.      * DST_VEC_LOC is the slot in the PVS input vector memory when PVS/TCL is
  278.      * enabled.  This memory provides the imputs to the vertex shader program
  279.      * and ordering is not important.  When PVS/TCL is disabled, this field maps
  280.      * directly to the GA input memory and the order is signifigant.  In
  281.      * PVS_BYPASS mode the order is as follows:
  282.      * 0 Position
  283.      * 1 Point Size
  284.      * 2 Color 0
  285.      * 3 Color 1
  286.      * 4 Color 2
  287.      * 5 Color 3
  288.      * 6 Textures 0
  289.      * 7 Textures 1
  290.      * 8 Textures 2
  291.      * 9 Textures 3 - 7
  292.      * 14 Fog
  293.      */
  294.  
  295.      OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_0,
  296.                    ((R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_0_SHIFT) |
  297.                     (0 << R300_SKIP_DWORDS_0_SHIFT) |
  298.                     (0 << R300_DST_VEC_LOC_0_SHIFT) |
  299.                      R300_SIGNED_0 |
  300.                     (R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_1_SHIFT) |
  301.                     (0 << R300_SKIP_DWORDS_1_SHIFT) |
  302.                     (6 << R300_DST_VEC_LOC_1_SHIFT) |
  303.                      R300_LAST_VEC_1 |
  304.                      R300_SIGNED_1));
  305.  
  306.     /* load the vertex shader
  307.      * We pre-load vertex programs in RADEONInit3DEngine():
  308.      * - exa no mask
  309.      * - exa mask
  310.      * - Xv
  311.      * Here we select the offset of the vertex program we want to use
  312.      */
  313.     if (info->has_tcl) {
  314.             OUT_ACCEL_REG(R300_VAP_PVS_CODE_CNTL_0,
  315.                      ((3 << R300_PVS_FIRST_INST_SHIFT) |
  316.                       (4 << R300_PVS_XYZW_VALID_INST_SHIFT) |
  317.                       (4 << R300_PVS_LAST_INST_SHIFT)));
  318.             OUT_ACCEL_REG(R300_VAP_PVS_CODE_CNTL_1,
  319.                       (4 << R300_PVS_LAST_VTX_SRC_INST_SHIFT));
  320.     }
  321.  
  322.     /* Position and one or two sets of 2 texture coordinates */
  323.     OUT_ACCEL_REG(R300_VAP_OUT_VTX_FMT_0, R300_VTX_POS_PRESENT);   //VTX_COLOR_0_PRESENT
  324.     OUT_ACCEL_REG(R300_VAP_OUT_VTX_FMT_1, (2 << R300_TEX_0_COMP_CNT_SHIFT));
  325.  
  326.     OUT_ACCEL_REG(R300_TX_INVALTAGS, 0x0);
  327.     OUT_ACCEL_REG(R300_TX_ENABLE, txenable);
  328.     FINISH_ACCEL();
  329.  
  330.     /* setup pixel shader */
  331.  
  332.  
  333.     /* setup pixel shader */
  334.     if (IS_R300_3D)
  335.     {
  336.         u32_t output_fmt;
  337.         int src_color, src_alpha;
  338.         int mask_color, mask_alpha;
  339.  
  340.             src_color = R300_ALU_RGB_SRC0_RGB;
  341.  
  342.             src_alpha = R300_ALU_ALPHA_SRC0_A;
  343.  
  344.             mask_color = R300_ALU_RGB_1_0;
  345.             mask_alpha = R300_ALU_ALPHA_1_0;
  346.  
  347.         /* shader output swizzling */
  348.         output_fmt = (R300_OUT_FMT_C4_8 |
  349.                       R300_OUT_FMT_C0_SEL_BLUE |
  350.                       R300_OUT_FMT_C1_SEL_GREEN |
  351.                       R300_OUT_FMT_C2_SEL_RED |
  352.                       R300_OUT_FMT_C3_SEL_ALPHA);
  353.  
  354.  
  355.         /* setup the rasterizer, load FS */
  356.         BEGIN_ACCEL(10);
  357.             /* 2 components: 2 for tex0 */
  358.             OUT_ACCEL_REG(R300_RS_COUNT,
  359.                       ((2 << R300_RS_COUNT_IT_COUNT_SHIFT) |
  360.                         R300_RS_COUNT_HIRES_EN));
  361.  
  362.             OUT_ACCEL_REG(R300_RS_INST_COUNT, R300_INST_COUNT_RS(0) | R300_TX_OFFSET_RS(6));
  363.  
  364.             OUT_ACCEL_REG(R300_US_CODE_OFFSET, (R300_ALU_CODE_OFFSET(0) |
  365.                         R300_ALU_CODE_SIZE(0)   |
  366.                                                 R300_TEX_CODE_OFFSET(0) |
  367.                                                 R300_TEX_CODE_SIZE(0)));
  368.  
  369.             OUT_ACCEL_REG(R300_US_CODE_ADDR_3,
  370.                           (R300_ALU_START(0) |
  371.                R300_ALU_SIZE(0)  |
  372.                            R300_TEX_START(0) |
  373.                R300_TEX_SIZE(0)  |
  374.                            R300_RGBA_OUT));
  375.  
  376.         OUT_ACCEL_REG(R300_US_PIXSIZE, 1); /* highest temp used */
  377.         /* shader output swizzling */
  378.         OUT_ACCEL_REG(R300_US_OUT_FMT_0, output_fmt);
  379.  
  380.         /* tex inst for src texture is pre-loaded in RADEONInit3DEngine() */
  381.         /* tex inst for mask texture is pre-loaded in RADEONInit3DEngine() */
  382.  
  383.         /* RGB inst
  384.          * temp addresses for texture inputs
  385.          * ALU_RGB_ADDR0 is src tex (temp 0)
  386.          * ALU_RGB_ADDR1 is mask tex (temp 1)
  387.          * R300_ALU_RGB_OMASK - output components to write
  388.          * R300_ALU_RGB_TARGET_A - render target
  389.          */
  390.         OUT_ACCEL_REG(R300_US_ALU_RGB_ADDR(0),
  391.                      (R300_ALU_RGB_ADDR0(0) |
  392.                       R300_ALU_RGB_ADDR1(1) |
  393.                       R300_ALU_RGB_ADDR2(0) |
  394.                       R300_ALU_RGB_ADDRD(0) |
  395.                       R300_ALU_RGB_OMASK((R300_ALU_RGB_MASK_R |
  396.                                           R300_ALU_RGB_MASK_G |
  397.                                           R300_ALU_RGB_MASK_B)) |
  398.                       R300_ALU_RGB_TARGET_A));
  399.         /* RGB inst
  400.          * ALU operation
  401.          */
  402.         OUT_ACCEL_REG(R300_US_ALU_RGB_INST(0),
  403.                  (R300_ALU_RGB_SEL_A(src_color) |
  404.                   R300_ALU_RGB_MOD_A(R300_ALU_RGB_MOD_NOP) |
  405.                   R300_ALU_RGB_SEL_B(mask_color) |
  406.                   R300_ALU_RGB_MOD_B(R300_ALU_RGB_MOD_NOP) |
  407.                   R300_ALU_RGB_SEL_C(R300_ALU_RGB_0_0) |
  408.                   R300_ALU_RGB_MOD_C(R300_ALU_RGB_MOD_NOP) |
  409.                   R300_ALU_RGB_OP(R300_ALU_RGB_OP_MAD) |
  410.                   R300_ALU_RGB_OMOD(R300_ALU_RGB_OMOD_NONE) |
  411.                   R300_ALU_RGB_CLAMP));
  412.         /* Alpha inst
  413.          * temp addresses for texture inputs
  414.          * ALU_ALPHA_ADDR0 is src tex (0)
  415.          * ALU_ALPHA_ADDR1 is mask tex (1)
  416.          * R300_ALU_ALPHA_OMASK - output components to write
  417.          * R300_ALU_ALPHA_TARGET_A - render target
  418.          */
  419.         OUT_ACCEL_REG(R300_US_ALU_ALPHA_ADDR(0),
  420.                  (R300_ALU_ALPHA_ADDR0(0) |
  421.                   R300_ALU_ALPHA_ADDR1(1) |
  422.                   R300_ALU_ALPHA_ADDR2(0) |
  423.                   R300_ALU_ALPHA_ADDRD(0) |
  424.                   R300_ALU_ALPHA_OMASK(R300_ALU_ALPHA_MASK_A) |
  425.                   R300_ALU_ALPHA_TARGET_A |
  426.                   R300_ALU_ALPHA_OMASK_W(R300_ALU_ALPHA_MASK_NONE)));
  427.         /* Alpha inst
  428.          * ALU operation
  429.          */
  430.         OUT_ACCEL_REG(R300_US_ALU_ALPHA_INST(0),
  431.                  (R300_ALU_ALPHA_SEL_A(src_alpha) |
  432.                   R300_ALU_ALPHA_MOD_A(R300_ALU_ALPHA_MOD_NOP) |
  433.                   R300_ALU_ALPHA_SEL_B(mask_alpha) |
  434.                   R300_ALU_ALPHA_MOD_B(R300_ALU_ALPHA_MOD_NOP) |
  435.                   R300_ALU_ALPHA_SEL_C(R300_ALU_ALPHA_0_0) |
  436.                   R300_ALU_ALPHA_MOD_C(R300_ALU_ALPHA_MOD_NOP) |
  437.                   R300_ALU_ALPHA_OP(R300_ALU_ALPHA_OP_MAD) |
  438.                   R300_ALU_ALPHA_OMOD(R300_ALU_ALPHA_OMOD_NONE) |
  439.                   R300_ALU_ALPHA_CLAMP));
  440.     FINISH_ACCEL();
  441.     }
  442.     else
  443.     {
  444.         u32_t output_fmt;
  445.         u32_t src_color, src_alpha;
  446.         u32_t mask_color, mask_alpha;
  447.  
  448. //        if (PICT_FORMAT_RGB(PICT_a8r8g8b8) == 0)
  449. //            src_color = (R500_ALU_RGB_R_SWIZ_A_0 |
  450. //                         R500_ALU_RGB_G_SWIZ_A_0 |
  451. //                         R500_ALU_RGB_B_SWIZ_A_0);
  452. //        else
  453.             src_color = (R500_ALU_RGB_R_SWIZ_A_R |
  454.                      R500_ALU_RGB_G_SWIZ_A_G |
  455.                      R500_ALU_RGB_B_SWIZ_A_B);
  456.  
  457. //        if (PICT_FORMAT_A(PICT_a8r8g8b8) == 0)
  458. //            src_alpha = R500_ALPHA_SWIZ_A_1;
  459. //        else
  460.             src_alpha = R500_ALPHA_SWIZ_A_A;
  461.  
  462.         mask_color = (R500_ALU_RGB_R_SWIZ_B_1 |
  463.                       R500_ALU_RGB_G_SWIZ_B_1 |
  464.                       R500_ALU_RGB_B_SWIZ_B_1);
  465.         mask_alpha = R500_ALPHA_SWIZ_B_1;
  466.  
  467.         /* shader output swizzling */
  468.         output_fmt = (R300_OUT_FMT_C4_8         |
  469.                       R300_OUT_FMT_C0_SEL_BLUE  |
  470.                       R300_OUT_FMT_C1_SEL_GREEN |
  471.                       R300_OUT_FMT_C2_SEL_RED   |
  472.                       R300_OUT_FMT_C3_SEL_ALPHA);
  473.  
  474.         BEGIN_ACCEL(6);
  475.         OUT_ACCEL_REG(R300_RS_COUNT,
  476.                      ((2 << R300_RS_COUNT_IT_COUNT_SHIFT) |
  477.                        R300_RS_COUNT_HIRES_EN));
  478.  
  479.         OUT_ACCEL_REG(R300_RS_INST_COUNT, R300_INST_COUNT_RS(0) | R300_TX_OFFSET_RS(6));
  480.  
  481.         OUT_ACCEL_REG(R500_US_CODE_ADDR, (R500_US_CODE_START_ADDR(0) |
  482.                                           R500_US_CODE_END_ADDR(1)));
  483.         OUT_ACCEL_REG(R500_US_CODE_RANGE, (R500_US_CODE_RANGE_ADDR(0) |
  484.                                            R500_US_CODE_RANGE_SIZE(1)));
  485.         OUT_ACCEL_REG(R500_US_CODE_OFFSET, 0);
  486.  
  487.         OUT_ACCEL_REG(R300_US_OUT_FMT_0, output_fmt);
  488.         COMMIT_RING();
  489.  
  490.         BEGIN_ACCEL(13);
  491.         OUT_ACCEL_REG(R500_GA_US_VECTOR_INDEX, 0);
  492.             /* tex inst for src texture */
  493.         OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_INST_TYPE_TEX     |
  494.                                                R500_INST_TEX_SEM_WAIT |
  495.                                                R500_INST_RGB_WMASK_R  |
  496.                                                R500_INST_RGB_WMASK_G  |
  497.                                                R500_INST_RGB_WMASK_B  |
  498.                                                R500_INST_ALPHA_WMASK  |
  499.                                                R500_INST_RGB_CLAMP |
  500.                                                R500_INST_ALPHA_CLAMP));
  501.  
  502.        OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_TEX_ID(0) |
  503.                                                    R500_TEX_INST_LD |
  504.                                                    R500_TEX_SEM_ACQUIRE |
  505.                                                    R500_TEX_IGNORE_UNCOVERED));
  506.  
  507.             OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_TEX_SRC_ADDR(0) |
  508.                                                    R500_TEX_SRC_S_SWIZ_R |
  509.                                                    R500_TEX_SRC_T_SWIZ_G |
  510.                                                    R500_TEX_DST_ADDR(0) |
  511.                                                    R500_TEX_DST_R_SWIZ_R |
  512.                                                    R500_TEX_DST_G_SWIZ_G |
  513.                                                    R500_TEX_DST_B_SWIZ_B |
  514.                                                    R500_TEX_DST_A_SWIZ_A));
  515.             OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_DX_ADDR(0) |
  516.                                                    R500_DX_S_SWIZ_R |
  517.                                                    R500_DX_T_SWIZ_R |
  518.                                                    R500_DX_R_SWIZ_R |
  519.                                                    R500_DX_Q_SWIZ_R |
  520.                                                    R500_DY_ADDR(0) |
  521.                                                    R500_DY_S_SWIZ_R |
  522.                                                    R500_DY_T_SWIZ_R |
  523.                                                    R500_DY_R_SWIZ_R |
  524.                                                    R500_DY_Q_SWIZ_R));
  525.             OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, 0x00000000);
  526.             OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, 0x00000000);
  527.  
  528.         /* ALU inst */
  529.         /* *_OMASK* - output component write mask */
  530.         OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_INST_TYPE_OUT |
  531.                                                R500_INST_TEX_SEM_WAIT |
  532.                                                R500_INST_LAST |
  533.                                                R500_INST_RGB_OMASK_R |
  534.                                                R500_INST_RGB_OMASK_G |
  535.                                                R500_INST_RGB_OMASK_B |
  536.                                                R500_INST_ALPHA_OMASK |
  537.                                                R500_INST_RGB_CLAMP |
  538.                                                R500_INST_ALPHA_CLAMP));
  539.         /* ALU inst
  540.          * temp addresses for texture inputs
  541.          * RGB_ADDR0 is src tex (temp 0)
  542.          * RGB_ADDR1 is mask tex (temp 1)
  543.          */
  544.         OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_RGB_ADDR0(0) |
  545.                                                R500_RGB_ADDR1(1) |
  546.                                                R500_RGB_ADDR2(0)));
  547.         /* ALU inst
  548.          * temp addresses for texture inputs
  549.          * ALPHA_ADDR0 is src tex (temp 0)
  550.          * ALPHA_ADDR1 is mask tex (temp 1)
  551.          */
  552.         OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_ALPHA_ADDR0(0) |
  553.                                                R500_ALPHA_ADDR1(1) |
  554.                                                R500_ALPHA_ADDR2(0)));
  555.  
  556.         /* R500_ALU_RGB_TARGET - RGB render target */
  557.         OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_ALU_RGB_SEL_A_SRC0 |
  558.                                                src_color |
  559.                                                R500_ALU_RGB_SEL_B_SRC1 |
  560.                                                mask_color |
  561.                                                R500_ALU_RGB_TARGET(0)));
  562.  
  563.         /* R500_ALPHA_RGB_TARGET - alpha render target */
  564.         OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_ALPHA_OP_MAD |
  565.                                                R500_ALPHA_ADDRD(0) |
  566.                                                R500_ALPHA_SEL_A_SRC0 |
  567.                                                src_alpha |
  568.                                                R500_ALPHA_SEL_B_SRC1 |
  569.                                                mask_alpha |
  570.                                                R500_ALPHA_TARGET(0)));
  571.  
  572.         OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_ALU_RGBA_OP_MAD |
  573.                                                R500_ALU_RGBA_ADDRD(0) |
  574.                                                R500_ALU_RGBA_R_SWIZ_0 |
  575.                                                R500_ALU_RGBA_G_SWIZ_0 |
  576.                                                R500_ALU_RGBA_B_SWIZ_0 |
  577.                                                R500_ALU_RGBA_A_SWIZ_0));
  578.         FINISH_ACCEL();
  579.     }
  580.  
  581.     BEGIN_ACCEL(3);
  582.     OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset);
  583.     OUT_ACCEL_REG(R300_RB3D_COLORPITCH0, colorpitch);
  584.  
  585.     blendcntl = RADEONGetBlendCntl(op, PICT_a8r8g8b8);
  586.     OUT_ACCEL_REG(R300_RB3D_BLENDCNTL, blendcntl | R300_ALPHA_BLEND_ENABLE |
  587.                                        R300_READ_ENABLE);
  588.  
  589.     FINISH_ACCEL();
  590.  
  591.     safe_sti(ifl);
  592.  
  593.     return TRUE;
  594. }
  595.  
  596.  
  597. #define VTX_COUNT 4
  598.  
  599. static __inline__ u32_t F_TO_DW(float val)
  600. {
  601.     union {
  602.         float f;
  603.         u32_t l;
  604.     } tmp;
  605.     tmp.f = val;
  606.     return tmp.l;
  607. }
  608.  
  609. #define OUT_RING_F(x) OUT_RING(F_TO_DW(x))
  610.  
  611. #define VTX_OUT(_dstX, _dstY, _srcX, _srcY)     \
  612. do {                                            \
  613.     OUT_RING_F(_dstX);                          \
  614.     OUT_RING_F(_dstY);                          \
  615.     OUT_RING_F(_srcX);                          \
  616.     OUT_RING_F(_srcY);                          \
  617. } while (0)
  618.  
  619.  
  620.  
  621. static int R300CompositeTile(int srcX, int srcY,
  622.                                 int dstX, int dstY,
  623.                                 int w, int h)
  624. {
  625.   //  RINFO_FROM_SCREEN(pDst->drawable.pScreen);
  626.     int vtx_count;
  627.     xPointFixed srcTopLeft, srcTopRight, srcBottomLeft, srcBottomRight;
  628.     xPointFixed maskTopLeft, maskTopRight, maskBottomLeft, maskBottomRight;
  629.  
  630.     u32_t *ring;
  631.  
  632.     u32_t ifl;
  633.  
  634.  //   ACCEL_PREAMBLE();
  635.  
  636.  //   ENTER_DRAW(0);
  637.  
  638.     /* ErrorF("RadeonComposite (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n",
  639.        srcX, srcY, maskX, maskY,dstX, dstY, w, h); */
  640.  
  641.     srcTopLeft.x     = IntToxFixed(srcX);
  642.     srcTopLeft.y     = IntToxFixed(srcY);
  643.     srcTopRight.x    = IntToxFixed(srcX + w);
  644.     srcTopRight.y    = IntToxFixed(srcY);
  645.     srcBottomLeft.x  = IntToxFixed(srcX);
  646.     srcBottomLeft.y  = IntToxFixed(srcY + h);
  647.     srcBottomRight.x = IntToxFixed(srcX + w);
  648.     srcBottomRight.y = IntToxFixed(srcY + h);
  649.  
  650. /*
  651.     if (is_transform[0]) {
  652.         transformPoint(transform[0], &srcTopLeft);
  653.         transformPoint(transform[0], &srcTopRight);
  654.         transformPoint(transform[0], &srcBottomLeft);
  655.         transformPoint(transform[0], &srcBottomRight);
  656.     }
  657.     if (is_transform[1]) {
  658.         transformPoint(transform[1], &maskTopLeft);
  659.         transformPoint(transform[1], &maskTopRight);
  660.         transformPoint(transform[1], &maskBottomLeft);
  661.         transformPoint(transform[1], &maskBottomRight);
  662.     }
  663. */
  664.     vtx_count = VTX_COUNT;
  665.  
  666.  
  667.     ifl = safe_cli();
  668.  
  669.     BEGIN_RING(7 + 4 * vtx_count);
  670.  
  671.       OUT_ACCEL_REG(R300_VAP_VTX_SIZE, vtx_count);
  672.  
  673.       OUT_RING(CP_PACKET3(R200_CP_PACKET3_3D_DRAW_IMMD_2,
  674.                         4 * vtx_count));
  675.       OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN |
  676.               RADEON_CP_VC_CNTL_PRIM_WALK_RING |
  677.               (4 << RADEON_CP_VC_CNTL_NUM_SHIFT));
  678.  
  679.  
  680.       VTX_OUT((float)dstX, (float)dstY,
  681.               xFixedToFloat(srcTopLeft.x) / w,      // info->texW[0],
  682.               xFixedToFloat(srcTopLeft.y) / h);     // info->texH[0]);
  683.  
  684.       VTX_OUT((float)dstX, (float)(dstY + h),
  685.               xFixedToFloat(srcBottomLeft.x) / w,   // info->texW[0],
  686.               xFixedToFloat(srcBottomLeft.y) / h);  // info->texH[0]);
  687.  
  688.       VTX_OUT((float)(dstX + w), (float)(dstY + h),
  689.               xFixedToFloat(srcBottomRight.x) / w,  // info->texW[0],
  690.               xFixedToFloat(srcBottomRight.y) / h); // info->texH[0]);
  691.  
  692.       VTX_OUT((float)(dstX + w), (float)dstY,
  693.               xFixedToFloat(srcTopRight.x) / w,     // info->texW[0],
  694.               xFixedToFloat(srcTopRight.y) / h);    // info->texH[0]);
  695.  
  696.           /* flushing is pipelined, free/finish is not */
  697.       OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D);
  698.  
  699.  //     OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN);
  700.  
  701.     COMMIT_RING();
  702.  
  703.     safe_sti(ifl);
  704.  
  705.  //   LEAVE_DRAW(0);
  706. }
  707.  
  708.  
  709. static int R200CompositeTile(int srcX, int srcY,
  710.                              int dstX, int dstY,
  711.                              int w, int h)
  712. {
  713.     xPointFixed srcTopLeft, srcTopRight, srcBottomLeft, srcBottomRight;
  714.     xPointFixed maskTopLeft, maskTopRight, maskBottomLeft, maskBottomRight;
  715.  
  716.     srcTopLeft.x     = IntToxFixed(srcX);
  717.     srcTopLeft.y     = IntToxFixed(srcY);
  718.     srcTopRight.x    = IntToxFixed(srcX + w);
  719.     srcTopRight.y    = IntToxFixed(srcY);
  720.     srcBottomLeft.x  = IntToxFixed(srcX);
  721.     srcBottomLeft.y  = IntToxFixed(srcY + h);
  722.     srcBottomRight.x = IntToxFixed(srcX + w);
  723.     srcBottomRight.y = IntToxFixed(srcY + h);
  724.  
  725.     {
  726.         u32_t *ring;
  727.         u32_t  ifl = safe_cli();
  728.  
  729.         BEGIN_RING(4 + 4 * VTX_COUNT);
  730.  
  731.         OUT_RING(CP_PACKET3(R200_CP_PACKET3_3D_DRAW_IMMD_2, 4 * VTX_COUNT));
  732.         OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN |
  733.                  RADEON_CP_VC_CNTL_PRIM_WALK_RING |
  734.                 (4 << RADEON_CP_VC_CNTL_NUM_SHIFT));
  735.  
  736.  
  737.         VTX_OUT((float)dstX, (float)dstY,
  738.               xFixedToFloat(srcTopLeft.x) / w,      // info->texW[0],
  739.               xFixedToFloat(srcTopLeft.y) / h);     // info->texH[0]);
  740.  
  741.         VTX_OUT((float)dstX, (float)(dstY + h),
  742.               xFixedToFloat(srcBottomLeft.x) / w,   // info->texW[0],
  743.               xFixedToFloat(srcBottomLeft.y) / h);  // info->texH[0]);
  744.  
  745.         VTX_OUT((float)(dstX + w), (float)(dstY + h),
  746.               xFixedToFloat(srcBottomRight.x) / w,  // info->texW[0],
  747.               xFixedToFloat(srcBottomRight.y) / h); // info->texH[0]);
  748.  
  749.         VTX_OUT((float)(dstX + w), (float)dstY,
  750.               xFixedToFloat(srcTopRight.x) / w,     // info->texW[0],
  751.               xFixedToFloat(srcTopRight.y) / h);    // info->texH[0]);
  752.  
  753.         OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN);
  754.  
  755.         COMMIT_RING();
  756.         safe_sti(ifl);
  757.     };
  758. };
  759.  
  760. #undef VTX_OUT
  761. #undef VTX_OUT_MASK
  762.  
  763.  
  764. int RadeonComposite( io_blit_t *blit)
  765. {
  766.     int tileSrcY, tileMaskY, tileDstY;
  767.     int remainingHeight;
  768.  
  769.     local_pixmap_t *srcpixmap;
  770.     local_pixmap_t *dstpixmap;
  771.  
  772.     dbgprintf("Blit Alpha src: %x dst: %x\n",blit->srcpix, blit->dstpix);
  773.  
  774.     dstpixmap = (blit->dstpix == (void*)-1) ? &scr_pixmap : blit->dstpix ;
  775.     srcpixmap = (blit->srcpix == (void*)-1) ? &scr_pixmap : blit->srcpix ;
  776.  
  777.     {
  778.         u32_t *ring;
  779.         u32_t ifl = safe_cli();
  780.  
  781.         BEGIN_RING(2 + 6);
  782.  
  783.         CP_REG(R5XX_DP_WRITE_MASK, 0xFF000000);
  784.  
  785.         OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4));
  786.  
  787.         OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL  |
  788.                  RADEON_GMC_BRUSH_SOLID_COLOR      |
  789.                  RADEON_GMC_DST_32BPP              |
  790.                  RADEON_GMC_SRC_DATATYPE_COLOR     |
  791.                  R5XX_GMC_CLR_CMP_CNTL_DIS         |
  792.                  R5XX_ROP3_P
  793.                 );
  794.  
  795.         OUT_RING(srcpixmap->pitch_offset);
  796.         OUT_RING(blit->alpha<<24);
  797.         OUT_RING( 0 );
  798.         OUT_RING((srcpixmap->width<<16)|srcpixmap->height);
  799.  
  800.         COMMIT_RING();
  801.  
  802.         RHDPtr info = &rhd;
  803.  
  804.         if( IS_R300_3D || IS_R500_3D )
  805.         {
  806.             R300PrepareComposite(dstpixmap, blit->dst_x, blit->dst_y,
  807.                                  srcpixmap, blit->src_x, blit->src_y,
  808.                                  blit->w, blit->h, 3);
  809.  
  810. //    if (!need_src_tile_x && !need_src_tile_y) {
  811.             R300CompositeTile( blit->src_x, blit->src_y,
  812.                                blit->dst_x, blit->dst_y,
  813.                                blit->w, blit->h);
  814.         }
  815.         else if ((info->ChipFamily == CHIP_FAMILY_RV250) ||
  816.                  (info->ChipFamily == CHIP_FAMILY_RV280) ||
  817.                  (info->ChipFamily == CHIP_FAMILY_RS300) ||
  818.                  (info->ChipFamily == CHIP_FAMILY_R200))
  819.         {
  820.             R200PrepareComposite(dstpixmap, blit->dst_x, blit->dst_y,
  821.                                  srcpixmap, blit->src_x, blit->src_y,
  822.                                  blit->w, blit->h, blit->alpha);
  823.             R200CompositeTile( blit->src_x, blit->src_y,
  824.                                blit->dst_x, blit->dst_y,
  825.                                blit->w, blit->h);
  826.         };
  827.  
  828.  
  829.         safe_sti(ifl);
  830.     };
  831.  
  832.  
  833.  
  834.        return 0;
  835.   //  }
  836.  
  837.     /* Tiling logic borrowed from exaFillRegionTiled */
  838.  
  839. #if 0
  840.     modulus(srcY, src_tile_height, tileSrcY);
  841.     tileMaskY = maskY;
  842.     tileDstY = dstY;
  843.  
  844.     remainingHeight = height;
  845.     while (remainingHeight > 0) {
  846.         int remainingWidth = width;
  847.         int tileSrcX, tileMaskX, tileDstX;
  848.         int h = src_tile_height - tileSrcY;
  849.  
  850.         if (h > remainingHeight)
  851.             h = remainingHeight;
  852.         remainingHeight -= h;
  853.  
  854.         modulus(srcX, src_tile_width, tileSrcX);
  855.         tileMaskX = maskX;
  856.         tileDstX = dstX;
  857.  
  858.         while (remainingWidth > 0) {
  859.             int w = src_tile_width - tileSrcX;
  860.             if (w > remainingWidth)
  861.                 w = remainingWidth;
  862.             remainingWidth -= w;
  863.  
  864.             FUNC_NAME(RadeonCompositeTile)(pDst,
  865.                                            tileSrcX, tileSrcY,
  866.                                            tileMaskX, tileMaskY,
  867.                                            tileDstX, tileDstY,
  868.                                            w, h);
  869.  
  870.             tileSrcX = 0;
  871.             tileMaskX += w;
  872.             tileDstX += w;
  873.         }
  874.         tileSrcY = 0;
  875.         tileMaskY += h;
  876.         tileDstY += h;
  877.     }
  878. #endif
  879.  
  880. }
  881.