mirror of https://github.com/cemu-project/Cemu.git
Merge branch 'cemu-project:main' into readback-vk-fixes
This commit is contained in:
commit
31c6ddd0fd
|
@ -345,7 +345,7 @@ GraphicPack2::GraphicPack2(fs::path rulesPath, IniParser& rules)
|
||||||
const auto preset_name = rules.FindOption("name");
|
const auto preset_name = rules.FindOption("name");
|
||||||
if (!preset_name)
|
if (!preset_name)
|
||||||
{
|
{
|
||||||
cemuLog_log(LogType::Force, "Graphic pack \"{}\": Preset in line {} skipped because it has no name option defined", m_name, rules.GetCurrentSectionLineNumber());
|
cemuLog_log(LogType::Force, "Graphic pack \"{}\": Preset in line {} skipped because it has no name option defined", GetNormalizedPathString(), rules.GetCurrentSectionLineNumber());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,7 +369,7 @@ GraphicPack2::GraphicPack2(fs::path rulesPath, IniParser& rules)
|
||||||
}
|
}
|
||||||
catch (const std::exception & ex)
|
catch (const std::exception & ex)
|
||||||
{
|
{
|
||||||
cemuLog_log(LogType::Force, "Graphic pack \"{}\": Can't parse preset \"{}\": {}", m_name, *preset_name, ex.what());
|
cemuLog_log(LogType::Force, "Graphic pack \"{}\": Can't parse preset \"{}\": {}", GetNormalizedPathString(), *preset_name, ex.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (boost::iequals(currentSectionName, "RAM"))
|
else if (boost::iequals(currentSectionName, "RAM"))
|
||||||
|
@ -383,7 +383,7 @@ GraphicPack2::GraphicPack2(fs::path rulesPath, IniParser& rules)
|
||||||
{
|
{
|
||||||
if (m_version <= 5)
|
if (m_version <= 5)
|
||||||
{
|
{
|
||||||
cemuLog_log(LogType::Force, "Graphic pack \"{}\": [RAM] options are only available for graphic pack version 6 or higher", m_name, optionNameBuf);
|
cemuLog_log(LogType::Force, "Graphic pack \"{}\": [RAM] options are only available for graphic pack version 6 or higher", GetNormalizedPathString(), optionNameBuf);
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,12 +393,12 @@ GraphicPack2::GraphicPack2(fs::path rulesPath, IniParser& rules)
|
||||||
{
|
{
|
||||||
if (addrEnd <= addrStart)
|
if (addrEnd <= addrStart)
|
||||||
{
|
{
|
||||||
cemuLog_log(LogType::Force, "Graphic pack \"{}\": start address (0x{:08x}) must be greater than end address (0x{:08x}) for {}", m_name, addrStart, addrEnd, optionNameBuf);
|
cemuLog_log(LogType::Force, "Graphic pack \"{}\": start address (0x{:08x}) must be greater than end address (0x{:08x}) for {}", GetNormalizedPathString(), addrStart, addrEnd, optionNameBuf);
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
else if ((addrStart & 0xFFF) != 0 || (addrEnd & 0xFFF) != 0)
|
else if ((addrStart & 0xFFF) != 0 || (addrEnd & 0xFFF) != 0)
|
||||||
{
|
{
|
||||||
cemuLog_log(LogType::Force, "Graphic pack \"{}\": addresses for %s are not aligned to 0x1000", m_name, optionNameBuf);
|
cemuLog_log(LogType::Force, "Graphic pack \"{}\": addresses for %s are not aligned to 0x1000", GetNormalizedPathString(), optionNameBuf);
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -408,7 +408,7 @@ GraphicPack2::GraphicPack2(fs::path rulesPath, IniParser& rules)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cemuLog_log(LogType::Force, "Graphic pack \"{}\": has invalid syntax for option {}", m_name, optionNameBuf);
|
cemuLog_log(LogType::Force, "Graphic pack \"{}\": has invalid syntax for option {}", GetNormalizedPathString(), optionNameBuf);
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -422,24 +422,32 @@ GraphicPack2::GraphicPack2(fs::path rulesPath, IniParser& rules)
|
||||||
std::unordered_map<std::string, std::vector<PresetPtr>> tmp_map;
|
std::unordered_map<std::string, std::vector<PresetPtr>> tmp_map;
|
||||||
|
|
||||||
// all vars must be defined in the default preset vars before
|
// all vars must be defined in the default preset vars before
|
||||||
for (const auto& entry : m_presets)
|
std::vector<std::pair<std::string, std::string>> mismatchingPresetVars;
|
||||||
|
for (const auto& presetEntry : m_presets)
|
||||||
{
|
{
|
||||||
tmp_map[entry->category].emplace_back(entry);
|
tmp_map[presetEntry->category].emplace_back(presetEntry);
|
||||||
|
|
||||||
for (auto& kv : entry->variables)
|
for (auto& presetVar : presetEntry->variables)
|
||||||
{
|
{
|
||||||
const auto it = m_preset_vars.find(kv.first);
|
const auto it = m_preset_vars.find(presetVar.first);
|
||||||
if (it == m_preset_vars.cend())
|
if (it == m_preset_vars.cend())
|
||||||
{
|
{
|
||||||
cemuLog_log(LogType::Force, "Graphic pack: \"{}\" contains preset variables which are not defined in the default section", m_name);
|
mismatchingPresetVars.emplace_back(presetEntry->name, presetVar.first);
|
||||||
throw std::exception();
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// overwrite var type with default var type
|
// overwrite var type with default var type
|
||||||
kv.second.first = it->second.first;
|
presetVar.second.first = it->second.first;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!mismatchingPresetVars.empty())
|
||||||
|
{
|
||||||
|
cemuLog_log(LogType::Force, "Graphic pack \"{}\" contains preset variables which are not defined in the [Default] section:", GetNormalizedPathString());
|
||||||
|
for (const auto& [presetName, varName] : mismatchingPresetVars)
|
||||||
|
cemuLog_log(LogType::Force, "Preset: {} Variable: {}", presetName, varName);
|
||||||
|
throw std::exception();
|
||||||
|
}
|
||||||
|
|
||||||
// have first entry be default active for every category if no default= is set
|
// have first entry be default active for every category if no default= is set
|
||||||
for(auto entry : get_values(tmp_map))
|
for(auto entry : get_values(tmp_map))
|
||||||
{
|
{
|
||||||
|
@ -469,7 +477,7 @@ GraphicPack2::GraphicPack2(fs::path rulesPath, IniParser& rules)
|
||||||
auto& p2 = kv.second[i + 1];
|
auto& p2 = kv.second[i + 1];
|
||||||
if (p1->variables.size() != p2->variables.size())
|
if (p1->variables.size() != p2->variables.size())
|
||||||
{
|
{
|
||||||
cemuLog_log(LogType::Force, "Graphic pack: \"{}\" contains inconsistent preset variables", m_name);
|
cemuLog_log(LogType::Force, "Graphic pack: \"{}\" contains inconsistent preset variables", GetNormalizedPathString());
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -477,14 +485,14 @@ GraphicPack2::GraphicPack2(fs::path rulesPath, IniParser& rules)
|
||||||
std::set<std::string> keys2(get_keys(p2->variables).begin(), get_keys(p2->variables).end());
|
std::set<std::string> keys2(get_keys(p2->variables).begin(), get_keys(p2->variables).end());
|
||||||
if (keys1 != keys2)
|
if (keys1 != keys2)
|
||||||
{
|
{
|
||||||
cemuLog_log(LogType::Force, "Graphic pack: \"{}\" contains inconsistent preset variables", m_name);
|
cemuLog_log(LogType::Force, "Graphic pack: \"{}\" contains inconsistent preset variables", GetNormalizedPathString());
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(p1->is_default)
|
if(p1->is_default)
|
||||||
{
|
{
|
||||||
if(has_default)
|
if(has_default)
|
||||||
cemuLog_log(LogType::Force, "Graphic pack: \"{}\" has more than one preset with the default key set for the same category \"{}\"", m_name, p1->name);
|
cemuLog_log(LogType::Force, "Graphic pack: \"{}\" has more than one preset with the default key set for the same category \"{}\"", GetNormalizedPathString(), p1->name);
|
||||||
p1->active = true;
|
p1->active = true;
|
||||||
has_default = true;
|
has_default = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -370,6 +370,8 @@ bool LatteDecompiler_IsALUTransInstruction(bool isOP3, uint32 opcode)
|
||||||
opcode == ALU_OP2_INST_LSHR_INT ||
|
opcode == ALU_OP2_INST_LSHR_INT ||
|
||||||
opcode == ALU_OP2_INST_MAX_INT ||
|
opcode == ALU_OP2_INST_MAX_INT ||
|
||||||
opcode == ALU_OP2_INST_MIN_INT ||
|
opcode == ALU_OP2_INST_MIN_INT ||
|
||||||
|
opcode == ALU_OP2_INST_MAX_UINT ||
|
||||||
|
opcode == ALU_OP2_INST_MIN_UINT ||
|
||||||
opcode == ALU_OP2_INST_MOVA_FLOOR ||
|
opcode == ALU_OP2_INST_MOVA_FLOOR ||
|
||||||
opcode == ALU_OP2_INST_MOVA_INT ||
|
opcode == ALU_OP2_INST_MOVA_INT ||
|
||||||
opcode == ALU_OP2_INST_SETE_DX10 ||
|
opcode == ALU_OP2_INST_SETE_DX10 ||
|
||||||
|
|
|
@ -140,6 +140,8 @@ bool _isIntegerInstruction(const LatteDecompilerALUInstruction& aluInstruction)
|
||||||
case ALU_OP2_INST_SUB_INT:
|
case ALU_OP2_INST_SUB_INT:
|
||||||
case ALU_OP2_INST_MAX_INT:
|
case ALU_OP2_INST_MAX_INT:
|
||||||
case ALU_OP2_INST_MIN_INT:
|
case ALU_OP2_INST_MIN_INT:
|
||||||
|
case ALU_OP2_INST_MAX_UINT:
|
||||||
|
case ALU_OP2_INST_MIN_UINT:
|
||||||
case ALU_OP2_INST_SETE_INT:
|
case ALU_OP2_INST_SETE_INT:
|
||||||
case ALU_OP2_INST_SETGT_INT:
|
case ALU_OP2_INST_SETGT_INT:
|
||||||
case ALU_OP2_INST_SETGE_INT:
|
case ALU_OP2_INST_SETGE_INT:
|
||||||
|
|
|
@ -1415,19 +1415,23 @@ void _emitALUOP2InstructionCode(LatteDecompilerShaderContext* shaderContext, Lat
|
||||||
}
|
}
|
||||||
else if( aluInstruction->opcode == ALU_OP2_INST_ADD_INT )
|
else if( aluInstruction->opcode == ALU_OP2_INST_ADD_INT )
|
||||||
_emitALUOperationBinary<LATTE_DECOMPILER_DTYPE_SIGNED_INT>(shaderContext, aluInstruction, " + ");
|
_emitALUOperationBinary<LATTE_DECOMPILER_DTYPE_SIGNED_INT>(shaderContext, aluInstruction, " + ");
|
||||||
else if( aluInstruction->opcode == ALU_OP2_INST_MAX_INT || aluInstruction->opcode == ALU_OP2_INST_MIN_INT )
|
else if( aluInstruction->opcode == ALU_OP2_INST_MAX_INT || aluInstruction->opcode == ALU_OP2_INST_MIN_INT ||
|
||||||
|
aluInstruction->opcode == ALU_OP2_INST_MAX_UINT || aluInstruction->opcode == ALU_OP2_INST_MIN_UINT)
|
||||||
{
|
{
|
||||||
// not verified
|
// not verified
|
||||||
|
bool isUnsigned = aluInstruction->opcode == ALU_OP2_INST_MAX_UINT || aluInstruction->opcode == ALU_OP2_INST_MIN_UINT;
|
||||||
|
auto opType = isUnsigned ? LATTE_DECOMPILER_DTYPE_UNSIGNED_INT : LATTE_DECOMPILER_DTYPE_SIGNED_INT;
|
||||||
_emitInstructionOutputVariableName(shaderContext, aluInstruction);
|
_emitInstructionOutputVariableName(shaderContext, aluInstruction);
|
||||||
if( aluInstruction->opcode == ALU_OP2_INST_MAX_INT )
|
src->add(" = ");
|
||||||
src->add(" = max(");
|
_emitTypeConversionPrefix(shaderContext, opType, outputType);
|
||||||
|
if( aluInstruction->opcode == ALU_OP2_INST_MAX_INT || aluInstruction->opcode == ALU_OP2_INST_MAX_UINT )
|
||||||
|
src->add("max(");
|
||||||
else
|
else
|
||||||
src->add(" = min(");
|
src->add("min(");
|
||||||
_emitTypeConversionPrefix(shaderContext, LATTE_DECOMPILER_DTYPE_SIGNED_INT, outputType);
|
_emitOperandInputCode(shaderContext, aluInstruction, 0, opType);
|
||||||
_emitOperandInputCode(shaderContext, aluInstruction, 0, LATTE_DECOMPILER_DTYPE_SIGNED_INT);
|
|
||||||
src->add(", ");
|
src->add(", ");
|
||||||
_emitOperandInputCode(shaderContext, aluInstruction, 1, LATTE_DECOMPILER_DTYPE_SIGNED_INT);
|
_emitOperandInputCode(shaderContext, aluInstruction, 1, opType);
|
||||||
_emitTypeConversionSuffix(shaderContext, LATTE_DECOMPILER_DTYPE_SIGNED_INT, outputType);
|
_emitTypeConversionSuffix(shaderContext, opType, outputType);
|
||||||
src->add(");" _CRLF);
|
src->add(");" _CRLF);
|
||||||
}
|
}
|
||||||
else if( aluInstruction->opcode == ALU_OP2_INST_SUB_INT )
|
else if( aluInstruction->opcode == ALU_OP2_INST_SUB_INT )
|
||||||
|
|
|
@ -60,6 +60,8 @@
|
||||||
#define ALU_OP2_INST_SUB_INT (0x035) // integer instruction
|
#define ALU_OP2_INST_SUB_INT (0x035) // integer instruction
|
||||||
#define ALU_OP2_INST_MAX_INT (0x036) // integer instruction
|
#define ALU_OP2_INST_MAX_INT (0x036) // integer instruction
|
||||||
#define ALU_OP2_INST_MIN_INT (0x037) // integer instruction
|
#define ALU_OP2_INST_MIN_INT (0x037) // integer instruction
|
||||||
|
#define ALU_OP2_INST_MAX_UINT (0x038) // integer instruction
|
||||||
|
#define ALU_OP2_INST_MIN_UINT (0x039) // integer instruction
|
||||||
#define ALU_OP2_INST_SETE_INT (0x03A) // integer instruction
|
#define ALU_OP2_INST_SETE_INT (0x03A) // integer instruction
|
||||||
#define ALU_OP2_INST_SETGT_INT (0x03B) // integer instruction
|
#define ALU_OP2_INST_SETGT_INT (0x03B) // integer instruction
|
||||||
#define ALU_OP2_INST_SETGE_INT (0x03C) // integer instruction
|
#define ALU_OP2_INST_SETGE_INT (0x03C) // integer instruction
|
||||||
|
|
|
@ -1114,13 +1114,13 @@ namespace coreinit
|
||||||
thread->requestFlags = (OSThread_t::REQUEST_FLAG_BIT)(thread->requestFlags & OSThread_t::REQUEST_FLAG_CANCEL); // remove all flags except cancel flag
|
thread->requestFlags = (OSThread_t::REQUEST_FLAG_BIT)(thread->requestFlags & OSThread_t::REQUEST_FLAG_CANCEL); // remove all flags except cancel flag
|
||||||
|
|
||||||
// update total cycles
|
// update total cycles
|
||||||
uint64 remainingCycles = std::min((uint64)hCPU->remainingCycles, (uint64)thread->quantumTicks);
|
sint64 executedCycles = (sint64)thread->quantumTicks - (sint64)hCPU->remainingCycles;
|
||||||
uint64 executedCycles = thread->quantumTicks - remainingCycles;
|
executedCycles = std::max<sint64>(executedCycles, 0);
|
||||||
if (executedCycles < hCPU->skippedCycles)
|
if (executedCycles < (sint64)hCPU->skippedCycles)
|
||||||
executedCycles = 0;
|
executedCycles = 0;
|
||||||
else
|
else
|
||||||
executedCycles -= hCPU->skippedCycles;
|
executedCycles -= hCPU->skippedCycles;
|
||||||
thread->totalCycles += executedCycles;
|
thread->totalCycles += (uint64)executedCycles;
|
||||||
// store context and set current thread to null
|
// store context and set current thread to null
|
||||||
__OSThreadStoreContext(hCPU, thread);
|
__OSThreadStoreContext(hCPU, thread);
|
||||||
OSSetCurrentThread(OSGetCoreId(), nullptr);
|
OSSetCurrentThread(OSGetCoreId(), nullptr);
|
||||||
|
|
|
@ -421,7 +421,7 @@ namespace GX2
|
||||||
{
|
{
|
||||||
if(aluRegisterOffset&0x8000)
|
if(aluRegisterOffset&0x8000)
|
||||||
{
|
{
|
||||||
cemuLog_logDebug(LogType::Force, "_GX2SubmitUniformReg(): Unhandled loop const special case or invalid offset");
|
cemuLog_logDebugOnce(LogType::Force, "_GX2SubmitUniformReg(): Unhandled loop const special case or invalid offset");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if((aluRegisterOffset+sizeInU32s) > 0x400)
|
if((aluRegisterOffset+sizeInU32s) > 0x400)
|
||||||
|
|
|
@ -675,6 +675,7 @@ namespace nsyshid
|
||||||
|
|
||||||
figureChangeResponse[13] = GenerateChecksum(figureChangeResponse, 13);
|
figureChangeResponse[13] = GenerateChecksum(figureChangeResponse, 13);
|
||||||
m_figureAddedRemovedResponses.push(figureChangeResponse);
|
m_figureAddedRemovedResponses.push(figureChangeResponse);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DimensionsUSB::CancelRemove(uint8 index)
|
bool DimensionsUSB::CancelRemove(uint8 index)
|
||||||
|
|
|
@ -198,14 +198,20 @@ bool ActiveSettings::ShaderPreventInfiniteLoopsEnabled()
|
||||||
{
|
{
|
||||||
const uint64 titleId = CafeSystem::GetForegroundTitleId();
|
const uint64 titleId = CafeSystem::GetForegroundTitleId();
|
||||||
// workaround for NSMBU (and variants) having a bug where shaders can get stuck in infinite loops
|
// workaround for NSMBU (and variants) having a bug where shaders can get stuck in infinite loops
|
||||||
// update: As of Cemu 1.20.0 this should no longer be required
|
// Fatal Frame has an actual infinite loop in shader 0xb6a67c19f6472e00 encountered during a cutscene for the second drop (eShop version only?)
|
||||||
|
// update: As of Cemu 1.20.0 this should no longer be required for NSMBU/NSLU due to fixes with uniform handling. But we leave it here for good measure
|
||||||
|
// todo - Once we add support for loop config registers this workaround should become unnecessary
|
||||||
return /* NSMBU JP */ titleId == 0x0005000010101C00 ||
|
return /* NSMBU JP */ titleId == 0x0005000010101C00 ||
|
||||||
/* NSMBU US */ titleId == 0x0005000010101D00 ||
|
/* NSMBU US */ titleId == 0x0005000010101D00 ||
|
||||||
/* NSMBU EU */ titleId == 0x0005000010101E00 ||
|
/* NSMBU EU */ titleId == 0x0005000010101E00 ||
|
||||||
/* NSMBU+L US */ titleId == 0x000500001014B700 ||
|
/* NSMBU+L US */ titleId == 0x000500001014B700 ||
|
||||||
/* NSMBU+L EU */ titleId == 0x000500001014B800 ||
|
/* NSMBU+L EU */ titleId == 0x000500001014B800 ||
|
||||||
/* NSLU US */ titleId == 0x0005000010142300 ||
|
/* NSLU US */ titleId == 0x0005000010142300 ||
|
||||||
/* NSLU EU */ titleId == 0x0005000010142400;
|
/* NSLU EU */ titleId == 0x0005000010142400 ||
|
||||||
|
/* Project Zero: Maiden of Black Water (EU) */ titleId == 0x00050000101D0300 ||
|
||||||
|
/* Fatal Frame: Maiden of Black Water (US) */ titleId == 0x00050000101D0600 ||
|
||||||
|
/* Project Zero: Maiden of Black Water (JP) */ titleId == 0x000500001014D200 ||
|
||||||
|
/* Project Zero: Maiden of Black Water (Trial, EU) */ titleId == 0x00050000101D3F00;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ActiveSettings::FlushGPUCacheOnSwap()
|
bool ActiveSettings::FlushGPUCacheOnSwap()
|
||||||
|
|
|
@ -408,7 +408,7 @@ bool VPADController::push_rumble(uint8* pattern, uint8 length)
|
||||||
std::scoped_lock lock(m_rumble_mutex);
|
std::scoped_lock lock(m_rumble_mutex);
|
||||||
if (m_rumble_queue.size() >= 5)
|
if (m_rumble_queue.size() >= 5)
|
||||||
{
|
{
|
||||||
cemuLog_logDebug(LogType::Force, "too many cmds");
|
cemuLog_logDebugOnce(LogType::Force, "VPADControlMotor(): Pattern too long");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue