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.
1439 lines
58 KiB
1439 lines
58 KiB
/******************************Module*Header**********************************\
|
|
*
|
|
* *******************
|
|
* * D3D SAMPLE CODE *
|
|
* *******************
|
|
*
|
|
* Module Name: d3dcntxt.c
|
|
*
|
|
* Content: Main context callbacks for D3D
|
|
*
|
|
* Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
|
|
* Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved.
|
|
\*****************************************************************************/
|
|
|
|
#include "glint.h"
|
|
#if W95_DDRAW
|
|
#include <dmemmgr.h>
|
|
#endif
|
|
#include "dma.h"
|
|
#include "tag.h"
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// ****************************************************************************
|
|
// *********************** D3D Context handle management **********************
|
|
// ****************************************************************************
|
|
//-----------------------------------------------------------------------------
|
|
// Here we abstract the managment of context structures. If you wish to modify
|
|
// the way these are managed, this is the place to perform the modification
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Maximum simultaneous number of contexts we can keep track of
|
|
#define MAX_CONTEXT_NUM 200
|
|
|
|
// Since these variables are global they are forced
|
|
// into shared data segment by the build.
|
|
P3_D3DCONTEXT* g_D3DContextSlots[MAX_CONTEXT_NUM] = {NULL};
|
|
BOOL g_D3DInitialised = FALSE;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// _D3D_CTX_HandleInitialization
|
|
//
|
|
// Initialize the handle data structures (array) . Be careful not to initialize
|
|
// it twice (between mode changes for example) as this info has to be persistent
|
|
//-----------------------------------------------------------------------------
|
|
VOID _D3D_CTX_HandleInitialization(VOID)
|
|
{
|
|
DWORD i;
|
|
|
|
// Do only the first time the driver is loaded.
|
|
if (g_D3DInitialised == FALSE)
|
|
{
|
|
// Clear the contexts. Since this is done only once, lets do it right,
|
|
// rather than just clearing with a memset(g_D3DContextSlots,0,size);
|
|
for (i = 0; i < MAX_CONTEXT_NUM; i++)
|
|
{
|
|
g_D3DContextSlots[i] = NULL;
|
|
}
|
|
|
|
// This will assure we only initialize the data once
|
|
g_D3DInitialised = TRUE;
|
|
}
|
|
} // _D3D_CTX_HandleInitialization
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// __CTX_NewHandle
|
|
//
|
|
// Returns a valid context handle number to use in all D3D callbacks and ready
|
|
// to be associated with a P3_D3DCONTEXT structure
|
|
//-----------------------------------------------------------------------------
|
|
DWORD __CTX_NewHandle(VOID)
|
|
{
|
|
DWORD dwSlotNum;
|
|
|
|
// Find an empty slot.
|
|
for (dwSlotNum = 1; dwSlotNum < MAX_CONTEXT_NUM; dwSlotNum++)
|
|
{
|
|
if (g_D3DContextSlots[dwSlotNum] == NULL)
|
|
{
|
|
return dwSlotNum;
|
|
}
|
|
}
|
|
|
|
DISPDBG((WRNLVL,"WARN:No empty context slots left"));
|
|
return 0; // no empty slots left, check for this return value!
|
|
} // __CTX_NewHandle
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// __CTX_AssocPtrToHandle
|
|
//
|
|
// Associate a pointer (to a P3_D3DCONTEXT) with this context handle
|
|
//-----------------------------------------------------------------------------
|
|
VOID __CTX_AssocPtrToHandle(DWORD hHandle,P3_D3DCONTEXT* pContext)
|
|
{
|
|
ASSERTDD(hHandle < MAX_CONTEXT_NUM,
|
|
"Accessing g_D3DContextSlots out of bounds");
|
|
|
|
g_D3DContextSlots[hHandle] = pContext;
|
|
} // __CTX_AssocPtrToHandle
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// _D3D_CTX_HandleToPtr
|
|
//
|
|
// Returns the pointer associated to this context handle
|
|
//-----------------------------------------------------------------------------
|
|
P3_D3DCONTEXT*
|
|
_D3D_CTX_HandleToPtr(ULONG_PTR hHandle)
|
|
{
|
|
return g_D3DContextSlots[(DWORD)(hHandle)];
|
|
} // _D3D_CTX_HandleToPtr
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// __CTX_HandleRelease
|
|
//
|
|
// This marks the handle number as "free" so it can be reused again when
|
|
// a new D3D context is created
|
|
//-----------------------------------------------------------------------------
|
|
VOID __CTX_HandleRelease(DWORD hHandle)
|
|
{
|
|
ASSERTDD(hHandle < MAX_CONTEXT_NUM,
|
|
"Accessing g_D3DContextSlots out of bounds");
|
|
|
|
g_D3DContextSlots[hHandle] = NULL;
|
|
} // __CTX_HandleRelease
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// ****************************************************************************
|
|
// ***********Hardware specific context and state initial setup ***************
|
|
// ****************************************************************************
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// __CTX_CleanDirect3DContext
|
|
//
|
|
// After it has been decided that a context is indeed still active
|
|
// and is being freed, this function walks along cleaning everything
|
|
// up. Note it can be called either as a result of a D3DContextDestroy,
|
|
// or as a result of the app exiting without freeing the context, or
|
|
// as the result of an error whilst creating the context.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
VOID
|
|
__CTX_CleanDirect3DContext(
|
|
P3_D3DCONTEXT* pContext)
|
|
{
|
|
P3_THUNKEDDATA *pThisDisplay = pContext->pThisDisplay;
|
|
|
|
#if DX8_MULTISAMPLING || DX7_ANTIALIAS
|
|
// Free any antialiasing buffer we might have left around in vidmem
|
|
if (pContext->dwAliasBackBuffer != 0)
|
|
{
|
|
_DX_LIN_FreeLinearMemory(&pThisDisplay->LocalVideoHeap0Info,
|
|
pContext->dwAliasBackBuffer);
|
|
pContext->dwAliasBackBuffer = 0;
|
|
pContext->dwAliasPixelOffset = 0;
|
|
}
|
|
|
|
if (pContext->dwAliasZBuffer != 0)
|
|
{
|
|
_DX_LIN_FreeLinearMemory(&pThisDisplay->LocalVideoHeap0Info,
|
|
pContext->dwAliasZBuffer);
|
|
pContext->dwAliasZBuffer = 0;
|
|
pContext->dwAliasZPixelOffset = 0;
|
|
}
|
|
#endif // DX8_MULTISAMPLING || DX7_ANTIALIAS
|
|
|
|
//@@BEGIN_DDKSPLIT
|
|
#if DX7_VIDMEM_VB
|
|
// Free up the useful DrawPrim buffers.
|
|
// Yes, these are device-global rather than per-context, but that's fine
|
|
// since whenever they are used, a macro checks to see if they are big
|
|
// enough and if not re-allocates them. The data does not need to
|
|
// survive across calls.
|
|
// I'm doing the free here instead of end-of-driver-day because there
|
|
// is no elegant place to do it then.
|
|
if ( (void *)pThisDisplay->DrawPrimIndexBufferMem != NULL )
|
|
{
|
|
ASSERTDD ( pThisDisplay->DrawPrimIndexBufferMemSize > 0,
|
|
"** D3DContextDestroy - DrawPrimIndexBufferMemSize "
|
|
"negative or zero, but memory pointer not NULL" );
|
|
HEAP_FREE ( (void *)pThisDisplay->DrawPrimIndexBufferMem );
|
|
pThisDisplay->DrawPrimIndexBufferMem = (ULONG_PTR)NULL;
|
|
pThisDisplay->DrawPrimIndexBufferMemSize = 0;
|
|
}
|
|
else
|
|
{
|
|
ASSERTDD ( pThisDisplay->DrawPrimIndexBufferMemSize == 0,
|
|
"** D3DContextDestroy - DrawPrimIndexBufferMemSize "
|
|
"not zero, but memory pointer is NULL" );
|
|
pThisDisplay->DrawPrimIndexBufferMemSize = 0;
|
|
}
|
|
|
|
if ( (void *)pThisDisplay->DrawPrimVertexBufferMem != NULL )
|
|
{
|
|
ASSERTDD ( pThisDisplay->DrawPrimVertexBufferMemSize > 0,
|
|
"** D3DContextDestroy - DrawPrimVertexBufferMemSize "
|
|
"negative or zero, but memory pointer not NULL" );
|
|
HEAP_FREE ( (void *)pThisDisplay->DrawPrimVertexBufferMem );
|
|
pThisDisplay->DrawPrimVertexBufferMem = (ULONG_PTR)NULL;
|
|
pThisDisplay->DrawPrimVertexBufferMemSize = 0;
|
|
}
|
|
else
|
|
{
|
|
ASSERTDD ( pThisDisplay->DrawPrimVertexBufferMemSize == 0,
|
|
"** D3DContextDestroy - DrawPrimVertexBufferMemSize "
|
|
"not zero, but memory pointer is NULL" );
|
|
pThisDisplay->DrawPrimVertexBufferMemSize = 0;
|
|
}
|
|
#endif DX7_VIDMEM_VB
|
|
//@@END_DDKSPLIT
|
|
|
|
#if DX7_D3DSTATEBLOCKS
|
|
// Free up any remaining state sets
|
|
_D3D_SB_DeleteAllStateSets(pContext);
|
|
#endif //DX7_D3DSTATEBLOCKS
|
|
|
|
#if DX7_PALETTETEXTURE
|
|
// Destroy the per context palette pointer array
|
|
if (pContext->pPalettePointerArray)
|
|
{
|
|
PA_DestroyArray(pContext->pPalettePointerArray, NULL);
|
|
}
|
|
#endif
|
|
|
|
} // __CTX_CleanDirect3DContext()
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// __CTX_Perm3_DisableUnits
|
|
//
|
|
// Disables all the mode registers to give us a clean start.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
static VOID
|
|
__CTX_Perm3_DisableUnits(
|
|
P3_D3DCONTEXT* pContext)
|
|
{
|
|
P3_THUNKEDDATA *pThisDisplay = pContext->pThisDisplay;
|
|
P3_DMA_DEFS();
|
|
|
|
P3_DMA_GET_BUFFER();
|
|
|
|
P3_ENSURE_DX_SPACE(128);
|
|
|
|
WAIT_FIFO(32);
|
|
SEND_P3_DATA(RasterizerMode, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(AreaStippleMode, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(LineStippleMode, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(ScissorMode, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(DepthMode, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(ColorDDAMode, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(FogMode, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(AntialiasMode, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(AlphaTestMode, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(LBReadMode, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(Window, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(StencilMode, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(LBWriteMode, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(FBReadMode, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(PatternRAMMode, __PERMEDIA_DISABLE);
|
|
|
|
WAIT_FIFO(18);
|
|
SEND_P3_DATA(DitherMode, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(AlphaBlendMode, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(LogicalOpMode, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(FBWriteMode, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(StatisticMode, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(PixelSize, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(FBSourceData, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(LBWriteFormat, __PERMEDIA_DISABLE);
|
|
|
|
WAIT_FIFO(32);
|
|
|
|
|
|
SEND_P3_DATA(TextureReadMode, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(TextureCoordMode, __PERMEDIA_DISABLE);
|
|
|
|
SEND_P3_DATA(ChromaTestMode, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(FilterMode, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(LUTTransfer, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(LUTIndex, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(LUTAddress, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(LUTMode, __PERMEDIA_DISABLE);
|
|
|
|
if (TLCHIP_GAMMA)
|
|
{
|
|
WAIT_FIFO(32);
|
|
SEND_P3_DATA(Light0Mode, 0);
|
|
SEND_P3_DATA(Light1Mode, 0);
|
|
SEND_P3_DATA(Light2Mode, 0);
|
|
SEND_P3_DATA(Light3Mode, 0);
|
|
SEND_P3_DATA(Light4Mode, 0);
|
|
SEND_P3_DATA(Light5Mode, 0);
|
|
SEND_P3_DATA(Light6Mode, 0);
|
|
SEND_P3_DATA(Light7Mode, 0);
|
|
SEND_P3_DATA(Light8Mode, 0);
|
|
SEND_P3_DATA(Light9Mode, 0);
|
|
SEND_P3_DATA(Light10Mode, 0);
|
|
SEND_P3_DATA(Light11Mode, 0);
|
|
SEND_P3_DATA(Light12Mode, 0);
|
|
SEND_P3_DATA(Light13Mode, 0);
|
|
SEND_P3_DATA(Light14Mode, 0);
|
|
SEND_P3_DATA(Light15Mode, 0);
|
|
|
|
WAIT_FIFO(32);
|
|
SEND_P3_DATA(TransformMode, 0);
|
|
SEND_P3_DATA(MaterialMode, 0);
|
|
SEND_P3_DATA(GeometryMode, 0);
|
|
SEND_P3_DATA(LightingMode, 0);
|
|
SEND_P3_DATA(ColorMaterialMode, 0);
|
|
SEND_P3_DATA(NormaliseMode, 0);
|
|
SEND_P3_DATA(LineMode, 0);
|
|
SEND_P3_DATA(TriangleMode, 0);
|
|
}
|
|
|
|
P3_DMA_COMMIT_BUFFER();
|
|
} // __CTX_Perm3_DisableUnits
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// __CTX_Perm3_SetupD3D_HWDefaults
|
|
//
|
|
// Sets up the initial value of registers for this D3D context. This is done
|
|
// within the current chip context (D3D_OPERATION) so that when we return to
|
|
// it from DD or GDI we get the correct register values restored
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void
|
|
__CTX_Perm3_SetupD3D_HWDefaults(
|
|
P3_D3DCONTEXT* pContext)
|
|
{
|
|
P3_SOFTWARECOPY* pSoftP3RX = &pContext->SoftCopyGlint;
|
|
P3_THUNKEDDATA *pThisDisplay = pContext->pThisDisplay;
|
|
|
|
P3_DMA_DEFS();
|
|
|
|
// Make sure we our working within the right chip-regs context
|
|
D3D_OPERATION(pContext, pThisDisplay);
|
|
|
|
// Initially turn off all hardware units.
|
|
// We will turn on back whatever units are needed.
|
|
__CTX_Perm3_DisableUnits(pContext);
|
|
|
|
// Set up VertexControl register in HostIn unit.
|
|
pSoftP3RX->P3RX_P3VertexControl.Size = 1;
|
|
pSoftP3RX->P3RX_P3VertexControl.Flat = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RX_P3VertexControl.ReadAll = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RX_P3VertexControl.SkipFlags = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RX_P3VertexControl.CacheEnable = __PERMEDIA_ENABLE;
|
|
pSoftP3RX->P3RX_P3VertexControl.OGL = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RX_P3VertexControl.Line2D = __PERMEDIA_DISABLE;
|
|
|
|
// Constant LBReadMode setup
|
|
pSoftP3RX->LBReadMode.WindowOrigin = __GLINT_TOP_LEFT_WINDOW_ORIGIN; // Top left
|
|
pSoftP3RX->LBReadMode.DataType = __GLINT_LBDEFAULT; // default
|
|
pSoftP3RX->LBReadMode.ReadSourceEnable = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->LBReadMode.ReadDestinationEnable = __PERMEDIA_DISABLE;
|
|
|
|
// Constant DitherMode setup
|
|
pSoftP3RX->DitherMode.ColorOrder = COLOR_MODE;
|
|
pSoftP3RX->DitherMode.XOffset = DITHER_XOFFSET;
|
|
pSoftP3RX->DitherMode.YOffset = DITHER_YOFFSET;
|
|
pSoftP3RX->DitherMode.UnitEnable = __PERMEDIA_ENABLE;
|
|
|
|
// Alpha Blend Mode Setup
|
|
pSoftP3RX->P3RXAlphaBlendColorMode.Enable = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXAlphaBlendColorMode.SourceBlend = 0;
|
|
pSoftP3RX->P3RXAlphaBlendColorMode.DestBlend = 0;
|
|
pSoftP3RX->P3RXAlphaBlendColorMode.SourceTimesTwo = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXAlphaBlendColorMode.DestTimesTwo = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXAlphaBlendColorMode.InvertSource = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXAlphaBlendColorMode.InvertDest = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXAlphaBlendColorMode.ColorFormat = P3RX_ALPHABLENDMODE_COLORFORMAT_8888;
|
|
pSoftP3RX->P3RXAlphaBlendColorMode.ColorOrder = COLOR_MODE;
|
|
pSoftP3RX->P3RXAlphaBlendColorMode.ColorConversion = P3RX_ALPHABLENDMODE_CONVERT_SHIFT;
|
|
pSoftP3RX->P3RXAlphaBlendColorMode.ConstantSource = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXAlphaBlendColorMode.ConstantDest = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXAlphaBlendColorMode.Operation = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXAlphaBlendColorMode.SwapSD = __PERMEDIA_DISABLE;
|
|
|
|
pSoftP3RX->P3RXAlphaBlendAlphaMode.Enable = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXAlphaBlendAlphaMode.SourceBlend = 0;
|
|
pSoftP3RX->P3RXAlphaBlendAlphaMode.DestBlend = 0;
|
|
pSoftP3RX->P3RXAlphaBlendAlphaMode.SourceTimesTwo = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXAlphaBlendAlphaMode.DestTimesTwo = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXAlphaBlendAlphaMode.InvertSource = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXAlphaBlendAlphaMode.InvertDest = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXAlphaBlendAlphaMode.NoAlphaBuffer = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXAlphaBlendAlphaMode.AlphaType = 0; // Use GL Blend modes
|
|
pSoftP3RX->P3RXAlphaBlendAlphaMode.AlphaConversion = P3RX_ALPHABLENDMODE_CONVERT_SCALE;
|
|
pSoftP3RX->P3RXAlphaBlendAlphaMode.ConstantSource = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXAlphaBlendAlphaMode.ConstantDest = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXAlphaBlendAlphaMode.Operation = __PERMEDIA_DISABLE;
|
|
DIRTY_ALPHABLEND(pContext);
|
|
|
|
// Local Buffer Read format bits that don't change
|
|
pSoftP3RX->P3RXLBReadFormat.GIDPosition = 0;
|
|
pSoftP3RX->P3RXLBReadFormat.GIDWidth = 0; // No GID
|
|
pSoftP3RX->P3RXLBReadFormat.StencilPosition = 0;
|
|
pSoftP3RX->P3RXLBReadFormat.StencilWidth = 0; // No Stencil
|
|
|
|
pSoftP3RX->P3RXLBWriteFormat.GIDPosition = 0;
|
|
pSoftP3RX->P3RXLBWriteFormat.GIDWidth = 0; // No GID
|
|
pSoftP3RX->P3RXLBWriteFormat.StencilPosition = 0;
|
|
pSoftP3RX->P3RXLBWriteFormat.StencilWidth = 0; // No Stencil
|
|
|
|
// Never do a source read operation
|
|
pSoftP3RX->P3RXLBSourceReadMode.Enable = 0;
|
|
pSoftP3RX->P3RXLBSourceReadMode.Origin = 0;
|
|
pSoftP3RX->P3RXLBSourceReadMode.StripeHeight = 0;
|
|
pSoftP3RX->P3RXLBSourceReadMode.StripePitch = 0;
|
|
pSoftP3RX->P3RXLBSourceReadMode.PrefetchEnable = 0;
|
|
|
|
// Default is to read the Z Buffer
|
|
pSoftP3RX->P3RXLBDestReadMode.Enable = 1;
|
|
pSoftP3RX->P3RXLBDestReadMode.Origin = 0;
|
|
pSoftP3RX->P3RXLBDestReadMode.StripeHeight = 0;
|
|
pSoftP3RX->P3RXLBDestReadMode.StripePitch = 0;
|
|
pSoftP3RX->P3RXLBDestReadMode.PrefetchEnable = 0;
|
|
|
|
// Local Buffer Write mode
|
|
pSoftP3RX->P3RXLBWriteMode.WriteEnable = __PERMEDIA_ENABLE; // Initially allow LB Writes
|
|
pSoftP3RX->P3RXLBWriteMode.StripeHeight = 0;
|
|
pSoftP3RX->P3RXLBWriteMode.StripePitch = 0;
|
|
pSoftP3RX->P3RXLBWriteMode.Origin = __GLINT_TOP_LEFT_WINDOW_ORIGIN;
|
|
pSoftP3RX->P3RXLBWriteMode.Operation = __PERMEDIA_DISABLE;
|
|
|
|
// Frame Buffer WriteMode
|
|
pSoftP3RX->P3RXFBWriteMode.WriteEnable = __PERMEDIA_ENABLE;
|
|
pSoftP3RX->P3RXFBWriteMode.Replicate = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXFBWriteMode.OpaqueSpan = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXFBWriteMode.StripePitch = P3RX_STRIPE_1;
|
|
pSoftP3RX->P3RXFBWriteMode.StripeHeight = P3RX_STRIPE_1;
|
|
pSoftP3RX->P3RXFBWriteMode.Enable0 = __PERMEDIA_ENABLE;
|
|
|
|
// FB Destination reads
|
|
pSoftP3RX->P3RXFBDestReadMode.ReadEnable = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXFBDestReadMode.Enable0 = __PERMEDIA_ENABLE;
|
|
|
|
// FB Source reads
|
|
pSoftP3RX->P3RXFBSourceReadMode.ReadEnable = __PERMEDIA_DISABLE;
|
|
|
|
// Depth comparisons
|
|
pSoftP3RX->P3RXDepthMode.WriteMask = __PERMEDIA_ENABLE;
|
|
pSoftP3RX->P3RXDepthMode.CompareMode = __GLINT_DEPTH_COMPARE_MODE_ALWAYS;
|
|
pSoftP3RX->P3RXDepthMode.NewDepthSource = __GLINT_DEPTH_SOURCE_DDA;
|
|
pSoftP3RX->P3RXDepthMode.Enable = __PERMEDIA_DISABLE;
|
|
|
|
#define NLZ 0
|
|
#if NLZ
|
|
pSoftP3RX->P3RXDepthMode.Normalise = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXDepthMode.NonLinearZ = __PERMEDIA_ENABLE;
|
|
#else
|
|
pSoftP3RX->P3RXDepthMode.Normalise = __PERMEDIA_ENABLE;
|
|
pSoftP3RX->P3RXDepthMode.NonLinearZ = __PERMEDIA_DISABLE;
|
|
#endif
|
|
pSoftP3RX->P3RXDepthMode.ExponentScale = 2;
|
|
pSoftP3RX->P3RXDepthMode.ExponentWidth = 1;
|
|
|
|
// Only setup to write to the chip after the above call, as
|
|
// we may upset the DMA buffer setup.
|
|
P3_DMA_GET_BUFFER_ENTRIES(20);
|
|
|
|
// Window Region data
|
|
SEND_P3_DATA(FBSourceOffset, 0x0);
|
|
|
|
// Write Masks
|
|
SEND_P3_DATA(FBSoftwareWriteMask, __GLINT_ALL_WRITEMASKS_SET);
|
|
SEND_P3_DATA(FBHardwareWriteMask, __GLINT_ALL_WRITEMASKS_SET);
|
|
|
|
// Host out unit
|
|
SEND_P3_DATA(FilterMode, __PERMEDIA_DISABLE);
|
|
SEND_P3_DATA(StatisticMode, __PERMEDIA_DISABLE); // Disable Stats
|
|
|
|
// Local Buffer
|
|
SEND_P3_DATA(LBSourceOffset, 0);
|
|
|
|
// Window setups
|
|
SEND_P3_DATA(WindowOrigin, __GLINT_TOP_LEFT_WINDOW_ORIGIN);
|
|
SEND_P3_DATA(FBWindowBase, 0x0);
|
|
|
|
SEND_P3_DATA(RasterizerMode, 0);
|
|
|
|
// Setup a step of -1, as this doesn't change very much
|
|
SEND_P3_DATA(dY, 0xFFFF0000);
|
|
|
|
P3_DMA_COMMIT_BUFFER();
|
|
|
|
P3_DMA_GET_BUFFER_ENTRIES(16);
|
|
|
|
// Stencil mode setup
|
|
pSoftP3RX->P3RXStencilMode.StencilWidth = 0;
|
|
pSoftP3RX->P3RXStencilMode.DPFail = __GLINT_STENCIL_METHOD_KEEP;
|
|
pSoftP3RX->P3RXStencilMode.DPPass = __GLINT_STENCIL_METHOD_KEEP;
|
|
pSoftP3RX->P3RXStencilMode.Enable = __PERMEDIA_DISABLE;
|
|
COPY_P3_DATA(StencilMode, pSoftP3RX->P3RXStencilMode);
|
|
|
|
pSoftP3RX->P3RXFogMode.Enable = __PERMEDIA_ENABLE; // Qualified by the render command
|
|
pSoftP3RX->P3RXFogMode.ColorMode = P3RX_FOGMODE_COLORMODE_RGB; // RGBA
|
|
pSoftP3RX->P3RXFogMode.Table = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXFogMode.UseZ = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXFogMode.ZShift = 23; // Take the top 8 bits of the z value
|
|
pSoftP3RX->P3RXFogMode.InvertFI = __PERMEDIA_DISABLE;
|
|
DIRTY_FOG(pContext);
|
|
|
|
pSoftP3RX->P3RXWindow.Enable = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXWindow.CompareMode = 0;
|
|
pSoftP3RX->P3RXWindow.ForceLBUpdate = 0;
|
|
pSoftP3RX->P3RXWindow.LBUpdateSource = 0;
|
|
pSoftP3RX->P3RXWindow.GID = 0;
|
|
pSoftP3RX->P3RXWindow.FrameCount = 0;
|
|
pSoftP3RX->P3RXWindow.StencilFCP = 0;
|
|
pSoftP3RX->P3RXWindow.DepthFCP = 0;
|
|
COPY_P3_DATA(Window, pSoftP3RX->P3RXWindow);
|
|
|
|
SEND_P3_DATA(ChromaUpper, 0x00000000);
|
|
SEND_P3_DATA(ChromaLower, 0x00000000);
|
|
|
|
// Use a black border for the bilinear filter.
|
|
// This will only work for certain types of texture...
|
|
SEND_P3_DATA(BorderColor0, 0x0);
|
|
SEND_P3_DATA(BorderColor1, 0x0);
|
|
|
|
// Alpha Test - later we'll DIRTY_EVERYTHING
|
|
pSoftP3RX->P3RXAlphaTestMode.Enable = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXAlphaTestMode.Reference = 0x0;
|
|
pSoftP3RX->P3RXAlphaTestMode.Compare = __GLINT_ALPHA_COMPARE_MODE_ALWAYS;
|
|
|
|
SEND_P3_DATA(AreaStippleMode, (1 | (2 << 1) | (2 << 4)));
|
|
|
|
pSoftP3RX->P3RX_P3DeltaMode.TargetChip = __PERMEDIA_ENABLE;
|
|
pSoftP3RX->P3RX_P3DeltaMode.SpecularTextureEnable = __PERMEDIA_ENABLE;
|
|
pSoftP3RX->P3RX_P3DeltaMode.TextureParameterMode = 2; // Normalise
|
|
pSoftP3RX->P3RX_P3DeltaMode.TextureEnable = __PERMEDIA_ENABLE;
|
|
pSoftP3RX->P3RX_P3DeltaMode.DiffuseTextureEnable = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RX_P3DeltaMode.SmoothShadingEnable = __PERMEDIA_ENABLE;
|
|
pSoftP3RX->P3RX_P3DeltaMode.SubPixelCorrectionEnable = __PERMEDIA_ENABLE;
|
|
pSoftP3RX->P3RX_P3DeltaMode.DiamondExit = __PERMEDIA_ENABLE;
|
|
|
|
#if 1
|
|
pSoftP3RX->P3RX_P3DeltaMode.NoDraw = __PERMEDIA_DISABLE;
|
|
#else
|
|
pSoftP3RX->P3RX_P3DeltaMode.NoDraw = __PERMEDIA_ENABLE;
|
|
#endif
|
|
|
|
pSoftP3RX->P3RX_P3DeltaMode.ClampEnable = __PERMEDIA_ENABLE;
|
|
pSoftP3RX->P3RX_P3DeltaMode.FillDirection = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RX_P3DeltaMode.DepthFormat = 3; // Always 32 bits
|
|
pSoftP3RX->P3RX_P3DeltaMode.ColorOrder = COLOR_MODE;
|
|
pSoftP3RX->P3RX_P3DeltaMode.BiasCoordinates = __PERMEDIA_ENABLE;
|
|
pSoftP3RX->P3RX_P3DeltaMode.Texture3DEnable = __PERMEDIA_DISABLE; // Always perspective correct (q is 1 otherwise)
|
|
pSoftP3RX->P3RX_P3DeltaMode.TextureEnable1 = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RX_P3DeltaMode.DepthEnable = __PERMEDIA_ENABLE;
|
|
COPY_P3_DATA(DeltaMode, pSoftP3RX->P3RX_P3DeltaMode);
|
|
|
|
P3_DMA_COMMIT_BUFFER();
|
|
|
|
P3_DMA_GET_BUFFER_ENTRIES(18);
|
|
|
|
{
|
|
float ZBias;
|
|
|
|
pContext->XBias = 0.5f;
|
|
pContext->YBias = 0.5f;
|
|
|
|
ZBias = 0.0f;
|
|
SEND_P3_DATA(XBias, *(DWORD*)&pContext->XBias);
|
|
SEND_P3_DATA(YBias, *(DWORD*)&pContext->YBias);
|
|
SEND_P3_DATA(ZBias, *(DWORD*)&ZBias);
|
|
}
|
|
|
|
pSoftP3RX->P3RX_P3DeltaControl.FullScreenAA = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RX_P3DeltaControl.DrawLineEndPoint = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RX_P3DeltaControl.UseProvokingVertex = __PERMEDIA_DISABLE;
|
|
COPY_P3_DATA(DeltaControl, pSoftP3RX->P3RX_P3DeltaControl);
|
|
|
|
pSoftP3RX->P3RXTextureCoordMode.Enable = __PERMEDIA_ENABLE;
|
|
pSoftP3RX->P3RXTextureCoordMode.WrapS = __GLINT_TEXADDRESS_WRAP_REPEAT;
|
|
pSoftP3RX->P3RXTextureCoordMode.WrapT = __GLINT_TEXADDRESS_WRAP_REPEAT;
|
|
pSoftP3RX->P3RXTextureCoordMode.Operation = __GLINT_TEXADDRESS_OPERATION_3D; // Perspective correct
|
|
pSoftP3RX->P3RXTextureCoordMode.InhibitDDAInitialisation = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureCoordMode.EnableLOD = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureCoordMode.EnableDY = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureCoordMode.TextureMapType = __GLINT_TEXADDRESS_TEXMAP_2D; // Always 2D
|
|
pSoftP3RX->P3RXTextureCoordMode.DuplicateCoord = __PERMEDIA_DISABLE;
|
|
COPY_P3_DATA(TextureCoordMode, pSoftP3RX->P3RXTextureCoordMode);
|
|
|
|
pSoftP3RX->P3RXTextureReadMode0.Enable = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureReadMode0.Width = log2(256);
|
|
pSoftP3RX->P3RXTextureReadMode0.Height = log2(256);
|
|
pSoftP3RX->P3RXTextureReadMode0.TexelSize = P3RX_TEXREADMODE_TEXELSIZE_16; // Pixel depth
|
|
pSoftP3RX->P3RXTextureReadMode0.Texture3D = __PERMEDIA_DISABLE; // 3D Texture coordinates
|
|
pSoftP3RX->P3RXTextureReadMode0.CombineCaches = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureReadMode0.MapBaseLevel = 0;
|
|
pSoftP3RX->P3RXTextureReadMode0.MapMaxLevel = 0;
|
|
pSoftP3RX->P3RXTextureReadMode0.LogicalTexture = 0;
|
|
pSoftP3RX->P3RXTextureReadMode0.Origin = __GLINT_TOP_LEFT_WINDOW_ORIGIN;
|
|
pSoftP3RX->P3RXTextureReadMode0.TextureType = P3RX_TEXREADMODE_TEXTURETYPE_NORMAL;
|
|
pSoftP3RX->P3RXTextureReadMode0.ByteSwap = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureReadMode0.Mirror = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureReadMode0.Invert = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureReadMode0.OpaqueSpan = __PERMEDIA_DISABLE;
|
|
COPY_P3_DATA(TextureReadMode0, pSoftP3RX->P3RXTextureReadMode0);
|
|
|
|
pSoftP3RX->P3RXTextureReadMode1.Enable = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureReadMode1.Width = log2(256);
|
|
pSoftP3RX->P3RXTextureReadMode1.Height = log2(256);
|
|
pSoftP3RX->P3RXTextureReadMode1.TexelSize = P3RX_TEXREADMODE_TEXELSIZE_16; // Pixel depth
|
|
pSoftP3RX->P3RXTextureReadMode1.Texture3D = __PERMEDIA_DISABLE; // 3D Texture coordinates
|
|
pSoftP3RX->P3RXTextureReadMode1.CombineCaches = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureReadMode1.MapBaseLevel = 0;
|
|
pSoftP3RX->P3RXTextureReadMode1.MapMaxLevel = 0;
|
|
pSoftP3RX->P3RXTextureReadMode1.LogicalTexture = 0;
|
|
pSoftP3RX->P3RXTextureReadMode1.Origin = __GLINT_TOP_LEFT_WINDOW_ORIGIN;
|
|
pSoftP3RX->P3RXTextureReadMode1.TextureType = P3RX_TEXREADMODE_TEXTURETYPE_NORMAL;
|
|
pSoftP3RX->P3RXTextureReadMode1.ByteSwap = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureReadMode1.Mirror = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureReadMode1.Invert = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureReadMode1.OpaqueSpan = __PERMEDIA_DISABLE;
|
|
COPY_P3_DATA(TextureReadMode1, pSoftP3RX->P3RXTextureReadMode1);
|
|
|
|
pSoftP3RX->P3RXTextureIndexMode0.Enable = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureIndexMode0.Width = log2(256);
|
|
pSoftP3RX->P3RXTextureIndexMode0.Height = log2(256);
|
|
pSoftP3RX->P3RXTextureIndexMode0.Border = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureIndexMode0.WrapU = P3RX_TEXINDEXMODE_WRAP_CLAMPEDGE;
|
|
pSoftP3RX->P3RXTextureIndexMode0.WrapV = P3RX_TEXINDEXMODE_WRAP_CLAMPEDGE;
|
|
pSoftP3RX->P3RXTextureIndexMode0.MapType = __GLINT_TEXADDRESS_TEXMAP_2D;
|
|
pSoftP3RX->P3RXTextureIndexMode0.MagnificationFilter = __GLINT_TEXTUREREAD_FILTER_NEAREST;
|
|
pSoftP3RX->P3RXTextureIndexMode0.MinificationFilter = __GLINT_TEXTUREREAD_FILTER_NEAREST;
|
|
pSoftP3RX->P3RXTextureIndexMode0.Texture3DEnable = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureIndexMode0.MipMapEnable = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureIndexMode0.NearestBias = 1;
|
|
pSoftP3RX->P3RXTextureIndexMode0.LinearBias = 0;
|
|
pSoftP3RX->P3RXTextureIndexMode0.SourceTexelEnable = __PERMEDIA_DISABLE;
|
|
COPY_P3_DATA(TextureIndexMode0, pSoftP3RX->P3RXTextureIndexMode0);
|
|
|
|
pSoftP3RX->P3RXTextureIndexMode1.Enable = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureIndexMode1.Width = log2(256);
|
|
pSoftP3RX->P3RXTextureIndexMode1.Height = log2(256);
|
|
pSoftP3RX->P3RXTextureIndexMode1.Border = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureIndexMode1.WrapU = P3RX_TEXINDEXMODE_WRAP_CLAMPEDGE;
|
|
pSoftP3RX->P3RXTextureIndexMode1.WrapV = P3RX_TEXINDEXMODE_WRAP_CLAMPEDGE;
|
|
pSoftP3RX->P3RXTextureIndexMode1.MapType = __GLINT_TEXADDRESS_TEXMAP_2D;
|
|
pSoftP3RX->P3RXTextureIndexMode1.MagnificationFilter = __GLINT_TEXTUREREAD_FILTER_NEAREST;
|
|
pSoftP3RX->P3RXTextureIndexMode1.MinificationFilter = __GLINT_TEXTUREREAD_FILTER_NEAREST;
|
|
pSoftP3RX->P3RXTextureIndexMode1.Texture3DEnable = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureIndexMode1.MipMapEnable = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureIndexMode1.NearestBias = 1;
|
|
pSoftP3RX->P3RXTextureIndexMode1.LinearBias = 0;
|
|
pSoftP3RX->P3RXTextureIndexMode1.SourceTexelEnable = __PERMEDIA_DISABLE;
|
|
COPY_P3_DATA(TextureIndexMode1, pSoftP3RX->P3RXTextureIndexMode1);
|
|
|
|
pSoftP3RX->P3RXTextureCompositeColorMode0.Enable = 0;
|
|
pSoftP3RX->P3RXTextureCompositeColorMode0.Scale = 1;
|
|
|
|
pSoftP3RX->P3RXTextureCompositeColorMode1.Enable = 0;
|
|
pSoftP3RX->P3RXTextureCompositeColorMode1.Scale = 1;
|
|
|
|
pSoftP3RX->P3RXTextureCompositeAlphaMode0.Enable = 0;
|
|
pSoftP3RX->P3RXTextureCompositeAlphaMode0.Scale = 1;
|
|
|
|
pSoftP3RX->P3RXTextureCompositeAlphaMode1.Enable = 0;
|
|
pSoftP3RX->P3RXTextureCompositeAlphaMode1.Scale = 1;
|
|
|
|
P3_DMA_COMMIT_BUFFER();
|
|
|
|
P3_DMA_GET_BUFFER_ENTRIES(16);
|
|
|
|
COPY_P3_DATA(TextureCompositeColorMode0, pSoftP3RX->P3RXTextureCompositeColorMode0);
|
|
COPY_P3_DATA(TextureCompositeColorMode1, pSoftP3RX->P3RXTextureCompositeColorMode1);
|
|
COPY_P3_DATA(TextureCompositeAlphaMode0, pSoftP3RX->P3RXTextureCompositeAlphaMode0);
|
|
COPY_P3_DATA(TextureCompositeAlphaMode1, pSoftP3RX->P3RXTextureCompositeAlphaMode1);
|
|
|
|
// Set up the TC TFACTOR defaults.
|
|
SEND_P3_DATA(TextureCompositeFactor0, 0);
|
|
SEND_P3_DATA(TextureCompositeFactor1, 0);
|
|
|
|
SEND_P3_DATA(TextureCacheReplacementMode, 0 );
|
|
|
|
P3_DMA_COMMIT_BUFFER();
|
|
|
|
P3_DMA_GET_BUFFER_ENTRIES(24);
|
|
|
|
// Used for 3D Texture-maps
|
|
SEND_P3_DATA(TextureMapSize, 0);
|
|
|
|
SEND_P3_DATA(TextureLODBiasS, 0);
|
|
SEND_P3_DATA(TextureLODBiasT, 0);
|
|
|
|
{
|
|
float f = 1.0f;
|
|
COPY_P3_DATA(TextureLODScale, f);
|
|
COPY_P3_DATA(TextureLODScale1, f);
|
|
}
|
|
|
|
P3RX_INVALIDATECACHE(__PERMEDIA_ENABLE, __PERMEDIA_ENABLE);
|
|
|
|
pSoftP3RX->P3RXTextureApplicationMode.Enable = __PERMEDIA_ENABLE;
|
|
pSoftP3RX->P3RXTextureApplicationMode.EnableKs = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureApplicationMode.EnableKd = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureApplicationMode.MotionCompEnable = __PERMEDIA_DISABLE;
|
|
|
|
// Put the texture application unit in pass-through
|
|
pSoftP3RX->P3RXTextureApplicationMode.ColorA = 0;
|
|
pSoftP3RX->P3RXTextureApplicationMode.ColorB = P3RX_TEXAPP_B_TC;
|
|
pSoftP3RX->P3RXTextureApplicationMode.ColorI = 0;
|
|
pSoftP3RX->P3RXTextureApplicationMode.ColorInvertI = 0;
|
|
pSoftP3RX->P3RXTextureApplicationMode.ColorOperation = P3RX_TEXAPP_OPERATION_PASS_B;
|
|
pSoftP3RX->P3RXTextureApplicationMode.AlphaA = 0;
|
|
pSoftP3RX->P3RXTextureApplicationMode.AlphaB = P3RX_TEXAPP_B_TA;
|
|
pSoftP3RX->P3RXTextureApplicationMode.AlphaI = 0;
|
|
pSoftP3RX->P3RXTextureApplicationMode.AlphaInvertI = 0;
|
|
pSoftP3RX->P3RXTextureApplicationMode.AlphaOperation = P3RX_TEXAPP_OPERATION_PASS_B;
|
|
COPY_P3_DATA(TextureApplicationMode, pSoftP3RX->P3RXTextureApplicationMode);
|
|
|
|
// Set up the TA TFACTOR default.
|
|
SEND_P3_DATA(TextureEnvColor, 0);
|
|
|
|
// Turn on texture cache and invalidate it.
|
|
SEND_P3_DATA(TextureCacheControl, 3);
|
|
|
|
P3_DMA_COMMIT_BUFFER();
|
|
|
|
P3_DMA_GET_BUFFER_ENTRIES(16);
|
|
|
|
//pGlint->TextureMask = 0;
|
|
SEND_P3_DATA(TextureBaseAddr0, 0);
|
|
SEND_P3_DATA(TextureBaseAddr1, 0);
|
|
|
|
pSoftP3RX->P3RXChromaTestMode.Enable = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXChromaTestMode.Source = __GLINT_CHROMA_FBSOURCE ;
|
|
COPY_P3_DATA(ChromaTestMode, pSoftP3RX->P3RXChromaTestMode);
|
|
|
|
pSoftP3RX->P3RXTextureFilterMode.Enable = __PERMEDIA_ENABLE;
|
|
pSoftP3RX->P3RXTextureFilterMode.Format0 = 0;
|
|
pSoftP3RX->P3RXTextureFilterMode.ColorOrder0 = COLOR_MODE;
|
|
pSoftP3RX->P3RXTextureFilterMode.AlphaMapEnable0 = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureFilterMode.AlphaMapSense0 = __GLINT_TEXTUREFILTER_ALPHAMAPSENSE_EXCLUDE;
|
|
pSoftP3RX->P3RXTextureFilterMode.CombineCaches = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureFilterMode.Format1 = 0;
|
|
pSoftP3RX->P3RXTextureFilterMode.ColorOrder1 = COLOR_MODE;
|
|
pSoftP3RX->P3RXTextureFilterMode.AlphaMapEnable1 = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXTextureFilterMode.AlphaMapSense1 = __GLINT_TEXTUREFILTER_ALPHAMAPSENSE_EXCLUDE;
|
|
COPY_P3_DATA(TextureFilterMode, pSoftP3RX->P3RXTextureFilterMode);
|
|
|
|
pSoftP3RX->P3RXLUTMode.Enable = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXLUTMode.InColorOrder = P3RX_LUTMODE_INCOLORORDER_BGR;
|
|
pSoftP3RX->P3RXLUTMode.LoadFormat = P3RX_LUTMODE_LOADFORMAT_COPY;
|
|
pSoftP3RX->P3RXLUTMode.LoadColorOrder = P3RX_LUTMODE_LOADCOLORORDER_RGB;
|
|
pSoftP3RX->P3RXLUTMode.FragmentOperation = P3RX_LUTMODE_FRAGMENTOP_INDEXEDTEXTURE;
|
|
COPY_P3_DATA(LUTMode, pSoftP3RX->P3RXLUTMode);
|
|
|
|
pSoftP3RX->P3RXRasterizerMode.D3DRules = __PERMEDIA_ENABLE;
|
|
pSoftP3RX->P3RXRasterizerMode.MultiRXBlit = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXRasterizerMode.OpaqueSpan = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXRasterizerMode.WordPacking = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXRasterizerMode.StripeHeight = 0;
|
|
pSoftP3RX->P3RXRasterizerMode.BitMaskRelative = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXRasterizerMode.YLimitsEnable = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXRasterizerMode.MultiGLINT = __PERMEDIA_ENABLE;
|
|
pSoftP3RX->P3RXRasterizerMode.HostDataByteSwapMode = 0;
|
|
pSoftP3RX->P3RXRasterizerMode.BitMaskOffset = 0;
|
|
pSoftP3RX->P3RXRasterizerMode.BitMaskPacking = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXRasterizerMode.BitMaskByteSwapMode = 0;
|
|
pSoftP3RX->P3RXRasterizerMode.ForceBackgroundColor = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXRasterizerMode.BiasCoordinates = 0;
|
|
pSoftP3RX->P3RXRasterizerMode.FractionAdjust = 0;
|
|
pSoftP3RX->P3RXRasterizerMode.InvertBitMask = __PERMEDIA_DISABLE;
|
|
pSoftP3RX->P3RXRasterizerMode.MirrorBitMask = __PERMEDIA_DISABLE;
|
|
COPY_P3_DATA(RasterizerMode, pSoftP3RX->P3RXRasterizerMode);
|
|
|
|
pSoftP3RX->P3RXScanlineOwnership.Mask = 0;
|
|
pSoftP3RX->P3RXScanlineOwnership.MyId = 0;
|
|
COPY_P3_DATA(ScanlineOwnership, pSoftP3RX->P3RXScanlineOwnership);
|
|
|
|
P3_DMA_COMMIT_BUFFER();
|
|
|
|
} // __CTX_Perm3_SetupD3D_HWDefaults
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// __CTX_SetupD3DContext_Defaults
|
|
//
|
|
// Initializes our private D3D context data (renderstates, TSS and other).
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void
|
|
__CTX_SetupD3DContext_Defaults(
|
|
P3_D3DCONTEXT* pContext)
|
|
{
|
|
DWORD dwStageNum;
|
|
|
|
// Set all the stages to 'unused' and disabled
|
|
for (dwStageNum = 0; dwStageNum < D3DHAL_TSS_MAXSTAGES; dwStageNum++)
|
|
{
|
|
pContext->iTexStage[dwStageNum] = -1;
|
|
pContext->TextureStageState[dwStageNum].m_dwVal[D3DTSS_COLOROP] =
|
|
D3DTOP_DISABLE;
|
|
}
|
|
|
|
// No texture at present.
|
|
pContext->TextureStageState[TEXSTAGE_0].m_dwVal[D3DTSS_COLOROP] = D3DTOP_DISABLE;
|
|
pContext->TextureStageState[TEXSTAGE_0].m_dwVal[D3DTSS_ALPHAOP] = D3DTOP_DISABLE;
|
|
|
|
pContext->TextureStageState[TEXSTAGE_0].m_dwVal[D3DTSS_TEXTUREMAP] = 0;
|
|
pContext->TextureStageState[TEXSTAGE_1].m_dwVal[D3DTSS_TEXTUREMAP] = 0;
|
|
|
|
pContext->TextureStageState[TEXSTAGE_0].m_dwVal[D3DTSS_MINFILTER] = D3DTFN_POINT;
|
|
pContext->TextureStageState[TEXSTAGE_1].m_dwVal[D3DTSS_MINFILTER] = D3DTFN_POINT;
|
|
pContext->TextureStageState[TEXSTAGE_0].m_dwVal[D3DTSS_MIPFILTER] = D3DTFN_POINT;
|
|
pContext->TextureStageState[TEXSTAGE_1].m_dwVal[D3DTSS_MIPFILTER] = D3DTFN_POINT;
|
|
pContext->TextureStageState[TEXSTAGE_0].m_dwVal[D3DTSS_MAGFILTER] = D3DTFN_POINT;
|
|
pContext->TextureStageState[TEXSTAGE_1].m_dwVal[D3DTSS_MAGFILTER] = D3DTFN_POINT;
|
|
|
|
pContext->eChipBlendStatus = BSF_UNINITIALISED;
|
|
|
|
// Initially set values to force change of texture
|
|
pContext->bTextureValid = TRUE;
|
|
|
|
// Defaults states
|
|
pContext->RenderStates[D3DRENDERSTATE_TEXTUREMAPBLEND] = D3DTBLEND_COPY;
|
|
pContext->fRenderStates[D3DRENDERSTATE_FOGTABLESTART] = 0.0f;
|
|
pContext->fRenderStates[D3DRENDERSTATE_FOGTABLEEND] = 1.0f;
|
|
pContext->RenderStates[D3DRENDERSTATE_CULLMODE] = D3DCULL_CCW;
|
|
pContext->RenderStates[D3DRENDERSTATE_PLANEMASK] = 0xFFFFFFFF;
|
|
pContext->RenderStates[D3DRENDERSTATE_LOCALVIEWER] = FALSE;
|
|
pContext->RenderStates[D3DRENDERSTATE_COLORKEYENABLE] = FALSE;
|
|
|
|
#if DX8_DDI
|
|
// New DX8 D3DRS_COLORWRITEENABLE default = allow write to all channels
|
|
pContext->dwColorWriteHWMask = 0xFFFFFFFF;
|
|
pContext->dwColorWriteSWMask = 0xFFFFFFFF;
|
|
#endif //DX8_DDI
|
|
|
|
// On context creation, no render states are overridden (for legacy intfce's)
|
|
STATESET_INIT(pContext->overrides);
|
|
|
|
// Set default culling state
|
|
SET_CULLING_TO_CCW(pContext);
|
|
|
|
#if DX7_D3DSTATEBLOCKS
|
|
// Default state block recording mode = no recording
|
|
pContext->bStateRecMode = FALSE;
|
|
pContext->pCurrSS = NULL;
|
|
pContext->pIndexTableSS = NULL;
|
|
pContext->dwMaxSSIndex = 0;
|
|
#endif //DX7_D3DSTATEBLOCKS
|
|
|
|
|
|
#if DX8_POINTSPRITES
|
|
// Point sprite defaults
|
|
pContext->PntSprite.bEnabled = FALSE;
|
|
pContext->PntSprite.fSize = 1.0f;
|
|
pContext->PntSprite.fSizeMin = 1.0f;
|
|
pContext->PntSprite.fSizeMax = P3_MAX_POINTSPRITE_SIZE;
|
|
#endif //DX8_POINTSPRITES
|
|
|
|
// Multistreaming default setup
|
|
pContext->lpVertices = NULL;
|
|
pContext->dwVertexType = 0;
|
|
#if DX8_DDI
|
|
pContext->lpIndices = NULL;
|
|
pContext->dwIndicesStride = 0;
|
|
pContext->dwVerticesStride = 0;
|
|
#endif // DX8_DDI
|
|
|
|
//*********************************
|
|
// INTERNAL CONTEXT RENDERING STATE
|
|
//*********************************
|
|
|
|
pContext->bKeptStipple = FALSE; // By default, stippling off.
|
|
pContext->bCanChromaKey = FALSE; // Turn Chroma keying off by default
|
|
|
|
#if DX8_MULTISAMPLING || DX7_ANTIALIAS
|
|
pContext->dwAliasPixelOffset = 0x0;
|
|
pContext->dwAliasZPixelOffset = 0x0;
|
|
pContext->dwAliasZBuffer = 0x0;
|
|
pContext->dwAliasBackBuffer = 0x0;
|
|
#if DX8_DDI
|
|
if (pContext->pSurfRenderInt->dwSampling)
|
|
{
|
|
pContext->RenderStates[D3DRS_MULTISAMPLEANTIALIAS] = TRUE;
|
|
pContext->Flags |= SURFACE_ANTIALIAS;
|
|
}
|
|
#endif
|
|
#endif // DX8_MULTISAMPLING || DX7_ANTIALIAS
|
|
|
|
// Set texturing on
|
|
pContext->Flags |= SURFACE_TEXTURING;
|
|
|
|
// Initialize the mipmap bias
|
|
pContext->MipMapLODBias[0] = 0.0f;
|
|
pContext->MipMapLODBias[1] = 0.0f;
|
|
|
|
// Initialise the RenderCommand. States will add to this
|
|
pContext->RenderCommand = 0;
|
|
RENDER_SUB_PIXEL_CORRECTION_ENABLE(pContext->RenderCommand);
|
|
|
|
// Dirty all states
|
|
DIRTY_EVERYTHING(pContext);
|
|
|
|
} // __CTX_SetupD3DContext_Defaults
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// ****************************************************************************
|
|
// ***************************** D3D HAL Callbacks ****************************
|
|
// ****************************************************************************
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//-----------------------------Public Routine----------------------------------
|
|
//
|
|
// D3DContextCreate
|
|
//
|
|
// The ContextCreate callback is invoked when a new Direct3D device is being
|
|
// created by a Direct3D application. The driver is required to generate a
|
|
// unique context id for this new context. Direct3D will then use this context
|
|
// id in every subsequent callback invocation for this Direct3D device.
|
|
//
|
|
// Context is the current rasterization state. For instance, if there are 3
|
|
// applications running, each will have a different state at any point in time.
|
|
// When each one is running, the hardware has to make sure that the context,
|
|
// (whether doing Gouraud shading, for example) is the same as the last time
|
|
// that application got a time slice.
|
|
//
|
|
// State is anything that the particular device needs to know per context
|
|
// i.e. what surface is being rendered to, shading, texture, texture handles,
|
|
// what physical surfaces those texture handles represent, etc. The context
|
|
// encapsulates all state for the Direct3D device - state is not shared
|
|
// between contexts. Therefore the driver needs to maintain full state
|
|
// information for each context. This state will be changed by calls to the
|
|
// RenderState callback. In the case of rasterization only hardware, the
|
|
// driver need only maintain rasterization state. As well as state, the driver
|
|
// will also want to store the lpDDS, lpDDSZ, and dwPid from the callback
|
|
// data argument.
|
|
//
|
|
// The driver should not create a context handle of zero. This is guaranteed
|
|
// to be an invalid context handle.
|
|
//
|
|
// Parameters
|
|
// pccd
|
|
// Pointer to a structure containing things including the current
|
|
// rendering surface, the current Z surface, and the DirectX object
|
|
// handle, etc.
|
|
//
|
|
// .lpDDGbl
|
|
// Points to the DirectDraw structure representing the
|
|
// DirectDraw object.
|
|
// .lpDDLcl(replaces lpDDGbl in DX7)
|
|
// Points to the DirectDraw structure representing the
|
|
// DirectDraw object.
|
|
// .lpDDS
|
|
// This is the surface that is to be used as the rendering
|
|
// target, i.e., the 3D accelerator sprays its bits at this
|
|
// surface.
|
|
// .lpDDSZ
|
|
// The surface that is to be used as the Z buffer. If this
|
|
// is NULL, no Z buffering is to be performed.
|
|
// .dwPid
|
|
// The process id of the Direct3D application that initiated
|
|
// the creation of the Direct3D device.
|
|
// .dwhContext
|
|
// The driver should place the context ID that it wants Direct3D
|
|
// to use when communicating with the driver. This should be
|
|
// unique.
|
|
// .ddrval
|
|
// Return code. DD_OK indicates success.
|
|
//
|
|
// Return Value
|
|
// Returns one of the following values:
|
|
// DDHAL_DRIVER_HANDLED
|
|
// DDHAL_DRIVER_NOTHANDLED
|
|
//
|
|
// Notes:
|
|
//
|
|
// Currently the context isn't locked, so we can't switch in a register context.
|
|
// All chip specific setup is therefore saved for the first execute.
|
|
// This is guaranteed to have the lock.
|
|
// Some chip state is duplicated in the context structure. This
|
|
// means that a software copy is kept to stop unnecessary changes to
|
|
// the chip state.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
DWORD CALLBACK
|
|
D3DContextCreate(
|
|
LPD3DHAL_CONTEXTCREATEDATA pccd)
|
|
{
|
|
LPDDRAWI_DDRAWSURFACE_LCL lpLclFrame = NULL;
|
|
LPDDRAWI_DDRAWSURFACE_LCL lpLclZ = NULL;
|
|
P3_D3DCONTEXT *pContext;
|
|
P3_THUNKEDDATA *pThisDisplay;
|
|
DWORD Result;
|
|
DWORD dwSlotNum;
|
|
ULONG_PTR dwDXInterface;
|
|
BOOL bRet;
|
|
|
|
DBG_CB_ENTRY(D3DContextCreate);
|
|
|
|
// Get our pThisDisplay
|
|
GET_THUNKEDDATA(pThisDisplay, pccd->lpDDLcl->lpGbl);
|
|
|
|
//***********************************************************************
|
|
// Create a new D3D context driver structure and asssociate an id with it
|
|
//***********************************************************************
|
|
|
|
// Find a context empty slot.
|
|
dwSlotNum = __CTX_NewHandle();
|
|
|
|
if (dwSlotNum == 0)
|
|
{
|
|
// no context slots left
|
|
pccd->ddrval = D3DHAL_OUTOFCONTEXTS;
|
|
DBG_CB_EXIT(D3DContextCreate,pccd->ddrval);
|
|
return (DDHAL_DRIVER_HANDLED);
|
|
}
|
|
|
|
// Return to the runtime the D3D context id that will be used to
|
|
// identify calls for this context from now on. Store prev value
|
|
// since that tells us which API are we being called from
|
|
// (4=DX8, 3=DX7, 2=DX6, 1=DX5, 0=DX3)
|
|
dwDXInterface = pccd->dwhContext; // in: DX API version
|
|
pccd->dwhContext = dwSlotNum; // out: Context handle
|
|
|
|
// Now allocate the driver's d3d context structure in kernel memory.
|
|
pContext = (P3_D3DCONTEXT*)HEAP_ALLOC(FL_ZERO_MEMORY,
|
|
sizeof(P3_D3DCONTEXT),
|
|
ALLOC_TAG_DX(1));
|
|
|
|
if (pContext == NULL)
|
|
{
|
|
DISPDBG((ERRLVL,"ERROR: Couldn't allocate Context mem"));
|
|
goto Error_OutOfMem_A;
|
|
}
|
|
else
|
|
{
|
|
DISPDBG((DBGLVL,"Allocated Context Mem - proceeding to clear"));
|
|
memset((void *)pContext, 0, sizeof(P3_D3DCONTEXT));
|
|
}
|
|
|
|
// This context id is now to be associated with this context pointer
|
|
__CTX_AssocPtrToHandle(dwSlotNum, pContext);
|
|
|
|
//*************************************************************************
|
|
// Initialize the D3D context structure
|
|
//*************************************************************************
|
|
|
|
//*******
|
|
// HEADER
|
|
//*******
|
|
|
|
// Set up the magic number to perform sanity checks
|
|
pContext->MagicNo = RC_MAGIC_NO;
|
|
|
|
// Record the usage of this context handle
|
|
pContext->dwContextHandle = dwSlotNum;
|
|
|
|
// Keep (self) pointers to the structure for destroy time
|
|
pContext->pSelf = pContext;
|
|
|
|
#if DX8_DDI
|
|
// Remember which DX interface is creating this context
|
|
// - it will make things much easier later
|
|
pContext->dwDXInterface = dwDXInterface;
|
|
#endif // DX8_DDI
|
|
|
|
//**********************
|
|
// GLOBAL DRIVER CONTEXT
|
|
//**********************
|
|
|
|
// Remember the card we are running on
|
|
pContext->pThisDisplay = pThisDisplay;
|
|
|
|
// On DX7 we need to keep a copy of the local ddraw object
|
|
// for surface handle management
|
|
pContext->pDDLcl = pccd->lpDDLcl;
|
|
pContext->pDDGbl = pccd->lpDDLcl->lpGbl;
|
|
|
|
//*******************
|
|
// RENDERING SURFACES
|
|
//*******************
|
|
|
|
// On DX7 we extract the local surface pointers directly
|
|
lpLclFrame = pccd->lpDDSLcl;
|
|
|
|
if (pccd->lpDDSZ)
|
|
{
|
|
lpLclZ = pccd->lpDDSZLcl;
|
|
}
|
|
|
|
#if DBG
|
|
// Spew debug rendering surfaces data on the debug build
|
|
DISPDBG((DBGLVL,"Allocated Direct3D context: 0x%x",pccd->dwhContext));
|
|
DISPDBG((DBGLVL,"Driver Struct = %p, Surface = %p",
|
|
pContext->pDDGbl, lpLclFrame));
|
|
DISPDBG((DBGLVL,"Z Surface = %p",lpLclZ));
|
|
|
|
if ((DWORD*)lpLclZ != NULL)
|
|
{
|
|
DISPDBG((DBGLVL," ZlpGbl: %p", lpLclZ->lpGbl));
|
|
|
|
DISPDBG((DBGLVL," fpVidMem = %08lx",lpLclZ->lpGbl->fpVidMem));
|
|
DISPDBG((DBGLVL," lPitch = %08lx",lpLclZ->lpGbl->lPitch));
|
|
DISPDBG((DBGLVL," wHeight = %08lx",lpLclZ->lpGbl->wHeight));
|
|
DISPDBG((DBGLVL," wWidth = %08lx",lpLclZ->lpGbl->wWidth));
|
|
}
|
|
|
|
DISPDBG((DBGLVL,"Buffer Surface = %p",lpLclFrame));
|
|
if ((DWORD*)lpLclFrame != NULL)
|
|
{
|
|
DISPDBG((DBGLVL," fpVidMem = %08lx",lpLclFrame->lpGbl->fpVidMem));
|
|
DISPDBG((DBGLVL," lPitch = %08lx",lpLclFrame->lpGbl->lPitch));
|
|
DISPDBG((DBGLVL," wHeight = %08lx",lpLclFrame->lpGbl->wHeight));
|
|
DISPDBG((DBGLVL," wWidth = %08lx",lpLclFrame->lpGbl->wWidth));
|
|
}
|
|
#endif // DBG
|
|
|
|
#if DX7_TEXMANAGEMENT
|
|
// Initialize texture management for this context
|
|
if(FAILED(_D3D_TM_Ctx_Initialize(pContext)))
|
|
{
|
|
// We failed. Cleanup before we leave
|
|
DISPDBG((ERRLVL,"ERROR: Couldn't initialize Texture Management"));
|
|
goto Error_OutOfMem_B;
|
|
}
|
|
#endif // DX7_TEXMANAGEMENT
|
|
|
|
// There may not have been any textures (DD surfaces) created yet through
|
|
// D3DCreateSurfaceEx. If this is the case, create a new DD locals hash
|
|
// entry and fill it will a pointer array
|
|
pContext->pTexturePointerArray =
|
|
(PointerArray*)HT_GetEntry(pThisDisplay->pDirectDrawLocalsHashTable,
|
|
(ULONG_PTR)pContext->pDDLcl);
|
|
if (!pContext->pTexturePointerArray)
|
|
{
|
|
DISPDBG((DBGLVL,"Creating new pointer array for PDDLcl "
|
|
"0x%x in ContextCreate", pContext->pDDLcl));
|
|
|
|
// Create a pointer array
|
|
pContext->pTexturePointerArray = PA_CreateArray();
|
|
|
|
if (!pContext->pTexturePointerArray)
|
|
{
|
|
// We ran out of memory. Cleanup before we leave
|
|
DISPDBG((ERRLVL,"ERROR: Couldn't allocate Context mem "
|
|
"for pTexturePointerArray"));
|
|
goto Error_OutOfMem_B;
|
|
}
|
|
|
|
// It is an array of surfaces, so set the destroy callback
|
|
PA_SetDataDestroyCallback(pContext->pTexturePointerArray,
|
|
_D3D_SU_SurfaceArrayDestroyCallback);
|
|
|
|
// Add this DD local to the hash table, and
|
|
// store the texture pointer array
|
|
if(!HT_AddEntry(pThisDisplay->pDirectDrawLocalsHashTable,
|
|
(ULONG_PTR)pContext->pDDLcl,
|
|
pContext->pTexturePointerArray))
|
|
{
|
|
// failed to add entry, noe cleanup and exit
|
|
// We ran out of memory. Cleanup before we leave
|
|
DISPDBG((ERRLVL,"ERROR: Couldn't allocate Context mem"));
|
|
goto Error_OutOfMem_C;
|
|
}
|
|
}
|
|
|
|
// Record the internal surface information
|
|
pContext->pSurfRenderInt =
|
|
GetSurfaceFromHandle(pContext,
|
|
lpLclFrame->lpSurfMore->dwSurfaceHandle);
|
|
|
|
if ( NULL == pContext->pSurfRenderInt)
|
|
{
|
|
// We ran out of memory when allocating for the rendertarget.
|
|
// Cleanup before we leave
|
|
DISPDBG((ERRLVL,"ERROR: Couldn't allocate pSurfRenderInt mem"));
|
|
goto Error_OutOfMem_D;
|
|
}
|
|
|
|
if (lpLclZ)
|
|
{
|
|
pContext->pSurfZBufferInt =
|
|
GetSurfaceFromHandle(pContext,
|
|
lpLclZ->lpSurfMore->dwSurfaceHandle);
|
|
|
|
if ( NULL == pContext->pSurfZBufferInt)
|
|
{
|
|
// We ran out of memory when allocating for the depth buffer.
|
|
// Cleanup before we leave
|
|
DISPDBG((ERRLVL,"ERROR: Couldn't allocate pSurfZBufferInt mem"));
|
|
goto Error_OutOfMem_D;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pContext->pSurfZBufferInt = NULL;
|
|
}
|
|
|
|
pContext->ModeChangeCount = pThisDisplay->ModeChangeCount;
|
|
|
|
|
|
//******************
|
|
// DEBUG USEFUL INFO
|
|
//******************
|
|
|
|
// Store the process id in which this d3d context was created
|
|
pContext->OwningProcess = pccd->dwPID;
|
|
|
|
// Depth of the primary surface
|
|
pContext->BPP = pContext->pThisDisplay->ddpfDisplay.dwRGBBitCount >> 3;
|
|
|
|
//******************************
|
|
// HW STATE FOR THIS D3D CONTEXT
|
|
//******************************
|
|
|
|
// Did we setup a DMA buffer at start of day, or FIFO's?
|
|
if (pThisDisplay->DMAInfo.dwBuffSize == 0)
|
|
{
|
|
DISPDBG((WRNLVL, "No DMA buffer available - using FIFO's for 3D"));
|
|
pContext->b3D_FIFOS = TRUE;
|
|
}
|
|
else
|
|
{
|
|
DISPDBG((WRNLVL, "Using shared DMA buffer"));
|
|
pContext->b3D_FIFOS = FALSE;
|
|
}
|
|
|
|
//************************************
|
|
// DEFAULT D3D OVERALL RENDERING STATE
|
|
//************************************
|
|
|
|
__CTX_SetupD3DContext_Defaults(pContext);
|
|
|
|
//*************************************************************************
|
|
// ACTUALLY SETUP HARDWARE IN ORDER TO USE THIS D3D CONTEXT
|
|
//*************************************************************************
|
|
|
|
STOP_SOFTWARE_CURSOR(pThisDisplay);
|
|
|
|
// Setup default states values to the chip
|
|
__CTX_Perm3_SetupD3D_HWDefaults(pContext);
|
|
|
|
|
|
// Find out info for screen size and depth
|
|
DISPDBG((DBGLVL, "ScreenWidth %d, ScreenHeight %d, Bytes/Pixel %d",
|
|
pContext->pThisDisplay->dwScreenWidth,
|
|
pContext->pThisDisplay->dwScreenHeight, pContext->BPP));
|
|
|
|
// Setup the relevent registers for the surfaces in use in this context.
|
|
if ( FAILED( _D3D_OP_SetRenderTarget(pContext,
|
|
pContext->pSurfRenderInt,
|
|
pContext->pSurfZBufferInt,
|
|
TRUE) ))
|
|
{
|
|
goto Error_OutOfMem_D;
|
|
}
|
|
|
|
// Process some defaults with which we initialize each D3D context
|
|
_D3D_ST_ProcessOneRenderState(pContext,
|
|
D3DRENDERSTATE_SHADEMODE,
|
|
D3DSHADE_GOURAUD);
|
|
|
|
_D3D_ST_ProcessOneRenderState(pContext,
|
|
D3DRENDERSTATE_FOGCOLOR,
|
|
0xFFFFFFFF);
|
|
#if DX8_DDI
|
|
// On DX8 D3DRENDERSTATE_TEXTUREPERSPECTIVE has been retired and is assumed
|
|
// to be set always to TRUE. We must make sure we are setting the hw up
|
|
// correctly, so in order to do that we make an explicit setup call here
|
|
_D3D_ST_ProcessOneRenderState(pContext,
|
|
D3DRENDERSTATE_TEXTUREPERSPECTIVE,
|
|
1);
|
|
#endif // DX8_DDI
|
|
|
|
#if DX7_PALETTETEXTURE
|
|
// Palette pointer array is per context, it is NOT associated with DD Local
|
|
pContext->pPalettePointerArray = PA_CreateArray();
|
|
|
|
if (! pContext->pPalettePointerArray)
|
|
{
|
|
// We ran out of memory. Cleanup before we leave
|
|
DISPDBG((ERRLVL,"ERROR: Couldn't allocate Context mem "
|
|
"for pPalettePointerArray"));
|
|
goto Error_OutOfMem_D;
|
|
}
|
|
|
|
// It is an array of surfaces, so set the destroy callback
|
|
PA_SetDataDestroyCallback(pContext->pTexturePointerArray,
|
|
_D3D_SU_PaletteArrayDestroyCallback);
|
|
#endif
|
|
|
|
START_SOFTWARE_CURSOR(pThisDisplay);
|
|
|
|
pccd->ddrval = DD_OK; // Call handled OK
|
|
|
|
DBG_CB_EXIT(D3DContextCreate,pccd->ddrval);
|
|
|
|
return (DDHAL_DRIVER_HANDLED);
|
|
|
|
//**************************************************************************
|
|
// ERROR HANDLING CODE PATHS
|
|
//**************************************************************************
|
|
Error_OutOfMem_D:
|
|
// Remove the texture pointer array from the hash table
|
|
HT_RemoveEntry(pThisDisplay->pDirectDrawLocalsHashTable,
|
|
(ULONG_PTR)pccd->lpDDLcl,
|
|
pThisDisplay);
|
|
goto Error_OutOfMem_B;
|
|
|
|
Error_OutOfMem_C:
|
|
// Free binding surface array (we'll no longer need it, and
|
|
// D3DCreateSurfaceEx will create a new one if necessary)
|
|
PA_DestroyArray(pContext->pTexturePointerArray, pThisDisplay);
|
|
|
|
Error_OutOfMem_B:
|
|
// Free D3D context data structure that we allocated
|
|
HEAP_FREE(pContext->pSelf);
|
|
|
|
Error_OutOfMem_A:
|
|
// Release the context handle (otherwise it will remain in use forever)
|
|
__CTX_HandleRelease((DWORD)pccd->dwhContext);
|
|
|
|
pccd->dwhContext = 0;
|
|
pccd->ddrval = DDERR_OUTOFMEMORY;
|
|
DBG_CB_EXIT(D3DContextCreate,pccd->ddrval);
|
|
return (DDHAL_DRIVER_HANDLED);
|
|
|
|
} // D3DContextCreate
|
|
|
|
//-----------------------------Public Routine----------------------------------
|
|
//
|
|
// D3DContextDestroy
|
|
//
|
|
// This callback is invoked when a Direct3D Device is being destroyed. As each
|
|
// device is represented by a context ID, the driver is passed a context to
|
|
// destroy.
|
|
//
|
|
// The driver should free all resources it allocated to the context being
|
|
// deleted. For example, the driver should free any texture resources it
|
|
// associated with the context. The driver should not free the DirectDraw
|
|
// surface(s) associated with the context because these will be freed by
|
|
// DirectDraw in response to an application or Direct3D runtime request.
|
|
//
|
|
// Parameters
|
|
// pcdd
|
|
// Pointer to Context destroy information.
|
|
//
|
|
// .dwhContext
|
|
// The ID of the context to be destroyed.
|
|
// .ddrval
|
|
// Return code. DD_OK indicates success.
|
|
//
|
|
// Return Value
|
|
// Returns one of the following values:
|
|
// DDHAL_DRIVER_HANDLED
|
|
// DDHAL_DRIVER_NOTHANDLED
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
DWORD CALLBACK
|
|
D3DContextDestroy(
|
|
LPD3DHAL_CONTEXTDESTROYDATA pccd)
|
|
{
|
|
P3_D3DCONTEXT *pContext;
|
|
P3_THUNKEDDATA *pThisDisplay;
|
|
|
|
DBG_CB_ENTRY(D3DContextDestroy);
|
|
|
|
// Deleting context
|
|
DISPDBG((DBGLVL,"D3DContextDestroy Context = %08lx",pccd->dwhContext));
|
|
|
|
pContext = _D3D_CTX_HandleToPtr(pccd->dwhContext);
|
|
|
|
if (!CHECK_D3DCONTEXT_VALIDITY(pContext))
|
|
{
|
|
pccd->ddrval = D3DHAL_CONTEXT_BAD;
|
|
DISPDBG((WRNLVL,"Context not valid"));
|
|
|
|
DBG_CB_EXIT(D3DContextDestroy,pccd->ddrval );
|
|
return (DDHAL_DRIVER_HANDLED);
|
|
}
|
|
|
|
pThisDisplay = pContext->pThisDisplay;
|
|
|
|
// Flush any DMA and Sync the chip so that that DMA can complete
|
|
// (deletecontexts aren't an every day occurance, so we may as well)
|
|
|
|
STOP_SOFTWARE_CURSOR(pThisDisplay);
|
|
|
|
#if WNT_DDRAW
|
|
if (pThisDisplay->ppdev->bEnabled)
|
|
{
|
|
#endif
|
|
DDRAW_OPERATION(pContext, pThisDisplay);
|
|
|
|
{
|
|
P3_DMA_DEFS();
|
|
P3_DMA_GET_BUFFER();
|
|
P3_DMA_FLUSH_BUFFER();
|
|
}
|
|
|
|
SYNC_WITH_GLINT;
|
|
#if WNT_DDRAW
|
|
}
|
|
#endif
|
|
|
|
START_SOFTWARE_CURSOR(pThisDisplay);
|
|
|
|
// Mark the context as disabled
|
|
pContext->MagicNo = RC_MAGIC_DISABLE;
|
|
|
|
#if DX7_TEXMANAGEMENT
|
|
// Cleanup any texture management stuff before leaving
|
|
_D3D_TM_Ctx_Destroy(pContext);
|
|
#endif // DX7_TEXMANAGEMENT
|
|
|
|
// Free and cleanup any associated hardware resources
|
|
__CTX_CleanDirect3DContext(pContext);
|
|
|
|
// Mark the context as now empty (dwhContext is ULONG_PTR for Win64)
|
|
__CTX_HandleRelease((DWORD)pccd->dwhContext);
|
|
|
|
// Finally, free up rendering context structure and set to NULL
|
|
HEAP_FREE(pContext->pSelf);
|
|
pContext = NULL;
|
|
|
|
pccd->ddrval = DD_OK;
|
|
|
|
DBG_CB_EXIT(D3DContextDestroy, pccd->ddrval);
|
|
|
|
return (DDHAL_DRIVER_HANDLED);
|
|
} // D3DContextDestroy
|
|
|
|
|
|
|
|
|