diff --git a/include/SDL3/SDL_gxm.h b/include/SDL3/SDL_gxm.h new file mode 100644 index 000000000..1a80e2664 --- /dev/null +++ b/include/SDL3/SDL_gxm.h @@ -0,0 +1,33 @@ +#ifndef SDL_gxm_h_ +#define SDL_gxm_h_ + +#include +#include + +#include +#include + +#include +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + void *address; + Uint8 wait_vblank; +} VITA_GXM_DisplayData; + +extern SceClibMspace SDL_gxm_get_cdramPool(); + +extern int SDL_gxm_init(); +extern bool SDL_gxm_is_init(); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include + +#endif \ No newline at end of file diff --git a/src/SDL_error.c b/src/SDL_error.c index 3f4273b4f..e41b8d81b 100644 --- a/src/SDL_error.c +++ b/src/SDL_error.c @@ -66,7 +66,7 @@ bool SDL_SetErrorV(SDL_PRINTF_FORMAT_STRING const char *fmt, va_list ap) // Enable this if you want to see all errors printed as they occur. // Note that there are many recoverable errors that may happen internally and // can be safely ignored if the public API doesn't return an error code. -#if 0 +#if 1 SDL_LogError(SDL_LOG_CATEGORY_ERROR, "%s", error->str); #endif } diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 0a088a8b4..cace29340 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -2871,7 +2871,7 @@ static void SDL_RenderLogicalPresentation(SDL_Renderer *renderer) // now set everything back. view->logical_presentation_mode = mode; - SDL_SetRenderViewport(renderer, &orig_viewport); + //SDL_SetRenderViewport(renderer, &orig_viewport); if (clipping_enabled) { SDL_SetRenderClipRect(renderer, &orig_cliprect); } @@ -3040,7 +3040,7 @@ bool SDL_SetRenderViewport(SDL_Renderer *renderer, const SDL_Rect *rect) SDL_RenderViewState *view = renderer->view; if (rect) { if ((rect->w < 0) || (rect->h < 0)) { - return SDL_SetError("rect has a negative size"); + return SDL_SetError("rect has a negative size %d %d", rect->w, rect->h); } SDL_copyp(&view->viewport, rect); } else { diff --git a/src/render/opengles2/SDL_shaders_gles2.c b/src/render/opengles2/SDL_shaders_gles2.c index 3bff21178..0b6dace68 100644 --- a/src/render/opengles2/SDL_shaders_gles2.c +++ b/src/render/opengles2/SDL_shaders_gles2.c @@ -130,9 +130,7 @@ static const char GLES2_Fragment_TextureARGB[] = "void main()\n" "{\n" " mediump vec4 color = texture2D(u_texture, v_texCoord);\n" -" gl_FragColor = color;\n" -" gl_FragColor.r = color.b;\n" -" gl_FragColor.b = color.r;\n" +" gl_FragColor.rgba = color.bgra;\n" " gl_FragColor *= v_color;\n" "}\n" ; @@ -144,9 +142,7 @@ static const char GLES2_Fragment_TextureRGB[] = "void main()\n" "{\n" " mediump vec4 color = texture2D(u_texture, v_texCoord);\n" -" gl_FragColor = color;\n" -" gl_FragColor.r = color.b;\n" -" gl_FragColor.b = color.r;\n" +" gl_FragColor.rgb = color.bgr;\n" " gl_FragColor.a = 1.0;\n" " gl_FragColor *= v_color;\n" "}\n" @@ -183,9 +179,7 @@ static const char GLES2_Fragment_TextureARGB_PixelArt[] = "void main()\n" "{\n" RGB_PIXELART_GETCOLOR -" gl_FragColor = color;\n" -" gl_FragColor.r = color.b;\n" -" gl_FragColor.b = color.r;\n" +" gl_FragColor.rgba = color.bgra;\n" " gl_FragColor *= v_color;\n" "}\n" ; @@ -197,9 +191,7 @@ static const char GLES2_Fragment_TextureRGB_PixelArt[] = "void main()\n" "{\n" RGB_PIXELART_GETCOLOR -" gl_FragColor = color;\n" -" gl_FragColor.r = color.b;\n" -" gl_FragColor.b = color.r;\n" +" gl_FragColor.rgb = color.bgr;\n" " gl_FragColor.a = 1.0;\n" " gl_FragColor *= v_color;\n" "}\n" diff --git a/src/render/vitagxm/SDL_render_vita_gxm.c b/src/render/vitagxm/SDL_render_vita_gxm.c index 039155b73..dc1640634 100644 --- a/src/render/vitagxm/SDL_render_vita_gxm.c +++ b/src/render/vitagxm/SDL_render_vita_gxm.c @@ -1197,6 +1197,11 @@ static bool VITA_GXM_RenderPresent(SDL_Renderer *renderer) VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->internal; SceCommonDialogUpdateParam updateParam; + uint32_t* pixels = data->displayBufferData[data->backBufferIndex]; + for(int i = 0; i < 10*960; i++) { + pixels[i] = 0xffffffff; + } + data->displayData.address = data->displayBufferData[data->backBufferIndex]; SDL_memset(&updateParam, 0, sizeof(updateParam)); diff --git a/src/render/vitagxm/SDL_render_vita_gxm_memory.c b/src/render/vitagxm/SDL_render_vita_gxm_memory.c index e37a345c3..1a3904433 100644 --- a/src/render/vitagxm/SDL_render_vita_gxm_memory.c +++ b/src/render/vitagxm/SDL_render_vita_gxm_memory.c @@ -25,6 +25,9 @@ #include "SDL_render_vita_gxm_memory.h" +static SceUID cdramPoolUID = -1; +static SceClibMspace cdramPool = NULL; + void *vita_mem_alloc(unsigned int type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid) { void *mem; @@ -64,61 +67,70 @@ void vita_mem_free(SceUID uid) sceKernelFreeMemBlock(uid); } -void *vita_gpu_mem_alloc(VITA_GXM_RenderData *data, unsigned int size) -{ - void *mem; +static bool cdramPool_init() { + if(cdramPool) { + return true; + } + int poolsize; + int ret; + void* mem; + SceKernelFreeMemorySizeInfo info; + info.size = sizeof(SceKernelFreeMemorySizeInfo); + sceKernelGetFreeMemorySize(&info); + + poolsize = ALIGN(info.size_cdram, 256 * 1024); + if (poolsize > info.size_cdram) { + poolsize = ALIGN(info.size_cdram - 256 * 1024, 256 * 1024); + } + poolsize -= 16 * 1024 * 1024; + cdramPoolUID = sceKernelAllocMemBlock("gpu_cdram_pool", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, poolsize, NULL); + if (cdramPool < 0) { + return false; + } - if (!data->texturePool) { - int poolsize; - int ret; - SceKernelFreeMemorySizeInfo info; - info.size = sizeof(SceKernelFreeMemorySizeInfo); - sceKernelGetFreeMemorySize(&info); + ret = sceKernelGetMemBlockBase(cdramPoolUID, &mem); + if (ret < 0) { + return false; + } + cdramPool = sceClibMspaceCreate(mem, poolsize); - poolsize = ALIGN(info.size_cdram, 256 * 1024); - if (poolsize > info.size_cdram) { - poolsize = ALIGN(info.size_cdram - 256 * 1024, 256 * 1024); - } - data->texturePoolUID = sceKernelAllocMemBlock("gpu_texture_pool", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, poolsize, NULL); - if (data->texturePoolUID < 0) { - return NULL; - } + if (!cdramPool) { + return false; + } + ret = sceGxmMapMemory(mem, poolsize, SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE); + if (ret < 0) { + return false; + } + return true; +} - ret = sceKernelGetMemBlockBase(data->texturePoolUID, &mem); - if (ret < 0) { - return NULL; - } - data->texturePool = sceClibMspaceCreate(mem, poolsize); +SceClibMspace SDL_gxm_get_cdramPool() { + cdramPool_init(); + return cdramPool; +} - if (!data->texturePool) { - return NULL; - } - ret = sceGxmMapMemory(mem, poolsize, SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE); - if (ret < 0) { - return NULL; - } - } - return sceClibMspaceMemalign(data->texturePool, SCE_GXM_TEXTURE_ALIGNMENT, size); +void *vita_gpu_mem_alloc(VITA_GXM_RenderData *data, unsigned int alignment, unsigned int size) +{ + cdramPool_init(); + return sceClibMspaceMemalign(cdramPool, alignment, size); } void vita_gpu_mem_free(VITA_GXM_RenderData *data, void *ptr) { - if (data->texturePool) { - sceClibMspaceFree(data->texturePool, ptr); - } + sceClibMspaceFree(cdramPool, ptr); } void vita_gpu_mem_destroy(VITA_GXM_RenderData *data) { void *mem = NULL; - if (data->texturePool) { - sceClibMspaceDestroy(data->texturePool); - data->texturePool = NULL; - if (sceKernelGetMemBlockBase(data->texturePoolUID, &mem) < 0) { + if (cdramPool) { + sceClibMspaceDestroy(cdramPool); + cdramPool = NULL; + if (sceKernelGetMemBlockBase(cdramPoolUID, &mem) < 0) { return; } sceGxmUnmapMemory(mem); - sceKernelFreeMemBlock(data->texturePoolUID); + sceKernelFreeMemBlock(cdramPoolUID); } } diff --git a/src/render/vitagxm/SDL_render_vita_gxm_memory.h b/src/render/vitagxm/SDL_render_vita_gxm_memory.h index cc548b3ba..18d011c8b 100644 --- a/src/render/vitagxm/SDL_render_vita_gxm_memory.h +++ b/src/render/vitagxm/SDL_render_vita_gxm_memory.h @@ -31,7 +31,7 @@ void *vita_mem_alloc(unsigned int type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid); void vita_mem_free(SceUID uid); -void *vita_gpu_mem_alloc(VITA_GXM_RenderData *data, unsigned int size); +void *vita_gpu_mem_alloc(VITA_GXM_RenderData *data, unsigned int alignment, unsigned int size); void vita_gpu_mem_free(VITA_GXM_RenderData *data, void *ptr); void vita_gpu_mem_destroy(VITA_GXM_RenderData *data); void *vita_mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset); diff --git a/src/render/vitagxm/SDL_render_vita_gxm_tools.c b/src/render/vitagxm/SDL_render_vita_gxm_tools.c index 48af7b8f6..b12a5bfd9 100644 --- a/src/render/vitagxm/SDL_render_vita_gxm_tools.c +++ b/src/render/vitagxm/SDL_render_vita_gxm_tools.c @@ -291,6 +291,38 @@ void unset_clip_rectangle(VITA_GXM_RenderData *data) 0xFF); } +static bool gxm_initialized = false; + +bool SDL_gxm_is_init() { + return gxm_initialized; +} + +__weak_symbol void load_razor() {} + +int SDL_gxm_init() { + if(gxm_initialized) { + return 0; + } + + load_razor(); + + SceGxmInitializeParams initializeParams; + SDL_memset(&initializeParams, 0, sizeof(SceGxmInitializeParams)); + initializeParams.flags = 0; + initializeParams.displayQueueMaxPendingCount = VITA_GXM_PENDING_SWAPS; + initializeParams.displayQueueCallback = display_callback; + initializeParams.displayQueueCallbackDataSize = sizeof(VITA_GXM_DisplayData); + initializeParams.parameterBufferSize = SCE_GXM_DEFAULT_PARAMETER_BUFFER_SIZE; + + int err = sceGxmInitialize(&initializeParams); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "gxm init failed: %d", err); + return err; + } + gxm_initialized = true; + return 0; +} + int gxm_init(SDL_Renderer *renderer) { unsigned int i, x, y; @@ -376,18 +408,8 @@ int gxm_init(SDL_Renderer *renderer) VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->internal; - SceGxmInitializeParams initializeParams; - SDL_memset(&initializeParams, 0, sizeof(SceGxmInitializeParams)); - initializeParams.flags = 0; - initializeParams.displayQueueMaxPendingCount = VITA_GXM_PENDING_SWAPS; - initializeParams.displayQueueCallback = display_callback; - initializeParams.displayQueueCallbackDataSize = sizeof(VITA_GXM_DisplayData); - initializeParams.parameterBufferSize = SCE_GXM_DEFAULT_PARAMETER_BUFFER_SIZE; - - err = sceGxmInitialize(&initializeParams); - - if (err != 0) { - SDL_LogError(SDL_LOG_CATEGORY_RENDER, "gxm init failed: %d", err); + err = SDL_gxm_init(); + if(err != 0) { return err; } @@ -464,6 +486,10 @@ int gxm_init(SDL_Renderer *renderer) SCE_GXM_COLOR_SURFACE_ALIGNMENT, SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, &data->displayBufferUid[i]); + if(!data->displayBufferData[i]) { + SDL_Log("failed to allocate display buffer"); + return -1; + } // SDL_memset the buffer to black for (y = 0; y < VITA_GXM_SCREEN_HEIGHT; y++) { @@ -535,7 +561,6 @@ int gxm_init(SDL_Renderer *renderer) SCE_GXM_STENCIL_OP_KEEP, 0xFF, 0xFF); - // allocate memory for buffers and USSE code patcherBuffer = vita_mem_alloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, @@ -1012,6 +1037,7 @@ gxm_texture *create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsig // Allocate a GPU buffer for the texture texture_data = vita_gpu_mem_alloc( data, + SCE_GXM_TEXTURE_ALIGNMENT, tex_size); // Try SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE in case we're out of VRAM diff --git a/src/render/vitagxm/SDL_render_vita_gxm_types.h b/src/render/vitagxm/SDL_render_vita_gxm_types.h index 6fc2c9e81..06ccecc91 100644 --- a/src/render/vitagxm/SDL_render_vita_gxm_types.h +++ b/src/render/vitagxm/SDL_render_vita_gxm_types.h @@ -25,6 +25,7 @@ #include "SDL_internal.h" #include "../SDL_sysrender.h" +#include #include #include @@ -47,12 +48,6 @@ #define VITA_GXM_PENDING_SWAPS 2 #define VITA_GXM_POOL_SIZE 2 * 1024 * 1024 -typedef struct -{ - void *address; - Uint8 wait_vblank; -} VITA_GXM_DisplayData; - typedef struct clear_vertex { float x; @@ -193,8 +188,6 @@ typedef struct blend_fragment_programs blendFragmentPrograms; gxm_drawstate_cache drawstate; - SceClibMspace texturePool; - SceUID texturePoolUID; } VITA_GXM_RenderData; typedef struct diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c index f40a92d85..b46b94730 100644 --- a/src/video/SDL_surface.c +++ b/src/video/SDL_surface.c @@ -271,6 +271,7 @@ SDL_Surface *SDL_CreateSurfaceFrom(int width, int height, SDL_PixelFormat format } if (pitch < 0 || (size_t)pitch < minimalPitch) { + SDL_Log("pitch=%d minimalPitch=%d", pitch, minimalPitch); SDL_InvalidParamError("pitch"); return NULL; }