Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions src/render/SDL_render.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@
#include "software/SDL_render_sw_c.h"
#include "../video/SDL_pixels_c.h"

#if defined(__loongarch__)
#if SDL_VIDEO_OPENGL
#include "SDL_opengl.h"
#endif /* SDL_VIDEO_OPENGL */
#endif

#if defined(__ANDROID__)
#include "../core/android/SDL_android.h"
#endif
Expand Down Expand Up @@ -954,6 +960,34 @@ static void SDL_CalculateSimulatedVSyncInterval(SDL_Renderer *renderer, SDL_Wind
}
#endif /* !SDL_RENDER_DISABLED */

#if defined(__loongarch__)
static SDL_bool SDL_CheckIntegratedGraphics()
{
SDL_Window *window = SDL_CreateWindow("OpenGL test", -32, -32, 32, 32,
SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN);
SDL_bool has_lg100_or_lg110 = SDL_FALSE;

if (window) {
SDL_GLContext context = SDL_GL_CreateContext(window);

if (context) {
const GLubyte *(APIENTRY *glGetStringFunc)(GLenum) =
SDL_GL_GetProcAddress("glGetString");
if (glGetStringFunc) {
const char *renderer = (const char*)glGetStringFunc(GL_RENDERER);
if (renderer && (SDL_strstr(renderer, "LG110") ||
SDL_strstr(renderer, "LG100"))) {
has_lg100_or_lg110 = SDL_TRUE;
}
}
SDL_GL_DeleteContext(context);
}
SDL_DestroyWindow(window);
}
return has_lg100_or_lg110;
}
#endif

SDL_Renderer *SDL_CreateRenderer(SDL_Window *window, int index, Uint32 flags)
{
#ifndef SDL_RENDER_DISABLED
Expand All @@ -967,6 +1001,14 @@ SDL_Renderer *SDL_CreateRenderer(SDL_Window *window, int index, Uint32 flags)
Android_ActivityMutex_Lock_Running();
#endif

/*CPU acceleration runs faster than integrated graphichs on Loongson at pressent.*/
#if defined(__linux__) && defined(__loongarch__)
if (SDL_CheckIntegratedGraphics()) {
SDL_SetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION, "0");
flags = SDL_RENDERER_SOFTWARE;
}
#endif

if (!window) {
SDL_InvalidParamError("window");
goto error;
Expand Down
69 changes: 67 additions & 2 deletions src/video/SDL_blit_A.c
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,66 @@ static void BlitRGBtoRGBPixelAlphaMMX(SDL_BlitInfo *info)

#endif /* __MMX__ */

#if defined(__loongarch_sx)

static void
BlitRGBtoRGBPixelAlphaLSX(SDL_BlitInfo * info)
{
int width = info->dst_w;
int height = info->dst_h;
Uint32 *srcp = (Uint32 *) info->src;
int srcskip = info->src_skip >> 2;
Uint32 *dstp = (Uint32 *) info->dst;
int dstskip = info->dst_skip >> 2;
SDL_PixelFormat *sf = info->src_fmt;
Uint32 amask = sf->Amask;
Uint32 ashift = sf->Ashift;
Uint64 multmask, multmask2;

__m128i src1, src2, src3, dst1, alpha, alpha2;
multmask = 0x00FF;
multmask <<= (ashift * 2);
multmask2 = 0x00FF00FF00FF00FFULL;

while (height--) {
/* *INDENT-OFF* */
DUFFS_LOOP4({
Uint32 alpha1 = *srcp & amask;
if (alpha1 == 0) {
/* do nothing */
} else if (alpha1 == amask) {
*dstp = *srcp;
} else {
src1 = __lsx_vreplgr2vr_w(*srcp);
src1 = __lsx_vinsgr2vr_w(src1, *dstp, 1);
src2 = __lsx_vsllwil_hu_bu(src1, 0);

alpha = __lsx_vreplgr2vr_w(alpha1);
alpha = __lsx_vsrl_d(alpha, __lsx_vreplgr2vr_d(ashift));
alpha = __lsx_vilvl_h(alpha, alpha);
alpha2 = __lsx_vilvl_w(alpha, alpha);
alpha = __lsx_vor_v(alpha2, __lsx_vreplgr2vr_d(multmask));
alpha2 = __lsx_vxor_v(alpha2, __lsx_vreplgr2vr_d(multmask2));

src3 = __lsx_vilvl_d(alpha2, alpha);
src1 = __lsx_vmul_h(src2, src3);
src1 = __lsx_vsrli_h(src1, 8);
src2 = __lsx_vilvh_d(src1, src1);
src1 = __lsx_vadd_h(src1, src2);
dst1 = __lsx_vssrlni_bu_h(src1, src1, 0);
__lsx_vstelm_w(dst1, dstp, 0, 0);
}
++srcp;
++dstp;
}, width);
/* *INDENT-ON* */
srcp += srcskip;
dstp += dstskip;
}
}

#endif /* __loongarch_sx */

#ifdef SDL_ARM_SIMD_BLITTERS
void BlitARGBto565PixelAlphaARMSIMDAsm(int32_t w, int32_t h, uint16_t *dst, int32_t dst_stride, uint32_t *src, int32_t src_stride);

Expand Down Expand Up @@ -1456,7 +1516,7 @@ SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface *surface)

