# HG changeset patch # User nick # Date 1006250458 0 # Node ID 64ce4a515a78ccd101edb2e970bd2c5475f0dfdc # Parent 9eb1cae56cae7b40c20d99befe5f39eff5c6cf5e Bad attempt of YV12 direct support diff -r 9eb1cae56cae -r 64ce4a515a78 drivers/radeon/radeon_vid.c --- a/drivers/radeon/radeon_vid.c Tue Nov 20 09:26:44 2001 +0000 +++ b/drivers/radeon/radeon_vid.c Tue Nov 20 10:00:58 2001 +0000 @@ -84,6 +84,7 @@ uint32_t y_x_end; uint32_t v_inc; uint32_t p1_blank_lines_at_top; + uint32_t p23_blank_lines_at_top; uint32_t vid_buf_pitch0_value; uint32_t vid_buf_pitch1_value; uint32_t p1_x_start_end; @@ -99,6 +100,7 @@ uint32_t p1_v_accum_init; uint32_t p1_h_accum_init; + uint32_t p23_v_accum_init; uint32_t p23_h_accum_init; uint32_t scale_cntl; uint32_t exclusive_horz; @@ -127,6 +129,7 @@ { OV0_Y_X_END, 0 }, { OV0_V_INC, 0 }, { OV0_P1_BLANK_LINES_AT_TOP, 0 }, + { OV0_P23_BLANK_LINES_AT_TOP, 0 }, { OV0_VID_BUF_PITCH0_VALUE, 0 }, { OV0_VID_BUF_PITCH1_VALUE, 0 }, { OV0_P1_X_START_END, 0 }, @@ -140,6 +143,7 @@ { OV0_VID_BUF5_BASE_ADRS, 0 }, { OV0_P1_V_ACCUM_INIT, 0 }, { OV0_P1_H_ACCUM_INIT, 0 }, + { OV0_P23_V_ACCUM_INIT, 0 }, { OV0_P23_H_ACCUM_INIT, 0 }, { OV0_SCALE_CNTL, 0 }, { OV0_EXCLUSIVE_HORZ, 0 }, @@ -156,7 +160,7 @@ static uint8_t *radeon_mmio_base = 0; static uint32_t radeon_mem_base = 0; -#define RADEON_SRC_BASE 0x1000000ULL /* this driver uses all video memory */ +static int32_t radeon_overlay_off = 0; static uint32_t radeon_ram_size = 0; @@ -273,8 +277,11 @@ case IMGFMT_YVU9: bes_flags |= SCALER_SOURCE_YUV9; break; case IMGFMT_IYUV: bes_flags |= SCALER_SOURCE_YUV12; break; - case IMGFMT_YV12: case IMGFMT_I420: + case IMGFMT_YV12: bes_flags |= SCALER_SOURCE_YUV12 | + SCALER_PIX_EXPAND | + SCALER_Y2R_TEMP; + break; case IMGFMT_YUY2: default: bes_flags |= SCALER_SOURCE_VYUY422; break; } @@ -309,8 +316,8 @@ static int radeon_vid_init_video( mga_vid_config_t *config ) { - uint32_t tmp,src_w,pitch,h_inc,step_by,left,top; - + uint32_t tmp,src_w,pitch,h_inc,step_by,left,leftUV,top; + int is_420; RTRACE("radeon_vid: usr_config: version = %x format=%x card=%x ram=%u src(%ux%u) dest(%u:%ux%u:%u) frame_size=%u num_frames=%u\n" ,(uint32_t)config->version ,(uint32_t)config->format @@ -348,6 +355,8 @@ printk( "radeon_vid: Unsupported pixel format: 0x%X\n",config->format); return -1; } + is_420 = 0; + if(config->format == IMGFMT_YV12 || config->format == IMGFMT_I420) is_420 = 1; switch(config->format) { default: @@ -366,7 +375,6 @@ case IMGFMT_RGB32: case IMGFMT_BGR32: pitch = ((XXX_WIDTH*4) + 15) & ~15; break; } - /*pitch 9c0 ->4e0 */ left = XXX_SRC_X << 16; top = XXX_SRC_Y << 16; @@ -384,13 +392,33 @@ /* keep everything in 16.16 */ - besr.vid_buf0_base_adrs = RADEON_SRC_BASE; /* I guess that offset 0 is o'k */ - besr.vid_buf0_base_adrs += ((left & ~7) << 1)&0xfffffff0; - besr.vid_buf1_base_adrs = besr.vid_buf0_base_adrs + config->frame_size; - besr.vid_buf2_base_adrs = besr.vid_buf0_base_adrs; - besr.vid_buf3_base_adrs = besr.vid_buf0_base_adrs + config->frame_size; - besr.vid_buf4_base_adrs = besr.vid_buf0_base_adrs; - besr.vid_buf5_base_adrs = besr.vid_buf0_base_adrs + config->frame_size; + if(is_420) + { + uint32_t dstPitch,d1line,d2line,d3line; + dstPitch = (XXX_WIDTH + 31) & ~31; /* of luma */ + d1line = top * dstPitch; + d2line = (XXX_HEIGHT * dstPitch) + ((top >> 1) * (dstPitch >> 1)); + d3line = d2line + ((XXX_HEIGHT >> 1) * (dstPitch >> 1)); + d1line += (left >> 16) & ~15; + d2line += (left >> 17) & ~15; + d3line += (left >> 17) & ~15; + besr.vid_buf0_base_adrs = (radeon_overlay_off + d1line) & 0xfffffff0; + besr.vid_buf1_base_adrs = ((radeon_overlay_off + d2line) & 0xfffffff0) | 0x00000001; + besr.vid_buf2_base_adrs = ((radeon_overlay_off + d3line) & 0xfffffff0) | 0x00000001; + besr.vid_buf3_base_adrs = besr.vid_buf0_base_adrs; + besr.vid_buf4_base_adrs = besr.vid_buf1_base_adrs; + besr.vid_buf5_base_adrs = besr.vid_buf2_base_adrs; + } + else + { + besr.vid_buf0_base_adrs = radeon_overlay_off; + besr.vid_buf0_base_adrs += ((left & ~7) << 1)&0xfffffff0; + besr.vid_buf1_base_adrs = besr.vid_buf0_base_adrs + config->frame_size; + besr.vid_buf2_base_adrs = besr.vid_buf0_base_adrs; + besr.vid_buf3_base_adrs = besr.vid_buf0_base_adrs + config->frame_size; + besr.vid_buf4_base_adrs = besr.vid_buf0_base_adrs; + besr.vid_buf5_base_adrs = besr.vid_buf0_base_adrs + config->frame_size; + } tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3); besr.p1_h_accum_init = ((tmp << 4) & 0x000f8000) | @@ -403,21 +431,27 @@ tmp = (top & 0x0000ffff) + 0x00018000; besr.p1_v_accum_init = ((tmp << 4) & 0x03ff8000) | 0x00000001; + + tmp = ((top >> 1) & 0x0000ffff) + 0x00018000; + besr.p23_v_accum_init = is_420 ? ((tmp << 4) & 0x01ff8000) | 0x00000001 : 0; + + leftUV = (left >> 17) & 7; left = (left >> 16) & 7; besr.h_inc = h_inc | ((h_inc >> 1) << 16); besr.step_by = step_by | (step_by << 8); besr.y_x_start = (config->x_org+8) | (config->y_org << 16); /*5c008->5d009*/ besr.y_x_end = (config->x_org + config->dest_width+8) | ((config->y_org + config->dest_height) << 16); besr.p1_blank_lines_at_top = 0x00000fff | ((config->src_height - 1) << 16); + besr.p23_blank_lines_at_top = is_420 ? 0x000007ff | ((((config->src_height+1)>>1) - 1) << 16) : 0; besr.vid_buf_pitch0_value = pitch; - besr.vid_buf_pitch1_value = pitch; + besr.vid_buf_pitch1_value = is_420 ? pitch/2 : pitch; RTRACE("radeon_vid: BES: v_inc=%x h_inc=%x step_by=%x\n",besr.v_inc,besr.h_inc,besr.step_by); RTRACE("radeon_vid: BES: vid_buf0_basey=%x\n",besr.vid_buf0_base_adrs); RTRACE("radeon_vid: BES: y_x_start=%x y_x_end=%x blank_at_top=%x pitch0_value=%x\n" ,besr.y_x_start,besr.y_x_end,besr.p1_blank_lines_at_top,besr.vid_buf_pitch0_value); besr.p1_x_start_end = (config->src_width + left - 1) | (left << 16); - left >>= 1; src_w=config->src_width >> 1; - besr.p2_x_start_end = (src_w + left - 1) | (left << 16); + src_w=config->src_width >> 1; + besr.p2_x_start_end = (src_w + left - 1) | (leftUV << 16); besr.p3_x_start_end = besr.p2_x_start_end; return 0; } @@ -429,17 +463,16 @@ { default: case 0: off = besr.vid_buf0_base_adrs; break; - case 1: off = besr.vid_buf1_base_adrs; break; - case 2: off = besr.vid_buf2_base_adrs; break; + case 1: off = besr.vid_buf3_base_adrs; break; + case 2: off = besr.vid_buf0_base_adrs; break; case 3: off = besr.vid_buf3_base_adrs; break; - case 4: off = besr.vid_buf4_base_adrs; break; - case 5: off = besr.vid_buf5_base_adrs; break; + case 4: off = besr.vid_buf0_base_adrs; break; + case 5: off = besr.vid_buf3_base_adrs; break; } OUTREG(OV0_REG_LOAD_CNTL, REG_LD_CTL_LOCK); while(!(INREG(OV0_REG_LOAD_CNTL)®_LD_CTL_LOCK_READBACK)); OUTREG(OV0_VID_BUF0_BASE_ADRS, off); OUTREG(OV0_REG_LOAD_CNTL, 0); - } static int video_on = 0; @@ -458,31 +491,37 @@ if(copy_from_user(&radeon_config,(mga_vid_config_t*) arg,sizeof(mga_vid_config_t))) { printk( "radeon_vid: failed copy from userspace\n"); - return(-EFAULT); + return -EFAULT; } if(radeon_config.version != MGA_VID_VERSION){ printk( "radeon_vid: incompatible version! driver: %X requested: %X\n",MGA_VID_VERSION,radeon_config.version); - return(-EFAULT); + return -EFAULT; } if(radeon_config.frame_size==0 || radeon_config.frame_size>1024*768*2){ printk( "radeon_vid: illegal frame_size: %d\n",radeon_config.frame_size); - return(-EFAULT); + return -EFAULT; } if(radeon_config.num_frames<1 || radeon_config.num_frames>4){ printk( "radeon_vid: illegal num_frames: %d\n",radeon_config.num_frames); - return(-EFAULT); + return -EFAULT; } /* FIXME: Fake of G400 ;) or would be better G200 ??? */ radeon_config.card_type = 0; radeon_config.ram_size = radeon_ram_size; - + radeon_overlay_off = radeon_ram_size*0x100000 - radeon_config.frame_size*radeon_config.num_frames; + radeon_overlay_off &= 0xffff0000; + if(radeon_overlay_off < 0){ + printk("radeon_vid: not enough video memory. Need: %u has: %u\n",radeon_config.frame_size*radeon_config.num_frames,radeon_ram_size*0x100000); + return -EFAULT; + } + RTRACE("radeon_vid: using video overlay at offset %p\n",radeon_overlay_off); if (copy_to_user((mga_vid_config_t *) arg, &radeon_config, sizeof(mga_vid_config_t))) { printk( "radeon_vid: failed copy to userspace\n"); - return(-EFAULT); + return -EFAULT; } return radeon_vid_init_video(&radeon_config); break; @@ -577,7 +616,7 @@ { RTRACE( "radeon_vid: mapping video memory into userspace\n"); - if(remap_page_range(vma->vm_start, radeon_mem_base + RADEON_SRC_BASE, + if(remap_page_range(vma->vm_start, radeon_mem_base + radeon_overlay_off, vma->vm_end - vma->vm_start, vma->vm_page_prot)) { printk( "radeon_vid: error mapping video memory\n"); diff -r 9eb1cae56cae -r 64ce4a515a78 libvo/vesa_lvo.c --- a/libvo/vesa_lvo.c Tue Nov 20 09:26:44 2001 +0000 +++ b/libvo/vesa_lvo.c Tue Nov 20 10:00:58 2001 +0000 @@ -144,6 +144,49 @@ if(lvo_handler != -1) close(lvo_handler); } +static void +CopyData420( + unsigned char *src1, + unsigned char *src2, + unsigned char *src3, + unsigned char *dst1, + unsigned char *dst2, + unsigned char *dst3, + int srcPitch, + int srcPitch2, + int dstPitch, + int h, + int w +){ + int count; + + count = h; + while(count--) { + memcpy(dst1, src1, w); + src1 += srcPitch; + dst1 += dstPitch; + } + + w >>= 1; + h >>= 1; + dstPitch >>= 1; + + count = h; + while(count--) { + memcpy(dst2, src2, w); + src2 += srcPitch2; + dst2 += dstPitch; + } + + count = h; + while(count--) { + memcpy(dst3, src3, w); + src3 += srcPitch2; + dst3 += dstPitch; + } +} + + uint32_t vlvo_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y) { #if 0 @@ -195,6 +238,25 @@ ,w,h,stride[0],stride[1],w*2); } else +#else + if(src_format == IMGFMT_YV12) + { + uint32_t dstPitch,d1line,d2line,d3line,d1offset,d2offset,d3offset; + dstPitch = (mga_vid_config.src_width + 15) & ~15; /* of luma */ + d1line = y * dstPitch; + d2line = (mga_vid_config.src_height * dstPitch) + ((y >> 1) * (dstPitch >> 1)); + d3line = d2line + ((mga_vid_config.src_height >> 1) * (dstPitch >> 1)); + + y &= ~1; + + d1offset = (y * dstPitch) + x; + d2offset = d2line + (x >> 1); + d3offset = d3line + (x >> 1); + CopyData420(image[0],image[1],image[2], + dst+d1offset,dst+d2offset,dst+d3offset, + stride[0],stride[1],dstPitch,h,w); + } + else #endif memcpy(dst,image[0],mga_vid_config.frame_size); #endif