diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/hle/service/filesystem/filesystem.cpp | 7 | ||||
-rw-r--r-- | src/video_core/engines/shader_bytecode.h | 15 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 29 | ||||
-rw-r--r-- | src/yuzu/main.cpp | 16 | ||||
-rw-r--r-- | src/yuzu/main.h | 2 |
5 files changed, 53 insertions, 16 deletions
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 881c39e31..a4426af96 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -60,17 +60,20 @@ ResultCode VfsDirectoryServiceWrapper::CreateFile(const std::string& path_, u64 ResultCode VfsDirectoryServiceWrapper::DeleteFile(const std::string& path_) const { std::string path(FileUtil::SanitizePath(path_)); - auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path)); if (path.empty()) { // TODO(DarkLordZach): Why do games call this and what should it do? Works as is but... return RESULT_SUCCESS; } - if (dir->GetFile(FileUtil::GetFilename(path)) == nullptr) + + auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path)); + if (dir->GetFile(FileUtil::GetFilename(path)) == nullptr) { return FileSys::ERROR_PATH_NOT_FOUND; + } if (!dir->DeleteFile(FileUtil::GetFilename(path))) { // TODO(DarkLordZach): Find a better error code for this return ResultCode(-1); } + return RESULT_SUCCESS; } diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 3e4efbe0c..a7daea766 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h @@ -243,7 +243,8 @@ enum class TextureType : u64 { TextureCube = 3, }; -enum class IpaMode : u64 { Pass = 0, None = 1, Constant = 2, Sc = 3 }; +enum class IpaInterpMode : u64 { Linear = 0, Perspective = 1, Flat = 2, Sc = 3 }; +enum class IpaSampleMode : u64 { Default = 0, Centroid = 1, Offset = 2 }; union Instruction { Instruction& operator=(const Instruction& instr) { @@ -328,10 +329,16 @@ union Instruction { } alu; union { - BitField<54, 3, IpaMode> mode; + BitField<51, 1, u64> saturate; + BitField<52, 2, IpaSampleMode> sample_mode; + BitField<54, 2, IpaInterpMode> interp_mode; } ipa; union { + BitField<39, 2, u64> tab5cb8_2; + BitField<41, 3, u64> tab5c68_1; + BitField<44, 2, u64> tab5c68_0; + BitField<47, 1, u64> cc; BitField<48, 1, u64> negate_b; } fmul; @@ -399,8 +406,11 @@ union Instruction { } flow; union { + BitField<47, 1, u64> cc; BitField<48, 1, u64> negate_b; BitField<49, 1, u64> negate_c; + BitField<51, 2, u64> tab5980_1; + BitField<53, 2, u64> tab5980_0; } ffma; union { @@ -509,6 +519,7 @@ union Instruction { union { BitField<0, 8, Register> gpr0; BitField<28, 8, Register> gpr28; + BitField<49, 1, u64> nodep; BitField<50, 3, u64> component_mask_selector; BitField<53, 4, u64> texture_info; diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 391c92d47..c4e7e1e3b 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -887,6 +887,8 @@ private: // TEXS has two destination registers and a swizzle. The first two elements in the swizzle // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1 + ASSERT_MSG(instr.texs.nodep == 0, "TEXS nodep not implemented"); + size_t written_components = 0; for (u32 component = 0; component < 4; ++component) { if (!instr.texs.IsComponentEnabled(component)) { @@ -1038,6 +1040,15 @@ private: case OpCode::Id::FMUL_R: case OpCode::Id::FMUL_IMM: { // FMUL does not have 'abs' bits and only the second operand has a 'neg' bit. + ASSERT_MSG(instr.fmul.tab5cb8_2 == 0, "FMUL tab5cb8_2({}) is not implemented", + instr.fmul.tab5cb8_2.Value()); + ASSERT_MSG(instr.fmul.tab5c68_1 == 0, "FMUL tab5cb8_1({}) is not implemented", + instr.fmul.tab5c68_1.Value()); + ASSERT_MSG(instr.fmul.tab5c68_0 == 1, "FMUL tab5cb8_0({}) is not implemented", + instr.fmul.tab5c68_0 + .Value()); // SMO typical sends 1 here which seems to be the default + ASSERT_MSG(instr.fmul.cc == 0, "FMUL cc is not implemented"); + op_b = GetOperandAbsNeg(op_b, false, instr.fmul.negate_b); regs.SetRegisterToFloat(instr.gpr0, 0, op_a + " * " + op_b, 1, 1, instr.alu.saturate_d); @@ -1436,6 +1447,12 @@ private: std::string op_b = instr.ffma.negate_b ? "-" : ""; std::string op_c = instr.ffma.negate_c ? "-" : ""; + ASSERT_MSG(instr.ffma.cc == 0, "FFMA cc not implemented"); + ASSERT_MSG(instr.ffma.tab5980_0 == 1, "FFMA tab5980_0({}) not implemented", + instr.ffma.tab5980_0.Value()); // Seems to be 1 by default based on SMO + ASSERT_MSG(instr.ffma.tab5980_1 == 0, "FFMA tab5980_1({}) not implemented", + instr.ffma.tab5980_1.Value()); + switch (opcode->GetId()) { case OpCode::Id::FFMA_CR: { op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset, @@ -2110,8 +2127,12 @@ private: case OpCode::Id::IPA: { const auto& attribute = instr.attribute.fmt28; const auto& reg = instr.gpr0; - switch (instr.ipa.mode) { - case Tegra::Shader::IpaMode::Pass: + ASSERT_MSG(instr.ipa.sample_mode == Tegra::Shader::IpaSampleMode::Default, + "Unhandled IPA sample mode: {}", + static_cast<u32>(instr.ipa.sample_mode.Value())); + ASSERT_MSG(instr.ipa.saturate == 0, "IPA saturate not implemented"); + switch (instr.ipa.interp_mode) { + case Tegra::Shader::IpaInterpMode::Linear: if (stage == Maxwell3D::Regs::ShaderStage::Fragment && attribute.index == Attribute::Index::Position) { switch (attribute.element) { @@ -2132,12 +2153,12 @@ private: regs.SetRegisterToInputAttibute(reg, attribute.element, attribute.index); } break; - case Tegra::Shader::IpaMode::None: + case Tegra::Shader::IpaInterpMode::Perspective: regs.SetRegisterToInputAttibute(reg, attribute.element, attribute.index); break; default: LOG_CRITICAL(HW_GPU, "Unhandled IPA mode: {}", - static_cast<u32>(instr.ipa.mode.Value())); + static_cast<u32>(instr.ipa.interp_mode.Value())); UNREACHABLE(); regs.SetRegisterToInputAttibute(reg, attribute.element, attribute.index); } diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index e11ba7854..cfc48a416 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -419,7 +419,7 @@ void GMainWindow::OnDisplayTitleBars(bool show) { } } -bool GMainWindow::SupportsRequiredGLExtensions() { +QStringList GMainWindow::GetUnsupportedGLExtensions() { QStringList unsupported_ext; if (!GLAD_GL_ARB_program_interface_query) @@ -446,7 +446,7 @@ bool GMainWindow::SupportsRequiredGLExtensions() { for (const QString& ext : unsupported_ext) LOG_CRITICAL(Frontend, "Unsupported GL extension: {}", ext.toStdString()); - return unsupported_ext.empty(); + return unsupported_ext; } bool GMainWindow::LoadROM(const QString& filename) { @@ -464,11 +464,13 @@ bool GMainWindow::LoadROM(const QString& filename) { return false; } - if (!SupportsRequiredGLExtensions()) { - QMessageBox::critical( - this, tr("Error while initializing OpenGL Core!"), - tr("Your GPU may not support one or more required OpenGL extensions. Please " - "ensure you have the latest graphics driver. See the log for more details.")); + QStringList unsupported_gl_extensions = GetUnsupportedGLExtensions(); + if (!unsupported_gl_extensions.empty()) { + QMessageBox::critical(this, tr("Error while initializing OpenGL Core!"), + tr("Your GPU may not support one or more required OpenGL" + "extensions. Please ensure you have the latest graphics " + "driver.<br><br>Unsupported extensions:<br>") + + unsupported_gl_extensions.join("<br>")); return false; } diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 0b97e8220..3d6ebe329 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -85,7 +85,7 @@ private: void ConnectWidgetEvents(); void ConnectMenuEvents(); - bool SupportsRequiredGLExtensions(); + QStringList GetUnsupportedGLExtensions(); bool LoadROM(const QString& filename); void BootGame(const QString& filename); void ShutdownGame(); |