case 4:
if (sf->Rmask == df->Rmask && sf->Gmask == df->Gmask && sf->Bmask == df->Bmask && sf->BytesPerPixel == 4) {
#if defined(__MMX__) || defined(__3dNOW__)
#if defined(__MMX__) || defined(__3dNOW__) || defined(__loongarch_sx)
if (sf->Rshift % 8 == 0 && sf->Gshift % 8 == 0 && sf->Bshift % 8 == 0 && sf->Ashift % 8 == 0 && sf->Aloss == 0) {
#ifdef __3dNOW__
if (SDL_Has3DNow()) {
Expand All @@ -1467,9 +1527,14 @@ SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface *surface)
if (SDL_HasMMX()) {
return BlitRGBtoRGBPixelAlphaMMX;
}
#endif
#ifdef __loongarch_sx
if (SDL_HasLSX()) {
return BlitRGBtoRGBPixelAlphaLSX;
}
#endif
}
#endif /* __MMX__ || __3dNOW__ */
#endif /* __MMX__ || __3dNOW__ || __loongarch_sx*/
if (sf->Amask == 0xff000000) {
#ifdef SDL_ARM_NEON_BLITTERS
if (SDL_HasNEON()) {
Expand Down
62 changes: 62 additions & 0 deletions src/video/SDL_fillrect.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,61 @@ DEFINE_SSE_FILLRECT(4, Uint32)
/* *INDENT-ON* */ /* clang-format on */
#endif /* __SSE__ */

#if defined(__loongarch_sx)

#define LSX_BEGIN __m128i c128 = __lsx_vreplgr2vr_w(color);

#define LSX_WORK \
for (i = n / 64; i--;) { \
__lsx_vst(c128, p, 0); \
__lsx_vst(c128, p, 16); \
__lsx_vst(c128, p, 32); \
__lsx_vst(c128, p, 48); \
p += 64; \
}

#define DEFINE_LSX_FILLRECT(bpp, type) \
static void \
SDL_FillRect##bpp##LSX(Uint8 *pixels, int pitch, Uint32 color, int w, int h) \
{ \
int i, n; \
Uint8 *p = NULL; \
\
LSX_BEGIN; \
\
while (h--) { \
n = w * bpp; \
p = pixels; \
\
if (n > 63) { \
int adjust = 16 - ((uintptr_t)p & 15); \
if (adjust < 16) { \
n -= adjust; \
adjust /= bpp; \
while (adjust--) { \
*((type *)p) = (type)color; \
p += bpp; \
} \
} \
LSX_WORK; \
} \
if (n & 63) { \
int remainder = (n & 63); \
remainder /= bpp; \
while (remainder--) { \
*((type *)p) = (type)color; \
p += bpp; \
} \
} \
pixels += pitch; \
} \
\
}

DEFINE_LSX_FILLRECT(4, Uint32)

#endif

static void SDL_FillRect1(Uint8 *pixels, int pitch, Uint32 color, int w, int h)
{
int n;
Expand Down Expand Up @@ -423,6 +478,13 @@ int SDL_FillRects(SDL_Surface *dst, const SDL_Rect *rects, int count,
break;
}
#endif

#ifdef __loongarch_sx
if (SDL_HasLSX()) {
fill_function = SDL_FillRect4LSX;
break;
}
#endif
fill_function = SDL_FillRect4;
break;
}
Expand Down
Loading