/******************************Module*Header*******************************\ * Module Name: mcdpoint.c * * Contains all of the point-rendering routines for the Cirrus Logic 546X MCD driver. * * (based on mcdpoint.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" #define TRUNCCOORD(value, intValue)\ intValue = __MCD_VERTEX_FIXED_TO_INT(__MCD_VERTEX_FLOAT_TO_FIXED(value)) VOID FASTCALL __MCDRenderPoint(DEVRC *pRc, MCDVERTEX *a) { ULONG clipNum; RECTL *pClip; LONG lCoord; PDEV *ppdev = pRc->ppdev; unsigned int *pdwNext = ppdev->LL_State.pDL->pdwNext; // 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 LONG ax, ay; 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) #if 0 // FUTURE - need to enable 3d control regs setup for texture // Turn on alpha blending if it is required and is not already on // Also turn it off if it is on and is not required // // Note: LL_ALPHA bit should be 1 // if( (dwFlags ^ (LL_State.dwControl0>>15)) & 1 ) { // Alpha enable is bit 15 in control0, so toggle it // LL_State.dwControl0 ^= 0x00008000; // bit 15 *pdwNext++ = write_register( CONTROL0_3D, 1 ); *pdwNext++ = LL_State.dwControl0; } #if 0 // MCD never uses alpha_mode 0 // Set up the da_main, da_ortho registers necessary for // constant alpha blending // ======== if( (dwFlags & LL_ALPHA) && (LL_State.Control0.Alpha_Mode == 0) ) { // Check if a new value needs to be set // if( LL_State.rDA_MAIN != LL_State.AlphaConstSource || LL_State.rDA_ORTHO != LL_State.AlphaConstDest ) { *(pdwNext+0) = write_register( DA_MAIN_3D, 2 ); *(pdwNext+1) = LL_State.rDA_MAIN = LL_State.AlphaConstSource; *(pdwNext+2) = LL_State.rDA_ORTHO = LL_State.AlphaConstDest; pdwNext += 3; } } #endif // NOTE!!! - caller (MCDPrimDrawPoints) will put this in outlist, which will be sent at end of this proc // *pdwNext++ = write_register( Y_COUNT_3D, 1 ); // *pdwNext++ = 0; #endif 0 // FUTURE - (end 3d control regs setup for texture) // Store the first address for the opcode // dwOrig = pdwNext; // Start with a plain point instruction (no modifiers) // and assume same color. Count=2 for x,y // dwOpcode = POINT | SAME_COLOR | 2; // 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 ); */ // no point stippling for OpenGL dwOpcode |= pRc->privateEnables & __MCDENABLE_Z ; dwOpcode |= pRc->privateEnables & __MCDENABLE_DITHER ; //SNAPCOORD(a->windowCoord.x, ax); TRUNCCOORD(a->windowCoord.x, ax); lCoord = ax + pRc->xOffset; // adds window offset, removes a000 offset *(pdwNext+1) = (DWORD) (lCoord << 16 ); //SNAPCOORD(a->windowCoord.y, ay); TRUNCCOORD(a->windowCoord.y, ay); lCoord = ay + pRc->yOffset; // adds window offset, removes a000 offset *(pdwNext+2) = (DWORD) ((lCoord << 16) + 1); pdwNext += 3; if( !(dwFlags & LL_SAME_COLOR) ) { register DWORD color; // Clear same_color flag // dwOpcode ^= LL_SAME_COLOR; *pdwNext = FTOL(a->colors[0].r * pRc->rScale); *(pdwNext+1) = FTOL(a->colors[0].g * pRc->gScale); *(pdwNext+2) = FTOL(a->colors[0].b * pRc->bScale); dwOpcode += 3; pdwNext += 3; } if( pRc->privateEnables & __MCDENABLE_Z) { *pdwNext++ = FTOL(a->windowCoord.z * pRc->zScale); dwOpcode += 1; } #if 0 if( dwFlags & LL_TEXTURE ) { ... ... ... } #endif if (pRc->privateEnables & (__MCDENABLE_BLEND|__MCDENABLE_FOG)) { float v1alp; 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; } else { v1alp = a->fog * (float)16777215.0; // convert from 0->1.0 val to 0->ff.ffff val } *pdwNext++ = FTOL(v1alp) & 0x00ffff00;// bits 31->24 and 7->0 reserved dwOpcode += ( FETCH_COLOR | ALPHA + 1 ); } // 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 pt 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 __MCDRenderGenPoint(DEVRC *pRc, MCDVERTEX *pv) { // MGA and S3 MCD's have no code in this proc MCDBG_PRINT("__MCDRenderGenPoint - EMPTY ROUTINE"); }