From fa0d65fc7b789193d1c8b078f446d3c497e5458b Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Fri, 8 Nov 2019 22:32:52 +0000
Subject: [PATCH 1/4] microprofile: Silence conversion warnings

---
 externals/microprofile/microprofile.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/externals/microprofile/microprofile.h b/externals/microprofile/microprofile.h
index 384863ccc..cdb312b87 100644
--- a/externals/microprofile/microprofile.h
+++ b/externals/microprofile/microprofile.h
@@ -814,7 +814,7 @@ struct MicroProfile
 
 inline int MicroProfileLogType(MicroProfileLogEntry Index)
 {
-    return ((MP_LOG_BEGIN_MASK & Index)>>62) & 0x3;
+    return (int)(((MP_LOG_BEGIN_MASK & Index)>>62) & 0x3ULL);
 }
 
 inline uint64_t MicroProfileLogTimerIndex(MicroProfileLogEntry Index)
@@ -861,12 +861,12 @@ T MicroProfileMax(T a, T b)
 
 inline int64_t MicroProfileMsToTick(float fMs, int64_t nTicksPerSecond)
 {
-    return (int64_t)(fMs*0.001f*nTicksPerSecond);
+    return (int64_t)(fMs*0.001f*(float)nTicksPerSecond);
 }
 
 inline float MicroProfileTickToMsMultiplier(int64_t nTicksPerSecond)
 {
-    return 1000.f / nTicksPerSecond;
+    return 1000.f / (float)nTicksPerSecond;
 }
 
 inline uint16_t MicroProfileGetGroupIndex(MicroProfileToken t)

From 096f339a2a817054c9e2dfef188a5e2470126236 Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Fri, 8 Nov 2019 17:08:07 -0300
Subject: [PATCH 2/4] video_core: Silence implicit conversion warnings

---
 src/video_core/engines/maxwell_3d.cpp         |  3 +-
 src/video_core/engines/shader_bytecode.h      | 12 +--
 .../renderer_opengl/gl_rasterizer.cpp         |  2 +-
 .../renderer_opengl/renderer_opengl.cpp       |  6 +-
 src/video_core/shader/decode.cpp              |  4 +-
 src/video_core/shader/shader_ir.h             |  6 +-
 src/video_core/textures/astc.cpp              | 73 ++++++++++---------
 src/video_core/textures/texture.h             |  7 +-
 src/video_core/video_core.cpp                 |  2 +-
 9 files changed, 62 insertions(+), 53 deletions(-)

diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 2bed6cb38..42ce49a4d 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -261,7 +261,8 @@ void Maxwell3D::CallMacroMethod(u32 method, std::size_t num_parameters, const u3
     executing_macro = 0;
 
     // Lookup the macro offset
-    const u32 entry = ((method - MacroRegistersStart) >> 1) % macro_positions.size();
+    const u32 entry =
+        ((method - MacroRegistersStart) >> 1) % static_cast<u32>(macro_positions.size());
 
     // Execute the current macro.
     macro_interpreter.Execute(macro_positions[entry], num_parameters, parameters);
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 8f6bc76eb..78d6886fb 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -1478,7 +1478,8 @@ union Instruction {
             u32 value = static_cast<u32>(target);
             // The branch offset is relative to the next instruction and is stored in bytes, so
             // divide it by the size of an instruction and add 1 to it.
-            return static_cast<s32>((value ^ mask) - mask) / sizeof(Instruction) + 1;
+            return static_cast<s32>((value ^ mask) - mask) / static_cast<s32>(sizeof(Instruction)) +
+                   1;
         }
     } bra;
 
@@ -1492,7 +1493,8 @@ union Instruction {
             u32 value = static_cast<u32>(target);
             // The branch offset is relative to the next instruction and is stored in bytes, so
             // divide it by the size of an instruction and add 1 to it.
-            return static_cast<s32>((value ^ mask) - mask) / sizeof(Instruction) + 1;
+            return static_cast<s32>((value ^ mask) - mask) / static_cast<s32>(sizeof(Instruction)) +
+                   1;
         }
     } brx;
 
@@ -1851,11 +1853,11 @@ private:
                 const std::size_t bit_position = opcode_bitsize - i - 1;
                 switch (bitstring[i]) {
                 case '0':
-                    mask |= 1 << bit_position;
+                    mask |= static_cast<u16>(1U << bit_position);
                     break;
                 case '1':
-                    expect |= 1 << bit_position;
-                    mask |= 1 << bit_position;
+                    expect |= static_cast<u16>(1U << bit_position);
+                    mask |= static_cast<u16>(1U << bit_position);
                     break;
                 default:
                     // Ignore
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index e560d70d5..e43ba9d6b 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -375,7 +375,7 @@ void RasterizerOpenGL::ConfigureFramebuffers() {
         fbkey.color_attachments[index] = GL_COLOR_ATTACHMENT0 + regs.rt_control.GetMap(index);
         fbkey.colors[index] = std::move(color_surface);
     }
-    fbkey.colors_count = regs.rt_control.count;
+    fbkey.colors_count = static_cast<u16>(regs.rt_control.count);
 
     if (depth_surface) {
         // Assume that a surface will be written to if it is used as a framebuffer, even if
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 4bbd17b12..7646cbb0e 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -323,10 +323,12 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
     // (e.g. handheld mode) on a 1920x1080 framebuffer.
     f32 scale_u = 1.f, scale_v = 1.f;
     if (framebuffer_crop_rect.GetWidth() > 0) {
-        scale_u = static_cast<f32>(framebuffer_crop_rect.GetWidth()) / screen_info.texture.width;
+        scale_u = static_cast<f32>(framebuffer_crop_rect.GetWidth()) /
+                  static_cast<f32>(screen_info.texture.width);
     }
     if (framebuffer_crop_rect.GetHeight() > 0) {
-        scale_v = static_cast<f32>(framebuffer_crop_rect.GetHeight()) / screen_info.texture.height;
+        scale_v = static_cast<f32>(framebuffer_crop_rect.GetHeight()) /
+                  static_cast<f32>(screen_info.texture.height);
     }
 
     std::array<ScreenRectVertex, 4> vertices = {{
diff --git a/src/video_core/shader/decode.cpp b/src/video_core/shader/decode.cpp
index 21fb9cb83..22c3e5120 100644
--- a/src/video_core/shader/decode.cpp
+++ b/src/video_core/shader/decode.cpp
@@ -154,10 +154,10 @@ void ShaderIR::Decode() {
         LOG_CRITICAL(HW_GPU, "Unknown decompilation mode!");
         [[fallthrough]];
     case CompileDepth::BruteForce: {
+        const auto shader_end = static_cast<u32>(program_code.size());
         coverage_begin = main_offset;
-        const std::size_t shader_end = program_code.size();
         coverage_end = shader_end;
-        for (u32 label = main_offset; label < shader_end; label++) {
+        for (u32 label = main_offset; label < shader_end; ++label) {
             basic_blocks.insert({label, DecodeRange(label, label + 1)});
         }
         break;
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index 26c8fde22..76a849818 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -49,7 +49,7 @@ public:
     }
 
     u32 GetSize() const {
-        return max_offset + sizeof(float);
+        return max_offset + static_cast<u32>(sizeof(float));
     }
 
     u32 GetMaxOffset() const {
@@ -165,8 +165,8 @@ public:
         return program_manager.GetVariables();
     }
 
-    u32 ConvertAddressToNvidiaSpace(const u32 address) const {
-        return (address - main_offset) * sizeof(Tegra::Shader::Instruction);
+    u32 ConvertAddressToNvidiaSpace(u32 address) const {
+        return (address - main_offset) * static_cast<u32>(sizeof(Tegra::Shader::Instruction));
     }
 
     /// Returns a condition code evaluated from internal flags
diff --git a/src/video_core/textures/astc.cpp b/src/video_core/textures/astc.cpp
index 58b608a36..33bd31865 100644
--- a/src/video_core/textures/astc.cpp
+++ b/src/video_core/textures/astc.cpp
@@ -92,11 +92,11 @@ private:
         const unsigned int mask = 1 << m_NextBit++;
 
         // clear the bit
-        *m_CurByte &= ~mask;
+        *m_CurByte &= static_cast<unsigned char>(~mask);
 
         // Write the bit, if necessary
         if (b)
-            *m_CurByte |= mask;
+            *m_CurByte |= static_cast<unsigned char>(mask);
 
         // Next byte?
         if (m_NextBit >= 8) {
@@ -137,7 +137,7 @@ public:
         }
 
         uint64_t mask = (1 << (end - start + 1)) - 1;
-        return (m_Bits >> start) & mask;
+        return (m_Bits >> start) & static_cast<IntType>(mask);
     }
 
 private:
@@ -656,7 +656,7 @@ static IntType Replicate(const IntType& val, uint32_t numBits, uint32_t toBit) {
         return 0;
     if (toBit == 0)
         return 0;
-    IntType v = val & ((1 << numBits) - 1);
+    IntType v = val & static_cast<IntType>((1 << numBits) - 1);
     IntType res = v;
     uint32_t reslen = numBits;
     while (reslen < toBit) {
@@ -666,8 +666,8 @@ static IntType Replicate(const IntType& val, uint32_t numBits, uint32_t toBit) {
             comp = numBits - newshift;
             numBits = newshift;
         }
-        res <<= numBits;
-        res |= v >> comp;
+        res = static_cast<IntType>(res << numBits);
+        res = static_cast<IntType>(res | (v >> comp));
         reslen += numBits;
     }
     return res;
@@ -714,7 +714,7 @@ public:
             // Do nothing
             return val;
         } else if (oldDepth == 0 && newDepth != 0) {
-            return (1 << newDepth) - 1;
+            return static_cast<ChannelType>((1 << newDepth) - 1);
         } else if (newDepth > oldDepth) {
             return Replicate(val, oldDepth, newDepth);
         } else {
@@ -722,10 +722,11 @@ public:
             if (newDepth == 0) {
                 return 0xFF;
             } else {
-                uint8_t bitsWasted = oldDepth - newDepth;
+                uint8_t bitsWasted = static_cast<uint8_t>(oldDepth - newDepth);
                 uint16_t v = static_cast<uint16_t>(val);
-                v = (v + (1 << (bitsWasted - 1))) >> bitsWasted;
-                v = ::std::min<uint16_t>(::std::max<uint16_t>(0, v), (1 << newDepth) - 1);
+                v = static_cast<uint16_t>((v + (1 << (bitsWasted - 1))) >> bitsWasted);
+                v = ::std::min<uint16_t>(::std::max<uint16_t>(0, v),
+                                         static_cast<uint16_t>((1 << newDepth) - 1));
                 return static_cast<uint8_t>(v);
             }
         }
@@ -1191,18 +1192,18 @@ static uint32_t SelectPartition(int32_t seed, int32_t x, int32_t y, int32_t z,
     uint8_t seed11 = static_cast<uint8_t>((rnum >> 26) & 0xF);
     uint8_t seed12 = static_cast<uint8_t>(((rnum >> 30) | (rnum << 2)) & 0xF);
 
-    seed1 *= seed1;
-    seed2 *= seed2;
-    seed3 *= seed3;
-    seed4 *= seed4;
-    seed5 *= seed5;
-    seed6 *= seed6;
-    seed7 *= seed7;
-    seed8 *= seed8;
-    seed9 *= seed9;
-    seed10 *= seed10;
-    seed11 *= seed11;
-    seed12 *= seed12;
+    seed1 = static_cast<uint8_t>(seed1 * seed1);
+    seed2 = static_cast<uint8_t>(seed2 * seed2);
+    seed3 = static_cast<uint8_t>(seed3 * seed3);
+    seed4 = static_cast<uint8_t>(seed4 * seed4);
+    seed5 = static_cast<uint8_t>(seed5 * seed5);
+    seed6 = static_cast<uint8_t>(seed6 * seed6);
+    seed7 = static_cast<uint8_t>(seed7 * seed7);
+    seed8 = static_cast<uint8_t>(seed8 * seed8);
+    seed9 = static_cast<uint8_t>(seed9 * seed9);
+    seed10 = static_cast<uint8_t>(seed10 * seed10);
+    seed11 = static_cast<uint8_t>(seed11 * seed11);
+    seed12 = static_cast<uint8_t>(seed12 * seed12);
 
     int32_t sh1, sh2, sh3;
     if (seed & 1) {
@@ -1214,18 +1215,18 @@ static uint32_t SelectPartition(int32_t seed, int32_t x, int32_t y, int32_t z,
     }
     sh3 = (seed & 0x10) ? sh1 : sh2;
 
-    seed1 >>= sh1;
-    seed2 >>= sh2;
-    seed3 >>= sh1;
-    seed4 >>= sh2;
-    seed5 >>= sh1;
-    seed6 >>= sh2;
-    seed7 >>= sh1;
-    seed8 >>= sh2;
-    seed9 >>= sh3;
-    seed10 >>= sh3;
-    seed11 >>= sh3;
-    seed12 >>= sh3;
+    seed1 = static_cast<uint8_t>(seed1 >> sh1);
+    seed2 = static_cast<uint8_t>(seed2 >> sh2);
+    seed3 = static_cast<uint8_t>(seed3 >> sh1);
+    seed4 = static_cast<uint8_t>(seed4 >> sh2);
+    seed5 = static_cast<uint8_t>(seed5 >> sh1);
+    seed6 = static_cast<uint8_t>(seed6 >> sh2);
+    seed7 = static_cast<uint8_t>(seed7 >> sh1);
+    seed8 = static_cast<uint8_t>(seed8 >> sh2);
+    seed9 = static_cast<uint8_t>(seed9 >> sh3);
+    seed10 = static_cast<uint8_t>(seed10 >> sh3);
+    seed11 = static_cast<uint8_t>(seed11 >> sh3);
+    seed12 = static_cast<uint8_t>(seed12 >> sh3);
 
     int32_t a = seed1 * x + seed2 * y + seed11 * z + (rnum >> 14);
     int32_t b = seed3 * x + seed4 * y + seed12 * z + (rnum >> 10);
@@ -1558,7 +1559,9 @@ static void DecompressBlock(const uint8_t inBuf[16], const uint32_t blockWidth,
 
     // Make sure that higher non-texel bits are set to zero
     const uint32_t clearByteStart = (weightParams.GetPackedBitSize() >> 3) + 1;
-    texelWeightData[clearByteStart - 1] &= (1 << (weightParams.GetPackedBitSize() % 8)) - 1;
+    texelWeightData[clearByteStart - 1] =
+        texelWeightData[clearByteStart - 1] &
+        static_cast<uint8_t>((1 << (weightParams.GetPackedBitSize() % 8)) - 1);
     memset(texelWeightData + clearByteStart, 0, 16 - clearByteStart);
 
     std::vector<IntegerEncodedValue> texelWeightValues;
diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h
index 27c8ce975..8e82c6748 100644
--- a/src/video_core/textures/texture.h
+++ b/src/video_core/textures/texture.h
@@ -342,13 +342,14 @@ struct TSCEntry {
     float GetLodBias() const {
         // Sign extend the 13-bit value.
         constexpr u32 mask = 1U << (13 - 1);
-        return static_cast<s32>((mip_lod_bias ^ mask) - mask) / 256.0f;
+        return static_cast<float>(static_cast<s32>((mip_lod_bias ^ mask) - mask)) / 256.0f;
     }
 
     std::array<float, 4> GetBorderColor() const {
         if (srgb_conversion) {
-            return {srgb_border_color_r / 255.0f, srgb_border_color_g / 255.0f,
-                    srgb_border_color_b / 255.0f, border_color[3]};
+            return {static_cast<float>(srgb_border_color_r) / 255.0f,
+                    static_cast<float>(srgb_border_color_g) / 255.0f,
+                    static_cast<float>(srgb_border_color_b) / 255.0f, border_color[3]};
         }
         return border_color;
     }
diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp
index 60cda0ca3..8e947394c 100644
--- a/src/video_core/video_core.cpp
+++ b/src/video_core/video_core.cpp
@@ -28,7 +28,7 @@ std::unique_ptr<Tegra::GPU> CreateGPU(Core::System& system) {
 
 u16 GetResolutionScaleFactor(const RendererBase& renderer) {
     return static_cast<u16>(
-        Settings::values.resolution_factor
+        Settings::values.resolution_factor != 0
             ? Settings::values.resolution_factor
             : renderer.GetRenderWindow().GetFramebufferLayout().GetScalingRatio());
 }

From 18c1cb68fd9b49751344f09413307d80a346f1f9 Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Fri, 8 Nov 2019 17:14:21 -0300
Subject: [PATCH 3/4] video_core: Treat implicit conversions as errors

---
 src/video_core/CMakeLists.txt | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index c911c6ec4..35e933858 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -180,3 +180,9 @@ target_link_libraries(video_core PRIVATE glad)
 if (ENABLE_VULKAN)
     target_link_libraries(video_core PRIVATE sirit)
 endif()
+
+if (MSVC)
+    target_compile_options(video_core PRIVATE /we4267)
+else()
+    target_compile_options(video_core PRIVATE -Werror=conversion -Wno-sign-conversion)
+endif()

From fb9418798d9421128c17a52c2b0160d71f015db0 Mon Sep 17 00:00:00 2001
From: Rodrigo Locatti <reinuseslisp@airmail.cc>
Date: Mon, 11 Nov 2019 18:00:37 -0300
Subject: [PATCH 4/4] video_core: Enable sign conversion warnings

Enable sign conversion warnings but don't treat them as errors.
---
 src/video_core/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 35e933858..45d8eaf23 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -184,5 +184,5 @@ endif()
 if (MSVC)
     target_compile_options(video_core PRIVATE /we4267)
 else()
-    target_compile_options(video_core PRIVATE -Werror=conversion -Wno-sign-conversion)
+    target_compile_options(video_core PRIVATE -Werror=conversion -Wno-error=sign-conversion)
 endif()