Add AVX support for the painting and image code.

There are no new routines, this is just the old SSE2 and SSSE3 code
compiled in AVX mode, meaning the instructions use the VEX prefix.

Change-Id: I79a8bfaf6b30a050618db899f5a3bbc220449f0b
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
This commit is contained in:
Thiago Macieira 2011-12-28 17:22:34 -02:00 committed by Qt by Nokia
parent 018cb899d4
commit 9b94570fdf
9 changed files with 246 additions and 11 deletions

View File

@ -84,6 +84,18 @@ win32:!contains(QT_CONFIG, directwrite) {
silent:ssse3_compiler.commands = @echo compiling[ssse3] ${QMAKE_FILE_IN} && $$ssse3_compiler.commands
QMAKE_EXTRA_COMPILERS += ssse3_compiler
}
avx {
avx_compiler.commands = $$QMAKE_CXX -c -Winline
avx_compiler.commands += -mavx
avx_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
avx_compiler.dependency_type = TYPE_C
avx_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
avx_compiler.input = AVX_SOURCES
avx_compiler.variable_out = OBJECTS
avx_compiler.name = compiling[avx] ${QMAKE_FILE_IN}
silent:avx_compiler.commands = @echo compiling[avx] ${QMAKE_FILE_IN} && $$avx_compiler.commands
QMAKE_EXTRA_COMPILERS += avx_compiler
}
iwmmxt {
iwmmxt_compiler.commands = $$QMAKE_CXX -c -Winline
iwmmxt_compiler.commands += -mcpu=iwmmxt

View File

@ -77,3 +77,4 @@ contains(QT_CONFIG, gif):include($$PWD/qgifhandler.pri)
NEON_SOURCES += image/qimage_neon.cpp
SSE2_SOURCES += image/qimage_sse2.cpp
SSSE3_SOURCES += image/qimage_ssse3.cpp
AVX_SOURCES += image/qimage_avx.cpp

View File

@ -3273,19 +3273,32 @@ void qInitImageConversions()
Q_UNUSED(features);
#ifdef QT_HAVE_SSE2
if (features & SSE2) {
extern bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags);
inplace_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_inplace_sse2;
}
#ifdef QT_HAVE_AVX
if (features & AVX) {
extern bool convert_ARGB_to_ARGB_PM_inplace_avx(QImageData *data, Qt::ImageConversionFlags);
inplace_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_inplace_avx;
extern void convert_RGB888_to_RGB32_avx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_avx;
converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_avx;
converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_avx;
} else
#endif
if (features & SSE2) {
extern bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags);
inplace_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_inplace_sse2;
#ifdef QT_HAVE_SSSE3
if (features & SSSE3) {
extern void convert_RGB888_to_RGB32_ssse3(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_ssse3;
converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_ssse3;
converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_ssse3;
}
if (features & SSSE3) {
extern void convert_RGB888_to_RGB32_ssse3(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_ssse3;
converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_ssse3;
converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_ssse3;
}
#endif
}
#endif // SSE2
#ifdef QT_HAVE_NEON
if (features & NEON) {
extern void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);

View File

@ -0,0 +1,57 @@
/****************************************************************************
**
** Copyright (C) 2012 Intel Corporation
** Contact: http://www.qt-project.org/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <private/qsimd_p.h>
#ifdef QT_HAVE_AVX
#ifndef __AVX__
#error "AVX not enabled in this file, cannot proceed"
#endif
#define convert_ARGB_to_ARGB_PM_inplace_sse2 convert_ARGB_to_ARGB_PM_inplace_avx
#include "qimage_sse2.cpp"
#define qt_convert_rgb888_to_rgb32_ssse3 qt_convert_rgb888_to_rgb32_avx
#define convert_RGB888_to_RGB32_ssse3 convert_RGB888_to_RGB32_avx
#include "qimage_ssse3.cpp"
#endif

View File

@ -91,12 +91,13 @@ SOURCES += \
if(mmx|3dnow|sse|sse2|iwmmxt) {
if(mmx|3dnow|sse|sse2|iwmmxt|avx) {
HEADERS += painting/qdrawhelper_x86_p.h \
painting/qdrawingprimitive_sse2_p.h
SSE2_SOURCES += painting/qdrawhelper_sse2.cpp
SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp
IWMMXT_SOURCES += painting/qdrawhelper_iwmmxt.cpp
AVX_SOURCES += painting/qdrawhelper_avx.cpp
}
NEON_SOURCES += painting/qdrawhelper_neon.cpp

View File

@ -5805,6 +5805,24 @@ void qInitDrawhelperAsm()
const uint features = qDetectCPUFeatures();
if (false) {
#ifdef QT_HAVE_AVX
} else if (features & AVX) {
qt_memfill32 = qt_memfill32_avx;
qt_memfill16 = qt_memfill16_avx;
qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_avx;
qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_avx;
qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_avx;
qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_avx;
extern void qt_scale_image_argb32_on_argb32_avx(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
const QRectF &targetRect,
const QRectF &sourceRect,
const QRect &clip,
int const_alpha);
qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_avx;
qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_avx;
#endif
#ifdef QT_HAVE_SSE2
} else if (features & SSE2) {
qt_memfill32 = qt_memfill32_sse2;
@ -5859,12 +5877,51 @@ void qInitDrawhelperAsm()
}
#endif // SSSE3
#ifdef QT_HAVE_AVX
if (features & AVX) {
extern void qt_blend_rgb32_on_rgb32_avx(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
int w, int h,
int const_alpha);
extern void qt_blend_argb32_on_argb32_avx(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
int w, int h,
int const_alpha);
qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx;
qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx;
extern const uint * QT_FASTCALL qt_fetch_radial_gradient_avx(uint *buffer, const Operator *op, const QSpanData *data,
int y, int x, int length);
qt_fetch_radial_gradient = qt_fetch_radial_gradient_avx;
}
#endif // AVX
#endif // SSE2
#ifdef QT_HAVE_SSE2
if (features & SSE2) {
functionForModeAsm = qt_functionForMode_SSE2;
functionForModeSolidAsm = qt_functionForModeSolid_SSE2;
}
#endif
#ifdef QT_HAVE_AVX
if (features & AVX) {
extern void QT_FASTCALL comp_func_SourceOver_avx(uint *destPixels,
const uint *srcPixels,
int length,
uint const_alpha);
extern void QT_FASTCALL comp_func_solid_SourceOver_avx(uint *destPixels, int length, uint color, uint const_alpha);
extern void QT_FASTCALL comp_func_Plus_avx(uint *dst, const uint *src, int length, uint const_alpha);
extern void QT_FASTCALL comp_func_Source_avx(uint *dst, const uint *src, int length, uint const_alpha);
functionForModeAsm[0] = comp_func_SourceOver_avx;
functionForModeAsm[QPainter::CompositionMode_Source] = comp_func_Source_avx;
functionForModeAsm[QPainter::CompositionMode_Plus] = comp_func_Plus_avx;
functionForModeSolidAsm[0] = comp_func_solid_SourceOver_avx;
}
#endif // SSE2

View File

@ -0,0 +1,70 @@
/****************************************************************************
**
** Copyright (C) 2012 Intel Corporation
** Contact: http://www.qt-project.org/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <private/qsimd_p.h>
#ifdef QT_HAVE_AVX
#define QDRAWHELPER_AVX
#ifndef __AVX__
#error "AVX not enabled in this file, cannot proceed"
#endif
#define qt_blend_argb32_on_argb32_ssse3 qt_blend_argb32_on_argb32_avx
#include "qdrawhelper_ssse3.cpp"
//#define qt_blend_argb32_on_argb32_sse2 qt_blend_argb32_on_argb32_avx
#define qt_blend_rgb32_on_rgb32_sse2 qt_blend_rgb32_on_rgb32_avx
#define comp_func_SourceOver_sse2 comp_func_SourceOver_avx
#define comp_func_Plus_sse2 comp_func_Plus_avx
#define comp_func_Source_sse2 comp_func_Source_avx
#define comp_func_solid_SourceOver_sse2 comp_func_solid_SourceOver_avx
#define qt_memfill32_sse2 qt_memfill32_avx
#define qt_memfill16_sse2 qt_memfill16_avx
#define qt_bitmapblit32_sse2 qt_bitmapblit32_avx
#define qt_bitmapblit16_sse2 qt_bitmapblit16_avx
#define QSimdSse2 QSimdAvx
#define qt_fetch_radial_gradient_sse2 qt_fetch_radial_gradient_avx
#define qt_scale_image_argb32_on_argb32_sse2 qt_scale_image_argb32_on_argb32_avx
#include "qdrawhelper_sse2.cpp"
#endif

View File

@ -48,6 +48,8 @@
QT_BEGIN_NAMESPACE
#ifndef QDRAWHELPER_AVX
// in AVX mode, we'll use the SSSE3 code
void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
int w, int h,
@ -83,6 +85,7 @@ void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
}
}
}
#endif
// qblendfunctions.cpp
void qt_blend_rgb32_on_rgb32(uchar *destPixels, int dbpl,
@ -310,6 +313,7 @@ void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, u
}
}
#ifndef QDRAWHELPER_AVX
CompositionFunctionSolid qt_functionForModeSolid_SSE2[numCompositionFunctions] = {
comp_func_solid_SourceOver_sse2,
comp_func_solid_DestinationOver,
@ -381,6 +385,7 @@ CompositionFunction qt_functionForMode_SSE2[numCompositionFunctions] = {
rasterop_NotSourceAndDestination,
rasterop_SourceAndNotDestination
};
#endif
void qt_memfill16_sse2(quint16 *dest, quint16 value, int count)
{

View File

@ -79,6 +79,25 @@ extern CompositionFunction qt_functionForMode_SSE2[];
extern CompositionFunctionSolid qt_functionForModeSolid_SSE2[];
#endif // QT_HAVE_SSE2
#ifdef QT_HAVE_AVX
void qt_memfill32_avx(quint32 *dest, quint32 value, int count);
void qt_memfill16_avx(quint16 *dest, quint16 value, int count);
void qt_bitmapblit32_avx(QRasterBuffer *rasterBuffer, int x, int y,
quint32 color,
const uchar *src, int width, int height, int stride);
void qt_bitmapblit16_avx(QRasterBuffer *rasterBuffer, int x, int y,
quint32 color,
const uchar *src, int width, int height, int stride);
void qt_blend_argb32_on_argb32_avx(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
int w, int h,
int const_alpha);
void qt_blend_rgb32_on_rgb32_avx(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
int w, int h,
int const_alpha);
#endif // QT_HAVE_AVX
#ifdef QT_HAVE_IWMMXT
void qt_blend_color_argb_iwmmxt(int count, const QSpan *spans, void *userData);