From a2cdd9ac18b149568be4b25ba934ecc93b53ef66 Mon Sep 17 00:00:00 2001 From: Clownacy Date: Thu, 23 Apr 2020 13:23:10 +0100 Subject: [PATCH] Allow surfaces to be marked as not-render-targets The Wii U has a very limited pool of memory for render targets (32MB), so we should only use it if we have to. This 'fixes' a bug in the enhanced branch, where if you use 2x sprites at 854x480, the third line of the text box will be corrupted (text will appear on the second line instead, and be black instead of white). The other renderers haven't been updated for the API change yet. --- src/Backends/Rendering.h | 2 +- src/Backends/Rendering/WiiU.cpp | 43 ++++++++++++++++++++++----------- src/Draw.cpp | 6 ++--- 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/Backends/Rendering.h b/src/Backends/Rendering.h index ba2fb18e..f1cac7f7 100644 --- a/src/Backends/Rendering.h +++ b/src/Backends/Rendering.h @@ -14,7 +14,7 @@ typedef struct RenderBackend_Rect RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_width, int screen_height, bool fullscreen); void RenderBackend_Deinit(void); void RenderBackend_DrawScreen(void); -RenderBackend_Surface* RenderBackend_CreateSurface(unsigned int width, unsigned int height); +RenderBackend_Surface* RenderBackend_CreateSurface(unsigned int width, unsigned int height, bool render_target); void RenderBackend_FreeSurface(RenderBackend_Surface *surface); bool RenderBackend_IsSurfaceLost(RenderBackend_Surface *surface); void RenderBackend_RestoreSurface(RenderBackend_Surface *surface); diff --git a/src/Backends/Rendering/WiiU.cpp b/src/Backends/Rendering/WiiU.cpp index 2fdae8c4..a38adc94 100644 --- a/src/Backends/Rendering/WiiU.cpp +++ b/src/Backends/Rendering/WiiU.cpp @@ -31,6 +31,7 @@ typedef struct RenderBackend_Surface GX2ColorBuffer colour_buffer; unsigned int width; unsigned int height; + bool render_target; unsigned char *lock_buffer; // TODO - Dumb } RenderBackend_Surface; @@ -146,7 +147,7 @@ RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_w GX2InitSampler(&sampler, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_LINEAR); // Create framebuffer surface - framebuffer_surface = RenderBackend_CreateSurface(screen_width, screen_height); + framebuffer_surface = RenderBackend_CreateSurface(screen_width, screen_height, true); if (framebuffer_surface != NULL) { @@ -350,7 +351,7 @@ void RenderBackend_DrawScreen(void) GX2SetContextState(gx2_context); } -RenderBackend_Surface* RenderBackend_CreateSurface(unsigned int width, unsigned int height) +RenderBackend_Surface* RenderBackend_CreateSurface(unsigned int width, unsigned int height, bool render_target) { RenderBackend_Surface *surface = (RenderBackend_Surface*)malloc(sizeof(RenderBackend_Surface)); @@ -358,6 +359,7 @@ RenderBackend_Surface* RenderBackend_CreateSurface(unsigned int width, unsigned { surface->width = width; surface->height = height; + surface->render_target = render_target; // Initialise texture memset(&surface->texture, 0, sizeof(surface->texture)); @@ -374,23 +376,34 @@ RenderBackend_Surface* RenderBackend_CreateSurface(unsigned int width, unsigned GX2CalcSurfaceSizeAndAlignment(&surface->texture.surface); GX2InitTextureRegs(&surface->texture); - if (GX2RCreateSurface(&surface->texture.surface, (GX2RResourceFlags)(GX2R_RESOURCE_BIND_TEXTURE | GX2R_RESOURCE_BIND_COLOR_BUFFER | + GX2RResourceFlags resource_flags = (GX2RResourceFlags)(GX2R_RESOURCE_BIND_TEXTURE | GX2R_RESOURCE_USAGE_CPU_WRITE | GX2R_RESOURCE_USAGE_CPU_READ | - GX2R_RESOURCE_USAGE_GPU_WRITE | GX2R_RESOURCE_USAGE_GPU_READ))) + GX2R_RESOURCE_USAGE_GPU_WRITE | GX2R_RESOURCE_USAGE_GPU_READ); + + resource_flags = (GX2RResourceFlags)(resource_flags | GX2R_RESOURCE_BIND_COLOR_BUFFER); + + if (GX2RCreateSurface(&surface->texture.surface, resource_flags)) { - // Initialise colour buffer (needed so the texture can be drawn to) - memset(&surface->colour_buffer, 0, sizeof(surface->colour_buffer)); - surface->colour_buffer.surface = surface->texture.surface; - surface->colour_buffer.viewNumSlices = 1; - GX2InitColorBufferRegs(&surface->colour_buffer); - - if (GX2RCreateSurfaceUserMemory(&surface->colour_buffer.surface, (uint8_t*)surface->texture.surface.image, (uint8_t*)surface->texture.surface.mipmaps, surface->texture.surface.resourceFlags)) + if (!render_target) + { return surface; + } else - Backend_PrintError("GX2RCreateSurfaceUserMemory failed in RenderBackend_CreateSurface"); + { + // Initialise colour buffer (needed so the texture can be drawn to) + memset(&surface->colour_buffer, 0, sizeof(surface->colour_buffer)); + surface->colour_buffer.surface = surface->texture.surface; + surface->colour_buffer.viewNumSlices = 1; + GX2InitColorBufferRegs(&surface->colour_buffer); + + if (GX2RCreateSurfaceUserMemory(&surface->colour_buffer.surface, (uint8_t*)surface->texture.surface.image, (uint8_t*)surface->texture.surface.mipmaps, surface->texture.surface.resourceFlags)) + return surface; + else + Backend_PrintError("GX2RCreateSurfaceUserMemory failed in RenderBackend_CreateSurface"); - GX2RDestroySurfaceEx(&surface->texture.surface, (GX2RResourceFlags)0); + GX2RDestroySurfaceEx(&surface->texture.surface, (GX2RResourceFlags)0); + } } else { @@ -407,7 +420,9 @@ void RenderBackend_FreeSurface(RenderBackend_Surface *surface) { if (surface != NULL) { - GX2RDestroySurfaceEx(&surface->colour_buffer.surface, (GX2RResourceFlags)0); + if (surface->render_target) + GX2RDestroySurfaceEx(&surface->colour_buffer.surface, (GX2RResourceFlags)0); + GX2RDestroySurfaceEx(&surface->texture.surface, (GX2RResourceFlags)0); free(surface); } diff --git a/src/Draw.cpp b/src/Draw.cpp index 6e5659c2..31792511 100644 --- a/src/Draw.cpp +++ b/src/Draw.cpp @@ -219,7 +219,7 @@ BOOL MakeSurface_Resource(const char *name, SurfaceID surf_no) if (image_buffer == NULL) return FALSE; - surf[surf_no] = RenderBackend_CreateSurface(width * magnification, height * magnification); + surf[surf_no] = RenderBackend_CreateSurface(width * magnification, height * magnification, false); if (surf[surf_no] == NULL) { @@ -281,7 +281,7 @@ BOOL MakeSurface_File(const char *name, SurfaceID surf_no) return FALSE; } - surf[surf_no] = RenderBackend_CreateSurface(width * magnification, height * magnification); + surf[surf_no] = RenderBackend_CreateSurface(width * magnification, height * magnification, false); if (surf[surf_no] == NULL) { @@ -392,7 +392,7 @@ BOOL MakeSurface_Generic(int bxsize, int bysize, SurfaceID surf_no, BOOL bSystem if (surf[surf_no] != NULL) return FALSE; - surf[surf_no] = RenderBackend_CreateSurface(bxsize * magnification, bysize * magnification); + surf[surf_no] = RenderBackend_CreateSurface(bxsize * magnification, bysize * magnification, true); if (surf[surf_no] == NULL) return FALSE;