diff options
-rw-r--r-- | src/radeon_reg.h | 15 | ||||
-rw-r--r-- | src/radeon_textured_video.c | 89 | ||||
-rw-r--r-- | src/radeon_textured_videofuncs.c | 226 | ||||
-rw-r--r-- | src/radeon_video.h | 5 |
4 files changed, 305 insertions, 30 deletions
diff --git a/src/radeon_reg.h b/src/radeon_reg.h index 0af88597..247a0e7d 100644 --- a/src/radeon_reg.h +++ b/src/radeon_reg.h @@ -4406,6 +4406,7 @@ #define R300_TX_INVALTAGS 0x4100 #define R300_TX_FILTER0_0 0x4400 #define R300_TX_FILTER0_1 0x4404 +#define R300_TX_FILTER0_2 0x4408 # define R300_TX_CLAMP_S(x) ((x) << 0) # define R300_TX_CLAMP_T(x) ((x) << 3) # define R300_TX_CLAMP_R(x) ((x) << 6) @@ -4424,8 +4425,10 @@ # define R300_TX_ID_SHIFT 28 #define R300_TX_FILTER1_0 0x4440 #define R300_TX_FILTER1_1 0x4444 +#define R300_TX_FILTER1_2 0x4448 #define R300_TX_FORMAT0_0 0x4480 #define R300_TX_FORMAT0_1 0x4484 +#define R300_TX_FORMAT0_2 0x4488 # define R300_TXWIDTH_SHIFT 0 # define R300_TXHEIGHT_SHIFT 11 # define R300_NUM_LEVELS_SHIFT 26 @@ -4434,6 +4437,7 @@ # define R300_TXPITCH_EN (1 << 31) #define R300_TX_FORMAT1_0 0x44c0 #define R300_TX_FORMAT1_1 0x44c4 +#define R300_TX_FORMAT1_2 0x44c8 # define R300_TX_FORMAT_X8 0x0 # define R300_TX_FORMAT_X16 0x1 # define R300_TX_FORMAT_Y4X4 0x2 @@ -4506,13 +4510,23 @@ # define R300_TX_FORMAT_YUV_TO_RGB_NO_CLAMP (2 << 22) # define R300_TX_FORMAT_SWAP_YUV (1 << 24) +# define R300_TX_FORMAT_CACHE_WHOLE (0 << 27) +# define R300_TX_FORMAT_CACHE_HALF_REGION_0 (2 << 27) +# define R300_TX_FORMAT_CACHE_HALF_REGION_1 (3 << 27) +# define R300_TX_FORMAT_CACHE_FOURTH_REGION_0 (4 << 27) +# define R300_TX_FORMAT_CACHE_FOURTH_REGION_1 (5 << 27) +# define R300_TX_FORMAT_CACHE_FOURTH_REGION_2 (6 << 27) +# define R300_TX_FORMAT_CACHE_FOURTH_REGION_3 (7 << 27) + #define R300_TX_FORMAT2_0 0x4500 #define R300_TX_FORMAT2_1 0x4504 +#define R300_TX_FORMAT2_2 0x4508 # define R500_TXWIDTH_11 (1 << 15) # define R500_TXHEIGHT_11 (1 << 16) #define R300_TX_OFFSET_0 0x4540 #define R300_TX_OFFSET_1 0x4544 +#define R300_TX_OFFSET_2 0x4548 # define R300_ENDIAN_SWAP_16_BIT (1 << 0) # define R300_ENDIAN_SWAP_32_BIT (2 << 0) # define R300_ENDIAN_SWAP_HALF_DWORD (3 << 0) @@ -4523,6 +4537,7 @@ #define R300_TX_ENABLE 0x4104 # define R300_TEX_0_ENABLE (1 << 0) # define R300_TEX_1_ENABLE (1 << 1) +# define R300_TEX_2_ENABLE (1 << 2) #define R300_US_W_FMT 0x46b4 #define R300_US_OUT_FMT_1 0x46a8 diff --git a/src/radeon_textured_video.c b/src/radeon_textured_video.c index f72f2c59..ed4dd3e0 100644 --- a/src/radeon_textured_video.c +++ b/src/radeon_textured_video.c @@ -304,8 +304,9 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn, RADEONInfoPtr info = RADEONPTR(pScrn); RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; INT32 x1, x2, y1, y2; - int srcPitch, srcPitch2, dstPitch; + int srcPitch, srcPitch2, dstPitch, dstPitch2 = 0; int s2offset, s3offset, tmp; + int d2line, d3line; int top, left, npixels, nlines, size; BoxRec dstBox; int dst_width = width, dst_height = height; @@ -335,18 +336,45 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn, if ((x1 >= x2) || (y1 >= y2)) return Success; + /* Bicubic filter setup */ + pPriv->bicubic_enabled = (pPriv->bicubic_state != BICUBIC_OFF); + if (!(IS_R300_3D || IS_R500_3D || IS_R600_3D)) + pPriv->bicubic_enabled = FALSE; + if (pPriv->bicubic_enabled && (pPriv->bicubic_state == BICUBIC_AUTO)) { + /* + * Applying the bicubic filter with a scale of less than 200% + * results in a blurred picture, so disable the filter. + */ + if ((src_w > drw_w / 2) || (src_h > drw_h / 2)) + pPriv->bicubic_enabled = FALSE; + } + + pPriv->planar_hw = pPriv->planar_state; + if (pPriv->bicubic_enabled || !( IS_R300_3D )) + pPriv->planar_hw = 0; + switch(id) { case FOURCC_YV12: case FOURCC_I420: - dstPitch = ((dst_width << 1) + 15) & ~15; srcPitch = (width + 3) & ~3; srcPitch2 = ((width >> 1) + 3) & ~3; - size = dstPitch * dst_height; + if (pPriv->planar_hw) { + dstPitch = (dst_width + 15) & ~15; + dstPitch = (dstPitch + 63) & ~63; + dstPitch2 = ((dst_width >> 1) + 15) & ~15; + dstPitch2 = (dstPitch2 + 63) & ~63; + size = dstPitch * dst_height + 2 * dstPitch2 * ((dst_height + 1) >> 1); + } else { + dstPitch = ((dst_width << 1) + 15) & ~15; + dstPitch = (dstPitch + 63) & ~63; + size = dstPitch * dst_height; + } break; case FOURCC_UYVY: case FOURCC_YUY2: default: dstPitch = ((dst_width << 1) + 15) & ~15; + dstPitch = (dstPitch + 63) & ~63; srcPitch = (width << 1); srcPitch2 = 0; size = dstPitch * dst_height; @@ -355,8 +383,7 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn, if (info->ChipFamily >= CHIP_FAMILY_R600) dstPitch = (dstPitch + 255) & ~255; - else - dstPitch = (dstPitch + 63) & ~63; + /* FIXME: size calc (adjust dstPitch earlier) */ if (pPriv->video_memory != NULL && size != pPriv->size) { radeon_legacy_free_memory(pScrn, pPriv->video_memory); @@ -376,19 +403,6 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn, return BadAlloc; } - /* Bicubic filter setup */ - pPriv->bicubic_enabled = (pPriv->bicubic_state != BICUBIC_OFF); - if (!(IS_R300_3D || IS_R500_3D || IS_R600_3D)) - pPriv->bicubic_enabled = FALSE; - if (pPriv->bicubic_enabled && (pPriv->bicubic_state == BICUBIC_AUTO)) { - /* - * Applying the bicubic filter with a scale of less than 200% - * results in a blurred picture, so disable the filter. - */ - if ((src_w > drw_w / 2) || (src_h > drw_h / 2)) - pPriv->bicubic_enabled = FALSE; - } - /* Bicubic filter loading */ if (pPriv->bicubic_memory == NULL && pPriv->bicubic_enabled) { pPriv->bicubic_offset = radeon_legacy_allocate_memory(pScrn, @@ -432,10 +446,16 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn, else pPriv->src_addr = (uint8_t *)(info->FB + pPriv->video_offset + (top * dstPitch)); pPriv->src_pitch = dstPitch; + pPriv->planeu_offset = dstPitch * dst_height; + pPriv->planev_offset = pPriv->planeu_offset + dstPitch2 * ((dst_height + 1) >> 1); pPriv->size = size; pPriv->pDraw = pDraw; + #if 0 + ErrorF("planeu_offset: 0x%x\n", pPriv->planeu_offset); + ErrorF("planev_offset: 0x%x\n", pPriv->planev_offset); + ErrorF("dstPitch2: 0x%x\n", dstPitch2); ErrorF("src_offset: 0x%x\n", pPriv->src_offset); ErrorF("src_addr: 0x%x\n", pPriv->src_addr); ErrorF("src_pitch: 0x%x\n", pPriv->src_pitch); @@ -470,6 +490,29 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn, srcPitch, srcPitch2, pPriv->src_pitch, width, height); } + } + else if (pPriv->planar_hw) { + top &= ~1; + s2offset = srcPitch * ((height + 1) & ~1); + s3offset = s2offset + srcPitch2 * ((height + 1) >> 1); + s2offset += (top >> 1) * srcPitch2 + (left >> 1); + s3offset += (top >> 1) * srcPitch2 + (left >> 1); + d2line = pPriv->planeu_offset; + d3line = pPriv->planev_offset; + d2line += (top >> 1) * dstPitch2 - (top * dstPitch); + d3line += (top >> 1) * dstPitch2 - (top * dstPitch); + nlines = ((y2 + 0xffff) >> 16) - top; + if(id == FOURCC_YV12) { + tmp = s2offset; + s2offset = s3offset; + s3offset = tmp; + } + RADEONCopyData(pScrn, buf + (top * srcPitch) + left, pPriv->src_addr + left, + srcPitch, dstPitch, nlines, npixels, 1); + RADEONCopyData(pScrn, buf + s2offset, pPriv->src_addr + d2line + (left >> 1), + srcPitch2, dstPitch2, (nlines + 1) >> 1, npixels >> 1, 1); + RADEONCopyData(pScrn, buf + s3offset, pPriv->src_addr + d3line + (left >> 1), + srcPitch2, dstPitch2, (nlines + 1) >> 1, npixels >> 1, 1); } else { top &= ~1; nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top; @@ -590,17 +633,19 @@ static XF86AttributeRec Attributes[NUM_ATTRIBUTES+1] = {0, 0, 0, NULL} }; -#define NUM_ATTRIBUTES_R300 2 +#define NUM_ATTRIBUTES_R300 3 static XF86AttributeRec Attributes_r300[NUM_ATTRIBUTES_R300+1] = { {XvSettable | XvGettable, 0, 2, "XV_BICUBIC"}, {XvSettable | XvGettable, 0, 1, "XV_VSYNC"}, + {XvSettable | XvGettable, 0, 1, "XV_HWPLANAR"}, {0, 0, 0, NULL} }; static Atom xvBicubic; static Atom xvVSync; +static Atom xvHWPlanar; #define NUM_IMAGES 4 @@ -627,6 +672,8 @@ RADEONGetTexPortAttribute(ScrnInfoPtr pScrn, *value = pPriv->bicubic_state; else if (attribute == xvVSync) *value = pPriv->vsync; + else if (attribute == xvHWPlanar) + *value = pPriv->planar_state; else return BadMatch; @@ -648,6 +695,8 @@ RADEONSetTexPortAttribute(ScrnInfoPtr pScrn, pPriv->bicubic_state = ClipValue (value, 0, 2); else if (attribute == xvVSync) pPriv->vsync = ClipValue (value, 0, 1); + else if (attribute == xvHWPlanar) + pPriv->planar_state = ClipValue (value, 0, 1); else return BadMatch; @@ -671,6 +720,7 @@ RADEONSetupImageTexturedVideo(ScreenPtr pScreen) xvBicubic = MAKE_ATOM("XV_BICUBIC"); xvVSync = MAKE_ATOM("XV_VSYNC"); + xvHWPlanar = MAKE_ATOM("XV_HWPLANAR"); adapt->type = XvWindowMask | XvInputMask | XvImageMask; adapt->flags = 0; @@ -720,6 +770,7 @@ RADEONSetupImageTexturedVideo(ScreenPtr pScreen) pPriv->doubleBuffer = 0; pPriv->bicubic_state = BICUBIC_AUTO; pPriv->vsync = TRUE; + pPriv->planar_state = 1; /* gotta uninit this someplace, XXX: shouldn't be necessary for textured */ REGION_NULL(pScreen, &pPriv->clip); diff --git a/src/radeon_textured_videofuncs.c b/src/radeon_textured_videofuncs.c index f55ae12f..aa5d4108 100644 --- a/src/radeon_textured_videofuncs.c +++ b/src/radeon_textured_videofuncs.c @@ -97,6 +97,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv uint32_t dst_offset, dst_pitch, dst_format; uint32_t txenable, colorpitch; uint32_t blendcntl; + Bool isplanar = FALSE; int dstxoff, dstyoff, pixel_shift, vtx_count; BoxPtr pBox = REGION_RECTS(&pPriv->clip); int nBox = REGION_NUM_RECTS(&pPriv->clip); @@ -181,16 +182,29 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv if (RADEONTilingEnabled(pScrn, pPixmap)) colorpitch |= R300_COLORTILE; - if (pPriv->id == FOURCC_UYVY) - txformat1 = R300_TX_FORMAT_YVYU422; - else - txformat1 = R300_TX_FORMAT_VYUY422; + if (pPriv->planar_hw && (pPriv->id == FOURCC_I420 || pPriv->id == FOURCC_YV12)) { + isplanar = TRUE; + } - txformat1 |= R300_TX_FORMAT_YUV_TO_RGB_CLAMP; + if (isplanar) { + txformat1 = R300_TX_FORMAT_X8 | R300_TX_FORMAT_CACHE_HALF_REGION_0; + txpitch = pPriv->src_pitch; + } else { + if (pPriv->id == FOURCC_UYVY) + txformat1 = R300_TX_FORMAT_YVYU422; + else + txformat1 = R300_TX_FORMAT_VYUY422; + + txformat1 |= R300_TX_FORMAT_YUV_TO_RGB_CLAMP; + + /* pitch is in pixels */ + txpitch = pPriv->src_pitch / 2; + } + txpitch -= 1; txformat0 = ((((pPriv->w - 1) & 0x7ff) << R300_TXWIDTH_SHIFT) | - (((pPriv->h - 1) & 0x7ff) << R300_TXHEIGHT_SHIFT) | - R300_TXPITCH_EN); + (((pPriv->h - 1) & 0x7ff) << R300_TXHEIGHT_SHIFT) | + R300_TXPITCH_EN); info->accel_state->texW[0] = pPriv->w; info->accel_state->texH[0] = pPriv->h; @@ -201,9 +215,6 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv R300_TX_MIN_FILTER_LINEAR | (0 << R300_TX_ID_SHIFT)); - /* pitch is in pixels */ - txpitch = pPriv->src_pitch / 2; - txpitch -= 1; if (IS_R500_3D && ((pPriv->w - 1) & 0x800)) txpitch |= R500_TXWIDTH_11; @@ -224,6 +235,34 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv txenable = R300_TEX_0_ENABLE; + if (isplanar) { + txformat0 = ((((((pPriv->w + 1 ) >> 1) - 1) & 0x7ff) << R300_TXWIDTH_SHIFT) | + (((((pPriv->h + 1 ) >> 1 ) - 1) & 0x7ff) << R300_TXHEIGHT_SHIFT) | + R300_TXPITCH_EN); + txpitch = ((pPriv->src_pitch >> 1) + 63) & ~63; + txpitch -= 1; + txfilter = (R300_TX_CLAMP_S(R300_TX_CLAMP_CLAMP_LAST) | + R300_TX_CLAMP_T(R300_TX_CLAMP_CLAMP_LAST) | + R300_TX_MIN_FILTER_LINEAR | + R300_TX_MAG_FILTER_LINEAR); + + BEGIN_ACCEL(12); + OUT_ACCEL_REG(R300_TX_FILTER0_1, txfilter | (1 << R300_TX_ID_SHIFT)); + OUT_ACCEL_REG(R300_TX_FILTER1_1, 0); + OUT_ACCEL_REG(R300_TX_FORMAT0_1, txformat0); + OUT_ACCEL_REG(R300_TX_FORMAT1_1, R300_TX_FORMAT_X8 | R300_TX_FORMAT_CACHE_FOURTH_REGION_2); + OUT_ACCEL_REG(R300_TX_FORMAT2_1, txpitch); + OUT_ACCEL_REG(R300_TX_OFFSET_1, txoffset + pPriv->planeu_offset); + OUT_ACCEL_REG(R300_TX_FILTER0_2, txfilter | (2 << R300_TX_ID_SHIFT)); + OUT_ACCEL_REG(R300_TX_FILTER1_2, 0); + OUT_ACCEL_REG(R300_TX_FORMAT0_2, txformat0); + OUT_ACCEL_REG(R300_TX_FORMAT1_2, R300_TX_FORMAT_X8 | R300_TX_FORMAT_CACHE_FOURTH_REGION_3); + OUT_ACCEL_REG(R300_TX_FORMAT2_2, txpitch); + OUT_ACCEL_REG(R300_TX_OFFSET_2, txoffset + pPriv->planev_offset); + FINISH_ACCEL(); + txenable |= R300_TEX_1_ENABLE | R300_TEX_2_ENABLE; + } + if (pPriv->bicubic_enabled) { /* Size is 128x1 */ txformat0 = ((0x7f << R300_TXWIDTH_SHIFT) | @@ -691,6 +730,171 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv OUT_ACCEL_REG(R300_US_ALU_CONST_A(1), 0); FINISH_ACCEL(); + } else if (isplanar) { + /* + * y' = y - .0625 + * u' = u - .5 + * v' = v - .5; + * + * r = 1.1643 * y' + 0.0 * u' + 1.5958 * v' + * g = 1.1643 * y' - 0.39173 * u' - 0.81290 * v' + * b = 1.1643 * y' + 2.017 * u' + 0.0 * v' + * + * DP3 might look like the straightforward solution + * but we'd need to move the texture yuv values in + * the same reg for this to work. Therefore use MADs. + * Without changing the shader at all (only the constants) + * could also provide hue/saturation/brightness/contrast control. + * + * yco = 1.1643 + * uco = 0, -0.39173, 2.017 + * vco = 1.5958, -0.8129, 0 + * off = -0.0625 * yco + -0.5 * uco[r] + -0.5 * vco[r], + * -0.0625 * yco + -0.5 * uco[g] + -0.5 * vco[g], + * -0.0625 * yco + -0.5 * uco[b] + -0.5 * vco[b], + * + * temp = MAD(yco, yuv.yyyy, off) + * temp = MAD(uco, yuv.uuuu, temp) + * result = MAD(vco, yuv.vvvv, temp) + */ + float yco = 1.1643; + float uco[3] = {0.0, -0.39173, 2.017}; + float vco[3] = {1.5958, -0.8129, 0.0}; + float off[3] = {-0.0625 * yco + -0.5 * uco[0] + -0.5 * vco[0], + -0.0625 * yco + -0.5 * uco[1] + -0.5 * vco[1], + -0.0625 * yco + -0.5 * uco[2] + -0.5 * vco[2]}; + + BEGIN_ACCEL(33); + /* 2 components: same 2 for tex0/1/2 */ + OUT_ACCEL_REG(R300_RS_COUNT, + ((2 << R300_RS_COUNT_IT_COUNT_SHIFT) | + R300_RS_COUNT_HIRES_EN)); + /* R300_INST_COUNT_RS - highest RS instruction used */ + OUT_ACCEL_REG(R300_RS_INST_COUNT, R300_INST_COUNT_RS(0) | R300_TX_OFFSET_RS(6)); + + OUT_ACCEL_REG(R300_US_PIXSIZE, 2); /* highest temp used */ + + /* Indirection levels */ + OUT_ACCEL_REG(R300_US_CONFIG, ((0 << R300_NLEVEL_SHIFT) | + R300_FIRST_TEX)); + + OUT_ACCEL_REG(R300_US_CODE_OFFSET, (R300_ALU_CODE_OFFSET(0) | + R300_ALU_CODE_SIZE(3) | + R300_TEX_CODE_OFFSET(0) | + R300_TEX_CODE_SIZE(3))); + + OUT_ACCEL_REG(R300_US_CODE_ADDR_3, (R300_ALU_START(0) | + R300_ALU_SIZE(2) | + R300_TEX_START(0) | + R300_TEX_SIZE(2) | + R300_RGBA_OUT)); + + /* tex inst */ + OUT_ACCEL_REG(R300_US_TEX_INST_0, (R300_TEX_SRC_ADDR(0) | + R300_TEX_DST_ADDR(0) | + R300_TEX_ID(0) | + R300_TEX_INST(R300_TEX_INST_LD))); + OUT_ACCEL_REG(R300_US_TEX_INST_1, (R300_TEX_SRC_ADDR(0) | + R300_TEX_DST_ADDR(1) | + R300_TEX_ID(1) | + R300_TEX_INST(R300_TEX_INST_LD))); + OUT_ACCEL_REG(R300_US_TEX_INST_2, (R300_TEX_SRC_ADDR(0) | + R300_TEX_DST_ADDR(2) | + R300_TEX_ID(2) | + R300_TEX_INST(R300_TEX_INST_LD))); + + /* ALU inst */ + /* MAD temp0, const0.a, temp0, const0.rgb */ + OUT_ACCEL_REG(R300_US_ALU_RGB_ADDR(0), (R300_ALU_RGB_ADDR0(R300_ALU_RGB_CONST(0)) | + R300_ALU_RGB_ADDR1(0) | + R300_ALU_RGB_ADDR2(0) | + R300_ALU_RGB_ADDRD(0) | + R300_ALU_RGB_WMASK(R300_ALU_RGB_MASK_RGB))); + OUT_ACCEL_REG(R300_US_ALU_RGB_INST(0), (R300_ALU_RGB_SEL_A(R300_ALU_RGB_SRC0_AAA) | + R300_ALU_RGB_MOD_A(R300_ALU_RGB_MOD_NOP) | + R300_ALU_RGB_SEL_B(R300_ALU_RGB_SRC1_RGB) | + R300_ALU_RGB_MOD_B(R300_ALU_RGB_MOD_NOP) | + R300_ALU_RGB_SEL_C(R300_ALU_RGB_SRC0_RGB) | + R300_ALU_RGB_MOD_C(R300_ALU_RGB_MOD_NOP) | + R300_ALU_RGB_OP(R300_ALU_RGB_OP_MAD) | + R300_ALU_RGB_OMOD(R300_ALU_RGB_OMOD_NONE))); + /* alpha nop, but need to set up alpha source for rgb usage */ + OUT_ACCEL_REG(R300_US_ALU_ALPHA_ADDR(0), (R300_ALU_ALPHA_ADDR0(R300_ALU_ALPHA_CONST(0)) | + R300_ALU_ALPHA_ADDR1(0) | + R300_ALU_ALPHA_ADDR2(0) | + R300_ALU_ALPHA_ADDRD(0) | + R300_ALU_ALPHA_WMASK(R300_ALU_ALPHA_MASK_NONE))); + OUT_ACCEL_REG(R300_US_ALU_ALPHA_INST(0), (R300_ALU_ALPHA_OP(R300_ALU_ALPHA_OP_MAD) | + R300_ALU_ALPHA_SEL_A(R300_ALU_ALPHA_0_0) | + R300_ALU_ALPHA_SEL_B(R300_ALU_ALPHA_0_0) | + R300_ALU_ALPHA_SEL_C(R300_ALU_ALPHA_0_0))); + + /* MAD const1, temp1, temp0 */ + OUT_ACCEL_REG(R300_US_ALU_RGB_ADDR(1), (R300_ALU_RGB_ADDR0(R300_ALU_RGB_CONST(1)) | + R300_ALU_RGB_ADDR1(1) | + R300_ALU_RGB_ADDR2(0) | + R300_ALU_RGB_ADDRD(0) | + R300_ALU_RGB_WMASK(R300_ALU_RGB_MASK_RGB))); + OUT_ACCEL_REG(R300_US_ALU_RGB_INST(1), (R300_ALU_RGB_SEL_A(R300_ALU_RGB_SRC0_RGB) | + R300_ALU_RGB_MOD_A(R300_ALU_RGB_MOD_NOP) | + R300_ALU_RGB_SEL_B(R300_ALU_RGB_SRC1_RGB) | + R300_ALU_RGB_MOD_B(R300_ALU_RGB_MOD_NOP) | + R300_ALU_RGB_SEL_C(R300_ALU_RGB_SRC2_RGB) | + R300_ALU_RGB_MOD_C(R300_ALU_RGB_MOD_NOP) | + R300_ALU_RGB_OP(R300_ALU_RGB_OP_MAD) | + R300_ALU_RGB_OMOD(R300_ALU_RGB_OMOD_NONE))); + /* alpha nop */ + OUT_ACCEL_REG(R300_US_ALU_ALPHA_ADDR(1), (R300_ALU_ALPHA_ADDRD(0) | + R300_ALU_ALPHA_WMASK(R300_ALU_ALPHA_MASK_NONE))); + OUT_ACCEL_REG(R300_US_ALU_ALPHA_INST(1), (R300_ALU_ALPHA_OP(R300_ALU_ALPHA_OP_MAD) | + R300_ALU_ALPHA_SEL_A(R300_ALU_ALPHA_0_0) | + R300_ALU_ALPHA_SEL_B(R300_ALU_ALPHA_0_0) | + R300_ALU_ALPHA_SEL_C(R300_ALU_ALPHA_0_0))); + + /* MAD result, const2, temp2, temp0 */ + OUT_ACCEL_REG(R300_US_ALU_RGB_ADDR(2), (R300_ALU_RGB_ADDR0(R300_ALU_RGB_CONST(2)) | + R300_ALU_RGB_ADDR1(2) | + R300_ALU_RGB_ADDR2(0) | + R300_ALU_RGB_ADDRD(0) | + R300_ALU_RGB_WMASK(R300_ALU_RGB_MASK_RGB) | + R300_ALU_RGB_OMASK(R300_ALU_RGB_MASK_RGB))); + OUT_ACCEL_REG(R300_US_ALU_RGB_INST(2), (R300_ALU_RGB_SEL_A(R300_ALU_RGB_SRC0_RGB) | + R300_ALU_RGB_MOD_A(R300_ALU_RGB_MOD_NOP) | + R300_ALU_RGB_SEL_B(R300_ALU_RGB_SRC1_RGB) | + R300_ALU_RGB_MOD_B(R300_ALU_RGB_MOD_NOP) | + R300_ALU_RGB_SEL_C(R300_ALU_RGB_SRC2_RGB) | + R300_ALU_RGB_MOD_C(R300_ALU_RGB_MOD_NOP) | + R300_ALU_RGB_OP(R300_ALU_RGB_OP_MAD) | + R300_ALU_RGB_OMOD(R300_ALU_RGB_OMOD_NONE) | + R300_ALU_RGB_CLAMP)); + /* write alpha 1 */ + OUT_ACCEL_REG(R300_US_ALU_ALPHA_ADDR(4), (R300_ALU_ALPHA_ADDRD(0) | + R300_ALU_ALPHA_OMASK(R300_ALU_ALPHA_MASK_A) | + R300_ALU_ALPHA_TARGET_A)); + OUT_ACCEL_REG(R300_US_ALU_ALPHA_INST(4), (R300_ALU_ALPHA_OP(R300_ALU_ALPHA_OP_MAD) | + R300_ALU_ALPHA_SEL_A(R300_ALU_ALPHA_0_0) | + R300_ALU_ALPHA_SEL_B(R300_ALU_ALPHA_0_0) | + R300_ALU_ALPHA_SEL_C(R300_ALU_ALPHA_1_0))); + + /* Shader constants. */ + /* constant 0: off, yco */ + OUT_ACCEL_REG(R300_US_ALU_CONST_R(0), F_TO_24(off[0])); + OUT_ACCEL_REG(R300_US_ALU_CONST_G(0), F_TO_24(off[1])); + OUT_ACCEL_REG(R300_US_ALU_CONST_B(0), F_TO_24(off[2])); + OUT_ACCEL_REG(R300_US_ALU_CONST_A(0), F_TO_24(yco)); + /* constant 1: uco */ + OUT_ACCEL_REG(R300_US_ALU_CONST_R(1), F_TO_24(uco[0])); + OUT_ACCEL_REG(R300_US_ALU_CONST_G(1), F_TO_24(uco[1])); + OUT_ACCEL_REG(R300_US_ALU_CONST_B(1), F_TO_24(uco[2])); + OUT_ACCEL_REG(R300_US_ALU_CONST_A(1), F_TO_24(0.0)); + /* constant 2: vco */ + OUT_ACCEL_REG(R300_US_ALU_CONST_R(2), F_TO_24(vco[0])); + OUT_ACCEL_REG(R300_US_ALU_CONST_G(2), F_TO_24(vco[1])); + OUT_ACCEL_REG(R300_US_ALU_CONST_B(2), F_TO_24(vco[2])); + OUT_ACCEL_REG(R300_US_ALU_CONST_A(2), F_TO_24(0.0)); + + FINISH_ACCEL(); + } else { BEGIN_ACCEL(11); /* 2 components: 2 for tex0 */ @@ -760,7 +964,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv R300_ALU_ALPHA_OMOD(R300_ALU_ALPHA_OMOD_NONE) | R300_ALU_ALPHA_CLAMP)); FINISH_ACCEL(); - } + } } else { if (pPriv->bicubic_enabled) { BEGIN_ACCEL(7); diff --git a/src/radeon_video.h b/src/radeon_video.h index 7f1891e4..34fb07f0 100644 --- a/src/radeon_video.h +++ b/src/radeon_video.h @@ -90,6 +90,11 @@ typedef struct { void *video_memory; int video_offset; + Bool planar_hw; + Bool planar_state; + int planeu_offset; + int planev_offset; + /* bicubic filtering */ void *bicubic_memory; int bicubic_offset; |