Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

356 lines
11 KiB

/******************************Module*Header*******************************\
* Module Name: mcdline.c
*
* Contains all of the line-rendering routines for the Cirrus Logic 546X MCD driver.
*
* (based on mcdline.c from NT4.0 DDK)
*
* Copyright (c) 1996 Microsoft Corporation
* Copyright (c) 1997 Cirrus Logic, Inc.
\**************************************************************************/
#include "precomp.h"
#include "mcdhw.h"
#include "mcdutil.h"
#include "mcdmath.h"
//#undef CHECK_FIFO_FREE
//#define CHECK_FIFO_FREE
#define EXCHANGE(i,j) \
{ \
ptemp=i; \
i=j; j=ptemp; \
}
VOID FASTCALL __MCDRenderLine(DEVRC *pRc, MCDVERTEX *a, MCDVERTEX *b, BOOL resetLine)
{
ULONG clipNum;
RECTL *pClip;
LONG lCoord;
PDEV *ppdev = pRc->ppdev;
unsigned int *pdwNext = ppdev->LL_State.pDL->pdwNext;
void *ptemp; // for EXCHANGE and ROTATE_L macros
// output queue stuff...
DWORD *pSrc;
DWORD *pDest = ppdev->LL_State.pRegs + HOST_3D_DATA_PORT;
DWORD *pdwStart = ppdev->LL_State.pDL->pdwStartOutPtr;
DWORD dwFlags=0; // MCD_TEMP - dwflags initialized to 0
DWORD *dwOrig; /* Temp display list pointer */
DWORD dwOpcode; // Built opcode
float frecip_step;
float v1red,v1grn,v1blu;
LONG ax, bx, ay, by;
// FUTURE - do something with resetLine input to line render proc
if ((clipNum = pRc->pEnumClip->c) > 1) {
pClip = &pRc->pEnumClip->arcl[0];
SET_HW_CLIP_REGS(pRc,pdwNext);
pClip++;
}
// window coords are float values, and need to have
// viewportadjust (MCDVIEWPORT) values subtracted to get to real screen space
// color values are 0->1 floats and must be multiplied by scale values (MCDRCINFO)
// to get to nbits range (scale = 0xff for 8 bit, 0x7 for 3 bit, etc.)
// Z values are 0->1 floats and must be multiplied by zscale values (MCDRCINFO)
// Exchange the pointers to vertices if the second point
// of the line is above the first one
//
pRc->pvProvoking = a; // keep track of original first for possible flat shading
if( a->windowCoord.y > b->windowCoord.y )
{
EXCHANGE(a,b);
}
// Store the first address for the opcode
//
dwOrig = pdwNext;
pdwNext += 3;
// Start with a plain line instruction (no modifiers)
// and assume same color. Also add three words for DDA
// line parameters + count (they can not be avoided)
//
dwOpcode = LINE | SAME_COLOR | (2+3);
// Set flags as requested from the dwFlags field of a batch.
// These bits have 1-1 correspondence to their instruction
// counterparts.
//
// Flags : LL_DITHER - Use dither pattern
// LL_PATTERN - Draw pattern
// LL_STIPPLE - Use stipple mask
// LL_LIGHTING - Do lighting
// LL_Z_BUFFER - Use Z buffer
// FETCH_COLOR - Appended for alpha blending
// LL_GOURAUD - Use Gouraud shading
// LL_TEXTURE - Texture mapping
//
/*
dwOpcode |= dwFlags &
( LL_DITHER | LL_PATTERN | LL_STIPPLE
| LL_LIGHTING | LL_Z_BUFFER | FETCH_COLOR
| LL_GOURAUD | LL_TEXTURE );
*/
dwOpcode |= pRc->privateEnables & (__MCDENABLE_SMOOTH|__MCDENABLE_Z);
if (pRc->privateEnables & __MCDENABLE_LINE_STIPPLE)
{
dwOpcode |= LL_STIPPLE;
}
else
{
// can dither only if no stipple
dwOpcode |= (pRc->privateEnables & __MCDENABLE_DITHER) ;
}
if( !(dwFlags & LL_SAME_COLOR) )
{
register DWORD color;
// Clear same_color flag
//
dwOpcode ^= LL_SAME_COLOR;
// If the line is shaded, the starting color that should
// be set is the topmost point (pVert1)
if (pRc->privateEnables & __MCDENABLE_SMOOTH)
{
v1red = a->colors[0].r * pRc->rScale;
*pdwNext = FTOL(v1red);
v1grn = a->colors[0].g * pRc->gScale;
v1blu = a->colors[0].b * pRc->bScale;
*(pdwNext+1) = FTOL(v1grn);
*(pdwNext+2) = FTOL(v1blu);
dwOpcode += 3;
pdwNext += 3;
}
else
{
MCDCOLOR *pColor = &pRc->pvProvoking->colors[0];
*pdwNext = FTOL(pColor->r * pRc->rScale);
*(pdwNext+1) = FTOL(pColor->g * pRc->gScale);
*(pdwNext+2) = FTOL(pColor->b * pRc->bScale);
dwOpcode += 3;
pdwNext += 3;
}
}
// Set the parameters of a line slope and count
// Note: line can only go down, so dy is always positive
//
{
int dx, dy, abs_dx, xdir;
// Well ordered points - set starting point1 coords
// using a pointer to the origin of the instruction
//
ax = FTOL(a->windowCoord.x);
lCoord = ax + pRc->xOffset;
*(dwOrig+1) = (DWORD) (lCoord << 16 );
ay = FTOL(a->windowCoord.y);
lCoord = ay + pRc->yOffset;
*(dwOrig+2) = (DWORD) (lCoord << 16 );
bx = FTOL(b->windowCoord.x);
by = FTOL(b->windowCoord.y);
// dx = x2 - x1,
// dy = y2 - y1 (always positive)
//
dx = bx - ax;
dy = by - ay;
// NOTE that dx and dy are in 32.0 format (LL3D has them in 16.16)
// so math below differs from LL3D
// make sure dx is positive, and setup xdir needed for x major since we're
// already doing the compare here to prevent having to do again for x major case
if (dx < 0)
{
abs_dx = -dx;
xdir = 0xffff0000;
}
else
{
abs_dx = dx;
xdir = 0x00010000;
}
if( abs_dx > dy )
{
// X-major
//
// compute slope with positive dx
frecip_step = ppdev->frecips[abs_dx];
*(pdwNext + 0) = xdir;
*(pdwNext + 1) = abs_dx;
// *(pdwNext + 2) = (double)dy / (double)ABS(dx) * 65536.0;
*(pdwNext + 2) = FTOL(dy * frecip_step * (float)65536.0); // equivalent to above
}
else
{
// Y-major
//
frecip_step = ppdev->frecips[dy];
*(pdwNext + 1) = dy; // Positive count always, by virtue of earlier EXCHANGE
*(pdwNext + 2) = 0x10000; // dy = 1
// *(pdwNext + 0) = (double)dx / (double)dy * 65536.0;
*(pdwNext + 0) = FTOL(dx * frecip_step * (float)65536.0); // equivalent to above
}
pdwNext += 3;
}
if (pRc->privateEnables & __MCDENABLE_SMOOTH)
{
float tmp;
// Calculate and set the color gradients
//
tmp = ((b->colors[0].r * pRc->rScale) - v1red) * frecip_step;
*pdwNext++ = FTOL(tmp);
tmp = ((b->colors[0].g * pRc->gScale) - v1grn) * frecip_step;
*pdwNext++ = FTOL(tmp);
tmp = ((b->colors[0].b * pRc->bScale) - v1blu) * frecip_step;
*pdwNext++ = FTOL(tmp);
// Increase count field by 6 for DR_MAIN_3D, DG_MAIN_3D,
// DB_MAIN_3D and DR_ORTHO_3D, DG_ORTHO_3D, DB_ORTHO_3D
//
dwOpcode += 3;
}
if( pRc->privateEnables & __MCDENABLE_Z)
{
float fdz_main = (b->windowCoord.z - a->windowCoord.z) * pRc->zScale * frecip_step;
*pdwNext++ = FTOL(a->windowCoord.z * pRc->zScale);
*pdwNext++ = FTOL(fdz_main);
// Increase count field by 2 for Z_3D, DZ_MAIN_3D
//
dwOpcode += 2;
}
#if 0
if( dwFlags & LL_TEXTURE )
{
...
...
...
}
#endif
if (pRc->privateEnables & (__MCDENABLE_BLEND|__MCDENABLE_FOG))
{
float v1alp,tmp;
if (pRc->privateEnables & __MCDENABLE_BLEND)
{
// recall that if both blending and fog active, all prims punted back to software
v1alp = a->colors[0].a * pRc->aScale;
*(pdwNext+0) = FTOL(v1alp);
tmp = ((b->colors[0].a * pRc->aScale) - v1alp) * frecip_step;
*(pdwNext+1) = FTOL(tmp);
}
else
{
v1alp = a->fog * (float)16777215.0; // convert from 0->1.0 val to 0->ff.ffff val
*(pdwNext+0) = FTOL(v1alp);
tmp = ((b->fog * (float)16777215.0) - v1alp) * frecip_step;
*(pdwNext+1) = FTOL(tmp);
}
*(pdwNext+0) &= 0x00ffff00;// bits 31->24 and 7->0 reserved
*(pdwNext+1) &= 0xffffff00;// bits 7->0 reserved
dwOpcode += ( FETCH_COLOR | ALPHA + 2 );
pdwNext += 2;
}
// Store the final opcode
//
*dwOrig = dwOpcode;
while (--clipNum) {
int len = (dwOpcode & 0x3F) + 1; // num words for line primitive
SET_HW_CLIP_REGS(pRc,pdwNext)
pClip++;
// dump same line regs again to draw while clipping against occlusion rectangle
pSrc = dwOrig;
while( len-- ) *pdwNext++ = *pSrc++;
}
// output queued data here....
#if 0 // FUTURE - enable queueing algorithm - just outputting everything for now
OUTPUT_COPROCMODE_QUEUE
#else // 0
{
pSrc = pdwStart;
while (pSrc != pdwNext)
{
/* Get the amount of data for this opcode */
int len = (*pSrc & 0x3F) + 1;
USB_TIMEOUT_FIX(ppdev)
while( len-- ) *pDest = *pSrc++;
}
}
#endif // 0
ppdev->LL_State.pDL->pdwNext = ppdev->LL_State.pDL->pdwStartOutPtr = pdwStart;
}
VOID FASTCALL __MCDRenderGenLine(DEVRC *pRc, MCDVERTEX *pv1, MCDVERTEX *pv2, BOOL resetLine)
{
// MGA and S3 MCD's have no code in this proc
MCDBG_PRINT("__MCDRenderGenLine - EMPTY ROUTINE");
}