When sorting two D arrays directly, swapping rows multiplies the swapping time by a factor of the column count.

One way around that is to create an array of rowNumbers and sort that based on the values in the unsorted array. Once that array is sorted, it is used to create the output array.

This example of that techniques uses a bubble sort, but it can be used with QuickSort.
It uses one time loops (creating rowArray and afterSort) to eliminated the repeated loop through columns that swapping rows entails.

Dim dataArray As Variant

Sub sort2D()
Dim lowRow As Long, highRow As Long
Dim lowCol As Long, highCol As Long
Dim i As Long, j As Long, temp As Variant
Dim rowArray() As Long
Dim afterSort As Variant

dataArray = Range("a1:g20")
lowRow = LBound(dataArray, 1): highRow = UBound(dataArray, 1)
lowCol = LBound(dataArray, 2): highCol = UBound(dataArray, 2)

Rem create rowArray = {1,2,3,...,20}

    ReDim rowArray(lowRow To highRow)
    For i = lowRow To highRow
        rowArray(i) = i
    Next i

Rem sort rowArray with rowLT comparison function

    For i = lowRow To highRow - 1
        For j = i + 1 To highRow
            If rowLT(rowArray(j), rowArray(i)) Then
                temp = rowArray(i)
                rowArray(i) = rowArray(j)
                rowArray(j) = temp
            End If
        Next j
    Next i

Rem use rowArray to make afterSort array

    ReDim afterSort(lowRow To highRow, lowCol To highCol)
    For i = lowRow To highRow
        For j = lowCol To highCol
            afterSort(i, j) = dataArray(rowArray(i), j)
        Next j
    Next i

Range("i1:o20").Value = afterSort
End Sub

Function rowLT(aRow, bRow) As Boolean
    rowLT = (dataArray(aRow, 1) < dataArray(bRow, 1))
End Function