SetVertexData4f support
This commit is contained in:
parent
ba5d25e2ed
commit
136083d72a
|
|
@ -489,6 +489,17 @@ const char *CxbxGetErrorDescription(HRESULT hResult)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// TODO move to shader file. Needs to be called whenever a shader or declaration is set
|
||||
void SetOverrideFlags(CxbxVertexShader* pCxbxVertexShader) {
|
||||
if (pCxbxVertexShader != nullptr && pCxbxVertexShader->pHostVertexShader != nullptr) {
|
||||
float overrideFlags[16];
|
||||
for (int i = 0; i < 16; i++) {
|
||||
overrideFlags[i] = !pCxbxVertexShader->VertexShaderInfo.vRegisterInDeclaration[i];
|
||||
}
|
||||
g_pD3DDevice->SetVertexShaderConstantF(X_D3DVS_CONSTREG_VERTEXDATA4F_FLAG_BASE, overrideFlags, 4);
|
||||
}
|
||||
}
|
||||
|
||||
const char *D3DErrorString(HRESULT hResult)
|
||||
{
|
||||
static char buffer[1024];
|
||||
|
|
@ -3452,6 +3463,8 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SelectVertexShader)
|
|||
pHostVertexDeclaration = pCxbxVertexShader->pHostVertexDeclaration;
|
||||
pHostVertexShader = pCxbxVertexShader->pHostVertexShader;
|
||||
HostFVF = pCxbxVertexShader->HostFVF;
|
||||
|
||||
SetOverrideFlags(pCxbxVertexShader);
|
||||
}
|
||||
|
||||
hRet = g_pD3DDevice->SetVertexDeclaration(pHostVertexDeclaration);
|
||||
|
|
@ -3808,15 +3821,10 @@ void UpdateViewPortOffsetAndScaleConstants()
|
|||
{
|
||||
float vOffset[4], vScale[4];
|
||||
GetViewPortOffsetAndScale(vOffset, vScale);
|
||||
float vScaleReversed[4] = { 1.0f / (double)vScale[0], 1.0f / (double)vScale[1], 1.0f / (double)vScale[2], 0 };
|
||||
|
||||
g_pD3DDevice->SetVertexShaderConstantF(X_D3DVS_VIEWPORT_SCALE_MIRROR_INVERTED, vScaleReversed, 1);
|
||||
g_pD3DDevice->SetVertexShaderConstantF(X_D3DVS_VIEWPORT_SCALE_MIRROR, vScale, 1);
|
||||
g_pD3DDevice->SetVertexShaderConstantF(X_D3DVS_VIEWPORT_OFFSET_MIRROR, vOffset, 1);
|
||||
|
||||
// Set 0 and 1 constant, used to compare and transform W when required
|
||||
float ZeroOne[] = { 0, 1, 0, 0 };
|
||||
g_pD3DDevice->SetVertexShaderConstantF(X_D3DVS_VIEWPORT_SCALE_ZERO_ONE, ZeroOne, 1);
|
||||
|
||||
// Store viewport offset and scale in constant registers 58 (c-38) and
|
||||
// 59 (c-37) used for screen space transformation.
|
||||
// We only do this if X_D3DSCM_NORESERVEDCONSTANTS is not set, since enabling this flag frees up these registers for shader used
|
||||
|
|
@ -6674,18 +6682,12 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetVertexShader)
|
|||
}
|
||||
else
|
||||
{
|
||||
SetOverrideFlags(pCxbxVertexShader);
|
||||
|
||||
hRet = g_pD3DDevice->SetVertexShader(pCxbxVertexShader->pHostVertexShader);
|
||||
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexShader(VshHandleIsVertexShader)");
|
||||
}
|
||||
|
||||
// Set default constant values for specular, diffuse, etc
|
||||
static const float ColorBlack[4] = { 0,0,0,0 };
|
||||
static const float ColorWhite[4] = { 1,1,1,1 };
|
||||
|
||||
g_pD3DDevice->SetVertexShaderConstantF(CXBX_D3DVS_CONSTREG_VERTEXDATA4F_BASE + XTL::X_D3DVSDE_DIFFUSE, ColorWhite, 1);
|
||||
g_pD3DDevice->SetVertexShaderConstantF(CXBX_D3DVS_CONSTREG_VERTEXDATA4F_BASE + XTL::X_D3DVSDE_BACKDIFFUSE, ColorWhite, 1);
|
||||
g_pD3DDevice->SetVertexShaderConstantF(CXBX_D3DVS_CONSTREG_VERTEXDATA4F_BASE + XTL::X_D3DVSDE_SPECULAR, ColorBlack, 1);
|
||||
g_pD3DDevice->SetVertexShaderConstantF(CXBX_D3DVS_CONSTREG_VERTEXDATA4F_BASE + XTL::X_D3DVSDE_BACKSPECULAR, ColorBlack, 1);
|
||||
} else {
|
||||
hRet = g_pD3DDevice->SetVertexShader(nullptr);
|
||||
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexShader");
|
||||
|
|
|
|||
|
|
@ -25,6 +25,13 @@ struct VS_OUTPUT
|
|||
// Xbox constant registers
|
||||
extern uniform float4 c[192] : register(c0);
|
||||
|
||||
// Vertex input overrides for SetVertexData4f support
|
||||
extern float4 vOverrideValue[16] : register(c192);
|
||||
extern float4 vOverridePacked[4] : register(c208);
|
||||
|
||||
extern float4 xboxViewportScale : register(c212);
|
||||
extern float4 xboxViewportOffset : register(c213);
|
||||
|
||||
// Overloaded casts, assuring all inputs are treated as float4
|
||||
float4 _tof4(float src) { return float4(src, src, src, src); }
|
||||
float4 _tof4(float2 src) { return src.xyyy; }
|
||||
|
|
@ -176,16 +183,16 @@ float _rcc(float input)
|
|||
float4 reverseScreenspaceTransform(float4 oPos)
|
||||
{
|
||||
// On Xbox, oPos should contain the vertex position in screenspace
|
||||
// We need to reverse this transformation
|
||||
// Conventionally, each Xbox Vertex Shader includes instructions like this
|
||||
// mul oPos.xyz, r12, c-38
|
||||
// +rcc r1.x, r12.w
|
||||
// mad oPos.xyz, r12, r1.x, c-37
|
||||
// where c-37 and c-38 are reserved transform values
|
||||
|
||||
// Lets hope c-37 and c-38 contain the conventional values
|
||||
oPos.xyz -= (float3)c[-37 + 96]; // reverse offset
|
||||
oPos.xyz -= xboxViewportOffset.xyz; // reverse offset
|
||||
oPos.xyz *= oPos.w; // reverse perspective divide
|
||||
oPos.xyz /= (float3)c[-38 + 96]; // reverse scale
|
||||
oPos.xyz /= xboxViewportScale.xyz; // reverse scale
|
||||
|
||||
return oPos;
|
||||
}
|
||||
|
|
@ -208,25 +215,33 @@ VS_OUTPUT main(const VS_INPUT xIn)
|
|||
r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = r8 = r9 = r10 = r11 = float4(0, 0, 0, 0);
|
||||
#define r12 oPos // oPos and r12 are two ways of accessing the same register on Xbox
|
||||
|
||||
// Input registers
|
||||
float4 v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15;
|
||||
// Initialize input variables
|
||||
v0 = xIn.v[0];
|
||||
v1 = xIn.v[1];
|
||||
v2 = xIn.v[2];
|
||||
v3 = xIn.v[3];
|
||||
v4 = xIn.v[4];
|
||||
v5 = xIn.v[5];
|
||||
v6 = xIn.v[6];
|
||||
v7 = xIn.v[7];
|
||||
v8 = xIn.v[8];
|
||||
v9 = xIn.v[9];
|
||||
v10 = xIn.v[10];
|
||||
v11 = xIn.v[11];
|
||||
v12 = xIn.v[12];
|
||||
v13 = xIn.v[13];
|
||||
v14 = xIn.v[14];
|
||||
v15 = xIn.v[15];
|
||||
// Input registerss
|
||||
float4 v[16];
|
||||
# define v0 v[0]
|
||||
# define v1 v[1]
|
||||
# define v2 v[2]
|
||||
# define v3 v[3]
|
||||
# define v4 v[4]
|
||||
# define v5 v[5]
|
||||
# define v6 v[6]
|
||||
# define v7 v[7]
|
||||
# define v8 v[8]
|
||||
# define v9 v[9]
|
||||
# define v10 v[10]
|
||||
# define v11 v[11]
|
||||
# define v12 v[12]
|
||||
# define v13 v[13]
|
||||
# define v14 v[14]
|
||||
# define v15 v[15]
|
||||
|
||||
// View 4 packed overrides as an array of 16 floats
|
||||
float vOverride[16] = (float[16])vOverridePacked;
|
||||
|
||||
// Initialize input registers from the vertex buffer
|
||||
// Or use an override value set with SetVertexData4f
|
||||
for(uint i = 0; i < 16; i++){
|
||||
v[i] = vOverride[i] ? vOverrideValue[i] : xIn.v[i];
|
||||
}
|
||||
|
||||
// Xbox shader program
|
||||
// <Xbox Shader>
|
||||
|
|
|
|||
|
|
@ -988,17 +988,13 @@ typedef DWORD X_VERTEXSHADERCONSTANTMODE;
|
|||
|
||||
#define X_D3DSCM_CORRECTION 96 // Add 96 to arrive at the range 0..191 (instead of 96..95)
|
||||
#define X_D3DVS_CONSTREG_COUNT 192
|
||||
#define X_D3DVS_RESERVED_CONSTANT1 -38 // Becomes 58 after correction, contains Scale v
|
||||
#define X_D3DVS_RESERVED_CONSTANT2 -37 // Becomes 59 after correction, contains Offset
|
||||
#define X_D3DVS_RESERVED_CONSTANT1_CORRECTED (X_D3DVS_RESERVED_CONSTANT1 + X_D3DVS_CONSTREG_BIAS)
|
||||
#define X_D3DVS_RESERVED_CONSTANT2_CORRECTED (X_D3DVS_RESERVED_CONSTANT2 + X_D3DVS_CONSTREG_BIAS)
|
||||
|
||||
// Special Registers, used to pass additional information to the shaders
|
||||
#define X_D3DVS_CONSTREG_VERTEXDATA4F_BASE (X_D3DVS_CONSTREG_COUNT + 1)
|
||||
#define X_D3DVS_CONSTREG_VERTEXDATA4F_END (X_D3DVS_CONSTREG_VERTEXDATA4F_BASE + 14)
|
||||
#define X_D3DVS_VIEWPORT_SCALE_MIRROR_INVERTED (X_D3DVS_CONSTREG_VERTEXDATA4F_END + 1)
|
||||
#define X_D3DVS_VIEWPORT_OFFSET_MIRROR (X_D3DVS_VIEWPORT_SCALE_MIRROR_INVERTED + 1)
|
||||
#define X_D3DVS_VIEWPORT_SCALE_ZERO_ONE (X_D3DVS_VIEWPORT_OFFSET_MIRROR + 1)
|
||||
// TODO co-locate shader workaround constants with shader code
|
||||
#define X_D3DVS_CONSTREG_VERTEXDATA4F_BASE (X_D3DVS_CONSTREG_COUNT)
|
||||
#define X_D3DVS_CONSTREG_VERTEXDATA4F_FLAG_BASE (X_D3DVS_CONSTREG_VERTEXDATA4F_BASE + 16)
|
||||
#define X_D3DVS_VIEWPORT_SCALE_MIRROR (X_D3DVS_CONSTREG_VERTEXDATA4F_FLAG_BASE + 4)
|
||||
#define X_D3DVS_VIEWPORT_OFFSET_MIRROR (X_D3DVS_VIEWPORT_SCALE_MIRROR + 1)
|
||||
|
||||
#define X_D3DSCM_RESERVED_CONSTANT_SCALE_CORRECTED (X_D3DSCM_RESERVED_CONSTANT_SCALE + X_D3DSCM_CORRECTION)
|
||||
#define X_D3DSCM_RESERVED_CONSTANT_OFFSET_CORRECTED (X_D3DSCM_RESERVED_CONSTANT_OFFSET + X_D3DSCM_CORRECTION)
|
||||
|
|
|
|||
|
|
@ -302,7 +302,7 @@ typedef struct _VSH_XBOX_SHADER
|
|||
}
|
||||
VSH_XBOX_SHADER;
|
||||
|
||||
// TODO : Reinstate and use : std::array<bool, 16> RegVIsPresentInDeclaration;
|
||||
std::array<bool, 16> RegVIsPresentInDeclaration;
|
||||
|
||||
/* TODO : map non-FVF Xbox vertex shader handle to CxbxVertexShader (a struct containing a host Xbox vertex shader handle and the original members)
|
||||
std::unordered_map<DWORD, CxbxVertexShader> g_CxbxVertexShaders;
|
||||
|
|
@ -1290,7 +1290,7 @@ private:
|
|||
}
|
||||
|
||||
// Add this register to the list of declared registers
|
||||
// TODO : Reinstate and use : RegVIsPresentInDeclaration[VertexRegister] = true;
|
||||
RegVIsPresentInDeclaration[VertexRegister] = true;
|
||||
|
||||
DWORD XboxVertexElementDataType = (*pXboxToken & X_D3DVSD_DATATYPEMASK) >> X_D3DVSD_DATATYPESHIFT;
|
||||
WORD XboxVertexElementByteSize = 0;
|
||||
|
|
@ -1617,7 +1617,7 @@ public:
|
|||
|
||||
IsFixedFunction = bIsFixedFunction;
|
||||
|
||||
// TODO : Reinstate and use : RegVIsPresentInDeclaration.fill(false);
|
||||
RegVIsPresentInDeclaration.fill(false);
|
||||
|
||||
// First of all some info:
|
||||
// We have to figure out which flags are set and then
|
||||
|
|
@ -1661,6 +1661,11 @@ public:
|
|||
// Free the preprocessed declaration copy
|
||||
free(pXboxVertexDeclarationCopy);
|
||||
|
||||
for (int i = 0; i < RegVIsPresentInDeclaration.size(); i++) {
|
||||
pCxbxVertexShaderInfo->vRegisterInDeclaration[i] = RegVIsPresentInDeclaration[i];
|
||||
EmuLog(LOG_LEVEL::DEBUG, "Vertex regs used: v%d %d", i, pCxbxVertexShaderInfo->vRegisterInDeclaration[i]);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ typedef struct _CxbxVertexShaderInfo
|
|||
{
|
||||
UINT NumberOfVertexStreams; // The number of streams the vertex shader uses
|
||||
CxbxVertexShaderStreamInfo VertexStreams[X_VSH_MAX_STREAMS];
|
||||
bool vRegisterInDeclaration[16];
|
||||
}
|
||||
CxbxVertexShaderInfo;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue