From 50a51657b0c1bd46f738f2cec265f50f98826551 Mon Sep 17 00:00:00 2001 From: PatrickvL Date: Thu, 12 Dec 2019 14:36:14 +0100 Subject: [PATCH] Force A0's X mask during decoding (in VshAddInstructionMAC_ARL) instead of HLSL conversion (in OutputHlsl) Also applied Unix EOL style (again) --- src/core/hle/D3D8/XbVertexShader.cpp | 170 +++++++++++++-------------- 1 file changed, 85 insertions(+), 85 deletions(-) diff --git a/src/core/hle/D3D8/XbVertexShader.cpp b/src/core/hle/D3D8/XbVertexShader.cpp index 09ad36ded..bfa816d8a 100644 --- a/src/core/hle/D3D8/XbVertexShader.cpp +++ b/src/core/hle/D3D8/XbVertexShader.cpp @@ -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("// "), 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);