Merge branch 'exa' of ../xf86-video-intel into modesetting

Conflicts:

	man/i810.man
	src/Makefile.am
	src/i830.h
	src/i830_driver.c
	src/i830_rotate.c
	src/i830_video.c
This commit is contained in:
Eric Anholt 2006-11-30 09:15:30 -08:00
commit b94b7c4bcf
20 changed files with 2677 additions and 848 deletions

View File

@ -206,7 +206,12 @@ atctivate the legacy texture pool (see
). If you run 3D programs with large texture memory requirements, you might
gain some performance by increasing this value.
Default: 32768.
.TP
.BI "Option \*qAccelMethod\*q \*q" string \*q
Choose acceleration architecture, either "XAA" or "EXA". XAA is the old
(but stable) XFree86 based acceleration architecture. EXA is a newer and
simpler acceleration architecture designed to better accelerate the X Render
extension. Default: "XAA".
.SH "SEE ALSO"
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)

View File

@ -24,7 +24,8 @@ SUBDIRS = xvmc bios_reader ch7xxx sil164
# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
# _ladir passes a dummy rpath to libtool so the thing will actually link
# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ -DI830_XV
AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ \
-DI830_XV -DI830_USE_XAA -DI830_USE_EXA
i810_drv_la_LTLIBRARIES = i810_drv.la
i810_drv_la_LDFLAGS = -module -avoid-version
@ -84,7 +85,11 @@ i810_drv_la_SOURCES = \
i915_3d.c \
i915_3d.h \
i915_reg.h \
i915_video.c
i915_video.c \
i830_exa.c \
i830_xaa.c \
i830_exa_render.c \
i915_exa_render.c
if HAVE_GEN4ASM
sf_prog.h: packed_yuv_sf.g4a

View File

@ -69,6 +69,15 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "i830_dri.h"
#endif
#ifdef I830_USE_EXA
#include "exa.h"
Bool I830EXAInit(ScreenPtr pScreen);
#endif
#ifdef I830_USE_XAA
Bool I830XAAInit(ScreenPtr pScreen);
#endif
typedef struct _I830OutputRec I830OutputRec, *I830OutputPtr;
#include "common.h"
@ -282,6 +291,14 @@ struct _I830OutputRec {
#endif
};
/** enumeration of 3d consumers so some can maintain invariant state. */
enum last_3d {
LAST_3D_OTHER,
LAST_3D_VIDEO,
LAST_3D_RENDER,
LAST_3D_ROTATION
};
typedef struct _I830PipeRec {
Bool enabled;
Bool gammaEnabled;
@ -340,7 +357,9 @@ typedef struct _I830Rec {
I830MemRange FrontBuffer2;
I830MemRange Scratch;
I830MemRange Scratch2;
#ifdef I830_USE_EXA
I830MemRange Offscreen;
#endif
/* Regions allocated either from the above pools, or from agpgart. */
I830MemRange *CursorMem;
I830MemRange *CursorMemARGB;
@ -418,13 +437,22 @@ typedef struct _I830Rec {
I830RegRec ModeReg;
Bool useEXA;
Bool noAccel;
Bool SWCursor;
Bool cursorOn;
#ifdef I830_USE_XAA
XAAInfoRecPtr AccelInfoRec;
#endif
xf86CursorInfoPtr CursorInfoRec;
CloseScreenProcPtr CloseScreen;
#ifdef I830_USE_EXA
unsigned int copy_src_pitch;
unsigned int copy_src_off;
ExaDriverPtr EXADriverPtr;
#endif
I830WriteIndexedByteFunc writeControl;
I830ReadIndexedByteFunc readControl;
I830WriteByteFunc writeStandard;
@ -563,6 +591,8 @@ typedef struct _I830Rec {
CARD32 savePaletteB[256];
CARD32 saveSWF[17];
CARD32 saveBLC_PWM_CTL;
enum last_3d last_3d;
} I830Rec;
#define I830PTR(p) ((I830Ptr)((p)->driverPrivate))
@ -670,6 +700,9 @@ void i830_dvo_init(ScrnInfoPtr pScrn);
/* i830_lvds.c */
void i830_lvds_init(ScrnInfoPtr pScrn);
extern void i830MarkSync(ScrnInfoPtr pScrn);
extern void i830WaitSync(ScrnInfoPtr pScrn);
/* i830_memory.c */
Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn);

View File

@ -34,13 +34,11 @@
#include "i830_reg.h"
#define CMD_3D (0x3<<29)
void I830EmitInvarientState( ScrnInfoPtr pScrn )
{
I830Ptr pI830 = I830PTR(pScrn);
BEGIN_LP_RING(38);
BEGIN_LP_RING(40);
OUT_RING(_3DSTATE_MAP_CUBE | MAP_UNIT(0));
OUT_RING(_3DSTATE_MAP_CUBE | MAP_UNIT(1));
@ -99,6 +97,12 @@ void I830EmitInvarientState( ScrnInfoPtr pScrn )
OUT_RING(_3DSTATE_MAP_COORD_TRANSFORM);
OUT_RING(DISABLE_TEX_TRANSFORM | TEXTURE_SET(3));
OUT_RING(_3DSTATE_MAP_COORD_SETBIND_CMD);
OUT_RING(TEXBIND_SET3(TEXCOORDSRC_VTXSET_3) |
TEXBIND_SET2(TEXCOORDSRC_VTXSET_2) |
TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) |
TEXBIND_SET0(TEXCOORDSRC_VTXSET_0));
OUT_RING(_3DSTATE_RASTER_RULES_CMD |
ENABLE_POINT_RASTER_RULE |
OGL_POINT_RASTER_RULE |

View File

@ -7,10 +7,6 @@
#include "config.h"
#endif
#ifndef DO_SCANLINE_IMAGE_WRITE
#define DO_SCANLINE_IMAGE_WRITE 0
#endif
/**************************************************************************
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
@ -111,7 +107,12 @@ I830WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis)
DRICloseScreen(screenInfo.screens[pScrn->scrnIndex]);
}
#endif
#ifdef I830_USE_XAA
pI830->AccelInfoRec = NULL; /* Stops recursive behavior */
#endif
#ifdef I830_USE_EXA
pI830->EXADriverPtr = NULL;
#endif
FatalError("lockup\n");
}
@ -219,47 +220,9 @@ I830RefreshRing(ScrnInfoPtr pScrn)
pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8);
if (pI830->LpRing->space < 0)
pI830->LpRing->space += pI830->LpRing->mem.Size;
if (pI830->AccelInfoRec)
pI830->AccelInfoRec->NeedToSync = TRUE;
i830MarkSync(pScrn);
}
/* I830 Accel Functions */
static void I830SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
int pattx, int patty,
int fg, int bg, int rop,
unsigned int planemask);
static void I830SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
int pattx, int patty,
int x, int y, int w, int h);
static void I830SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
int fg, int bg,
int rop,
unsigned int mask);
static void I830SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr
pScrn, int x,
int y, int w,
int h,
int skipleft);
static void I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
#if DO_SCANLINE_IMAGE_WRITE
static void I830SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop,
unsigned int planemask,
int trans_color, int bpp,
int depth);
static void I830SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn,
int x, int y, int w, int h,
int skipleft);
static void I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno);
#endif
static void I830RestoreAccelState(ScrnInfoPtr pScrn);
/* The following function sets up the supported acceleration. Call it
* from the FbInit() function in the SVGA driver, or before ScreenInit
* in a monolithic server.
@ -267,597 +230,15 @@ static void I830RestoreAccelState(ScrnInfoPtr pScrn);
Bool
I830AccelInit(ScreenPtr pScreen)
{
XAAInfoRecPtr infoPtr;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
int i;
int width = 0;
int nr_buffers = 0;
unsigned char *ptr = NULL;
#ifdef I830_USE_EXA
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830AccelInit\n");
pI830->AccelInfoRec = infoPtr = XAACreateInfoRec();
if (!infoPtr)
return FALSE;
pI830->bufferOffset = 0;
infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS | PIXMAP_CACHE;
/* Use the same sync function as the I830.
*/
infoPtr->Sync = I830Sync;
/* Everything else is different enough to justify different functions */
{
infoPtr->SolidFillFlags = NO_PLANEMASK;
infoPtr->SetupForSolidFill = I830SetupForSolidFill;
infoPtr->SubsequentSolidFillRect = I830SubsequentSolidFillRect;
}
{
infoPtr->ScreenToScreenCopyFlags = (NO_PLANEMASK | NO_TRANSPARENCY);
infoPtr->SetupForScreenToScreenCopy = I830SetupForScreenToScreenCopy;
infoPtr->SubsequentScreenToScreenCopy =
I830SubsequentScreenToScreenCopy;
}
{
infoPtr->SetupForMono8x8PatternFill = I830SetupForMono8x8PatternFill;
infoPtr->SubsequentMono8x8PatternFillRect =
I830SubsequentMono8x8PatternFillRect;
infoPtr->Mono8x8PatternFillFlags = (HARDWARE_PATTERN_PROGRAMMED_BITS |
HARDWARE_PATTERN_SCREEN_ORIGIN |
HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
BIT_ORDER_IN_BYTE_MSBFIRST |
NO_PLANEMASK);
}
/* On the primary screen */
if (pI830->init == 0) {
if (pI830->Scratch.Size != 0) {
width = ((pScrn->displayWidth + 31) & ~31) / 8;
nr_buffers = pI830->Scratch.Size / width;
ptr = pI830->FbBase + pI830->Scratch.Start;
}
} else {
/* On the secondary screen */
I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
if (pI8301->Scratch2.Size != 0) {
width = ((pScrn->displayWidth + 31) & ~31) / 8;
nr_buffers = pI8301->Scratch2.Size / width;
/* We have to use the primary screen's FbBase, as that's where
* we allocated Scratch2, so we get the correct pointer */
ptr = pI8301->FbBase + pI8301->Scratch2.Start;
}
}
if (nr_buffers) {
pI830->NumScanlineColorExpandBuffers = nr_buffers;
pI830->ScanlineColorExpandBuffers = (unsigned char **)
xnfcalloc(nr_buffers, sizeof(unsigned char *));
for (i = 0; i < nr_buffers; i++, ptr += width)
pI830->ScanlineColorExpandBuffers[i] = ptr;
infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
(NO_PLANEMASK | ROP_NEEDS_SOURCE | BIT_ORDER_IN_BYTE_MSBFIRST);
infoPtr->ScanlineColorExpandBuffers = (unsigned char **)
xnfcalloc(1, sizeof(unsigned char *));
infoPtr->NumScanlineColorExpandBuffers = 1;
infoPtr->ScanlineColorExpandBuffers[0] =
pI830->ScanlineColorExpandBuffers[0];
pI830->nextColorExpandBuf = 0;
infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
I830SetupForScanlineCPUToScreenColorExpandFill;
infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
I830SubsequentScanlineCPUToScreenColorExpandFill;
infoPtr->SubsequentColorExpandScanline =
I830SubsequentColorExpandScanline;
#if DO_SCANLINE_IMAGE_WRITE
infoPtr->NumScanlineImageWriteBuffers = 1;
infoPtr->ScanlineImageWriteBuffers = infoPtr->ScanlineColorExpandBuffers;
infoPtr->SetupForScanlineImageWrite = I830SetupForScanlineImageWrite;
infoPtr->SubsequentScanlineImageWriteRect =
I830SubsequentScanlineImageWriteRect;
infoPtr->SubsequentImageWriteScanline = I830SubsequentImageWriteScanline;
infoPtr->ScanlineImageWriteFlags = NO_GXCOPY |
NO_PLANEMASK |
ROP_NEEDS_SOURCE |
SCANLINE_PAD_DWORD;
if (pI830->useEXA)
return I830EXAInit(pScreen);
#endif
}
{
Bool shared_accel = FALSE;
int i;
for(i = 0; i < pScrn->numEntities; i++) {
if(xf86IsEntityShared(pScrn->entityList[i]))
shared_accel = TRUE;
}
if(shared_accel == TRUE)
infoPtr->RestoreAccelState = I830RestoreAccelState;
}
I830SelectBuffer(pScrn, I830_SELECT_FRONT);
return XAAInit(pScreen, infoPtr);
}
#ifdef XF86DRI
static unsigned int
CheckTiling(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
unsigned int tiled = 0;
/* Check tiling */
if (IS_I965G(pI830)) {
if (pI830->bufferOffset == pScrn->fbOffset && pI830->front_tiled == FENCE_XMAJOR)
tiled = 1;
if (pI830->bufferOffset == pI830->RotatedMem.Start && pI830->rotated_tiled == FENCE_XMAJOR)
tiled = 1;
if (pI830->bufferOffset == pI830->BackBuffer.Start && pI830->back_tiled == FENCE_XMAJOR)
tiled = 1;
/* not really supported as it's always YMajor tiled */
if (pI830->bufferOffset == pI830->DepthBuffer.Start && pI830->depth_tiled == FENCE_XMAJOR)
tiled = 1;
}
return tiled;
}
#else
#define CheckTiling(pScrn) 0
#endif
void
I830SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
unsigned int planemask)
{
I830Ptr pI830 = I830PTR(pScrn);
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SetupForFillRectSolid color: %x rop: %x mask: %x\n",
color, rop, planemask);
pI830->BR[13] = ((XAAGetPatternROP(rop) << 16) |
(pScrn->displayWidth * pI830->cpp));
pI830->BR[16] = color;
switch (pScrn->bitsPerPixel) {
case 8:
break;
case 16:
pI830->BR[13] |= (1 << 24);
break;
case 32:
pI830->BR[13] |= ((1 << 25) | (1 << 24));
break;
}
}
void
I830SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
{
I830Ptr pI830 = I830PTR(pScrn);
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SubsequentFillRectSolid %d,%d %dx%d\n", x, y, w, h);
{
BEGIN_LP_RING(6);
if (pScrn->bitsPerPixel == 32) {
OUT_RING(COLOR_BLT_CMD | COLOR_BLT_WRITE_ALPHA |
COLOR_BLT_WRITE_RGB);
} else {
OUT_RING(COLOR_BLT_CMD);
}
OUT_RING(pI830->BR[13]);
OUT_RING((h << 16) | (w * pI830->cpp));
OUT_RING(pI830->bufferOffset + (y * pScrn->displayWidth + x) *
pI830->cpp);
OUT_RING(pI830->BR[16]);
OUT_RING(0);
ADVANCE_LP_RING();
}
if (IS_I965G(pI830))
I830EmitFlush(pScrn);
}
void
I830SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
unsigned int planemask, int transparency_color)
{
I830Ptr pI830 = I830PTR(pScrn);
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SetupForScreenToScreenCopy %d %d %x %x %d\n",
xdir, ydir, rop, planemask, transparency_color);
pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
pI830->BR[13] |= XAAGetCopyROP(rop) << 16;
switch (pScrn->bitsPerPixel) {
case 8:
break;
case 16:
pI830->BR[13] |= (1 << 24);
break;
case 32:
pI830->BR[13] |= ((1 << 25) | (1 << 24));
break;
}
}
void
I830SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int src_x1, int src_y1,
int dst_x1, int dst_y1, int w, int h)
{
I830Ptr pI830 = I830PTR(pScrn);
int dst_x2, dst_y2;
unsigned int tiled = CheckTiling(pScrn);
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SubsequentScreenToScreenCopy %d,%d - %d,%d %dx%d\n",
src_x1, src_y1, dst_x1, dst_y1, w, h);
dst_x2 = dst_x1 + w;
dst_y2 = dst_y1 + h;
if (tiled)
pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) |
(pI830->BR[13] & 0xFFFF0000);
{
BEGIN_LP_RING(8);
if (pScrn->bitsPerPixel == 32) {
OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
XY_SRC_COPY_BLT_WRITE_RGB | tiled << 15 | tiled << 11);
} else {
OUT_RING(XY_SRC_COPY_BLT_CMD | tiled << 15 | tiled << 11);
}
OUT_RING(pI830->BR[13]);
OUT_RING((dst_y1 << 16) | (dst_x1 & 0xffff));
OUT_RING((dst_y2 << 16) | (dst_x2 & 0xffff));
OUT_RING(pI830->bufferOffset);
OUT_RING((src_y1 << 16) | (src_x1 & 0xffff));
OUT_RING(pI830->BR[13] & 0xFFFF);
OUT_RING(pI830->bufferOffset);
ADVANCE_LP_RING();
}
if (IS_I965G(pI830))
I830EmitFlush(pScrn);
}
static void
I830SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattx, int patty,
int fg, int bg, int rop,
unsigned int planemask)
{
I830Ptr pI830 = I830PTR(pScrn);
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SetupForMono8x8PatternFill\n");
pI830->BR[16] = pattx;
pI830->BR[17] = patty;
pI830->BR[18] = bg;
pI830->BR[19] = fg;
pI830->BR[13] = (pScrn->displayWidth * pI830->cpp); /* In bytes */
pI830->BR[13] |= XAAGetPatternROP(rop) << 16;
if (bg == -1)
pI830->BR[13] |= (1 << 28);
switch (pScrn->bitsPerPixel) {
case 8:
break;
case 16:
pI830->BR[13] |= (1 << 24);
break;
case 32:
pI830->BR[13] |= ((1 << 25) | (1 << 24));
break;
}
}
static void
I830SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int pattx, int patty,
int x, int y, int w, int h)
{
I830Ptr pI830 = I830PTR(pScrn);
int x1, x2, y1, y2;
unsigned int tiled = CheckTiling(pScrn);
x1 = x;
x2 = x + w;
y1 = y;
y2 = y + h;
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SubsequentMono8x8PatternFillRect\n");
if (tiled)
pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) |
(pI830->BR[13] & 0xFFFF0000);
{
BEGIN_LP_RING(10);
if (pScrn->bitsPerPixel == 32) {
OUT_RING(XY_MONO_PAT_BLT_CMD | XY_MONO_PAT_BLT_WRITE_ALPHA |
XY_MONO_PAT_BLT_WRITE_RGB |
tiled << 11 |
((patty << 8) & XY_MONO_PAT_VERT_SEED) |
((pattx << 12) & XY_MONO_PAT_HORT_SEED));
} else {
OUT_RING(XY_MONO_PAT_BLT_CMD |
tiled << 11 |
((patty << 8) & XY_MONO_PAT_VERT_SEED) |
((pattx << 12) & XY_MONO_PAT_HORT_SEED));
}
OUT_RING(pI830->BR[13]);
OUT_RING((y1 << 16) | x1);
OUT_RING((y2 << 16) | x2);
OUT_RING(pI830->bufferOffset);
OUT_RING(pI830->BR[18]); /* bg */
OUT_RING(pI830->BR[19]); /* fg */
OUT_RING(pI830->BR[16]); /* pattern data */
OUT_RING(pI830->BR[17]);
OUT_RING(0);
ADVANCE_LP_RING();
}
if (IS_I965G(pI830))
I830EmitFlush(pScrn);
}
static void
I830GetNextScanlineColorExpandBuffer(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
XAAInfoRecPtr infoPtr = pI830->AccelInfoRec;
if (pI830->nextColorExpandBuf == pI830->NumScanlineColorExpandBuffers)
I830Sync(pScrn);
infoPtr->ScanlineColorExpandBuffers[0] =
pI830->ScanlineColorExpandBuffers[pI830->nextColorExpandBuf];
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("using color expand buffer %d\n", pI830->nextColorExpandBuf);
pI830->nextColorExpandBuf++;
}
static void
I830SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
int fg, int bg, int rop,
unsigned int planemask)
{
I830Ptr pI830 = I830PTR(pScrn);
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SetupForScanlineScreenToScreenColorExpand %d %d %x %x\n",
fg, bg, rop, planemask);
/* Fill out register values */
pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
pI830->BR[13] |= XAAGetCopyROP(rop) << 16;
if (bg == -1)
pI830->BR[13] |= (1 << 29);
switch (pScrn->bitsPerPixel) {
case 8:
break;
case 16:
pI830->BR[13] |= (1 << 24);
break;
case 32:
pI830->BR[13] |= ((1 << 25) | (1 << 24));
break;
}
pI830->BR[18] = bg;
pI830->BR[19] = fg;
I830GetNextScanlineColorExpandBuffer(pScrn);
}
static void
I830SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
int x, int y,
int w, int h, int skipleft)
{
I830Ptr pI830 = I830PTR(pScrn);
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SubsequentScanlineCPUToScreenColorExpandFill "
"%d,%d %dx%x %d\n", x, y, w, h, skipleft);
/* Fill out register values */
pI830->BR[9] = (pI830->bufferOffset +
(y * pScrn->displayWidth + x) * pI830->cpp);
pI830->BR[11] = ((1 << 16) | w);
}
static void
I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
{
I830Ptr pI830 = I830PTR(pScrn);
unsigned int tiled = CheckTiling(pScrn);
if (pI830->init == 0) {
pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
pI830->FbBase);
} else {
I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
/* We have to use the primary screen's FbBase, as that's where
* we allocated Scratch2, so we get the correct pointer */
pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
pI8301->FbBase);
}
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SubsequentColorExpandScanline %d (addr %x)\n",
bufno, pI830->BR[12]);
if (tiled)
pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) |
(pI830->BR[13] & 0xFFFF0000);
{
BEGIN_LP_RING(8);
if (pScrn->bitsPerPixel == 32) {
OUT_RING(XY_MONO_SRC_BLT_CMD | XY_MONO_SRC_BLT_WRITE_ALPHA |
tiled << 11 |
XY_MONO_SRC_BLT_WRITE_RGB);
} else {
OUT_RING(XY_MONO_SRC_BLT_CMD | tiled << 11);
}
OUT_RING(pI830->BR[13]);
OUT_RING(0); /* x1 = 0, y1 = 0 */
OUT_RING(pI830->BR[11]); /* x2 = w, y2 = 1 */
OUT_RING(pI830->BR[9]); /* dst addr */
OUT_RING(pI830->BR[12]); /* src addr */
OUT_RING(pI830->BR[18]); /* bg */
OUT_RING(pI830->BR[19]); /* fg */
ADVANCE_LP_RING();
}
/* Advance to next scanline.
*/
pI830->BR[9] += pScrn->displayWidth * pI830->cpp;
I830GetNextScanlineColorExpandBuffer(pScrn);
if (IS_I965G(pI830))
I830EmitFlush(pScrn);
}
#if DO_SCANLINE_IMAGE_WRITE
static void
I830SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop,
unsigned int planemask, int trans_color,
int bpp, int depth)
{
I830Ptr pI830 = I830PTR(pScrn);
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SetupForScanlineImageWrite %x %x\n", rop, planemask);
/* Fill out register values */
pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
pI830->BR[13] |= XAAGetCopyROP(rop) << 16;
switch (pScrn->bitsPerPixel) {
case 8:
break;
case 16:
pI830->BR[13] |= (1 << 24);
break;
case 32:
pI830->BR[13] |= ((1 << 25) | (1 << 24));
break;
}
I830GetNextScanlineColorExpandBuffer(pScrn);
}
static void
I830SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, int x, int y,
int w, int h, int skipleft)
{
I830Ptr pI830 = I830PTR(pScrn);
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SubsequentScanlineImageWriteRect "
"%d,%d %dx%x %d\n", x, y, w, h, skipleft);
/* Fill out register values */
pI830->BR[9] = (pI830->bufferOffset +
(y * pScrn->displayWidth + x) * pI830->cpp);
pI830->BR[11] = ((1 << 16) | w);
}
static void
I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno)
{
I830Ptr pI830 = I830PTR(pScrn);
unsigned int tiled = CheckTiling(pScrn);
if (pI830->init == 0) {
pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
pI830->FbBase);
} else {
I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
/* We have to use the primary screen's FbBase, as that's where
* we allocated Scratch2, so we get the correct pointer */
pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
pI8301->FbBase);
}
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SubsequentImageWriteScanline %d (addr %x)\n",
bufno, pI830->BR[12]);
{
BEGIN_LP_RING(8);
if (pScrn->bitsPerPixel == 32) {
OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
tiled << 11 |
XY_SRC_COPY_BLT_WRITE_RGB);
} else {
OUT_RING(XY_SRC_COPY_BLT_CMD | tiled << 11);
}
OUT_RING(pI830->BR[13]);
OUT_RING(0); /* x1 = 0, y1 = 0 */
OUT_RING(pI830->BR[11]); /* x2 = w, y2 = 1 */
OUT_RING(pI830->BR[9]); /* dst addr */
OUT_RING(0); /* source origin (0,0) */
OUT_RING(pI830->BR[11] & 0xffff); /* source pitch */
OUT_RING(pI830->BR[12]); /* src addr */
ADVANCE_LP_RING();
}
/* Advance to next scanline.
*/
pI830->BR[9] += pScrn->displayWidth * pI830->cpp;
I830GetNextScanlineColorExpandBuffer(pScrn);
}
#endif
/* Support for multiscreen */
static void
I830RestoreAccelState(ScrnInfoPtr pScrn)
{
#if 0
/* might be needed, but everything is on a ring, so I don't think so */
I830Sync(pScrn);
#ifdef I830_USE_XAA
return I830XAAInit(pScreen);
#endif
return FALSE;
}

