summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/video
diff options
context:
space:
mode:
author Ted Green <tedgreen99@protonmail.com>2018-03-11 12:36:08 -0600
committer Ted Green <tedgreen99@protonmail.com>2018-03-11 12:36:59 -0600
commit10bca50668dbdd6bdffbd85f8b1cabeb053fd453 (patch)
treed100305428b1bc6b36d9d068dcef64eb0deb7ce6 /src/emu/video
parent4c6ec5cd03f2b130576107f7b80c1dca27f1264f (diff)
rgbsse: Fix scaling functions for negative values. Fixes graphical anomalies in warfa.
Diffstat (limited to 'src/emu/video')
-rw-r--r--src/emu/video/rgbsse.h24
1 files changed, 13 insertions, 11 deletions
diff --git a/src/emu/video/rgbsse.h b/src/emu/video/rgbsse.h
index 0b1a13c0beb..a04145a4d82 100644
--- a/src/emu/video/rgbsse.h
+++ b/src/emu/video/rgbsse.h
@@ -304,7 +304,7 @@ public:
// clamp_to_uint8();
//}
- // This version needs values to be 12 bits or less
+ // This version needs absolute value of value and scale to be 11 bits or less
inline void scale_imm_and_clamp(const s16 scale)
{
// Set mult a 16 bit inputs to scale
@@ -324,7 +324,7 @@ public:
m_value = _mm_unpacklo_epi16(m_value, _mm_setzero_si128());
}
- // This function needs values to be 12 bits or less
+ // This function needs absolute value of color and scale to be 11 bits or less
inline void scale_add_and_clamp(const rgbaint_t& scale, const rgbaint_t& other)
{
// Pack scale into mult a 16 bits
@@ -337,16 +337,15 @@ public:
m_value = _mm_slli_epi16(m_value, 4);
// Do the 16 bit multiply, bottom 64 bits will contain 16 bit truncated results
m_value = _mm_mulhi_epi16(m_value, tmp1);
- // Clamp to u8
- m_value = _mm_packus_epi16(m_value, _mm_setzero_si128());
- // Unpack up to s32
- m_value = _mm_unpacklo_epi8(m_value, _mm_setzero_si128());
- m_value = _mm_unpacklo_epi16(m_value, _mm_setzero_si128());
+ // Unpack up to s32, putting the 16 bit value at the top so the sign bit is set by the 16 bit result
+ m_value = _mm_unpacklo_epi16(_mm_setzero_si128(), m_value);
+ // Arithmetic shift down the 16 bit value to the lower 16 bits
+ sra_imm(16);
add(other);
clamp_to_uint8();
}
- // This function needs values to be 12 bits or less
+ // This function needs absolute value of color and scale to be 11 bits or less
inline void scale2_add_and_clamp(const rgbaint_t& scale, const rgbaint_t& other, const rgbaint_t& scale2)
{
// Pack both scale values into mult a 16 bits
@@ -359,9 +358,12 @@ public:
m_value = _mm_slli_epi16(m_value, 4);
// Do the 16 bit multiply, top and bottom 64 bits will contain 16 bit truncated results
tmp1 = _mm_mulhi_epi16(m_value, tmp1);
- // Unpack the results
- m_value = _mm_unpacklo_epi16(tmp1, _mm_setzero_si128());
- tmp1 = _mm_unpackhi_epi16(tmp1, _mm_setzero_si128());
+ // Unpack up to s32, putting the 16 bit value at the top so the sign bit is set by the 16 bit result
+ m_value = _mm_unpacklo_epi16(_mm_setzero_si128(), tmp1);
+ tmp1 = _mm_unpackhi_epi16(_mm_setzero_si128(), tmp1);
+ // Arithmetic shift down the 16 bit value to the lower 16 bits
+ sra_imm(16);
+ tmp1 = _mm_srai_epi32(tmp1, 16);
// Add the results
m_value = _mm_add_epi32(m_value, tmp1);
clamp_to_uint8();