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.
1183 lines
44 KiB
1183 lines
44 KiB
/******************************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
|