Refactor getting host D3DFORMAT, use it for COLORSIGN, and add signed-to-unsigned mapping
This commit is contained in:
parent
734eeff548
commit
f4ba149c0d
|
@ -253,14 +253,23 @@ static bool alphakill[4] = ALPHAKILL;
|
||||||
|
|
||||||
static const float4 WarningColor = float4(0, 1, 1, 1); // Returned when unhandled scenario is encountered
|
static const float4 WarningColor = float4(0, 1, 1, 1); // Returned when unhandled scenario is encountered
|
||||||
|
|
||||||
|
#define unsigned_to_signed(x) (((x) * 2) - 1) // Shifts range from [0..1] to [-1..1] (just like s_bx2)
|
||||||
|
#define signed_to_unsigned(x) (((x) + 1) / 2) // Shifts range from [-1..1] to [0..1]
|
||||||
|
|
||||||
float4 PerformColorSign(const float4 ColorSign, float4 t)
|
float4 PerformColorSign(const float4 ColorSign, float4 t)
|
||||||
{
|
{
|
||||||
// Per color channel, optionally convert the value range into two's complement signed values (from (0, +1) to (-1, +1), using s_bx2):
|
// Per color channel, based on the ColorSign setting :
|
||||||
// This is often used for bumpmaps
|
// either keep the value range as-is (when ColorSign is zero)
|
||||||
if (ColorSign.r > 0) t.r = s_bx2(t.r);
|
// or convert from [0..1] to [-1..+1] (when ColorSign is more than zero, often used for bumpmaps),
|
||||||
if (ColorSign.g > 0) t.g = s_bx2(t.g);
|
// or convert from [-1..1] to [0..1] (when ColorSign is less than zero):
|
||||||
if (ColorSign.b > 0) t.b = s_bx2(t.b);
|
if (ColorSign.r > 0) t.r = unsigned_to_signed(t.r);
|
||||||
if (ColorSign.a > 0) t.a = s_bx2(t.a);
|
if (ColorSign.g > 0) t.g = unsigned_to_signed(t.g);
|
||||||
|
if (ColorSign.b > 0) t.b = unsigned_to_signed(t.b);
|
||||||
|
if (ColorSign.a > 0) t.a = unsigned_to_signed(t.a);
|
||||||
|
if (ColorSign.r < 0) t.r = signed_to_unsigned(t.r);
|
||||||
|
if (ColorSign.g < 0) t.g = signed_to_unsigned(t.g);
|
||||||
|
if (ColorSign.b < 0) t.b = signed_to_unsigned(t.b);
|
||||||
|
if (ColorSign.a < 0) t.a = signed_to_unsigned(t.a);
|
||||||
// TODO : Instead of the above, create a mirror texture with a host format that has identical component layout, but with all components signed.
|
// TODO : Instead of the above, create a mirror texture with a host format that has identical component layout, but with all components signed.
|
||||||
// Then, in here, when any component has to be read as signed, sample the signed texture (ouch : with what dimension and coordinate?!)
|
// Then, in here, when any component has to be read as signed, sample the signed texture (ouch : with what dimension and coordinate?!)
|
||||||
// and replace the components that we read from the unsigned texture, but which have to be signed, with the signed components read from the signed mirror texture.
|
// and replace the components that we read from the unsigned texture, but which have to be signed, with the signed components read from the signed mirror texture.
|
||||||
|
|
|
@ -184,6 +184,7 @@ static xbox::PVOID g_pXbox_Palette_Data[xbox::X_D3DTS_STAGECOU
|
||||||
static unsigned g_Xbox_Palette_Size[xbox::X_D3DTS_STAGECOUNT] = { 0 }; // cached palette size
|
static unsigned g_Xbox_Palette_Size[xbox::X_D3DTS_STAGECOUNT] = { 0 }; // cached palette size
|
||||||
|
|
||||||
|
|
||||||
|
D3DFORMAT g_HostTextureFormats[xbox::X_D3DTS_STAGECOUNT]; // Updated by CxbxUpdateHostTextures(), read by CxbxCalcColorSign
|
||||||
xbox::X_D3DBaseTexture *g_pXbox_SetTexture[xbox::X_D3DTS_STAGECOUNT] = {0,0,0,0}; // Set by our D3DDevice_SetTexture and D3DDevice_SwitchTexture patches
|
xbox::X_D3DBaseTexture *g_pXbox_SetTexture[xbox::X_D3DTS_STAGECOUNT] = {0,0,0,0}; // Set by our D3DDevice_SetTexture and D3DDevice_SwitchTexture patches
|
||||||
static xbox::X_D3DBaseTexture CxbxActiveTextureCopies[xbox::X_D3DTS_STAGECOUNT] = {}; // Set by D3DDevice_SwitchTexture. Cached active texture
|
static xbox::X_D3DBaseTexture CxbxActiveTextureCopies[xbox::X_D3DTS_STAGECOUNT] = {}; // Set by D3DDevice_SwitchTexture. Cached active texture
|
||||||
|
|
||||||
|
@ -905,8 +906,13 @@ void *GetDataFromXboxResource(xbox::X_D3DResource *pXboxResource)
|
||||||
return (uint8_t*)pData;
|
return (uint8_t*)pData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD D3DUSAGE_INVALID = -1;
|
||||||
|
|
||||||
typedef struct _resource_info_t {
|
typedef struct _resource_info_t {
|
||||||
|
|
||||||
ComPtr<IDirect3DResource> pHostResource;
|
ComPtr<IDirect3DResource> pHostResource;
|
||||||
|
D3DFORMAT HostFormat = D3DFMT_UNKNOWN;
|
||||||
|
DWORD HostUsage = D3DUSAGE_INVALID;
|
||||||
DWORD dwXboxResourceType = 0;
|
DWORD dwXboxResourceType = 0;
|
||||||
void* pXboxData = xbox::zeroptr;
|
void* pXboxData = xbox::zeroptr;
|
||||||
size_t szXboxDataSize = 0;
|
size_t szXboxDataSize = 0;
|
||||||
|
@ -1149,6 +1155,42 @@ void SetHostResource(xbox::X_D3DResource* pXboxResource, IDirect3DResource* pHos
|
||||||
resourceInfo.lastUpdate = std::chrono::steady_clock::now();
|
resourceInfo.lastUpdate = std::chrono::steady_clock::now();
|
||||||
resourceInfo.nextHashTime = resourceInfo.lastUpdate + resourceInfo.hashLifeTime;
|
resourceInfo.nextHashTime = resourceInfo.lastUpdate + resourceInfo.hashLifeTime;
|
||||||
resourceInfo.forceRehash = false;
|
resourceInfo.forceRehash = false;
|
||||||
|
|
||||||
|
HRESULT hRet = STATUS_INVALID_PARAMETER; // Default to an error condition, so we can use D3D_OK to check for success
|
||||||
|
D3DSURFACE_DESC surfaceDesc;
|
||||||
|
D3DVOLUME_DESC volumeDesc;
|
||||||
|
UINT Level = 0; // TODO : When should Level every be something other than zero, and if so : what other value?
|
||||||
|
switch (resourceInfo.dwXboxResourceType) {// TODO : Better check pHostResource class type
|
||||||
|
case xbox::X_D3DRTYPE_SURFACE:
|
||||||
|
hRet = ((IDirect3DSurface*)pHostResource)->GetDesc(&surfaceDesc);
|
||||||
|
break;
|
||||||
|
case xbox::X_D3DRTYPE_TEXTURE:
|
||||||
|
hRet = ((IDirect3DTexture*)pHostResource)->GetLevelDesc(Level, &surfaceDesc);
|
||||||
|
break;
|
||||||
|
case xbox::X_D3DRTYPE_VOLUMETEXTURE: {
|
||||||
|
hRet = ((IDirect3DVolumeTexture*)pHostResource)->GetLevelDesc(Level, &volumeDesc);
|
||||||
|
break; }
|
||||||
|
case xbox::X_D3DRTYPE_CUBETEXTURE:
|
||||||
|
hRet = ((IDirect3DCubeTexture*)pHostResource)->GetLevelDesc(Level, &surfaceDesc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3DFORMAT hostFormat = D3DFMT_UNKNOWN;
|
||||||
|
DWORD hostUsage = D3DUSAGE_INVALID;
|
||||||
|
|
||||||
|
if (SUCCEEDED(hRet)) {
|
||||||
|
if (resourceInfo.dwXboxResourceType == xbox::X_D3DRTYPE_VOLUMETEXTURE) {
|
||||||
|
hostFormat = volumeDesc.Format;
|
||||||
|
hostUsage = volumeDesc.Usage;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hostFormat = surfaceDesc.Format;
|
||||||
|
hostUsage = surfaceDesc.Usage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resourceInfo.HostFormat = hostFormat;
|
||||||
|
resourceInfo.HostUsage = hostUsage;
|
||||||
}
|
}
|
||||||
|
|
||||||
IDirect3DSurface *GetHostSurface(xbox::X_D3DResource *pXboxResource, DWORD D3DUsage = 0)
|
IDirect3DSurface *GetHostSurface(xbox::X_D3DResource *pXboxResource, DWORD D3DUsage = 0)
|
||||||
|
@ -2280,30 +2322,20 @@ static void EmuVerifyResourceIsRegistered(xbox::X_D3DResource *pResource, DWORD
|
||||||
auto& ResourceCache = GetResourceCache(key);
|
auto& ResourceCache = GetResourceCache(key);
|
||||||
auto it = ResourceCache.find(key);
|
auto it = ResourceCache.find(key);
|
||||||
if (it != ResourceCache.end()) {
|
if (it != ResourceCache.end()) {
|
||||||
|
// TODO : Should this check be (D3DUsage & D3DUSAGE_RENDERTARGET) instead?
|
||||||
if (D3DUsage == D3DUSAGE_RENDERTARGET && IsResourceAPixelContainer(pResource) && EmuXBFormatIsRenderTarget(GetXboxPixelContainerFormat((xbox::X_D3DPixelContainer*)pResource))) {
|
if (D3DUsage == D3DUSAGE_RENDERTARGET && IsResourceAPixelContainer(pResource) && EmuXBFormatIsRenderTarget(GetXboxPixelContainerFormat((xbox::X_D3DPixelContainer*)pResource))) {
|
||||||
// Render targets have special behavior: We can't trash them on guest modification
|
// Render targets have special behavior: We can't trash them on guest modification
|
||||||
// this fixes an issue where CubeMaps were broken because the surface Set in GetCubeMapSurface
|
// this fixes an issue where CubeMaps were broken because the surface Set in GetCubeMapSurface
|
||||||
// would be overwritten by the surface created in SetRenderTarget
|
// would be overwritten by the surface created in SetRenderTarget
|
||||||
// However, if a non-rendertarget surface is used here, we'll need to recreate it as a render target!
|
// However, if a non-rendertarget surface is used here, we'll need to recreate it as a render target!
|
||||||
auto hostResource = it->second.pHostResource.Get();
|
auto hostResource = it->second.pHostResource;
|
||||||
auto xboxSurface = (xbox::X_D3DSurface*)pResource;
|
assert(xboxResourceType == GetXboxD3DResourceType(pResource));
|
||||||
auto xboxTexture = (xbox::X_D3DTexture*)pResource;
|
|
||||||
auto xboxResourceType = GetXboxD3DResourceType(pResource);
|
|
||||||
|
|
||||||
// Determine if the associated host resource is a render target already, if so, do nothing
|
|
||||||
HRESULT hRet = STATUS_INVALID_PARAMETER; // Default to an error condition, so we can use D3D_OK to check for success
|
|
||||||
D3DSURFACE_DESC surfaceDesc;
|
|
||||||
if (xboxResourceType == xbox::X_D3DRTYPE_SURFACE) {
|
|
||||||
hRet = ((IDirect3DSurface*)hostResource)->GetDesc(&surfaceDesc);
|
|
||||||
} else if (xboxResourceType == xbox::X_D3DRTYPE_TEXTURE) {
|
|
||||||
hRet = ((IDirect3DTexture*)hostResource)->GetLevelDesc(0, &surfaceDesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only continue checking if we were able to get the surface desc, if it failed, we fall-through
|
// Only continue checking if we were able to get the surface desc, if it failed, we fall-through
|
||||||
// to previous resource management behavior
|
// to previous resource management behavior
|
||||||
if (SUCCEEDED(hRet)) {
|
if (it->second.HostUsage != D3DUSAGE_INVALID) {
|
||||||
// If this resource is already created as a render target on the host, simply return
|
// If this resource is already created as a render target on the host, simply return
|
||||||
if (surfaceDesc.Usage & D3DUSAGE_RENDERTARGET) {
|
if (it->second.HostUsage & D3DUSAGE_RENDERTARGET) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2311,6 +2343,8 @@ static void EmuVerifyResourceIsRegistered(xbox::X_D3DResource *pResource, DWORD
|
||||||
// We need to re-create it as a render target
|
// We need to re-create it as a render target
|
||||||
switch (xboxResourceType) {
|
switch (xboxResourceType) {
|
||||||
case xbox::X_D3DRTYPE_SURFACE: {
|
case xbox::X_D3DRTYPE_SURFACE: {
|
||||||
|
auto xboxSurface = (xbox::X_D3DSurface*)pResource;
|
||||||
|
|
||||||
// Free the host surface
|
// Free the host surface
|
||||||
FreeHostResource(key);
|
FreeHostResource(key);
|
||||||
|
|
||||||
|
@ -7301,7 +7335,6 @@ void CxbxUpdateHostTextures()
|
||||||
auto pXboxBaseTexture = g_pXbox_SetTexture[stage];
|
auto pXboxBaseTexture = g_pXbox_SetTexture[stage];
|
||||||
IDirect3DBaseTexture* pHostBaseTexture = nullptr;
|
IDirect3DBaseTexture* pHostBaseTexture = nullptr;
|
||||||
bool bNeedRelease = false;
|
bool bNeedRelease = false;
|
||||||
|
|
||||||
if (pXboxBaseTexture != xbox::zeroptr) {
|
if (pXboxBaseTexture != xbox::zeroptr) {
|
||||||
DWORD XboxResourceType = GetXboxCommonResourceType(pXboxBaseTexture);
|
DWORD XboxResourceType = GetXboxCommonResourceType(pXboxBaseTexture);
|
||||||
switch (XboxResourceType) {
|
switch (XboxResourceType) {
|
||||||
|
@ -7320,6 +7353,15 @@ void CxbxUpdateHostTextures()
|
||||||
LOG_TEST_CASE("ActiveTexture set to an unhandled resource type!");
|
LOG_TEST_CASE("ActiveTexture set to an unhandled resource type!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read HostFormat from GetResourceCache :
|
||||||
|
// TODO : Optimize this, as we're doing the lookup twice (once in GetHostBaseTexture, once here)
|
||||||
|
auto key = GetHostResourceKey(pXboxBaseTexture, stage);
|
||||||
|
auto& ResourceCache = GetResourceCache(key);
|
||||||
|
auto it = ResourceCache.find(key);
|
||||||
|
if (it != ResourceCache.end()) {
|
||||||
|
g_HostTextureFormats[stage] = it->second.HostFormat;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT hRet = g_pD3DDevice->SetTexture(stage, pHostBaseTexture);
|
HRESULT hRet = g_pD3DDevice->SetTexture(stage, pHostBaseTexture);
|
||||||
|
|
|
@ -59,6 +59,8 @@ extern xbox::dword_xt g_Xbox_VertexShader_Handle;
|
||||||
|
|
||||||
extern xbox::X_PixelShader *g_pXbox_PixelShader;
|
extern xbox::X_PixelShader *g_pXbox_PixelShader;
|
||||||
|
|
||||||
|
extern D3DFORMAT g_HostTextureFormats[xbox::X_D3DTS_STAGECOUNT];
|
||||||
|
|
||||||
extern xbox::X_D3DBaseTexture *g_pXbox_SetTexture[xbox::X_D3DTS_STAGECOUNT];
|
extern xbox::X_D3DBaseTexture *g_pXbox_SetTexture[xbox::X_D3DTS_STAGECOUNT];
|
||||||
|
|
||||||
namespace xbox {
|
namespace xbox {
|
||||||
|
|
|
@ -4,17 +4,23 @@
|
||||||
|
|
||||||
static const float4 WarningColor = float4(0, 1, 1, 1); // Returned when unhandled scenario is encountered
|
static const float4 WarningColor = float4(0, 1, 1, 1); // Returned when unhandled scenario is encountered
|
||||||
|
|
||||||
#define s_bx2(x) (( 2 * max(0, x)) - 1) // PS_INPUTMAPPING_EXPAND_NORMAL= 0x40L, // invalid for final combiner // Shifts range from [0..1] to [-1..1]
|
#define unsigned_to_signed(x) (((x) * 2) - 1) // Shifts range from [0..1] to [-1..1] (just like s_bx2)
|
||||||
#define s_bias(x) (max(0, x) - 0.5) // PS_INPUTMAPPING_HALFBIAS_NORMAL= 0x80L, // invalid for final combiner // Clamps negative x to 0 and then subtracts 0.5
|
#define signed_to_unsigned(x) (((x) + 1) / 2) // Shifts range from [-1..1] to [0..1]
|
||||||
|
|
||||||
float4 PerformColorSign(const float4 ColorSign, float4 t)
|
float4 PerformColorSign(const float4 ColorSign, float4 t)
|
||||||
{
|
{
|
||||||
// Per color channel, optionally convert the value range into two's complement signed values (from (0, +1) to (-1, +1), using s_bx2):
|
// Per color channel, based on the ColorSign setting :
|
||||||
// This is often used for bumpmaps
|
// either keep the value range as-is (when ColorSign is zero)
|
||||||
if (ColorSign.r > 0) t.r = s_bx2(t.r);
|
// or convert from [0..1] to [-1..+1] (when ColorSign is more than zero, often used for bumpmaps),
|
||||||
if (ColorSign.g > 0) t.g = s_bx2(t.g);
|
// or convert from [-1..1] to [0..1] (when ColorSign is less than zero):
|
||||||
if (ColorSign.b > 0) t.b = s_bx2(t.b);
|
if (ColorSign.r > 0) t.r = unsigned_to_signed(t.r);
|
||||||
if (ColorSign.a > 0) t.a = s_bx2(t.a);
|
if (ColorSign.g > 0) t.g = unsigned_to_signed(t.g);
|
||||||
|
if (ColorSign.b > 0) t.b = unsigned_to_signed(t.b);
|
||||||
|
if (ColorSign.a > 0) t.a = unsigned_to_signed(t.a);
|
||||||
|
if (ColorSign.r < 0) t.r = signed_to_unsigned(t.r);
|
||||||
|
if (ColorSign.g < 0) t.g = signed_to_unsigned(t.g);
|
||||||
|
if (ColorSign.b < 0) t.b = signed_to_unsigned(t.b);
|
||||||
|
if (ColorSign.a < 0) t.a = signed_to_unsigned(t.a);
|
||||||
// TODO : Instead of the above, create a mirror texture with a host format that has identical component layout, but with all components signed.
|
// TODO : Instead of the above, create a mirror texture with a host format that has identical component layout, but with all components signed.
|
||||||
// Then, in here, when any component has to be read as signed, sample the signed texture (ouch : with what dimension and coordinate?!)
|
// Then, in here, when any component has to be read as signed, sample the signed texture (ouch : with what dimension and coordinate?!)
|
||||||
// and replace the components that we read from the unsigned texture, but which have to be signed, with the signed components read from the signed mirror texture.
|
// and replace the components that we read from the unsigned texture, but which have to be signed, with the signed components read from the signed mirror texture.
|
||||||
|
|
|
@ -968,28 +968,54 @@ float AsFloat(uint32_t value)
|
||||||
return *(float*)&v;
|
return *(float*)&v;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This mimicks behaviour of XDK LazySetShaderStageProgram, which we bypass due to our drawing patches without trampolines.
|
// Determines the Cxbx ColorSign requirement, as handled in the HLSL shaders by PerformColorSign()
|
||||||
DWORD CxbxGetColorSign(int stage_nr)
|
float CxbxComponentColorSignFromXboxAndHost(bool XboxMarksComponentSigned, bool HostComponentIsSigned)
|
||||||
{
|
{
|
||||||
// When bump environment mapping is enabled
|
// Equal "signedness" between Xbox and host implies we must not convert the component scale :
|
||||||
if (XboxTextureStates.Get(stage_nr, xbox::X_D3DTSS_COLOROP) >= xbox::X_D3DTOP_BUMPENVMAP)
|
if (XboxMarksComponentSigned == HostComponentIsSigned)
|
||||||
// Always mark the blue (alias for U) and green (alias for V) color channels as signed :
|
return 0.0f;
|
||||||
return xbox::X_D3DTSIGN_GSIGNED | xbox::X_D3DTSIGN_BSIGNED;
|
|
||||||
|
// Xbox wants the components to be signed (even though host has them unsigned)
|
||||||
|
if (XboxMarksComponentSigned)
|
||||||
|
return 1.0f; // Mark the component for scaling from unsigned_to_signed
|
||||||
|
|
||||||
|
// Xbox doesn't want signed values, but host has them signed :
|
||||||
|
return -1.0f; // Mark the component for scaling from signed_to_unsigned
|
||||||
|
}
|
||||||
|
|
||||||
|
D3DXCOLOR CxbxCalcColorSign(int stage_nr)
|
||||||
|
{
|
||||||
|
// Without overrides, just use what the running executable put in COLORSIGN :
|
||||||
|
DWORD XboxColorSign = XboxTextureStates.Get(stage_nr, xbox::X_D3DTSS_COLORSIGN);
|
||||||
|
|
||||||
|
{ // This mimicks behaviour of XDK LazySetShaderStageProgram, which we bypass due to our drawing patches without trampolines.
|
||||||
|
// When bump environment mapping is enabled
|
||||||
|
if (XboxTextureStates.Get(stage_nr, xbox::X_D3DTSS_COLOROP) >= xbox::X_D3DTOP_BUMPENVMAP)
|
||||||
|
// Always mark the blue (alias for U) and green (alias for V) color channels as signed :
|
||||||
|
XboxColorSign |= xbox::X_D3DTSIGN_GSIGNED | xbox::X_D3DTSIGN_BSIGNED;
|
||||||
|
}
|
||||||
|
|
||||||
#if 0 // When this block is enabled, XDK samples BumpEarth and BumpLens turn red-ish, so keep this off for now...
|
#if 0 // When this block is enabled, XDK samples BumpEarth and BumpLens turn red-ish, so keep this off for now...
|
||||||
// TODO : Perhaps turn COLORSIGN off when the active host texture is already signed (like D3DFMT_L6V5U5 if supported)
|
|
||||||
// and enable COLORSIGN when the active host texture was converted from signed to unsigned?
|
|
||||||
|
|
||||||
// Check if the pixel shader specifies bump mapping for this stage (TODO : How to handle this with the fixed function shader?)
|
// Check if the pixel shader specifies bump mapping for this stage (TODO : How to handle this with the fixed function shader?)
|
||||||
DWORD PSTextureModes = XboxRenderStates.GetXboxRenderState(xbox::X_D3DRS_PSTEXTUREMODES);
|
DWORD PSTextureModes = XboxRenderStates.GetXboxRenderState(xbox::X_D3DRS_PSTEXTUREMODES);
|
||||||
PS_TEXTUREMODES StageTextureMode = (PS_TEXTUREMODES)((PSTextureModes >> (stage_nr * 5)) & PS_TEXTUREMODES_MASK);
|
PS_TEXTUREMODES StageTextureMode = (PS_TEXTUREMODES)((PSTextureModes >> (stage_nr * 5)) & PS_TEXTUREMODES_MASK);
|
||||||
if (StageTextureMode == PS_TEXTUREMODES_BUMPENVMAP || StageTextureMode == PS_TEXTUREMODES_BUMPENVMAP_LUM)
|
if (StageTextureMode == PS_TEXTUREMODES_BUMPENVMAP || StageTextureMode == PS_TEXTUREMODES_BUMPENVMAP_LUM)
|
||||||
return xbox::X_D3DTSIGN_GSIGNED | xbox::X_D3DTSIGN_BSIGNED;
|
XboxColorSign |= xbox::X_D3DTSIGN_GSIGNED | xbox::X_D3DTSIGN_BSIGNED;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
// Host D3DFMT's with one or more signed components : D3DFMT_V8U8, D3DFMT_Q8W8V8U8, D3DFMT_V16U16, D3DFMT_Q16W16V16U16, D3DFMT_CxV8U8
|
||||||
|
D3DFORMAT HostTextureFormat = g_HostTextureFormats[stage_nr];
|
||||||
|
bool HostTextureFormatIsSignedForA = (HostTextureFormat == D3DFMT_Q8W8V8U8); // No need to check for unused formats : D3DFMT_Q16W16V16U16, D3DFMT_CxV8U8, D3DFMT_A2W10V10U10
|
||||||
|
bool HostTextureFormatIsSignedForR = (HostTextureFormat == D3DFMT_V8U8) || (HostTextureFormat == D3DFMT_V16U16) || (HostTextureFormat == D3DFMT_L6V5U5) || (HostTextureFormat == D3DFMT_X8L8V8U8) || HostTextureFormatIsSignedForA;
|
||||||
|
bool HostTextureFormatIsSignedForG = HostTextureFormatIsSignedForR;
|
||||||
|
bool HostTextureFormatIsSignedForB = HostTextureFormatIsSignedForA;
|
||||||
|
|
||||||
// Without overrides, just return what the running executable put in COLORSIGN :
|
D3DXCOLOR CxbxColorSign;
|
||||||
return XboxTextureStates.Get(stage_nr, xbox::X_D3DTSS_COLORSIGN);
|
CxbxColorSign.r = CxbxComponentColorSignFromXboxAndHost(XboxColorSign & xbox::X_D3DTSIGN_RSIGNED, HostTextureFormatIsSignedForR); // Maps to COLORSIGN.r
|
||||||
|
CxbxColorSign.g = CxbxComponentColorSignFromXboxAndHost(XboxColorSign & xbox::X_D3DTSIGN_GSIGNED, HostTextureFormatIsSignedForG); // Maps to COLORSIGN.g
|
||||||
|
CxbxColorSign.b = CxbxComponentColorSignFromXboxAndHost(XboxColorSign & xbox::X_D3DTSIGN_BSIGNED, HostTextureFormatIsSignedForB); // Maps to COLORSIGN.b
|
||||||
|
CxbxColorSign.a = CxbxComponentColorSignFromXboxAndHost(XboxColorSign & xbox::X_D3DTSIGN_ASIGNED, HostTextureFormatIsSignedForA); // Maps to COLORSIGN.a
|
||||||
|
return CxbxColorSign;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set constant state for the fixed function pixel shader
|
// Set constant state for the fixed function pixel shader
|
||||||
|
@ -1010,11 +1036,11 @@ void UpdateFixedFunctionPixelShaderState()
|
||||||
for (int i = 0; i < xbox::X_D3DTS_STAGECOUNT; i++) {
|
for (int i = 0; i < xbox::X_D3DTS_STAGECOUNT; i++) {
|
||||||
auto stage = &ffPsState.stages[i];
|
auto stage = &ffPsState.stages[i];
|
||||||
stage->COLORKEYOP = (float)XboxTextureStates.Get(i, xbox::X_D3DTSS_COLORKEYOP);
|
stage->COLORKEYOP = (float)XboxTextureStates.Get(i, xbox::X_D3DTSS_COLORKEYOP);
|
||||||
DWORD colorsign = CxbxGetColorSign(i);
|
auto CxbxColorSign = CxbxCalcColorSign(i);
|
||||||
stage->COLORSIGN.x = (colorsign & xbox::X_D3DTSIGN_RSIGNED) ? 1.0f : 0.0f; // Maps to COLORSIGN.r
|
stage->COLORSIGN.x = CxbxColorSign.r;
|
||||||
stage->COLORSIGN.y = (colorsign & xbox::X_D3DTSIGN_GSIGNED) ? 1.0f : 0.0f; // Maps to COLORSIGN.g
|
stage->COLORSIGN.y = CxbxColorSign.g;
|
||||||
stage->COLORSIGN.z = (colorsign & xbox::X_D3DTSIGN_BSIGNED) ? 1.0f : 0.0f; // Maps to COLORSIGN.b
|
stage->COLORSIGN.z = CxbxColorSign.b;
|
||||||
stage->COLORSIGN.w = (colorsign & xbox::X_D3DTSIGN_ASIGNED) ? 1.0f : 0.0f; // Maps to COLORSIGN.a
|
stage->COLORSIGN.w = CxbxColorSign.a;
|
||||||
stage->ALPHAKILL = (float)XboxTextureStates.Get(i, xbox::X_D3DTSS_ALPHAKILL);
|
stage->ALPHAKILL = (float)XboxTextureStates.Get(i, xbox::X_D3DTSS_ALPHAKILL);
|
||||||
stage->BUMPENVMAT00 = AsFloat(XboxTextureStates.Get(i, xbox::X_D3DTSS_BUMPENVMAT00));
|
stage->BUMPENVMAT00 = AsFloat(XboxTextureStates.Get(i, xbox::X_D3DTSS_BUMPENVMAT00));
|
||||||
stage->BUMPENVMAT01 = AsFloat(XboxTextureStates.Get(i, xbox::X_D3DTSS_BUMPENVMAT01));
|
stage->BUMPENVMAT01 = AsFloat(XboxTextureStates.Get(i, xbox::X_D3DTSS_BUMPENVMAT01));
|
||||||
|
@ -1136,11 +1162,7 @@ void DxbxUpdateActivePixelShader() // NOPATCH
|
||||||
|
|
||||||
// Texture color sign
|
// Texture color sign
|
||||||
for (int stage_nr = 0; stage_nr < xbox::X_D3DTS_STAGECOUNT; stage_nr++) {
|
for (int stage_nr = 0; stage_nr < xbox::X_D3DTS_STAGECOUNT; stage_nr++) {
|
||||||
auto colorsign = CxbxGetColorSign(stage_nr);
|
fColor[PSH_XBOX_CONSTANT_COLORSIGN + stage_nr] = CxbxCalcColorSign(stage_nr);
|
||||||
fColor[PSH_XBOX_CONSTANT_COLORSIGN + stage_nr].r = (colorsign & xbox::X_D3DTSIGN_RSIGNED) ? 1.0f : 0.0f; // Maps to COLORSIGN[stage].r (treated as bool, true when > 0.0)
|
|
||||||
fColor[PSH_XBOX_CONSTANT_COLORSIGN + stage_nr].g = (colorsign & xbox::X_D3DTSIGN_GSIGNED) ? 1.0f : 0.0f; // Maps to COLORSIGN[stage].g
|
|
||||||
fColor[PSH_XBOX_CONSTANT_COLORSIGN + stage_nr].b = (colorsign & xbox::X_D3DTSIGN_BSIGNED) ? 1.0f : 0.0f; // Maps to COLORSIGN[stage].b
|
|
||||||
fColor[PSH_XBOX_CONSTANT_COLORSIGN + stage_nr].a = (colorsign & xbox::X_D3DTSIGN_ASIGNED) ? 1.0f : 0.0f; // Maps to COLORSIGN[stage].a
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 // New, doesn't work yet
|
#if 0 // New, doesn't work yet
|
||||||
|
|
Loading…
Reference in New Issue