View File

@ -238,6 +238,7 @@ static void
I830_FillRect(ScrnInfoPtr pScrn,
int x, int y, int w, int h, unsigned long color)
{
#ifdef I830_USE_XAA
I830Ptr pI830 = I830PTR(pScrn);
MARKER();
@ -247,6 +248,7 @@ I830_FillRect(ScrnInfoPtr pScrn,
(*pI830->AccelInfoRec->SubsequentSolidFillRect) (pScrn, x, y, w, h);
SET_SYNC_FLAG(pI830->AccelInfoRec);
}
#endif
}
static void
@ -278,6 +280,7 @@ static void
I830_BlitRect(ScrnInfoPtr pScrn,
int srcx, int srcy, int w, int h, int dstx, int dsty)
{
#ifdef I830_USE_XAA
I830Ptr pI830 = I830PTR(pScrn);
MARKER();
@ -292,6 +295,7 @@ I830_BlitRect(ScrnInfoPtr pScrn,
dstx, dsty, w, h);
SET_SYNC_FLAG(pI830->AccelInfoRec);
}
#endif
}
#if 0

View File

@ -1028,6 +1028,8 @@ I830DRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
if (I810_DEBUG & DEBUG_VERBOSE_DRI)
ErrorF("i830DRISwapContext (in)\n");
pI830->last_3d = LAST_3D_OTHER;
if (!pScrn->vtSema)
return;
pI830->LockHeld = 1;
@ -1047,7 +1049,6 @@ I830DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
BoxPtr pbox = REGION_RECTS(prgn);
int nbox = REGION_NUM_RECTS(prgn);
@ -1085,7 +1086,7 @@ I830DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
}
I830SelectBuffer(pScrn, I830_SELECT_FRONT);
pI830->AccelInfoRec->NeedToSync = TRUE;
i830MarkSync(pScrn);
}
/* This routine is a modified form of XAADoBitBlt with the calls to
@ -1248,8 +1249,7 @@ I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
DEALLOCATE_LOCAL(pptNew1);
DEALLOCATE_LOCAL(pboxNew1);
}
pI830->AccelInfoRec->NeedToSync = TRUE;
i830MarkSync(pScrn);
}
/* Use callbacks from dri.c to support pageflipping mode for a single

View File

@ -201,6 +201,18 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <errno.h>
#endif
#ifdef I830_USE_EXA
const char *I830exaSymbols[] = {
"exaGetVersion",
"exaDriverInit",
"exaDriverFini",
"exaOffscreenAlloc",
"exaOffscreenFree",
"exaWaitSync",
NULL
};
#endif
#define BIT(x) (1 << (x))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define NB_OF(x) (sizeof (x) / sizeof (*x))
@ -247,6 +259,9 @@ static PciChipsets I830PciChipsets[] = {
*/
typedef enum {
#if defined(I830_USE_XAA) && defined(I830_USE_EXA)
OPTION_ACCELMETHOD,
#endif
OPTION_NOACCEL,
OPTION_SW_CURSOR,
OPTION_CACHE_LINES,
@ -270,6 +285,9 @@ typedef enum {
} I830Opts;
static OptionInfoRec I830Options[] = {
#if defined(I830_USE_XAA) && defined(I830_USE_EXA)
{OPTION_ACCELMETHOD, "AccelMethod", OPTV_ANYSTR, {0}, FALSE},
#endif
{OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_CACHE_LINES, "CacheLines", OPTV_INTEGER, {0}, FALSE},
@ -1186,6 +1204,42 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
if (xf86ReturnOptValBool(pI830->Options, OPTION_NOACCEL, FALSE)) {
pI830->noAccel = TRUE;
}
/*
* The ugliness below:
* If either XAA or EXA (exclusive) is compiled in, default to it.
*
* If both are compiled in, and the user didn't specify noAccel, use the
* config option AccelMethod to determine which to use, defaulting to XAA
* if none is specified, or if the string was unrecognized.
*
* All this *could* go away if we removed XAA support from this driver,
* for example. :)
*/
if (!pI830->noAccel) {
#if (defined(I830_USE_EXA) && defined(I830_USE_XAA)) || !defined(I830_USE_EXA)
pI830->useEXA = FALSE;
#else
pI830->useEXA = TRUE;
#endif
#if defined(I830_USE_XAA) && defined(I830_USE_EXA)
int from = X_DEFAULT;
if ((s = (char *)xf86GetOptValString(pI830->Options,
OPTION_ACCELMETHOD))) {
if (!xf86NameCmp(s, "EXA")) {
from = X_CONFIG;
pI830->useEXA = TRUE;
}
else if (!xf86NameCmp(s, "XAA")) {
from = X_CONFIG;
pI830->useEXA = FALSE;
}
}
#endif
xf86DrvMsg(pScrn->scrnIndex, from, "Using %s for acceleration\n",
pI830->useEXA ? "EXA" : "XAA");
}
if (xf86ReturnOptValBool(pI830->Options, OPTION_SW_CURSOR, FALSE)) {
pI830->SWCursor = TRUE;
}
@ -1770,14 +1824,33 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
xf86LoaderReqSymLists(I810fbSymbols, NULL);
if (!pI830->noAccel) {
#ifdef I830_USE_XAA
if (!pI830->noAccel && !pI830->useEXA) {
if (!xf86LoadSubModule(pScrn, "xaa")) {
PreInitCleanup(pScrn);
return FALSE;
}
xf86LoaderReqSymLists(I810xaaSymbols, NULL);
}
#endif
#ifdef I830_USE_EXA
if (!pI830->noAccel && pI830->useEXA) {
XF86ModReqInfo req;
int errmaj, errmin;
memset(&req, 0, sizeof(req));
req.majorversion = 2;
req.minorversion = 0;
if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req,
&errmaj, &errmin)) {
LoaderErrorMsg(NULL, "exa", errmaj, errmin);
PreInitCleanup(pScrn);
return FALSE;
}
xf86LoaderReqSymLists(I830exaSymbols, NULL);
}
#endif
if (!pI830->SWCursor) {
if (!xf86LoadSubModule(pScrn, "ramdac")) {
PreInitCleanup(pScrn);
@ -1923,16 +1996,25 @@ ResetState(ScrnInfoPtr pScrn, Bool flush)
for (i = 0; i < FENCE_NR; i++)
OUTREG(FENCE + i * 4, 0);
}
/* Flush the ring buffer (if enabled), then disable it. */
if (pI830->AccelInfoRec != NULL && flush) {
temp = INREG(LP_RING + RING_LEN);
if (temp & 1) {
I830RefreshRing(pScrn);
I830Sync(pScrn);
DO_RING_IDLE();
}
}
/* God this is ugly */
#define flush_ring() do { \
temp = INREG(LP_RING + RING_LEN); \
if (temp & 1) { \
I830RefreshRing(pScrn); \
I830Sync(pScrn); \
DO_RING_IDLE(); \
} \
} while(0)
#ifdef I830_USE_XAA
if (!pI830->useEXA && flush && pI830->AccelInfoRec)
flush_ring();
#endif
#ifdef I830_USE_XAA
if (pI830->useEXA && flush && pI830->EXADriverPtr)
flush_ring();
#endif
OUTREG(LP_RING + RING_LEN, 0);
OUTREG(LP_RING + RING_HEAD, 0);
OUTREG(LP_RING + RING_TAIL, 0);
@ -2636,10 +2718,23 @@ IntelEmitInvarientState(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
CARD32 ctx_addr;
#ifdef XF86DRI
drmI830Sarea *sarea;
#endif
if (pI830->noAccel)
return;
#ifdef XF86DRI
if (pI830->directRenderingEnabled) {
sarea = DRIGetSAREAPrivate(pScrn->pScreen);
/* Mark that the X Server was the last holder of the context */
if (sarea)
sarea->ctxOwner = DRIGetContext(pScrn->pScreen);
}
#endif
ctx_addr = pI830->ContextMem.Start;
/* Align to a 2k boundry */
ctx_addr = ((ctx_addr + 2048 - 1) / 2048) * 2048;
@ -3189,7 +3284,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
break;
}
#ifdef XF86DRI
if (pI830->directRenderingEnabled && (pI830->mmModeFlags & I830_KERNEL_MM)) {
unsigned long aperEnd = ROUND_DOWN_TO(pI830->FbMapSize, GTT_PAGE_SIZE)
@ -3469,10 +3563,7 @@ I830SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
#endif
/* Sync the engine before mode switch */
if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
(*pI830->AccelInfoRec->Sync)(pScrn);
pI830->AccelInfoRec->NeedToSync = FALSE;
}
i830WaitSync(pScrn);
/* Check if our currentmode is about to change. We do this so if we
* are rotating, we don't need to call the mode setup again.
@ -3619,7 +3710,9 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
I830Ptr pI830 = I830PTR(pScrn);
#ifdef I830_USE_XAA
XAAInfoRecPtr infoPtr = pI830->AccelInfoRec;
#endif
pI830->closing = TRUE;
#ifdef XF86DRI
@ -3652,14 +3745,21 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen)
xfree(pI830->ScanlineColorExpandBuffers);
pI830->ScanlineColorExpandBuffers = 0;
}
#ifdef I830_USE_XAA
if (infoPtr) {
if (infoPtr->ScanlineColorExpandBuffers)
xfree(infoPtr->ScanlineColorExpandBuffers);
XAADestroyInfoRec(infoPtr);
pI830->AccelInfoRec = NULL;
}
#endif
#ifdef I830_USE_EXA
if (pI830->useEXA && pI830->EXADriverPtr) {
exaDriverFini(pScreen);
xfree(pI830->EXADriverPtr);
pI830->EXADriverPtr = NULL;
}
#endif
if (pI830->CursorInfoRec) {
xf86DestroyCursorInfoRec(pI830->CursorInfoRec);
pI830->CursorInfoRec = 0;
@ -3852,6 +3952,43 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
return 1000;
}
void
i830WaitSync(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
#ifdef I830_USE_XAA
if (!pI830->noAccel && !pI830->useEXA && pI830->AccelInfoRec
&& pI830->AccelInfoRec->NeedToSync) {
(*pI830->AccelInfoRec->Sync)(pScrn);
pI830->AccelInfoRec->NeedToSync = FALSE;
}
#endif
#ifdef I830_USE_EXA
if (!pI830->noAccel && pI830->useEXA && pI830->EXADriverPtr) {
ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
exaWaitSync(pScreen);
}
#endif
}
void
i830MarkSync(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
#ifdef I830_USE_XAA
if (!pI830->useEXA && pI830->AccelInfoRec)
pI830->AccelInfoRec->NeedToSync = TRUE;
#endif
#ifdef I830_USE_EXA
if (pI830->useEXA && pI830->EXADriverPtr) {
ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
exaMarkSync(pScreen);
}
#endif
}
void
I830InitpScrn(ScrnInfoPtr pScrn)
{

505
src/i830_exa.c Normal file
View File

@ -0,0 +1,505 @@
/**************************************************************************
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
All Rights Reserved.
Copyright (c) 2005 Jesse Barnes <jbarnes@virtuousgeek.org>
Based on code from i830_xaa.c.
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 PRECISION INSIGHT 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.
**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "xf86.h"
#include "xaarop.h"
#include "i830.h"
#include "i810_reg.h"
#include "i830_reg.h"
#ifdef I830DEBUG
#define DEBUG_I830FALLBACK 1
#endif
#define ALWAYS_SYNC 1
#ifdef DEBUG_I830FALLBACK
#define I830FALLBACK(s, arg...) \
do { \
DPRINTF(PFX, "EXA fallback: " s "\n", ##arg); \
return FALSE; \
} while(0)
#else
#define I830FALLBACK(s, arg...) \
do { \
return FALSE; \
} while(0)
#endif
float scale_units[2][2];
const int I830CopyROP[16] =
{
ROP_0, /* GXclear */
ROP_DSa, /* GXand */
ROP_SDna, /* GXandReverse */
ROP_S, /* GXcopy */
ROP_DSna, /* GXandInverted */
ROP_D, /* GXnoop */
ROP_DSx, /* GXxor */
ROP_DSo, /* GXor */
ROP_DSon, /* GXnor */
ROP_DSxn, /* GXequiv */
ROP_Dn, /* GXinvert*/
ROP_SDno, /* GXorReverse */
ROP_Sn, /* GXcopyInverted */
ROP_DSno, /* GXorInverted */
ROP_DSan, /* GXnand */
ROP_1 /* GXset */
};
const int I830PatternROP[16] =
{
ROP_0,
ROP_DPa,
ROP_PDna,
ROP_P,
ROP_DPna,
ROP_D,
ROP_DPx,
ROP_DPo,
ROP_DPon,
ROP_PDxn,
ROP_Dn,
ROP_PDno,
ROP_Pn,
ROP_DPno,
ROP_DPan,
ROP_1
};
/* move to common.h */
union intfloat {
float f;
unsigned int ui;
};
#define OUT_RING_F(x) do { \
union intfloat tmp; \
tmp.f = (float)(x); \
OUT_RING(tmp.ui); \
} while(0)
Bool is_transform[2];
PictTransform *transform[2];
extern Bool I830EXACheckComposite(int, PicturePtr, PicturePtr, PicturePtr);
extern Bool I830EXAPrepareComposite(int, PicturePtr, PicturePtr, PicturePtr,
PixmapPtr, PixmapPtr, PixmapPtr);
extern Bool I915EXACheckComposite(int, PicturePtr, PicturePtr, PicturePtr);
extern Bool I915EXAPrepareComposite(int, PicturePtr, PicturePtr, PicturePtr,
PixmapPtr, PixmapPtr, PixmapPtr);
/**
* I830EXASync - wait for a command to finish
* @pScreen: current screen
* @marker: marker command to wait for
*
* Wait for the command specified by @marker to finish, then return. We don't
* actually do marker waits, though we might in the future. For now, just
* wait for a full idle.
*/
static void
I830EXASync(ScreenPtr pScreen, int marker)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Sync(pScrn);
}
/**
* I830EXAPrepareSolid - prepare for a Solid operation, if possible
*/
static Bool
I830EXAPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
{
ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
unsigned long offset, pitch;
if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planemask))
I830FALLBACK("planemask is not solid");
if (pPixmap->drawable.bitsPerPixel == 24)
I830FALLBACK("solid 24bpp unsupported!\n");
offset = exaGetPixmapOffset(pPixmap);
pitch = exaGetPixmapPitch(pPixmap);
if ( offset % pI830->EXADriverPtr->pixmapOffsetAlign != 0)
I830FALLBACK("pixmap offset not aligned");
if ( pitch % pI830->EXADriverPtr->pixmapPitchAlign != 0)
I830FALLBACK("pixmap pitch not aligned");
pI830->BR[13] = (pitch & 0xffff);
switch (pPixmap->drawable.bitsPerPixel) {
case 8:
break;
case 16:
/* RGB565 */
pI830->BR[13] |= (1 << 24);
break;
case 32:
/* RGB8888 */
pI830->BR[13] |= ((1 << 24) | (1 << 25));
break;
}
pI830->BR[13] |= (I830PatternROP[alu] & 0xff) << 16 ;
pI830->BR[16] = fg;
return TRUE;
}
static void
I830EXASolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
{
ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
unsigned long offset;
offset = exaGetPixmapOffset(pPixmap);
{
BEGIN_LP_RING(6);
if (pPixmap->drawable.bitsPerPixel == 32)
OUT_RING(XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA
| XY_COLOR_BLT_WRITE_RGB);
else
OUT_RING(XY_COLOR_BLT_CMD);
OUT_RING(pI830->BR[13]);
OUT_RING((y1 << 16) | (x1 & 0xffff));
OUT_RING((y2 << 16) | (x2 & 0xffff));
OUT_RING(offset);
OUT_RING(pI830->BR[16]);
ADVANCE_LP_RING();
}
}
static void
I830EXADoneSolid(PixmapPtr pPixmap)
{
#if ALWAYS_SYNC
ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
I830Sync(pScrn);
#endif
}
/**
* TODO:
* - support planemask using FULL_BLT_CMD?
*/
static Bool
I830EXAPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
int ydir, int alu, Pixel planemask)
{
ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
if (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planemask))
I830FALLBACK("planemask is not solid");
pI830->copy_src_pitch = exaGetPixmapPitch(pSrcPixmap);
pI830->copy_src_off = exaGetPixmapOffset(pSrcPixmap);
pI830->BR[13] = exaGetPixmapPitch(pDstPixmap);
pI830->BR[13] |= I830CopyROP[alu] << 16;
switch (pSrcPixmap->drawable.bitsPerPixel) {
case 8:
break;
case 16:
pI830->BR[13] |= (1 << 24);
break;
case 32:
pI830->BR[13] |= ((1 << 25) | (1 << 24));
break;
}
return TRUE;
}
static void
I830EXACopy(PixmapPtr pDstPixmap, int src_x1, int src_y1, int dst_x1,
int dst_y1, int w, int h)
{
ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
int dst_x2, dst_y2;
unsigned int dst_off;
dst_x2 = dst_x1 + w;
dst_y2 = dst_y1 + h;
dst_off = exaGetPixmapOffset(pDstPixmap);
{
BEGIN_LP_RING(8);
if (pDstPixmap->drawable.bitsPerPixel == 32)
OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
XY_SRC_COPY_BLT_WRITE_RGB);
else
OUT_RING(XY_SRC_COPY_BLT_CMD);
OUT_RING(pI830->BR[13]);
OUT_RING((dst_y1 << 16) | (dst_x1 & 0xffff));
OUT_RING((dst_y2 << 16) | (dst_x2 & 0xffff));
OUT_RING(dst_off);
OUT_RING((src_y1 << 16) | (src_x1 & 0xffff));
OUT_RING(pI830->copy_src_pitch);
OUT_RING(pI830->copy_src_off);
ADVANCE_LP_RING();
}
}
static void
I830EXADoneCopy(PixmapPtr pDstPixmap)
{
#if ALWAYS_SYNC
ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
I830Sync(pScrn);
#endif
}
static void
IntelEXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
int dstX, int dstY, int w, int h)
{
ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
int srcXend, srcYend, maskXend, maskYend;
PictVector v;
int pMask = 1;
DPRINTF(PFX, "Composite: srcX %d, srcY %d\n\t maskX %d, maskY %d\n\t"
"dstX %d, dstY %d\n\twidth %d, height %d\n\t"
"src_scale_x %f, src_scale_y %f, "
"mask_scale_x %f, mask_scale_y %f\n",
srcX, srcY, maskX, maskY, dstX, dstY, w, h,
scale_units[0][0], scale_units[0][1],
scale_units[1][0], scale_units[1][1]);
if (scale_units[1][0] == -1 || scale_units[1][1] == -1) {
pMask = 0;
}
srcXend = srcX + w;
srcYend = srcY + h;
maskXend = maskX + w;
maskYend = maskY + h;
if (is_transform[0]) {
v.vector[0] = IntToxFixed(srcX);
v.vector[1] = IntToxFixed(srcY);
v.vector[2] = xFixed1;
PictureTransformPoint(transform[0], &v);
srcX = xFixedToInt(v.vector[0]);
srcY = xFixedToInt(v.vector[1]);
v.vector[0] = IntToxFixed(srcXend);
v.vector[1] = IntToxFixed(srcYend);
v.vector[2] = xFixed1;
PictureTransformPoint(transform[0], &v);
srcXend = xFixedToInt(v.vector[0]);
srcYend = xFixedToInt(v.vector[1]);
}
if (is_transform[1]) {
v.vector[0] = IntToxFixed(maskX);
v.vector[1] = IntToxFixed(maskY);
v.vector[2] = xFixed1;
PictureTransformPoint(transform[1], &v);
maskX = xFixedToInt(v.vector[0]);
maskY = xFixedToInt(v.vector[1]);
v.vector[0] = IntToxFixed(maskXend);
v.vector[1] = IntToxFixed(maskYend);
v.vector[2] = xFixed1;
PictureTransformPoint(transform[1], &v);
maskXend = xFixedToInt(v.vector[0]);
maskYend = xFixedToInt(v.vector[1]);
}
DPRINTF(PFX, "After transform: srcX %d, srcY %d,srcXend %d, srcYend %d\n\t"
"maskX %d, maskY %d, maskXend %d, maskYend %d\n\t"
"dstX %d, dstY %d\n", srcX, srcY, srcXend, srcYend,
maskX, maskY, maskXend, maskYend, dstX, dstY);
{
int vertex_count;
if (pMask)
vertex_count = 4*6;
else
vertex_count = 4*4;
BEGIN_LP_RING(6+vertex_count);
OUT_RING(MI_NOOP);
OUT_RING(MI_NOOP);
OUT_RING(MI_NOOP);
OUT_RING(MI_NOOP);
OUT_RING(MI_NOOP);
OUT_RING(PRIM3D_INLINE | PRIM3D_TRIFAN | (vertex_count-1));
OUT_RING_F(dstX);
OUT_RING_F(dstY);
OUT_RING_F(srcX / scale_units[0][0]);
OUT_RING_F(srcY / scale_units[0][1]);
if (pMask) {
OUT_RING_F(maskX / scale_units[1][0]);
OUT_RING_F(maskY / scale_units[1][1]);
}
OUT_RING_F(dstX);
OUT_RING_F(dstY + h);
OUT_RING_F(srcX / scale_units[0][0]);
OUT_RING_F(srcYend / scale_units[0][1]);
if (pMask) {
OUT_RING_F(maskX / scale_units[1][0]);
OUT_RING_F(maskYend / scale_units[1][1]);
}
OUT_RING_F(dstX + w);
OUT_RING_F(dstY + h);
OUT_RING_F(srcXend / scale_units[0][0]);
OUT_RING_F(srcYend / scale_units[0][1]);
if (pMask) {
OUT_RING_F(maskXend / scale_units[1][0]);
OUT_RING_F(maskYend / scale_units[1][1]);
}
OUT_RING_F(dstX + w);
OUT_RING_F(dstY);
OUT_RING_F(srcXend / scale_units[0][0]);
OUT_RING_F(srcY / scale_units[0][1]);
if (pMask) {
OUT_RING_F(maskXend / scale_units[1][0]);
OUT_RING_F(maskY / scale_units[1][1]);
}
ADVANCE_LP_RING();
}
}
static void
IntelEXADoneComposite(PixmapPtr pDst)
{
#if ALWAYS_SYNC
ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
I830Sync(pScrn);
#endif
}
/*
* TODO:
* - Dual head?
*/
Bool
I830EXAInit(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
pI830->EXADriverPtr = exaDriverAlloc();
if (pI830->EXADriverPtr == NULL) {
pI830->noAccel = TRUE;
return FALSE;
}
memset(pI830->EXADriverPtr, 0, sizeof(*pI830->EXADriverPtr));
pI830->bufferOffset = 0;
pI830->EXADriverPtr->exa_major = 2;
pI830->EXADriverPtr->exa_minor = 0;
pI830->EXADriverPtr->memoryBase = pI830->FbBase;
pI830->EXADriverPtr->offScreenBase = pI830->Offscreen.Start;
pI830->EXADriverPtr->memorySize = pI830->Offscreen.End;
DPRINTF(PFX, "EXA Mem: memoryBase 0x%x, end 0x%x, offscreen base 0x%x, memorySize 0x%x\n",
pI830->EXADriverPtr->memoryBase,
pI830->EXADriverPtr->memoryBase + pI830->EXADriverPtr->memorySize,
pI830->EXADriverPtr->offScreenBase,
pI830->EXADriverPtr->memorySize);
if(pI830->EXADriverPtr->memorySize >
pI830->EXADriverPtr->offScreenBase)
pI830->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS;
else {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Not enough video RAM for "
"offscreen memory manager. Xv disabled\n");
/* disable Xv here... */
}
/* i915 3D requires 16 byte alignment (4k if tiled) */
pI830->EXADriverPtr->pixmapOffsetAlign = 256;
pI830->EXADriverPtr->pixmapPitchAlign = 64;
/* i845 and i945 2D limits rendering to 65536 lines and pitch of 32768. */
pI830->EXADriverPtr->maxX = 4095;
pI830->EXADriverPtr->maxY = 4095;
/* Sync */
pI830->EXADriverPtr->WaitMarker = I830EXASync;
/* Solid fill */
pI830->EXADriverPtr->PrepareSolid = I830EXAPrepareSolid;
pI830->EXADriverPtr->Solid = I830EXASolid;
pI830->EXADriverPtr->DoneSolid = I830EXADoneSolid;
/* Copy */
pI830->EXADriverPtr->PrepareCopy = I830EXAPrepareCopy;
pI830->EXADriverPtr->Copy = I830EXACopy;
pI830->EXADriverPtr->DoneCopy = I830EXADoneCopy;
/* Composite */
if (IS_I915G(pI830) || IS_I915GM(pI830) ||
IS_I945G(pI830) || IS_I945GM(pI830)) {
pI830->EXADriverPtr->CheckComposite = I915EXACheckComposite;
pI830->EXADriverPtr->PrepareComposite = I915EXAPrepareComposite;
pI830->EXADriverPtr->Composite = IntelEXAComposite;
pI830->EXADriverPtr->DoneComposite = IntelEXADoneComposite;
} else if (IS_I865G(pI830) || IS_I855(pI830) ||
IS_845G(pI830) || IS_I830(pI830)) {
pI830->EXADriverPtr->CheckComposite = I830EXACheckComposite;
pI830->EXADriverPtr->PrepareComposite = I830EXAPrepareComposite;
pI830->EXADriverPtr->Composite = IntelEXAComposite;
pI830->EXADriverPtr->DoneComposite = IntelEXADoneComposite;
}
if(!exaDriverInit(pScreen, pI830->EXADriverPtr)) {
xfree(pI830->EXADriverPtr);
pI830->noAccel = TRUE;
return FALSE;
}
I830SelectBuffer(pScrn, I830_SELECT_FRONT);
return TRUE;
}

