/******************************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 #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