diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp index a63a1fc498..7776249c8f 100644 --- a/src/core/gdbstub/gdbstub.cpp +++ b/src/core/gdbstub/gdbstub.cpp @@ -209,6 +209,22 @@ static std::map breakpoints_execute; static std::map breakpoints_read; static std::map breakpoints_write; +struct Module { + char name[128]; + PAddr beg; + PAddr end; +}; + +static std::vector modules; + +void RegisterModule(const char* name, PAddr beg, PAddr end) { + Module module; + strncpy(module.name, name, sizeof(module.name)); + module.beg = beg; + module.end = end; + modules.push_back(module); +} + static Kernel::Thread* FindThreadById(int id) { for (unsigned core = 0; core < Core::NUM_CPU_CORES; core++) { auto threads = Core::System::GetInstance().Scheduler(core)->GetThreadList(); @@ -609,12 +625,17 @@ static void HandleQuery() { SendReply("T0"); } else if (strncmp(query, "Supported", strlen("Supported")) == 0) { // PacketSize needs to be large enough for target xml - SendReply("PacketSize=2000;qXfer:features:read+;qXfer:threads:read+"); + std::string buffer = "PacketSize=2000;qXfer:features:read+;qXfer:threads:read+"; + if (modules.size()) { + buffer += ";qXfer:libraries:read+"; + } + SendReply(buffer.c_str()); } else if (strncmp(query, "Xfer:features:read:target.xml:", strlen("Xfer:features:read:target.xml:")) == 0) { SendReply(target_xml); } else if (strncmp(query, "Offsets", strlen("Offsets")) == 0) { - std::string buffer = fmt::format("TextSeg={:0x}", Memory::PROCESS_IMAGE_VADDR); + std::string buffer; + buffer = fmt::format("TextSeg={:0x}", Memory::PROCESS_IMAGE_VADDR); SendReply(buffer.c_str()); } else if (strncmp(query, "fThreadInfo", strlen("fThreadInfo")) == 0) { std::string val = "m"; @@ -643,6 +664,17 @@ static void HandleQuery() { } buffer += ""; SendReply(buffer.c_str()); + } else if (strncmp(query, "Xfer:libraries:read", strlen("Xfer:libraries:read")) == 0) { + std::string buffer; + buffer += "l"; + buffer += ""; + for (auto module : modules) { + buffer += + fmt::format(R"*("
)*", + module.name, module.beg); + } + buffer += ""; + SendReply(buffer.c_str()); } else { SendReply(""); } @@ -925,7 +957,7 @@ static void ReadMemory() { SendReply("E01"); } - if (!Memory::IsValidVirtualAddress(addr)) { + if (!Memory::IsValidVirtualAddress(addr) && (addr < Memory::STACK_AREA_VADDR)) { return SendReply("E00"); } @@ -1210,6 +1242,8 @@ static void Init(u16 port) { breakpoints_read.clear(); breakpoints_write.clear(); + modules.clear(); + // Start gdb server NGLOG_INFO(Debug_GDBStub, "Starting GDB server on port {}...", port); diff --git a/src/core/gdbstub/gdbstub.h b/src/core/gdbstub/gdbstub.h index efd5018843..2c17a7275b 100644 --- a/src/core/gdbstub/gdbstub.h +++ b/src/core/gdbstub/gdbstub.h @@ -51,6 +51,9 @@ bool IsServerEnabled(); /// Returns true if there is an active socket connection. bool IsConnected(); +/// Register module. +void RegisterModule(const char* name, PAddr beg, PAddr end); + /** * Signal to the gdbstub server that it should halt CPU execution. * diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index b01b2caf63..a9f232c0f9 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp @@ -9,6 +9,7 @@ #include "common/logging/log.h" #include "common/string_util.h" #include "core/file_sys/romfs_factory.h" +#include "core/gdbstub/gdbstub.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/resource_limit.h" #include "core/hle/service/filesystem/filesystem.h" @@ -133,6 +134,7 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load( next_load_addr = AppLoader_NSO::LoadModule(path, load_addr); if (next_load_addr) { NGLOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr); + GDBStub::RegisterModule(module, load_addr, next_load_addr); } else { next_load_addr = load_addr; } diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 0f6dec60b2..3fbf8e1f9a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -437,7 +437,7 @@ void RasterizerOpenGL::DrawArrays() { // Unbind textures for potential future use as framebuffer attachments for (auto& texture_unit : state.texture_units) { - texture_unit.texture_2d = 0; + texture_unit.Unbind(); } state.Apply(); @@ -613,6 +613,12 @@ u32 RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, GLuint progr if (used_buffer.IsIndirect()) { // Buffer is accessed indirectly, so upload the entire thing size = buffer.size * sizeof(float); + + if (size > MaxConstbufferSize) { + NGLOG_ERROR(HW_GPU, "indirect constbuffer size {} exceeds maximum {}", size, + MaxConstbufferSize); + size = MaxConstbufferSize; + } } else { // Buffer is accessed directly, upload just what we use size = used_buffer.GetSize() * sizeof(float); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 2ab0666814..4762983c9a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -55,7 +55,7 @@ public: }; /// Maximum supported size that a constbuffer can have in bytes. - static constexpr size_t MaxConstbufferSize = 0x1000; + static constexpr size_t MaxConstbufferSize = 0x10000; static_assert(MaxConstbufferSize % sizeof(GLvec4) == 0, "The maximum size of a constbuffer must be a multiple of the size of GLvec4"); diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 61d670dcbf..857164ff65 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -46,7 +46,7 @@ struct FormatTuple { static constexpr std::array tex_format_tuples = {{ {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, false}, // ABGR8 - {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, false}, // B5G6R5 + {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, false}, // B5G6R5 {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, false}, // A2B10G10R10 {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, false}, // A1B5G5R5 {GL_R8, GL_RED, GL_UNSIGNED_BYTE, false}, // R8 @@ -645,7 +645,7 @@ void CachedSurface::DownloadGLTexture(const MathUtil::Rectangle& rect, GLui glActiveTexture(GL_TEXTURE0); glGetTexImage(GL_TEXTURE_2D, 0, tuple.format, tuple.type, &gl_buffer[buffer_offset]); } else { - state.ResetTexture(texture.handle); + state.UnbindTexture(texture.handle); state.draw.read_framebuffer = read_fb_handle; state.Apply(); diff --git a/src/video_core/renderer_opengl/gl_resource_manager.h b/src/video_core/renderer_opengl/gl_resource_manager.h index 93f9172e76..0fed93ca56 100644 --- a/src/video_core/renderer_opengl/gl_resource_manager.h +++ b/src/video_core/renderer_opengl/gl_resource_manager.h @@ -38,7 +38,7 @@ public: if (handle == 0) return; glDeleteTextures(1, &handle); - OpenGLState::GetCurState().ResetTexture(handle).Apply(); + OpenGLState::GetCurState().UnbindTexture(handle).Apply(); handle = 0; } diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index cd7569e2f5..46eaad0217 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -811,6 +811,7 @@ private: if (!opcode) { NGLOG_CRITICAL(HW_GPU, "Unhandled instruction: {0:x}", instr.value); UNREACHABLE(); + return offset + 1; } shader.AddLine("// " + std::to_string(offset) + ": " + opcode->GetName()); diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index 6e5f9a789a..2e8a422a85 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp @@ -48,24 +48,9 @@ OpenGLState::OpenGLState() { logic_op = GL_COPY; for (auto& texture_unit : texture_units) { - texture_unit.texture_2d = 0; - texture_unit.sampler = 0; - texture_unit.swizzle.r = GL_RED; - texture_unit.swizzle.g = GL_GREEN; - texture_unit.swizzle.b = GL_BLUE; - texture_unit.swizzle.a = GL_ALPHA; + texture_unit.Reset(); } - lighting_lut.texture_buffer = 0; - - fog_lut.texture_buffer = 0; - - proctex_lut.texture_buffer = 0; - proctex_diff_lut.texture_buffer = 0; - proctex_color_map.texture_buffer = 0; - proctex_alpha_map.texture_buffer = 0; - proctex_noise_lut.texture_buffer = 0; - draw.read_framebuffer = 0; draw.draw_framebuffer = 0; draw.vertex_array = 0; @@ -229,48 +214,6 @@ void OpenGLState::Apply() const { } } - // Lighting LUTs - if (lighting_lut.texture_buffer != cur_state.lighting_lut.texture_buffer) { - glActiveTexture(TextureUnits::LightingLUT.Enum()); - glBindTexture(GL_TEXTURE_BUFFER, lighting_lut.texture_buffer); - } - - // Fog LUT - if (fog_lut.texture_buffer != cur_state.fog_lut.texture_buffer) { - glActiveTexture(TextureUnits::FogLUT.Enum()); - glBindTexture(GL_TEXTURE_BUFFER, fog_lut.texture_buffer); - } - - // ProcTex Noise LUT - if (proctex_noise_lut.texture_buffer != cur_state.proctex_noise_lut.texture_buffer) { - glActiveTexture(TextureUnits::ProcTexNoiseLUT.Enum()); - glBindTexture(GL_TEXTURE_BUFFER, proctex_noise_lut.texture_buffer); - } - - // ProcTex Color Map - if (proctex_color_map.texture_buffer != cur_state.proctex_color_map.texture_buffer) { - glActiveTexture(TextureUnits::ProcTexColorMap.Enum()); - glBindTexture(GL_TEXTURE_BUFFER, proctex_color_map.texture_buffer); - } - - // ProcTex Alpha Map - if (proctex_alpha_map.texture_buffer != cur_state.proctex_alpha_map.texture_buffer) { - glActiveTexture(TextureUnits::ProcTexAlphaMap.Enum()); - glBindTexture(GL_TEXTURE_BUFFER, proctex_alpha_map.texture_buffer); - } - - // ProcTex LUT - if (proctex_lut.texture_buffer != cur_state.proctex_lut.texture_buffer) { - glActiveTexture(TextureUnits::ProcTexLUT.Enum()); - glBindTexture(GL_TEXTURE_BUFFER, proctex_lut.texture_buffer); - } - - // ProcTex Diff LUT - if (proctex_diff_lut.texture_buffer != cur_state.proctex_diff_lut.texture_buffer) { - glActiveTexture(TextureUnits::ProcTexDiffLUT.Enum()); - glBindTexture(GL_TEXTURE_BUFFER, proctex_diff_lut.texture_buffer); - } - // Framebuffer if (draw.read_framebuffer != cur_state.draw.read_framebuffer) { glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer); @@ -338,26 +281,12 @@ void OpenGLState::Apply() const { cur_state = *this; } -OpenGLState& OpenGLState::ResetTexture(GLuint handle) { +OpenGLState& OpenGLState::UnbindTexture(GLuint handle) { for (auto& unit : texture_units) { if (unit.texture_2d == handle) { - unit.texture_2d = 0; + unit.Unbind(); } } - if (lighting_lut.texture_buffer == handle) - lighting_lut.texture_buffer = 0; - if (fog_lut.texture_buffer == handle) - fog_lut.texture_buffer = 0; - if (proctex_noise_lut.texture_buffer == handle) - proctex_noise_lut.texture_buffer = 0; - if (proctex_color_map.texture_buffer == handle) - proctex_color_map.texture_buffer = 0; - if (proctex_alpha_map.texture_buffer == handle) - proctex_alpha_map.texture_buffer = 0; - if (proctex_lut.texture_buffer == handle) - proctex_lut.texture_buffer = 0; - if (proctex_diff_lut.texture_buffer == handle) - proctex_diff_lut.texture_buffer = 0; return *this; } diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index 839e50e935..3398d7c04e 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h @@ -91,36 +91,21 @@ public: GLint b; // GL_TEXTURE_SWIZZLE_B GLint a; // GL_TEXTURE_SWIZZLE_A } swizzle; + + void Unbind() { + texture_2d = 0; + swizzle.r = GL_RED; + swizzle.g = GL_GREEN; + swizzle.b = GL_BLUE; + swizzle.a = GL_ALPHA; + } + + void Reset() { + Unbind(); + sampler = 0; + } } texture_units[32]; - struct { - GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER - } lighting_lut; - - struct { - GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER - } fog_lut; - - struct { - GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER - } proctex_noise_lut; - - struct { - GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER - } proctex_color_map; - - struct { - GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER - } proctex_alpha_map; - - struct { - GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER - } proctex_lut; - - struct { - GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER - } proctex_diff_lut; - struct { GLuint read_framebuffer; // GL_READ_FRAMEBUFFER_BINDING GLuint draw_framebuffer; // GL_DRAW_FRAMEBUFFER_BINDING @@ -165,7 +150,7 @@ public: void Apply() const; /// Resets any references to the given resource - OpenGLState& ResetTexture(GLuint handle); + OpenGLState& UnbindTexture(GLuint handle); OpenGLState& ResetSampler(GLuint handle); OpenGLState& ResetProgram(GLuint handle); OpenGLState& ResetPipeline(GLuint handle);