514
src/i830_exa_render.c Normal file
View File

@ -0,0 +1,514 @@
/*
* Copyright © 2006 Intel Corporation
*
* 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, sublicense,
* 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 NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS 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.
*
* Authors:
* Wang Zhenyu <zhenyu.z.wang@intel.com>
* Eric Anholt <eric@anholt.net>
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "xf86.h"
#include "i830.h"
#include "i830_reg.h"
#ifdef I830DEBUG
#define DEBUG_I830FALLBACK 1
#endif
#ifdef DEBUG_I830FALLBACK
#define I830FALLBACK(s, arg...) \
do { \
DPRINTF(PFX, "EXA fallback: " s "\n", ##arg); \
return FALSE; \
} while(0)
#else
#define I830FALLBACK(s, arg...) \
do { \
return FALSE; \
} while(0)
#endif
extern float scale_units[2][2];
extern Bool is_transform[2];
extern PictTransform *transform[2];
struct blendinfo {
Bool dst_alpha;
Bool src_alpha;
CARD32 src_blend;
CARD32 dst_blend;
};
struct formatinfo {
int fmt;
CARD32 card_fmt;
};
extern Bool
I830EXACheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
PicturePtr pDstPicture);
extern Bool
I830EXAPrepareComposite(int op, PicturePtr pSrcPicture,
PicturePtr pMaskPicture, PicturePtr pDstPicture,
PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst);
#define TB0C_LAST_STAGE (1 << 31)
#define TB0C_RESULT_SCALE_1X (0 << 29)
#define TB0C_RESULT_SCALE_2X (1 << 29)
#define TB0C_RESULT_SCALE_4X (2 << 29)
#define TB0C_OP_MODULE (3 << 25)
#define TB0C_OUTPUT_WRITE_CURRENT (0 << 24)
#define TB0C_OUTPUT_WRITE_ACCUM (1 << 24)
#define TB0C_ARG3_REPLICATE_ALPHA (1<<23)
#define TB0C_ARG3_INVERT (1<<22)
#define TB0C_ARG3_SEL_XXX
#define TB0C_ARG2_REPLICATE_ALPHA (1<<17)
#define TB0C_ARG2_INVERT (1<<16)
#define TB0C_ARG2_SEL_ONE (0 << 12)
#define TB0C_ARG2_SEL_FACTOR (1 << 12)
#define TB0C_ARG2_SEL_TEXEL0 (6 << 12)
#define TB0C_ARG2_SEL_TEXEL1 (7 << 12)
#define TB0C_ARG2_SEL_TEXEL2 (8 << 12)
#define TB0C_ARG2_SEL_TEXEL3 (9 << 12)
#define TB0C_ARG1_REPLICATE_ALPHA (1<<11)
#define TB0C_ARG1_INVERT (1<<10)
#define TB0C_ARG1_SEL_TEXEL0 (6 << 6)
#define TB0C_ARG1_SEL_TEXEL1 (7 << 6)
#define TB0C_ARG1_SEL_TEXEL2 (8 << 6)
#define TB0C_ARG1_SEL_TEXEL3 (9 << 6)
#define TB0C_ARG0_REPLICATE_ALPHA (1<<5)
#define TB0C_ARG0_SEL_XXX
#define TB0A_CTR_STAGE_ENABLE (1<<31)
#define TB0A_RESULT_SCALE_1X (0 << 29)
#define TB0A_RESULT_SCALE_2X (1 << 29)
#define TB0A_RESULT_SCALE_4X (2 << 29)
#define TB0A_OP_MODULE (3 << 25)
#define TB0A_OUTPUT_WRITE_CURRENT (0<<24)
#define TB0A_OUTPUT_WRITE_ACCUM (1<<24)
#define TB0A_CTR_STAGE_SEL_BITS_XXX
#define TB0A_ARG3_SEL_XXX
#define TB0A_ARG3_INVERT (1<<17)
#define TB0A_ARG2_INVERT (1<<16)
#define TB0A_ARG2_SEL_ONE (0 << 12)
#define TB0A_ARG2_SEL_TEXEL0 (6 << 12)
#define TB0A_ARG2_SEL_TEXEL1 (7 << 12)
#define TB0A_ARG2_SEL_TEXEL2 (8 << 12)
#define TB0A_ARG2_SEL_TEXEL3 (9 << 12)
#define TB0A_ARG1_INVERT (1<<10)
#define TB0A_ARG1_SEL_TEXEL0 (6 << 6)
#define TB0A_ARG1_SEL_TEXEL1 (7 << 6)
#define TB0A_ARG1_SEL_TEXEL2 (8 << 6)
#define TB0A_ARG1_SEL_TEXEL3 (9 << 6)
static struct blendinfo I830BlendOp[] = {
/* Clear */
{0, 0, BLENDFACTOR_ZERO, BLENDFACTOR_ZERO},
/* Src */
{0, 0, BLENDFACTOR_ONE, BLENDFACTOR_ZERO},
/* Dst */
{0, 0, BLENDFACTOR_ZERO, BLENDFACTOR_ONE},
/* Over */
{0, 1, BLENDFACTOR_ONE, BLENDFACTOR_INV_SRC_ALPHA},
/* OverReverse */
{1, 0, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_ONE},
/* In */
{1, 0, BLENDFACTOR_DST_ALPHA, BLENDFACTOR_ZERO},
/* InReverse */
{0, 1, BLENDFACTOR_ZERO, BLENDFACTOR_SRC_ALPHA},
/* Out */
{1, 0, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_ZERO},
/* OutReverse */
{0, 1, BLENDFACTOR_ZERO, BLENDFACTOR_INV_SRC_ALPHA},
/* Atop */
{1, 1, BLENDFACTOR_DST_ALPHA, BLENDFACTOR_INV_SRC_ALPHA},
/* AtopReverse */
{1, 1, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_SRC_ALPHA},
/* Xor */
{1, 1, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_INV_SRC_ALPHA},
/* Add */
{0, 0, BLENDFACTOR_ONE, BLENDFACTOR_ONE},
};
static struct formatinfo I830TexFormats[] = {
{PICT_a8r8g8b8, MT_32BIT_ARGB8888 },
{PICT_x8r8g8b8, MT_32BIT_ARGB8888 },
{PICT_a8b8g8r8, MT_32BIT_ABGR8888 },
{PICT_x8b8g8r8, MT_32BIT_ABGR8888 },
{PICT_r5g6b5, MT_16BIT_RGB565 },
{PICT_a1r5g5b5, MT_16BIT_ARGB1555 },
{PICT_x1r5g5b5, MT_16BIT_ARGB1555 },
{PICT_a8, MT_8BIT_I8 },
};
static Bool I830GetDestFormat(PicturePtr pDstPicture, CARD32 *dst_format)
{
/* XXX: color buffer format for i830 */
switch (pDstPicture->format) {
case PICT_a8r8g8b8:
case PICT_x8r8g8b8:
*dst_format = COLR_BUF_ARGB8888;
break;
case PICT_r5g6b5:
*dst_format = COLR_BUF_RGB565;
break;
case PICT_a1r5g5b5:
case PICT_x1r5g5b5:
*dst_format = COLR_BUF_ARGB1555;
break;
case PICT_a8:
*dst_format = COLR_BUF_8BIT;
break;
case PICT_a4r4g4b4:
case PICT_x4r4g4b4:
*dst_format = COLR_BUF_ARGB4444;
break;
default:
I830FALLBACK("Unsupported dest format 0x%x\n",
(int)pDstPicture->format);
}
return TRUE;
}
static CARD32 I830GetBlendCntl(int op, PicturePtr pMask, CARD32 dst_format)
{
CARD32 sblend, dblend;
sblend = I830BlendOp[op].src_blend;
dblend = I830BlendOp[op].dst_blend;
/* If there's no dst alpha channel, adjust the blend op so that we'll treat
* it as always 1.
*/
if (PICT_FORMAT_A(dst_format) == 0 && I830BlendOp[op].dst_alpha) {
if (sblend == BLENDFACTOR_DST_ALPHA)
sblend = BLENDFACTOR_ONE;
else if (sblend == BLENDFACTOR_INV_DST_ALPHA)
sblend = BLENDFACTOR_ZERO;
}
/* If the source alpha is being used, then we should only be in a case where
* the source blend factor is 0, and the source blend value is the mask
* channels multiplied by the source picture's alpha.
*/
if (pMask && pMask->componentAlpha && I830BlendOp[op].src_alpha) {
if (dblend == BLENDFACTOR_SRC_ALPHA) {
dblend = BLENDFACTOR_SRC_COLR;
} else if (dblend == BLENDFACTOR_INV_SRC_ALPHA) {
dblend = BLENDFACTOR_INV_SRC_COLR;
}
}
return (sblend << S8_SRC_BLEND_FACTOR_SHIFT) |
(dblend << S8_DST_BLEND_FACTOR_SHIFT);
}
static Bool I830CheckCompositeTexture(PicturePtr pPict, int unit)
{
int w = pPict->pDrawable->width;
int h = pPict->pDrawable->height;
int i;
if ((w > 0x7ff) || (h > 0x7ff))
I830FALLBACK("Picture w/h too large (%dx%d)\n", w, h);
for (i = 0; i < sizeof(I830TexFormats) / sizeof(I830TexFormats[0]); i++)
{
if (I830TexFormats[i].fmt == pPict->format)
break;
}
if (i == sizeof(I830TexFormats) / sizeof(I830TexFormats[0]))
I830FALLBACK("Unsupported picture format 0x%x\n",
(int)pPict->format);
/* FIXME: fix repeat support */
if (pPict->repeat)
I830FALLBACK("repeat unsupport now\n");
if (pPict->filter != PictFilterNearest &&
pPict->filter != PictFilterBilinear)
I830FALLBACK("Unsupported filter 0x%x\n", pPict->filter);
return TRUE;
}
static Bool
I830TextureSetup(PicturePtr pPict, PixmapPtr pPix, int unit)
{
ScrnInfoPtr pScrn = xf86Screens[pPict->pDrawable->pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
CARD32 format, offset, pitch, filter;
int w, h, i;
CARD32 wrap_mode = TEXCOORDMODE_CLAMP;
offset = exaGetPixmapOffset(pPix);
pitch = exaGetPixmapPitch(pPix);
w = pPict->pDrawable->width;
h = pPict->pDrawable->height;
scale_units[unit][0] = pPix->drawable.width;
scale_units[unit][1] = pPix->drawable.height;
for (i = 0; i < sizeof(I830TexFormats) / sizeof(I830TexFormats[0]); i++) {
if (I830TexFormats[i].fmt == pPict->format)
break;
}
if ( i == sizeof(I830TexFormats)/ sizeof(I830TexFormats[0]) )
I830FALLBACK("unknown texture format\n");
format = I830TexFormats[i].card_fmt;
if (pPict->repeat)
wrap_mode = TEXCOORDMODE_WRAP; /* XXX: correct ? */
switch (pPict->filter) {
case PictFilterNearest:
filter = ((FILTER_NEAREST<<TM0S3_MAG_FILTER_SHIFT) |
(FILTER_NEAREST<<TM0S3_MIN_FILTER_SHIFT));
break;
case PictFilterBilinear:
filter = ((FILTER_LINEAR<<TM0S3_MAG_FILTER_SHIFT) |
(FILTER_LINEAR<<TM0S3_MIN_FILTER_SHIFT));
break;
default:
filter = 0;
I830FALLBACK("Bad filter 0x%x\n", pPict->filter);
}
{
if (pPix->drawable.bitsPerPixel == 8)
format |= MAP_SURFACE_8BIT;
else if (pPix->drawable.bitsPerPixel == 16)
format |= MAP_SURFACE_16BIT;
else
format |= MAP_SURFACE_32BIT;
BEGIN_LP_RING(6);
OUT_RING(_3DSTATE_MAP_INFO_CMD);
OUT_RING(format | TEXMAP_INDEX(unit) | MAP_FORMAT_2D);
OUT_RING(((pPix->drawable.height - 1) << 16) |
(pPix->drawable.width - 1)); /* height, width */
OUT_RING(offset); /* map address */
OUT_RING(((pitch / 4) - 1) << 2); /* map pitch */
OUT_RING(0);
ADVANCE_LP_RING();
}
{
BEGIN_LP_RING(2);
/* coord sets */
OUT_RING(_3DSTATE_MAP_COORD_SET_CMD | TEXCOORD_SET(unit) |
ENABLE_TEXCOORD_PARAMS | TEXCOORDS_ARE_NORMAL |
TEXCOORDTYPE_CARTESIAN | ENABLE_ADDR_V_CNTL |
TEXCOORD_ADDR_V_MODE(wrap_mode) |
ENABLE_ADDR_U_CNTL | TEXCOORD_ADDR_U_MODE(wrap_mode));
OUT_RING(MI_NOOP);
/* XXX: filter seems hang engine...*/
#if 0
OUT_RING(I830_STATE3D_MAP_FILTER | FILTER_MAP_INDEX(unit) | ENABLE_KEYS| DISABLE_COLOR_KEY | DISABLE_CHROMA_KEY | DISABLE_KILL_PIXEL |ENABLE_MIP_MODE_FILTER | MIPFILTER_NONE | filter);
OUT_RING(0);
#endif
/* max & min mip level ? or base mip level? */
ADVANCE_LP_RING();
}
/* XXX */
if (pPict->transform != 0) {
is_transform[unit] = TRUE;
transform[unit] = pPict->transform;
} else {
is_transform[unit] = FALSE;
}
#ifdef I830DEBUG
ErrorF("try to sync to show any errors...");
I830Sync(pScrn);
#endif
return TRUE;
}
Bool
I830EXACheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
PicturePtr pDstPicture)
{
CARD32 tmp1;
/* Check for unsupported compositing operations. */
if (op >= sizeof(I830BlendOp) / sizeof(I830BlendOp[0]))
I830FALLBACK("Unsupported Composite op 0x%x\n", op);
if (pMaskPicture != NULL && pMaskPicture->componentAlpha) {
/* Check if it's component alpha that relies on a source alpha and on
* the source value. We can only get one of those into the single
* source value that we get to blend with.
*/
if (I830BlendOp[op].src_alpha &&
(I830BlendOp[op].src_blend != BLENDFACTOR_ZERO))
I830FALLBACK("Component alpha not supported with source "
"alpha and source value blending.\n");
}
if (!I830CheckCompositeTexture(pSrcPicture, 0))
I830FALLBACK("Check Src picture texture\n");
if (pMaskPicture != NULL && !I830CheckCompositeTexture(pMaskPicture, 1))
I830FALLBACK("Check Mask picture texture\n");
if (!I830GetDestFormat(pDstPicture, &tmp1))
I830FALLBACK("Get Color buffer format\n");
return TRUE;
}
Bool
I830EXAPrepareComposite(int op, PicturePtr pSrcPicture,
PicturePtr pMaskPicture, PicturePtr pDstPicture,
PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
{
/* XXX: setup texture map from pixmap, vertex format, blend cntl */
ScrnInfoPtr pScrn = xf86Screens[pSrcPicture->pDrawable->pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
CARD32 dst_format, dst_offset, dst_pitch;
I830GetDestFormat(pDstPicture, &dst_format);
dst_offset = exaGetPixmapOffset(pDst);
dst_pitch = exaGetPixmapPitch(pDst);
pI830->last_3d = LAST_3D_RENDER;
if (!I830TextureSetup(pSrcPicture, pSrc, 0))
I830FALLBACK("fail to setup src texture\n");
if (pMask != NULL) {
if (!I830TextureSetup(pMaskPicture, pMask, 1))
I830FALLBACK("fail to setup mask texture\n");
} else {
is_transform[1] = FALSE;
scale_units[1][0] = -1;
scale_units[1][1] = -1;
}
{
CARD32 cblend, ablend, blendctl, vf2;
BEGIN_LP_RING(22+6);
/*color buffer*/
OUT_RING(_3DSTATE_BUF_INFO_CMD);
OUT_RING(BUF_3D_ID_COLOR_BACK| BUF_3D_PITCH(dst_pitch));
OUT_RING(BUF_3D_ADDR(dst_offset));
OUT_RING(MI_NOOP);
OUT_RING(_3DSTATE_DST_BUF_VARS_CMD);
OUT_RING(dst_format);
OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
OUT_RING(MI_NOOP); /* pad to quadword */
/* defaults */
OUT_RING(_3DSTATE_DFLT_Z_CMD);
OUT_RING(0);
OUT_RING(_3DSTATE_DFLT_DIFFUSE_CMD);
OUT_RING(0);
OUT_RING(_3DSTATE_DFLT_SPEC_CMD);
OUT_RING(0);
OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | 0);
OUT_RING((1 << S3_POINT_WIDTH_SHIFT) | (2 << S3_LINE_WIDTH_SHIFT) |
S3_CULLMODE_NONE | S3_VERTEXHAS_XY);
OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | 0);
if (pMask)
vf2 = 2 << 12; /* 2 texture coord sets */
else
vf2 = 1 << 12;
vf2 |= (TEXCOORDFMT_2D << 16);
if (pMask)
vf2 |= (TEXCOORDFMT_2D << 18);
else
vf2 |= (TEXCOORDFMT_1D << 18);
vf2 |= (TEXCOORDFMT_1D << 20);
vf2 |= (TEXCOORDFMT_1D << 22);
vf2 |= (TEXCOORDFMT_1D << 24);
vf2 |= (TEXCOORDFMT_1D << 26);
vf2 |= (TEXCOORDFMT_1D << 28);
vf2 |= (TEXCOORDFMT_1D << 30);
OUT_RING(vf2);
OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
OUT_RING(MI_NOOP); /* pad to quadword */
/* For (src In mask) operation */
/* IN operator: Multiply src by mask components or mask alpha.*/
/* TEXBLENDOP_MODULE: arg1*arg2 */
cblend = TB0C_LAST_STAGE | TB0C_RESULT_SCALE_1X | TB0C_OP_MODULE |
TB0C_OUTPUT_WRITE_CURRENT;
ablend = TB0A_RESULT_SCALE_1X | TB0A_OP_MODULE |
TB0A_OUTPUT_WRITE_CURRENT;
cblend |= TB0C_ARG1_SEL_TEXEL0;
ablend |= TB0A_ARG1_SEL_TEXEL0;
if (pMask) {
if (pMaskPicture->componentAlpha && pDstPicture->format != PICT_a8)
cblend |= TB0C_ARG2_SEL_TEXEL1;
else
cblend |= (TB0C_ARG2_SEL_TEXEL1 | TB0C_ARG2_REPLICATE_ALPHA);
ablend |= TB0A_ARG2_SEL_TEXEL1;
} else {
cblend |= TB0C_ARG2_SEL_ONE;
ablend |= TB0A_ARG2_SEL_ONE;
}
OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_2 | LOAD_TEXTURE_BLEND_STAGE(0)|1);
OUT_RING(cblend);
OUT_RING(ablend);
OUT_RING(0);
OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
OUT_RING(MI_NOOP); /* pad to quadword */
blendctl = I830GetBlendCntl(op, pMaskPicture, pDstPicture->format);
OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(8) | 0);
OUT_RING(S8_ENABLE_COLOR_BLEND | S8_BLENDFUNC_ADD |(blendctl<<4) |
S8_ENABLE_COLOR_BUFFER_WRITE);
ADVANCE_LP_RING();
}
#ifdef I830DEBUG
Error("try to sync to show any errors...");
I830Sync(pScrn);
#endif
return TRUE;
}

View File

@ -870,6 +870,34 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
}
return FALSE;
}
#ifdef I830_USE_EXA
size = lineSize * pScrn->virtualY;
size = ROUND_TO_PAGE(size);
if (tileable) {
align = KB(512);
alignflags = ALIGN_BOTH_ENDS;
} else {
align = KB(64);
alignflags = 0;
}
alloced = I830AllocVidMem(pScrn, &(pI830->Offscreen),
&(pI830->StolenPool), size, align,
flags | alignflags |
FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
if (alloced < size) {
if (!dryrun) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate "
"offscreen memory. Not enough VRAM?\n");
}
return FALSE;
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Successful allocate "
"offscreen memory at 0x%lx, size %ld KB\n",
pI830->Offscreen.Start, pI830->Offscreen.Size/1024);
}
#endif
} else {
long lineSize;
long extra = 0;

View File

@ -31,6 +31,23 @@
#define I830_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value)
#define CMD_3D (0x3<<29)
#define PRIM3D_INLINE (CMD_3D | (0x1f<<24))
#define PRIM3D_TRILIST (0x0<<18)
#define PRIM3D_TRISTRIP (0x1<<18)
#define PRIM3D_TRISTRIP_RVRSE (0x2<<18)
#define PRIM3D_TRIFAN (0x3<<18)
#define PRIM3D_POLY (0x4<<18)
#define PRIM3D_LINELIST (0x5<<18)
#define PRIM3D_LINESTRIP (0x6<<18)
#define PRIM3D_RECTLIST (0x7<<18)
#define PRIM3D_POINTLIST (0x8<<18)
#define PRIM3D_DIB (0x9<<18)
#define PRIM3D_CLEAR_RECT (0xa<<18)
#define PRIM3D_ZONE_INIT (0xd<<18)
#define PRIM3D_MASK (0x1f<<18)
#define _3DSTATE_AA_CMD (CMD_3D | (0x06<<24))
#define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16)
#define AA_LINE_ECAAR_WIDTH_0_5 0
@ -85,6 +102,8 @@
#define COLR_BUF_RGB555 (1<<8)
#define COLR_BUF_RGB565 (2<<8)
#define COLR_BUF_ARGB8888 (3<<8)
#define COLR_BUF_ARGB4444 (8<<8)
#define COLR_BUF_ARGB1555 (9<<8)
#define DEPTH_IS_Z 0
#define DEPTH_IS_W (1<<6)
#define DEPTH_FRMT_16_FIXED 0
@ -202,6 +221,22 @@
#define ENABLE_DST_ABLEND_FACTOR (1<<5)
#define DST_ABLEND_FACT(x) (x)
#define BLENDFACTOR_ZERO 0x01
#define BLENDFACTOR_ONE 0x02
#define BLENDFACTOR_SRC_COLR 0x03
#define BLENDFACTOR_INV_SRC_COLR 0x04
#define BLENDFACTOR_SRC_ALPHA 0x05
#define BLENDFACTOR_INV_SRC_ALPHA 0x06
#define BLENDFACTOR_DST_ALPHA 0x07
#define BLENDFACTOR_INV_DST_ALPHA 0x08
#define BLENDFACTOR_DST_COLR 0x09
#define BLENDFACTOR_INV_DST_COLR 0x0a
#define BLENDFACTOR_SRC_ALPHA_SATURATE 0x0b
#define BLENDFACTOR_CONST_COLOR 0x0c
#define BLENDFACTOR_INV_CONST_COLOR 0x0d
#define BLENDFACTOR_CONST_ALPHA 0x0e
#define BLENDFACTOR_INV_CONST_ALPHA 0x0f
#define BLENDFACTOR_MASK 0x0f
/* _3DSTATE_MAP_BLEND_ARG, p152 */
#define _3DSTATE_MAP_BLEND_ARG_CMD(stage) (CMD_3D|(0x0e<<24)|((stage)<<20))
@ -301,6 +336,7 @@
/* _3DSTATE_MAP_COORD_SETS, p164 */
#define _3DSTATE_MAP_COORD_SET_CMD (CMD_3D|(0x1c<<24)|(0x01<<19))
#define TEXCOORD_SET(n) ((n)<<16)
#define ENABLE_TEXCOORD_PARAMS (1<<15)
#define TEXCOORDS_ARE_NORMAL (1<<14)
#define TEXCOORDS_ARE_IN_TEXELUNITS 0
@ -329,6 +365,13 @@
#define CUBE_NEGZ_ENABLE (1<<1)
#define CUBE_POSZ_ENABLE (1<<0)
#define _3DSTATE_MAP_INFO_CMD (CMD_3D|(0x1d<<24)|(0x0<<16)|3)
#define TEXMAP_INDEX(x) ((x)<<28)
#define MAP_SURFACE_8BIT (1<<24)
#define MAP_SURFACE_16BIT (2<<24)
#define MAP_SURFACE_32BIT (3<<24)
#define MAP_FORMAT_2D (0)
#define MAP_FORMAT_3D_CUBE (1<<11)
/* _3DSTATE_MODES_1, p190 */
#define _3DSTATE_MODES_1_CMD (CMD_3D|(0x08<<24))
@ -523,14 +566,57 @@
/* Stipple command, carried over from the i810, apparently:
*/
#define _3DSTATE_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
#define _3DSTATE_STIPPLE (CMD_3D|(0x1d<<24)|(0x83<<16))
#define ST1_ENABLE (1<<16)
#define ST1_MASK (0xffff)
#define _3DSTATE_LOAD_STATE_IMMEDIATE_1 (CMD_3D|(0x1d<<24)|(0x04<<16))
#define I1_LOAD_S(n) (1<<((n)+4))
#define S3_POINT_WIDTH_SHIFT 23
#define S3_LINE_WIDTH_SHIFT 19
#define S3_ALPHA_SHADE_MODE_SHIFT 18
#define S3_FOG_SHADE_MODE_SHIFT 17
#define S3_SPEC_SHADE_MODE_SHIFT 16
#define S3_COLOR_SHADE_MODE_SHIFT 15
#define S3_CULL_MODE_SHIFT 13
#define S3_CULLMODE_BOTH (0)
#define S3_CULLMODE_NONE (1<<13)
#define S3_CULLMODE_CW (2<<13)
#define S3_CULLMODE_CCW (3<<13)
#define S3_POINT_WIDTH_PRESENT (1<<12)
#define S3_SPEC_FOG_PRESENT (1<<11)
#define S3_DIFFUSE_PRESENT (1<<10)
#define S3_DEPTH_OFFSET_PRESENT (1<<9)
#define S3_POSITION_SHIFT 6
#define S3_VERTEXHAS_XYZ (1<<6)
#define S3_VERTEXHAS_XYZW (2<<6)
#define S3_VERTEXHAS_XY (3<<6)
#define S3_VERTEXHAS_XYW (4<<6)
#define S3_ENABLE_SPEC_ADD (1<<5)
#define S3_ENABLE_FOG (1<<4)
#define S3_ENABLE_LOCAL_DEPTH_BIAS (1<<3)
#define S3_ENABLE_SPRITE_POINT (1<<1)
#define S3_ENABLE_ANTIALIASING 1
#define S8_ENABLE_ALPHA_TEST (1<<31)
#define S8_ALPHA_TEST_FUNC_SHIFT 28
#define S8_ALPHA_REFVALUE_SHIFT 20
#define S8_ENABLE_DEPTH_TEST (1<<19)
#define S8_DEPTH_TEST_FUNC_SHIFT 16
#define S8_ENABLE_COLOR_BLEND (1<<15)
#define S8_COLOR_BLEND_FUNC_SHIFT 12
#define S8_BLENDFUNC_ADD (0)
#define S8_BLENDFUNC_SUB (1<<12)
#define S8_BLENDFUNC_RVRSE_SUB (2<<12)
#define S8_BLENDFUNC_MIN (3<<12)
#define S8_BLENDFUNC_MAX (4<<12)
#define S8_SRC_BLEND_FACTOR_SHIFT 8
#define S8_DST_BLEND_FACTOR_SHIFT 4
#define S8_ENABLE_DEPTH_BUFFER_WRITE (1<<3)
#define S8_ENABLE_COLOR_BUFFER_WRITE (1<<2)
#define _3DSTATE_LOAD_STATE_IMMEDIATE_2 ((0x3<<29)|(0x1d<<24)|(0x03<<16))
#define LOAD_TEXTURE_MAP0 (1<<11)
#define _3DSTATE_LOAD_STATE_IMMEDIATE_2 (CMD_3D|(0x1d<<24)|(0x03<<16))
#define LOAD_TEXTURE_MAP(x) (1<<((x)+11))
#define LOAD_TEXTURE_BLEND_STAGE(x) (1<<((x)+7))
#define LOAD_GLOBAL_COLOR_FACTOR (1<<6)
#define TM0S0_ADDRESS_MASK 0xfffffffc
@ -591,6 +677,8 @@
#define TM0S2_CUBE_FACE_ENA_SHIFT 15
#define TM0S2_CUBE_FACE_ENA_MASK (1<<15)
#define TM0S2_MAP_FORMAT (1<<14)
#define TM0S2_MAP_2D (0<<14)
#define TM0S2_MAP_3D_CUBE (1<<14)
#define TM0S2_VERTICAL_LINE_STRIDE (1<<13)
#define TM0S2_VERITCAL_LINE_STRIDE_OFF (1<<12)
#define TM0S2_OUTPUT_CHAN_SHIFT 10
@ -634,4 +722,23 @@
#define FLUSH_MAP_CACHE (1<<0)
#define _3DSTATE_MAP_FILTER_CMD (CMD_3D|(0x1c<<24)|(0x02<<19))
#define FILTER_TEXMAP_INDEX(x) ((x) << 16)
#define MAG_MODE_FILTER_ENABLE (1 << 5)
#define MIN_MODE_FILTER_ENABLE (1 << 2)
#define MAG_MAPFILTER_NEAREST (0 << 3)
#define MAG_MAPFILTER_LINEAR (1 << 3)
#define MAG_MAPFILTER_ANISOTROPIC (2 << 3)
#define MIN_MAPFILTER_NEAREST (0)
#define MIN_MAPFILTER_LINEAR (1)
#define MIN_MAPFILTER_ANISOTROPIC (2)
#define ENABLE_KEYS (1<<15)
#define DISABLE_COLOR_KEY 0
#define DISABLE_CHROMA_KEY 0
#define DISABLE_KILL_PIXEL 0
#define ENABLE_MIP_MODE_FILTER (1 << 9)
#define MIPFILTER_NONE 0
#define MIPFILTER_NEAREST 1
#define MIPFILTER_LINEAR 3
#endif

View File

@ -211,11 +211,6 @@ I915UpdateRotate (ScreenPtr pScreen,
struct matrix23 rotMatrix;
int j;
int use_fence;
Bool updateInvarient = FALSE;
#ifdef XF86DRI
drmI830Sarea *sarea = NULL;
drm_context_t myContext = 0;
#endif
Bool didLock = FALSE;
if (I830IsPrimary(pScrn)) {
@ -246,58 +241,20 @@ I915UpdateRotate (ScreenPtr pScreen,
}
#ifdef XF86DRI
if (pI8301->directRenderingEnabled) {
sarea = DRIGetSAREAPrivate(pScrn1->pScreen);
myContext = DRIGetContext(pScrn1->pScreen);
if (pI8301->directRenderingEnabled)
didLock = I830DRILock(pScrn1);
}
#endif
/* If another screen was active, we don't know the current state. */
if (pScrn->scrnIndex != *pI830->used3D)
updateInvarient = TRUE;
#ifdef XF86DRI
if (sarea && sarea->ctxOwner != myContext)
updateInvarient = TRUE;
#endif
pI830->last_3d = LAST_3D_OTHER;
if (updateInvarient) {
if (pI830->last_3d != LAST_3D_ROTATION) {
FS_LOCALS(3);
*pI830->used3D = pScrn->scrnIndex;
#ifdef XF86DRI
if (sarea)
sarea->ctxOwner = myContext;
#endif
BEGIN_LP_RING(54);
BEGIN_LP_RING(34);
/* invarient state */
OUT_RING(MI_NOOP);
OUT_RING(_3DSTATE_AA_CMD |
AA_LINE_ECAAR_WIDTH_ENABLE | AA_LINE_ECAAR_WIDTH_1_0 |
AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0);
OUT_RING(_3DSTATE_DFLT_DIFFUSE_CMD);
OUT_RING(0x00000000);
OUT_RING(_3DSTATE_DFLT_SPEC_CMD);
OUT_RING(0x00000000);
OUT_RING(_3DSTATE_DFLT_Z_CMD);
OUT_RING(0x00000000);
OUT_RING(_3DSTATE_COORD_SET_BINDINGS |
CSB_TCB(0, 0) | CSB_TCB(1, 1) |
CSB_TCB(2, 2) | CSB_TCB(3, 3) |
CSB_TCB(4, 4) | CSB_TCB(5, 5) |
CSB_TCB(6, 6) | CSB_TCB(7, 7));
OUT_RING(_3DSTATE_RASTER_RULES_CMD |
ENABLE_TRI_FAN_PROVOKE_VRTX | TRI_FAN_PROVOKE_VRTX(2) |
ENABLE_LINE_STRIP_PROVOKE_VRTX | LINE_STRIP_PROVOKE_VRTX(1) |
ENABLE_TEXKILL_3D_4D | TEXKILL_4D |
ENABLE_POINT_RASTER_RULE | OGL_POINT_RASTER_RULE);
OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | 1);
OUT_RING(0x00000000);
/* flush map & render cache */
OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
@ -313,24 +270,13 @@ I915UpdateRotate (ScreenPtr pScreen,
OUT_RING(MI_NOOP);
OUT_RING(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
OUT_RING(_3DSTATE_SCISSOR_RECT_0_CMD);
OUT_RING(0x00000000); /* ymin, xmin */
OUT_RING(0x00000000); /* ymax, xmax */
OUT_RING(0x7c000003); /* XXX: magic numbers */
OUT_RING(0x7d070000);
OUT_RING(0x00000000);
OUT_RING(0x68000002);
/* context setup */
OUT_RING(_3DSTATE_MODES_4_CMD |
ENABLE_LOGIC_OP_FUNC | LOGIC_OP_FUNC(LOGICOP_COPY) |
MODE4_ENABLE_STENCIL_WRITE_MASK |
MODE4_ENABLE_STENCIL_TEST_MASK);
OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
I1_LOAD_S(2) | I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 4);
I1_LOAD_S(2) | I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 3);
OUT_RING(S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) |
S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) |
@ -349,14 +295,6 @@ I915UpdateRotate (ScreenPtr pScreen,
(1 << S6_CBUF_DST_BLEND_FACT_SHIFT) | S6_COLOR_WRITE_ENABLE |
(2 << S6_TRISTRIP_PV_SHIFT));
OUT_RING(_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD |
IAB_MODIFY_ENABLE |
IAB_MODIFY_FUNC | (BLENDFUNC_ADD << IAB_FUNC_SHIFT) |
IAB_MODIFY_SRC_FACTOR |
(BLENDFACT_ONE << IAB_SRC_FACTOR_SHIFT) |
IAB_MODIFY_DST_FACTOR |
(BLENDFACT_ZERO << IAB_DST_FACTOR_SHIFT));
OUT_RING(_3DSTATE_CONST_BLEND_COLOR_CMD);
OUT_RING(0x00000000);
@ -373,9 +311,6 @@ I915UpdateRotate (ScreenPtr pScreen,
DEPTH_FRMT_24_FIXED_8_OTHER);
}
OUT_RING(_3DSTATE_STIPPLE);
OUT_RING(0x00000000);
/* texture sampler state */
OUT_RING(_3DSTATE_SAMPLER_STATE | 3);
OUT_RING(0x00000001);
@ -493,13 +428,8 @@ I830UpdateRotate (ScreenPtr pScreen,
CARD32 vb[32]; /* 32 dword vertex buffer */
float verts[4][2], tex[4][2];
struct matrix23 rotMatrix;
Bool updateInvarient = FALSE;
int use_fence;
int j;
#ifdef XF86DRI
drmI830Sarea *sarea = NULL;
drm_context_t myContext = 0;
#endif
Bool didLock = FALSE;
if (I830IsPrimary(pScrn)) {
@ -530,28 +460,18 @@ I830UpdateRotate (ScreenPtr pScreen,
}
#ifdef XF86DRI
if (pI8301->directRenderingEnabled) {
sarea = DRIGetSAREAPrivate(pScrn1->pScreen);
myContext = DRIGetContext(pScrn1->pScreen);
if (pI8301->directRenderingEnabled)
didLock = I830DRILock(pScrn1);
}
#endif
if (pScrn->scrnIndex != *pI830->used3D)
updateInvarient = TRUE;
pI830->last_3d = LAST_3D_OTHER;
#ifdef XF86DRI
if (sarea && sarea->ctxOwner != myContext)
updateInvarient = TRUE;
#endif
if (updateInvarient) {
if (pI830->last_3d != LAST_3D_ROTATION) {
*pI830->used3D = pScrn->scrnIndex;
#ifdef XF86DRI
if (sarea)
sarea->ctxOwner = myContext;
#endif
pI830->last_3d = LAST_3D_ROTATION;
BEGIN_LP_RING(48);
OUT_RING(0x682008a1);
OUT_RING(0x6f402100);
@ -1021,21 +941,27 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayModePtr mode)
}
}
/* Don't allow pixmap cache or offscreen pixmaps when rotated */
/* XAA needs some serious fixing for this to happen */
if (pI830->rotation == RR_Rotate_0) {
pI830->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS | PIXMAP_CACHE;
pI830->AccelInfoRec->UsingPixmapCache = TRUE;
/* funny as it seems this will enable XAA's createpixmap */
pI830->AccelInfoRec->maxOffPixWidth = 0;
pI830->AccelInfoRec->maxOffPixHeight = 0;
} else {
pI830->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER;
pI830->AccelInfoRec->UsingPixmapCache = FALSE;
/* funny as it seems this will disable XAA's createpixmap */
pI830->AccelInfoRec->maxOffPixWidth = 1;
pI830->AccelInfoRec->maxOffPixHeight = 1;
#ifdef I830_USE_XAA
if (pI830->AccelInfoRec != NULL) {
/* Don't allow pixmap cache or offscreen pixmaps when rotated */
/* XAA needs some serious fixing for this to happen */
if (pI830->rotation == RR_Rotate_0) {
pI830->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS |
PIXMAP_CACHE;
pI830->AccelInfoRec->UsingPixmapCache = TRUE;
/* funny as it seems this will enable XAA's createpixmap */
pI830->AccelInfoRec->maxOffPixWidth = 0;
pI830->AccelInfoRec->maxOffPixHeight = 0;
} else {
pI830->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER;
pI830->AccelInfoRec->UsingPixmapCache = FALSE;
/* funny as it seems this will disable XAA's createpixmap */
pI830->AccelInfoRec->maxOffPixWidth = 1;
pI830->AccelInfoRec->maxOffPixHeight = 1;
}
}
#endif
return TRUE;
BAIL4:

View File

@ -2804,8 +2804,6 @@ I830AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size)
ScreenPtr pScreen;
FBLinearPtr new_linear = NULL;
ErrorF("I830AllocateMemory\n");
if (linear) {
if (linear->size >= size)
return linear;

711
src/i830_xaa.c Normal file
View File

@ -0,0 +1,711 @@
/**************************************************************************
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
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 PRECISION INSIGHT 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.
**************************************************************************/
/*
* 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.
*/
/*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "xf86.h"
#include "xaarop.h"
#include "i830.h"
#include "i810_reg.h"
#ifndef DO_SCANLINE_IMAGE_WRITE
#define DO_SCANLINE_IMAGE_WRITE 0
#endif
/* I830 Accel Functions */
static void I830SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
int pattx, int patty,
int fg, int bg, int rop,
unsigned int planemask);
static void I830SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
int pattx, int patty,
int x, int y, int w, int h);
static void I830SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
int fg, int bg,
int rop,
unsigned int mask);
static void I830SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr
pScrn, int x,
int y, int w,
int h,
int skipleft);
static void I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
#if DO_SCANLINE_IMAGE_WRITE
static void I830SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop,
unsigned int planemask,
int trans_color, int bpp,
int depth);
static void I830SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn,
int x, int y, int w, int h,
int skipleft);
static void I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno);
#endif
static void I830RestoreAccelState(ScrnInfoPtr pScrn);
#ifdef I830_USE_EXA
extern const int I830PatternROP[16];
extern const int I830CopyROP[16];
#endif
Bool
I830XAAInit(ScreenPtr pScreen)
{
XAAInfoRecPtr infoPtr;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
int i;
int width = 0;
int nr_buffers = 0;
unsigned char *ptr = NULL;
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830XAAInit\n");
pI830->AccelInfoRec = infoPtr = XAACreateInfoRec();
if (!infoPtr)
return FALSE;
pI830->bufferOffset = 0;
infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS | PIXMAP_CACHE;
/* Use the same sync function as the I830.
*/
infoPtr->Sync = I830Sync;
/* Everything else is different enough to justify different functions */
{
infoPtr->SolidFillFlags = NO_PLANEMASK;
infoPtr->SetupForSolidFill = I830SetupForSolidFill;
infoPtr->SubsequentSolidFillRect = I830SubsequentSolidFillRect;
}
{
infoPtr->ScreenToScreenCopyFlags = (NO_PLANEMASK | NO_TRANSPARENCY);
infoPtr->SetupForScreenToScreenCopy = I830SetupForScreenToScreenCopy;
infoPtr->SubsequentScreenToScreenCopy =
I830SubsequentScreenToScreenCopy;
}
{
infoPtr->SetupForMono8x8PatternFill = I830SetupForMono8x8PatternFill;
infoPtr->SubsequentMono8x8PatternFillRect =
I830SubsequentMono8x8PatternFillRect;
infoPtr->Mono8x8PatternFillFlags = (HARDWARE_PATTERN_PROGRAMMED_BITS |
HARDWARE_PATTERN_SCREEN_ORIGIN |
HARDWARE_PATTERN_PROGRAMMED_ORIGIN|
BIT_ORDER_IN_BYTE_MSBFIRST |
NO_PLANEMASK);
}
/* On the primary screen */
if (pI830->init == 0) {
if (pI830->Scratch.Size != 0) {
width = ((pScrn->displayWidth + 31) & ~31) / 8;
nr_buffers = pI830->Scratch.Size / width;
ptr = pI830->FbBase + pI830->Scratch.Start;
}
} else {
/* On the secondary screen */
I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
if (pI8301->Scratch2.Size != 0) {
width = ((pScrn->displayWidth + 31) & ~31) / 8;
nr_buffers = pI8301->Scratch2.Size / width;
/* We have to use the primary screen's FbBase, as that's where
* we allocated Scratch2, so we get the correct pointer */
ptr = pI8301->FbBase + pI8301->Scratch2.Start;
}
}
if (nr_buffers) {
pI830->NumScanlineColorExpandBuffers = nr_buffers;
pI830->ScanlineColorExpandBuffers = (unsigned char **)
xnfcalloc(nr_buffers, sizeof(unsigned char *));
for (i = 0; i < nr_buffers; i++, ptr += width)
pI830->ScanlineColorExpandBuffers[i] = ptr;
infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
(NO_PLANEMASK | ROP_NEEDS_SOURCE | BIT_ORDER_IN_BYTE_MSBFIRST);
infoPtr->ScanlineColorExpandBuffers = (unsigned char **)
xnfcalloc(1, sizeof(unsigned char *));
infoPtr->NumScanlineColorExpandBuffers = 1;
infoPtr->ScanlineColorExpandBuffers[0] =
pI830->ScanlineColorExpandBuffers[0];
pI830->nextColorExpandBuf = 0;
infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
I830SetupForScanlineCPUToScreenColorExpandFill;
infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
I830SubsequentScanlineCPUToScreenColorExpandFill;
infoPtr->SubsequentColorExpandScanline =
I830SubsequentColorExpandScanline;
#if DO_SCANLINE_IMAGE_WRITE
infoPtr->NumScanlineImageWriteBuffers = 1;
infoPtr->ScanlineImageWriteBuffers =
infoPtr->ScanlineColorExpandBuffers;
infoPtr->SetupForScanlineImageWrite = I830SetupForScanlineImageWrite;
infoPtr->SubsequentScanlineImageWriteRect =
I830SubsequentScanlineImageWriteRect;
infoPtr->SubsequentImageWriteScanline =
I830SubsequentImageWriteScanline;
infoPtr->ScanlineImageWriteFlags = NO_GXCOPY |
NO_PLANEMASK |
ROP_NEEDS_SOURCE |
SCANLINE_PAD_DWORD;
#endif
}
{
Bool shared_accel = FALSE;
int i;
for(i = 0; i < pScrn->numEntities; i++) {
if(xf86IsEntityShared(pScrn->entityList[i]))
shared_accel = TRUE;
}
if(shared_accel == TRUE)
infoPtr->RestoreAccelState = I830RestoreAccelState;
}
I830SelectBuffer(pScrn, I830_SELECT_FRONT);
return XAAInit(pScreen, infoPtr);
}
#ifdef XF86DRI
static unsigned int
CheckTiling(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
unsigned int tiled = 0;
/* Check tiling */
if (IS_I965G(pI830)) {
if (pI830->bufferOffset == pScrn->fbOffset && pI830->front_tiled == FENCE_XMAJOR)
tiled = 1;
if (pI830->bufferOffset == pI830->RotatedMem.Start && pI830->rotated_tiled == FENCE_XMAJOR)
tiled = 1;
if (pI830->bufferOffset == pI830->BackBuffer.Start && pI830->back_tiled == FENCE_XMAJOR)
tiled = 1;
/* not really supported as it's always YMajor tiled */
if (pI830->bufferOffset == pI830->DepthBuffer.Start && pI830->depth_tiled == FENCE_XMAJOR)
tiled = 1;
}
return tiled;
}
#else
#define CheckTiling(pScrn) 0
#endif
void
I830SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
unsigned int planemask)
{
I830Ptr pI830 = I830PTR(pScrn);
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SetupForFillRectSolid color: %x rop: %x mask: %x\n",
color, rop, planemask);
#ifdef I830_USE_EXA
/* This function gets used by I830DRIInitBuffers(), and we might not have
* XAAGetPatternROP() available. So just use the ROPs from our EXA code
* if available.
*/
pI830->BR[13] = ((I830PatternROP[rop] << 16) |
(pScrn->displayWidth * pI830->cpp));
#else
pI830->BR[13] = ((XAAGetPatternROP(rop) << 16) |
(pScrn->displayWidth * pI830->cpp));
#endif
pI830->BR[16] = color;
switch (pScrn->bitsPerPixel) {
case 8:
break;
case 16:
pI830->BR[13] |= (1 << 24);
break;
case 32:
pI830->BR[13] |= ((1 << 25) | (1 << 24));
break;
}
}
void
I830SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
{
I830Ptr pI830 = I830PTR(pScrn);
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SubsequentFillRectSolid %d,%d %dx%d\n", x, y, w, h);
{
BEGIN_LP_RING(6);
if (pScrn->bitsPerPixel == 32) {
OUT_RING(COLOR_BLT_CMD | COLOR_BLT_WRITE_ALPHA |
COLOR_BLT_WRITE_RGB);
} else {
OUT_RING(COLOR_BLT_CMD);
}
OUT_RING(pI830->BR[13]);
OUT_RING((h << 16) | (w * pI830->cpp));
OUT_RING(pI830->bufferOffset + (y * pScrn->displayWidth + x) *
pI830->cpp);
OUT_RING(pI830->BR[16]);
OUT_RING(0);
ADVANCE_LP_RING();
}
if (IS_I965G(pI830))
I830EmitFlush(pScrn);
}
void
I830SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
unsigned int planemask, int transparency_color)
{
I830Ptr pI830 = I830PTR(pScrn);
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SetupForScreenToScreenCopy %d %d %x %x %d\n",
xdir, ydir, rop, planemask, transparency_color);
pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
#ifdef I830_USE_EXA
/* This function gets used by I830DRIInitBuffers(), and we might not have
* XAAGetCopyROP() available. So just use the ROPs from our EXA code
* if available.
*/
pI830->BR[13] |= I830CopyROP[rop] << 16;
#else
pI830->BR[13] |= XAAGetCopyROP(rop) << 16;
#endif
switch (pScrn->bitsPerPixel) {
case 8:
break;
case 16:
pI830->BR[13] |= (1 << 24);
break;
case 32:
pI830->BR[13] |= ((1 << 25) | (1 << 24));
break;
}
}
void
I830SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int src_x1, int src_y1,
int dst_x1, int dst_y1, int w, int h)
{
I830Ptr pI830 = I830PTR(pScrn);
int dst_x2, dst_y2;
unsigned int tiled = CheckTiling(pScrn);
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SubsequentScreenToScreenCopy %d,%d - %d,%d %dx%d\n",
src_x1, src_y1, dst_x1, dst_y1, w, h);
dst_x2 = dst_x1 + w;
dst_y2 = dst_y1 + h;
if (tiled)
pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) |
(pI830->BR[13] & 0xFFFF0000);
{
BEGIN_LP_RING(8);
if (pScrn->bitsPerPixel == 32) {
OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
XY_SRC_COPY_BLT_WRITE_RGB | tiled << 15 | tiled << 11);
} else {
OUT_RING(XY_SRC_COPY_BLT_CMD | tiled << 15 | tiled << 11);
}
OUT_RING(pI830->BR[13]);
OUT_RING((dst_y1 << 16) | (dst_x1 & 0xffff));
OUT_RING((dst_y2 << 16) | (dst_x2 & 0xffff));
OUT_RING(pI830->bufferOffset);
OUT_RING((src_y1 << 16) | (src_x1 & 0xffff));
OUT_RING(pI830->BR[13] & 0xFFFF);
OUT_RING(pI830->bufferOffset);
ADVANCE_LP_RING();
}
if (IS_I965G(pI830))
I830EmitFlush(pScrn);
}
static void
I830SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattx, int patty,
int fg, int bg, int rop,
unsigned int planemask)
{
I830Ptr pI830 = I830PTR(pScrn);
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SetupForMono8x8PatternFill\n");
pI830->BR[16] = pattx;
pI830->BR[17] = patty;
pI830->BR[18] = bg;
pI830->BR[19] = fg;
pI830->BR[13] = (pScrn->displayWidth * pI830->cpp); /* In bytes */
pI830->BR[13] |= XAAGetPatternROP(rop) << 16;
if (bg == -1)
pI830->BR[13] |= (1 << 28);
switch (pScrn->bitsPerPixel) {
case 8:
break;
case 16:
pI830->BR[13] |= (1 << 24);
break;
case 32:
pI830->BR[13] |= ((1 << 25) | (1 << 24));
break;
}
}
static void
I830SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int pattx, int patty,
int x, int y, int w, int h)
{
I830Ptr pI830 = I830PTR(pScrn);
int x1, x2, y1, y2;
unsigned int tiled = CheckTiling(pScrn);
x1 = x;
x2 = x + w;
y1 = y;
y2 = y + h;
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SubsequentMono8x8PatternFillRect\n");
if (tiled)
pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) |
(pI830->BR[13] & 0xFFFF0000);
{
BEGIN_LP_RING(10);
if (pScrn->bitsPerPixel == 32) {
OUT_RING(XY_MONO_PAT_BLT_CMD | XY_MONO_PAT_BLT_WRITE_ALPHA |
XY_MONO_PAT_BLT_WRITE_RGB | tiled << 11 |
((patty << 8) & XY_MONO_PAT_VERT_SEED) |
((pattx << 12) & XY_MONO_PAT_HORT_SEED));
} else {
OUT_RING(XY_MONO_PAT_BLT_CMD | tiled << 11 |
((patty << 8) & XY_MONO_PAT_VERT_SEED) |
((pattx << 12) & XY_MONO_PAT_HORT_SEED));
}
OUT_RING(pI830->BR[13]);
OUT_RING((y1 << 16) | x1);
OUT_RING((y2 << 16) | x2);
OUT_RING(pI830->bufferOffset);
OUT_RING(pI830->BR[18]); /* bg */
OUT_RING(pI830->BR[19]); /* fg */
OUT_RING(pI830->BR[16]); /* pattern data */
OUT_RING(pI830->BR[17]);
OUT_RING(0);
ADVANCE_LP_RING();
}
if (IS_I965G(pI830))
I830EmitFlush(pScrn);
}
static void
I830GetNextScanlineColorExpandBuffer(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
XAAInfoRecPtr infoPtr = pI830->AccelInfoRec;
if (pI830->nextColorExpandBuf == pI830->NumScanlineColorExpandBuffers)
I830Sync(pScrn);
infoPtr->ScanlineColorExpandBuffers[0] =
pI830->ScanlineColorExpandBuffers[pI830->nextColorExpandBuf];
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("using color expand buffer %d\n", pI830->nextColorExpandBuf);
pI830->nextColorExpandBuf++;
}
static void
I830SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
int fg, int bg, int rop,
unsigned int planemask)
{
I830Ptr pI830 = I830PTR(pScrn);
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SetupForScanlineScreenToScreenColorExpand %d %d %x %x\n",
fg, bg, rop, planemask);
/* Fill out register values */
pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
pI830->BR[13] |= XAAGetCopyROP(rop) << 16;
if (bg == -1)
pI830->BR[13] |= (1 << 29);
switch (pScrn->bitsPerPixel) {
case 8:
break;
case 16:
pI830->BR[13] |= (1 << 24);
break;
case 32:
pI830->BR[13] |= ((1 << 25) | (1 << 24));
break;
}
pI830->BR[18] = bg;
pI830->BR[19] = fg;
I830GetNextScanlineColorExpandBuffer(pScrn);
}
static void
I830SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
int x, int y,
int w, int h, int skipleft)
{
I830Ptr pI830 = I830PTR(pScrn);
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SubsequentScanlineCPUToScreenColorExpandFill "
"%d,%d %dx%x %d\n", x, y, w, h, skipleft);
/* Fill out register values */
pI830->BR[9] = (pI830->bufferOffset +
(y * pScrn->displayWidth + x) * pI830->cpp);
pI830->BR[11] = ((1 << 16) | w);
}
static void
I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
{
I830Ptr pI830 = I830PTR(pScrn);
unsigned int tiled = CheckTiling(pScrn);
if (pI830->init == 0) {
pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
pI830->FbBase);
} else {
I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
/* We have to use the primary screen's FbBase, as that's where
* we allocated Scratch2, so we get the correct pointer */
pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
pI8301->FbBase);
}
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SubsequentColorExpandScanline %d (addr %x)\n",
bufno, pI830->BR[12]);
if (tiled)
pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) |
(pI830->BR[13] & 0xFFFF0000);
{
BEGIN_LP_RING(8);
if (pScrn->bitsPerPixel == 32) {
OUT_RING(XY_MONO_SRC_BLT_CMD | XY_MONO_SRC_BLT_WRITE_ALPHA |
tiled << 11 | XY_MONO_SRC_BLT_WRITE_RGB);
} else {
OUT_RING(XY_MONO_SRC_BLT_CMD | tiled << 11);
}
OUT_RING(pI830->BR[13]);
OUT_RING(0); /* x1 = 0, y1 = 0 */
OUT_RING(pI830->BR[11]); /* x2 = w, y2 = 1 */
OUT_RING(pI830->BR[9]); /* dst addr */
OUT_RING(pI830->BR[12]); /* src addr */
OUT_RING(pI830->BR[18]); /* bg */
OUT_RING(pI830->BR[19]); /* fg */
ADVANCE_LP_RING();
}
/* Advance to next scanline.
*/
pI830->BR[9] += pScrn->displayWidth * pI830->cpp;
I830GetNextScanlineColorExpandBuffer(pScrn);
if (IS_I965G(pI830))
I830EmitFlush(pScrn);
}
#if DO_SCANLINE_IMAGE_WRITE
static void
I830SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop,
unsigned int planemask, int trans_color,
int bpp, int depth)
{
I830Ptr pI830 = I830PTR(pScrn);
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SetupForScanlineImageWrite %x %x\n", rop, planemask);
/* Fill out register values */
pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
pI830->BR[13] |= XAAGetCopyROP(rop) << 16;
switch (pScrn->bitsPerPixel) {
case 8:
break;
case 16:
pI830->BR[13] |= (1 << 24);
break;
case 32:
pI830->BR[13] |= ((1 << 25) | (1 << 24));
break;
}
I830GetNextScanlineColorExpandBuffer(pScrn);
}
static void
I830SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, int x, int y,
int w, int h, int skipleft)
{
I830Ptr pI830 = I830PTR(pScrn);
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SubsequentScanlineImageWriteRect "
"%d,%d %dx%x %d\n", x, y, w, h, skipleft);
/* Fill out register values */
pI830->BR[9] = (pI830->bufferOffset +
(y * pScrn->displayWidth + x) * pI830->cpp);
pI830->BR[11] = ((1 << 16) | w);
}
static void
I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno)
{
I830Ptr pI830 = I830PTR(pScrn);
unsigned int tiled = CheckTiling(pScrn);
if (pI830->init == 0) {
pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
pI830->FbBase);
} else {
I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
/* We have to use the primary screen's FbBase, as that's where
* we allocated Scratch2, so we get the correct pointer */
pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
pI8301->FbBase);
}
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SubsequentImageWriteScanline %d (addr %x)\n",
bufno, pI830->BR[12]);
{
BEGIN_LP_RING(8);
if (pScrn->bitsPerPixel == 32) {
OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
tiled << 11 | XY_SRC_COPY_BLT_WRITE_RGB);
} else {
OUT_RING(XY_SRC_COPY_BLT_CMD | tiled << 11);
}
OUT_RING(pI830->BR[13]);
OUT_RING(0); /* x1 = 0, y1 = 0 */
OUT_RING(pI830->BR[11]); /* x2 = w, y2 = 1 */
OUT_RING(pI830->BR[9]); /* dst addr */
OUT_RING(0); /* source origin (0,0) */
OUT_RING(pI830->BR[11] & 0xffff); /* source pitch */
OUT_RING(pI830->BR[12]); /* src addr */
ADVANCE_LP_RING();
}
/* Advance to next scanline.
*/
pI830->BR[9] += pScrn->displayWidth * pI830->cpp;
I830GetNextScanlineColorExpandBuffer(pScrn);
}
#endif /* DO_SCANLINE_IMAGE_WRITE */
/* Support for multiscreen */
static void
I830RestoreAccelState(ScrnInfoPtr pScrn)
{
#if 0
/* might be needed, but everything is on a ring, so I don't think so */
I830Sync(pScrn);
#endif
}

