]> granicus.if.org Git - libvpx/commitdiff
VPX: Add vpx_hadamard_32x32_sse2
authorScott LaVarnway <slavarnway@google.com>
Fri, 20 Jul 2018 14:23:11 +0000 (07:23 -0700)
committerJames Zern <jzern@google.com>
Sat, 21 Jul 2018 18:10:05 +0000 (18:10 +0000)
BUG=webm:1546

Change-Id: Ide5828b890c5c27cfcca2d5e318a914f7cde1158

test/hadamard_test.cc
vpx_dsp/vpx_dsp_rtcd_defs.pl
vpx_dsp/x86/avg_intrin_sse2.c

index a2e36a757d598e441d5ef0db723478b6a09adf18..ad9b1a38a855e19ae4f91c1e27c5528521b5aa67 100644 (file)
@@ -302,12 +302,30 @@ INSTANTIATE_TEST_CASE_P(MSA, Hadamard16x16Test,
 
 class Hadamard32x32Test : public HadamardTestBase {};
 
+void HadamardSpeedTest32x32(HadamardFunc const func, int times) {
+  DECLARE_ALIGNED(16, int16_t, input[1024]);
+  DECLARE_ALIGNED(16, tran_low_t, output[1024]);
+  memset(input, 1, sizeof(input));
+  HadamardSpeedTest("Hadamard32x32", func, input, 32, output, times);
+}
+
 TEST_P(Hadamard32x32Test, CompareReferenceRandom) {
   CompareReferenceRandom<32>();
 }
 
 TEST_P(Hadamard32x32Test, VaryStride) { VaryStride<32>(); }
 
+TEST_P(Hadamard32x32Test, DISABLED_Speed) {
+  HadamardSpeedTest32x32(h_func_, 10);
+  HadamardSpeedTest32x32(h_func_, 10000);
+  HadamardSpeedTest32x32(h_func_, 10000000);
+}
+
 INSTANTIATE_TEST_CASE_P(C, Hadamard32x32Test,
                         ::testing::Values(&vpx_hadamard_32x32_c));
+
+#if HAVE_SSE2
+INSTANTIATE_TEST_CASE_P(SSE2, Hadamard32x32Test,
+                        ::testing::Values(&vpx_hadamard_32x32_sse2));
+#endif  // HAVE_SSE2
 }  // namespace
index b662c70c02cf66729b57061c6ddab78a8d2a348c..13b83e1f5123f43eb038ba8fc1ddf2c4b07ab3dd 100644 (file)
@@ -783,7 +783,7 @@ if (vpx_config("CONFIG_VP9_ENCODER") eq "yes") {
     specialize qw/vpx_hadamard_16x16 avx2 sse2 neon vsx/;
 
     add_proto qw/void vpx_hadamard_32x32/, "const int16_t *src_diff, ptrdiff_t src_stride, tran_low_t *coeff";
-    specialize qw/vpx_hadamard_32x32/;
+    specialize qw/vpx_hadamard_32x32 sse2/;
 
     add_proto qw/int vpx_satd/, "const tran_low_t *coeff, int length";
     specialize qw/vpx_satd avx2 sse2 neon/;
@@ -795,7 +795,7 @@ if (vpx_config("CONFIG_VP9_ENCODER") eq "yes") {
     specialize qw/vpx_hadamard_16x16 avx2 sse2 neon msa vsx/;
 
     add_proto qw/void vpx_hadamard_32x32/, "const int16_t *src_diff, ptrdiff_t src_stride, int16_t *coeff";
-    specialize qw/vpx_hadamard_32x32/;
+    specialize qw/vpx_hadamard_32x32 sse2/;
 
     add_proto qw/int vpx_satd/, "const int16_t *coeff, int length";
     specialize qw/vpx_satd avx2 sse2 neon msa/;
index 0362c63c5d1bd6690b21d1c364a19a724a803f4c..784135acb9e30ee990814a23968f0d0bf52473d2 100644 (file)
@@ -335,6 +335,45 @@ void vpx_hadamard_16x16_sse2(int16_t const *src_diff, ptrdiff_t src_stride,
   }
 }
 
+void vpx_hadamard_32x32_sse2(const int16_t *src_diff, ptrdiff_t src_stride,
+                             tran_low_t *coeff) {
+  int idx;
+  for (idx = 0; idx < 4; ++idx) {
+    const int16_t *src_ptr =
+        src_diff + (idx >> 1) * 16 * src_stride + (idx & 0x01) * 16;
+    vpx_hadamard_16x16_sse2(src_ptr, src_stride, coeff + idx * 256);
+  }
+
+  for (idx = 0; idx < 256; idx += 8) {
+    __m128i coeff0 = load_tran_low(coeff);
+    __m128i coeff1 = load_tran_low(coeff + 256);
+    __m128i coeff2 = load_tran_low(coeff + 512);
+    __m128i coeff3 = load_tran_low(coeff + 768);
+
+    __m128i b0 = _mm_add_epi16(coeff0, coeff1);
+    __m128i b1 = _mm_sub_epi16(coeff0, coeff1);
+    __m128i b2 = _mm_add_epi16(coeff2, coeff3);
+    __m128i b3 = _mm_sub_epi16(coeff2, coeff3);
+
+    b0 = _mm_srai_epi16(b0, 2);
+    b1 = _mm_srai_epi16(b1, 2);
+    b2 = _mm_srai_epi16(b2, 2);
+    b3 = _mm_srai_epi16(b3, 2);
+
+    coeff0 = _mm_add_epi16(b0, b2);
+    coeff1 = _mm_add_epi16(b1, b3);
+    store_tran_low(coeff0, coeff);
+    store_tran_low(coeff1, coeff + 256);
+
+    coeff2 = _mm_sub_epi16(b0, b2);
+    coeff3 = _mm_sub_epi16(b1, b3);
+    store_tran_low(coeff2, coeff + 512);
+    store_tran_low(coeff3, coeff + 768);
+
+    coeff += 8;
+  }
+}
+
 int vpx_satd_sse2(const tran_low_t *coeff, int length) {
   int i;
   const __m128i zero = _mm_setzero_si128();