Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3DS: Initial accelerated renderer #9598

Draft
wants to merge 14 commits into
base: SDL2
Choose a base branch
from
Draft
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
8 changes: 7 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2854,6 +2854,9 @@ elseif(N3DS)
file(GLOB N3DS_MAIN_SOURCES ${SDL2_SOURCE_DIR}/src/main/n3ds/*.c)
set(SDLMAIN_SOURCES ${SDLMAIN_SOURCES} ${N3DS_MAIN_SOURCES})

file(GLOB N3DS_CORE_SOURCES ${SDL2_SOURCE_DIR}/src/core/n3ds/*.c)
list(APPEND SOURCE_FILES ${N3DS_CORE_SOURCES})

if(SDL_AUDIO)
set(SDL_AUDIO_DRIVER_N3DS 1)
file(GLOB N3DS_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/n3ds/*.c)
Expand Down Expand Up @@ -2907,9 +2910,12 @@ elseif(N3DS)

if(SDL_VIDEO)
set(SDL_VIDEO_DRIVER_N3DS 1)
file(GLOB N3DS_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/n3ds/*.c)
set(SDL_VIDEO_RENDER_N3DS 1)
file(GLOB N3DS_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/n3ds/*.c ${SDL2_SOURCE_DIR}/src/render/n3ds/*.c)
list(APPEND SOURCE_FILES ${N3DS_VIDEO_SOURCES})
set(SDL_VIDEO_OPENGL 0)
set(HAVE_SDL_VIDEO TRUE)
list(APPEND EXTRA_LIBS citro3d)
endif()

if(SDL_LOCALE)
Expand Down
1 change: 1 addition & 0 deletions include/SDL_config.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,7 @@
#cmakedefine SDL_VIDEO_RENDER_OGL_ES2 @SDL_VIDEO_RENDER_OGL_ES2@
#cmakedefine SDL_VIDEO_RENDER_DIRECTFB @SDL_VIDEO_RENDER_DIRECTFB@
#cmakedefine SDL_VIDEO_RENDER_METAL @SDL_VIDEO_RENDER_METAL@
#cmakedefine SDL_VIDEO_RENDER_N3DS @SDL_VIDEO_RENDER_N3DS@
#cmakedefine SDL_VIDEO_RENDER_VITA_GXM @SDL_VIDEO_RENDER_VITA_GXM@
#cmakedefine SDL_VIDEO_RENDER_PS2 @SDL_VIDEO_RENDER_PS2@
#cmakedefine SDL_VIDEO_RENDER_PSP @SDL_VIDEO_RENDER_PSP@
Expand Down
8 changes: 7 additions & 1 deletion src/SDL_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@
#ifndef SDL_VIDEO_RENDER_VITA_GXM
#define SDL_VIDEO_RENDER_VITA_GXM 0
#endif
#ifndef SDL_VIDEO_RENDER_N3DS
#define SDL_VIDEO_RENDER_N3DS 0
#endif
#else /* define all as 0 */
#undef SDL_VIDEO_RENDER_SW
#define SDL_VIDEO_RENDER_SW 0
Expand All @@ -185,6 +188,8 @@
#define SDL_VIDEO_RENDER_PSP 0
#undef SDL_VIDEO_RENDER_VITA_GXM
#define SDL_VIDEO_RENDER_VITA_GXM 0
#undef SDL_VIDEO_RENDER_N3DS
#define SDL_VIDEO_RENDER_N3DS 0
#endif /* SDL_RENDER_DISABLED */

#define SDL_HAS_RENDER_DRIVER \
Expand All @@ -199,7 +204,8 @@
SDL_VIDEO_RENDER_DIRECTFB | \
SDL_VIDEO_RENDER_PS2 | \
SDL_VIDEO_RENDER_PSP | \
SDL_VIDEO_RENDER_VITA_GXM)
SDL_VIDEO_RENDER_VITA_GXM | \
SDL_VIDEO_RENDER_N3DS)

#if !defined(SDL_RENDER_DISABLED) && !SDL_HAS_RENDER_DRIVER
#error SDL_RENDER enabled without any backend drivers.
Expand Down
53 changes: 53 additions & 0 deletions src/core/n3ds/SDL_n3ds.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <[email protected]>

This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include <3ds.h>
#include "../../SDL_internal.h"

#include "3ds/allocator/linear.h"
#include "SDL_stdinc.h"

#ifdef __3DS__

void* N3DS_linearRealloc(void* mem, size_t size) {
/* FIXME: Remove this once libctru implements linearRealloc(). */
if (mem == NULL) {
return linearAlloc(size);
} else if (linearGetSize(mem) <= size) {
return mem;
} else {
void *newMem = linearAlloc(size);
if (newMem != NULL) {
SDL_memcpy(newMem, mem, size);
linearFree(mem);
return newMem;
} else {
return NULL;
}
}
}

void N3DS_linearFree(void* mem) {
linearFree(mem);
}

#endif /* __3DS__ */

/* vi: set ts=4 sw=4 expandtab: */
41 changes: 41 additions & 0 deletions src/core/n3ds/SDL_n3ds.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <[email protected]>

This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#include "SDL_system.h"

/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
/* *INDENT-OFF* */
extern "C" {
/* *INDENT-ON* */
#endif

extern void* N3DS_linearRealloc(void* mem, size_t size);
extern void N3DS_linearFree(void* mem);

/* Ends C function definitions when using C++ */
#ifdef __cplusplus
/* *INDENT-OFF* */
}
/* *INDENT-ON* */
#endif