View File

@ -38,7 +38,7 @@ void I915EmitInvarientState( ScrnInfoPtr pScrn )
{
I830Ptr pI830 = I830PTR(pScrn);
BEGIN_LP_RING(20);
BEGIN_LP_RING(24);
OUT_RING(_3DSTATE_AA_CMD |
AA_LINE_ECAAR_WIDTH_ENABLE |
@ -46,6 +46,13 @@ void I915EmitInvarientState( ScrnInfoPtr pScrn )
AA_LINE_REGION_WIDTH_ENABLE |
AA_LINE_REGION_WIDTH_1_0);
/* Disable independent alpha blend */
OUT_RING(_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD |
IAB_MODIFY_ENABLE |
IAB_MODIFY_FUNC | (BLENDFUNC_ADD << IAB_FUNC_SHIFT) |
IAB_MODIFY_SRC_FACTOR | (BLENDFACT_ONE << IAB_SRC_FACTOR_SHIFT) |
IAB_MODIFY_DST_FACTOR | (BLENDFACT_ZERO << IAB_DST_FACTOR_SHIFT));
OUT_RING(_3DSTATE_DFLT_DIFFUSE_CMD);
OUT_RING(0);
@ -76,17 +83,15 @@ void I915EmitInvarientState( ScrnInfoPtr pScrn )
ENABLE_TEXKILL_3D_4D |
TEXKILL_4D);
/* Need to initialize this to zero.
*/
OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
I1_LOAD_S(3) |
(1));
OUT_RING(0);
/* XXX: Use this */
OUT_RING(_3DSTATE_SCISSOR_ENABLE_CMD |
DISABLE_SCISSOR_RECT);
OUT_RING(_3DSTATE_MODES_4_CMD |
ENABLE_LOGIC_OP_FUNC | LOGIC_OP_FUNC(LOGICOP_COPY) |
ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(0xff) |
ENABLE_STENCIL_TEST_MASK | STENCIL_TEST_MASK(0xff));
OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | 0);
OUT_RING(0x00000000); /* Disable texture coordinate wrap-shortest */
OUT_RING(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
OUT_RING(_3DSTATE_SCISSOR_RECT_0_CMD);
OUT_RING(0);
OUT_RING(0);
@ -96,12 +101,11 @@ void I915EmitInvarientState( ScrnInfoPtr pScrn )
OUT_RING(_3DSTATE_LOAD_INDIRECT | 0); /* disable indirect state */
OUT_RING(0);
/* Don't support twosided stencil yet */
OUT_RING(_3DSTATE_BACKFACE_STENCIL_OPS |
BFO_ENABLE_STENCIL_TWO_SIDE |
0 );
OUT_RING(_3DSTATE_STIPPLE);
OUT_RING(0x00000000);
OUT_RING(_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0 );
OUT_RING(MI_NOOP);
OUT_RING(0);
ADVANCE_LP_RING();
}

