|
|
/******************************Module*Header*******************************\
* * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * !! !! * !! WARNING: NOT DDK SAMPLE CODE !! * !! !! * !! This source code is provided for completeness only and should not be !! * !! used as sample code for display driver development. Only those sources !! * !! marked as sample code for a given driver component should be used for !! * !! development purposes. !! * !! !! * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * * Module Name: directx.h * * Content: DirectX macros and definitions * * Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved. * Copyright (c) 1995-2003 Microsoft Corporation \**************************************************************************/
#ifndef __DIRECTX_H
#define __DIRECTX_H
#ifdef WNT_DDRAW
#include "dx95type.h"
#endif
#ifndef __GLINTDEF
#include "glintdef.h"
#endif
#include "pmdef.h"
#ifndef __P3RXDEF
#include "p3rxdef.h"
#endif
#include "surf_fmt.h"
#include "ddover.h"
//------------------------------------------------------------------
//
//------------------------------------------------------------------
#define VTG_MEMORY_ADDRESS(a) (0x1000F | (((a >> 2) << 4) & 0xFFFF) )
#define VTG_VIDEO_ADDRESS(a) (0x20000 | (((a >> 2) << 4) & 0xFFFF) )
#define MEM_MEMORYSCRATCH 0x10
#define VID_SCREENBASE 0x0
#if DX7_STEREO
#define VID_VIDEOCONTROL 0x58
#define VID_SCREENBASERIGHT 0x80
#define __VIDEO_STEREOENABLE 0x800
#endif
//------------------------------------------------------------------
//
//------------------------------------------------------------------
#if !DBG
#define STOP_SOFTWARE_CURSOR(pThisDisplay) \
pThisDisplay->pGLInfo->dwFlags |= GMVF_GCOP #define START_SOFTWARE_CURSOR(pThisDisplay) \
pThisDisplay->pGLInfo->dwFlags &= ~GMVF_GCOP #else
#define STOP_SOFTWARE_CURSOR(pThisDisplay) \
{ \ DISPDBG((DBGLVL, "STOP_SW_CURSOR %s %d", __FILE__, __LINE__ )); \ if (pThisDisplay->pGLInfo->dwFlags & GMVF_GCOP) \ DISPDBG((WRNLVL,"Stopping Cursor that is already stopped!"));\ pThisDisplay->pGLInfo->dwFlags |= GMVF_GCOP; \ }
#define START_SOFTWARE_CURSOR(pThisDisplay) \
{ \ DISPDBG((DBGLVL, "START_SW_CURSOR %s, %d", __FILE__, __LINE__ ));\ if (!(pThisDisplay->pGLInfo->dwFlags & GMVF_GCOP)) \ DISPDBG((WRNLVL,"Starting Cursor that is already started!"));\ pThisDisplay->pGLInfo->dwFlags &= ~GMVF_GCOP; \ }
#endif // !DBG
//------------------------------------------------------------------
//
//------------------------------------------------------------------
// From MS, undocumented sharing flag
#define HEAP_SHARED 0x04000000 // put heap in shared memory
//------------------------------------------------------------------
// Defines for video flipping, etc.
//------------------------------------------------------------------
#define IN_VBLANK \
(pThisDisplay->pGlint->LineCount < pThisDisplay->pGlint->VbEnd)
#define IN_DISPLAY (!IN_VBLANK)
//------------------------------------------------------------------
//
//------------------------------------------------------------------
#if WNT_DDRAW
#define DXCONTEXT_IMMEDIATE(pThisDisplay) \
vGlintSwitchContext(pThisDisplay->ppdev, \ pThisDisplay->ppdev->DDContextID); #define IS_DXCONTEXT_CURRENT(pThisDisplay) \
(((pThisDisplay->ppdev->currentCtxt) != \ (pThisDisplay->ppdev->DDContextID)) ? FALSE : TRUE) #else // WNT_DDRAW
#define DXCONTEXT_IMMEDIATE(pThisDisplay) \
ChangeContext(pThisDisplay, \ pThisDisplay->pGLInfo, \ CONTEXT_DIRECTX_HANDLE);
#define IS_DXCONTEXT_CURRENT(pThisDisplay) \
((pThisDisplay->pGLInfo->dwCurrentContext != CONTEXT_DIRECTX_HANDLE) ? \ FALSE : TRUE) #endif // WNT_DDRAW
//------------------------------------------------------------------
// For comparing GUID's
//------------------------------------------------------------------
#ifdef __cplusplus
#define MATCH_GUID(a, b) IsEqualIID((a), (b))
#else
#define MATCH_GUID(a, b) IsEqualIID(&(a), &(b))
#endif
//------------------------------------------------------------------
// Registry
//------------------------------------------------------------------
#ifdef WNT_DDRAW
#define GET_REGISTRY_ULONG_FROM_STRING(a, b) \
bGlintQueryRegistryValueUlong(pThisDisplay->ppdev, L##a, (DWORD*)b) #define SET_REGISTRY_STRING_FROM_ULONG(a, b) \
bGlintSetRegistryValueString(pThisDisplay->ppdev, L##a, b) #define GET_REGISTRY_STRING(a, b) \
bGlintQueryRegistryValueString(pThisDisplay->ppdev, L##a, b, c) #else
// Win95 calls the same registry call as it always did,
// NT makes the call with an extra parameter - the ppdev
BOOL bGlintQueryRegistryValueString(LPTSTR valueStr, char* pString, int StringLen); BOOL bGlintQueryRegistryValueUlong(LPTSTR valueStr, PULONG pData); BOOL bGlintQueryRegistryValueUlongAsUlong(LPTSTR valueStr, PULONG pData); BOOL bGlintSetRegistryValueString(LPTSTR valueStr, ULONG Data);
#define GET_REGISTRY_ULONG_FROM_STRING(a, b) \
bGlintQueryRegistryValueUlong(a, (DWORD*)b) #define GET_REGISTRY_STRING(a, b) \
bGlintQueryRegistryValueString(a, b, strlen(a)) #define SET_REGISTRY_STRING_FROM_ULONG(a, b) \
bGlintSetRegistryValueString(a, b)
#endif // WNT_DDRAW
//------------------------------------------------------------------
// Memory Allocation calls
//------------------------------------------------------------------
#ifdef WNT_DDRAW
#define HEAP_ALLOC(flags, size, tag) ENGALLOCMEM(FL_ZERO_MEMORY, size, tag)
#define HEAP_FREE(ptr) ENGFREEMEM(ptr)
// Shared memory allocation calls. On NT , the 16 bit ptr is irrelevant and
// the call is resolved as a normal call to HEAP_ALLOC/HEAP_FREE
// The 16 bit ptrs are alwasy defined as DWORD and the 32 bit as ULONG_PTR
__inline void SHARED_HEAP_ALLOC(DWORD *ppData16, ULONG_PTR* ppData32, DWORD size) { *ppData32 = (ULONG_PTR) HEAP_ALLOC(FL_ZERO_MEMORY, size , ALLOC_TAG_DX(S)); *ppData16 = (DWORD)(*ppData32); }
__inline void SHARED_HEAP_FREE(DWORD *ppData16, ULONG_PTR * ppData32, BOOL bZero) { HEAP_FREE((PVOID)(*ppData32));
if (bZero) { *ppData32 = 0; *ppData16 = 0; } }
#else
#define FL_ZERO_MEMORY HEAP_ZERO_MEMORY
#define HEAP_ALLOC(flags, size, tag) \
HeapAlloc((HANDLE)g_DXGlobals.hHeap32, flags, size) #define HEAP_FREE(ptr) \
HeapFree((HANDLE)g_DXGlobals.hHeap32, 0, ptr)
BOOL SharedHeapAlloc(DWORD* ppData16, ULONG_PTR* ppData32, DWORD size); void SharedHeapFree(DWORD ptr16, ULONG_PTR ptr32);
// Shared memory allocation calls. On Win9x , the 16 bit ptr is important.
// We map this calls to some Win9x specific code
#define SHARED_HEAP_ALLOC( ppData16, ppData32, size) \
SharedHeapAlloc(ppData16, ppData32, size);
#define SHARED_HEAP_FREE( ppData16, ppData32, bZero) \
{ \ SharedHeapFree(*(ppData16), *(ppData32)); \ if (bZero) \ { \ *ppData32 = 0; \ *ppData16 = 0; \ } \ }
#endif // WNT_DDRAW
//------------------------------------------------------------------
// Display driver's DC
//------------------------------------------------------------------
// Allows us to get the display driver's DC at any point.
// CREATE_DRIVER_DC must be matched by a DELETE_DRIVER_DC.
#define CREATE_DRIVER_DC(pGLInfo) ( \
( ( (pGLInfo)->szDeviceName[7] == '\0' ) && \ ( (pGLInfo)->szDeviceName[6] == 'Y' ) && \ ( (pGLInfo)->szDeviceName[5] == 'A' ) && \ ( (pGLInfo)->szDeviceName[4] == 'L' ) && \ ( (pGLInfo)->szDeviceName[3] == 'P' ) && \ ( (pGLInfo)->szDeviceName[2] == 'S' ) && \ ( (pGLInfo)->szDeviceName[1] == 'I' ) && \ ( (pGLInfo)->szDeviceName[0] == 'D' ) ) ? \ /* The Win95 and NT4-compatible version */ \ ( CreateDC ( "DISPLAY", NULL, NULL, NULL ) ) : \ /* The Win98 and NT5-compatible multimon version */ \ ( CreateDC ( NULL, (pGLInfo)->szDeviceName, NULL, NULL ) ) \ )
#define DELETE_DRIVER_DC(hDC) DeleteDC(hDC)
//------------------------------------------------------------------
// Macro to define a FOURCC.
// Needed on NT builds. On Win9x it comes from the DDK.
//------------------------------------------------------------------
#ifndef MAKEFOURCC
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \ ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 )) #endif //defined(MAKEFOURCC)
// For the video
#define FOURCC_YUV422 (MAKEFOURCC('Y','U','Y','2'))
#define FOURCC_YUV411 (MAKEFOURCC('Y','4','1','1'))
// Mediamatics private 4CC's
#define FOURCC_MVCA (MAKEFOURCC('M','V','C','A'))
#define FOURCC_MVSU (MAKEFOURCC('M','V','S','U'))
#define FOURCC_MVSB (MAKEFOURCC('M','V','S','B'))
//------------------------------------------------------------------
//------------------------------------------------------------------
#define PACKED_PP_LOOKUP(a) (pThisDisplay->PPCodes[(a) >> 5] & 0x1FF)
#define PACKED_PP_LOOKUP4(a) (pThisDisplay->PPCodes[(a) >> 5])
#define PP0_LOOKUP(a) (PACKED_PP_LOOKUP(a) & 0x7)
#define PP1_LOOKUP(a) ((PACKED_PP_LOOKUP(a) >> 3) & 0x7)
#define PP2_LOOKUP(a) ((PACKED_PP_LOOKUP(a) >> 6) & 0x7)
#define PP3_LOOKUP(a) ((PACKED_PP_LOOKUP(a) >> 9) & 0x7)
//------------------------------------------------------------------
// Globals that are truly global across multiple displays
//------------------------------------------------------------------
typedef enum tagPixelCenterSetting { PIXELCENTER_ZERO, PIXELCENTER_NEARLY_HALF, PIXELCENTER_HALF, PIXELCENTER_FORCE_DWORD = 0xFFFFFFFF } PixelCenterSetting;
typedef struct tagDirectXGlobals { // State
HINSTANCE hInstance; // Instance handle for this DLL
DWORD hHeap32; // Shared 32 bit heap
} DirectXGlobals;
// There is one global structure in the driver. This is shared across
// all applications and all cards. It holds data such as the current
// driver settings and a handle to the memory heap that is used within
// the driver. There is also a global pointer that points at the current
// primary display
extern DirectXGlobals g_DXGlobals;
//------------------------------------------------------------------
// Driver thunked data
//------------------------------------------------------------------
#if W95_DDRAW
extern P3_THUNKEDDATA* g_pDriverData; #endif
extern struct tagThunkedData* g_pThisTemp;
#if WNT_DDRAW
#define GET_THUNKEDDATA(pThisDisplay,a) \
{ \ pThisDisplay = (P3_THUNKEDDATA*)(((PPDEV) ((a)->dhpdev))->thunkData);\ }
#else // WNT_DDRAW
#if !DBG
#define GET_THUNKEDDATA(pThisDisplay,a) \
{ \ if ((a)->dwReserved3) \ { \ pThisDisplay = (P3_THUNKEDDATA*)(a)->dwReserved3; \ } \ else \ { \ pThisDisplay = g_pDriverData; \ } \ }
#else
#define GET_THUNKEDDATA(pThisDisplay,a) \
{ \ if ((a)->dwReserved3) \ { \ pThisDisplay = (P3_THUNKEDDATA*)(a)->dwReserved3; \ DISPDBG((DBGLVL,"Secondary Display: DevHandle=0x%x", \ pThisDisplay->pGLInfo->dwDeviceHandle)); \ } \ else \ { \ pThisDisplay = g_pDriverData; \ DISPDBG((DBGLVL,"Primary Display DevHandle=0x%x", \ pThisDisplay->pGLInfo->dwDeviceHandle)); \ } \ }
#endif // !DBG
#endif // WNT_DDRAW
//------------------------------------------------------------------
//
//------------------------------------------------------------------
#define PATCH_SELECTIVE 0
#define PATCH_ALWAYS 1
#define PATCH_NEVER 2
//------------------------------------------------------------------
// Color format conversion macros
//------------------------------------------------------------------
#define FORMAT_565_32BIT(val) \
( (((val & 0xF800) >> 8) << 16) | \ (((val & 0x7E0) >> 3) << 8) | \ (((val & 0x1F) << 3) ) )
#define FORMAT_565_32BIT_BGR(val) \
( (((val & 0xF800) >> 8) ) | \ (((val & 0x7E0) >> 3) << 8) | \ (((val & 0x1F) << 19) ) )
#define FORMAT_565_32BIT_ZEROEXTEND(val) \
( (((val & 0xF800) >> 11) ) | \ (((val & 0x7E0) >> 3) << 6) | \ (((val & 0x1F) << 16) ) )
#define FORMAT_5551_32BIT(val) \
( (((val & 0x8000) >> 8) << 24) | \ (((val & 0x7C00) >> 7) << 16) | \ (((val & 0x3E0) >> 2) << 8 ) | \ (((val & 0x1F) << 3) ) )
#define FORMAT_5551_32BIT_BGR(val) \
( (((val & 0x8000) >> 8) << 24) | \ (((val & 0x7C00) >> 7) ) | \ (((val & 0x3E0) >> 2) << 8 ) | \ (((val & 0x1F) <<19) ) )
#define FORMAT_5551_32BIT_ZEROEXTEND(val) \
( (((val & 0x8000) << 9 ) ) | \ (((val & 0x7C00) >> 10 ) ) | \ (((val & 0x3E0) >> 2 ) << 5) | \ (((val & 0x1F) << 16 ) ) )
#define FORMAT_4444_32BIT(val) \
( (((val & 0xF000) << 16) ) | \ (((val & 0xF00) >> 4) << 16) | \ (((val & 0xF0) << 8) ) | \ (((val & 0xF) << 4) ) )
#define FORMAT_4444_32BIT_BGR(val) \
( ((val & 0xF000) << 16) | \ ((val & 0xF00) >> 4) | \ ((val & 0xF0) << 8) | \ ((val & 0xF) << 20) )
#define FORMAT_4444_32BIT_ZEROEXTEND(val) \
( ((val & 0xF000) << 12) | \ ((val & 0xF00) >> 8) | \ ((val & 0xF0) << 4) | \ ((val & 0xF) << 16) )
#define FORMAT_332_32BIT(val) \
( (((val & 0xE0) << 16) ) | \ (((val & 0x1C) << 3) << 8) | \ (((val & 0x3) << 6) ) )
#define FORMAT_332_32BIT_BGR(val) \
( (((val & 0xE0) ) ) | \ (((val & 0x1C) << 3) << 8) | \ (((val & 0x3) << 22) ) )
#define FORMAT_332_32BIT_ZEROEXTEND(val) \
( (((val & 0xE0) >> 5) ) | \ (((val & 0x1C) << 3) << 3) | \ (((val & 0x3) << 16)) )
#define FORMAT_2321_32BIT(val) \
( (((val & 0x80) << 24) ) | \ (((val & 0x60) << 17) ) | \ (((val & 0x1C) << 3) << 8) | \ (((val & 0x3) << 6) ) )
#define FORMAT_2321_32BIT_BGR(val) \
( (((val & 0x80) << 24) ) | \ (((val & 0x60) << 1) ) | \ (((val & 0x1C) << 3) << 8) | \ (((val & 0x3) << 22) ))
#define FORMAT_2321_32BIT_ZEROEXTEND(val) \
( (((val & 0x80) << 17) ) | \ (((val & 0x60) >> 5) ) | \ (((val & 0x1C) << 3) << 3) | \ (((val & 0x3) << 16) ) )
#define FORMAT_8888_32BIT_BGR(val) \
( ((val & 0xFF00FF00) ) | \ ((val & 0xFF0000) >> 16) | \ ((val & 0xFF) << 16) )
#define FORMAT_888_32BIT_BGR(val) \
( ((val & 0xFF00FF00) ) | \ ((val & 0xFF0000) >> 16) | \ ((val & 0xFF) << 16) )
#define CHROMA_UPPER_ALPHA(val) \
(val | 0xFF000000)
#define CHROMA_LOWER_ALPHA(val) \
(val & 0x00FFFFFF)
#define CHROMA_332_UPPER(val) \
(val | 0x001F1F3F)
#define FORMAT_PALETTE_32BIT(val) \
( ((val & 0xFF) ) | \ ((val & 0xFF) << 8) | \ ((val & 0xFF) << 16))
//------------------------------------------------------------------
// Macros for handling Render IDs.
//------------------------------------------------------------------
#if 1
// The real values
#define RENDER_ID_KNACKERED_BITS 0x00000000
#define RENDER_ID_VALID_BITS_UPPER 0x00000000
#define RENDER_ID_VALID_BITS_LOWER 0xffffffff
#define RENDER_ID_VALID_BITS_UPPER_SHIFT 0
#define RENDER_ID_VALID_BITS_SIGN_SHIFT 0
#define RENDER_ID_LOWER_LIMIT -100
#define RENDER_ID_UPPER_LIMIT 65000
#define RENDER_ID_REGISTER_NAME MemScratch
#else
// For soak-testing - should catch wrap errors much more quickly.
// Also tests the mechanism that copes with dodgy bits in the
// register (P2 MinRegion legacy stuff, but it's free to support).
#define RENDER_ID_KNACKERED_BITS 0xfff0fff0
#define RENDER_ID_VALID_BITS_UPPER 0x000f0000
#define RENDER_ID_VALID_BITS_LOWER 0x0000000f
#define RENDER_ID_VALID_BITS_UPPER_SHIFT 12
#define RENDER_ID_VALID_BITS_SIGN_SHIFT 24
#define RENDER_ID_LOWER_LIMIT -20
#define RENDER_ID_UPPER_LIMIT 100
#endif
//------------------------------------------------------------------
// Flipping compile time switches
//------------------------------------------------------------------
#if WNT_DDRAW
// Can't use timeGetTime under WinNT
// We should try to backoff using something else instead, but...
#define USE_FLIP_BACKOFF 0
#else
// Set this to 1 to enable the back-off code for flips and locks.
// On some things it's faster, on some things it's slower - tune as desired.
#define USE_FLIP_BACKOFF 1
#endif
// Get a new render ID. Need to do the OR afterwards to make
// sure the +1 gets the bits carried up properly next time.
// No need to do the OR before, because we assume dwRenderID is
// always a "valid" number, with those bits set.
#define GET_NEW_HOST_RENDER_ID() ( pThisDisplay->dwRenderID = ( pThisDisplay->dwRenderID + 1 ) | RENDER_ID_KNACKERED_BITS, pThisDisplay->dwRenderID )
// Get render ID of last operation.
#define GET_HOST_RENDER_ID() ( pThisDisplay->dwRenderID )
// Send this ID to the chip (do just after the render command).
//#define SEND_HOST_RENDER_ID(my_id) SEND_P3_DATA(RENDER_ID_REGISTER_NAME,(my_id))
#define SEND_HOST_RENDER_ID(my_id) \
SEND_P3_DATA(VTGAddress, VTG_MEMORY_ADDRESS(MEM_MEMORYSCRATCH)); \ SEND_P3_DATA(VTGData, my_id)
// Read the current ID from the chip.
#define GET_CURRENT_CHIP_RENDER_ID() ( READ_GLINT_CTRL_REG(RENDER_ID_REGISTER_NAME) | RENDER_ID_KNACKERED_BITS )
// Is the RenderID value on the chip valid?
#define CHIP_RENDER_ID_IS_VALID() ( (BOOL)pThisDisplay->bRenderIDValid )
// Do a render ID comparison. RenderIDs wrap, so you have
// to do the subtraction and _then_ test the top bit,
// not do the comparison between the two directly.
// think about a=0xfffffffe and b=0x1, and then
// about a=0x7ffffffe and b=0x80000001.
// If the two are more than 0x80000000 apart, then this
// will give the wrong result, but that's a _lot_ of renders.
// At a render every 1us (1MHz), that's still about 35 minutes.
// Bear in mind, a render is a sequence of polygons, not just one.
// If apps do as we suggest and send about 50 tris per render, and
// if they manage to get 8million tris a second troughput
// they get about 3.7 hours before wrapping.
// If this really is a problem, just extend it to 64 bits using
// MaxRegion as well.
// On P2, we only have 24 useable bits, so the wrap will happen
// sooner - every 52 seconds. However, this should at the very
// worst cause a few more SYNCs than necessary, even if it does
// go wrong. Use the above "debug" settings to do soak-testing -
// they make only 8 bits valid.
#define RENDER_ID_LESS_THAN(a,b) ( (signed)(a-b) < 0 )
// Decide if a render has finished.
#if !DBG
#define RENDER_ID_HAS_COMPLETED(my_id) ( !RENDER_ID_LESS_THAN ( (GET_CURRENT_CHIP_RENDER_ID()), (my_id) ) )
#else
// A version that is rather more paranoid about correct values.
// It's instantiated in gldd32.c
BOOL HWC_bRenderIDHasCompleted ( DWORD dwID, P3_THUNKEDDATA* pThisDisplay ); #define RENDER_ID_HAS_COMPLETED(my_id) ( HWC_bRenderIDHasCompleted ( (my_id), pThisDisplay ) )
#endif // !DBG
// This should be called once RENDER_ID_HAS_COMPLETED has failed,
// just in case a wrap-round bug has occurred. If it's true, the
// chip needs to be synced, and the surface RenderIDs updated with
// GET_HOST_RENDER_ID(). This is fairly slow,
// but that's OK, since most things that use RENDER_ID_HAS_COMPLETED
// will start spinning when it fails anyway (locks, flips, etc).
// Note that just re-syncing every time the wrap-around
// happens is not enough - we need to bring the surface
// up to date as well, so this is just as efficient
// as always resyncing, and usually faster.
// This should also never happen in real-life, but it's a
// safety net in case it does. The soak-test settings should be
// aggressive enough to force it to happen.
#define NEED_TO_RESYNC_CHIP_AND_SURFACE(my_id) ( RENDER_ID_LESS_THAN ( GET_HOST_RENDER_ID(), (my_id) ) )
// Set/get a surface's read-from/written-to render ID.
#define SET_SIB_RENDER_ID_WRITE(lpSIB,my_id) (lpSIB)->dwRenderIDWrite = (my_id)
#define SET_SIB_RENDER_ID_READ(lpSIB,my_id) (lpSIB)->dwRenderIDRead = (my_id)
#define GET_SIB_RENDER_ID_WRITE(lpSIB) ((lpSIB)->dwRenderIDWrite)
#define GET_SIB_RENDER_ID_READ(lpSIB) ((lpSIB)->dwRenderIDRead)
#define SIB_WRITE_FINISHED(lpSIB) ( RENDER_ID_HAS_COMPLETED ( GET_SIB_RENDER_ID_WRITE ( lpSIB ) ) )
#define SIB_READ_FINISHED(lpSIB) ( RENDER_ID_HAS_COMPLETED ( GET_SIB_RENDER_ID_READ ( lpSIB ) ) )
//------------------------------------------------------------------
// Macros for determining DDraw surface characteristics
//------------------------------------------------------------------
#define DDSurf_Width(lpLcl) ( (lpLcl)->lpGbl->wWidth )
#define DDSurf_Height(lpLcl) ( (lpLcl)->lpGbl->wHeight )
#define DDSurf_Pitch(lpLcl) ( (lpLcl)->lpGbl->lPitch)
#define DDSurf_dwCaps(lpLcl) ( (lpLcl)->ddsCaps.dwCaps)
#if WNT_DDRAW
#define DDSurf_IsAGP(lpLcl) \
( ((lpLcl)->ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM) ? 1 : 0 )
#define DDSurf_HasPixelFormat(dwFlags) (1)
#define DDSurf_BitDepth(lpLcl) \
((lpLcl)->lpGbl->ddpfSurface.dwRGBBitCount) #define DDSurf_AlphaBitDepth(lpLcl) \
((lpLcl)->lpGbl->ddpfSurface.dwAlphaBitDepth) #define DDSurf_RGBAlphaBitMask(lpLcl) \
((lpLcl)->lpGbl->ddpfSurface.dwRGBAlphaBitMask) #define DDSurf_GetPixelFormat(lpLcl) \
(&(lpLcl)->lpGbl->ddpfSurface) #else
#define DDSurf_HasPixelFormat(dwFlags) \
((dwFlags & DDRAWISURF_HASPIXELFORMAT) ? 1 : 0) #define DDSurf_IsAGP(lpLcl) \
( ((lpLcl)->ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM) ? 1 : 0 )
#define DDS_LCL(pdds) (((DDRAWI_DDRAWSURFACE_INT *)pdds)->lpLcl)
#define DDP_LCL(pddp) (((DDRAWI_DDRAWPALETTE_INT *)pdds)->lpLcl)
#define DDSurf_BitDepth(lpLcl) \
( ((lpLcl)->dwFlags & DDRAWISURF_HASPIXELFORMAT) ? \ ((lpLcl)->lpGbl->ddpfSurface.dwRGBBitCount) : \ ((lpLcl)->lpGbl->lpDD->vmiData.ddpfDisplay.dwRGBBitCount) \ )
#define DDSurf_AlphaBitDepth(lpLcl) \
( ((lpLcl)->dwFlags & DDRAWISURF_HASPIXELFORMAT) ? \ ((lpLcl)->lpGbl->ddpfSurface.dwAlphaBitDepth) : \ ((lpLcl)->lpGbl->lpDD->vmiData.ddpfDisplay.dwAlphaBitDepth) \ )
#define DDSurf_RGBAlphaBitMask(lpLcl) \
( ((lpLcl)->dwFlags & DDRAWISURF_HASPIXELFORMAT) ? \ ((lpLcl)->lpGbl->ddpfSurface.dwRGBAlphaBitMask) : \ ((lpLcl)->lpGbl->lpDD->vmiData.ddpfDisplay.dwRGBAlphaBitMask) \ )
#define DDSurf_GetPixelFormat(lpLcl) \
(((lpLcl)->dwFlags & DDRAWISURF_HASPIXELFORMAT) ? \ (&(lpLcl)->lpGbl->ddpfSurface) : \ (&(lpLcl)->lpGbl->lpDD->vmiData.ddpfDisplay) \ ) #endif
// Function to return the correct entry in the lookup table
P3_SURF_FORMAT* _DD_SUR_GetSurfaceFormat(LPDDRAWI_DDRAWSURFACE_LCL pLcl);
static DWORD ShiftLookup[5] = { 0, 0, 1, 0, 2}; #define DDSurf_GetPixelShift(a) \
(ShiftLookup[(DDSurf_BitDepth(a) >> 3)])
#define DDSurf_GetPixelToDWORDShift(pSurfLcl) \
(2 - DDSurf_GetPixelShift(pSurfLcl))
#define DDSurf_GetPixelPitch(pSurfLcl) \
((DDSurf_BitDepth(pSurfLcl) == 24) ? \ (DDSurf_Pitch(pSurfLcl) / 3) : \ (DDSurf_BitDepth(pSurfLcl) == 4) ? \ (DDSurf_Pitch(pSurfLcl) * 2) : \ (DDSurf_Pitch(pSurfLcl) >> DDSurf_GetPixelShift(pSurfLcl)))
#define DDSurf_GetByteWidth(pSurfLcl) \
((DDSurf_BitDepth(pSurfLcl) == 24) ? \ (DDSurf_Width(pSurfLcl) * 3) : \ (DDSurf_BitDepth(pSurfLcl) == 4) ? \ (DDSurf_Width(pSurfLcl) / 2) : \ (DDSurf_Width(pSurfLcl) << DDSurf_GetPixelShift(pSurfLcl)))
#define DDSurf_FromInt(pSurfInt) \
((LPDDRAWI_DDRAWSURFACE_LCL)((LPDDRAWI_DDRAWSURFACE_INT)pSurfInt)->lpLcl)
// 4bpp = 3, 8bpp = 0, 16bpp = 1, 24bpp = 4, 32bpp = 2
static DWORD ChipPixelSize[9] = { 0, 3, 0, 0, 1, 0, 4, 0, 2 }; #define DDSurf_GetChipPixelSize(pSurf) \
(ChipPixelSize[(DDSurf_BitDepth(pSurf) >> 2)])
#define DDSurf_GetBppMask(pSurfLcl) \
(3 >> (DDSurf_GetChipPixelSize(pSurfLcl)))
// Calculates the offset of this agp surface from the base of the agp region
unsigned long __inline DDSurf_SurfaceOffsetFromAGPBase( P3_THUNKEDDATA* pThisDisplay, LPDDRAWI_DDRAWSURFACE_LCL pLcl) { unsigned long ulOffset;
ASSERTDD(pLcl->ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM, "ERROR: DDSurf_SurfaceOffsetFromAGPBase passed non AGP surface");
#if WNT_DDRAW
// The offset into AGP memory can't be more than 4GB! //azn - check this
ulOffset = (DWORD)(pLcl->lpGbl->fpHeapOffset - pLcl->lpGbl->lpVidMemHeap->fpStart); #else
ulOffset = (SURFACE_PHYSICALVIDMEM(pLcl->lpGbl) - pThisDisplay->dwGARTDevBase); #endif
return ulOffset; } // DDSurf_SurfaceOffsetFromAGPBase
// Calculates the offset of this surface from the base of the memory as
// the chip sees it. For AGP this is the currently scrolled window
// position on P2, and on P3 it is the real physical memory address
long __inline DDSurf_SurfaceOffsetFromMemoryBase( P3_THUNKEDDATA* pThisDisplay, LPDDRAWI_DDRAWSURFACE_LCL pLcl) { long lOffset;
#if WNT_DDRAW
if (pLcl->ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM) //azn
{ DISPDBG((DBGLVL,"HeapOffset: 0x%x, fpStart: 0x%x", pLcl->lpGbl->fpHeapOffset, pLcl->lpGbl->lpVidMemHeap->fpStart));
if (pThisDisplay->pGLInfo->dwRenderFamily == P3R3_ID) { // Return the offset into the heap, accounting for the adjustment
// we might have made to the base
lOffset = ((long)pLcl->lpGbl->fpHeapOffset - (long)pLcl->lpGbl->lpVidMemHeap->fpStart) + ((long)pThisDisplay->dwGARTDevBase); } else { // Return the offset into the heap, accounting for the adjustment
// we might have made to the base
lOffset = ((long)pLcl->lpGbl->fpHeapOffset - (long)pLcl->lpGbl->lpVidMemHeap->fpStart) - ((long)pThisDisplay->dwGARTDev - (long)pThisDisplay->dwGARTDevBase ); } } else { lOffset = ((long)pLcl->lpGbl->fpVidMem - (long)pThisDisplay->dwScreenFlatAddr); } #else
if (pThisDisplay->pGLInfo->dwRenderFamily == P3R3_ID) { if (pLcl->ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM) { lOffset = (long)SURFACE_PHYSICALVIDMEM(pLcl->lpGbl); } else { lOffset = ((long)pLcl->lpGbl->fpVidMem - (long)pThisDisplay->dwScreenFlatAddr); } } else { if (pLcl->ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM) { lOffset = ((long)SURFACE_PHYSICALVIDMEM(pLcl->lpGbl) - (long)pThisDisplay->dwGARTDev); } else { lOffset = ((long)pLcl->lpGbl->fpVidMem - (long)pThisDisplay->dwScreenFlatAddr); } } #endif // WNT_DDRAW
return lOffset; } // DDSurf_SurfaceOffsetFromMemoryBase
//------------------------------------------------------------------
// Function to send a command to the VXD.
//------------------------------------------------------------------
#if W95_DDRAW
BOOL VXDCommand(DWORD dwCommand, void* pIn, DWORD dwInSize, void* pOut, DWORD dwOutSize); #endif
//------------------------------------------------------------------
// DirectDraw Callbacks
//------------------------------------------------------------------
DWORD CALLBACK DdCanCreateSurface( LPDDHAL_CANCREATESURFACEDATA pccsd ); DWORD CALLBACK DdCreateSurface( LPDDHAL_CREATESURFACEDATA pcsd ); DWORD CALLBACK DdDestroySurface( LPDDHAL_DESTROYSURFACEDATA psdd ); DWORD CALLBACK DdBlt( LPDDHAL_BLTDATA lpBlt ); DWORD CALLBACK UpdateOverlay32(LPDDHAL_UPDATEOVERLAYDATA puod); DWORD CALLBACK DdSetColorKey(LPDDHAL_SETCOLORKEYDATA psckd); DWORD CALLBACK DdUpdateOverlay(LPDDHAL_UPDATEOVERLAYDATA puod);
void _D3D_SU_DirectDrawLocalDestroyCallback(HashTable* pTable, void* pData, void* pExtra); void _D3D_SU_SurfaceArrayDestroyCallback(PointerArray* pArray, void* pData, void* pExtra);
void _D3D_SU_PaletteArrayDestroyCallback(PointerArray* pArray, void* pData, void* pExtra);
#if DX7_STEREO
BOOL _DD_bIsStereoMode(P3_THUNKEDDATA* pThisDisplay, DWORD dwWidth, DWORD dwHeight, DWORD dwBpp); #endif
#if WNT_DDRAW
DWORD CALLBACK DdMapMemory(PDD_MAPMEMORYDATA lpMapMemory); DWORD CALLBACK DdGetDriverInfo(LPDDHAL_GETDRIVERINFODATA lpData);
// NT specific callbacks in gdi\heap.c
DWORD CALLBACK DdFreeDriverMemory(PDD_FREEDRIVERMEMORYDATA lpFreeDriverMemory); DWORD CALLBACK DdSetExclusiveMode(PDD_SETEXCLUSIVEMODEDATA lpSetExclusiveMode); DWORD CALLBACK DdFlipToGDISurface(PDD_FLIPTOGDISURFACEDATA lpFlipToGDISurface);
#else // WNT_DDRAW
DWORD CALLBACK DdUpdateNonLocalHeap(LPDDHAL_UPDATENONLOCALHEAPDATA plhd); DWORD CALLBACK DdGetHeapAlignment(LPDDHAL_GETHEAPALIGNMENTDATA lpGhaData); DWORD CALLBACK DdGetDriverInfo(LPDDHAL_GETDRIVERINFODATA lpData);
#endif // WNT_DDRAW
DWORD CALLBACK DdGetAvailDriverMemory(LPDDHAL_GETAVAILDRIVERMEMORYDATA pgadmd);
// Overlay source update
void _DD_OV_UpdateSource(P3_THUNKEDDATA* pThisDisplay, LPDDRAWI_DDRAWSURFACE_LCL pSurf);
DWORD CALLBACK SetOverlayPosition32(LPDDHAL_SETOVERLAYPOSITIONDATA psopd); DWORD CALLBACK DdSetOverlayPosition(LPDDHAL_SETOVERLAYPOSITIONDATA psopd);
#if W95_DDRAW
DWORD CALLBACK DDGetVideoPortConnectInfo(LPDDHAL_GETVPORTCONNECTDATA pInput); DWORD CALLBACK DdCanCreateVideoPort (LPDDHAL_CANCREATEVPORTDATA pInput); DWORD CALLBACK DdCreateVideoPort (LPDDHAL_CREATEVPORTDATA pInput); DWORD CALLBACK DdFlipVideoPort (LPDDHAL_FLIPVPORTDATA pInput); DWORD CALLBACK DdGetVideoPortBandwidth (LPDDHAL_GETVPORTBANDWIDTHDATA pInput); DWORD CALLBACK DdGetVideoPortInputFormats (LPDDHAL_GETVPORTINPUTFORMATDATA pInput); DWORD CALLBACK DdGetVideoPortOutputFormats (LPDDHAL_GETVPORTOUTPUTFORMATDATA pInput); DWORD CALLBACK DdGetVideoPortField (LPDDHAL_GETVPORTFIELDDATA pInput); DWORD CALLBACK DdGetVideoPortLine (LPDDHAL_GETVPORTLINEDATA pInput); DWORD CALLBACK DdDestroyVideoPort (LPDDHAL_DESTROYVPORTDATA pInput); DWORD CALLBACK DdGetVideoPortFlipStatus (LPDDHAL_GETVPORTFLIPSTATUSDATA pInput); DWORD CALLBACK DdUpdateVideoPort (LPDDHAL_UPDATEVPORTDATA pInput); DWORD CALLBACK DdWaitForVideoPortSync (LPDDHAL_WAITFORVPORTSYNCDATA pInput); DWORD CALLBACK DdGetVideoSignalStatus(LPDDHAL_GETVPORTSIGNALDATA pInput); DWORD CALLBACK DdSyncSurfaceData(LPDDHAL_SYNCSURFACEDATA pInput); DWORD CALLBACK DdSyncVideoPortData(LPDDHAL_SYNCVIDEOPORTDATA pInput); #endif // W95_DDRAW
//------------------------------------------------------------------
// Permedia3 Blit Functions
//------------------------------------------------------------------
typedef void (P3RXEFFECTSBLT)(struct tagThunkedData*, LPDDRAWI_DDRAWSURFACE_LCL pSource, LPDDRAWI_DDRAWSURFACE_LCL pDest, P3_SURF_FORMAT* pFormatSource, P3_SURF_FORMAT* pFormatDest, LPDDHAL_BLTDATA lpBlt, RECTL *rSrc, RECTL *rDest);
VOID _DD_BLT_P3Clear( // Clearing
P3_THUNKEDDATA* pThisDisplay, RECTL *rDest, DWORD ClearValue, BOOL bDisableFastFill, BOOL bIsZBuffer, FLATPTR pDestfpVidMem, DWORD dwDestPatchMode, DWORD dwDestPixelPitch, DWORD dwDestBitDepth );
VOID _DD_BLT_P3Clear_AA( P3_THUNKEDDATA* pThisDisplay, RECTL *rDest, DWORD dwSurfaceOffset, DWORD ClearValue, BOOL bDisableFastFill, DWORD dwDestPatchMode, DWORD dwDestPixelPitch, DWORD dwDestBitDepth, DDSCAPS DestDdsCaps);
void _DD_P3Download( // Downloads (sysmem -> video)
P3_THUNKEDDATA* pThisDisplay, FLATPTR pSrcfpVidMem, FLATPTR pDestfpVidMem, DWORD dwSrcChipPatchMode, DWORD dwDestChipPatchMode, DWORD dwSrcPitch, DWORD dwDestPitch, DWORD dwDestPixelPitch, DWORD dwDestPixelSize, RECTL* rSrc, RECTL* rDest); void _DD_P3DownloadDD( P3_THUNKEDDATA* pThisDisplay, LPDDRAWI_DDRAWSURFACE_LCL pSource, LPDDRAWI_DDRAWSURFACE_LCL pDest, P3_SURF_FORMAT* pFormatSource, P3_SURF_FORMAT* pFormatDest, RECTL* rSrc, RECTL* rDest);
void _DD_P3DownloadDstCh( struct tagThunkedData*, LPDDRAWI_DDRAWSURFACE_LCL pSource, LPDDRAWI_DDRAWSURFACE_LCL pDest, P3_SURF_FORMAT* pFormatSource, P3_SURF_FORMAT* pFormatDest, LPDDHAL_BLTDATA lpBlt, RECTL* rSrc, RECTL* rDest);
VOID _DD_BLT_P3CopyBlt( // Blts
P3_THUNKEDDATA* pThisDisplay, FLATPTR pSrcfpVidMem, FLATPTR pDestfpVidMem, DWORD dwSrcChipPatchMode, DWORD dwDestChipPatchMode, DWORD dwSrcPitch, DWORD dwDestPitch, DWORD dwSrcOffset, DWORD dwDestOffset, DWORD dwDestPixelSize, RECTL *rSrc, RECTL *rDest);
VOID _DD_P3BltStretchSrcChDstCh( P3_THUNKEDDATA* pThisDisplay, FLATPTR fpSrcVidMem, P3_SURF_FORMAT* pFormatSource, DWORD dwSrcPixelSize, DWORD dwSrcWidth, DWORD dwSrcHeight, DWORD dwSrcPixelPitch, DWORD dwSrcPatchMode, ULONG ulSrcOffsetFromMemBase, DWORD dwSrcFlags, DDPIXELFORMAT* pSrcDDPF, BOOL bIsSourceAGP, FLATPTR fpDestVidMem, P3_SURF_FORMAT* pFormatDest, DWORD dwDestPixelSize, DWORD dwDestWidth, DWORD dwDestHeight, DWORD dwDestPixelPitch, DWORD dwDestPatchMode, ULONG ulDestOffsetFromMemBase, DWORD dwBltFlags, DWORD dwBltDDFX, DDCOLORKEY BltSrcColorKey, DDCOLORKEY BltDestColorKey, RECTL *rSrc, RECTL *rDest);
VOID _DD_BLT_SysMemToSysMemCopy( FLATPTR fpSrcVidMem, LONG lSrcPitch, DWORD dwSrcBitCount, FLATPTR fpDstVidMem, LONG lDstPitch, DWORD dwDstBitCount, RECTL* rSource, RECTL* rDest); // FX Blits
P3RXEFFECTSBLT _DD_P3BltStretchSrcChDstCh_DD; P3RXEFFECTSBLT _DD_P3BltStretchSrcChDstChOverlap; P3RXEFFECTSBLT _DD_P3BltSourceChroma;
void P3RX_AA_Shrink(struct _p3_d3dcontext* pContext);
BOOL _DD_BLT_FixRectlOrigin(char *pszPlace, RECTL *rSrc, RECTL *rDest);
DWORD _DD_BLT_GetBltDirection( FLATPTR pSrcfpVidMem, FLATPTR pDestfpVidMem, RECTL *rSrc, RECTL *rDest, BOOL *pbBlocking);
//------------------------------------------------------------------
// DX Utility functions.
//------------------------------------------------------------------
// Initialise 32 Bit data
BOOL _DD_InitDDHAL32Bit(struct tagThunkedData* pThisDisplay);
// Query flip status
HRESULT _DX_QueryFlipStatus( struct tagThunkedData* pThisDisplay, FLATPTR fpVidMem, BOOL bAllowDMAFlush ); // Change the mode setup
void ChangeDDHAL32Mode(struct tagThunkedData* pThisDisplay); // Checks that the current mode info is correct
#define VALIDATE_MODE_AND_STATE(pThisDisplay) \
if ((pThisDisplay->bResetMode != 0) || \ (pThisDisplay->bStartOfDay)) \ ChangeDDHAL32Mode(pThisDisplay);
//-----------------------------------------------------------------------------
//
// ****************** Mathematical definitions and macros *********************
//
//-----------------------------------------------------------------------------
#define math_e 2.718281828f
// Usefull maths stuff
extern float pow4( float x ); extern float myPow( float x, float y );
#if WNT_DDRAW
// Might be running on non-Intel processors.
static __inline void myDiv(float *result, float dividend, float divisor) { *result = dividend/divisor; } // myDiv()
#else
static __inline void myDiv(float *result, float dividend, float divisor) { __asm { fld dividend fdiv divisor mov eax,result fstp dword ptr [eax] } } // myDiv()
#endif // WNT_DDRAW
__inline void myFtoi(int *result, float f) { *result = (int)f; } //myFtoi
static __inline float myFabs(float f) { float* pFloat = &f; DWORD dwReturn = *((DWORD*)pFloat); dwReturn &= ~0x80000000; return (*((float*)&dwReturn)); } //
// Utility functions, used by NT4, NT5 and Win9X
static __inline int log2(int s) { int d = 1, iter = -1; do { d *= 2; iter++; } while (d <= s); iter += ((s << 1) != d); return iter; }
#ifdef _X86_
//-----------------------------------------------------------------------------
//
// myPow
//
// Compute x^y for arbitrary x and y
//
//-----------------------------------------------------------------------------
__inline float myPow( float x, float y ) { float res = 0.0f; int intres;
__asm { fld y // y
fld x // x y
fyl2x // y*log2(x)
fstp res }
// Remove integer part of res as f2xm1 has limited input range
myFtoi ( &intres, res ); res -= intres;
__asm { fild intres // Stash integer part for FSCALE
fld res f2xm1 // ST = 2^^fracx - 1
fld1 fadd // ST = 2^^fracx
fscale // ST = 2^^x
fstp res fstp st(0) // Clean up stack
}
return res; } // myPow
#elif defined(_AMD64_)
double pow(double, double);
__inline float myPow( float x, float y ) { return (float)pow((double)x, (double)y); }
#elif defined(_IA64_)
__inline float myPow( float x, float y ) { return powf(x,y); }
#else
#error "No Target Architecture"
#endif //_X86_
//-----------------------------------------------------------------------------
//
// pow4
//
// Compute 4^x for arbitrary x
//
//-----------------------------------------------------------------------------
__inline float pow4( float x ) { #if defined(_IA64_)
return 0.0F; #else
return myPow( 4.0F, x ); #endif
} // pow4
#endif // __DIRECTX_H
|