diff options
author | 2021-07-08 18:35:00 -0700 | |
---|---|---|
committer | 2021-07-09 11:35:00 +1000 | |
commit | 6ffc98289c9466cb01941c05a5b3088ac022a0b6 (patch) | |
tree | 62bc23850838f7f48d47f555292ea409f15f51ae /src/emu/video | |
parent | e9a86fc9fe55d45265b39fa7368e1645629aa314 (diff) |
video/voodoo.cpp: Major rewrite: (#8267)
* Changed to use modern poly.h instead of polylgcy.h.
* Moved helper classes into separate voodoo namespace.
* Derived device classes from video_device_interface.
* Split classes so that later versions derive from earlier versions.
* Created device maps to be directly included.
* Redesigned register mapping to use helper classes and delegates.
* Rewrote rasterizers to use C++ templates instead of macros.
* Added logic to compute equations for color/texture combine units.
* Added special generic identity-texel rasterizer cases.
* Removed pipeline stalls on texture and palette changes.
* Removed pipeline stalls on most all parameter changes.
* Generally re-thought and cleaned up logic throughout.
* Parameterized cycle stealing on status reads; updated all existing voodoo consumers to configure it as it was before.
-vidoe/poly.h: Various improvements:
* Exposed poly_array class for broader use.
* Changed poly_array to intelligently determine maximum size.
* Added logic to track multiple "last" instances in poly_array.
* Extended logic to support up to 16m work items.
* Removed MaxPolys parameter from poly_manager template.
* Added Flags parameter to poly_manager template.
* Added POLY_FLAG_NO_CLIPPING flag to remove clipping code when not needed.
* poly_manager now supports a MaxParams value of 0.
* Made paramcount a template parameter for render_* functions.
* Added reset_after_wait() method to be overridden by derived classes.
* Switched to using std:: helpers instead of internal methods.
* Removed useless dependency on screen_device.
* TRACK_POLY_WAITS now produces more complete statistics.
-video/polylgcy.cpp: Removed legacy implementation of polygon renderer.
-machine/gt64xxx.cpp: Prevent lockups by disallowing 0-duration timers.
-machine/pci.cpp: Added support for adding subdevice maps directly.
-emu/video/rgbsse.h: Improved min/max for SSE4.1+ and scale+clamp operations for all.
-emu/vidoe/rgbutil.h: Made palette expansion constexpr and added argbexpand function.
-osd/osdcore.cpp: Changed osd_ticks to use QueryPerformanceCounter on Windows since the mingw std::chrono::high_resolution_clock is anything but.
Diffstat (limited to 'src/emu/video')
-rw-r--r-- | src/emu/video/rgbsse.cpp | 2 | ||||
-rw-r--r-- | src/emu/video/rgbsse.h | 66 | ||||
-rw-r--r-- | src/emu/video/rgbutil.h | 2 |
3 files changed, 34 insertions, 36 deletions
diff --git a/src/emu/video/rgbsse.cpp b/src/emu/video/rgbsse.cpp index 3b9c80273af..d7cabfa19a2 100644 --- a/src/emu/video/rgbsse.cpp +++ b/src/emu/video/rgbsse.cpp @@ -12,7 +12,7 @@ #include "emu.h" -#if (!defined(MAME_DEBUG) || defined(__OPTIMIZE__)) && (defined(__SSE2__) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 2))) +#if (!defined(MAME_DEBUG) || defined(__OPTIMIZE__)) && (defined(__SSE2__) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 2))) #include "rgbsse.h" diff --git a/src/emu/video/rgbsse.h b/src/emu/video/rgbsse.h index a04145a4d82..ea3bc1e208b 100644 --- a/src/emu/video/rgbsse.h +++ b/src/emu/video/rgbsse.h @@ -271,6 +271,9 @@ public: inline void min(const s32 value) { __m128i val = _mm_set1_epi32(value); +#ifdef __SSE4_1__ + m_value = _mm_min_epi32(m_value, val); +#else __m128i is_greater_than = _mm_cmpgt_epi32(m_value, val); __m128i val_to_set = _mm_and_si128(val, is_greater_than); @@ -278,11 +281,15 @@ public: m_value = _mm_and_si128(m_value, keep_mask); m_value = _mm_or_si128(val_to_set, m_value); +#endif } inline void max(const s32 value) { __m128i val = _mm_set1_epi32(value); +#ifdef __SSE4_1__ + m_value = _mm_max_epi32(m_value, val); +#else __m128i is_less_than = _mm_cmplt_epi32(m_value, val); __m128i val_to_set = _mm_and_si128(val, is_less_than); @@ -290,6 +297,7 @@ public: m_value = _mm_and_si128(m_value, keep_mask); m_value = _mm_or_si128(val_to_set, m_value); +#endif } void blend(const rgbaint_t& other, u8 factor); @@ -324,48 +332,38 @@ public: m_value = _mm_unpacklo_epi16(m_value, _mm_setzero_si128()); } - // This function needs absolute value of color and scale to be 11 bits or less + // This function needs absolute value of color and scale to be 15 bits or less inline void scale_add_and_clamp(const rgbaint_t& scale, const rgbaint_t& other) { - // Pack scale into mult a 16 bits - __m128i tmp1 = _mm_packs_epi32(scale.m_value, _mm_setzero_si128()); - // Shift up by 4 - tmp1 = _mm_slli_epi16(tmp1, 4); - // Pack color into mult b 16 bit inputs - m_value = _mm_packs_epi32(m_value, _mm_setzero_si128()); - // Shift up by 4 - 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); - // 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); +#ifdef __SSE4_1__ + m_value = _mm_mullo_epi32(m_value, scale.m_value); +#else + // Mask off the top 16 bits of each 32-bit value + m_value = _mm_and_si128(m_value, _mm_set1_epi32(0x0000ffff)); + // Do 16x16 multiplies and sum into 32-bit pairs; the AND above ensures upper pair is always 0 + m_value = _mm_madd_epi16(m_value, scale.m_value); +#endif + // Arithmetic shift down the result by 8 bits + sra_imm(8); add(other); clamp_to_uint8(); } - // This function needs absolute value of color and scale to be 11 bits or less + // This function needs absolute value of color and scale to be 15 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 - __m128i tmp1 = _mm_packs_epi32(scale.m_value, scale2.m_value); - // Shift up by 4 - tmp1 = _mm_slli_epi16(tmp1, 4); - // Pack both color values into mult b 16 bit inputs - m_value = _mm_packs_epi32(m_value, other.m_value); - // Shift up by 4 - 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 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); + // Pack 32-bit values to 16-bit values in low half, and scales in top half + __m128i tmp1 = _mm_packs_epi32(m_value, scale.m_value); + // Same for other and scale2 + __m128i tmp2 = _mm_packs_epi32(other.m_value, scale2.m_value); + // Interleave the low halves (m_value, other) + __m128i tmp3 = _mm_unpacklo_epi16(tmp1, tmp2); + // Interleave the top halves (scale, scale2) + __m128i tmp4 = _mm_unpackhi_epi16(tmp1, tmp2); + // Multiply values by scales and add adjacent pairs + m_value = _mm_madd_epi16(tmp3, tmp4); + // Final shift by 8 + sra_imm(8); clamp_to_uint8(); } diff --git a/src/emu/video/rgbutil.h b/src/emu/video/rgbutil.h index acf7abb8f82..c6ee325c754 100644 --- a/src/emu/video/rgbutil.h +++ b/src/emu/video/rgbutil.h @@ -13,7 +13,7 @@ #define MAME_EMU_VIDEO_RGBUTIL_H // use SSE on 64-bit implementations, where it can be assumed -#if (!defined(MAME_DEBUG) || defined(__OPTIMIZE__)) && (defined(__SSE2__) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 2))) +#if (!defined(MAME_DEBUG) || defined(__OPTIMIZE__)) && (defined(__SSE2__) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 2))) #define MAME_RGB_HIGH_PRECISION #include "rgbsse.h" |