View File

@ -33,7 +33,7 @@
#define MASK_Y 0x2
#define MASK_Z 0x4
#define MASK_W 0x8
#define MASK_XYZ (MASK_X | MASK_Y | MASK_W)
#define MASK_XYZ (MASK_X | MASK_Y | MASK_Z)
#define MASK_XYZW (MASK_XYZ | MASK_W)
#define MASK_SATURATE 0x10
@ -350,8 +350,16 @@ _i915_fs_arith(int cmd, int dest_reg,
return op;
}
/** Move operand0 to dest_reg */
#define i915_fs_mov(dest_reg, operand0) \
do { \
FS_OUT(i915_fs_arith(MOV, dest_reg, operand0, \
i915_fs_operand_none(), \
i915_fs_operand_none())); \
} while (0)
/**
* Move the values in operand0 to the dest reg with the masking/saturation
* Move the value in operand0 to the dest reg with the masking/saturation
* specified.
*/
#define i915_fs_mov_masked(dest_reg, dest_mask, operand0) \
@ -375,6 +383,13 @@ do { \
i915_fs_operand_none())); \
} while (0)
/** Add operand0 and operand1 and put the result in dest_reg */
#define i915_fs_mul(dest_reg, operand0, operand1) \
do { \
FS_OUT(i915_fs_arith(MUL, dest_reg, operand0, operand1, \
i915_fs_operand_none())); \
} while (0)
/**
* Perform a 3-component dot-product of operand0 and operand1 and put the
* resulting scalar in the channels of dest_reg specified by the dest_mask.
@ -383,7 +398,7 @@ do { \
do { \
struct i915_fs_op op; \
\
op = i915_fs_arith(DP3, dest_reg, operand0, i915_fs_operand_none(), \
op = i915_fs_arith(DP3, dest_reg, operand0, operand1, \
i915_fs_operand_none()); \
op.ui[0] &= ~A0_DEST_CHANNEL_ALL; \
op.ui[0] |= ((dest_mask) & ~MASK_SATURATE) << A0_DEST_CHANNEL_SHIFT; \
@ -421,11 +436,13 @@ do { \
#define FS_END() \
do { \
int _i; \
BEGIN_LP_RING(_cur_shader_commands * 3 + 1); \
int _i, _pad = (_cur_shader_commands & 0x1) ? 0 : 1; \
BEGIN_LP_RING(_cur_shader_commands * 3 + 1 + _pad); \
OUT_RING(_3DSTATE_PIXEL_SHADER_PROGRAM | \
(_cur_shader_commands * 3 - 1)); \
for (_i = 0; _i < _cur_shader_commands * 3; _i++) \
OUT_RING(_shader_buf[_i]); \
if (_pad != 0) \
OUT_RING(MI_NOOP); \
ADVANCE_LP_RING(); \
} while (0);

489
src/i915_exa_render.c Normal file
View File

@ -0,0 +1,489 @@
/*
* Copyright © 2006 Intel Corporation
*
* 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, sublicense,
* 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 NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS 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.
*
* Authors:
* Wang Zhenyu <zhenyu.z.wang@intel.com>
* Eric Anholt <eric@anholt.net>
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "xf86.h"
#include "i830.h"
#include "i915_reg.h"
#include "i915_3d.h"
#ifdef I830DEBUG
#define DEBUG_I830FALLBACK 1
#endif
#ifdef DEBUG_I830FALLBACK
#define I830FALLBACK(s, arg...) \
do { \
DPRINTF(PFX, "EXA fallback: " s "\n", ##arg); \
return FALSE; \
} while(0)
#else
#define I830FALLBACK(s, arg...) \
do { \
return FALSE; \
} while(0)
#endif
extern float scale_units[2][2];
extern Bool is_transform[2];
extern PictTransform *transform[2];
static CARD32 mapstate[6];
static CARD32 samplerstate[6];
struct formatinfo {
int fmt;
CARD32 card_fmt;
};
struct blendinfo {
Bool dst_alpha;
Bool src_alpha;
CARD32 src_blend;
CARD32 dst_blend;
};
extern Bool
I915EXACheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
PicturePtr pDstPicture);
extern Bool
I915EXAPrepareComposite(int op, PicturePtr pSrcPicture,
PicturePtr pMaskPicture, PicturePtr pDstPicture,
PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst);
static struct blendinfo I915BlendOp[] = {
/* Clear */
{0, 0, BLENDFACT_ZERO, BLENDFACT_ZERO},
/* Src */
{0, 0, BLENDFACT_ONE, BLENDFACT_ZERO},
/* Dst */
{0, 0, BLENDFACT_ZERO, BLENDFACT_ONE},
/* Over */
{0, 1, BLENDFACT_ONE, BLENDFACT_INV_SRC_ALPHA},
/* OverReverse */
{1, 0, BLENDFACT_INV_DST_ALPHA, BLENDFACT_ONE},
/* In */
{1, 0, BLENDFACT_DST_ALPHA, BLENDFACT_ZERO},
/* InReverse */
{0, 1, BLENDFACT_ZERO, BLENDFACT_SRC_ALPHA},
/* Out */
{1, 0, BLENDFACT_INV_DST_ALPHA, BLENDFACT_ZERO},
/* OutReverse */
{0, 1, BLENDFACT_ZERO, BLENDFACT_INV_SRC_ALPHA},
/* Atop */
{1, 1, BLENDFACT_DST_ALPHA, BLENDFACT_INV_SRC_ALPHA},
/* AtopReverse */
{1, 1, BLENDFACT_INV_DST_ALPHA, BLENDFACT_SRC_ALPHA},
/* Xor */
{1, 1, BLENDFACT_INV_DST_ALPHA, BLENDFACT_INV_SRC_ALPHA},
/* Add */
{0, 0, BLENDFACT_ONE, BLENDFACT_ONE},
};
static struct formatinfo I915TexFormats[] = {
{PICT_a8r8g8b8, MAPSURF_32BIT | MT_32BIT_ARGB8888 },
{PICT_x8r8g8b8, MAPSURF_32BIT | MT_32BIT_XRGB8888 },
{PICT_a8b8g8r8, MAPSURF_32BIT | MT_32BIT_ABGR8888 },
{PICT_x8b8g8r8, MAPSURF_32BIT | MT_32BIT_XBGR8888 },
{PICT_r5g6b5, MAPSURF_16BIT | MT_16BIT_RGB565 },
{PICT_a1r5g5b5, MAPSURF_16BIT | MT_16BIT_ARGB1555 },
{PICT_x1r5g5b5, MAPSURF_16BIT | MT_16BIT_ARGB1555 },
{PICT_a8, MAPSURF_8BIT | MT_8BIT_A8 },
};
static CARD32 I915GetBlendCntl(int op, PicturePtr pMask, CARD32 dst_format)
{
CARD32 sblend, dblend;
sblend = I915BlendOp[op].src_blend;
dblend = I915BlendOp[op].dst_blend;
/* If there's no dst alpha channel, adjust the blend op so that we'll treat
* it as always 1.
*/
if (PICT_FORMAT_A(dst_format) == 0 && I915BlendOp[op].dst_alpha) {
if (sblend == BLENDFACT_DST_ALPHA)
sblend = BLENDFACT_ONE;
else if (sblend == BLENDFACT_INV_DST_ALPHA)
sblend = BLENDFACT_ZERO;
}
/* If the source alpha is being used, then we should only be in a case where
* the source blend factor is 0, and the source blend value is the mask
* channels multiplied by the source picture's alpha.
*/
if (pMask && pMask->componentAlpha && I915BlendOp[op].src_alpha) {
if (dblend == BLENDFACT_SRC_ALPHA) {
dblend = BLENDFACT_SRC_COLR;
} else if (dblend == BLENDFACT_INV_SRC_ALPHA) {
dblend = BLENDFACT_INV_SRC_COLR;
}
}
return (sblend << S6_CBUF_SRC_BLEND_FACT_SHIFT) |
(dblend << S6_CBUF_DST_BLEND_FACT_SHIFT);
}
static Bool I915GetDestFormat(PicturePtr pDstPicture, CARD32 *dst_format)
{
switch (pDstPicture->format) {
case PICT_a8r8g8b8:
case PICT_x8r8g8b8:
*dst_format = COLR_BUF_ARGB8888;
break;
case PICT_r5g6b5:
*dst_format = COLR_BUF_RGB565;
break;
case PICT_a1r5g5b5:
case PICT_x1r5g5b5:
*dst_format = COLR_BUF_ARGB1555;
break;
/* COLR_BUF_8BIT is special for YUV surfaces. While we may end up being
* able to use it depending on how the hardware implements it, disable it
* for now while we don't know what exactly it does (what channel does it
* read from?
*/
/*
case PICT_a8:
*dst_format = COLR_BUF_8BIT;
break;
*/
case PICT_a4r4g4b4:
case PICT_x4r4g4b4:
*dst_format = COLR_BUF_ARGB4444;
break;
default:
I830FALLBACK("Unsupported dest format 0x%x\n",
(int)pDstPicture->format);
}
return TRUE;
}
static Bool I915CheckCompositeTexture(PicturePtr pPict, int unit)
{
int w = pPict->pDrawable->width;
int h = pPict->pDrawable->height;
int i;
if ((w > 0x7ff) || (h > 0x7ff))
I830FALLBACK("Picture w/h too large (%dx%d)\n", w, h);
for (i = 0; i < sizeof(I915TexFormats) / sizeof(I915TexFormats[0]); i++)
{
if (I915TexFormats[i].fmt == pPict->format)
break;
}
if (i == sizeof(I915TexFormats) / sizeof(I915TexFormats[0]))
I830FALLBACK("Unsupported picture format 0x%x\n",
(int)pPict->format);
if (pPict->repeat && pPict->repeatType != RepeatNormal)
I830FALLBACK("extended repeat (%d) not supported\n",
pPict->repeatType);
if (pPict->filter != PictFilterNearest &&
pPict->filter != PictFilterBilinear)
I830FALLBACK("Unsupported filter 0x%x\n", pPict->filter);
return TRUE;
}
Bool
I915EXACheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
PicturePtr pDstPicture)
{
CARD32 tmp1;
/* Check for unsupported compositing operations. */
if (op >= sizeof(I915BlendOp) / sizeof(I915BlendOp[0]))
I830FALLBACK("Unsupported Composite op 0x%x\n", op);
if (pMaskPicture != NULL && pMaskPicture->componentAlpha) {
/* Check if it's component alpha that relies on a source alpha and on
* the source value. We can only get one of those into the single
* source value that we get to blend with.
*/
if (I915BlendOp[op].src_alpha &&
(I915BlendOp[op].src_blend != BLENDFACT_ZERO))
I830FALLBACK("Component alpha not supported with source "
"alpha and source value blending.\n");
}
if (!I915CheckCompositeTexture(pSrcPicture, 0))
I830FALLBACK("Check Src picture texture\n");
if (pMaskPicture != NULL && !I915CheckCompositeTexture(pMaskPicture, 1))
I830FALLBACK("Check Mask picture texture\n");
if (!I915GetDestFormat(pDstPicture, &tmp1))
I830FALLBACK("Get Color buffer format\n");
return TRUE;
}
static Bool
I915TextureSetup(PicturePtr pPict, PixmapPtr pPix, int unit)
{
ScrnInfoPtr pScrn = xf86Screens[pPict->pDrawable->pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
CARD32 format, offset, pitch, filter;
int w, h, i;
CARD32 wrap_mode = TEXCOORDMODE_CLAMP_BORDER;
offset = exaGetPixmapOffset(pPix);
pitch = exaGetPixmapPitch(pPix);
w = pPict->pDrawable->width;
h = pPict->pDrawable->height;
scale_units[unit][0] = pPix->drawable.width;
scale_units[unit][1] = pPix->drawable.height;
for (i = 0; i < sizeof(I915TexFormats) / sizeof(I915TexFormats[0]); i++) {
if (I915TexFormats[i].fmt == pPict->format)
break;
}
if (i == sizeof(I915TexFormats)/ sizeof(I915TexFormats[0]))
I830FALLBACK("unknown texture format\n");
format = I915TexFormats[i].card_fmt;
if (pPict->repeat)
wrap_mode = TEXCOORDMODE_WRAP;
switch (pPict->filter) {
case PictFilterNearest:
filter = (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT) |
(FILTER_NEAREST << SS2_MIN_FILTER_SHIFT);
break;
case PictFilterBilinear:
filter = (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
(FILTER_LINEAR << SS2_MIN_FILTER_SHIFT);
break;
default:
filter = 0;
I830FALLBACK("Bad filter 0x%x\n", pPict->filter);
}
mapstate[unit * 3 + 0] = offset;
mapstate[unit * 3 + 1] = format |
((pPix->drawable.height - 1) << MS3_HEIGHT_SHIFT) |
((pPix->drawable.width - 1) << MS3_WIDTH_SHIFT);
if (!pI830->disableTiling)
samplerstate[unit * 3 + 1] |= MS3_USE_FENCE_REGS;
mapstate[unit * 3 + 2] = ((pitch / 4) - 1) << MS4_PITCH_SHIFT;
samplerstate[unit * 3 + 0] = (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT);
samplerstate[unit * 3 + 0] |= filter;
samplerstate[unit * 3 + 1] = SS3_NORMALIZED_COORDS;
samplerstate[unit * 3 + 1] |= wrap_mode << SS3_TCX_ADDR_MODE_SHIFT;
samplerstate[unit * 3 + 1] |= wrap_mode << SS3_TCY_ADDR_MODE_SHIFT;
samplerstate[unit * 3 + 1] |= unit << SS3_TEXTUREMAP_INDEX_SHIFT;
samplerstate[unit * 3 + 2] = 0x00000000; /* border color */
if (pPict->transform != 0) {
is_transform[unit] = TRUE;
transform[unit] = pPict->transform;
} else {
is_transform[unit] = FALSE;
}
return TRUE;
}
Bool
I915EXAPrepareComposite(int op, PicturePtr pSrcPicture,
PicturePtr pMaskPicture, PicturePtr pDstPicture,
PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
{
ScrnInfoPtr pScrn = xf86Screens[pSrcPicture->pDrawable->pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
CARD32 dst_format, dst_offset, dst_pitch;
CARD32 blendctl;
#ifdef I830DEBUG
ErrorF("Enter i915 prepareComposite\n");
#endif
pI830->last_3d = LAST_3D_RENDER;
I915GetDestFormat(pDstPicture, &dst_format);
dst_offset = exaGetPixmapOffset(pDst);
dst_pitch = exaGetPixmapPitch(pDst);
FS_LOCALS(20);
if (!I915TextureSetup(pSrcPicture, pSrc, 0))
I830FALLBACK("fail to setup src texture\n");
if (pMask != NULL) {
if (!I915TextureSetup(pMaskPicture, pMask, 1))
I830FALLBACK("fail to setup mask texture\n");
} else {
is_transform[1] = FALSE;
scale_units[1][0] = -1;
scale_units[1][1] = -1;
}
if (pMask == NULL) {
BEGIN_LP_RING(10);
OUT_RING(_3DSTATE_MAP_STATE | 3);
OUT_RING(0x00000001); /* map 0 */
OUT_RING(mapstate[0]);
OUT_RING(mapstate[1]);
OUT_RING(mapstate[2]);
OUT_RING(_3DSTATE_SAMPLER_STATE | 3);
OUT_RING(0x00000001); /* sampler 0 */
OUT_RING(samplerstate[0]);
OUT_RING(samplerstate[1]);
OUT_RING(samplerstate[2]);
ADVANCE_LP_RING();
} else {
BEGIN_LP_RING(16);
OUT_RING(_3DSTATE_MAP_STATE | 6);
OUT_RING(0x00000003); /* map 0,1 */
OUT_RING(mapstate[0]);
OUT_RING(mapstate[1]);
OUT_RING(mapstate[2]);
OUT_RING(mapstate[3]);
OUT_RING(mapstate[4]);
OUT_RING(mapstate[5]);
OUT_RING(_3DSTATE_SAMPLER_STATE | 6);
OUT_RING(0x00000003); /* sampler 0,1 */
OUT_RING(samplerstate[0]);
OUT_RING(samplerstate[1]);
OUT_RING(samplerstate[2]);
OUT_RING(samplerstate[3]);
OUT_RING(samplerstate[4]);
OUT_RING(samplerstate[5]);
ADVANCE_LP_RING();
}
{
CARD32 ss2;
BEGIN_LP_RING(18);
/* color buffer
* XXX: Need to add USE_FENCE if we ever tile the X Server's pixmaps or
* visible screen.
*/
OUT_RING(_3DSTATE_BUF_INFO_CMD);
OUT_RING(BUF_3D_ID_COLOR_BACK| BUF_3D_PITCH(dst_pitch));
OUT_RING(BUF_3D_ADDR(dst_offset));
OUT_RING(_3DSTATE_DST_BUF_VARS_CMD);
OUT_RING(dst_format);
OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 3);
ss2 = S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D);
if (pMask)
ss2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_2D);
else
ss2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT);
ss2 |= S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT);
ss2 |= S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT);
ss2 |= S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT);
ss2 |= S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT);
ss2 |= S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT);
ss2 |= S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT);
OUT_RING(ss2);
OUT_RING((1 << S4_POINT_WIDTH_SHIFT) | S4_LINE_WIDTH_ONE |
S4_CULLMODE_NONE| S4_VFMT_XY);
blendctl = I915GetBlendCntl(op, pMaskPicture, pDstPicture->format);
OUT_RING(0x00000000); /* Disable stencil buffer */
OUT_RING(S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE |
(BLENDFUNC_ADD << S6_CBUF_BLEND_FUNC_SHIFT) | blendctl);
/* issue a flush */
OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
OUT_RING(MI_NOOP);
/* draw rect is unconditional */
OUT_RING(_3DSTATE_DRAW_RECT_CMD);
OUT_RING(0x00000000);
OUT_RING(0x00000000); /* ymin, xmin*/
OUT_RING(DRAW_YMAX(pDst->drawable.height - 1) |
DRAW_XMAX(pDst->drawable.width - 1));
OUT_RING(0x00000000); /* yorig, xorig (relate to color buffer?)*/
OUT_RING(MI_NOOP);
ADVANCE_LP_RING();
}
FS_BEGIN();
/* Declare the registers necessary for our program. I don't think the
* S then T ordering is necessary.
*/
i915_fs_dcl(FS_S0);
if (pMask)
i915_fs_dcl(FS_S1);
i915_fs_dcl(FS_T0);
if (pMask)
i915_fs_dcl(FS_T1);
/* Load the pSrcPicture texel */
i915_fs_texld(FS_R0, FS_S0, FS_T0);
/* If the texture lacks an alpha channel, force the alpha to 1. */
if (PICT_FORMAT_A(pSrcPicture->format) == 0)
i915_fs_mov_masked(FS_R0, MASK_W, i915_fs_operand_one());
if (!pMask) {
/* No mask, so move to output color */
i915_fs_mov(FS_OC, i915_fs_operand_reg(FS_R0));
} else {
/* Load the pMaskPicture texel */
i915_fs_texld(FS_R1, FS_S1, FS_T1);
/* If the texture lacks an alpha channel, force the alpha to 1. */
if (PICT_FORMAT_A(pMaskPicture->format) == 0)
i915_fs_mov_masked(FS_R1, MASK_W, i915_fs_operand_one());
/* If component alpha is set in the mask and the blend operation
* uses the source alpha, then we know we don't need the source
* value (otherwise we would have hit a fallback earlier), so we
* provide the source alpha (src.A * mask.X) as output color.
* Conversely, if CA is set and we don't need the source alpha, then
* we produce the source value (src.X * mask.X) and the source alpha
* is unused.. Otherwise, we provide the non-CA source value
* (src.X * mask.A).
*/
if (pMaskPicture->componentAlpha) {
if (I915BlendOp[op].src_alpha) {
i915_fs_mul(FS_OC, i915_fs_operand(FS_R0, W, W, W, W),
i915_fs_operand_reg(FS_R1));
} else {
i915_fs_mul(FS_OC, i915_fs_operand_reg(FS_R0),
i915_fs_operand_reg(FS_R1));
}
} else {
i915_fs_mul(FS_OC, i915_fs_operand_reg(FS_R0),
i915_fs_operand(FS_R1, W, W, W, W));
}
}
FS_END();
return TRUE;
}

View File

@ -161,6 +161,9 @@
#define COLR_BUF_RGB555 (1<<8)
#define COLR_BUF_RGB565 (2<<8)
#define COLR_BUF_ARGB8888 (3<<8)
#define COLR_BUF_ARGB4444 (8<<8)
#define COLR_BUF_ARGB1555 (9<<8)
#define COLR_BUF_ARGB2AAA (0xa<<8)
#define DEPTH_FRMT_16_FIXED 0
#define DEPTH_FRMT_16_FLOAT (1<<2)
#define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2)
@ -685,7 +688,9 @@
/* p207 */
/* p207.
* The DWORD count is 3 times the number of bits set in MS1_MAPMASK_MASK
*/
#define _3DSTATE_MAP_STATE (CMD_3D|(0x1d<<24)|(0x0<<16))
#define MS1_MAPMASK_SHIFT 0
@ -752,6 +757,7 @@
#define MS3_TILED_SURFACE (1<<1)
#define MS3_TILE_WALK (1<<0)
/* The pitch is the pitch measured in DWORDS, minus 1 */
#define MS4_PITCH_SHIFT 21
#define MS4_CUBE_FACE_ENA_NEGX (1<<20)
#define MS4_CUBE_FACE_ENA_POSX (1<<19)
@ -768,7 +774,9 @@
#define MS4_VOLUME_DEPTH_SHIFT 0
#define MS4_VOLUME_DEPTH_MASK (0xff<<0)
/* p244 */
/* p244.
* The DWORD count is 3 times the number of bits set in SS1_MAPMASK_MASK.
*/
#define _3DSTATE_SAMPLER_STATE (CMD_3D|(0x1d<<24)|(0x1<<16))
#define SS1_MAPMASK_SHIFT 0

