mirror of
https://github.com/Cesarus85/ringfall-mjolnir-vr.git
synced 2026-10-26 16:00:35 +01:00
794 lines
30 KiB
C++
794 lines
30 KiB
C++
/* January fixed-function register combiners.
|
|
* Adapted from the legacy combiner implementation in RXDK-Libs.
|
|
* Copyright 2026 Team Resurgent. SPDX-License-Identifier: GPL-3.0-or-later
|
|
* Reference commit 29e018674a3443f9df5b5cb4478bb9c54d8a2a3a.
|
|
* Original cachebeta code/PDB controls per-device storage, types and semantics.
|
|
* Valid domain: four texture stages, eight combiner stages, selectors A..D,
|
|
* initialized device and exclusive access to its texture-stage shadow state.
|
|
*/
|
|
#include "combiner_internal.h"
|
|
#pragma code_seg("D3D")
|
|
namespace D3D
|
|
{
|
|
/* Original writable shift table. Its private-data ownership remains unresolved
|
|
* in the extracted target; keep the authentic name rather than an address. */
|
|
static DWORD kelvinCombinerInputShift[4] = { 24, 16, 8, 0 };
|
|
|
|
void WINAPI nvKelvinACSetAlphaInputOne(
|
|
CDevice *pDevice,
|
|
kelvinCombinerInput eInput,
|
|
DWORD dwCombinerStage,
|
|
BOOL bNegate)
|
|
{
|
|
DWORD dwICW = 0;
|
|
dwICW |= bNegate ? PS_INPUTMAPPING_EXPAND_NORMAL : PS_INPUTMAPPING_UNSIGNED_INVERT;
|
|
pDevice->m_AlphaICW[dwCombinerStage] |= dwICW << kelvinCombinerInputShift[eInput];
|
|
return;
|
|
}
|
|
|
|
HRESULT WINAPI nvKelvinACSelectAlphaInput(
|
|
CDevice *pDevice,
|
|
kelvinCombinerInput eInput,
|
|
DWORD dwCombinerStage,
|
|
DWORD dwD3DStage,
|
|
DWORD dwD3DTSSArg,
|
|
BOOL bComplement,
|
|
BOOL bExpandNormal)
|
|
{
|
|
DWORD dwICW = 0;
|
|
switch (D3D__TextureState[dwD3DStage][dwD3DTSSArg] & D3DTA_SELECTMASK)
|
|
{
|
|
case D3DTA_CURRENT:
|
|
if (dwCombinerStage != 0)
|
|
{
|
|
dwICW |= PS_REGISTER_R0;
|
|
break;
|
|
}
|
|
/* Current in stage zero is incoming diffuse. */
|
|
case D3DTA_DIFFUSE:
|
|
dwICW |= PS_REGISTER_V0;
|
|
break;
|
|
case D3DTA_TEXTURE:
|
|
if (pDevice->m_Textures[dwD3DStage] == NULL)
|
|
return TSS_USES_NULL_TEXTURE;
|
|
dwICW |= (PS_REGISTER_T0 + dwD3DStage) & D3DTA_SELECTMASK;
|
|
break;
|
|
case D3DTA_TFACTOR:
|
|
dwICW |= PS_REGISTER_C0;
|
|
break;
|
|
case D3DTA_TEMP:
|
|
dwICW |= PS_REGISTER_R1;
|
|
break;
|
|
case D3DTA_SPECULAR:
|
|
dwICW |= PS_REGISTER_V1;
|
|
pDevice->m_StateFlags |= COMBINER_NEEDS_SPECULAR;
|
|
break;
|
|
default:
|
|
/* Original release behavior outside valid selectors. */
|
|
break;
|
|
}
|
|
dwICW |= PS_CHANNEL_ALPHA;
|
|
bComplement = ((D3D__TextureState[dwD3DStage][dwD3DTSSArg] & D3DTA_COMPLEMENT)
|
|
^ (bComplement ? D3DTA_COMPLEMENT : 0)) ? TRUE : FALSE;
|
|
if (bExpandNormal)
|
|
dwICW |= bComplement ? PS_INPUTMAPPING_EXPAND_NEGATE : PS_INPUTMAPPING_EXPAND_NORMAL;
|
|
else
|
|
dwICW |= bComplement ? PS_INPUTMAPPING_UNSIGNED_INVERT : PS_INPUTMAPPING_UNSIGNED_IDENTITY;
|
|
pDevice->m_AlphaICW[dwCombinerStage] |= dwICW << kelvinCombinerInputShift[eInput];
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinACSelect1(
|
|
CDevice *pDevice,
|
|
DWORD dwHWStage,
|
|
DWORD dwD3DStage)
|
|
{
|
|
HRESULT hr = nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG1, FALSE, FALSE);
|
|
nvKelvinACSetAlphaInputOne(pDevice, kelvinCombinerInputB, dwHWStage, FALSE);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinACSelect2(
|
|
CDevice *pDevice,
|
|
DWORD dwHWStage,
|
|
DWORD dwD3DStage)
|
|
{
|
|
nvKelvinACSetAlphaInputOne(pDevice, kelvinCombinerInputC, dwHWStage, FALSE);
|
|
HRESULT hr = nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputD, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG2, FALSE, FALSE);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinACModulate(
|
|
CDevice *pDevice,
|
|
DWORD dwHWStage,
|
|
DWORD dwD3DStage)
|
|
{
|
|
HRESULT hr = nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG1, FALSE, FALSE);
|
|
hr |= nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputB, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG2, FALSE, FALSE);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinACAdd(
|
|
CDevice *pDevice,
|
|
DWORD dwHWStage,
|
|
DWORD dwD3DStage)
|
|
{
|
|
HRESULT hr = nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG1, FALSE, FALSE);
|
|
nvKelvinACSetAlphaInputOne(pDevice, kelvinCombinerInputB, dwHWStage, FALSE);
|
|
nvKelvinACSetAlphaInputOne(pDevice, kelvinCombinerInputC, dwHWStage, FALSE);
|
|
hr |= nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputD, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG2, FALSE, FALSE);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinACSub(
|
|
CDevice *pDevice,
|
|
DWORD dwHWStage,
|
|
DWORD dwD3DStage)
|
|
{
|
|
HRESULT hr = nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG1, FALSE, FALSE);
|
|
nvKelvinACSetAlphaInputOne(pDevice, kelvinCombinerInputB, dwHWStage, FALSE);
|
|
nvKelvinACSetAlphaInputOne(pDevice, kelvinCombinerInputC, dwHWStage, TRUE);
|
|
hr |= nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputD, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG2, FALSE, FALSE);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinACAddSmooth(
|
|
CDevice *pDevice,
|
|
DWORD dwHWStage,
|
|
DWORD dwD3DStage)
|
|
{
|
|
HRESULT hr = nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG1, FALSE, FALSE);
|
|
nvKelvinACSetAlphaInputOne(pDevice, kelvinCombinerInputB, dwHWStage, FALSE);
|
|
hr |= nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputC, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG1, TRUE, FALSE);
|
|
hr |= nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputD, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG2, FALSE, FALSE);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinACBlendAlpha(
|
|
CDevice *pDevice,
|
|
DWORD dwHWStage,
|
|
DWORD dwD3DStage,
|
|
DWORD dwType)
|
|
{
|
|
HRESULT hr = nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG1, FALSE, FALSE);
|
|
DWORD dwTemp;
|
|
if (dwType == COMBINER_PREMULTIPLIED_TEXTURE)
|
|
{
|
|
nvKelvinACSetAlphaInputOne(pDevice, kelvinCombinerInputB, dwHWStage, FALSE);
|
|
dwType = D3DTA_TEXTURE;
|
|
}
|
|
else
|
|
{
|
|
dwTemp = D3D__TextureState[dwD3DStage][D3DTSS_ALPHAARG2];
|
|
D3D__TextureState[dwD3DStage][D3DTSS_ALPHAARG2] = dwType;
|
|
hr |= nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputB, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG2, FALSE, FALSE);
|
|
D3D__TextureState[dwD3DStage][D3DTSS_ALPHAARG2] = dwTemp;
|
|
}
|
|
dwTemp = D3D__TextureState[dwD3DStage][D3DTSS_ALPHAARG1];
|
|
D3D__TextureState[dwD3DStage][D3DTSS_ALPHAARG1] = dwType;
|
|
hr |= nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputC, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG1, TRUE, FALSE);
|
|
D3D__TextureState[dwD3DStage][D3DTSS_ALPHAARG1] = dwTemp;
|
|
hr |= nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputD, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG2, FALSE, FALSE);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinACPremodulate(
|
|
CDevice *pDevice,
|
|
DWORD dwHWStage,
|
|
DWORD dwD3DStage)
|
|
{
|
|
HRESULT hr;
|
|
if (dwHWStage == 0)
|
|
{
|
|
/* The original reads the next row without checking that it exists.
|
|
* Point-sprite stage remapping can supply texture stage three. Retain
|
|
* a bounded fallback rather than manufacturing that out-of-bounds read.
|
|
* This complete defensive draft is nonexact and receives zero credit. */
|
|
if (dwD3DStage < D3DTSS_MAXSTAGES - 1
|
|
&& D3D__TextureState[dwD3DStage + 1][D3DTSS_ALPHAOP] != D3DTOP_DISABLE)
|
|
{
|
|
hr = nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG1, FALSE, FALSE);
|
|
DWORD dwTemp = D3D__TextureState[dwD3DStage][D3DTSS_ALPHAARG2];
|
|
D3D__TextureState[dwD3DStage][D3DTSS_ALPHAARG2] = D3DTA_TEXTURE;
|
|
hr |= nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputB, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG2, FALSE, FALSE);
|
|
D3D__TextureState[dwD3DStage][D3DTSS_ALPHAARG2] = dwTemp;
|
|
}
|
|
else
|
|
{
|
|
hr = nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG1, FALSE, FALSE);
|
|
nvKelvinACSetAlphaInputOne(pDevice, kelvinCombinerInputB, dwHWStage, FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG1, FALSE, FALSE);
|
|
nvKelvinACSetAlphaInputOne(pDevice, kelvinCombinerInputB, dwHWStage, FALSE);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinACMultiplyAdd(
|
|
CDevice *pDevice,
|
|
int dwHWStage,
|
|
int dwD3DStage)
|
|
{
|
|
HRESULT hr = nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG0, FALSE, FALSE);
|
|
nvKelvinACSetAlphaInputOne(pDevice, kelvinCombinerInputB, dwHWStage, FALSE);
|
|
hr |= nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputC, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG1, FALSE, FALSE);
|
|
hr |= nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputD, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG2, FALSE, FALSE);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinACLerp(
|
|
CDevice *pDevice,
|
|
int dwHWStage,
|
|
int dwD3DStage)
|
|
{
|
|
HRESULT hr = nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG0, FALSE, FALSE);
|
|
hr |= nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputB, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG1, FALSE, FALSE);
|
|
hr |= nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputC, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG0, TRUE, FALSE);
|
|
hr |= nvKelvinACSelectAlphaInput(pDevice, kelvinCombinerInputD, dwHWStage, dwD3DStage, D3DTSS_ALPHAARG2, FALSE, FALSE);
|
|
return hr;
|
|
}
|
|
|
|
void WINAPI nvConstructKelvinOutputAlphaCombiners(
|
|
CDevice *pDevice,
|
|
BOOL bEnable,
|
|
DWORD dwStage,
|
|
DWORD dwD3DStage,
|
|
BOOL bBias,
|
|
DWORD dwShift,
|
|
BOOL bOutTemp)
|
|
{
|
|
/* January does not clear ICW here, unlike the later reference. */
|
|
if (!bEnable || D3D__TextureState[dwD3DStage][D3DTSS_COLOROP] == D3DTOP_DOTPRODUCT3)
|
|
return;
|
|
switch (dwShift)
|
|
{
|
|
case COMBINER_SHIFT_NONE:
|
|
pDevice->m_AlphaOCW[dwStage] |= bBias ? (PS_COMBINEROUTPUT_BIAS << 12) : (PS_COMBINEROUTPUT_IDENTITY << 12);
|
|
break;
|
|
case COMBINER_SHIFT_ONE:
|
|
pDevice->m_AlphaOCW[dwStage] |= bBias ? (PS_COMBINEROUTPUT_SHIFTLEFT_1_BIAS << 12) : (PS_COMBINEROUTPUT_SHIFTLEFT_1 << 12);
|
|
break;
|
|
case COMBINER_SHIFT_TWO:
|
|
pDevice->m_AlphaOCW[dwStage] |= bBias ? (PS_COMBINEROUTPUT_SHIFTLEFT_1_BIAS << 12) : (PS_COMBINEROUTPUT_SHIFTLEFT_2 << 12);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
pDevice->m_AlphaOCW[dwStage] |= PS_REGISTER_R0 << 8;
|
|
pDevice->m_AlphaOCW[dwStage] |= bOutTemp ? (PS_REGISTER_R1 << 8) : (PS_REGISTER_R0 << 8);
|
|
return;
|
|
}
|
|
|
|
void WINAPI ConstructAlphaCombiners(
|
|
CDevice *pDevice,
|
|
DWORD dwHWStage,
|
|
DWORD dwD3DStage,
|
|
BOOL bStageActive)
|
|
{
|
|
DWORD dwShift = 0;
|
|
BOOL bBias = FALSE;
|
|
BOOL bEnable = TRUE;
|
|
HRESULT hr = S_OK;
|
|
pDevice->m_AlphaICW[dwHWStage] = 0;
|
|
pDevice->m_AlphaOCW[dwHWStage] = 0;
|
|
if (!bStageActive)
|
|
{
|
|
if (dwHWStage == 0)
|
|
{
|
|
pDevice->m_AlphaICW[dwHWStage] |= (PS_REGISTER_V0 | PS_CHANNEL_ALPHA) << 24;
|
|
nvKelvinACSetAlphaInputOne(pDevice, kelvinCombinerInputB, dwHWStage, FALSE);
|
|
}
|
|
else
|
|
bEnable = FALSE;
|
|
}
|
|
else
|
|
{
|
|
switch (D3D__TextureState[dwD3DStage][D3DTSS_ALPHAOP])
|
|
{
|
|
default:
|
|
case D3DTOP_DOTPRODUCT3:
|
|
case D3DTOP_DISABLE:
|
|
if (dwHWStage == 0)
|
|
{
|
|
pDevice->m_AlphaICW[dwHWStage] |= (PS_REGISTER_V0 | PS_CHANNEL_ALPHA) << 24;
|
|
nvKelvinACSetAlphaInputOne(pDevice, kelvinCombinerInputB, dwHWStage, FALSE);
|
|
}
|
|
else
|
|
bEnable = FALSE;
|
|
break;
|
|
case D3DTOP_SELECTARG1:
|
|
hr = nvKelvinACSelect1(pDevice, dwHWStage, dwD3DStage);
|
|
break;
|
|
case D3DTOP_SELECTARG2:
|
|
hr = nvKelvinACSelect2(pDevice, dwHWStage, dwD3DStage);
|
|
break;
|
|
case D3DTOP_MODULATE4X:
|
|
dwShift++;
|
|
/* Each fallthrough adds one scaling bit. */
|
|
case D3DTOP_MODULATE2X:
|
|
dwShift++;
|
|
case D3DTOP_MODULATE:
|
|
hr = nvKelvinACModulate(pDevice, dwHWStage, dwD3DStage);
|
|
break;
|
|
case D3DTOP_ADDSIGNED2X:
|
|
dwShift = 1;
|
|
case D3DTOP_ADDSIGNED:
|
|
bBias = TRUE;
|
|
case D3DTOP_ADD:
|
|
hr = nvKelvinACAdd(pDevice, dwHWStage, dwD3DStage);
|
|
break;
|
|
case D3DTOP_SUBTRACT:
|
|
hr = nvKelvinACSub(pDevice, dwHWStage, dwD3DStage);
|
|
break;
|
|
case D3DTOP_ADDSMOOTH:
|
|
hr = nvKelvinACAddSmooth(pDevice, dwHWStage, dwD3DStage);
|
|
break;
|
|
case D3DTOP_BLENDDIFFUSEALPHA:
|
|
hr = nvKelvinACBlendAlpha(pDevice, dwHWStage, dwD3DStage, D3DTA_DIFFUSE);
|
|
break;
|
|
case D3DTOP_BLENDTEXTUREALPHA:
|
|
hr = nvKelvinACBlendAlpha(pDevice, dwHWStage, dwD3DStage, D3DTA_TEXTURE);
|
|
break;
|
|
case D3DTOP_BLENDFACTORALPHA:
|
|
hr = nvKelvinACBlendAlpha(pDevice, dwHWStage, dwD3DStage, D3DTA_TFACTOR);
|
|
break;
|
|
case D3DTOP_BLENDTEXTUREALPHAPM:
|
|
hr = nvKelvinACBlendAlpha(pDevice, dwHWStage, dwD3DStage, COMBINER_PREMULTIPLIED_TEXTURE);
|
|
break;
|
|
case D3DTOP_BLENDCURRENTALPHA:
|
|
hr = nvKelvinACBlendAlpha(pDevice, dwHWStage, dwD3DStage, D3DTA_CURRENT);
|
|
break;
|
|
case D3DTOP_PREMODULATE:
|
|
hr = nvKelvinACPremodulate(pDevice, dwHWStage, dwD3DStage);
|
|
break;
|
|
case D3DTOP_MULTIPLYADD:
|
|
hr = nvKelvinACMultiplyAdd(pDevice, dwHWStage, dwD3DStage);
|
|
break;
|
|
case D3DTOP_LERP:
|
|
hr = nvKelvinACLerp(pDevice, dwHWStage, dwD3DStage);
|
|
break;
|
|
}
|
|
}
|
|
if (hr == TSS_USES_NULL_TEXTURE)
|
|
{
|
|
if (dwHWStage == 0)
|
|
pDevice->m_AlphaICW[dwHWStage] = (PS_REGISTER_V0 | PS_CHANNEL_ALPHA) << 24;
|
|
else
|
|
pDevice->m_AlphaICW[dwHWStage] = (PS_REGISTER_R0 | PS_CHANNEL_ALPHA) << 24;
|
|
nvKelvinACSetAlphaInputOne(pDevice, kelvinCombinerInputB, dwHWStage, FALSE);
|
|
}
|
|
nvConstructKelvinOutputAlphaCombiners(pDevice, bEnable, dwHWStage, dwD3DStage, bBias, dwShift,
|
|
D3D__TextureState[dwD3DStage][D3DTSS_RESULTARG] == D3DTA_TEMP);
|
|
return;
|
|
}
|
|
|
|
void WINAPI nvKelvinCCSetColorInputOne(
|
|
CDevice *pDevice,
|
|
kelvinCombinerInput eInput,
|
|
DWORD dwCombinerStage,
|
|
BOOL bNegate)
|
|
{
|
|
DWORD dwICW = 0;
|
|
dwICW |= bNegate ? PS_INPUTMAPPING_EXPAND_NORMAL : PS_INPUTMAPPING_UNSIGNED_INVERT;
|
|
pDevice->m_ColorICW[dwCombinerStage] |= dwICW << kelvinCombinerInputShift[eInput];
|
|
return;
|
|
}
|
|
|
|
HRESULT WINAPI nvKelvinCCSelectColorInput(
|
|
CDevice *pDevice,
|
|
kelvinCombinerInput eInput,
|
|
DWORD dwCombinerStage,
|
|
DWORD dwD3DStage,
|
|
DWORD dwD3DTSSArg,
|
|
BOOL bComplement,
|
|
BOOL bExpandNormal,
|
|
BOOL bAlphaReplicate)
|
|
{
|
|
DWORD dwICW = 0;
|
|
switch (D3D__TextureState[dwD3DStage][dwD3DTSSArg] & D3DTA_SELECTMASK)
|
|
{
|
|
case D3DTA_CURRENT:
|
|
if (dwCombinerStage != 0)
|
|
{
|
|
dwICW |= PS_REGISTER_R0;
|
|
break;
|
|
}
|
|
/* Current in stage zero is incoming diffuse. */
|
|
case D3DTA_DIFFUSE:
|
|
dwICW |= PS_REGISTER_V0;
|
|
break;
|
|
case D3DTA_TEXTURE:
|
|
if (pDevice->m_Textures[dwD3DStage] == NULL)
|
|
return TSS_USES_NULL_TEXTURE;
|
|
dwICW |= (PS_REGISTER_T0 + dwD3DStage) & D3DTA_SELECTMASK;
|
|
break;
|
|
case D3DTA_TFACTOR:
|
|
dwICW |= PS_REGISTER_C0;
|
|
break;
|
|
case D3DTA_SPECULAR:
|
|
dwICW |= PS_REGISTER_V1;
|
|
pDevice->m_StateFlags |= COMBINER_NEEDS_SPECULAR;
|
|
break;
|
|
case D3DTA_TEMP:
|
|
dwICW |= PS_REGISTER_R1;
|
|
break;
|
|
default:
|
|
/* Original release behavior outside valid selectors. */
|
|
break;
|
|
}
|
|
bAlphaReplicate |= D3D__TextureState[dwD3DStage][dwD3DTSSArg] & D3DTA_ALPHAREPLICATE;
|
|
dwICW |= bAlphaReplicate ? PS_CHANNEL_ALPHA : PS_CHANNEL_RGB;
|
|
bComplement = ((D3D__TextureState[dwD3DStage][dwD3DTSSArg] & D3DTA_COMPLEMENT)
|
|
^ (bComplement ? D3DTA_COMPLEMENT : 0)) ? TRUE : FALSE;
|
|
if (bExpandNormal)
|
|
dwICW |= bComplement ? PS_INPUTMAPPING_EXPAND_NEGATE : PS_INPUTMAPPING_EXPAND_NORMAL;
|
|
else
|
|
dwICW |= bComplement ? PS_INPUTMAPPING_UNSIGNED_INVERT : PS_INPUTMAPPING_UNSIGNED_IDENTITY;
|
|
pDevice->m_ColorICW[dwCombinerStage] |= dwICW << kelvinCombinerInputShift[eInput];
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinCCSelect1(
|
|
CDevice *pDevice,
|
|
DWORD dwHWStage,
|
|
DWORD dwD3DStage)
|
|
{
|
|
HRESULT hr = nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_COLORARG1, FALSE, FALSE, FALSE);
|
|
nvKelvinCCSetColorInputOne(pDevice, kelvinCombinerInputB, dwHWStage, FALSE);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinCCSelect2(
|
|
CDevice *pDevice,
|
|
DWORD dwHWStage,
|
|
DWORD dwD3DStage)
|
|
{
|
|
nvKelvinCCSetColorInputOne(pDevice, kelvinCombinerInputC, dwHWStage, FALSE);
|
|
HRESULT hr = nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputD, dwHWStage, dwD3DStage, D3DTSS_COLORARG2, FALSE, FALSE, FALSE);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinCCModulate(
|
|
CDevice *pDevice,
|
|
DWORD dwHWStage,
|
|
DWORD dwD3DStage)
|
|
{
|
|
HRESULT hr = nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_COLORARG1, FALSE, FALSE, FALSE);
|
|
hr |= nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputB, dwHWStage, dwD3DStage, D3DTSS_COLORARG2, FALSE, FALSE, FALSE);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinCCAdd(
|
|
CDevice *pDevice,
|
|
DWORD dwHWStage,
|
|
DWORD dwD3DStage)
|
|
{
|
|
HRESULT hr = nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_COLORARG1, FALSE, FALSE, FALSE);
|
|
nvKelvinCCSetColorInputOne(pDevice, kelvinCombinerInputB, dwHWStage, FALSE);
|
|
nvKelvinCCSetColorInputOne(pDevice, kelvinCombinerInputC, dwHWStage, FALSE);
|
|
hr |= nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputD, dwHWStage, dwD3DStage, D3DTSS_COLORARG2, FALSE, FALSE, FALSE);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinCCSub(
|
|
CDevice *pDevice,
|
|
DWORD dwHWStage,
|
|
DWORD dwD3DStage)
|
|
{
|
|
HRESULT hr = nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_COLORARG1, FALSE, FALSE, FALSE);
|
|
nvKelvinCCSetColorInputOne(pDevice, kelvinCombinerInputB, dwHWStage, FALSE);
|
|
nvKelvinCCSetColorInputOne(pDevice, kelvinCombinerInputC, dwHWStage, TRUE);
|
|
hr |= nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputD, dwHWStage, dwD3DStage, D3DTSS_COLORARG2, FALSE, FALSE, FALSE);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinCCAddSmooth(
|
|
CDevice *pDevice,
|
|
DWORD dwHWStage,
|
|
DWORD dwD3DStage)
|
|
{
|
|
HRESULT hr = nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_COLORARG1, FALSE, FALSE, FALSE);
|
|
nvKelvinCCSetColorInputOne(pDevice, kelvinCombinerInputB, dwHWStage, FALSE);
|
|
hr |= nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputC, dwHWStage, dwD3DStage, D3DTSS_COLORARG1, TRUE, FALSE, FALSE);
|
|
hr |= nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputD, dwHWStage, dwD3DStage, D3DTSS_COLORARG2, FALSE, FALSE, FALSE);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinCCBlendAlpha(
|
|
CDevice *pDevice,
|
|
DWORD dwHWStage,
|
|
DWORD dwD3DStage,
|
|
DWORD dwType)
|
|
{
|
|
HRESULT hr = nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_COLORARG1, FALSE, FALSE, FALSE);
|
|
DWORD dwTemp;
|
|
if (dwType == COMBINER_PREMULTIPLIED_TEXTURE)
|
|
{
|
|
nvKelvinCCSetColorInputOne(pDevice, kelvinCombinerInputB, dwHWStage, FALSE);
|
|
dwType = D3DTA_TEXTURE;
|
|
}
|
|
else
|
|
{
|
|
dwTemp = D3D__TextureState[dwD3DStage][D3DTSS_COLORARG2];
|
|
D3D__TextureState[dwD3DStage][D3DTSS_COLORARG2] = dwType;
|
|
hr |= nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputB, dwHWStage, dwD3DStage, D3DTSS_COLORARG2, FALSE, FALSE, TRUE);
|
|
D3D__TextureState[dwD3DStage][D3DTSS_COLORARG2] = dwTemp;
|
|
}
|
|
dwTemp = D3D__TextureState[dwD3DStage][D3DTSS_COLORARG1];
|
|
D3D__TextureState[dwD3DStage][D3DTSS_COLORARG1] = dwType;
|
|
hr |= nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputC, dwHWStage, dwD3DStage, D3DTSS_COLORARG1, TRUE, FALSE, TRUE);
|
|
D3D__TextureState[dwD3DStage][D3DTSS_COLORARG1] = dwTemp;
|
|
hr |= nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputD, dwHWStage, dwD3DStage, D3DTSS_COLORARG2, FALSE, FALSE, FALSE);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinCCPremodulate(
|
|
CDevice *pDevice,
|
|
DWORD dwHWStage,
|
|
DWORD dwD3DStage)
|
|
{
|
|
HRESULT hr;
|
|
if (dwHWStage == 0)
|
|
{
|
|
/* Color premodulation tests the fixed second texture row in January. */
|
|
if (D3D__TextureState[1][D3DTSS_COLOROP] != D3DTOP_DISABLE)
|
|
{
|
|
hr = nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_COLORARG1, FALSE, FALSE, FALSE);
|
|
DWORD dwTemp = D3D__TextureState[dwD3DStage][D3DTSS_COLORARG2];
|
|
D3D__TextureState[dwD3DStage][D3DTSS_COLORARG2] = D3DTA_TEXTURE;
|
|
hr |= nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputB, dwHWStage, dwD3DStage, D3DTSS_COLORARG2, FALSE, FALSE, FALSE);
|
|
D3D__TextureState[dwD3DStage][D3DTSS_COLORARG2] = dwTemp;
|
|
}
|
|
else
|
|
{
|
|
hr = nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_COLORARG1, FALSE, FALSE, FALSE);
|
|
nvKelvinCCSetColorInputOne(pDevice, kelvinCombinerInputB, dwHWStage, FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_COLORARG1, FALSE, FALSE, FALSE);
|
|
nvKelvinCCSetColorInputOne(pDevice, kelvinCombinerInputB, dwHWStage, FALSE);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinCCModulateAlpha(
|
|
CDevice *pDevice,
|
|
DWORD dwHWStage,
|
|
DWORD dwD3DStage,
|
|
BOOL bComplement)
|
|
{
|
|
HRESULT hr = nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_COLORARG1, FALSE, FALSE, FALSE);
|
|
nvKelvinCCSetColorInputOne(pDevice, kelvinCombinerInputB, dwHWStage, FALSE);
|
|
hr |= nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputC, dwHWStage, dwD3DStage, D3DTSS_COLORARG1, bComplement, FALSE, TRUE);
|
|
hr |= nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputD, dwHWStage, dwD3DStage, D3DTSS_COLORARG2, FALSE, FALSE, FALSE);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinCCModulateColor(
|
|
CDevice *pDevice,
|
|
DWORD dwHWStage,
|
|
DWORD dwD3DStage,
|
|
BOOL bComplement)
|
|
{
|
|
HRESULT hr = nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_COLORARG1, bComplement, FALSE, FALSE);
|
|
hr |= nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputB, dwHWStage, dwD3DStage, D3DTSS_COLORARG2, FALSE, FALSE, FALSE);
|
|
hr |= nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputC, dwHWStage, dwD3DStage, D3DTSS_COLORARG1, FALSE, FALSE, TRUE);
|
|
nvKelvinCCSetColorInputOne(pDevice, kelvinCombinerInputD, dwHWStage, FALSE);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinBumpMap(
|
|
CDevice *pDevice,
|
|
DWORD dwHWStage,
|
|
DWORD dwD3DStage)
|
|
{
|
|
HRESULT hr;
|
|
if (pDevice->m_Textures[dwD3DStage] == NULL)
|
|
hr = TSS_USES_NULL_TEXTURE;
|
|
else
|
|
{
|
|
DWORD dwArg1Cache = D3D__TextureState[dwD3DStage][D3DTSS_COLORARG1];
|
|
D3D__TextureState[dwD3DStage][D3DTSS_COLORARG1] = D3DTA_CURRENT;
|
|
hr = nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_COLORARG1, FALSE, FALSE, FALSE);
|
|
D3D__TextureState[dwD3DStage][D3DTSS_COLORARG1] = dwArg1Cache;
|
|
nvKelvinCCSetColorInputOne(pDevice, kelvinCombinerInputB, dwHWStage, FALSE);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinCCDotProduct(
|
|
CDevice *pDevice,
|
|
DWORD dwHWStage,
|
|
DWORD dwD3DStage)
|
|
{
|
|
HRESULT hr = nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_COLORARG1, FALSE, TRUE, FALSE);
|
|
hr |= nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputB, dwHWStage, dwD3DStage, D3DTSS_COLORARG2, FALSE, TRUE, FALSE);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinCCMultiplyAdd(
|
|
CDevice *pDevice,
|
|
int dwHWStage,
|
|
int dwD3DStage)
|
|
{
|
|
HRESULT hr = nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_COLORARG0, FALSE, FALSE, FALSE);
|
|
nvKelvinCCSetColorInputOne(pDevice, kelvinCombinerInputB, dwHWStage, FALSE);
|
|
hr |= nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputC, dwHWStage, dwD3DStage, D3DTSS_COLORARG1, FALSE, FALSE, FALSE);
|
|
hr |= nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputD, dwHWStage, dwD3DStage, D3DTSS_COLORARG2, FALSE, FALSE, FALSE);
|
|
return hr;
|
|
}
|
|
|
|
static HRESULT WINAPI nvKelvinCCLerp(
|
|
CDevice *pDevice,
|
|
int dwHWStage,
|
|
int dwD3DStage)
|
|
{
|
|
HRESULT hr = nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputA, dwHWStage, dwD3DStage, D3DTSS_COLORARG0, FALSE, FALSE, FALSE);
|
|
hr |= nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputB, dwHWStage, dwD3DStage, D3DTSS_COLORARG1, FALSE, FALSE, FALSE);
|
|
hr |= nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputC, dwHWStage, dwD3DStage, D3DTSS_COLORARG0, TRUE, FALSE, FALSE);
|
|
hr |= nvKelvinCCSelectColorInput(pDevice, kelvinCombinerInputD, dwHWStage, dwD3DStage, D3DTSS_COLORARG2, FALSE, FALSE, FALSE);
|
|
return hr;
|
|
}
|
|
|
|
void WINAPI nvConstructKelvinOutputColorCombiners(
|
|
CDevice *pDevice,
|
|
BOOL bEnable,
|
|
DWORD dwStage,
|
|
BOOL bBias,
|
|
DWORD dwShift,
|
|
BOOL bDotAB,
|
|
BOOL bDotCD,
|
|
BOOL bOutTemp)
|
|
{
|
|
if (!bEnable)
|
|
return;
|
|
switch (dwShift)
|
|
{
|
|
case COMBINER_SHIFT_NONE:
|
|
pDevice->m_ColorOCW[dwStage] |= bBias ? (PS_COMBINEROUTPUT_BIAS << 12) : (PS_COMBINEROUTPUT_IDENTITY << 12);
|
|
break;
|
|
case COMBINER_SHIFT_ONE:
|
|
pDevice->m_ColorOCW[dwStage] |= bBias ? (PS_COMBINEROUTPUT_SHIFTLEFT_1_BIAS << 12) : (PS_COMBINEROUTPUT_SHIFTLEFT_1 << 12);
|
|
break;
|
|
case COMBINER_SHIFT_TWO:
|
|
pDevice->m_ColorOCW[dwStage] |= bBias ? (PS_COMBINEROUTPUT_SHIFTLEFT_1_BIAS << 12) : (PS_COMBINEROUTPUT_SHIFTLEFT_2 << 12);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (bDotAB && bDotCD)
|
|
{
|
|
pDevice->m_ColorOCW[dwStage] |= (PS_COMBINEROUTPUT_AB_DOT_PRODUCT | PS_COMBINEROUTPUT_CD_DOT_PRODUCT
|
|
| PS_COMBINEROUTPUT_AB_BLUE_TO_ALPHA | PS_COMBINEROUTPUT_CD_BLUE_TO_ALPHA) << 12;
|
|
pDevice->m_ColorOCW[dwStage] |= bOutTemp ? (PS_REGISTER_R1 << 8) : (PS_REGISTER_R0 << 8);
|
|
}
|
|
else if (bDotAB)
|
|
{
|
|
pDevice->m_ColorOCW[dwStage] |= (PS_COMBINEROUTPUT_AB_DOT_PRODUCT | PS_COMBINEROUTPUT_AB_BLUE_TO_ALPHA) << 12;
|
|
pDevice->m_ColorOCW[dwStage] |= bOutTemp ? (PS_REGISTER_R1 << 4) : (PS_REGISTER_R0 << 4);
|
|
}
|
|
else
|
|
pDevice->m_ColorOCW[dwStage] |= bOutTemp ? (PS_REGISTER_R1 << 8) : (PS_REGISTER_R0 << 8);
|
|
return;
|
|
}
|
|
|
|
BOOL WINAPI ConstructColorCombiners(
|
|
CDevice *pDevice,
|
|
DWORD dwHWStage,
|
|
DWORD dwD3DStage)
|
|
{
|
|
BOOL bEnable = TRUE;
|
|
BOOL bStageActive = TRUE;
|
|
BOOL bDotProduct = FALSE;
|
|
BOOL bBias = FALSE;
|
|
DWORD dwShift = 0;
|
|
HRESULT hr = S_OK;
|
|
pDevice->m_ColorICW[dwHWStage] = 0;
|
|
pDevice->m_ColorOCW[dwHWStage] = 0;
|
|
switch (D3D__TextureState[dwD3DStage][D3DTSS_COLOROP])
|
|
{
|
|
default:
|
|
case D3DTOP_DISABLE:
|
|
if (dwHWStage == 0)
|
|
{
|
|
pDevice->m_ColorICW[dwHWStage] |= (PS_REGISTER_V0) << 24;
|
|
nvKelvinCCSetColorInputOne(pDevice, kelvinCombinerInputB, dwHWStage, FALSE);
|
|
}
|
|
else
|
|
bEnable = FALSE;
|
|
bStageActive = FALSE;
|
|
break;
|
|
case D3DTOP_SELECTARG1:
|
|
hr = nvKelvinCCSelect1(pDevice, dwHWStage, dwD3DStage);
|
|
break;
|
|
case D3DTOP_SELECTARG2:
|
|
hr = nvKelvinCCSelect2(pDevice, dwHWStage, dwD3DStage);
|
|
break;
|
|
case D3DTOP_MODULATE4X:
|
|
dwShift++;
|
|
/* Each fallthrough adds one scaling bit. */
|
|
case D3DTOP_MODULATE2X:
|
|
dwShift++;
|
|
case D3DTOP_MODULATE:
|
|
hr = nvKelvinCCModulate(pDevice, dwHWStage, dwD3DStage);
|
|
break;
|
|
case D3DTOP_ADDSIGNED2X:
|
|
dwShift = 1;
|
|
case D3DTOP_ADDSIGNED:
|
|
bBias = TRUE;
|
|
case D3DTOP_ADD:
|
|
hr = nvKelvinCCAdd(pDevice, dwHWStage, dwD3DStage);
|
|
break;
|
|
case D3DTOP_SUBTRACT:
|
|
hr = nvKelvinCCSub(pDevice, dwHWStage, dwD3DStage);
|
|
break;
|
|
case D3DTOP_ADDSMOOTH:
|
|
hr = nvKelvinCCAddSmooth(pDevice, dwHWStage, dwD3DStage);
|
|
break;
|
|
case D3DTOP_BLENDDIFFUSEALPHA:
|
|
hr = nvKelvinCCBlendAlpha(pDevice, dwHWStage, dwD3DStage, D3DTA_DIFFUSE);
|
|
break;
|
|
case D3DTOP_BLENDTEXTUREALPHA:
|
|
hr = nvKelvinCCBlendAlpha(pDevice, dwHWStage, dwD3DStage, D3DTA_TEXTURE);
|
|
break;
|
|
case D3DTOP_BLENDFACTORALPHA:
|
|
hr = nvKelvinCCBlendAlpha(pDevice, dwHWStage, dwD3DStage, D3DTA_TFACTOR);
|
|
break;
|
|
case D3DTOP_BLENDTEXTUREALPHAPM:
|
|
hr = nvKelvinCCBlendAlpha(pDevice, dwHWStage, dwD3DStage, COMBINER_PREMULTIPLIED_TEXTURE);
|
|
break;
|
|
case D3DTOP_BLENDCURRENTALPHA:
|
|
hr = nvKelvinCCBlendAlpha(pDevice, dwHWStage, dwD3DStage, D3DTA_CURRENT);
|
|
break;
|
|
case D3DTOP_PREMODULATE:
|
|
hr = nvKelvinCCPremodulate(pDevice, dwHWStage, dwD3DStage);
|
|
break;
|
|
case D3DTOP_MODULATEALPHA_ADDCOLOR:
|
|
hr = nvKelvinCCModulateAlpha(pDevice, dwHWStage, dwD3DStage, FALSE);
|
|
break;
|
|
case D3DTOP_MODULATECOLOR_ADDALPHA:
|
|
hr = nvKelvinCCModulateColor(pDevice, dwHWStage, dwD3DStage, FALSE);
|
|
break;
|
|
case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
|
|
hr = nvKelvinCCModulateAlpha(pDevice, dwHWStage, dwD3DStage, TRUE);
|
|
break;
|
|
case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
|
|
hr = nvKelvinCCModulateColor(pDevice, dwHWStage, dwD3DStage, TRUE);
|
|
break;
|
|
case D3DTOP_BUMPENVMAP:
|
|
case D3DTOP_BUMPENVMAPLUMINANCE:
|
|
hr = nvKelvinBumpMap(pDevice, dwHWStage, dwD3DStage);
|
|
break;
|
|
case D3DTOP_DOTPRODUCT3:
|
|
hr = nvKelvinCCDotProduct(pDevice, dwHWStage, dwD3DStage);
|
|
bDotProduct = TRUE;
|
|
break;
|
|
case D3DTOP_MULTIPLYADD:
|
|
hr = nvKelvinCCMultiplyAdd(pDevice, dwHWStage, dwD3DStage);
|
|
break;
|
|
case D3DTOP_LERP:
|
|
hr = nvKelvinCCLerp(pDevice, dwHWStage, dwD3DStage);
|
|
break;
|
|
}
|
|
if (hr == TSS_USES_NULL_TEXTURE)
|
|
{
|
|
if (dwHWStage == 0)
|
|
pDevice->m_ColorICW[dwHWStage] = (PS_REGISTER_V0) << 24;
|
|
else
|
|
pDevice->m_ColorICW[dwHWStage] = (PS_REGISTER_R0) << 24;
|
|
nvKelvinCCSetColorInputOne(pDevice, kelvinCombinerInputB, dwHWStage, FALSE);
|
|
}
|
|
nvConstructKelvinOutputColorCombiners(pDevice, bEnable, dwHWStage, bBias, dwShift,
|
|
bDotProduct, FALSE, D3D__TextureState[dwD3DStage][D3DTSS_RESULTARG] == D3DTA_TEMP);
|
|
return bStageActive;
|
|
}
|
|
|
|
}
|