diff options
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | src/citra_qt/configuration/configure_debug.ui | 7 | ||||
-rw-r--r-- | src/video_core/pica_state.h | 8 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 29 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 3 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.cpp | 10 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_state.cpp | 10 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_state.h | 2 | ||||
-rw-r--r-- | src/video_core/swrasterizer/rasterizer.cpp | 3 |
9 files changed, 43 insertions, 33 deletions
@@ -5,7 +5,7 @@ Citra Emulator [](https://travis-ci.org/citra-emu/citra) [](https://ci.appveyor.com/project/bunnei/citra) -Citra is an experimental open-source Nintendo 3DS emulator/debugger written in C++. It is written with portability in mind, with builds actively maintained for Windows, Linux and macOS. Citra only emulates a subset of 3DS hardware, and therefore is generally only useful for running/debugging homebrew applications. At this time, Citra is even able to boot several commercial games! Most of these do not run to a playable state, but we are working every day to advance the project forward. +Citra is an experimental open-source Nintendo 3DS emulator/debugger written in C++. It is written with portability in mind, with builds actively maintained for Windows, Linux and macOS. Citra only emulates a subset of 3DS hardware and therefore is generally only useful for running/debugging homebrew applications. At this time, Citra is even able to boot several commercial games! Most of these do not run to a playable state, but we are working every day to advance the project forward. Citra is licensed under the GPLv2 (or any later version). Refer to the license.txt file included. Please read the [FAQ](https://citra-emu.org/wiki/faq/) before getting started with the project. @@ -27,7 +27,7 @@ If you want to contribute please take a look at the [Contributor's Guide](CONTRI ### Support -We happily accept monetary donations, or donated games and hardware. Please see our [donations page](https://citra-emu.org/donate/) for more information on how you can contribute to Citra. Any donations received will go towards things like: +We happily accept monetary donations or donated games and hardware. Please see our [donations page](https://citra-emu.org/donate/) for more information on how you can contribute to Citra. Any donations received will go towards things like: * 3DS consoles for developers to explore the hardware * 3DS games for testing * Any equipment required for homebrew diff --git a/src/citra_qt/configuration/configure_debug.ui b/src/citra_qt/configuration/configure_debug.ui index bbbb0e3f4..96638ebdb 100644 --- a/src/citra_qt/configuration/configure_debug.ui +++ b/src/citra_qt/configuration/configure_debug.ui @@ -23,6 +23,13 @@ </property> <layout class="QVBoxLayout" name="verticalLayout_2"> <item> + <widget class="QLabel"> + <property name="text"> + <string>The GDB Stub only works correctly when the CPU JIT is off.</string> + </property> + </widget> + </item> + <item> <layout class="QHBoxLayout" name="horizontalLayout_3"> <item> <widget class="QCheckBox" name="toggle_gdbstub"> diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index 3b00df0b3..2d23d34e6 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -111,6 +111,14 @@ struct State { BitField<0, 13, s32> difference; // 1.1.11 fixed point BitField<13, 11, u32> value; // 0.0.11 fixed point + + float ToFloat() const { + return static_cast<float>(value) / 2047.0f; + } + + float DiffToFloat() const { + return static_cast<float>(difference) / 2047.0f; + } }; std::array<LutEntry, 128> lut; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 8b7991c04..ff3f69ba3 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -94,10 +94,10 @@ RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true) { framebuffer.Create(); // Allocate and bind lighting lut textures - lighting_lut_buffer.Create(); + lighting_lut.Create(); state.lighting_lut.texture_buffer = lighting_lut.handle; state.Apply(); - lighting_lut.Create(); + lighting_lut_buffer.Create(); glBindBuffer(GL_TEXTURE_BUFFER, lighting_lut_buffer.handle); glBufferData(GL_TEXTURE_BUFFER, sizeof(GLfloat) * 2 * 256 * Pica::LightingRegs::NumLightingSampler, nullptr, @@ -106,16 +106,14 @@ RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true) { glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32F, lighting_lut_buffer.handle); // Setup the LUT for the fog - { - fog_lut.Create(); - state.fog_lut.texture_1d = fog_lut.handle; - } + fog_lut.Create(); + state.fog_lut.texture_buffer = fog_lut.handle; state.Apply(); - + fog_lut_buffer.Create(); + glBindBuffer(GL_TEXTURE_BUFFER, fog_lut_buffer.handle); + glBufferData(GL_TEXTURE_BUFFER, sizeof(GLfloat) * 2 * 128, nullptr, GL_DYNAMIC_DRAW); glActiveTexture(TextureUnits::FogLUT.Enum()); - glTexImage1D(GL_TEXTURE_1D, 0, GL_R32UI, 128, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, nullptr); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32F, fog_lut_buffer.handle); // Setup the noise LUT for proctex proctex_noise_lut.Create(); @@ -1356,16 +1354,17 @@ void RasterizerOpenGL::SyncFogColor() { } void RasterizerOpenGL::SyncFogLUT() { - std::array<GLuint, 128> new_data; + std::array<GLvec2, 128> new_data; std::transform(Pica::g_state.fog.lut.begin(), Pica::g_state.fog.lut.end(), new_data.begin(), - [](const auto& entry) { return entry.raw; }); + [](const auto& entry) { + return GLvec2{entry.ToFloat(), entry.DiffToFloat()}; + }); if (new_data != fog_lut_data) { fog_lut_data = new_data; - glActiveTexture(TextureUnits::FogLUT.Enum()); - glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 128, GL_RED_INTEGER, GL_UNSIGNED_INT, - fog_lut_data.data()); + glBindBuffer(GL_TEXTURE_BUFFER, fog_lut_buffer.handle); + glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec2), new_data.data()); } } diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 79acd4230..a433c1d4a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -283,8 +283,9 @@ private: OGLTexture lighting_lut; std::array<std::array<GLvec2, 256>, Pica::LightingRegs::NumLightingSampler> lighting_lut_data{}; + OGLBuffer fog_lut_buffer; OGLTexture fog_lut; - std::array<GLuint, 128> fog_lut_data{}; + std::array<GLvec2, 128> fog_lut_data{}; OGLTexture proctex_noise_lut; std::array<GLvec2, 128> proctex_noise_lut_data{}; diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 0c7c4dd5c..c93b108fb 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp @@ -1052,7 +1052,7 @@ layout (std140) uniform shader_data { uniform sampler2D tex[3]; uniform samplerBuffer lighting_lut; -uniform usampler1D fog_lut; +uniform samplerBuffer fog_lut; uniform sampler1D proctex_noise_lut; uniform sampler1D proctex_color_map; uniform sampler1D proctex_alpha_map; @@ -1145,12 +1145,8 @@ vec4 secondary_fragment_color = vec4(0.0); // Generate clamped fog factor from LUT for given fog index out += "float fog_i = clamp(floor(fog_index), 0.0, 127.0);\n"; out += "float fog_f = fog_index - fog_i;\n"; - out += "uint fog_lut_entry = texelFetch(fog_lut, int(fog_i), 0).r;\n"; - out += "float fog_lut_entry_difference = float(int((fog_lut_entry & 0x1FFFU) << 19U) >> " - "19);\n"; // Extract signed difference - out += "float fog_lut_entry_value = float((fog_lut_entry >> 13U) & 0x7FFU);\n"; - out += "float fog_factor = (fog_lut_entry_value + fog_lut_entry_difference * fog_f) / " - "2047.0;\n"; + out += "vec2 fog_lut_entry = texelFetch(fog_lut, int(fog_i)).rg;\n"; + out += "float fog_factor = fog_lut_entry.r + fog_lut_entry.g * fog_f;\n"; out += "fog_factor = clamp(fog_factor, 0.0, 1.0);\n"; // Blend the fog diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index 14e63115c..eface2dea 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp @@ -54,7 +54,7 @@ OpenGLState::OpenGLState() { lighting_lut.texture_buffer = 0; - fog_lut.texture_1d = 0; + fog_lut.texture_buffer = 0; proctex_lut.texture_1d = 0; proctex_diff_lut.texture_1d = 0; @@ -198,9 +198,9 @@ void OpenGLState::Apply() const { } // Fog LUT - if (fog_lut.texture_1d != cur_state.fog_lut.texture_1d) { + if (fog_lut.texture_buffer != cur_state.fog_lut.texture_buffer) { glActiveTexture(TextureUnits::FogLUT.Enum()); - glBindTexture(GL_TEXTURE_1D, fog_lut.texture_1d); + glBindTexture(GL_TEXTURE_BUFFER, fog_lut.texture_buffer); } // ProcTex Noise LUT @@ -272,8 +272,8 @@ void OpenGLState::ResetTexture(GLuint handle) { } if (cur_state.lighting_lut.texture_buffer == handle) cur_state.lighting_lut.texture_buffer = 0; - if (cur_state.fog_lut.texture_1d == handle) - cur_state.fog_lut.texture_1d = 0; + if (cur_state.fog_lut.texture_buffer == handle) + cur_state.fog_lut.texture_buffer = 0; if (cur_state.proctex_noise_lut.texture_1d == handle) cur_state.proctex_noise_lut.texture_1d = 0; if (cur_state.proctex_color_map.texture_1d == handle) diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index bb0218708..1efcf0811 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h @@ -91,7 +91,7 @@ public: } lighting_lut; struct { - GLuint texture_1d; // GL_TEXTURE_BINDING_1D + GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER } fog_lut; struct { diff --git a/src/video_core/swrasterizer/rasterizer.cpp b/src/video_core/swrasterizer/rasterizer.cpp index cd7b6c39d..512e81c08 100644 --- a/src/video_core/swrasterizer/rasterizer.cpp +++ b/src/video_core/swrasterizer/rasterizer.cpp @@ -584,8 +584,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve float fog_i = MathUtil::Clamp(floorf(fog_index), 0.0f, 127.0f); float fog_f = fog_index - fog_i; const auto& fog_lut_entry = g_state.fog.lut[static_cast<unsigned int>(fog_i)]; - float fog_factor = (fog_lut_entry.value + fog_lut_entry.difference * fog_f) / - 2047.0f; // This is signed fixed point 1.11 + float fog_factor = fog_lut_entry.ToFloat() + fog_lut_entry.DiffToFloat() * fog_f; fog_factor = MathUtil::Clamp(fog_factor, 0.0f, 1.0f); // Blend the fog |