View File

@ -93,35 +93,9 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
*/
*pI830->used3D |= 1 << 30;
BEGIN_LP_RING(44);
pI830->last_3d = LAST_3D_VIDEO;
/* invarient state */
OUT_RING(MI_NOOP);
OUT_RING(_3DSTATE_AA_CMD |
AA_LINE_ECAAR_WIDTH_ENABLE | AA_LINE_ECAAR_WIDTH_1_0 |
AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0);
OUT_RING(_3DSTATE_DFLT_DIFFUSE_CMD);
OUT_RING(0x00000000);
OUT_RING(_3DSTATE_DFLT_SPEC_CMD);
OUT_RING(0x00000000);
OUT_RING(_3DSTATE_DFLT_Z_CMD);
OUT_RING(0x00000000);
OUT_RING(_3DSTATE_COORD_SET_BINDINGS | CSB_TCB(0, 0) | CSB_TCB(1, 1) |
CSB_TCB(2,2) | CSB_TCB(3,3) | CSB_TCB(4,4) | CSB_TCB(5,5) |
CSB_TCB(6,6) | CSB_TCB(7,7));
OUT_RING(_3DSTATE_RASTER_RULES_CMD |
ENABLE_TRI_FAN_PROVOKE_VRTX | TRI_FAN_PROVOKE_VRTX(2) |
ENABLE_LINE_STRIP_PROVOKE_VRTX | LINE_STRIP_PROVOKE_VRTX(1) |
ENABLE_TEXKILL_3D_4D | TEXKILL_4D |
ENABLE_POINT_RASTER_RULE | OGL_POINT_RASTER_RULE);
OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | 1);
OUT_RING(0x00000000); /* texture coordinate wrap */
BEGIN_LP_RING(24);
/* flush map & render cache */
OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
@ -136,25 +110,13 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
OUT_RING(0x00000000); /* yorigin, xorigin */
OUT_RING(MI_NOOP);
/* scissor */
OUT_RING(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
OUT_RING(_3DSTATE_SCISSOR_RECT_0_CMD);
OUT_RING(0x00000000); /* ymin, xmin */
OUT_RING(0x00000000); /* ymax, xmax */
OUT_RING(0x7c000003); /* unknown command */
OUT_RING(0x7d070000);
OUT_RING(0x00000000);
OUT_RING(0x68000002);
/* context setup */
OUT_RING(_3DSTATE_MODES_4_CMD |
ENABLE_LOGIC_OP_FUNC | LOGIC_OP_FUNC(LOGICOP_COPY) |
ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(0xff) |
ENABLE_STENCIL_TEST_MASK | STENCIL_TEST_MASK(0xff));
OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 4);
I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 3);
s2 = S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D);
if (planar)
s2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_2D);
@ -175,12 +137,6 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
(1 << S6_CBUF_DST_BLEND_FACT_SHIFT) | S6_COLOR_WRITE_ENABLE |
(2 << S6_TRISTRIP_PV_SHIFT));
OUT_RING(_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD |
IAB_MODIFY_ENABLE |
IAB_MODIFY_FUNC | (BLENDFUNC_ADD << IAB_FUNC_SHIFT) |
IAB_MODIFY_SRC_FACTOR | (BLENDFACT_ONE << IAB_SRC_FACTOR_SHIFT) |
IAB_MODIFY_DST_FACTOR | (BLENDFACT_ZERO << IAB_DST_FACTOR_SHIFT));
OUT_RING(_3DSTATE_CONST_BLEND_COLOR_CMD);
OUT_RING(0x00000000);
@ -193,9 +149,6 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
OUT_RING(LOD_PRECLAMP_OGL |
DSTORG_HORT_BIAS(0x80) | DSTORG_VERT_BIAS(0x80) | format);
OUT_RING(_3DSTATE_STIPPLE);
OUT_RING(0x00000000);
/* front buffer, pitch, offset */
OUT_RING(_3DSTATE_BUF_INFO_CMD);
OUT_RING(BUF_3D_ID_COLOR_BACK | BUF_3D_USE_FENCE |