summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/video
diff options
context:
space:
mode:
author Aaron Giles <aaronsgiles@users.noreply.github.com>2021-07-08 18:35:00 -0700
committer GitHub <noreply@github.com>2021-07-09 11:35:00 +1000
commit6ffc98289c9466cb01941c05a5b3088ac022a0b6 (patch)
tree62bc23850838f7f48d47f555292ea409f15f51ae /src/emu/video
parente9a86fc9fe55d45265b39fa7368e1645629aa314 (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.cpp2
-rw-r--r--src/emu/video/rgbsse.h66
-rw-r--r--src/emu/video/rgbutil.h2
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"