/* vi: set ts=4 sw=4 expandtab: */
24 changes: 20 additions & 4 deletions src/render/SDL_render.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
#include "../core/android/SDL_android.h"
#endif

#if defined(__3DS__)
# include "../core/n3ds/SDL_n3ds.h"
#endif

/* as a courtesy to iOS apps, we don't try to draw when in the background, as
that will crash the app. However, these apps _should_ have used
SDL_AddEventWatch to catch SDL_APP_WILLENTERBACKGROUND events and stopped
Expand Down Expand Up @@ -122,6 +126,9 @@ static const SDL_RenderDriver *render_drivers[] = {
#if SDL_VIDEO_RENDER_DIRECTFB
&DirectFB_RenderDriver,
#endif
#if SDL_VIDEO_RENDER_N3DS
&N3DS_RenderDriver,
#endif
#if SDL_VIDEO_RENDER_PS2
&PS2_RenderDriver,
#endif
Expand Down Expand Up @@ -306,7 +313,12 @@ void *SDL_AllocateRenderVertices(SDL_Renderer *renderer, const size_t numbytes,
newsize *= 2;
}

#ifdef __3DS__
/* The 3DS GPU expects vertex data to be linear in physical memory. */
ptr = N3DS_linearRealloc(renderer->vertex_data, newsize);
#else
ptr = SDL_realloc(renderer->vertex_data, newsize);
#endif

if (!ptr) {
SDL_OutOfMemory();
Expand Down Expand Up @@ -906,7 +918,7 @@ static SDL_INLINE void VerifyDrawQueueFunctions(const SDL_Renderer *renderer)
have to check that they aren't NULL over and over. */
SDL_assert(renderer->QueueSetViewport != NULL);
SDL_assert(renderer->QueueSetDrawColor != NULL);
SDL_assert(renderer->QueueDrawPoints != NULL);
SDL_assert(renderer->QueueDrawPoints != NULL || renderer->QueueGeometry != NULL);
SDL_assert(renderer->QueueDrawLines != NULL || renderer->QueueGeometry != NULL);
SDL_assert(renderer->QueueFillRects != NULL || renderer->QueueGeometry != NULL);
SDL_assert(renderer->QueueCopy != NULL || renderer->QueueGeometry != NULL);
Expand Down Expand Up @@ -2750,7 +2762,7 @@ int SDL_RenderDrawPoints(SDL_Renderer *renderer,
}
#endif

if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) {
if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f || renderer->point_method == SDL_RENDERPOINTMETHOD_GEOMETRY) {
retval = RenderDrawPointsWithRects(renderer, points, count);
} else {
fpoints = SDL_small_alloc(SDL_FPoint, count, &isstack);
Expand Down Expand Up @@ -2821,7 +2833,7 @@ int SDL_RenderDrawPointsF(SDL_Renderer *renderer,
}
#endif

if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) {
if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f || renderer->point_method == SDL_RENDERPOINTMETHOD_GEOMETRY) {
retval = RenderDrawPointsWithRectsF(renderer, points, count);
} else {
retval = QueueCmdDrawPoints(renderer, points, count);
Expand Down Expand Up @@ -2929,7 +2941,7 @@ static int RenderDrawLineBresenham(SDL_Renderer *renderer, int x1, int y1, int x
}
}

if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) {
if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f || renderer->point_method == SDL_RENDERPOINTMETHOD_GEOMETRY) {
retval = RenderDrawPointsWithRectsF(renderer, points, numpixels);
} else {
retval = QueueCmdDrawPoints(renderer, points, numpixels);
Expand Down Expand Up @@ -4380,7 +4392,11 @@ void SDL_DestroyRendererWithoutFreeing(SDL_Renderer *renderer)
cmd = next;
}

#ifdef __3DS__
N3DS_linearFree(renderer->vertex_data);
#else
SDL_free(renderer->vertex_data);
#endif

/* Free existing textures for this renderer */
while (renderer->textures) {
Expand Down
10 changes: 10 additions & 0 deletions src/render/SDL_sysrender.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ typedef struct SDL_VertexSolid
SDL_Color color;
} SDL_VertexSolid;

typedef enum
{
SDL_RENDERPOINTMETHOD_POINTS,
SDL_RENDERPOINTMETHOD_GEOMETRY,
} SDL_RenderPointMethod;

typedef enum
{
SDL_RENDERLINEMETHOD_POINTS,
Expand Down Expand Up @@ -246,6 +252,9 @@ struct SDL_Renderer
/* Whether or not to scale relative mouse motion */
SDL_bool relative_scaling;

/* The method of drawing points */
SDL_RenderPointMethod point_method;

/* The method of drawing lines */
SDL_RenderLineMethod line_method;

Expand Down Expand Up @@ -305,6 +314,7 @@ extern SDL_RenderDriver GLES2_RenderDriver;
extern SDL_RenderDriver GLES_RenderDriver;
extern SDL_RenderDriver DirectFB_RenderDriver;
extern SDL_RenderDriver METAL_RenderDriver;
extern SDL_RenderDriver N3DS_RenderDriver;
extern SDL_RenderDriver PS2_RenderDriver;
extern SDL_RenderDriver PSP_RenderDriver;
extern SDL_RenderDriver SW_RenderDriver;
Expand Down
Loading
Loading