Commit 948e0bf939 for aom

commit 948e0bf93907c638879856fee7e7ac55a14a2e1c
Author: Frank Galligan <fgalligan@google.com>
Date:   Sat Oct 31 09:54:06 2026 -0700

    av1: Optimize 8-pt inv txfm and DC fast paths

    Inline VEX-compiled 8-point 1D inverse transforms into AVX2 callers, add
    DC-only (eob == 1) fast paths for DCT_DCT inverse transforms, inline 8x8
    forward transforms, and specialize power-of-two above_row copies in
    reconintra.c.

    Benchmarking results (incremental vs prev CL / cumulative vs baseline):
    - Stock avifenc still-image (Default 1T): -2.02% / -28.83% encode time
    - Stock avifenc still-image (Default 8T): -0.38% / -23.19% encode time
    - 48-image multi-rate corpus (Full Suite 1T): -1.01% / -29.22% time
    - Bit-exact output (1T and 8T)

    TAG=agy
    CONV=b929a630-a6cd-45a0-979c-1767c30178ee
    Change-Id: I72e842559d7bcba88eef617ad6f467ac314475ad

diff --git a/av1/common/av1_inv_txfm1d_cfg.h b/av1/common/av1_inv_txfm1d_cfg.h
index 0f5b80aac9..0062214af1 100644
--- a/av1/common/av1_inv_txfm1d_cfg.h
+++ b/av1/common/av1_inv_txfm1d_cfg.h
@@ -36,7 +36,27 @@ static const int8_t inv_start_range[TX_SIZES_ALL] = {
   7,  // 64x16 transform
 };

-extern const int8_t *av1_inv_txfm_shift_ls[TX_SIZES_ALL];
+static const int8_t av1_inv_txfm_shift_ls[TX_SIZES_ALL][2] = {
+  { 0, -4 },   // 4x4 transform
+  { -1, -4 },  // 8x8 transform
+  { -2, -4 },  // 16x16 transform
+  { -2, -4 },  // 32x32 transform
+  { -2, -4 },  // 64x64 transform
+  { 0, -4 },   // 4x8 transform
+  { 0, -4 },   // 8x4 transform
+  { -1, -4 },  // 8x16 transform
+  { -1, -4 },  // 16x8 transform
+  { -1, -4 },  // 16x32 transform
+  { -1, -4 },  // 32x16 transform
+  { -1, -4 },  // 32x64 transform
+  { -1, -4 },  // 64x32 transform
+  { -1, -4 },  // 4x16 transform
+  { -1, -4 },  // 16x4 transform
+  { -2, -4 },  // 8x32 transform
+  { -2, -4 },  // 32x8 transform
+  { -2, -4 },  // 16x64 transform
+  { -2, -4 },  // 64x16 transform
+};

 // Values in both av1_inv_cos_bit_col and av1_inv_cos_bit_row are always 12
 // for each valid row and col combination
diff --git a/av1/common/av1_inv_txfm2d.c b/av1/common/av1_inv_txfm2d.c
index 715fcb000f..f5f1c5f0b7 100644
--- a/av1/common/av1_inv_txfm2d.c
+++ b/av1/common/av1_inv_txfm2d.c
@@ -131,34 +131,6 @@ static inline TxfmFunc inv_txfm_type_to_func(TXFM_TYPE txfm_type) {
   }
 }

-static const int8_t inv_shift_4x4[2] = { 0, -4 };
-static const int8_t inv_shift_8x8[2] = { -1, -4 };
-static const int8_t inv_shift_16x16[2] = { -2, -4 };
-static const int8_t inv_shift_32x32[2] = { -2, -4 };
-static const int8_t inv_shift_64x64[2] = { -2, -4 };
-static const int8_t inv_shift_4x8[2] = { 0, -4 };
-static const int8_t inv_shift_8x4[2] = { 0, -4 };
-static const int8_t inv_shift_8x16[2] = { -1, -4 };
-static const int8_t inv_shift_16x8[2] = { -1, -4 };
-static const int8_t inv_shift_16x32[2] = { -1, -4 };
-static const int8_t inv_shift_32x16[2] = { -1, -4 };
-static const int8_t inv_shift_32x64[2] = { -1, -4 };
-static const int8_t inv_shift_64x32[2] = { -1, -4 };
-static const int8_t inv_shift_4x16[2] = { -1, -4 };
-static const int8_t inv_shift_16x4[2] = { -1, -4 };
-static const int8_t inv_shift_8x32[2] = { -2, -4 };
-static const int8_t inv_shift_32x8[2] = { -2, -4 };
-static const int8_t inv_shift_16x64[2] = { -2, -4 };
-static const int8_t inv_shift_64x16[2] = { -2, -4 };
-
-const int8_t *av1_inv_txfm_shift_ls[TX_SIZES_ALL] = {
-  inv_shift_4x4,   inv_shift_8x8,   inv_shift_16x16, inv_shift_32x32,
-  inv_shift_64x64, inv_shift_4x8,   inv_shift_8x4,   inv_shift_8x16,
-  inv_shift_16x8,  inv_shift_16x32, inv_shift_32x16, inv_shift_32x64,
-  inv_shift_64x32, inv_shift_4x16,  inv_shift_16x4,  inv_shift_8x32,
-  inv_shift_32x8,  inv_shift_16x64, inv_shift_64x16,
-};
-
 static const int8_t iadst4_range[7] = { 0, 1, 0, 0, 0, 0, 0 };

 void av1_get_inv_txfm_cfg(TX_TYPE tx_type, TX_SIZE tx_size,
diff --git a/av1/common/reconintra.c b/av1/common/reconintra.c
index a4eaf77c88..09ddc1a51e 100644
--- a/av1/common/reconintra.c
+++ b/av1/common/reconintra.c
@@ -1081,6 +1081,26 @@ void av1_upsample_intra_edge_c(uint8_t *p, int sz) {
   }
 }

+static AOM_FORCE_INLINE void copy_above_row_lbd(uint8_t *above_row,
+                                                const uint8_t *above_ref,
+                                                int n_copy) {
+  if (n_copy == 4) {
+    memcpy(above_row, above_ref, 4);
+  } else if (n_copy == 8) {
+    memcpy(above_row, above_ref, 8);
+  } else if (n_copy == 16) {
+    memcpy(above_row, above_ref, 16);
+  } else if (n_copy == 32) {
+    memcpy(above_row, above_ref, 32);
+  } else if (n_copy == 64) {
+    memcpy(above_row, above_ref, 64);
+  } else if (n_copy == 128) {
+    memcpy(above_row, above_ref, 128);
+  } else {
+    memcpy(above_row, above_ref, n_copy);
+  }
+}
+
 static void build_directional_and_filter_intra_predictors(
     const uint8_t *ref, int ref_stride, uint8_t *dst, int dst_stride,
     PREDICTION_MODE mode, int p_angle, FILTER_INTRA_MODE filter_intra_mode,
@@ -1148,7 +1168,7 @@ static void build_directional_and_filter_intra_predictors(
     const int num_top_pixels_needed = txwpx + (n_topright_px >= 0 ? txhpx : 0);
     if (n_top_px > 0) {
       const int n_top_copy = n_top_px + (n_topright_px > 0 ? n_topright_px : 0);
-      memcpy(above_row, above_ref, n_top_copy);
+      copy_above_row_lbd(above_row, above_ref, n_top_copy);
       if (n_top_copy < num_top_pixels_needed)
         memset(&above_row[n_top_copy], above_row[n_top_copy - 1],
                num_top_pixels_needed - n_top_copy);
@@ -1305,10 +1325,11 @@ static void build_non_directional_intra_predictors(
   }

   if (need_above) {
-    if (n_top_px > 0) {
-      memcpy(above_row, above_ref, n_top_px);
-      i = n_top_px;
-      if (i < txwpx) memset(&above_row[i], above_row[i - 1], txwpx - i);
+    if (LIKELY(n_top_px == txwpx)) {
+      copy_above_row_lbd(above_row, above_ref, txwpx);
+    } else if (n_top_px > 0) {
+      copy_above_row_lbd(above_row, above_ref, n_top_px);
+      memset(&above_row[n_top_px], above_row[n_top_px - 1], txwpx - n_top_px);
     } else {
       const uint8_t val = (n_left_px > 0) ? left_ref[0] : 127;
       memset(above_row, val, txwpx);
@@ -1400,6 +1421,26 @@ void av1_highbd_upsample_intra_edge_c(uint16_t *p, int sz, int bd) {
   }
 }

+static AOM_FORCE_INLINE void copy_above_row_hbd(uint16_t *above_row,
+                                                const uint16_t *above_ref,
+                                                int n_copy) {
+  if (n_copy == 4) {
+    memcpy(above_row, above_ref, 4 * sizeof(uint16_t));
+  } else if (n_copy == 8) {
+    memcpy(above_row, above_ref, 8 * sizeof(uint16_t));
+  } else if (n_copy == 16) {
+    memcpy(above_row, above_ref, 16 * sizeof(uint16_t));
+  } else if (n_copy == 32) {
+    memcpy(above_row, above_ref, 32 * sizeof(uint16_t));
+  } else if (n_copy == 64) {
+    memcpy(above_row, above_ref, 64 * sizeof(uint16_t));
+  } else if (n_copy == 128) {
+    memcpy(above_row, above_ref, 128 * sizeof(uint16_t));
+  } else {
+    memcpy(above_row, above_ref, n_copy * sizeof(uint16_t));
+  }
+}
+
 static void highbd_build_directional_and_filter_intra_predictors(
     const uint8_t *ref8, int ref_stride, uint8_t *dst8, int dst_stride,
     PREDICTION_MODE mode, int p_angle, FILTER_INTRA_MODE filter_intra_mode,
@@ -1471,7 +1512,7 @@ static void highbd_build_directional_and_filter_intra_predictors(
     const int num_top_pixels_needed = txwpx + (n_topright_px >= 0 ? txhpx : 0);
     if (n_top_px > 0) {
       const int n_top_copy = n_top_px + (n_topright_px > 0 ? n_topright_px : 0);
-      memcpy(above_row, above_ref, n_top_copy * sizeof(above_ref[0]));
+      copy_above_row_hbd(above_row, above_ref, n_top_copy);
       if (n_top_copy < num_top_pixels_needed)
         aom_memset16(&above_row[n_top_copy], above_row[n_top_copy - 1],
                      num_top_pixels_needed - n_top_copy);
@@ -1635,10 +1676,12 @@ static void highbd_build_non_directional_intra_predictors(
   }

   if (need_above) {
-    if (n_top_px > 0) {
-      memcpy(above_row, above_ref, n_top_px * sizeof(above_ref[0]));
-      i = n_top_px;
-      if (i < txwpx) aom_memset16(&above_row[i], above_row[i - 1], (txwpx - i));
+    if (LIKELY(n_top_px == txwpx)) {
+      copy_above_row_hbd(above_row, above_ref, txwpx);
+    } else if (n_top_px > 0) {
+      copy_above_row_hbd(above_row, above_ref, n_top_px);
+      aom_memset16(&above_row[n_top_px], above_row[n_top_px - 1],
+                   txwpx - n_top_px);
     } else {
       const int val = (n_left_px > 0) ? left_ref[0] : base - 1;
       aom_memset16(above_row, val, txwpx);
diff --git a/av1/common/x86/av1_inv_txfm_avx2.c b/av1/common/x86/av1_inv_txfm_avx2.c
index 0766210791..8136091a02 100644
--- a/av1/common/x86/av1_inv_txfm_avx2.c
+++ b/av1/common/x86/av1_inv_txfm_avx2.c
@@ -1636,19 +1636,47 @@ static const transform_1d_avx2
 static inline void lowbd_inv_txfm2d_add_no_identity_avx2(
     const int32_t *input, uint8_t *output, int stride, TX_TYPE tx_type,
     TX_SIZE tx_size, int eob) {
-  __m256i buf1[64 * 16];
-  int eobx, eoby;
-  get_eobx_eoby_scan_default(&eobx, &eoby, tx_size, eob);
   const int8_t *shift = av1_inv_txfm_shift_ls[tx_size];
-  const int txw_idx = get_txw_idx(tx_size);
-  const int txh_idx = get_txh_idx(tx_size);
   const int txfm_size_col = tx_size_wide[tx_size];
   const int txfm_size_row = tx_size_high[tx_size];
   const int buf_size_w_div16 = txfm_size_col >> 4;
+  const int rect_type = get_rect_tx_log_ratio(txfm_size_col, txfm_size_row);
+
+  // DC-only (eob == 1) fast path for DCT_DCT: compute the constant 2D inverse
+  // DCT contribution once and add it directly to the reconstruction buffer.
+  if (eob == 1 && tx_type == DCT_DCT) {
+    const int32_t *cospi = cospi_arr(INV_COS_BIT);
+    const __m128i w = _mm_set1_epi16(cospi[32] * 8);
+    const __m128i s0 = _mm_set1_epi16(1 << (15 + shift[0]));
+    const __m128i s1 = _mm_set1_epi16(1 << (15 - 4));
+    __m128i dc = _mm_cvtsi32_si128(input[0]);
+    dc = _mm_packs_epi32(dc, dc);
+    if (rect_type == 1 || rect_type == -1) {
+      dc = _mm_mulhrs_epi16(dc, _mm_set1_epi16(NewInvSqrt2 * 8));
+    }
+    dc = _mm_mulhrs_epi16(dc, w);
+    dc = _mm_mulhrs_epi16(dc, s0);
+    dc = _mm_mulhrs_epi16(dc, w);
+    dc = _mm_mulhrs_epi16(dc, s1);
+
+    const __m256i res = _mm256_broadcastw_epi16(dc);
+    for (int i = 0; i < buf_size_w_div16; i++) {
+      uint8_t *out_col = output + 16 * i;
+      for (int r = 0; r < txfm_size_row; ++r) {
+        write_recon_w16_avx2(res, out_col + r * stride);
+      }
+    }
+    return;
+  }
+
+  __m256i buf1[64 * 4];
+  int eobx, eoby;
+  get_eobx_eoby_scan_default(&eobx, &eoby, tx_size, eob);
+  const int txw_idx = get_txw_idx(tx_size);
+  const int txh_idx = get_txh_idx(tx_size);
   const int buf_size_nonzero_w = ((eobx + 16) >> 4) << 4;
   const int buf_size_nonzero_h_div16 = (eoby + 16) >> 4;
   const int input_stride = AOMMIN(32, txfm_size_row);
-  const int rect_type = get_rect_tx_log_ratio(txfm_size_col, txfm_size_row);

   const int fun_idx_x = lowbd_txfm_all_1d_zeros_idx[eobx];
   const int fun_idx_y = lowbd_txfm_all_1d_zeros_idx[eoby];
@@ -1688,7 +1716,7 @@ static inline void lowbd_inv_txfm2d_add_no_identity_avx2(
       }
     }
   }
-  const __m256i scale1 = _mm256_set1_epi16(1 << (15 + shift[1]));
+  const __m256i scale1 = _mm256_set1_epi16(1 << (15 - 4));
   for (int i = 0; i < buf_size_w_div16; i++) {
     __m256i *buf1_cur = buf1 + i * txfm_size_row;
     col_txfm(buf1_cur, buf1_cur);
@@ -1891,9 +1919,24 @@ static inline void lowbd_inv_txfm2d_add_v_identity_avx2(
   }
 }

+static void idct8_low1_avx2(const __m128i *input, __m128i *output) {
+  idct8_low1_ssse3_inline(input, output);
+}
+
+static void idct8_avx2(const __m128i *input, __m128i *output) {
+  idct8_sse2_inline(input, output);
+}
+
+static void iadst8_low1_avx2(const __m128i *input, __m128i *output) {
+  iadst8_low1_ssse3_inline(input, output);
+}
+
+static void iadst8_avx2(const __m128i *input, __m128i *output) {
+  iadst8_sse2_inline(input, output);
+}
+
 static const transform_1d_ssse3 lowbd_txfm_all_1d_zeros_8x8_arr[2][2] = {
-  { av1_idct8_low1_ssse3, av1_idct8_sse2 },
-  { av1_iadst8_low1_ssse3, av1_iadst8_sse2 }
+  { idct8_low1_avx2, idct8_avx2 }, { iadst8_low1_avx2, iadst8_avx2 }
 };

 static inline void load_buffer_avx2(const int32_t *in, int stride,
@@ -2114,9 +2157,90 @@ static inline void round_shift_lowbd_write_buffer_avx2(__m128i *in, int bit,
 static inline void lowbd_inv_txfm2d_8x8_no_identity_avx2(
     const int32_t *input, uint8_t *output, int stride, TX_TYPE tx_type,
     TX_SIZE tx_size, int eob) {
-  __m128i buf1[8];
+  (void)tx_size;
+  __m128i buf0[8], buf1[8];
   const int input_stride = 8;
-  const int8_t *shift = av1_inv_txfm_shift_ls[tx_size];
+
+  if (tx_type == DCT_DCT) {
+    // DC-only (eob == 1) fast path for 8x8 DCT_DCT.
+    if (eob == 1) {
+      const int32_t *cospi = cospi_arr(INV_COS_BIT);
+      const __m128i w = _mm_set1_epi16(cospi[32] * 8);
+      const __m128i s0 = _mm_set1_epi16(1 << (15 - 1));
+      const __m128i s1 = _mm_set1_epi16(1 << (15 - 4));
+      __m128i dc = _mm_cvtsi32_si128(input[0]);
+      dc = _mm_packs_epi32(dc, dc);
+      dc = _mm_mulhrs_epi16(dc, w);
+      dc = _mm_mulhrs_epi16(dc, s0);
+      dc = _mm_mulhrs_epi16(dc, w);
+      dc = _mm_mulhrs_epi16(dc, s1);
+
+      const __m256i dc256 = _mm256_broadcastw_epi16(dc);
+      const __m256i zero = _mm256_setzero_si256();
+      const __m128i v0 = _mm_loadl_epi64((__m128i const *)(output));
+      const __m128i v1 = _mm_loadl_epi64((__m128i const *)(output + stride));
+      const __m128i v2 =
+          _mm_loadl_epi64((__m128i const *)(output + 2 * stride));
+      const __m128i v3 =
+          _mm_loadl_epi64((__m128i const *)(output + 3 * stride));
+      const __m128i v4 =
+          _mm_loadl_epi64((__m128i const *)(output + 4 * stride));
+      const __m128i v5 =
+          _mm_loadl_epi64((__m128i const *)(output + 5 * stride));
+      const __m128i v6 =
+          _mm_loadl_epi64((__m128i const *)(output + 6 * stride));
+      const __m128i v7 =
+          _mm_loadl_epi64((__m128i const *)(output + 7 * stride));
+
+      const __m256i v01 =
+          _mm256_inserti128_si256(_mm256_castsi128_si256(v0), v1, 1);
+      const __m256i v23 =
+          _mm256_inserti128_si256(_mm256_castsi128_si256(v2), v3, 1);
+      const __m256i v45 =
+          _mm256_inserti128_si256(_mm256_castsi128_si256(v4), v5, 1);
+      const __m256i v67 =
+          _mm256_inserti128_si256(_mm256_castsi128_si256(v6), v7, 1);
+
+      const __m256i x0 =
+          _mm256_adds_epi16(dc256, _mm256_unpacklo_epi8(v01, zero));
+      const __m256i x1 =
+          _mm256_adds_epi16(dc256, _mm256_unpacklo_epi8(v23, zero));
+      const __m256i x2 =
+          _mm256_adds_epi16(dc256, _mm256_unpacklo_epi8(v45, zero));
+      const __m256i x3 =
+          _mm256_adds_epi16(dc256, _mm256_unpacklo_epi8(v67, zero));
+
+      const __m256i res_0123 = _mm256_packus_epi16(x0, x1);
+      const __m256i res_4567 = _mm256_packus_epi16(x2, x3);
+      const __m128i res_02 = _mm256_castsi256_si128(res_0123);
+      const __m128i res_13 = _mm256_extracti128_si256(res_0123, 1);
+      const __m128i res_46 = _mm256_castsi256_si128(res_4567);
+      const __m128i res_57 = _mm256_extracti128_si256(res_4567, 1);
+
+      _mm_storel_epi64((__m128i *)(output), res_02);
+      _mm_storel_epi64((__m128i *)(output + stride), res_13);
+      _mm_storel_epi64((__m128i *)(output + 2 * stride),
+                       _mm_unpackhi_epi64(res_02, res_02));
+      _mm_storel_epi64((__m128i *)(output + 3 * stride),
+                       _mm_unpackhi_epi64(res_13, res_13));
+      _mm_storel_epi64((__m128i *)(output + 4 * stride), res_46);
+      _mm_storel_epi64((__m128i *)(output + 5 * stride), res_57);
+      _mm_storel_epi64((__m128i *)(output + 6 * stride),
+                       _mm_unpackhi_epi64(res_46, res_46));
+      _mm_storel_epi64((__m128i *)(output + 7 * stride),
+                       _mm_unpackhi_epi64(res_57, res_57));
+      return;
+    }
+
+    int lr_flip = 0;
+    load_buffer_avx2(input, input_stride, buf0);
+    idct8_sse2_inline(buf0, buf0);
+    round_and_transpose_avx2(buf0, buf1, -1, &lr_flip);
+    idct8_sse2_inline(buf1, buf1);
+    round_shift_lowbd_write_buffer_avx2(buf1, -4, output, stride, 0);
+    return;
+  }
+
   assert(hitx_1d_tab[tx_type] < 2);
   assert(vitx_1d_tab[tx_type] < 2);
   const transform_1d_ssse3 row_txfm =
@@ -2129,17 +2253,11 @@ static inline void lowbd_inv_txfm2d_8x8_no_identity_avx2(
   int ud_flip, lr_flip;
   get_flip_cfg(tx_type, &ud_flip, &lr_flip);

-  __m128i buf0[8];
-  __m128i *buf0_cur = buf0;
-  load_buffer_avx2(input, input_stride, buf0_cur);
+  load_buffer_avx2(input, input_stride, buf0);
   row_txfm(buf0, buf0);
-
-  assert(shift[0] < 0);
-  __m128i *_buf1 = buf1;
-  round_and_transpose_avx2(buf0, _buf1, shift[0], &lr_flip);
-  assert(shift[1] < 0);
+  round_and_transpose_avx2(buf0, buf1, -1, &lr_flip);
   col_txfm(buf1, buf1);
-  round_shift_lowbd_write_buffer_avx2(buf1, shift[1], output, stride, ud_flip);
+  round_shift_lowbd_write_buffer_avx2(buf1, -4, output, stride, ud_flip);
 }

 // AVX2 implementation of 8x8 inverse transform. Observed that coding AVX2 for
diff --git a/av1/common/x86/av1_inv_txfm_ssse3.c b/av1/common/x86/av1_inv_txfm_ssse3.c
index 863c9cae29..0a83c8c672 100644
--- a/av1/common/x86/av1_inv_txfm_ssse3.c
+++ b/av1/common/x86/av1_inv_txfm_ssse3.c
@@ -79,74 +79,11 @@ static void idct4_w4_sse2(const __m128i *input, __m128i *output) {
 }

 void av1_idct8_low1_ssse3(const __m128i *input, __m128i *output) {
-  const int32_t *cospi = cospi_arr(INV_COS_BIT);
-
-  // stage 1
-  __m128i x[2];
-  x[0] = input[0];
-
-  // stage 2
-  // stage 3
-  btf_16_ssse3(cospi[32], cospi[32], x[0], x[0], x[1]);
-
-  // stage 4
-  // stage 5
-  output[0] = x[0];
-  output[7] = x[0];
-  output[1] = x[1];
-  output[6] = x[1];
-  output[2] = x[1];
-  output[5] = x[1];
-  output[3] = x[0];
-  output[4] = x[0];
+  idct8_low1_ssse3_inline(input, output);
 }

 void av1_idct8_sse2(const __m128i *input, __m128i *output) {
-  const int8_t cos_bit = INV_COS_BIT;
-  const int32_t *cospi = cospi_arr(INV_COS_BIT);
-  const __m128i __rounding = _mm_set1_epi32(1 << (INV_COS_BIT - 1));
-
-  const __m128i cospi_p56_m08 = pair_set_epi16(cospi[56], -cospi[8]);
-  const __m128i cospi_p08_p56 = pair_set_epi16(cospi[8], cospi[56]);
-  const __m128i cospi_p24_m40 = pair_set_epi16(cospi[24], -cospi[40]);
-  const __m128i cospi_p40_p24 = pair_set_epi16(cospi[40], cospi[24]);
-  const __m128i cospi_p32_p32 = pair_set_epi16(cospi[32], cospi[32]);
-  const __m128i cospi_p32_m32 = pair_set_epi16(cospi[32], -cospi[32]);
-  const __m128i cospi_p48_m16 = pair_set_epi16(cospi[48], -cospi[16]);
-  const __m128i cospi_p16_p48 = pair_set_epi16(cospi[16], cospi[48]);
-  const __m128i cospi_m32_p32 = pair_set_epi16(-cospi[32], cospi[32]);
-
-  // stage 1
-  __m128i x[8];
-  x[0] = input[0];
-  x[1] = input[4];
-  x[2] = input[2];
-  x[3] = input[6];
-  x[4] = input[1];
-  x[5] = input[5];
-  x[6] = input[3];
-  x[7] = input[7];
-
-  // stage 2
-  btf_16_sse2(cospi_p56_m08, cospi_p08_p56, x[4], x[7], x[4], x[7]);
-  btf_16_sse2(cospi_p24_m40, cospi_p40_p24, x[5], x[6], x[5], x[6]);
-
-  // stage 3
-  btf_16_sse2(cospi_p32_p32, cospi_p32_m32, x[0], x[1], x[0], x[1]);
-  btf_16_sse2(cospi_p48_m16, cospi_p16_p48, x[2], x[3], x[2], x[3]);
-  btf_16_adds_subs_sse2(x[4], x[5]);
-  btf_16_subs_adds_sse2(x[7], x[6]);
-
-  // stage 4
-  btf_16_adds_subs_sse2(x[0], x[3]);
-  btf_16_adds_subs_sse2(x[1], x[2]);
-  btf_16_sse2(cospi_m32_p32, cospi_p32_p32, x[5], x[6], x[5], x[6]);
-
-  // stage 5
-  btf_16_adds_subs_out_sse2(output[0], output[7], x[0], x[7]);
-  btf_16_adds_subs_out_sse2(output[1], output[6], x[1], x[6]);
-  btf_16_adds_subs_out_sse2(output[2], output[5], x[2], x[5]);
-  btf_16_adds_subs_out_sse2(output[3], output[4], x[3], x[4]);
+  idct8_sse2_inline(input, output);
 }

 static void idct8_w4_sse2(const __m128i *input, __m128i *output) {
@@ -1701,117 +1638,11 @@ static void iadst4_w4_sse2(const __m128i *input, __m128i *output) {
 }

 void av1_iadst8_low1_ssse3(const __m128i *input, __m128i *output) {
-  const int8_t cos_bit = INV_COS_BIT;
-  const int32_t *cospi = cospi_arr(INV_COS_BIT);
-  const __m128i __zero = _mm_setzero_si128();
-  const __m128i __rounding = _mm_set1_epi32(1 << (INV_COS_BIT - 1));
-
-  const __m128i cospi_p16_p48 = pair_set_epi16(cospi[16], cospi[48]);
-  const __m128i cospi_p48_m16 = pair_set_epi16(cospi[48], -cospi[16]);
-  const __m128i cospi_p32_p32 = pair_set_epi16(cospi[32], cospi[32]);
-  const __m128i cospi_p32_m32 = pair_set_epi16(cospi[32], -cospi[32]);
-
-  // stage 1
-  __m128i x[8];
-  x[1] = input[0];
-
-  // stage 2
-  btf_16_ssse3(cospi[60], -cospi[4], x[1], x[0], x[1]);
-
-  // stage 3
-  x[4] = x[0];
-  x[5] = x[1];
-
-  // stage 4
-  btf_16_sse2(cospi_p16_p48, cospi_p48_m16, x[4], x[5], x[4], x[5]);
-
-  // stage 5
-  x[2] = x[0];
-  x[3] = x[1];
-  x[6] = x[4];
-  x[7] = x[5];
-
-  // stage 6
-  btf_16_sse2(cospi_p32_p32, cospi_p32_m32, x[2], x[3], x[2], x[3]);
-  btf_16_sse2(cospi_p32_p32, cospi_p32_m32, x[6], x[7], x[6], x[7]);
-
-  // stage 7
-  output[0] = x[0];
-  output[1] = _mm_subs_epi16(__zero, x[4]);
-  output[2] = x[6];
-  output[3] = _mm_subs_epi16(__zero, x[2]);
-  output[4] = x[3];
-  output[5] = _mm_subs_epi16(__zero, x[7]);
-  output[6] = x[5];
-  output[7] = _mm_subs_epi16(__zero, x[1]);
+  iadst8_low1_ssse3_inline(input, output);
 }

 void av1_iadst8_sse2(const __m128i *input, __m128i *output) {
-  const int8_t cos_bit = INV_COS_BIT;
-  const int32_t *cospi = cospi_arr(INV_COS_BIT);
-  const __m128i __zero = _mm_setzero_si128();
-  const __m128i __rounding = _mm_set1_epi32(1 << (INV_COS_BIT - 1));
-
-  const __m128i cospi_p04_p60 = pair_set_epi16(cospi[4], cospi[60]);
-  const __m128i cospi_p60_m04 = pair_set_epi16(cospi[60], -cospi[4]);
-  const __m128i cospi_p20_p44 = pair_set_epi16(cospi[20], cospi[44]);
-  const __m128i cospi_p44_m20 = pair_set_epi16(cospi[44], -cospi[20]);
-  const __m128i cospi_p36_p28 = pair_set_epi16(cospi[36], cospi[28]);
-  const __m128i cospi_p28_m36 = pair_set_epi16(cospi[28], -cospi[36]);
-  const __m128i cospi_p52_p12 = pair_set_epi16(cospi[52], cospi[12]);
-  const __m128i cospi_p12_m52 = pair_set_epi16(cospi[12], -cospi[52]);
-  const __m128i cospi_p16_p48 = pair_set_epi16(cospi[16], cospi[48]);
-  const __m128i cospi_p48_m16 = pair_set_epi16(cospi[48], -cospi[16]);
-  const __m128i cospi_m48_p16 = pair_set_epi16(-cospi[48], cospi[16]);
-  const __m128i cospi_p32_p32 = pair_set_epi16(cospi[32], cospi[32]);
-  const __m128i cospi_p32_m32 = pair_set_epi16(cospi[32], -cospi[32]);
-
-  // stage 1
-  __m128i x[8];
-  x[0] = input[7];
-  x[1] = input[0];
-  x[2] = input[5];
-  x[3] = input[2];
-  x[4] = input[3];
-  x[5] = input[4];
-  x[6] = input[1];
-  x[7] = input[6];
-
-  // stage 2
-  btf_16_sse2(cospi_p04_p60, cospi_p60_m04, x[0], x[1], x[0], x[1]);
-  btf_16_sse2(cospi_p20_p44, cospi_p44_m20, x[2], x[3], x[2], x[3]);
-  btf_16_sse2(cospi_p36_p28, cospi_p28_m36, x[4], x[5], x[4], x[5]);
-  btf_16_sse2(cospi_p52_p12, cospi_p12_m52, x[6], x[7], x[6], x[7]);
-
-  // stage 3
-  btf_16_adds_subs_sse2(x[0], x[4]);
-  btf_16_adds_subs_sse2(x[1], x[5]);
-  btf_16_adds_subs_sse2(x[2], x[6]);
-  btf_16_adds_subs_sse2(x[3], x[7]);
-
-  // stage 4
-  btf_16_sse2(cospi_p16_p48, cospi_p48_m16, x[4], x[5], x[4], x[5]);
-  btf_16_sse2(cospi_m48_p16, cospi_p16_p48, x[6], x[7], x[6], x[7]);
-
-  // stage 5
-  btf_16_adds_subs_sse2(x[0], x[2]);
-  btf_16_adds_subs_sse2(x[1], x[3]);
-  btf_16_adds_subs_sse2(x[4], x[6]);
-  btf_16_adds_subs_sse2(x[5], x[7]);
-
-  // stage 6
-  btf_16_sse2(cospi_p32_p32, cospi_p32_m32, x[2], x[3], x[2], x[3]);
-  btf_16_sse2(cospi_p32_p32, cospi_p32_m32, x[6], x[7], x[6], x[7]);
-
-  // stage 7
-  output[0] = x[0];
-  output[1] = _mm_subs_epi16(__zero, x[4]);
-  output[2] = x[6];
-  output[3] = _mm_subs_epi16(__zero, x[2]);
-  output[4] = x[3];
-  output[5] = _mm_subs_epi16(__zero, x[7]);
-  output[6] = x[5];
-  output[7] = _mm_subs_epi16(__zero, x[1]);
+  iadst8_sse2_inline(input, output);
 }

 static void iadst8_w4_sse2(const __m128i *input, __m128i *output) {
@@ -2422,6 +2253,16 @@ static void lowbd_inv_txfm2d_add_4x4_ssse3(const int32_t *input,
   const int txfm_size_col = tx_size_wide[tx_size];
   const int txfm_size_row = tx_size_high[tx_size];

+  if (tx_type == DCT_DCT) {
+    load_buffer_32bit_to_16bit_w4(input, 4, buf, 4);
+    idct4_w4_sse2(buf, buf);
+    transpose_16bit_4x4(buf, buf);
+    idct4_w4_sse2(buf, buf);
+    round_shift_16bit_ssse3(buf, 4, -4);
+    lowbd_write_buffer_4xn_sse2(buf, output, stride, 0, 4);
+    return;
+  }
+
   const transform_1d_ssse3 row_txfm =
       lowbd_txfm_all_1d_w4_arr[txw_idx][hitx_1d_tab[tx_type]];
   const transform_1d_ssse3 col_txfm =
@@ -2476,19 +2317,57 @@ static inline void round_shift_ssse3(const __m128i *input, __m128i *output,
 static inline void lowbd_inv_txfm2d_add_no_identity_ssse3(
     const int32_t *input, uint8_t *output, int stride, TX_TYPE tx_type,
     TX_SIZE tx_size, int eob) {
+  const int8_t *shift = av1_inv_txfm_shift_ls[tx_size];
+  const int txfm_size_col = tx_size_wide[tx_size];
+  const int txfm_size_row = tx_size_high[tx_size];
+  const int rect_type = get_rect_tx_log_ratio(txfm_size_col, txfm_size_row);
+
+  // DC-only (eob == 1) fast path for DCT_DCT.
+  if (eob == 1 && tx_type == DCT_DCT) {
+    const int32_t *cospi = cospi_arr(INV_COS_BIT);
+    const __m128i w = _mm_set1_epi16(cospi[32] * 8);
+    const __m128i s0 = _mm_set1_epi16(1 << (15 + shift[0]));
+    const __m128i s1 = _mm_set1_epi16(1 << (15 - 4));
+    __m128i dc = _mm_cvtsi32_si128(input[0]);
+    dc = _mm_packs_epi32(dc, dc);
+    if (rect_type == 1 || rect_type == -1) {
+      dc = _mm_mulhrs_epi16(dc, _mm_set1_epi16(NewInvSqrt2 * 8));
+    }
+    dc = _mm_mulhrs_epi16(dc, w);
+    dc = _mm_mulhrs_epi16(dc, s0);
+    dc = _mm_mulhrs_epi16(dc, w);
+    dc = _mm_mulhrs_epi16(dc, s1);
+    dc = _mm_shuffle_epi32(_mm_unpacklo_epi16(dc, dc), 0);
+
+    if (txfm_size_col >= 16) {
+      for (int i = 0; i < (txfm_size_col >> 4); i++) {
+        uint8_t *out_col = output + 16 * i;
+        for (int r = 0; r < txfm_size_row; ++r) {
+          __m128i v = _mm_loadu_si128((__m128i const *)(out_col + r * stride));
+          __m128i u = lowbd_get_recon_16x16_sse2(v, dc, dc);
+          _mm_storeu_si128((__m128i *)(out_col + r * stride), u);
+        }
+      }
+    } else if (txfm_size_col == 8) {
+      for (int r = 0; r < txfm_size_row; ++r) {
+        const __m128i v =
+            _mm_loadl_epi64((__m128i const *)(output + r * stride));
+        const __m128i u = lowbd_get_recon_8x8_sse2(v, dc);
+        _mm_storel_epi64((__m128i *)(output + r * stride), u);
+      }
+    }
+    return;
+  }
+
   __m128i buf1[64 * 8];
   int eobx, eoby;
   get_eobx_eoby_scan_default(&eobx, &eoby, tx_size, eob);
-  const int8_t *shift = av1_inv_txfm_shift_ls[tx_size];
   const int txw_idx = get_txw_idx(tx_size);
   const int txh_idx = get_txh_idx(tx_size);
-  const int txfm_size_col = tx_size_wide[tx_size];
-  const int txfm_size_row = tx_size_high[tx_size];
   const int buf_size_w_div8 = txfm_size_col >> 3;
   const int buf_size_nonzero_w = ((eobx + 8) >> 3) << 3;
   const int buf_size_nonzero_h_div8 = (eoby + 8) >> 3;
   const int input_stride = AOMMIN(32, txfm_size_row);
-  const int rect_type = get_rect_tx_log_ratio(txfm_size_col, txfm_size_row);

   const int fun_idx_x = lowbd_txfm_all_1d_zeros_idx[eobx];
   const int fun_idx_y = lowbd_txfm_all_1d_zeros_idx[eoby];
@@ -2526,7 +2405,7 @@ static inline void lowbd_inv_txfm2d_add_no_identity_ssse3(
   }
   for (int i = 0; i < buf_size_w_div8; i++) {
     col_txfm(buf1 + i * txfm_size_row, buf1 + i * txfm_size_row);
-    round_shift_16bit_ssse3(buf1 + i * txfm_size_row, txfm_size_row, shift[1]);
+    round_shift_16bit_ssse3(buf1 + i * txfm_size_row, txfm_size_row, -4);
   }

   if (txfm_size_col >= 16) {
diff --git a/av1/common/x86/av1_inv_txfm_ssse3.h b/av1/common/x86/av1_inv_txfm_ssse3.h
index c06f7a12f4..b27554b10e 100644
--- a/av1/common/x86/av1_inv_txfm_ssse3.h
+++ b/av1/common/x86/av1_inv_txfm_ssse3.h
@@ -19,6 +19,8 @@

 #include "aom/aom_integer.h"
 #include "aom_dsp/x86/transpose_sse2.h"
+#include "av1/common/av1_inv_txfm1d_cfg.h"
+#include "av1/common/x86/av1_txfm_sse2.h"

 #ifdef __cplusplus
 extern "C" {
@@ -232,6 +234,181 @@ void av1_lowbd_inv_txfm2d_add_v_identity_ssse3(const int32_t *input,
                                                TX_TYPE tx_type, TX_SIZE tx_size,
                                                int eob);

+static inline void idct8_low1_ssse3_inline(const __m128i *input,
+                                           __m128i *output) {
+  const int32_t *cospi = cospi_arr(INV_COS_BIT);
+
+  __m128i x[2];
+  x[0] = input[0];
+
+  btf_16_ssse3(cospi[32], cospi[32], x[0], x[0], x[1]);
+
+  output[0] = x[0];
+  output[7] = x[0];
+  output[1] = x[1];
+  output[6] = x[1];
+  output[2] = x[1];
+  output[5] = x[1];
+  output[3] = x[0];
+  output[4] = x[0];
+}
+
+static inline void idct8_sse2_inline(const __m128i *input, __m128i *output) {
+  const int8_t cos_bit = INV_COS_BIT;
+  const int32_t *cospi = cospi_arr(INV_COS_BIT);
+  const __m128i __rounding = _mm_set1_epi32(1 << (INV_COS_BIT - 1));
+
+  const __m128i cospi_p56_m08 = pair_set_epi16(cospi[56], -cospi[8]);
+  const __m128i cospi_p08_p56 = pair_set_epi16(cospi[8], cospi[56]);
+  const __m128i cospi_p24_m40 = pair_set_epi16(cospi[24], -cospi[40]);
+  const __m128i cospi_p40_p24 = pair_set_epi16(cospi[40], cospi[24]);
+  const __m128i cospi_p32_p32 = pair_set_epi16(cospi[32], cospi[32]);
+  const __m128i cospi_p32_m32 = pair_set_epi16(cospi[32], -cospi[32]);
+  const __m128i cospi_p48_m16 = pair_set_epi16(cospi[48], -cospi[16]);
+  const __m128i cospi_p16_p48 = pair_set_epi16(cospi[16], cospi[48]);
+  const __m128i cospi_m32_p32 = pair_set_epi16(-cospi[32], cospi[32]);
+
+  // stage 1
+  __m128i x[8];
+  x[0] = input[0];
+  x[1] = input[4];
+  x[2] = input[2];
+  x[3] = input[6];
+  x[4] = input[1];
+  x[5] = input[5];
+  x[6] = input[3];
+  x[7] = input[7];
+
+  // stage 2
+  btf_16_sse2(cospi_p56_m08, cospi_p08_p56, x[4], x[7], x[4], x[7]);
+  btf_16_sse2(cospi_p24_m40, cospi_p40_p24, x[5], x[6], x[5], x[6]);
+
+  // stage 3
+  btf_16_sse2(cospi_p32_p32, cospi_p32_m32, x[0], x[1], x[0], x[1]);
+  btf_16_sse2(cospi_p48_m16, cospi_p16_p48, x[2], x[3], x[2], x[3]);
+  btf_16_adds_subs_sse2(x[4], x[5]);
+  btf_16_subs_adds_sse2(x[7], x[6]);
+
+  // stage 4
+  btf_16_adds_subs_sse2(x[0], x[3]);
+  btf_16_adds_subs_sse2(x[1], x[2]);
+  btf_16_sse2(cospi_m32_p32, cospi_p32_p32, x[5], x[6], x[5], x[6]);
+
+  // stage 5
+  btf_16_adds_subs_out_sse2(output[0], output[7], x[0], x[7]);
+  btf_16_adds_subs_out_sse2(output[1], output[6], x[1], x[6]);
+  btf_16_adds_subs_out_sse2(output[2], output[5], x[2], x[5]);
+  btf_16_adds_subs_out_sse2(output[3], output[4], x[3], x[4]);
+}
+
+static inline void iadst8_low1_ssse3_inline(const __m128i *input,
+                                            __m128i *output) {
+  const int8_t cos_bit = INV_COS_BIT;
+  const int32_t *cospi = cospi_arr(INV_COS_BIT);
+  const __m128i __zero = _mm_setzero_si128();
+  const __m128i __rounding = _mm_set1_epi32(1 << (INV_COS_BIT - 1));
+
+  const __m128i cospi_p16_p48 = pair_set_epi16(cospi[16], cospi[48]);
+  const __m128i cospi_p48_m16 = pair_set_epi16(cospi[48], -cospi[16]);
+  const __m128i cospi_p32_p32 = pair_set_epi16(cospi[32], cospi[32]);
+  const __m128i cospi_p32_m32 = pair_set_epi16(cospi[32], -cospi[32]);
+
+  __m128i x[8];
+  x[1] = input[0];
+
+  btf_16_ssse3(cospi[60], -cospi[4], x[1], x[0], x[1]);
+
+  x[4] = x[0];
+  x[5] = x[1];
+
+  btf_16_sse2(cospi_p16_p48, cospi_p48_m16, x[4], x[5], x[4], x[5]);
+
+  x[2] = x[0];
+  x[3] = x[1];
+  x[6] = x[4];
+  x[7] = x[5];
+
+  btf_16_sse2(cospi_p32_p32, cospi_p32_m32, x[2], x[3], x[2], x[3]);
+  btf_16_sse2(cospi_p32_p32, cospi_p32_m32, x[6], x[7], x[6], x[7]);
+
+  output[0] = x[0];
+  output[1] = _mm_subs_epi16(__zero, x[4]);
+  output[2] = x[6];
+  output[3] = _mm_subs_epi16(__zero, x[2]);
+  output[4] = x[3];
+  output[5] = _mm_subs_epi16(__zero, x[7]);
+  output[6] = x[5];
+  output[7] = _mm_subs_epi16(__zero, x[1]);
+}
+
+static inline void iadst8_sse2_inline(const __m128i *input, __m128i *output) {
+  const int8_t cos_bit = INV_COS_BIT;
+  const int32_t *cospi = cospi_arr(INV_COS_BIT);
+  const __m128i __zero = _mm_setzero_si128();
+  const __m128i __rounding = _mm_set1_epi32(1 << (INV_COS_BIT - 1));
+
+  const __m128i cospi_p04_p60 = pair_set_epi16(cospi[4], cospi[60]);
+  const __m128i cospi_p60_m04 = pair_set_epi16(cospi[60], -cospi[4]);
+  const __m128i cospi_p20_p44 = pair_set_epi16(cospi[20], cospi[44]);
+  const __m128i cospi_p44_m20 = pair_set_epi16(cospi[44], -cospi[20]);
+  const __m128i cospi_p36_p28 = pair_set_epi16(cospi[36], cospi[28]);
+  const __m128i cospi_p28_m36 = pair_set_epi16(cospi[28], -cospi[36]);
+  const __m128i cospi_p52_p12 = pair_set_epi16(cospi[52], cospi[12]);
+  const __m128i cospi_p12_m52 = pair_set_epi16(cospi[12], -cospi[52]);
+  const __m128i cospi_p16_p48 = pair_set_epi16(cospi[16], cospi[48]);
+  const __m128i cospi_p48_m16 = pair_set_epi16(cospi[48], -cospi[16]);
+  const __m128i cospi_m48_p16 = pair_set_epi16(-cospi[48], cospi[16]);
+  const __m128i cospi_p32_p32 = pair_set_epi16(cospi[32], cospi[32]);
+  const __m128i cospi_p32_m32 = pair_set_epi16(cospi[32], -cospi[32]);
+
+  // stage 1
+  __m128i x[8];
+  x[0] = input[7];
+  x[1] = input[0];
+  x[2] = input[5];
+  x[3] = input[2];
+  x[4] = input[3];
+  x[5] = input[4];
+  x[6] = input[1];
+  x[7] = input[6];
+
+  // stage 2
+  btf_16_sse2(cospi_p04_p60, cospi_p60_m04, x[0], x[1], x[0], x[1]);
+  btf_16_sse2(cospi_p20_p44, cospi_p44_m20, x[2], x[3], x[2], x[3]);
+  btf_16_sse2(cospi_p36_p28, cospi_p28_m36, x[4], x[5], x[4], x[5]);
+  btf_16_sse2(cospi_p52_p12, cospi_p12_m52, x[6], x[7], x[6], x[7]);
+
+  // stage 3
+  btf_16_adds_subs_sse2(x[0], x[4]);
+  btf_16_adds_subs_sse2(x[1], x[5]);
+  btf_16_adds_subs_sse2(x[2], x[6]);
+  btf_16_adds_subs_sse2(x[3], x[7]);
+
+  // stage 4
+  btf_16_sse2(cospi_p16_p48, cospi_p48_m16, x[4], x[5], x[4], x[5]);
+  btf_16_sse2(cospi_m48_p16, cospi_p16_p48, x[6], x[7], x[6], x[7]);
+
+  // stage 5
+  btf_16_adds_subs_sse2(x[0], x[2]);
+  btf_16_adds_subs_sse2(x[1], x[3]);
+  btf_16_adds_subs_sse2(x[4], x[6]);
+  btf_16_adds_subs_sse2(x[5], x[7]);
+
+  // stage 6
+  btf_16_sse2(cospi_p32_p32, cospi_p32_m32, x[2], x[3], x[2], x[3]);
+  btf_16_sse2(cospi_p32_p32, cospi_p32_m32, x[6], x[7], x[6], x[7]);
+
+  // stage 7
+  output[0] = x[0];
+  output[1] = _mm_subs_epi16(__zero, x[4]);
+  output[2] = x[6];
+  output[3] = _mm_subs_epi16(__zero, x[2]);
+  output[4] = x[3];
+  output[5] = _mm_subs_epi16(__zero, x[7]);
+  output[6] = x[5];
+  output[7] = _mm_subs_epi16(__zero, x[1]);
+}
+
 void av1_iadst8_low1_ssse3(const __m128i *input, __m128i *output);

 void av1_idct8_low1_ssse3(const __m128i *input, __m128i *output);
diff --git a/av1/encoder/x86/av1_fwd_txfm2d_avx2.c b/av1/encoder/x86/av1_fwd_txfm2d_avx2.c
index cf3c1166b7..081f22058e 100644
--- a/av1/encoder/x86/av1_fwd_txfm2d_avx2.c
+++ b/av1/encoder/x86/av1_fwd_txfm2d_avx2.c
@@ -1633,44 +1633,6 @@ static const transform_1d_avx2 row_txfm16x16_cb13_arr[TX_TYPES] = {
   fadst16x16_cb13_avx2      // H_FLIPADST
 };

-static const transform_1d_sse2 col_txfm8x8_arr[TX_TYPES] = {
-  fdct8x8_cb13_sse2,      // DCT_DCT
-  fadst8x8_cb13_sse2,     // ADST_DCT
-  fdct8x8_cb13_sse2,      // DCT_ADST
-  fadst8x8_cb13_sse2,     // ADST_ADST
-  fadst8x8_cb13_sse2,     // FLIPADST_DCT
-  fdct8x8_cb13_sse2,      // DCT_FLIPADST
-  fadst8x8_cb13_sse2,     // FLIPADST_FLIPADST
-  fadst8x8_cb13_sse2,     // ADST_FLIPADST
-  fadst8x8_cb13_sse2,     // FLIPADST_ADST
-  fidentity8x8_new_sse2,  // IDTX
-  fdct8x8_cb13_sse2,      // V_DCT
-  fidentity8x8_new_sse2,  // H_DCT
-  fadst8x8_cb13_sse2,     // V_ADST
-  fidentity8x8_new_sse2,  // H_ADST
-  fadst8x8_cb13_sse2,     // V_FLIPADST
-  fidentity8x8_new_sse2,  // H_FLIPADST
-};
-
-static const transform_1d_sse2 row_txfm8x8_arr[TX_TYPES] = {
-  fdct8x8_cb13_sse2,      // DCT_DCT
-  fdct8x8_cb13_sse2,      // ADST_DCT
-  fadst8x8_cb13_sse2,     // DCT_ADST
-  fadst8x8_cb13_sse2,     // ADST_ADST
-  fdct8x8_cb13_sse2,      // FLIPADST_DCT
-  fadst8x8_cb13_sse2,     // DCT_FLIPADST
-  fadst8x8_cb13_sse2,     // FLIPADST_FLIPADST
-  fadst8x8_cb13_sse2,     // ADST_FLIPADST
-  fadst8x8_cb13_sse2,     // FLIPADST_ADST
-  fidentity8x8_new_sse2,  // IDTX
-  fidentity8x8_new_sse2,  // V_DCT
-  fdct8x8_cb13_sse2,      // H_DCT
-  fidentity8x8_new_sse2,  // V_ADST
-  fadst8x8_cb13_sse2,     // H_ADST
-  fidentity8x8_new_sse2,  // V_FLIPADST
-  fadst8x8_cb13_sse2      // H_FLIPADST
-};
-
 static inline void load_buffer_and_round_shift(const int16_t *in, int stride,
                                                __m128i *out, int bit) {
   out[0] = _mm_load_si128((const __m128i *)(in + 0 * stride));
@@ -1851,7 +1813,7 @@ static inline void store_buffer_16bit_to_32bit_w8_avx2(const __m128i *const in,
 static void av1_lowbd_fwd_txfm2d_8x8_avx2(const int16_t *input, int32_t *output,
                                           int stride, TX_TYPE tx_type, int bd) {
   (void)bd;
-  __m128i buf0[8], buf1[8], *buf;
+  __m128i buf0[8], buf1[8];
   const int8_t *shift = av1_fwd_txfm_shift_ls[TX_8X8];

   // Fast path for DCT_DCT: bypass function pointer table and flip checks.
@@ -1864,26 +1826,20 @@ static void av1_lowbd_fwd_txfm2d_8x8_avx2(const int16_t *input, int32_t *output,
     return;
   }

-  const int txw_idx = get_txw_idx(TX_8X8);
-  const int txh_idx = get_txh_idx(TX_8X8);
-  const int cos_bit_col = av1_fwd_cos_bit_col[txw_idx][txh_idx];
-  const int cos_bit_row = av1_fwd_cos_bit_row[txw_idx][txh_idx];
-  const transform_1d_sse2 col_txfm = col_txfm8x8_arr[tx_type];
-  const transform_1d_sse2 row_txfm = row_txfm8x8_arr[tx_type];
   int ud_flip, lr_flip;
-
   get_flip_cfg(tx_type, &ud_flip, &lr_flip);
-  // Condition to check shift bit is avoided while round shifting, by assuming
-  // that shift[0] will always be positive.
   assert(shift[0] > 0);
   if (ud_flip)
     load_buffer_and_flip_round_shift(input, stride, buf0, shift[0]);
   else
     load_buffer_and_round_shift(input, stride, buf0, shift[0]);

-  col_txfm(buf0, buf0, cos_bit_col);
-  // Condition to check shift bit is avoided while round shifting, by assuming
-  // that shift[1] will always be negative.
+  switch (vtx_tab[tx_type]) {
+    case DCT_1D: fdct8x8_new_sse2(buf0, buf0, 13); break;
+    case ADST_1D:
+    case FLIPADST_1D: fadst8x8_new_sse2(buf0, buf0, 13); break;
+    default: fidentity8x8_new_sse2(buf0, buf0, 13); break;
+  }
   assert(shift[1] < 0);

   if (lr_flip) {
@@ -1892,13 +1848,15 @@ static void av1_lowbd_fwd_txfm2d_8x8_avx2(const int16_t *input, int32_t *output,
     transpose_round_shift_8x8(buf0, buf1, shift[1]);
   }

-  buf = buf1;
-  row_txfm(buf, buf, cos_bit_row);
+  switch (htx_tab[tx_type]) {
+    case DCT_1D: fdct8x8_new_sse2(buf1, buf1, 13); break;
+    case ADST_1D:
+    case FLIPADST_1D: fadst8x8_new_sse2(buf1, buf1, 13); break;
+    default: fidentity8x8_new_sse2(buf1, buf1, 13); break;
+  }

-  // Round and shift operation is avoided here as the shift bit is assumed to be
-  // zero always.
   assert(shift[2] == 0);
-  store_buffer_16bit_to_32bit_w8_avx2(buf, output, 8, 8);
+  store_buffer_16bit_to_32bit_w8_avx2(buf1, output, 8, 8);
 }

 static void lowbd_fwd_txfm2d_16x16_avx2(const int16_t *input, int32_t *output,