Force A0's X mask during decoding (in VshAddInstructionMAC_ARL) instead of HLSL conversion (in OutputHlsl)
Also applied Unix EOL style (again)
This commit is contained in:
parent
619b276d81
commit
50a51657b0
|
@ -250,7 +250,7 @@ typedef struct _VSH_SHADER_INSTRUCTION
|
|||
VSH_PARAMETER A;
|
||||
VSH_PARAMETER B;
|
||||
VSH_PARAMETER C;
|
||||
boolean a0x;
|
||||
boolean a0x;
|
||||
boolean Final;
|
||||
}
|
||||
VSH_SHADER_INSTRUCTION;
|
||||
|
@ -382,7 +382,7 @@ static uint8_t VshGetField(uint32_t *pShaderToken,
|
|||
// Final instruction
|
||||
{ 3, 0, 1 } // FLD_FINAL,
|
||||
};
|
||||
|
||||
|
||||
return (uint8_t)(VshGetFromToken(pShaderToken,
|
||||
FieldMapping[FieldName].SubToken,
|
||||
FieldMapping[FieldName].StartBit,
|
||||
|
@ -398,7 +398,7 @@ static inline int16_t ConvertCRegister(const int16_t CReg)
|
|||
static void VshParseInstruction(uint32_t *pShaderToken,
|
||||
VSH_SHADER_INSTRUCTION *pInstruction)
|
||||
{
|
||||
// First get the instruction(s).
|
||||
// First get the instruction(s).
|
||||
pInstruction->ILU = (VSH_ILU)VshGetField(pShaderToken, FLD_ILU);
|
||||
pInstruction->MAC = (VSH_MAC)VshGetField(pShaderToken, FLD_MAC);
|
||||
|
||||
|
@ -471,14 +471,14 @@ static void VshParseInstruction(uint32_t *pShaderToken,
|
|||
pInstruction->C.Swizzle[3] = (VSH_SWIZZLE)VshGetField(pShaderToken, FLD_C_SWZ_W);
|
||||
// Get output
|
||||
// Output register
|
||||
pInstruction->Output.OutputType = (VSH_OUTPUT_TYPE)VshGetField(pShaderToken, FLD_OUT_ORB);
|
||||
pInstruction->Output.OutputType = (VSH_OUTPUT_TYPE)VshGetField(pShaderToken, FLD_OUT_ORB);
|
||||
switch(pInstruction->Output.OutputType)
|
||||
{
|
||||
case OUTPUT_C:
|
||||
pInstruction->Output.OutputAddress = ConvertCRegister(VshGetField(pShaderToken, FLD_OUT_ADDRESS));
|
||||
break;
|
||||
case OUTPUT_O:
|
||||
pInstruction->Output.OutputAddress = VshGetField(pShaderToken, FLD_OUT_ADDRESS) & 0xF;
|
||||
pInstruction->Output.OutputAddress = VshGetField(pShaderToken, FLD_OUT_ADDRESS) & 0xF;
|
||||
break;
|
||||
}
|
||||
pInstruction->Output.OutputMux = (VSH_OUTPUT_MUX)VshGetField(pShaderToken, FLD_OUT_MUX);
|
||||
|
@ -499,8 +499,8 @@ static void VshParseInstruction(uint32_t *pShaderToken,
|
|||
pInstruction->Output.ILURMask[3] = VshGetField(pShaderToken, FLD_OUT_ILU_MASK_W);
|
||||
pInstruction->Output.ILURAddress = VshGetField(pShaderToken, FLD_OUT_R);
|
||||
// Finally, get a0.x indirect constant addressing
|
||||
pInstruction->a0x = VshGetField(pShaderToken, FLD_A0X);
|
||||
pInstruction->Final = VshGetField(pShaderToken, FLD_FINAL);
|
||||
pInstruction->a0x = VshGetField(pShaderToken, FLD_A0X);
|
||||
pInstruction->Final = VshGetField(pShaderToken, FLD_FINAL);
|
||||
}
|
||||
|
||||
static inline int VshIsMaskInUse(const boolean* pMask)
|
||||
|
@ -510,14 +510,14 @@ static inline int VshIsMaskInUse(const boolean* pMask)
|
|||
|
||||
static inline boolean VshInstrWritesToMAC_R(VSH_SHADER_INSTRUCTION* pInstruction)
|
||||
{
|
||||
return VshIsMaskInUse(pInstruction->Output.MACRMask)
|
||||
return VshIsMaskInUse(pInstruction->Output.MACRMask)
|
||||
&& pInstruction->MAC != MAC_NOP;
|
||||
}
|
||||
|
||||
static inline boolean VshInstrWritesToMAC_O(VSH_SHADER_INSTRUCTION* pInstruction)
|
||||
{
|
||||
return VshIsMaskInUse(pInstruction->Output.OutputMask)
|
||||
&& pInstruction->Output.OutputMux == OMUX_MAC
|
||||
return VshIsMaskInUse(pInstruction->Output.OutputMask)
|
||||
&& pInstruction->Output.OutputMux == OMUX_MAC
|
||||
&& pInstruction->MAC != MAC_NOP;
|
||||
}
|
||||
|
||||
|
@ -530,14 +530,14 @@ static inline boolean VshInstrWritesToMAC_ARL(VSH_SHADER_INSTRUCTION* pInstructi
|
|||
|
||||
static inline boolean VshInstrWritesToILU_R(VSH_SHADER_INSTRUCTION* pInstruction)
|
||||
{
|
||||
return VshIsMaskInUse(pInstruction->Output.ILURMask)
|
||||
return VshIsMaskInUse(pInstruction->Output.ILURMask)
|
||||
&& pInstruction->ILU != ILU_NOP;
|
||||
}
|
||||
|
||||
static inline boolean VshInstrWritesToILU_O(VSH_SHADER_INSTRUCTION* pInstruction)
|
||||
{
|
||||
return VshIsMaskInUse(pInstruction->Output.OutputMask)
|
||||
&& pInstruction->Output.OutputMux == OMUX_ILU
|
||||
return VshIsMaskInUse(pInstruction->Output.OutputMask)
|
||||
&& pInstruction->Output.OutputMux == OMUX_ILU
|
||||
&& pInstruction->ILU != ILU_NOP;
|
||||
}
|
||||
|
||||
|
@ -556,7 +556,7 @@ static void VshAddParameters(VSH_SHADER_INSTRUCTION *pInstruction,
|
|||
VSH_IMD_PARAMETER *pParameters)
|
||||
{
|
||||
uint8_t ParamCount = 0;
|
||||
|
||||
|
||||
if(MAC >= MAC_MOV)
|
||||
{
|
||||
VshAddParameter(&pInstruction->A, pInstruction->a0x, &pParameters[ParamCount]);
|
||||
|
@ -597,7 +597,7 @@ static boolean VshAddInstructionMAC_R(VSH_SHADER_INSTRUCTION *pInstruction,
|
|||
VSH_XBOX_SHADER *pShader,
|
||||
boolean IsCombined)
|
||||
{
|
||||
VSH_INTERMEDIATE_FORMAT *pIntermediate;
|
||||
VSH_INTERMEDIATE_FORMAT *pIntermediate;
|
||||
|
||||
if(!VshInstrWritesToMAC_R(pInstruction)) {
|
||||
return FALSE;
|
||||
|
@ -625,7 +625,7 @@ static boolean VshAddInstructionMAC_O(VSH_SHADER_INSTRUCTION* pInstruction,
|
|||
VSH_XBOX_SHADER *pShader,
|
||||
boolean IsCombined)
|
||||
{
|
||||
VSH_INTERMEDIATE_FORMAT *pIntermediate;
|
||||
VSH_INTERMEDIATE_FORMAT *pIntermediate;
|
||||
|
||||
if(!VshInstrWritesToMAC_O(pInstruction)) {
|
||||
return FALSE;
|
||||
|
@ -653,7 +653,7 @@ static boolean VshAddInstructionMAC_ARL(VSH_SHADER_INSTRUCTION *pInstruction,
|
|||
VSH_XBOX_SHADER *pShader,
|
||||
boolean IsCombined)
|
||||
{
|
||||
VSH_INTERMEDIATE_FORMAT *pIntermediate;
|
||||
VSH_INTERMEDIATE_FORMAT *pIntermediate;
|
||||
|
||||
if(!VshInstrWritesToMAC_ARL(pInstruction)) {
|
||||
return FALSE;
|
||||
|
@ -669,6 +669,7 @@ static boolean VshAddInstructionMAC_ARL(VSH_SHADER_INSTRUCTION *pInstruction,
|
|||
// Output param
|
||||
pIntermediate->Output.Type = IMD_OUTPUT_A0X;
|
||||
pIntermediate->Output.Address = pInstruction->Output.OutputAddress;
|
||||
pIntermediate->Output.Mask[0] = true; // force a0.x
|
||||
|
||||
// Other parameters
|
||||
VshAddParameters(pInstruction, ILU_NOP, pInstruction->MAC, pIntermediate->Parameters);
|
||||
|
@ -680,7 +681,7 @@ static boolean VshAddInstructionILU_R(VSH_SHADER_INSTRUCTION *pInstruction,
|
|||
VSH_XBOX_SHADER *pShader,
|
||||
boolean IsCombined)
|
||||
{
|
||||
VSH_INTERMEDIATE_FORMAT *pIntermediate;
|
||||
VSH_INTERMEDIATE_FORMAT *pIntermediate;
|
||||
|
||||
if(!VshInstrWritesToILU_R(pInstruction)) {
|
||||
return FALSE;
|
||||
|
@ -709,7 +710,7 @@ static boolean VshAddInstructionILU_O(VSH_SHADER_INSTRUCTION *pInstruction,
|
|||
VSH_XBOX_SHADER *pShader,
|
||||
boolean IsCombined)
|
||||
{
|
||||
VSH_INTERMEDIATE_FORMAT *pIntermediate;
|
||||
VSH_INTERMEDIATE_FORMAT *pIntermediate;
|
||||
|
||||
if(!VshInstrWritesToILU_O(pInstruction)) {
|
||||
return FALSE;
|
||||
|
@ -760,14 +761,14 @@ static void VshConvertToIntermediate(VSH_SHADER_INSTRUCTION *pInstruction,
|
|||
IsCombined = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (VshAddInstructionMAC_O(pInstruction, pShader, IsCombined)) {
|
||||
if (VshInstrWritesToILU_R(pInstruction) ||
|
||||
VshInstrWritesToILU_O(pInstruction)) {
|
||||
IsCombined = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Special case, arl (mov a0.x, ...)
|
||||
if (VshAddInstructionMAC_ARL(pInstruction, pShader, IsCombined)) {
|
||||
if (VshInstrWritesToILU_R(pInstruction) ||
|
||||
|
@ -775,13 +776,13 @@ static void VshConvertToIntermediate(VSH_SHADER_INSTRUCTION *pInstruction,
|
|||
IsCombined = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (VshAddInstructionILU_R(pInstruction, pShader, IsCombined)) {
|
||||
if (VshInstrWritesToILU_O(pInstruction)) {
|
||||
IsCombined = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
(void)VshAddInstructionILU_O(pInstruction, pShader, IsCombined);
|
||||
}
|
||||
|
||||
|
@ -1592,7 +1593,7 @@ public:
|
|||
// Get a preprocessed copy of the original Xbox Vertex Declaration
|
||||
auto pXboxVertexDeclarationCopy = RemoveXboxDeclarationRedefinition(pXboxDeclaration);
|
||||
|
||||
pVertexShaderInfoToSet = pCxbxVertexShaderInfo;
|
||||
pVertexShaderInfoToSet = pCxbxVertexShaderInfo;
|
||||
|
||||
IsFixedFunction = bIsFixedFunction;
|
||||
|
||||
|
@ -1640,7 +1641,7 @@ public:
|
|||
// Free the preprocessed declaration copy
|
||||
free(pXboxVertexDeclarationCopy);
|
||||
|
||||
for (int i = 0; i < RegVIsPresentInDeclaration.size(); i++) {
|
||||
for (size_t 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]);
|
||||
}
|
||||
|
@ -1777,7 +1778,7 @@ void CxbxImpl_SelectVertexShaderDirect
|
|||
|
||||
// HLSL outputs
|
||||
|
||||
static void OutputHlsl(std::stringstream& hlsl, VSH_IMD_OUTPUT& dest)
|
||||
static void OutputHlsl(std::stringstream& hlsl, VSH_IMD_OUTPUT& dest)
|
||||
{
|
||||
static const char* OReg_Name[/*VSH_OREG_NAME*/] = {
|
||||
"oPos",
|
||||
|
@ -1800,38 +1801,37 @@ static void OutputHlsl(std::stringstream& hlsl, VSH_IMD_OUTPUT& dest)
|
|||
|
||||
switch (dest.Type) {
|
||||
case IMD_OUTPUT_C:
|
||||
hlsl << "c[" << dest.Address << "]";
|
||||
LOG_TEST_CASE("Vertex shader writes to constant table");
|
||||
hlsl << "c[" << dest.Address << "]";
|
||||
LOG_TEST_CASE("Vertex shader writes to constant table");
|
||||
break;
|
||||
case IMD_OUTPUT_R:
|
||||
hlsl << "r" << dest.Address;
|
||||
break;
|
||||
case IMD_OUTPUT_O:
|
||||
case IMD_OUTPUT_O:
|
||||
assert(dest.Address < OREG_A0X);
|
||||
hlsl << OReg_Name[dest.Address];
|
||||
hlsl << OReg_Name[dest.Address];
|
||||
break;
|
||||
case IMD_OUTPUT_A0X:
|
||||
hlsl << "a0";
|
||||
dest.Mask[0] = true; // force a0.x
|
||||
hlsl << "a0";
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
// Write the mask as a separate argument to the opcode defines
|
||||
// Write the mask as a separate argument to the opcode defines
|
||||
// (No space, so that "dest,mask, ..." looks close to "dest.mask, ...")
|
||||
hlsl << ",";
|
||||
if (dest.Mask[0]) hlsl << "x";
|
||||
if (dest.Mask[1]) hlsl << "y";
|
||||
if (dest.Mask[2]) hlsl << "z";
|
||||
hlsl << ",";
|
||||
if (dest.Mask[0]) hlsl << "x";
|
||||
if (dest.Mask[1]) hlsl << "y";
|
||||
if (dest.Mask[2]) hlsl << "z";
|
||||
if (dest.Mask[3]) hlsl << "w";
|
||||
}
|
||||
|
||||
static void ParameterHlsl(std::stringstream& hlsl, VSH_IMD_PARAMETER& paramMeta)
|
||||
{
|
||||
// Print functions
|
||||
static char* RegisterName[/*VSH_PARAMETER_TYPE*/] = {
|
||||
static char* RegisterName[/*VSH_PARAMETER_TYPE*/] = {
|
||||
"?", // PARAM_UNKNOWN = 0,
|
||||
"r", // PARAM_R, // Temporary (scRatch) registers
|
||||
"v", // PARAM_V, // Vertex registers
|
||||
|
@ -1844,19 +1844,19 @@ static void ParameterHlsl(std::stringstream& hlsl, VSH_IMD_PARAMETER& paramMeta)
|
|||
if (param.Neg) {
|
||||
hlsl << "-";
|
||||
}
|
||||
|
||||
|
||||
int register_number = param.Address;
|
||||
if (param.ParameterType == PARAM_C) {
|
||||
if (param.ParameterType == PARAM_C) {
|
||||
// Map Xbox [-96, 95] to Host [0, 191]
|
||||
// Account for Xbox's negative constant indexes
|
||||
register_number += 96;
|
||||
register_number += 96;
|
||||
if (paramMeta.IndexesWithA0_X) {
|
||||
// Only display the offset if it's not 0.
|
||||
if (register_number != 0) {
|
||||
hlsl << "c[a0.x+" << register_number << "]";
|
||||
} else {
|
||||
hlsl << "c[a0.x]";
|
||||
}
|
||||
hlsl << "c[a0.x]";
|
||||
}
|
||||
} else {
|
||||
hlsl << "c[" << register_number << "]";
|
||||
}
|
||||
|
@ -1891,7 +1891,7 @@ static void ParameterHlsl(std::stringstream& hlsl, VSH_IMD_PARAMETER& paramMeta)
|
|||
}
|
||||
}
|
||||
|
||||
static void BuildShader(std::stringstream& hlsl, VSH_XBOX_SHADER* pShader)
|
||||
static void BuildShader(std::stringstream& hlsl, VSH_XBOX_SHADER* pShader)
|
||||
{
|
||||
// HLSL strings for all MAC opcodes, indexed with VSH_MAC
|
||||
static std::string VSH_MAC_HLSL[/*VSH_MAC*/] = {
|
||||
|
@ -1927,33 +1927,33 @@ static void BuildShader(std::stringstream& hlsl, VSH_XBOX_SHADER* pShader)
|
|||
|
||||
for (int i = 0; i < pShader->IntermediateCount; i++) {
|
||||
VSH_INTERMEDIATE_FORMAT& xboxInstruction = pShader->Intermediate[i];
|
||||
|
||||
|
||||
std::string str = "";
|
||||
if (xboxInstruction.InstructionType == IMD_MAC) {
|
||||
if (xboxInstruction.MAC > MAC_NOP && xboxInstruction.MAC <= MAC_ARL) {
|
||||
str = VSH_MAC_HLSL[xboxInstruction.MAC];
|
||||
if (xboxInstruction.InstructionType == IMD_MAC) {
|
||||
if (xboxInstruction.MAC > MAC_NOP && xboxInstruction.MAC <= MAC_ARL) {
|
||||
str = VSH_MAC_HLSL[xboxInstruction.MAC];
|
||||
}
|
||||
} else if (xboxInstruction.InstructionType == IMD_ILU) {
|
||||
if (xboxInstruction.ILU > ILU_NOP) {
|
||||
str = VSH_ILU_HLSL[xboxInstruction.ILU];
|
||||
if (xboxInstruction.ILU > ILU_NOP) {
|
||||
str = VSH_ILU_HLSL[xboxInstruction.ILU];
|
||||
}
|
||||
}
|
||||
|
||||
if (!str.empty()) {
|
||||
hlsl << "\n " << str << "("; // opcode
|
||||
OutputHlsl(hlsl, xboxInstruction.Output);
|
||||
}
|
||||
|
||||
if (!str.empty()) {
|
||||
hlsl << "\n " << str << "("; // opcode
|
||||
OutputHlsl(hlsl, xboxInstruction.Output);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (xboxInstruction.Parameters[i].Active) {
|
||||
hlsl << ", ";
|
||||
if (xboxInstruction.Parameters[i].Active) {
|
||||
hlsl << ", ";
|
||||
ParameterHlsl(hlsl, xboxInstruction.Parameters[i]);
|
||||
}
|
||||
}
|
||||
|
||||
hlsl << ");";
|
||||
}
|
||||
|
||||
hlsl << ");";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string DebugPrependLineNumbers(std::string shaderString) {
|
||||
std::stringstream shader(shaderString);
|
||||
auto debugShader = std::stringstream();
|
||||
|
@ -1994,11 +1994,11 @@ extern HRESULT EmuRecompileVshFunction
|
|||
*pbUseDeclarationOnly = 0;
|
||||
*pXboxFunctionSize = 0;
|
||||
*ppRecompiledShader = nullptr;
|
||||
|
||||
|
||||
if (!pShader) {
|
||||
EmuLog(LOG_LEVEL::WARNING, "Couldn't allocate memory for vertex shader conversion buffer");
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
pShader->ShaderHeader = *pXboxVertexShaderHeader;
|
||||
switch (pXboxVertexShaderHeader->Version) {
|
||||
|
@ -2022,8 +2022,8 @@ extern HRESULT EmuRecompileVshFunction
|
|||
static std::string hlsl_template =
|
||||
#include "core\hle\D3D8\Direct3D9\Xb.hlsl" // Note : This included .hlsl defines a raw string
|
||||
;
|
||||
|
||||
auto hlsl_stream = std::stringstream();
|
||||
|
||||
auto hlsl_stream = std::stringstream();
|
||||
|
||||
for (pToken = (DWORD*)((uint8_t*)pXboxFunction + sizeof(XTL::X_VSH_SHADER_HEADER)); !EOI; pToken += X_VSH_INSTRUCTION_SIZE) {
|
||||
VSH_SHADER_INSTRUCTION Inst;
|
||||
|
@ -2044,13 +2044,13 @@ extern HRESULT EmuRecompileVshFunction
|
|||
}
|
||||
|
||||
BuildShader(hlsl_stream, pShader);
|
||||
std::string hlsl_str = hlsl_stream.str();
|
||||
std::string hlsl_str = hlsl_stream.str();
|
||||
hlsl_str = std::regex_replace(hlsl_template, std::regex("// <Xbox Shader>"), hlsl_str);
|
||||
|
||||
DbgVshPrintf("--- HLSL conversion ---\n");
|
||||
DbgVshPrintf(DebugPrependLineNumbers(hlsl_str).c_str());
|
||||
DbgVshPrintf("-----------------------\n");
|
||||
|
||||
|
||||
hRet = D3DCompile(
|
||||
hlsl_str.c_str(),
|
||||
hlsl_str.length(),
|
||||
|
@ -2064,7 +2064,7 @@ extern HRESULT EmuRecompileVshFunction
|
|||
ppRecompiledShader, // out
|
||||
&pErrors // ppErrorMsgs out
|
||||
);
|
||||
if (FAILED(hRet)) {
|
||||
if (FAILED(hRet)) {
|
||||
EmuLog(LOG_LEVEL::WARNING, "Couldn't assemble recompiled vertex shader");
|
||||
}
|
||||
|
||||
|
@ -2073,26 +2073,26 @@ extern HRESULT EmuRecompileVshFunction
|
|||
if (pErrors) {
|
||||
// Log HLSL compiler errors
|
||||
EmuLog(hlslErrorLogLevel, "%s", (char*)(pErrors->GetBufferPointer()));
|
||||
pErrors->Release();
|
||||
pErrors = nullptr;
|
||||
}
|
||||
|
||||
pErrors->Release();
|
||||
pErrors = nullptr;
|
||||
}
|
||||
|
||||
LOG_CHECK_ENABLED(LOG_LEVEL::DEBUG)
|
||||
if (g_bPrintfOn)
|
||||
if (!FAILED(hRet)) {
|
||||
if (g_bPrintfOn)
|
||||
if (!FAILED(hRet)) {
|
||||
// Log disassembly
|
||||
hRet = D3DDisassemble(
|
||||
(*ppRecompiledShader)->GetBufferPointer(),
|
||||
(*ppRecompiledShader)->GetBufferSize(),
|
||||
D3D_DISASM_ENABLE_DEFAULT_VALUE_PRINTS | D3D_DISASM_ENABLE_INSTRUCTION_NUMBERING,
|
||||
NULL,
|
||||
&pErrors
|
||||
);
|
||||
hRet = D3DDisassemble(
|
||||
(*ppRecompiledShader)->GetBufferPointer(),
|
||||
(*ppRecompiledShader)->GetBufferSize(),
|
||||
D3D_DISASM_ENABLE_DEFAULT_VALUE_PRINTS | D3D_DISASM_ENABLE_INSTRUCTION_NUMBERING,
|
||||
NULL,
|
||||
&pErrors
|
||||
);
|
||||
if (pErrors) {
|
||||
EmuLog(hlslErrorLogLevel, "%s", (char*)(pErrors->GetBufferPointer()));
|
||||
pErrors->Release();
|
||||
}
|
||||
}
|
||||
pErrors->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(pShader);
|
||||
|
|
Loading…
Reference in New Issue