Use an HLSL accessor function for reading constant registers, allowing Xbox-native negative indices and out-of-bounds handling. This makes the generated HLSL look closed to the original Xbox vertex shader assembly.
This commit is contained in:
parent
d74e5947ee
commit
ff1412b3d9
|
@ -21,16 +21,19 @@ struct VS_OUTPUT
|
|||
float4 oT2 : TEXCOORD2; // Texture coordinate set 2
|
||||
float4 oT3 : TEXCOORD3; // Texture coordinate set 3
|
||||
};
|
||||
|
||||
// Xbox constant registers
|
||||
extern uniform float4 c[192] : register(c0);
|
||||
|
||||
#define X_D3DSCM_CORRECTION 96 // Add 96 to arrive at the range 0..191 (instead of -96..95)
|
||||
#define X_D3DVS_CONSTREG_COUNT 192
|
||||
|
||||
// Xbox constant registers
|
||||
uniform float4 C[X_D3DVS_CONSTREG_COUNT] : register(c0);
|
||||
|
||||
// Vertex input overrides for SetVertexData4f support
|
||||
extern float4 vOverrideValue[16] : register(c192);
|
||||
extern float4 vOverridePacked[4] : register(c208);
|
||||
uniform float4 vOverrideValue[16] : register(c192);
|
||||
uniform float4 vOverridePacked[4] : register(c208);
|
||||
|
||||
extern float4 xboxViewportScale : register(c212);
|
||||
extern float4 xboxViewportOffset : register(c213);
|
||||
uniform float4 xboxViewportScale : register(c212);
|
||||
uniform float4 xboxViewportOffset : register(c213);
|
||||
|
||||
// Overloaded casts, assuring all inputs are treated as float4
|
||||
float4 _tof4(float src) { return float4(src, src, src, src); }
|
||||
|
@ -40,6 +43,20 @@ float4 _tof4(float4 src) { return src; }
|
|||
float4 _ssss(float s) { return float4(s, s, s, s); } // a scalar output replicated across a 4-component vector
|
||||
#define _scalar(src) _tof4(src).x /* a scalar input */
|
||||
|
||||
float4 c(int register_number)
|
||||
{
|
||||
// Map Xbox [-96, 95] to Host [0, 191]
|
||||
// Account for Xbox's negative constant indexes
|
||||
register_number += X_D3DSCM_CORRECTION;
|
||||
if (register_number < 0)
|
||||
return 0;
|
||||
|
||||
if (register_number >= X_D3DVS_CONSTREG_COUNT) // X_D3DVS_CONSTREG_COUNT
|
||||
return 0;
|
||||
|
||||
return C[register_number];
|
||||
}
|
||||
|
||||
// http://xboxdevwiki.net/NV2A/Vertex_Shader
|
||||
// https://www.khronos.org/registry/OpenGL/extensions/NV/NV_vertex_program.txt
|
||||
// https://www.khronos.org/registry/OpenGL/extensions/NV/NV_vertex_program1_1.txt
|
||||
|
|
|
@ -986,7 +986,7 @@ typedef DWORD X_VERTEXSHADERCONSTANTMODE;
|
|||
#define X_D3DSCM_RESERVED_CONSTANT_SCALE -38 // Becomes 58 after correction, contains Scale v
|
||||
#define X_D3DSCM_RESERVED_CONSTANT_OFFSET -37 // Becomes 59 after correction, contains Offset
|
||||
|
||||
#define X_D3DSCM_CORRECTION 96 // Add 96 to arrive at the range 0..191 (instead of 96..95)
|
||||
#define X_D3DSCM_CORRECTION 96 // Add 96 to arrive at the range 0..191 (instead of -96..95)
|
||||
#define X_D3DVS_CONSTREG_COUNT 192
|
||||
|
||||
// Special Registers, used to pass additional information to the shaders
|
||||
|
|
|
@ -1601,7 +1601,9 @@ static void OutputHlsl(std::stringstream& hlsl, VSH_IMD_OUTPUT& dest)
|
|||
|
||||
switch (dest.Type) {
|
||||
case IMD_OUTPUT_C:
|
||||
hlsl << "c[" << dest.Address << "]";
|
||||
// Access the HLSL capital C[] constants array, with the index bias applied :
|
||||
// TODO : Avoid out-of-bound writes (perhaps writing to a reserverd index?)
|
||||
hlsl << "C[" << dest.Address + X_D3DSCM_CORRECTION << "]";
|
||||
LOG_TEST_CASE("Vertex shader writes to constant table");
|
||||
break;
|
||||
case IMD_OUTPUT_R:
|
||||
|
@ -1647,18 +1649,19 @@ static void ParameterHlsl(std::stringstream& hlsl, VSH_IMD_PARAMETER& paramMeta)
|
|||
|
||||
int register_number = param.Address;
|
||||
if (param.ParameterType == PARAM_C) {
|
||||
// Map Xbox [-96, 95] to Host [0, 191]
|
||||
// Account for Xbox's negative constant indexes
|
||||
register_number += 96;
|
||||
// Access constant registers through our HLSL c() function,
|
||||
// which allows dumping negative indices (like Xbox shaders),
|
||||
// and which returns zero when out-of-bounds indices are passed in:
|
||||
if (paramMeta.IndexesWithA0_X) {
|
||||
// Only display the offset if it's not 0.
|
||||
if (register_number != 0) {
|
||||
hlsl << "c[a0.x+" << register_number << "]";
|
||||
if (register_number == 0) {
|
||||
hlsl << "c(a0.x)"; // Hide the offset if it's 0
|
||||
} else if (register_number < 0) {
|
||||
hlsl << "c(a0.x" << register_number << ")"; // minus is part of the offset
|
||||
} else {
|
||||
hlsl << "c[a0.x]";
|
||||
hlsl << "c(a0.x+" << register_number << ")"; // show addition character
|
||||
}
|
||||
} else {
|
||||
hlsl << "c[" << register_number << "]";
|
||||
hlsl << "c(" << register_number << ")";
|
||||
}
|
||||
} else {
|
||||
hlsl << RegisterName[param.ParameterType] << register_number;
|
||||
|
|
Loading…
Reference in New Issue