Skip to content

Commit dc5b136

Browse files
HecaiYuanslouken
authored andcommitted
loongarch: add SDL_FillSurfaceRect4LSX opt
1 parent 0b1eb4c commit dc5b136

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -935,11 +935,13 @@ if(SDL_ASSEMBLY)
935935
set_property(SOURCE
936936
"${SDL3_SOURCE_DIR}/src/video/yuv2rgb/yuv_rgb_lsx.c"
937937
"${SDL3_SOURCE_DIR}/src/video/SDL_blit_A.c"
938+
"${SDL3_SOURCE_DIR}/src/video/SDL_fillrect.c"
938939
APPEND PROPERTY COMPILE_OPTIONS "-mlsx")
939940

940941
set_property(SOURCE
941942
"${SDL3_SOURCE_DIR}/src/video/yuv2rgb/yuv_rgb_lsx.c"
942943
"${SDL3_SOURCE_DIR}/src/video/SDL_blit_A.c"
944+
"${SDL3_SOURCE_DIR}/src/video/SDL_fillrect.c"
943945
PROPERTY SKIP_PRECOMPILE_HEADERS 1)
944946
set(HAVE_LSX TRUE)
945947
endif()

src/video/SDL_fillrect.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,69 @@ DEFINE_SSE_FILLRECT(4, Uint32)
133133
/* *INDENT-ON* */ // clang-format on
134134
#endif // __SSE__
135135

136+
#ifdef SDL_LSX_INTRINSICS
137+
/* *INDENT-OFF* */ // clang-format off
138+
139+
#define LSX_BEGIN __m128i c128 = __lsx_vreplgr2vr_w(color);
140+
141+
#define LSX_WORK \
142+
for (i = n / 64; i--;) { \
143+
__lsx_vst(c128, p, 0); \
144+
__lsx_vst(c128, p, 16); \
145+
__lsx_vst(c128, p, 32); \
146+
__lsx_vst(c128, p, 48); \
147+
p += 64; \
148+
}
149+
150+
#define DEFINE_LSX_FILLRECT(bpp, type) \
151+
static void SDL_TARGETING("lsx") SDL_FillSurfaceRect##bpp##LSX(Uint8 *pixels, int pitch, Uint32 color, int w, int h) \
152+
{ \
153+
int i, n; \
154+
Uint8 *p = NULL; \
155+
\
156+
/* If the number of bytes per row is equal to the pitch, treat */ \
157+
/* all rows as one long continuous row (for better performance) */ \
158+
if ((w) * (bpp) == pitch) { \
159+
w = w * h; \
160+
h = 1; \
161+
} \
162+
\
163+
LSX_BEGIN; \
164+
\
165+
while (h--) { \
166+
n = (w) * (bpp); \
167+
p = pixels; \
168+
\
169+
if (n > 63) { \
170+
int adjust = 16 - ((uintptr_t)p & 15); \
171+
if (adjust < 16) { \
172+
n -= adjust; \
173+
adjust /= (bpp); \
174+
while (adjust--) { \
175+
*((type *)p) = (type)color; \
176+
p += (bpp); \
177+
} \
178+
} \
179+
LSX_WORK; \
180+
} \
181+
if (n & 63) { \
182+
int remainder = (n & 63); \
183+
remainder /= (bpp); \
184+
while (remainder--) { \
185+
*((type *)p) = (type)color; \
186+
p += (bpp); \
187+
} \
188+
} \
189+
pixels += pitch; \
190+
} \
191+
\
192+
}
193+
194+
DEFINE_LSX_FILLRECT(4, Uint32)
195+
196+
/* *INDENT-ON* */ // clang-format on
197+
#endif /* __LSX__ */
198+
136199
static void SDL_FillSurfaceRect1(Uint8 *pixels, int pitch, Uint32 color, int w, int h)
137200
{
138201
int n;
@@ -339,6 +402,12 @@ bool SDL_FillSurfaceRects(SDL_Surface *dst, const SDL_Rect *rects, int count, Ui
339402
fill_function = SDL_FillSurfaceRect4SSE;
340403
break;
341404
}
405+
#endif
406+
#ifdef SDL_LSX_INTRINSICS
407+
if (SDL_HasLSX()) {
408+
fill_function = SDL_FillSurfaceRect4LSX;
409+
break;
410+
}
342411
#endif
343412
fill_function = SDL_FillSurfaceRect4;
344413
break;

0 commit comments

Comments
 (0)