Subversion Repositories Kolibri OS

Rev

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.  
  38. static Bool R300TextureSetup(RHDPtr info,local_pixmap_t *srcpix, int w, int h, int unit)
  39. {
  40.     u32_t txfilter, txformat0, txformat1, txoffset, txpitch;
  41.  
  42.     int i, pixel_shift;
  43.  
  44.  
  45.     txpitch = srcpix->pitch;
  46.     txoffset = (u32_t)srcpix->local;
  47.  
  48.     if ((txoffset & 0x1f) != 0)
  49.         dbgprintf("Bad texture offset 0x%x\n", (int)txoffset);
  50.     if ((txpitch & 0x1f) != 0)
  51.         dbgprintf("Bad texture pitch 0x%x\n", (int)txpitch);
  52.  
  53.     /* TXPITCH = pixels (texels) per line - 1 */
  54.     pixel_shift = 32 >> 4;
  55.     txpitch >>= pixel_shift;
  56.     txpitch -= 1;
  57.  
  58.     txformat1 = R300_TX_FORMAT_A8R8G8B8;
  59.  
  60.     txformat0 = ((((w - 1) & 0x7ff) << R300_TXWIDTH_SHIFT) |
  61.                  (((h - 1) & 0x7ff) << R300_TXHEIGHT_SHIFT));
  62.  
  63.     if (IS_R500_3D && ((w - 1) & 0x800))
  64.         txpitch |= R500_TXWIDTH_11;
  65.  
  66.     if (IS_R500_3D && ((h - 1) & 0x800))
  67.         txpitch |= R500_TXHEIGHT_11;
  68.  
  69.     /* Use TXPITCH instead of TXWIDTH for address computations: we could
  70.      * omit this if there is no padding, but there is no apparent advantage
  71.      * in doing so.
  72.      */
  73.     txformat0 |= R300_TXPITCH_EN;
  74.  
  75.     txfilter = R300_TX_CLAMP_S(R300_TX_CLAMP_CLAMP_GL);
  76.  
  77.     txfilter |= R300_TX_CLAMP_T(R300_TX_CLAMP_CLAMP_GL);
  78.  
  79.     txfilter |= (unit << R300_TX_ID_SHIFT);
  80.  
  81.         txfilter |= (R300_TX_MAG_FILTER_NEAREST | R300_TX_MIN_FILTER_NEAREST);
  82.  
  83.  
  84.     {
  85.         u32_t *ring;
  86.  
  87.         BEGIN_ACCEL(7);
  88.  
  89.         OUT_ACCEL_REG(R300_TX_FILTER0_0 + (unit * 4), txfilter);
  90.         OUT_ACCEL_REG(R300_TX_FILTER1_0 + (unit * 4), 0);
  91.         OUT_ACCEL_REG(R300_TX_FORMAT0_0 + (unit * 4), txformat0);
  92.         OUT_ACCEL_REG(R300_TX_FORMAT1_0 + (unit * 4), txformat1);
  93.         OUT_ACCEL_REG(R300_TX_FORMAT2_0 + (unit * 4), txpitch);
  94.         OUT_ACCEL_REG(R300_TX_OFFSET_0 + (unit * 4), txoffset);
  95. //    if (!pPict->repeat)
  96.         OUT_ACCEL_REG(R300_TX_BORDER_COLOR_0 + (unit * 4), 0);
  97.  
  98.         COMMIT_RING();
  99.     }
  100.  
  101.     return TRUE;
  102. }
  103.  
  104. static u32_t RADEONGetBlendCntl(int op, u32_t dst_format)
  105. {
  106.     u32_t sblend, dblend;
  107.  
  108.  
  109.     return RADEON_SRC_BLEND_GL_SRC_ALPHA | RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA;
  110. }
  111.  
  112.  
  113. Bool R300PrepareComposite(local_pixmap_t *dstpix, int dstX, int dstY,
  114.                           local_pixmap_t *srcpix, int srcX, int srcY,
  115.                           int w, int h, int op)
  116. {
  117.     u32_t dst_format, dst_offset, dst_pitch;
  118.     u32_t txenable, colorpitch;
  119.     u32_t blendcntl;
  120.     int pixel_shift;
  121.     u32_t *ring;
  122.  
  123.     RHDPtr info = &rhd;
  124.  
  125.     dst_format = R300_COLORFORMAT_ARGB8888;
  126.  
  127.     dst_offset = (u32_t)dstpix->local;
  128.  
  129.     dst_pitch = dstpix->pitch;
  130.  
  131.     pixel_shift = 32 >> 4;
  132.  
  133.     colorpitch = dst_pitch >> pixel_shift;
  134.  
  135.     colorpitch |= dst_format;
  136.  
  137.     if ((dst_offset & 0x0f) != 0)
  138.         dbgprintf("Bad destination offset 0x%x\n", (int)dst_offset);
  139.     if (((dst_pitch >> pixel_shift) & 0x7) != 0)
  140.         dbgprintf("Bad destination pitch 0x%x\n", (int)dst_pitch);
  141.  
  142.  
  143.     if (!R300TextureSetup(&rhd, srcpix, w, h, 0))
  144.         return FALSE;
  145.  
  146.     txenable = R300_TEX_0_ENABLE;
  147.  
  148.   //  RADEON_SWITCH_TO_3D();
  149.  
  150.     /* setup the VAP */
  151.  
  152.     BEGIN_ACCEL(7);
  153.  
  154.     /* These registers define the number, type, and location of data submitted
  155.      * to the PVS unit of GA input (when PVS is disabled)
  156.      * DST_VEC_LOC is the slot in the PVS input vector memory when PVS/TCL is
  157.      * enabled.  This memory provides the imputs to the vertex shader program
  158.      * and ordering is not important.  When PVS/TCL is disabled, this field maps
  159.      * directly to the GA input memory and the order is signifigant.  In
  160.      * PVS_BYPASS mode the order is as follows:
  161.      * 0 Position
  162.      * 1 Point Size
  163.      * 2 Color 0
  164.      * 3 Color 1
  165.      * 4 Color 2
  166.      * 5 Color 3
  167.      * 6 Textures 0
  168.      * 7 Textures 1
  169.      * 8 Textures 2
  170.      * 9 Textures 3 - 7
  171.      * 14 Fog
  172.      */
  173.  
  174.      OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_0,
  175.                    ((R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_0_SHIFT) |
  176.                     (0 << R300_SKIP_DWORDS_0_SHIFT) |
  177.                     (0 << R300_DST_VEC_LOC_0_SHIFT) |
  178.                      R300_SIGNED_0 |
  179.                     (R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_1_SHIFT) |
  180.                     (0 << R300_SKIP_DWORDS_1_SHIFT) |
  181.                     (6 << R300_DST_VEC_LOC_1_SHIFT) |
  182.                      R300_LAST_VEC_1 |
  183.                      R300_SIGNED_1));
  184.  
  185.     /* load the vertex shader
  186.      * We pre-load vertex programs in RADEONInit3DEngine():
  187.      * - exa no mask
  188.      * - exa mask
  189.      * - Xv
  190.      * Here we select the offset of the vertex program we want to use
  191.      */
  192.     if (info->has_tcl) {
  193.             OUT_ACCEL_REG(R300_VAP_PVS_CODE_CNTL_0,
  194.                      ((3 << R300_PVS_FIRST_INST_SHIFT) |
  195.                       (4 << R300_PVS_XYZW_VALID_INST_SHIFT) |
  196.                       (4 << R300_PVS_LAST_INST_SHIFT)));
  197.             OUT_ACCEL_REG(R300_VAP_PVS_CODE_CNTL_1,
  198.                       (4 << R300_PVS_LAST_VTX_SRC_INST_SHIFT));
  199.     }
  200.  
  201.     /* Position and one or two sets of 2 texture coordinates */
  202.     OUT_ACCEL_REG(R300_VAP_OUT_VTX_FMT_0, R300_VTX_POS_PRESENT);   //VTX_COLOR_0_PRESENT
  203.     OUT_ACCEL_REG(R300_VAP_OUT_VTX_FMT_1, (2 << R300_TEX_0_COMP_CNT_SHIFT));
  204.  
  205.     OUT_ACCEL_REG(R300_TX_INVALTAGS, 0x0);
  206.     OUT_ACCEL_REG(R300_TX_ENABLE, txenable);
  207.     FINISH_ACCEL();
  208.  
  209.     /* setup pixel shader */
  210.  
  211.  
  212.     /* setup pixel shader */
  213.     if (IS_R300_3D)
  214.     {
  215.         u32_t output_fmt;
  216.         int src_color, src_alpha;
  217.         int mask_color, mask_alpha;
  218.  
  219.             src_color = R300_ALU_RGB_SRC0_RGB;
  220.  
  221.             src_alpha = R300_ALU_ALPHA_SRC0_A;
  222.  
  223.             mask_color = R300_ALU_RGB_1_0;
  224.             mask_alpha = R300_ALU_ALPHA_1_0;
  225.  
  226.         /* shader output swizzling */
  227.         output_fmt = (R300_OUT_FMT_C4_8 |
  228.                       R300_OUT_FMT_C0_SEL_BLUE |
  229.                       R300_OUT_FMT_C1_SEL_GREEN |
  230.                       R300_OUT_FMT_C2_SEL_RED |
  231.                       R300_OUT_FMT_C3_SEL_ALPHA);
  232.  
  233.  
  234.         /* setup the rasterizer, load FS */
  235.         BEGIN_ACCEL(10);
  236.             /* 2 components: 2 for tex0 */
  237.             OUT_ACCEL_REG(R300_RS_COUNT,
  238.                       ((2 << R300_RS_COUNT_IT_COUNT_SHIFT) |
  239.                         R300_RS_COUNT_HIRES_EN));
  240.  
  241.             OUT_ACCEL_REG(R300_RS_INST_COUNT, R300_INST_COUNT_RS(0) | R300_TX_OFFSET_RS(6));
  242.  
  243.             OUT_ACCEL_REG(R300_US_CODE_OFFSET, (R300_ALU_CODE_OFFSET(0) |
  244.                         R300_ALU_CODE_SIZE(0)   |
  245.                                                 R300_TEX_CODE_OFFSET(0) |
  246.                                                 R300_TEX_CODE_SIZE(0)));
  247.  
  248.             OUT_ACCEL_REG(R300_US_CODE_ADDR_3,
  249.                           (R300_ALU_START(0) |
  250.                R300_ALU_SIZE(0)  |
  251.                            R300_TEX_START(0) |
  252.                R300_TEX_SIZE(0)  |
  253.                            R300_RGBA_OUT));
  254.  
  255. //        OUT_ACCEL_REG(R300_US_PIXSIZE, 1); /* highest temp used */
  256.         /* shader output swizzling */
  257.         OUT_ACCEL_REG(R300_US_OUT_FMT_0, output_fmt);
  258.  
  259.         /* tex inst for src texture is pre-loaded in RADEONInit3DEngine() */
  260.         /* tex inst for mask texture is pre-loaded in RADEONInit3DEngine() */
  261.  
  262.         /* RGB inst
  263.          * temp addresses for texture inputs
  264.          * ALU_RGB_ADDR0 is src tex (temp 0)
  265.          * ALU_RGB_ADDR1 is mask tex (temp 1)
  266.          * R300_ALU_RGB_OMASK - output components to write
  267.          * R300_ALU_RGB_TARGET_A - render target
  268.          */
  269.         OUT_ACCEL_REG(R300_US_ALU_RGB_ADDR(0),
  270.                      (R300_ALU_RGB_ADDR0(0) |
  271.                       R300_ALU_RGB_ADDR1(1) |
  272.                       R300_ALU_RGB_ADDR2(0) |
  273.                       R300_ALU_RGB_ADDRD(0) |
  274.                       R300_ALU_RGB_OMASK((R300_ALU_RGB_MASK_R |
  275.                                           R300_ALU_RGB_MASK_G |
  276.                                           R300_ALU_RGB_MASK_B)) |
  277.                       R300_ALU_RGB_TARGET_A));
  278.         /* RGB inst
  279.          * ALU operation
  280.          */
  281.         OUT_ACCEL_REG(R300_US_ALU_RGB_INST(0),
  282.                  (R300_ALU_RGB_SEL_A(src_color) |
  283.                   R300_ALU_RGB_MOD_A(R300_ALU_RGB_MOD_NOP) |
  284.                   R300_ALU_RGB_SEL_B(mask_color) |
  285.                   R300_ALU_RGB_MOD_B(R300_ALU_RGB_MOD_NOP) |
  286.                   R300_ALU_RGB_SEL_C(R300_ALU_RGB_0_0) |
  287.                   R300_ALU_RGB_MOD_C(R300_ALU_RGB_MOD_NOP) |
  288.                   R300_ALU_RGB_OP(R300_ALU_RGB_OP_MAD) |
  289.                   R300_ALU_RGB_OMOD(R300_ALU_RGB_OMOD_NONE) |
  290.                   R300_ALU_RGB_CLAMP));
  291.         /* Alpha inst
  292.          * temp addresses for texture inputs
  293.          * ALU_ALPHA_ADDR0 is src tex (0)
  294.          * ALU_ALPHA_ADDR1 is mask tex (1)
  295.          * R300_ALU_ALPHA_OMASK - output components to write
  296.          * R300_ALU_ALPHA_TARGET_A - render target
  297.          */
  298.         OUT_ACCEL_REG(R300_US_ALU_ALPHA_ADDR(0),
  299.                  (R300_ALU_ALPHA_ADDR0(0) |
  300.                   R300_ALU_ALPHA_ADDR1(1) |
  301.                   R300_ALU_ALPHA_ADDR2(0) |
  302.                   R300_ALU_ALPHA_ADDRD(0) |
  303.                   R300_ALU_ALPHA_OMASK(R300_ALU_ALPHA_MASK_A) |
  304.                   R300_ALU_ALPHA_TARGET_A |
  305.                   R300_ALU_ALPHA_OMASK_W(R300_ALU_ALPHA_MASK_NONE)));
  306.         /* Alpha inst
  307.          * ALU operation
  308.          */
  309.         OUT_ACCEL_REG(R300_US_ALU_ALPHA_INST(0),
  310.                  (R300_ALU_ALPHA_SEL_A(src_alpha) |
  311.                   R300_ALU_ALPHA_MOD_A(R300_ALU_ALPHA_MOD_NOP) |
  312.                   R300_ALU_ALPHA_SEL_B(mask_alpha) |
  313.                   R300_ALU_ALPHA_MOD_B(R300_ALU_ALPHA_MOD_NOP) |
  314.                   R300_ALU_ALPHA_SEL_C(R300_ALU_ALPHA_0_0) |
  315.                   R300_ALU_ALPHA_MOD_C(R300_ALU_ALPHA_MOD_NOP) |
  316.                   R300_ALU_ALPHA_OP(R300_ALU_ALPHA_OP_MAD) |
  317.                   R300_ALU_ALPHA_OMOD(R300_ALU_ALPHA_OMOD_NONE) |
  318.                   R300_ALU_ALPHA_CLAMP));
  319.     FINISH_ACCEL();
  320.     }
  321.     else
  322.     {
  323.         u32_t output_fmt;
  324.         u32_t src_color, src_alpha;
  325.         u32_t mask_color, mask_alpha;
  326.  
  327.             src_color = (R500_ALU_RGB_R_SWIZ_A_R |
  328.                      R500_ALU_RGB_G_SWIZ_A_G |
  329.                      R500_ALU_RGB_B_SWIZ_A_B);
  330.  
  331.             src_alpha = R500_ALPHA_SWIZ_A_A;
  332.  
  333.         mask_color = (R500_ALU_RGB_R_SWIZ_B_1 |
  334.                       R500_ALU_RGB_G_SWIZ_B_1 |
  335.                       R500_ALU_RGB_B_SWIZ_B_1);
  336.         mask_alpha = R500_ALPHA_SWIZ_B_1;
  337.  
  338.         /* shader output swizzling */
  339.         output_fmt = (R300_OUT_FMT_C4_8         |
  340.                       R300_OUT_FMT_C0_SEL_BLUE  |
  341.                       R300_OUT_FMT_C1_SEL_GREEN |
  342.                       R300_OUT_FMT_C2_SEL_RED   |
  343.                       R300_OUT_FMT_C3_SEL_ALPHA);
  344.  
  345.     BEGIN_ACCEL(6);
  346.         OUT_ACCEL_REG(R300_RS_COUNT,
  347.                      ((2 << R300_RS_COUNT_IT_COUNT_SHIFT) |
  348.                        R300_RS_COUNT_HIRES_EN));
  349.  
  350.         OUT_ACCEL_REG(R300_RS_INST_COUNT, R300_INST_COUNT_RS(0) | R300_TX_OFFSET_RS(6));
  351.  
  352.         OUT_ACCEL_REG(R500_US_CODE_ADDR, (R500_US_CODE_START_ADDR(0) |
  353.                                           R500_US_CODE_END_ADDR(1)));
  354.         OUT_ACCEL_REG(R500_US_CODE_RANGE, (R500_US_CODE_RANGE_ADDR(0) |
  355.                                            R500_US_CODE_RANGE_SIZE(1)));
  356.         OUT_ACCEL_REG(R500_US_CODE_OFFSET, 0);
  357.  
  358.         OUT_ACCEL_REG(R300_US_OUT_FMT_0, output_fmt);
  359.         COMMIT_RING();
  360.  
  361.         BEGIN_ACCEL(13);
  362.         OUT_ACCEL_REG(R500_GA_US_VECTOR_INDEX, 0);
  363.             /* tex inst for src texture */
  364.         OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_INST_TYPE_TEX     |
  365.                                                R500_INST_TEX_SEM_WAIT |
  366.                                                R500_INST_RGB_WMASK_R  |
  367.                                                R500_INST_RGB_WMASK_G  |
  368.                                                R500_INST_RGB_WMASK_B  |
  369.                                                R500_INST_ALPHA_WMASK  |
  370.                                                R500_INST_RGB_CLAMP |
  371.                                                R500_INST_ALPHA_CLAMP));
  372.  
  373.        OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_TEX_ID(0) |
  374.                                                    R500_TEX_INST_LD |
  375.                                                    R500_TEX_SEM_ACQUIRE |
  376.                                                    R500_TEX_IGNORE_UNCOVERED));
  377.  
  378.             OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_TEX_SRC_ADDR(0) |
  379.                                                    R500_TEX_SRC_S_SWIZ_R |
  380.                                                    R500_TEX_SRC_T_SWIZ_G |
  381.                                                    R500_TEX_DST_ADDR(0) |
  382.                                                    R500_TEX_DST_R_SWIZ_R |
  383.                                                    R500_TEX_DST_G_SWIZ_G |
  384.                                                    R500_TEX_DST_B_SWIZ_B |
  385.                                                    R500_TEX_DST_A_SWIZ_A));
  386.             OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_DX_ADDR(0) |
  387.                                                    R500_DX_S_SWIZ_R |
  388.                                                    R500_DX_T_SWIZ_R |
  389.                                                    R500_DX_R_SWIZ_R |
  390.                                                    R500_DX_Q_SWIZ_R |
  391.                                                    R500_DY_ADDR(0) |
  392.                                                    R500_DY_S_SWIZ_R |
  393.                                                    R500_DY_T_SWIZ_R |
  394.                                                    R500_DY_R_SWIZ_R |
  395.                                                    R500_DY_Q_SWIZ_R));
  396.             OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, 0x00000000);
  397.             OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, 0x00000000);
  398.  
  399.         /* ALU inst */
  400.         /* *_OMASK* - output component write mask */
  401.         OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_INST_TYPE_OUT |
  402.                                                R500_INST_TEX_SEM_WAIT |
  403.                                                R500_INST_LAST |
  404.                                                R500_INST_RGB_OMASK_R |
  405.                                                R500_INST_RGB_OMASK_G |
  406.                                                R500_INST_RGB_OMASK_B |
  407.                                                R500_INST_ALPHA_OMASK |
  408.                                                R500_INST_RGB_CLAMP |
  409.                                                R500_INST_ALPHA_CLAMP));
  410.         /* ALU inst
  411.          * temp addresses for texture inputs
  412.          * RGB_ADDR0 is src tex (temp 0)
  413.          * RGB_ADDR1 is mask tex (temp 1)
  414.          */
  415.         OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_RGB_ADDR0(0) |
  416.                                                R500_RGB_ADDR1(1) |
  417.                                                R500_RGB_ADDR2(0)));
  418.         /* ALU inst
  419.          * temp addresses for texture inputs
  420.          * ALPHA_ADDR0 is src tex (temp 0)
  421.          * ALPHA_ADDR1 is mask tex (temp 1)
  422.          */
  423.        OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_ALPHA_ADDR0(0) |
  424.                                                R500_ALPHA_ADDR1(1) |
  425.                                                R500_ALPHA_ADDR2(0)));
  426.  
  427.         /* R500_ALU_RGB_TARGET - RGB render target */
  428.        OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_ALU_RGB_SEL_A_SRC0 |
  429.                                                src_color |
  430.                                                R500_ALU_RGB_SEL_B_SRC1 |
  431.                                                mask_color |
  432.                                                R500_ALU_RGB_TARGET(0)));
  433.  
  434.         /* R500_ALPHA_RGB_TARGET - alpha render target */
  435.        OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_ALPHA_OP_MAD |
  436.                                                R500_ALPHA_ADDRD(0) |
  437.                                                R500_ALPHA_SEL_A_SRC0 |
  438.                                                src_alpha |
  439.                                                R500_ALPHA_SEL_B_SRC1 |
  440.                                                mask_alpha |
  441.                                                R500_ALPHA_TARGET(0)));
  442.  
  443.        OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_ALU_RGBA_OP_MAD |
  444.                                                R500_ALU_RGBA_ADDRD(0) |
  445.                                                R500_ALU_RGBA_R_SWIZ_0 |
  446.                                                R500_ALU_RGBA_G_SWIZ_0 |
  447.                                                R500_ALU_RGBA_B_SWIZ_0 |
  448.                                                R500_ALU_RGBA_A_SWIZ_0));
  449.         FINISH_ACCEL();
  450.     }
  451.  
  452.     BEGIN_ACCEL(3);
  453.     OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset);
  454.     OUT_ACCEL_REG(R300_RB3D_COLORPITCH0, colorpitch);
  455.  
  456.     blendcntl = RADEONGetBlendCntl(op, PICT_a8r8g8b8);
  457.     OUT_ACCEL_REG(R300_RB3D_BLENDCNTL, blendcntl | R300_ALPHA_BLEND_ENABLE |
  458.                                        R300_READ_ENABLE);
  459.  
  460.     FINISH_ACCEL();
  461.  
  462.     return TRUE;
  463. }
  464.  
  465.  
  466. #define VTX_COUNT 4
  467.  
  468. static __inline__ u32_t F_TO_DW(float val)
  469. {
  470.     union {
  471.       float f;
  472.       u32_t l;
  473.     }tmp;
  474.     tmp.f = val;
  475.     return tmp.l;
  476. }
  477.  
  478. #if R300_PIO
  479.  
  480. #define OUT_ACCEL_REG_F(reg, val) OUTREG(reg, F_TO_DW(val))
  481.  
  482. #define VTX_OUT(_dstX, _dstY, _srcX, _srcY) \
  483. do {                                                            \
  484.     OUT_ACCEL_REG_F(RADEON_SE_PORT_DATA0, _dstX);               \
  485.     OUT_ACCEL_REG_F(RADEON_SE_PORT_DATA0, _dstY);               \
  486.     OUT_ACCEL_REG_F(RADEON_SE_PORT_DATA0, _srcX);               \
  487.     OUT_ACCEL_REG_F(RADEON_SE_PORT_DATA0, _srcY);               \
  488. } while (0)
  489.  
  490. #else
  491.  
  492. #define OUT_RING_F(x) OUT_RING(F_TO_DW(x))
  493.  
  494. #define VTX_OUT(_dstX, _dstY, _srcX, _srcY)     \
  495. do {                                            \
  496.     OUT_RING_F(_dstX);                          \
  497.     OUT_RING_F(_dstY);                          \
  498.     OUT_RING_F(_srcX);                          \
  499.     OUT_RING_F(_srcY);                          \
  500. } while (0)
  501.  
  502. #endif
  503.  
  504. static int R300CompositeTile(int srcX, int srcY,
  505.                                 int dstX, int dstY,
  506.                                 int w, int h)
  507. {
  508.     int vtx_count;
  509.     xPointFixed srcTopLeft, srcTopRight, srcBottomLeft, srcBottomRight;
  510.     xPointFixed maskTopLeft, maskTopRight, maskBottomLeft, maskBottomRight;
  511.  
  512.     RHDPtr info = &rhd;
  513.  
  514.     u32_t *ring;
  515.  
  516.     srcTopLeft.x     = IntToxFixed(srcX);
  517.     srcTopLeft.y     = IntToxFixed(srcY);
  518.     srcTopRight.x    = IntToxFixed(srcX + w);
  519.     srcTopRight.y    = IntToxFixed(srcY);
  520.     srcBottomLeft.x  = IntToxFixed(srcX);
  521.     srcBottomLeft.y  = IntToxFixed(srcY + h);
  522.     srcBottomRight.x = IntToxFixed(srcX + w);
  523.     srcBottomRight.y = IntToxFixed(srcY + h);
  524.  
  525.     vtx_count = VTX_COUNT;
  526.  
  527. #if R300_PIO
  528.  
  529.     BEGIN_ACCEL(6 + vtx_count * 4);
  530.     OUT_ACCEL_REG(R300_VAP_VTX_SIZE, vtx_count);
  531.     OUT_ACCEL_REG(RADEON_SE_VF_CNTL,
  532.                   (RADEON_VF_PRIM_TYPE_QUAD_LIST |
  533.                    RADEON_VF_PRIM_WALK_DATA |
  534.                    (4 << RADEON_VF_NUM_VERTICES_SHIFT)));
  535.  
  536. #else
  537.     BEGIN_ACCEL(7 + 4 * vtx_count);
  538.     OUT_ACCEL_REG(R300_VAP_VTX_SIZE, vtx_count);
  539.  
  540.     OUT_RING(CP_PACKET3(R200_CP_PACKET3_3D_DRAW_IMMD_2,
  541.                         4 * vtx_count));
  542.     OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN |
  543.               RADEON_CP_VC_CNTL_PRIM_WALK_RING |
  544.               (4 << RADEON_CP_VC_CNTL_NUM_SHIFT));
  545.  
  546. #endif
  547.  
  548.       VTX_OUT((float)dstX, (float)dstY,
  549.               xFixedToFloat(srcTopLeft.x) / w,      // info->texW[0],
  550.               xFixedToFloat(srcTopLeft.y) / h);     // info->texH[0]);
  551.  
  552.       VTX_OUT((float)dstX, (float)(dstY + h),
  553.               xFixedToFloat(srcBottomLeft.x) / w,   // info->texW[0],
  554.               xFixedToFloat(srcBottomLeft.y) / h);  // info->texH[0]);
  555.  
  556.       VTX_OUT((float)(dstX + w), (float)(dstY + h),
  557.               xFixedToFloat(srcBottomRight.x) / w,  // info->texW[0],
  558.               xFixedToFloat(srcBottomRight.y) / h); // info->texH[0]);
  559.  
  560.       VTX_OUT((float)(dstX + w), (float)dstY,
  561.               xFixedToFloat(srcTopRight.x) / w,     // info->texW[0],
  562.               xFixedToFloat(srcTopRight.y) / h);    // info->texH[0]);
  563.  
  564.           /* flushing is pipelined, free/finish is not */
  565.       OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D);
  566.       OUT_ACCEL_REG(R300_SC_CLIP_RULE, 0xAAAA);
  567.       OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_RB3D_DC_FLUSH_ALL);
  568.       OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN);
  569.  
  570.     COMMIT_RING();
  571. }
  572.  
  573.  
  574. #undef VTX_OUT
  575. #undef VTX_OUT_MASK
  576.  
  577.  
  578. int RadeonComposite( io_blit_t *blit)
  579. {
  580.     int tileSrcY, tileMaskY, tileDstY;
  581.     int remainingHeight;
  582.  
  583.     local_pixmap_t *srcpixmap;
  584.     local_pixmap_t *dstpixmap;
  585.  
  586.     dbgprintf("Blit Alpha src: %x dst: %x\n",blit->srcpix, blit->dstpix);
  587.  
  588.     dstpixmap = (blit->dstpix == (void*)-1) ? &scr_pixmap : blit->dstpix ;
  589.     srcpixmap = (blit->srcpix == (void*)-1) ? &scr_pixmap : blit->srcpix ;
  590.  
  591.     lock_device();
  592.  
  593.     {
  594.         u32_t *ring;
  595.  
  596. #if R300_PIO
  597.  
  598.         FIFOWait(10);
  599.  
  600.         OUTREG(R5XX_DP_GUI_MASTER_CNTL,
  601.             RADEON_GMC_DST_PITCH_OFFSET_CNTL  |
  602.             RADEON_GMC_BRUSH_SOLID_COLOR      |
  603.             RADEON_GMC_DST_32BPP              |
  604.             RADEON_GMC_SRC_DATATYPE_COLOR     |
  605.             R5XX_GMC_CLR_CMP_CNTL_DIS         |
  606.             R5XX_ROP3_P
  607.            );
  608.  
  609.         OUTREG(R5XX_DST_PITCH_OFFSET, srcpixmap->pitch_offset);
  610.         OUTREG(R5XX_DP_BRUSH_FRGD_CLR, blit->alpha<<24);
  611.         OUTREG(R5XX_DP_WRITE_MASK, 0xFF000000);
  612.         OUTREG(R5XX_DP_CNTL, R5XX_DST_X_LEFT_TO_RIGHT | R5XX_DST_Y_TOP_TO_BOTTOM);
  613.         OUTREG(R5XX_DST_Y_X, 0);
  614.         OUTREG(R5XX_DST_WIDTH_HEIGHT,(srcpixmap->width<<16)|srcpixmap->height);
  615.  
  616.         OUTREG( RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN
  617.                                   | RADEON_WAIT_HOST_IDLECLEAN );
  618.  
  619.         OUTREG(R5XX_DP_WRITE_MASK, 0xFFFFFFFF);
  620.         OUTREG(RADEON_WAIT_UNTIL, RADEON_WAIT_HOST_IDLECLEAN |
  621.                                   RADEON_WAIT_2D_IDLECLEAN);
  622.  
  623. #else
  624.         BEGIN_RING(2 + 6);
  625.  
  626.         CP_REG(R5XX_DP_WRITE_MASK, 0xFF000000);
  627.  
  628.         OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4));
  629.  
  630.         OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL  |
  631.                  RADEON_GMC_BRUSH_SOLID_COLOR      |
  632.                  RADEON_GMC_DST_32BPP              |
  633.                  RADEON_GMC_SRC_DATATYPE_COLOR     |
  634.                  R5XX_GMC_CLR_CMP_CNTL_DIS         |
  635.                  R5XX_ROP3_P
  636.                 );
  637.  
  638.         OUT_RING(srcpixmap->pitch_offset);
  639.         OUT_RING(blit->alpha<<24);
  640.         OUT_RING( 0 );
  641.         OUT_RING((srcpixmap->width<<16)|srcpixmap->height);
  642.  
  643.         COMMIT_RING();
  644. #endif
  645.         RHDPtr info = &rhd;
  646.  
  647.         FIFOWait(64);
  648.         delay(2);
  649.  
  650.         if( IS_R300_3D || IS_R500_3D )
  651.         {
  652.             R300PrepareComposite(dstpixmap, blit->dst_x, blit->dst_y,
  653.                                  srcpixmap, blit->src_x, blit->src_y,
  654.                                  blit->w, blit->h, 3);
  655.  
  656.             R300CompositeTile( blit->src_x, blit->src_y,
  657.                                blit->dst_x, blit->dst_y,
  658.                                blit->w, blit->h);
  659.         }
  660.         else if ((info->ChipFamily == CHIP_FAMILY_RV250) ||
  661.                  (info->ChipFamily == CHIP_FAMILY_RV280) ||
  662.                  (info->ChipFamily == CHIP_FAMILY_RS300) ||
  663.                  (info->ChipFamily == CHIP_FAMILY_R200))
  664.         {
  665.         };
  666.  
  667.     };
  668.  
  669.     FIFOWait(64);
  670.     delay(2);
  671.  
  672.     unlock_device();
  673.  
  674.     return 0;
  675. };
  676.  
  677.  
  678.