From e542356d0cc37b61621da8d2b376d32407ec8eff Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 8 Aug 2018 01:27:12 -0400 Subject: gl_shader_decompiler: Let OpenGL interpret floats. - Accuracy is lost in translation to string, e.g. with NaN. - Needed for Super Mario Odyssey. --- src/video_core/engines/shader_bytecode.h | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'src/video_core/engines') diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index c7e3fb4b1..0d33c5a5e 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h @@ -254,20 +254,15 @@ union Instruction { BitField<56, 1, u64> invert_b; } lop32i; - float GetImm20_19() const { - float result{}; + u32 GetImm20_19() const { u32 imm{static_cast(imm20_19)}; imm <<= 12; imm |= negate_imm ? 0x80000000 : 0; - std::memcpy(&result, &imm, sizeof(imm)); - return result; + return imm; } - float GetImm20_32() const { - float result{}; - s32 imm{static_cast(imm20_32)}; - std::memcpy(&result, &imm, sizeof(imm)); - return result; + u32 GetImm20_32() const { + return static_cast(imm20_32); } s32 GetSignedImm20_20() const { -- cgit v1.2.3 From 57982df105a6d149cc82292541184e6ceabc288c Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 8 Aug 2018 02:07:44 -0400 Subject: maxwell_3d: Use correct const buffer size and check bounds. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fixes mem corruption with Super Mario Odyssey and Pokkén Tournament DX. --- src/video_core/engines/maxwell_3d.cpp | 2 ++ src/video_core/engines/maxwell_3d.h | 2 +- src/video_core/renderer_opengl/gl_rasterizer.cpp | 5 ++++- src/video_core/renderer_opengl/gl_state.h | 6 +++++- 4 files changed, 12 insertions(+), 3 deletions(-) (limited to 'src/video_core/engines') diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 5c0ae8009..ed22a2090 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -238,6 +238,8 @@ void Maxwell3D::ProcessCBBind(Regs::ShaderStage stage) { auto& buffer = shader.const_buffers[bind_data.index]; + ASSERT(bind_data.index < Regs::MaxConstBuffers); + buffer.enabled = bind_data.valid.Value() != 0; buffer.index = bind_data.index; buffer.address = regs.const_buffer.BufferAddress(); diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 4d0ff96a5..0506ac8fe 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -44,7 +44,7 @@ public: static constexpr size_t MaxShaderProgram = 6; static constexpr size_t MaxShaderStage = 5; // Maximum number of const buffers per shader stage. - static constexpr size_t MaxConstBuffers = 16; + static constexpr size_t MaxConstBuffers = 18; enum class QueryMode : u32 { Write = 0, diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index c2a931469..601a1084b 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -659,7 +659,10 @@ u32 RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, GLuint progr auto& buffer_draw_state = state.draw.const_buffers[static_cast(stage)][used_buffer.GetIndex()]; - ASSERT_MSG(buffer.enabled, "Attempted to upload disabled constbuffer"); + if (!buffer.enabled) { + continue; + } + buffer_draw_state.enabled = true; buffer_draw_state.bindpoint = current_bindpoint + bindpoint; diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index 24b1d956b..5c7b636e4 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h @@ -7,6 +7,10 @@ #include #include +#include "video_core/engines/maxwell_3d.h" + +using Regs = Tegra::Engines::Maxwell3D::Regs; + namespace TextureUnits { struct TextureUnit { @@ -120,7 +124,7 @@ public: GLuint bindpoint; GLuint ssbo; }; - std::array, 5> const_buffers{}; + std::array, 5> const_buffers; } draw; struct { -- cgit v1.2.3 From 7f0d0a93f74c4a1a76281ccdd4b985e50b89d440 Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 8 Aug 2018 02:25:00 -0400 Subject: gl_shader_decompiler: Stub input attribute Unknown_63. --- src/video_core/engines/shader_bytecode.h | 2 ++ src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 7 +++++++ 2 files changed, 9 insertions(+) (limited to 'src/video_core/engines') diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index c7e3fb4b1..42147588c 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h @@ -78,6 +78,8 @@ union Attribute { // shader, and a tuple of (TessCoord.x, TessCoord.y, TessCoord.z, ~) when inside a Tess Eval // shader. TessCoordInstanceIDVertexID = 47, + // TODO(bunnei): Figure out what this is used for. Super Mario Odyssey uses this. + Unknown_63 = 63, }; union { diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index e3217db81..724512000 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -523,6 +523,11 @@ private: // shader. ASSERT(stage == Maxwell3D::Regs::ShaderStage::Vertex); return "vec4(0, 0, uintBitsToFloat(gl_InstanceID), uintBitsToFloat(gl_VertexID))"; + case Attribute::Index::Unknown_63: + // TODO(bunnei): Figure out what this is used for. Super Mario Odyssey uses this. + LOG_CRITICAL(HW_GPU, "Unhandled input attribute Unknown_63"); + UNREACHABLE(); + break; default: const u32 index{static_cast(attribute) - static_cast(Attribute::Index::Attribute_0)}; @@ -534,6 +539,8 @@ private: LOG_CRITICAL(HW_GPU, "Unhandled input attribute: {}", index); UNREACHABLE(); } + + return "vec4(0, 0, 0, 0)"; } /// Generates code representing an output attribute register. -- cgit v1.2.3 From efe6b473c5b16d57e0bc6535e43fdafff23e6438 Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 8 Aug 2018 23:22:45 -0400 Subject: maxwell_3d: Ignore macros that have not been uploaded yet. - Used by Super Mario Odyssey (in game). --- src/video_core/engines/maxwell_3d.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'src/video_core/engines') diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index ed22a2090..a46ed4bd7 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -23,12 +23,17 @@ Maxwell3D::Maxwell3D(VideoCore::RasterizerInterface& rasterizer, MemoryManager& : memory_manager(memory_manager), rasterizer{rasterizer}, macro_interpreter(*this) {} void Maxwell3D::CallMacroMethod(u32 method, std::vector parameters) { - auto macro_code = uploaded_macros.find(method); + // Reset the current macro. + executing_macro = 0; + // The requested macro must have been uploaded already. - ASSERT_MSG(macro_code != uploaded_macros.end(), "Macro %08X was not uploaded", method); + auto macro_code = uploaded_macros.find(method); + if (macro_code == uploaded_macros.end()) { + LOG_ERROR(HW_GPU, "Macro {:04X} was not uploaded", method); + return; + } - // Reset the current macro and execute it. - executing_macro = 0; + // Execute the current macro. macro_interpreter.Execute(macro_code->second, std::move(parameters)); } -- cgit v1.2.3