i830_video.c
来自「是由intel提供的针对intel显卡915以上系列的linux驱动」· C语言 代码 · 共 2,323 行 · 第 1/5 页
C
2,323 行
#define VIDEO_DEBUG 0/*************************************************************************** Copyright 2000 Intel Corporation. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sub license, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.**************************************************************************//* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_video.c,v 1.11tsi Exp $ *//* * Reformatted with GNU indent (2.2.8), using the following options: * * -bad -bap -c41 -cd0 -ncdb -ci6 -cli0 -cp0 -ncs -d0 -di3 -i3 -ip3 -l78 * -lp -npcs -psl -sob -ss -br -ce -sc -hnl * * This provides a good match with the original i810 code and preferred * XFree86 formatting conventions. * * When editing this driver, please follow the existing formatting, and edit * with <TAB> characters expanded at 8-column intervals. *//* * i830_video.c: i830/i845 Xv driver. * * Copyright © 2002 by Alan Hourihane and David Dawes * * Authors: * Alan Hourihane <alanh@tungstengraphics.com> * David Dawes <dawes@xfree86.org> * * Derived from i810 Xv driver: * * Authors of i810 code: * Jonathan Bian <jonathan.bian@intel.com> * Offscreen Images: * Matt Sottek <matthew.j.sottek@intel.com> *//* * XXX Could support more formats. */#include "xf86.h"#include "xf86_OSproc.h"#include "xf86Resources.h"#include "xf86_ansic.h"#include "compiler.h"#include "xf86PciInfo.h"#include "xf86Pci.h"#include "xf86fbman.h"#include "regionstr.h"#include "randrstr.h"#include "i830.h"#include "xf86xv.h"#include <X11/extensions/Xv.h>#include "xaa.h"#include "xaalocal.h"#include "dixstruct.h"#include "fourcc.h"#ifndef USE_USLEEP_FOR_VIDEO#define USE_USLEEP_FOR_VIDEO 0#endif#define OFF_DELAY 250 /* milliseconds */#define FREE_DELAY 15000#define OFF_TIMER 0x01#define FREE_TIMER 0x02#define CLIENT_VIDEO_ON 0x04#define TIMER_MASK (OFF_TIMER | FREE_TIMER)static void I830InitOffscreenImages(ScreenPtr);static XF86VideoAdaptorPtr I830SetupImageVideo(ScreenPtr);static void I830StopVideo(ScrnInfoPtr, pointer, Bool);static int I830SetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer);static int I830GetPortAttribute(ScrnInfoPtr, Atom, INT32 *, pointer);static void I830QueryBestSize(ScrnInfoPtr, Bool, short, short, short, short, unsigned int *, unsigned int *, pointer);static int I830PutImage(ScrnInfoPtr, short, short, short, short, short, short, short, short, int, unsigned char *, short, short, Bool, RegionPtr, pointer);static int I830QueryImageAttributes(ScrnInfoPtr, int, unsigned short *, unsigned short *, int *, int *);static void I830BlockHandler(int, pointer, pointer, pointer);#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)static Atom xvBrightness, xvContrast, xvColorKey, xvPipe, xvDoubleBuffer;static Atom xvGamma0, xvGamma1, xvGamma2, xvGamma3, xvGamma4, xvGamma5;#define IMAGE_MAX_WIDTH 1920#define IMAGE_MAX_HEIGHT 1080#define IMAGE_MAX_WIDTH_LEGACY 1024#define IMAGE_MAX_HEIGHT_LEGACY 1080#if !VIDEO_DEBUG#define ErrorF Edummystatic voidEdummy(const char *dummy, ...){}#endif/* * This is more or less the correct way to initalise, update, and shut down * the overlay. Note OVERLAY_OFF should be used only after disabling the * overlay in OCMD and calling OVERLAY_UPDATE. * * XXX Need to make sure that the overlay engine is cleanly shutdown in * all modes of server exit. */#define OVERLAY_UPDATE \ do { \ BEGIN_LP_RING(6); \ OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE); \ OUT_RING(MI_NOOP); \ if (!*pI830->overlayOn) { \ OUT_RING(MI_NOOP); \ OUT_RING(MI_NOOP); \ OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_ON); \ ErrorF("Overlay goes from off to on\n"); \ *pI830->overlayOn = TRUE; \ } else { \ OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); \ OUT_RING(MI_NOOP); \ OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE); \ } \ OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); \ ADVANCE_LP_RING(); \ ErrorF("OVERLAY_UPDATE\n"); \ } while(0)#define OVERLAY_OFF \ do { \ if (*pI830->overlayOn) { \ int spin = 1000000; \ BEGIN_LP_RING(12); \ OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE); \ OUT_RING(MI_NOOP); \ OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); \ OUT_RING(MI_NOOP); \ OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE); \ OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); \ OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); \ OUT_RING(MI_NOOP); \ OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_OFF); \ OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); \ OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); \ OUT_RING(MI_NOOP); \ ADVANCE_LP_RING(); \ *pI830->overlayOn = FALSE; \ ErrorF("Overlay goes from on to off\n"); \ while (spin != 0 && (INREG(OCMD_REGISTER) & OVERLAY_ENABLE)){ \ ErrorF("SPIN %d\n",spin); \ spin--; \ } \ if (spin == 0) ErrorF("OVERLAY FAILED TO GO OFF\n"); \ ErrorF("OVERLAY_OFF\n"); \ } \ } while(0)/* * OCMD - Overlay Command Register */#define OCMD_REGISTER 0x30168#define MIRROR_MODE (0x3<<17)#define MIRROR_HORIZONTAL (0x1<<17)#define MIRROR_VERTICAL (0x2<<17)#define MIRROR_BOTH (0x3<<17)#define OV_BYTE_ORDER (0x3<<14)#define UV_SWAP (0x1<<14)#define Y_SWAP (0x2<<14)#define Y_AND_UV_SWAP (0x3<<14)#define SOURCE_FORMAT (0xf<<10)#define RGB_888 (0x1<<10)#define RGB_555 (0x2<<10)#define RGB_565 (0x3<<10)#define YUV_422 (0x8<<10)#define YUV_411 (0x9<<10)#define YUV_420 (0xc<<10)#define YUV_422_PLANAR (0xd<<10)#define YUV_410 (0xe<<10)#define TVSYNC_FLIP_PARITY (0x1<<9)#define TVSYNC_FLIP_ENABLE (0x1<<7)#define BUF_TYPE (0x1<<5)#define BUF_TYPE_FRAME (0x0<<5)#define BUF_TYPE_FIELD (0x1<<5)#define TEST_MODE (0x1<<4)#define BUFFER_SELECT (0x3<<2)#define BUFFER0 (0x0<<2)#define BUFFER1 (0x1<<2)#define FIELD_SELECT (0x1<<1)#define FIELD0 (0x0<<1)#define FIELD1 (0x1<<1)#define OVERLAY_ENABLE 0x1#define OFC_UPDATE 0x1/* OCONFIG register */#define CC_OUT_8BIT (0x1<<3)#define OVERLAY_PIPE_MASK (0x1<<18) #define OVERLAY_PIPE_A (0x0<<18) #define OVERLAY_PIPE_B (0x1<<18) #define THREE_LINE_BUFFERS (0x1<<0)#define TWO_LINE_BUFFERS (0x0<<0)/* DCLRKM register */#define DEST_KEY_ENABLE (0x1<<31)/* Polyphase filter coefficients */#define N_HORIZ_Y_TAPS 5#define N_VERT_Y_TAPS 3#define N_HORIZ_UV_TAPS 3#define N_VERT_UV_TAPS 3#define N_PHASES 17#define MAX_TAPS 5/* Filter cutoff frequency limits. */#define MIN_CUTOFF_FREQ 1.0#define MAX_CUTOFF_FREQ 3.0#define RGB16ToColorKey(c) \ (((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3))#define RGB15ToColorKey(c) \ (((c & 0x7c00) << 9) | ((c & 0x03E0) << 6) | ((c & 0x001F) << 3))/* client libraries expect an encoding */static XF86VideoEncodingRec DummyEncoding[1] = { { 0, "XV_IMAGE", IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, {1, 1} }};#define NUM_FORMATS 3static XF86VideoFormatRec Formats[NUM_FORMATS] = { {15, TrueColor}, {16, TrueColor}, {24, TrueColor}};#define CLONE_ATTRIBUTES 1static XF86AttributeRec CloneAttributes[CLONE_ATTRIBUTES] = { {XvSettable | XvGettable, 0, 1, "XV_PIPE"}};#define NUM_ATTRIBUTES 4static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = { {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"}, {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"}, {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}};#define GAMMA_ATTRIBUTES 6static XF86AttributeRec GammaAttributes[GAMMA_ATTRIBUTES] = { {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA0"}, {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA1"}, {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA2"}, {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA3"}, {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA4"}, {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA5"}};#define NUM_IMAGES 4static XF86ImageRec Images[NUM_IMAGES] = { XVIMAGE_YV12, XVIMAGE_I420, XVIMAGE_YUY2, XVIMAGE_UYVY};typedef struct { CARD32 OBUF_0Y; CARD32 OBUF_1Y; CARD32 OBUF_0U; CARD32 OBUF_0V; CARD32 OBUF_1U; CARD32 OBUF_1V; CARD32 OSTRIDE; CARD32 YRGB_VPH; CARD32 UV_VPH; CARD32 HORZ_PH; CARD32 INIT_PHS; CARD32 DWINPOS; CARD32 DWINSZ; CARD32 SWIDTH; CARD32 SWIDTHSW; CARD32 SHEIGHT; CARD32 YRGBSCALE; CARD32 UVSCALE; CARD32 OCLRC0; CARD32 OCLRC1; CARD32 DCLRKV; CARD32 DCLRKM; CARD32 SCLRKVH; CARD32 SCLRKVL; CARD32 SCLRKEN; CARD32 OCONFIG; CARD32 OCMD; CARD32 RESERVED1; /* 0x6C */ CARD32 AWINPOS; CARD32 AWINSZ; CARD32 RESERVED2; /* 0x78 */ CARD32 RESERVED3; /* 0x7C */ CARD32 RESERVED4; /* 0x80 */ CARD32 RESERVED5; /* 0x84 */ CARD32 RESERVED6; /* 0x88 */ CARD32 RESERVED7; /* 0x8C */ CARD32 RESERVED8; /* 0x90 */ CARD32 RESERVED9; /* 0x94 */ CARD32 RESERVEDA; /* 0x98 */ CARD32 RESERVEDB; /* 0x9C */ CARD32 FASTHSCALE; /* 0xA0 */ CARD32 UVSCALEV; /* 0xA4 */ CARD32 RESERVEDC[(0x200 - 0xA8) / 4]; /* 0xA8 - 0x1FC */ CARD16 Y_VCOEFS[N_VERT_Y_TAPS * N_PHASES]; /* 0x200 */ CARD16 RESERVEDD[0x100 / 2 - N_VERT_Y_TAPS * N_PHASES]; CARD16 Y_HCOEFS[N_HORIZ_Y_TAPS * N_PHASES]; /* 0x300 */ CARD16 RESERVEDE[0x200 / 2 - N_HORIZ_Y_TAPS * N_PHASES]; CARD16 UV_VCOEFS[N_VERT_UV_TAPS * N_PHASES]; /* 0x500 */ CARD16 RESERVEDF[0x100 / 2 - N_VERT_UV_TAPS * N_PHASES]; CARD16 UV_HCOEFS[N_HORIZ_UV_TAPS * N_PHASES]; /* 0x600 */ CARD16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES];} I830OverlayRegRec, *I830OverlayRegPtr;typedef struct { CARD32 YBuf0offset; CARD32 UBuf0offset; CARD32 VBuf0offset; CARD32 YBuf1offset; CARD32 UBuf1offset; CARD32 VBuf1offset; unsigned char currentBuf; int brightness; int contrast; int pipe; int doubleBuffer; RegionRec clip; CARD32 colorKey; CARD32 gamma0; CARD32 gamma1; CARD32 gamma2; CARD32 gamma3; CARD32 gamma4; CARD32 gamma5; CARD32 videoStatus; Time offTime; Time freeTime; FBLinearPtr linear; Bool overlayOK; int oneLineMode; int scaleRatio;} I830PortPrivRec, *I830PortPrivPtr;#define GET_PORT_PRIVATE(pScrn) \ (I830PortPrivPtr)((I830PTR(pScrn))->adaptor->pPortPrivates[0].ptr)#if VIDEO_DEBUGstatic voidCompareOverlay(I830Ptr pI830, CARD32 * overlay, int size){ int i; CARD32 val; int bad = 0; for (i = 0; i < size; i += 4) { val = INREG(0x30100 + i); if (val != overlay[i / 4]) { ErrorF("0x%05x value doesn't match (0x%lx != 0x%lx)\n", 0x30100 + i, val, overlay[i / 4]); bad++; } } if (!bad) ErrorF("CompareOverlay: no differences\n");}#endifvoidI830InitVideo(ScreenPtr pScreen){ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; XF86VideoAdaptorPtr newAdaptor = NULL; int num_adaptors; DPRINTF(PFX, "I830InitVideo\n");#if 0 { I830OverlayRegRec tmp; ErrorF("sizeof I830OverlayRegRec is 0x%x\n", sizeof(I830OverlayRegRec)); ErrorF("Reserved C, D, E, F, G are %x, %x, %x, %x, %x\n", (unsigned long)&(tmp.RESERVEDC[0]) - (unsigned long)&tmp, (unsigned long)&(tmp.RESERVEDD[0]) - (unsigned long)&tmp, (unsigned long)&(tmp.RESERVEDE[0]) - (unsigned long)&tmp, (unsigned long)&(tmp.RESERVEDF[0]) - (unsigned long)&tmp, (unsigned long)&(tmp.RESERVEDG[0]) - (unsigned long)&tmp); }#endif if (pScrn->bitsPerPixel != 8) { newAdaptor = I830SetupImageVideo(pScreen); I830InitOffscreenImages(pScreen); } num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); if (newAdaptor) { if (!num_adaptors) { num_adaptors = 1; adaptors = &newAdaptor; } else { newAdaptors = /* need to free this someplace */ xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr *)); if (newAdaptors) { memcpy(newAdaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr)); newAdaptors[num_adaptors] = newAdaptor; adaptors = newAdaptors; num_adaptors++; } } } if (num_adaptors)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?