📄 vgpcommon.c
字号:
return;
}
/* Record the new required section repeat-count */
psContext->ppsFFTNLSections[dwSectionIdx]->sConfig.dwRepeatCount = dwCount;
/* Rebind the section to register the new repeat count */
RebindSection(psContext->ppsFFTNLSections[dwSectionIdx], psContext);
}
/*****************************************************************************
FUNCTION : RebindSection
PURPOSE : Updates the HW section-definition for a section
PARAMETERS : psSection - The code-section to rebind
psContext - The rendering context to update
RETURNS : void
*****************************************************************************/
IMG_VOID RebindSection(PVSSECTION psSection, LPD3DM_CONTEXT psContext)
{
PVSSECTIONCFG psSectionCfg;
DWORD dwHWSectionID;
DWORD dwHWVGPSectionDef;
DWORD dwExeStart;
DWORD dwExeEnd;
/* Update the HW section-definition for this section, and flag that it has to be resent to the HW */
dwHWSectionID = psSection->dwHWSectionID;
dwHWVGPSectionDef = psSection->dwHWVGPSectionDef;
psSectionCfg = &psSection->sConfig;
dwExeStart = psSectionCfg->sExeRange.dwFirst;
dwExeEnd = psSectionCfg->sExeRange.dwLast;
dwHWVGPSectionDef &= MBX1_VGPSECTDEF_COUNT_CLRMSK &
(~MBX1_VGPSECTDEF_STARTADDR_MASK) &
(~MBX1_VGPSECTDEF_ENDADDR_MASK) &
(~MBX1_VGPSECTDEF_SECTIONID_MASK);
dwHWVGPSectionDef |= ((psSection->sConfig.dwRepeatCount - 1) << MBX1_VGPSECTDEF_COUNT_SHIFT) &
MBX1_VGPSECTDEF_COUNT_MASK;
dwHWVGPSectionDef |= (dwExeStart << MBX1_VGPSECTDEF_STARTADDR_SHIFT) &
MBX1_VGPSECTDEF_STARTADDR_MASK;
dwHWVGPSectionDef |= (dwExeEnd << MBX1_VGPSECTDEF_ENDADDR_SHIFT) &
MBX1_VGPSECTDEF_ENDADDR_MASK;
/*
dwHWVGPSectionDef |= (dwHWSectionID << MBX1_VGPSECTDEF_SECTIONID_SHIFT) &
MBX1_VGPSECTDEF_SECTIONID_MASK;
*/
psSection->dwHWVGPSectionDef = dwHWVGPSectionDef;
/*
Update the HW-state and flag that the section-definition needs to be
submitted to the HW
*/
psContext->sHWState.sVGPControl.pdwSectionDef[dwHWSectionID] = dwHWVGPSectionDef;
psContext->sHWStateCtl.dwVGPCtlStateChanged |= MBX1_VGPCONTROL_SECTION0DEF_ENABLE << dwHWSectionID;
}
/*****************************************************************************
FUNCTION : EnableSections
PURPOSE : Enables one or more vertex-shader code section
PARAMETERS : dwSectionsToEnable - Bit flags indicating which sections
should be enabled (bit N = section N)
psContext - The current rendering context
RETURNS : void
*****************************************************************************/
IMG_VOID EnableSections(DWORD dwSectionsToEnable,
LPD3DM_CONTEXT psContext)
{
DWORD i;
PVSSECTION psSection;
if(dwSectionsToEnable == 0)
{
return;
}
/* Cycle round sections to enable */
for(i = 0; i < psContext->dwSectionCount; i++)
{
if(!(dwSectionsToEnable & (MBX1_VGPCLIPCTL_SECTION0_ENABLE << i)))
{
continue;
}
psSection = psContext->ppsFFTNLSections[i];
RebindSection(psSection, psContext);
psContext->dwVGPClipCtl |= (MBX1_VGPCLIPCTL_SECTION0_ENABLE << i);
psContext->ppsFFTNLSections[i]->dwFlags |= VSSECTIONFLAGS_ENABLED;
if(i < psContext->dwFirstSection)
{
psContext->dwFirstSection = i;
}
}
}
/*****************************************************************************
FUNCTION : DisableSections
PURPOSE : Disables a vertex-shader code section
PARAMETERS : dwSectionsToDisable - flag array of sections to be disabled
psContext - The rendering context to update
*****************************************************************************/
IMG_VOID DisableSections(DWORD dwSectionsToDisable,
LPD3DM_CONTEXT psContext)
{
DWORD i;
PVSSECTION psSection;
if(dwSectionsToDisable == 0)
{
return;
}
/* Cycle round sections to enable */
for(i = 0; i < psContext->dwSectionCount; i++)
{
if(!(dwSectionsToDisable & (MBX1_VGPCLIPCTL_SECTION0_ENABLE << i)))
{
continue;
}
psSection = psContext->ppsFFTNLSections[i];
psContext->dwVGPClipCtl &= ~(MBX1_VGPCLIPCTL_SECTION0_ENABLE << i);
psSection->dwFlags &= ~VSSECTIONFLAGS_ENABLED;
}
/* Find first active section */
psContext->dwFirstSection = psContext->dwSectionCount;
for(i = 0; i < psContext->dwSectionCount; i++)
{
if(psContext->dwVGPClipCtl & (MBX1_VGPCLIPCTL_SECTION0_ENABLE << i))
{
if(i < psContext->dwFirstSection)
{
psContext->dwFirstSection = i;
break;
}
}
}
}
/*****************************************************************************
FUNCTION : SetSectionExeRange
PURPOSE : Sets the range of instruction to execute for a section
PARAMETERS : dwSectionIdx - Index of the section to change
dwFirstInst - Index of the first instruction to execute
dwLastInst - Index of the last instruction to execute
psContext - The current rendering context
RETURNS : void
*****************************************************************************/
IMG_VOID SetSectionExeRange(DWORD dwSectionIdx,
DWORD dwFirstInst,
DWORD dwLastInst,
LPD3DM_CONTEXT psContext)
{
PVSINSTRANGE psExeRange;
PVSINSTRANGE psLoadRange;
/* Validate the given section index */
if(dwSectionIdx >= psContext->dwSectionCount)
{
D3DM_DPF((DPF_VGP, "SetSectionExeRange: Invalid section index %d for section 0x%8.8X (max %d)", dwSectionIdx, psContext->ppsFFTNLSections[dwSectionIdx], psContext->dwSectionCount);
return;
}
/* Check the new range - must lie within the range of instructions loaded for this section */
psLoadRange = &psContext->ppsFFTNLSections[dwSectionIdx]->sConfig.sLoadRange;
if((psLoadRange->dwFirst + dwLastInst) > psLoadRange->dwLast)
{
D3DM_DPF((DPF_VGP, "SetSectionExeRange: Invalid exe start/end range (%d-%d)", dwFirstInst, dwLastInst);
/* Just set last instruction to last loaded instruction for this section */
dwLastInst = psLoadRange->dwLast - psLoadRange->dwFirst;
}
/* Record the new required instruction execution range */
psExeRange = &psContext->ppsFFTNLSections[dwSectionIdx]->sConfig.sExeRange;
psExeRange->dwFirst = psLoadRange->dwFirst + dwFirstInst;
psExeRange->dwLast = psLoadRange->dwFirst + dwLastInst;
}
/*****************************************************************************
FUNCTION : VGPTNLPrePrimSetup
PURPOSE : Updates the FF-TNL vertex-shader code and constants to reflect
the current D3D state. Called immediately before each 3D
primitive is processed.
PARAMETERS : psContext - The current SW context
dwPrimType - The type of primitive to be processed next
RETURNS : void
****************************************************************************/
IMG_VOID VGPTNLPrePrimSetup(LPD3DM_CONTEXT psContext)
{
PTRANSIENT_STATE psTState;
PSWTNLSTATE psSWTNLState;
DWORD dwTNLFlags;
BOOL bPassthrough;
psTState = &psContext->sTState;
psSWTNLState = &psTState->sSWTNLState;
/* Determine the current shader type */
dwTNLFlags = psSWTNLState->dwTNLFlags;
bPassthrough = !(dwTNLFlags & PVRD3DTNL_FLAGS_ENABLED);
/*
Nothing to do if no flags or data values have changed since the
last primitive
*/
if((psSWTNLState->dwTNLFlags == psSWTNLState->dwTNLActiveFlags) &&
(psSWTNLState->dwTNLFlags2 == psSWTNLState->dwTNLActiveFlags2))
{
// goto SkipPrePrim;FIXME - Test sectionmodflags
}
/* Update the TNL-state flags and derived state */
VGPTNLUpdateSWTNLState(psContext);
/* Reconfigure the fixed-function TNL shader */
VGPTNLUpdateFFTNLShader(psContext);
/* Set up the constants for this primitive */
VGPTNLUpdateConstants(psContext);
/*
Note that we have processed all the state changes since the last
primitives
*/
psSWTNLState->dwTNLFlags &= ~PVRD3DTNL_FLAGS_CHANGE_CLRMSK;
psSWTNLState->dwTNLActiveFlags = psSWTNLState->dwTNLFlags;
psSWTNLState->dwTNLFlags2 &= ~PVRD3DTNL_FLAGS2_CHANGE_CLRMSK;
psSWTNLState->dwTNLActiveFlags2 = psSWTNLState->dwTNLFlags2;
//SkipPrePrim:
/*
Enable VGP clipping as appropriate (applicable for both programmable
and fixed-function tNL shaders, so it is done)
*/
psContext->dwVGPClipCtl &= ~(MBX1_VGPCLIPCTL_CLIPPLANES_MASK |
MBX1_VGPCLIPCTL_STARTSECTION_MASK);
if(!bPassthrough)
{
if(psTState->dwRSFlags & TSTATE_RSFLAGS_CLIPPING)
{
psContext->dwVGPClipCtl |= MBX1_VGPCLIPCTL_FRONTCLIPPLANE_ENABLE |
MBX1_VGPCLIPCTL_REARCLIPPLANE_ENABLE;
psContext->dwVGPClipCtl |= ((1 << psSWTNLState->dwClipPlaneCount) - 1) <<
MBX1_VGPCLIPCTL_CLIPPLANES_SHIFT;
}
#if !defined(FIX_HW_PRN_306)
/* Must be untransformed-vertices. Enable the viewport transform */
psContext->dwVGPClipCtl |= MBX1_VGPCLIPCTL_VIEWPORTTRANS_ENABLE | MBX1_VGPCLIPCTL_WCLAMP_ENABLE;
#else
/* Must be untransformed-vertices. Enable the viewport transform */
psContext->dwVGPClipCtl |= MBX1_VGPCLIPCTL_VIEWPORTTRANS_ENABLE;
#endif
}
else
{
psContext->dwVGPClipCtl &= ~(MBX1_VGPCLIPCTL_VIEWPORTTRANS_ENABLE |
MBX1_VGPCLIPCTL_WCLAMP_ENABLE);
}
psContext->dwVGPClipCtl |= (psContext->dwFirstSection << MBX1_VGPCLIPCTL_STARTSECTION_SHIFT);
}
/*****************************************************************************
FUNCTION : SectionCreate
PURPOSE : Creates an empty vertex-shader code-section
PARAMETERS : dwInstCount - The maximum number of required instructions
available in the section
RETURNS : PVSSECTION - The created vertex-shader section
*****************************************************************************/
PVSSECTION SectionCreate(DWORD dwInstCount)
{
PVSSECTION psSection;
DWORD dwAllocSize;
/* Check the requested instruction count */
if(dwInstCount < 1 || dwInstCount > MBX1_VGPCODE_INST_COUNT)
{
D3DM_DPF((DPF_VGP, "VSSectionCreate: Invalid instruct-count %d (min 1, max %d)", dwInstCount, MBX1_VGPCODE_INST_COUNT));
return 0;
}
/* Try to create a new section with space for (up-to) the given number of instructions */
dwAllocSize = sizeof(VSSECTION) + (sizeof(HWVGPINST) * dwInstCount);
psSection = (PVSSECTION)D3DMAllocate(dwAllocSize);
if(!psSection)
{
D3DM_DPF((DPF_VGP, "VSSectionCreate: Unable to allocate %d-instruction section", dwInstCount));
return IMG_NULL;
}
/* Initialise any non-zero data */
psSection->dwMaxInsts = dwInstCount;
psSection->psInsts = (PHWVGPINST)(psSection + 1);
psSection->sConfig.dwRepeatCount = 1;
return psSection;
}
/*****************************************************************************
FUNCTION : SectionDestroy
PURPOSE : Destroys a vertex-shader code-section previously created using
VSSectionCreate
PARAMETERS : psSection - The code-section to destroy
RETURNS : void
*****************************************************************************/
IMG_VOID SectionDestroy(PVSSECTION psSection)
{
if(psSection)
{
D3DMFree(psSection);
}
}
/*****************************************************************************
FUNCTION : InitStateVGPInstructions
PURPOSE : Writes prototyped VGP-instructions to state control for submission
PARAMETERS : psContext - Current 3D rendering context
RETURNS : void
*****************************************************************************/
IMG_VOID InitStateVGPInstructions(LPD3DM_CONTEXT psContext)
{
DWORD i;
DWORD dwTotalInstCount = 0;
HWVGPINST *pInstBuffer;
D3DM_DPF((DPF_ENTRY, "->TACSWriteVGPInstructions"));
pInstBuffer = (HWVGPINST*) &psContext->sHWState.sVGPCode;
/* Loop through all sections, adding instructions to state buffer */
for(i = 0; i < psContext->dwSectionCount; i++)
{
DWORD j;
/* Indicate which hw address the section starts at */
psContext->ppsFFTNLSections[i]->dwHWInstStart = dwTotalInstCount;
psContext->ppsFFTNLSections[i]->sConfig.sLoadRange.dwFirst = dwTotalInstCount;
for(j=0; j < psContext->ppsFFTNLSections[i]->dwInstCount; j++)
{
*pInstBuffer++ = psContext->ppsFFTNLSections[i]->psInsts[j];
}
/* Update instruction count */
dwTotalInstCount += psContext->ppsFFTNLSections[i]->dwInstCount;
psContext->ppsFFTNLSections[i]->sConfig.sLoadRange.dwLast = dwTotalInstCount - 1;
/* Default exe range is load range */
psContext->ppsFFTNLSections[i]->sConfig.sExeRange.dwLast =
psContext->ppsFFTNLSections[i]->sConfig.sLoadRange.dwLast;
psContext->ppsFFTNLSections[i]->sConfig.sExeRange.dwFirst =
psContext->ppsFFTNLSections[i]->sConfig.sLoadRange.dwFirst;
}
/* Flag modified instructions */
FlagArraySetFlagRange((PFLAGARRAY)&psContext->sHWStateCtl.sVGPInstsChanged, 0, dwTotalInstCount - 1);
D3DM_DPF((DPF_EXIT, "<-TACSWriteVGPInstructions"));
}
/*****************************************************************************
FUNCTION : VGPTNLSetup
PURPOSE : Sets up Fixed Function VGP code sections
PARAMETERS : psContext - A 3D rendering context to setup the FF-TNL for
RETURNS : BOOL - True if the sections could be created OK. False on
failure
****************************************************************************/
BOOL VGPTNLSetup(LPD3DM_CONTEXT psContext)
{
HWVGPINST *psInst;
DWORD i;
/* Setup the prototype of sections that initialize the vertex colour sources */
psInst = psColourSourceSectionPrototype;
for (i = 0; i < 3; i++)
{
DWORD j;
for (j = 0; j < 3; j++)
{
DWORD k;
for (k = 0; k < 3; k++)
{
*psInst = psAmbientSourcePrototype[i];
psInst++;
*psInst = psDiffuseSourcePrototype[j];
psInst++;
*psInst = psSpecularSourceProt
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -