summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/ipc.h2
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp4
-rw-r--r--src/core/hle/result.h46
-rw-r--r--src/core/hle/service/fatal/fatal.cpp4
-rw-r--r--src/core/hle/service/fatal/fatal.h4
-rw-r--r--src/core/hle/service/fatal/fatal_u.cpp5
-rw-r--r--src/core/hle/service/nfp/nfp.cpp48
-rw-r--r--src/core/hle/service/service.cpp2
-rw-r--r--src/video_core/engines/shader_bytecode.h8
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp8
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h8
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp27
-rw-r--r--src/video_core/renderer_opengl/gl_shader_util.h27
-rw-r--r--src/yuzu/debugger/wait_tree.cpp26
-rw-r--r--src/yuzu/debugger/wait_tree.h11
15 files changed, 174 insertions, 56 deletions
diff --git a/src/core/hle/ipc.h b/src/core/hle/ipc.h
index ef6595550..c9257de77 100644
--- a/src/core/hle/ipc.h
+++ b/src/core/hle/ipc.h
@@ -32,6 +32,8 @@ enum class CommandType : u32 {
Close = 2,
Request = 4,
Control = 5,
+ RequestWithContext = 6,
+ ControlWithContext = 7,
Unspecified,
};
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index 349bc11df..01904467e 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -110,7 +110,9 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {
// Padding to align to 16 bytes
rp.AlignWithPadding();
- if (Session()->IsDomain() && (command_header->type == IPC::CommandType::Request || !incoming)) {
+ if (Session()->IsDomain() && ((command_header->type == IPC::CommandType::Request ||
+ command_header->type == IPC::CommandType::RequestWithContext) ||
+ !incoming)) {
// If this is an incoming message, only CommandType "Request" has a domain header
// All outgoing domain messages have the domain header, if only incoming has it
if (incoming || domain_message_header) {
diff --git a/src/core/hle/result.h b/src/core/hle/result.h
index 052f49979..e3eda4f54 100644
--- a/src/core/hle/result.h
+++ b/src/core/hle/result.h
@@ -42,41 +42,75 @@ enum class ErrorModule : u32 {
PM = 15,
NS = 16,
HTC = 18,
+ NCMContent = 20,
SM = 21,
RO = 22,
SDMMC = 24,
+ OVLN = 25,
SPL = 26,
ETHC = 100,
I2C = 101,
+ GPIO = 102,
+ UART = 103,
Settings = 105,
+ WLAN = 107,
+ XCD = 108,
NIFM = 110,
- Display = 114,
- NTC = 116,
+ Hwopus = 111,
+ Bluetooth = 113,
+ VI = 114,
+ NFP = 115,
+ Time = 116,
FGM = 117,
- PCIE = 120,
+ PCIe = 120,
Friends = 121,
+ BCAT = 122,
SSL = 123,
Account = 124,
+ News = 125,
Mii = 126,
+ NFC = 127,
AM = 128,
PlayReport = 129,
+ AHID = 130,
+ Qlaunch = 132,
PCV = 133,
OMM = 134,
+ BPC = 135,
+ PSM = 136,
NIM = 137,
PSC = 138,
+ TC = 139,
USB = 140,
+ NSD = 141,
+ PCTL = 142,
BTM = 143,
+ ETicket = 145,
+ NGC = 146,
ERPT = 147,
APM = 148,
+ ErrorUpload = 151,
+ Audio = 153,
NPNS = 154,
+ NPNSHTTPSTREAM = 155,
ARP = 157,
BOOT = 158,
- NFC = 161,
+ NFCMifare = 161,
UserlandAssert = 162,
+ Fatal = 163,
+ NIMShop = 164,
+ SPSM = 165,
+ BGTC = 167,
UserlandCrash = 168,
- HID = 203,
+ SREPO = 180,
+ HID = 202,
+ LDN = 203,
+ Irsensor = 205,
Capture = 206,
- TC = 651,
+ Manu = 208,
+ GRC = 212,
+ Migration = 216,
+ MigrationLdcServ = 217,
GeneralWebApplet = 800,
WifiWebAuthApplet = 809,
WhitelistedApplet = 810,
diff --git a/src/core/hle/service/fatal/fatal.cpp b/src/core/hle/service/fatal/fatal.cpp
index bb75e7314..2d4282209 100644
--- a/src/core/hle/service/fatal/fatal.cpp
+++ b/src/core/hle/service/fatal/fatal.cpp
@@ -13,7 +13,7 @@ namespace Service::Fatal {
Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
: ServiceFramework(name), module(std::move(module)) {}
-void Module::Interface::FatalSimple(Kernel::HLERequestContext& ctx) {
+void Module::Interface::ThrowFatalWithPolicy(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx);
u32 error_code = rp.Pop<u32>();
NGLOG_WARNING(Service_Fatal, "(STUBBED) called, error_code=0x{:X}", error_code);
@@ -21,7 +21,7 @@ void Module::Interface::FatalSimple(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS);
}
-void Module::Interface::TransitionToFatalError(Kernel::HLERequestContext& ctx) {
+void Module::Interface::ThrowFatalWithCpuContext(Kernel::HLERequestContext& ctx) {
NGLOG_WARNING(Service_Fatal, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
diff --git a/src/core/hle/service/fatal/fatal.h b/src/core/hle/service/fatal/fatal.h
index 2d8d08320..5bd111a14 100644
--- a/src/core/hle/service/fatal/fatal.h
+++ b/src/core/hle/service/fatal/fatal.h
@@ -14,8 +14,8 @@ public:
public:
Interface(std::shared_ptr<Module> module, const char* name);
- void FatalSimple(Kernel::HLERequestContext& ctx);
- void TransitionToFatalError(Kernel::HLERequestContext& ctx);
+ void ThrowFatalWithPolicy(Kernel::HLERequestContext& ctx);
+ void ThrowFatalWithCpuContext(Kernel::HLERequestContext& ctx);
protected:
std::shared_ptr<Module> module;
diff --git a/src/core/hle/service/fatal/fatal_u.cpp b/src/core/hle/service/fatal/fatal_u.cpp
index 26aa9f3b7..f0631329e 100644
--- a/src/core/hle/service/fatal/fatal_u.cpp
+++ b/src/core/hle/service/fatal/fatal_u.cpp
@@ -8,8 +8,9 @@ namespace Service::Fatal {
Fatal_U::Fatal_U(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "fatal:u") {
static const FunctionInfo functions[] = {
- {1, &Fatal_U::FatalSimple, "FatalSimple"},
- {2, &Fatal_U::TransitionToFatalError, "TransitionToFatalError"},
+ {0, nullptr, "ThrowFatal"},
+ {1, &Fatal_U::ThrowFatalWithPolicy, "ThrowFatalWithPolicy"},
+ {2, &Fatal_U::ThrowFatalWithCpuContext, "ThrowFatalWithCpuContext"},
};
RegisterHandlers(functions);
}
diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp
index cc0247881..2af4465de 100644
--- a/src/core/hle/service/nfp/nfp.cpp
+++ b/src/core/hle/service/nfp/nfp.cpp
@@ -17,30 +17,30 @@ public:
IUser() : ServiceFramework("IUser") {
static const FunctionInfo functions[] = {
{0, &IUser::Initialize, "Initialize"},
- {1, nullptr, "Unknown1"},
- {2, nullptr, "Unknown2"},
- {3, nullptr, "Unknown3"},
- {4, nullptr, "Unknown4"},
- {5, nullptr, "Unknown5"},
- {6, nullptr, "Unknown6"},
- {7, nullptr, "Unknown7"},
- {8, nullptr, "Unknown8"},
- {9, nullptr, "Unknown9"},
- {10, nullptr, "Unknown10"},
- {11, nullptr, "Unknown11"},
- {12, nullptr, "Unknown12"},
- {13, nullptr, "Unknown13"},
- {14, nullptr, "Unknown14"},
- {15, nullptr, "Unknown15"},
- {16, nullptr, "Unknown16"},
- {17, nullptr, "Unknown17"},
- {18, nullptr, "Unknown18"},
- {19, nullptr, "Unknown19"},
- {20, nullptr, "Unknown20"},
- {21, nullptr, "Unknown21"},
- {22, nullptr, "Unknown22"},
- {23, nullptr, "Unknown23"},
- {24, nullptr, "Unknown24"},
+ {1, nullptr, "Finalize"},
+ {2, nullptr, "ListDevices"},
+ {3, nullptr, "StartDetection"},
+ {4, nullptr, "StopDetection"},
+ {5, nullptr, "Mount"},
+ {6, nullptr, "Unmount"},
+ {7, nullptr, "OpenApplicationArea"},
+ {8, nullptr, "GetApplicationArea"},
+ {9, nullptr, "SetApplicationArea"},
+ {10, nullptr, "Flush"},
+ {11, nullptr, "Restore"},
+ {12, nullptr, "CreateApplicationArea"},
+ {13, nullptr, "GetTagInfo"},
+ {14, nullptr, "GetRegisterInfo"},
+ {15, nullptr, "GetCommonInfo"},
+ {16, nullptr, "GetModelInfo"},
+ {17, nullptr, "AttachActivateEvent"},
+ {18, nullptr, "AttachDeactivateEvent"},
+ {19, nullptr, "GetState"},
+ {20, nullptr, "GetDeviceState"},
+ {21, nullptr, "GetNpadId"},
+ {22, nullptr, "GetApplicationArea2"},
+ {23, nullptr, "AttachAvailabilityChangeEvent"},
+ {24, nullptr, "RecreateApplicationArea"},
};
RegisterHandlers(functions);
}
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index dc30702c6..5b91089cf 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -144,10 +144,12 @@ ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& co
rb.Push(RESULT_SUCCESS);
return ResultCode(ErrorModule::HIPC, ErrorDescription::RemoteProcessDead);
}
+ case IPC::CommandType::ControlWithContext:
case IPC::CommandType::Control: {
Core::System::GetInstance().ServiceManager().InvokeControlRequest(context);
break;
}
+ case IPC::CommandType::RequestWithContext:
case IPC::CommandType::Request: {
InvokeRequest(context);
break;
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index e1ceec268..8ea26c9c1 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -193,6 +193,11 @@ union Instruction {
BitField<50, 1, u64> abs_d;
BitField<56, 1, u64> negate_imm;
+ union {
+ BitField<39, 3, u64> pred;
+ BitField<42, 1, u64> negate_pred;
+ } fmnmx;
+
float GetImm20_19() const {
float result{};
u32 imm{static_cast<u32>(imm20_19)};
@@ -320,6 +325,7 @@ public:
ISETP_C,
ISETP_IMM,
ISETP_R,
+ PSETP,
};
enum class Type {
@@ -331,6 +337,7 @@ public:
FloatSet,
FloatSetPredicate,
IntegerSetPredicate,
+ PredicateSetPredicate,
Conversion,
Unknown,
};
@@ -477,6 +484,7 @@ private:
INST("010010110110----", Id::ISETP_C, Type::IntegerSetPredicate, "ISETP_C"),
INST("010110110110----", Id::ISETP_R, Type::IntegerSetPredicate, "ISETP_R"),
INST("0011011-0110----", Id::ISETP_IMM, Type::IntegerSetPredicate, "ISETP_IMM"),
+ INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"),
};
#undef INST
std::stable_sort(table.begin(), table.end(), [](const auto& a, const auto& b) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 907236136..35c1b1890 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -75,14 +75,11 @@ RasterizerOpenGL::RasterizerOpenGL() {
// Clipping plane 0 is always enabled for PICA fixed clip plane z <= 0
state.clip_distance[0] = true;
- // Generate VBO, VAO and UBO
- vertex_buffer = OGLStreamBuffer::MakeBuffer(GLAD_GL_ARB_buffer_storage, GL_ARRAY_BUFFER);
- vertex_buffer->Create(VERTEX_BUFFER_SIZE, VERTEX_BUFFER_SIZE / 2);
+ // Generate VAO and UBO
sw_vao.Create();
uniform_buffer.Create();
state.draw.vertex_array = sw_vao.handle;
- state.draw.vertex_buffer = vertex_buffer->GetHandle();
state.draw.uniform_buffer = uniform_buffer.handle;
state.Apply();
@@ -90,7 +87,6 @@ RasterizerOpenGL::RasterizerOpenGL() {
framebuffer.Create();
hw_vao.Create();
- hw_vao_enabled_attributes.fill(false);
stream_buffer = OGLStreamBuffer::MakeBuffer(has_ARB_buffer_storage, GL_ARRAY_BUFFER);
stream_buffer->Create(STREAM_BUFFER_SIZE, STREAM_BUFFER_SIZE / 2);
@@ -181,8 +177,6 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr,
glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset);
glVertexAttribBinding(index, attrib.buffer);
-
- hw_vao_enabled_attributes[index] = true;
}
return {array_ptr, buffer_offset};
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 9709e595e..4b915c76a 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -134,21 +134,17 @@ private:
std::unique_ptr<GLShader::ProgramManager> shader_program_manager;
OGLVertexArray sw_vao;
OGLVertexArray hw_vao;
- std::array<bool, 16> hw_vao_enabled_attributes;
std::array<SamplerInfo, GLShader::NumTextureSamplers> texture_samplers;
std::array<std::array<OGLBuffer, Tegra::Engines::Maxwell3D::Regs::MaxConstBuffers>,
Tegra::Engines::Maxwell3D::Regs::MaxShaderStage>
ssbos;
- static constexpr size_t VERTEX_BUFFER_SIZE = 128 * 1024 * 1024;
- std::unique_ptr<OGLStreamBuffer> vertex_buffer;
+ static constexpr size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;
+ std::unique_ptr<OGLStreamBuffer> stream_buffer;
OGLBuffer uniform_buffer;
OGLFramebuffer framebuffer;
- static constexpr size_t STREAM_BUFFER_SIZE = 4 * 1024 * 1024;
- std::unique_ptr<OGLStreamBuffer> stream_buffer;
-
size_t CalculateVertexArraysSize() const;
std::pair<u8*, GLintptr> SetupVertexArrays(u8* array_ptr, GLintptr buffer_offset);
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index abbf0893d..1aa24da46 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -580,14 +580,17 @@ private:
* @param instr Instruction to generate the if condition for.
* @returns string containing the predicate condition.
*/
- std::string GetPredicateCondition(Instruction instr) const {
+ std::string GetPredicateCondition(u64 index, bool negate) const {
using Tegra::Shader::Pred;
- ASSERT(instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex));
+ std::string variable;
- std::string variable =
- 'p' + std::to_string(static_cast<u64>(instr.pred.pred_index.Value()));
+ // Index 7 is used as an 'Always True' condition.
+ if (index == static_cast<u64>(Pred::UnusedIndex))
+ variable = "true";
+ else
+ variable = 'p' + std::to_string(index);
- if (instr.negate_pred) {
+ if (negate) {
return "!(" + variable + ')';
}
@@ -634,7 +637,9 @@ private:
"NeverExecute predicate not implemented");
if (instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)) {
- shader.AddLine("if (" + GetPredicateCondition(instr) + ')');
+ shader.AddLine("if (" +
+ GetPredicateCondition(instr.pred.pred_index, instr.negate_pred != 0) +
+ ')');
shader.AddLine('{');
++shader.scope;
}
@@ -730,6 +735,16 @@ private:
}
break;
}
+ case OpCode::Id::FMNMX: {
+ std::string condition =
+ GetPredicateCondition(instr.alu.fmnmx.pred, instr.alu.fmnmx.negate_pred != 0);
+ std::string parameters = op_a + ',' + op_b;
+ regs.SetRegisterToFloat(instr.gpr0, 0,
+ '(' + condition + ") ? min(" + parameters + ") : max(" +
+ parameters + ')',
+ 1, 1);
+ break;
+ }
case OpCode::Id::RRO: {
NGLOG_DEBUG(HW_GPU, "Skipping RRO instruction");
break;
diff --git a/src/video_core/renderer_opengl/gl_shader_util.h b/src/video_core/renderer_opengl/gl_shader_util.h
index a1fa9e814..2036a06a9 100644
--- a/src/video_core/renderer_opengl/gl_shader_util.h
+++ b/src/video_core/renderer_opengl/gl_shader_util.h
@@ -4,6 +4,7 @@
#pragma once
+#include <string>
#include <vector>
#include <glad/glad.h>
#include "common/assert.h"
@@ -12,6 +13,27 @@
namespace GLShader {
/**
+ * Utility function to log the source code of a list of shaders.
+ * @param shaders The OpenGL shaders whose source we will print.
+ */
+template <typename... T>
+void LogShaderSource(T... shaders) {
+ auto shader_list = {shaders...};
+
+ for (const auto& shader : shader_list) {
+ if (shader == 0)
+ continue;
+
+ GLint source_length;
+ glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &source_length);
+
+ std::string source(source_length, ' ');
+ glGetShaderSource(shader, source_length, nullptr, &source[0]);
+ NGLOG_INFO(Render_OpenGL, "Shader source {}", source);
+ }
+}
+
+/**
* Utility function to create and compile an OpenGL GLSL shader
* @param source String of the GLSL shader program
* @param type Type of the shader (GL_VERTEX_SHADER, GL_GEOMETRY_SHADER or GL_FRAGMENT_SHADER)
@@ -55,6 +77,11 @@ GLuint LoadProgram(bool separable_program, T... shaders) {
}
}
+ if (result == GL_FALSE) {
+ // There was a problem linking the shader, print the source for debugging purposes.
+ LogShaderSource(shaders...);
+ }
+
ASSERT_MSG(result == GL_TRUE, "Shader not linked");
((shaders == 0 ? (void)0 : glDetachShader(program_id, shaders)), ...);
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp
index 8b074db5a..017bef13c 100644
--- a/src/yuzu/debugger/wait_tree.cpp
+++ b/src/yuzu/debugger/wait_tree.cpp
@@ -98,6 +98,30 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeMutexInfo::GetChildren() cons
return list;
}
+WaitTreeCallstack::WaitTreeCallstack(const Kernel::Thread& thread) : thread(thread) {}
+
+QString WaitTreeCallstack::GetText() const {
+ return tr("Call stack");
+}
+
+std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeCallstack::GetChildren() const {
+ std::vector<std::unique_ptr<WaitTreeItem>> list;
+
+ constexpr size_t BaseRegister = 29;
+ u64 base_pointer = thread.context.cpu_registers[BaseRegister];
+
+ while (base_pointer != 0) {
+ u64 lr = Memory::Read64(base_pointer + sizeof(u64));
+ if (lr == 0)
+ break;
+ list.push_back(
+ std::make_unique<WaitTreeText>(tr("0x%1").arg(lr - sizeof(u32), 16, 16, QChar('0'))));
+ base_pointer = Memory::Read64(base_pointer);
+ }
+
+ return list;
+}
+
WaitTreeWaitObject::WaitTreeWaitObject(const Kernel::WaitObject& o) : object(o) {}
bool WaitTreeExpandableItem::IsExpandable() const {
@@ -269,6 +293,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const {
thread.IsSleepingOnWaitAll()));
}
+ list.push_back(std::make_unique<WaitTreeCallstack>(thread));
+
return list;
}
diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h
index 300ba9ae4..10fc9e968 100644
--- a/src/yuzu/debugger/wait_tree.h
+++ b/src/yuzu/debugger/wait_tree.h
@@ -73,6 +73,17 @@ private:
Kernel::SharedPtr<Kernel::Thread> owner;
};
+class WaitTreeCallstack : public WaitTreeExpandableItem {
+ Q_OBJECT
+public:
+ explicit WaitTreeCallstack(const Kernel::Thread& thread);
+ QString GetText() const override;
+ std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
+
+private:
+ const Kernel::Thread& thread;
+};
+
class WaitTreeWaitObject : public WaitTreeExpandableItem {
Q_OBJECT
public: