mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-07-09 02:39:42 +00:00
Add sve2 acceleration for blit2to2 key (#15953)
This commit is contained in:
@@ -3205,6 +3205,11 @@ SDL_BlitFunc SDL_CalculateBlitN(SDL_Surface *surface)
|
||||
If a particular case turns out to be useful we'll add it. */
|
||||
|
||||
if (srcfmt->bytes_per_pixel == 2 && surface->map.identity != 0) {
|
||||
#ifdef SDL_SVE2_INTRINSICS
|
||||
if (SDL_HasSVE2()) {
|
||||
return Blit2to2KeySVE2;
|
||||
}
|
||||
#endif
|
||||
return Blit2to2Key;
|
||||
} else {
|
||||
#ifdef SDL_ALTIVEC_BLITTERS
|
||||
|
||||
@@ -96,7 +96,7 @@ static inline void sdl_sve_rgb565_stride_blend_with_opacity(uint16_t *SDL_RESTRI
|
||||
size_t uStride,
|
||||
uint16_t hwOpacity)
|
||||
{
|
||||
sdl_sve_stride_loop_rgb16(uStride, vTailPred)
|
||||
sdl_sve_stride_loop_u16(uStride, vTailPred)
|
||||
{
|
||||
|
||||
svuint16x3_t vSource16x3 =
|
||||
|
||||
@@ -61,4 +61,276 @@ void Blit8888to565PixelSwizzleSVE2(SDL_BlitInfo *info)
|
||||
sdl_sve_rgb32_to_rgb565_swizzle_dispatcher(info);
|
||||
}
|
||||
|
||||
SDL_TARGETING("arch=armv8-a+sve2")
|
||||
ARM_NONNULL(1, 2)
|
||||
static inline void sdl_sve_rgb16_stride_key(uint16_t *SDL_RESTRICT phwSource,
|
||||
uint16_t *SDL_RESTRICT phwTarget,
|
||||
size_t uStride,
|
||||
uint16_t hwKey,
|
||||
uint16_t hwKeyMask)
|
||||
{
|
||||
sdl_sve_stride_loop_u16(uStride, vTailPred)
|
||||
{
|
||||
svuint16_t vSource = svld1_u16(vTailPred, phwSource);
|
||||
svuint16_t vTarget = svld1_u16(vTailPred, phwTarget);
|
||||
|
||||
svuint16_t vSourceMasked = svand_n_u16_m(vTailPred,
|
||||
vSource,
|
||||
hwKeyMask);
|
||||
vTarget = svsel_u16(svcmpeq_n_u16(vTailPred, vSourceMasked, hwKey),
|
||||
vTarget,
|
||||
vSource);
|
||||
|
||||
svst1_u16(vTailPred, phwTarget, vTarget);
|
||||
|
||||
phwSource += sve_iteration_advance;
|
||||
phwTarget += sve_iteration_advance;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_TARGETING("arch=armv8-a+sve2")
|
||||
ARM_NONNULL(1, 3)
|
||||
static inline void sdl_sve_rgb16_key(uint8_t *SDL_RESTRICT pchSource,
|
||||
size_t uSourceStride,
|
||||
uint8_t *SDL_RESTRICT pchTarget,
|
||||
size_t uTargetStride,
|
||||
int nWidth,
|
||||
int nHeight,
|
||||
uint16_t hwKey,
|
||||
uint16_t hwKeyMask)
|
||||
{
|
||||
assert(0 == ((uintptr_t)pchSource & 0x01));
|
||||
assert(0 == ((uintptr_t)pchTarget & 0x01));
|
||||
|
||||
while (nHeight--) {
|
||||
sdl_sve_rgb16_stride_key((uint16_t *)pchSource,
|
||||
(uint16_t *)pchTarget,
|
||||
nWidth,
|
||||
hwKey,
|
||||
hwKeyMask);
|
||||
|
||||
pchSource += uSourceStride;
|
||||
pchTarget += uTargetStride;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_TARGETING("arch=armv8-a+sve2")
|
||||
void Blit2to2KeySVE2(SDL_BlitInfo *info)
|
||||
{
|
||||
int width = info->dst_w;
|
||||
int height = info->dst_h;
|
||||
uint8_t *src = info->src;
|
||||
int srcskip = info->src_skip;
|
||||
uint8_t *dst = info->dst;
|
||||
int dstskip = info->dst_skip;
|
||||
|
||||
const SDL_PixelFormatDetails *srcfmt = info->src_fmt;
|
||||
const SDL_PixelFormatDetails *dstfmt = info->dst_fmt;
|
||||
|
||||
// Set up some basic variables
|
||||
int srcbpp = srcfmt->bytes_per_pixel;
|
||||
int dstbpp = dstfmt->bytes_per_pixel;
|
||||
|
||||
assert(srcbpp == 2);
|
||||
assert(dstbpp == 2);
|
||||
|
||||
int srcstride = srcskip + srcbpp * width;
|
||||
int dststride = dstskip + dstbpp * width;
|
||||
|
||||
uint32_t ckey = info->colorkey;
|
||||
uint32_t rgbmask = ~srcfmt->Amask;
|
||||
ckey &= rgbmask;
|
||||
|
||||
sdl_sve_rgb16_key(src,
|
||||
srcstride,
|
||||
dst,
|
||||
dststride,
|
||||
width,
|
||||
height,
|
||||
ckey,
|
||||
rgbmask);
|
||||
}
|
||||
|
||||
SDL_TARGETING("arch=armv8-a+sve2")
|
||||
ARM_NONNULL(1, 2)
|
||||
static inline void sdl_sve_rgb32_stride_key_copy_alpha(
|
||||
uint32_t *SDL_RESTRICT pwSource,
|
||||
uint32_t *SDL_RESTRICT pwTarget,
|
||||
size_t uStride,
|
||||
uint32_t wKey,
|
||||
uint32_t wKeyMask,
|
||||
uint32_t wOpacifyMask)
|
||||
{
|
||||
sdl_sve_stride_loop_u32(uStride, vTailPred)
|
||||
{
|
||||
svuint32_t vSource = svld1_u32(vTailPred, pwSource);
|
||||
svuint32_t vTarget = svld1_u32(vTailPred, pwTarget);
|
||||
|
||||
/*
|
||||
uint32_t opamask = ((uint32_t)info->a) << dstfmt->Ashift;
|
||||
...
|
||||
if ((*src32 & rgbmask) != ckey) {
|
||||
*dst32 = *src32 | opamask;
|
||||
}
|
||||
*/
|
||||
svuint32_t vSourceMasked = svand_n_u32_m(vTailPred,
|
||||
vSource,
|
||||
wKeyMask);
|
||||
vTarget = svsel_u32(svcmpeq_n_u32(vTailPred, vSourceMasked, wKey),
|
||||
vTarget,
|
||||
svorr_n_u32_m(vTailPred, vSource, wOpacifyMask));
|
||||
|
||||
svst1_u32(vTailPred, pwTarget, vTarget);
|
||||
|
||||
pwSource += sve_iteration_advance;
|
||||
pwTarget += sve_iteration_advance;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_TARGETING("arch=armv8-a+sve2")
|
||||
ARM_NONNULL(1, 2)
|
||||
static inline void sdl_sve_rgb32_stride_key_no_alpha(
|
||||
uint32_t *SDL_RESTRICT pwSource,
|
||||
uint32_t *SDL_RESTRICT pwTarget,
|
||||
size_t uStride,
|
||||
uint32_t wKey,
|
||||
uint32_t wKeyMask,
|
||||
uint32_t wActualRGBMask)
|
||||
{
|
||||
sdl_sve_stride_loop_u32(uStride, vTailPred)
|
||||
{
|
||||
svuint32_t vSource = svld1_u32(vTailPred, pwSource);
|
||||
svuint32_t vTarget = svld1_u32(vTailPred, pwTarget);
|
||||
|
||||
/*
|
||||
uint32_t rgbmaskactual = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask;
|
||||
...
|
||||
if ((*src32 & rgbmask) != ckey) {
|
||||
*dst32 = *src32 & rgbmaskactual;
|
||||
}
|
||||
*/
|
||||
svuint32_t vSourceMasked = svand_n_u32_m(vTailPred,
|
||||
vSource,
|
||||
wKeyMask);
|
||||
vTarget = svsel_u32(svcmpeq_n_u32(vTailPred, vSourceMasked, wKey),
|
||||
vTarget,
|
||||
svand_n_u32_m(vTailPred, vSource, wActualRGBMask));
|
||||
|
||||
svst1_u32(vTailPred, pwTarget, vTarget);
|
||||
|
||||
pwSource += sve_iteration_advance;
|
||||
pwTarget += sve_iteration_advance;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_TARGETING("arch=armv8-a+sve2")
|
||||
ARM_NONNULL(1, 3)
|
||||
static inline void sdl_sve_rgb32_key_copy_alpha(uint8_t *SDL_RESTRICT pchSource,
|
||||
size_t uSourceStride,
|
||||
uint8_t *SDL_RESTRICT pchTarget,
|
||||
size_t uTargetStride,
|
||||
int nWidth,
|
||||
int nHeight,
|
||||
uint32_t wKey,
|
||||
uint32_t wKeyMask,
|
||||
uint32_t wOpacifyMask)
|
||||
{
|
||||
assert(0 == ((uintptr_t)pchSource & 0x03));
|
||||
assert(0 == ((uintptr_t)pchTarget & 0x03));
|
||||
|
||||
while (nHeight--) {
|
||||
sdl_sve_rgb32_stride_key_copy_alpha((uint32_t *)pchSource,
|
||||
(uint32_t *)pchTarget,
|
||||
nWidth,
|
||||
wKey,
|
||||
wKeyMask,
|
||||
wOpacifyMask);
|
||||
|
||||
pchSource += uSourceStride;
|
||||
pchTarget += uTargetStride;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_TARGETING("arch=armv8-a+sve2")
|
||||
ARM_NONNULL(1, 3)
|
||||
static inline void sdl_sve_rgb32_key_no_alpha(uint8_t *SDL_RESTRICT pchSource,
|
||||
size_t uSourceStride,
|
||||
uint8_t *SDL_RESTRICT pchTarget,
|
||||
size_t uTargetStride,
|
||||
int nWidth,
|
||||
int nHeight,
|
||||
uint32_t wKey,
|
||||
uint32_t wKeyMask,
|
||||
uint32_t wActualRGBMask)
|
||||
{
|
||||
assert(0 == ((uintptr_t)pchSource & 0x03));
|
||||
assert(0 == ((uintptr_t)pchTarget & 0x03));
|
||||
|
||||
while (nHeight--) {
|
||||
sdl_sve_rgb32_stride_key_no_alpha((uint32_t *)pchSource,
|
||||
(uint32_t *)pchTarget,
|
||||
nWidth,
|
||||
wKey,
|
||||
wKeyMask,
|
||||
wActualRGBMask);
|
||||
|
||||
pchSource += uSourceStride;
|
||||
pchTarget += uTargetStride;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_TARGETING("arch=armv8-a+sve2")
|
||||
void Blit4to4KeySVE2(SDL_BlitInfo *info)
|
||||
{
|
||||
int width = info->dst_w;
|
||||
int height = info->dst_h;
|
||||
uint8_t *src = info->src;
|
||||
int srcskip = info->src_skip;
|
||||
uint8_t *dst = info->dst;
|
||||
int dstskip = info->dst_skip;
|
||||
|
||||
const SDL_PixelFormatDetails *srcfmt = info->src_fmt;
|
||||
const SDL_PixelFormatDetails *dstfmt = info->dst_fmt;
|
||||
|
||||
// Set up some basic variables
|
||||
int srcbpp = srcfmt->bytes_per_pixel;
|
||||
int dstbpp = dstfmt->bytes_per_pixel;
|
||||
|
||||
assert(srcbpp == 4);
|
||||
assert(dstbpp == 4);
|
||||
|
||||
int srcstride = srcskip + srcbpp * width;
|
||||
int dststride = dstskip + dstbpp * width;
|
||||
|
||||
uint32_t ckey = info->colorkey;
|
||||
uint32_t rgbmask = ~srcfmt->Amask;
|
||||
ckey &= rgbmask;
|
||||
|
||||
if (dstfmt->Amask) {
|
||||
uint32_t opamask = ((uint32_t)info->a) << dstfmt->Ashift;
|
||||
/* RGBA: set alpha from info->a */
|
||||
sdl_sve_rgb32_key_copy_alpha(src,
|
||||
srcstride,
|
||||
dst,
|
||||
dststride,
|
||||
width,
|
||||
height,
|
||||
ckey,
|
||||
rgbmask,
|
||||
opamask);
|
||||
} else {
|
||||
/* RGBA->RGB: only copy rgb and set alpha to zero */
|
||||
uint32_t rgbmaskactual = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask;
|
||||
sdl_sve_rgb32_key_no_alpha(src,
|
||||
srcstride,
|
||||
dst,
|
||||
dststride,
|
||||
width,
|
||||
height,
|
||||
ckey,
|
||||
rgbmask,
|
||||
rgbmaskactual);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_SVE2_INTRINSICS */
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
void Blit8888to8888PixelSwizzleSVE2(SDL_BlitInfo *info);
|
||||
void Blit8888to565PixelSwizzleSVE2(SDL_BlitInfo *info);
|
||||
void Blit2to2KeySVE2(SDL_BlitInfo *info);
|
||||
void Blit4to4KeySVE2(SDL_BlitInfo *info);
|
||||
|
||||
#endif /* SDL_SVE2_INTRINSICS */
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
/*
|
||||
* IMPORTANT: Please do NOT include this header file directly or indirectly
|
||||
* outside the src/video/arm folder.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(SDL_SVE2_EXTENSION_H) //&& (defined(__ARM_FEATURE_SVE2) && __ARM_FEATURE_SVE2)
|
||||
@@ -31,15 +31,15 @@
|
||||
#include "SDL_sve2_util.h"
|
||||
|
||||
/*
|
||||
* NOTE: Some Android builds didn't attach '-march=armv8-a+sve2' to
|
||||
* NOTE: Some Android builds didn't attach '-march=armv8-a+sve2' to
|
||||
* SDL_sve2_*.c and hence the macro __ARM_FEATURE_SVE is not
|
||||
* defined by the compiler. This might not be a problem as the
|
||||
* defined by the compiler. This might not be a problem as the
|
||||
* SDL_TARGETING("arch=armv8-a+sve2") enables the feature for
|
||||
* individual functions, until some version of compilers
|
||||
* provides arm_sve.h raising errors then __ARM_FEATURE_SVE
|
||||
* is not defined. Although it should be avoided, as a
|
||||
* workaround, we have to define the __ARM_FEATURE_SVE here as
|
||||
* an ugly hack.
|
||||
* provides arm_sve.h raising errors then __ARM_FEATURE_SVE
|
||||
* is not defined. Although it should be avoided, as a
|
||||
* workaround, we have to define the __ARM_FEATURE_SVE here as
|
||||
* an ugly hack.
|
||||
*/
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
#ifndef __ARM_FEATURE_SVE
|
||||
@@ -66,12 +66,12 @@
|
||||
#define svlens32() svlenu32()
|
||||
#define svlens64() svlenu64()
|
||||
|
||||
#define sdl_sve_stride_loop_accc8888(ma_stride_size, ma_pred_name) \
|
||||
#define sdl_sve_stride_loop_pixel(ma_stride_size, ma_pred_name) \
|
||||
for (svbool_t ma_pred_name, *pTemp = &ma_pred_name; \
|
||||
pTemp != NULL; \
|
||||
pTemp = NULL) \
|
||||
for (size_t SVE_SAFE_NAME(n) = 0, \
|
||||
sve_iteration_advance = svlenu32() * 4; \
|
||||
sve_iteration_advance = svlenu8(); \
|
||||
({ \
|
||||
ma_pred_name = svwhilelt_b8((int32_t)SVE_SAFE_NAME(n), \
|
||||
(int32_t)(ma_stride_size)); \
|
||||
@@ -79,10 +79,9 @@
|
||||
}); \
|
||||
SVE_SAFE_NAME(n) += sve_iteration_advance)
|
||||
|
||||
#define sdl_sve_stride_loop_rgb32(ma_stride_size, ma_pred_name) \
|
||||
sdl_sve_stride_loop_accc8888(ma_stride_size, ma_pred_name)
|
||||
#define sdl_sve_stride_loop_u8 sdl_sve_stride_loop_pixel
|
||||
|
||||
#define sdl_sve_stride_loop_rgb16(ma_stride_size, ma_pred_name) \
|
||||
#define sdl_sve_stride_loop_u16(ma_stride_size, ma_pred_name) \
|
||||
for (svbool_t ma_pred_name, *pTemp = &ma_pred_name; \
|
||||
pTemp != NULL; \
|
||||
pTemp = NULL) \
|
||||
@@ -95,6 +94,19 @@
|
||||
}); \
|
||||
SVE_SAFE_NAME(n) += sve_iteration_advance)
|
||||
|
||||
#define sdl_sve_stride_loop_u32(ma_stride_size, ma_pred_name) \
|
||||
for (svbool_t ma_pred_name, *pTemp = &ma_pred_name; \
|
||||
pTemp != NULL; \
|
||||
pTemp = NULL) \
|
||||
for (size_t SVE_SAFE_NAME(n) = 0, \
|
||||
sve_iteration_advance = svlenu32(); \
|
||||
({ \
|
||||
ma_pred_name = svwhilelt_b16((int32_t)SVE_SAFE_NAME(n), \
|
||||
(int32_t)(ma_stride_size)); \
|
||||
SVE_SAFE_NAME(n) < (ma_stride_size); \
|
||||
}); \
|
||||
SVE_SAFE_NAME(n) += sve_iteration_advance)
|
||||
|
||||
#define sdl_sve_pixel_ccc_foreach_chn(ma_source_u16x3, \
|
||||
ma_target_u16x3, \
|
||||
...) \
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
/*
|
||||
* IMPORTANT: Please do NOT include this header file directly or indirectly
|
||||
* outside the src/video/arm folder.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(SD_SVE2_SWIZZLE_H) //&& (defined(__ARM_FEATURE_SVE2) && __ARM_FEATURE_SVE2)
|
||||
@@ -31,7 +31,7 @@
|
||||
#include "SDL_sve2_extension.h"
|
||||
|
||||
#define sdl_sve_rgb32_stride_impl(ma_sve_chn_iterator, ...) \
|
||||
sdl_sve_stride_loop_rgb32(uStride, vTailPred) \
|
||||
sdl_sve_stride_loop_pixel(uStride, vTailPred) \
|
||||
{ \
|
||||
\
|
||||
svuint16x4_t vSourceLow16x4 = svundef4_u16(); \
|
||||
@@ -71,7 +71,7 @@
|
||||
ma_alpha_idx, \
|
||||
ma_sve_chn_iterator, \
|
||||
...) \
|
||||
sdl_sve_stride_loop_rgb32(uStride, vTailPred) \
|
||||
sdl_sve_stride_loop_pixel(uStride, vTailPred) \
|
||||
{ \
|
||||
\
|
||||
svuint16x4_t vSourceLow16x4 = svundef4_u16(); \
|
||||
@@ -115,7 +115,7 @@
|
||||
}
|
||||
|
||||
#define sdl_sve_rgb32_to_rgb565_stride_impl(ma_sve_chn_iterator, ...) \
|
||||
sdl_sve_stride_loop_rgb32(uStride, vTailPred) \
|
||||
sdl_sve_stride_loop_pixel(uStride, vTailPred) \
|
||||
{ \
|
||||
\
|
||||
svuint16x4_t vSourceLow16x4 = svundef4_u16(); \
|
||||
@@ -153,7 +153,7 @@
|
||||
ma_alpha_idx, \
|
||||
ma_sve_chn_iterator, \
|
||||
...) \
|
||||
sdl_sve_stride_loop_rgb32(uStride, vTailPred) \
|
||||
sdl_sve_stride_loop_pixel(uStride, vTailPred) \
|
||||
{ \
|
||||
\
|
||||
svuint16x4_t vSourceLow16x4 = svundef4_u16(); \
|
||||
|
||||
Reference in New Issue
Block a user