shithub: cstory

Download patch

ref: a2cdd9ac18b149568be4b25ba934ecc93b53ef66
parent: ebb96ad239944284eb4461c2ea2057c9f92d80c8
author: Clownacy <Clownacy@users.noreply.github.com>
date: Thu Apr 23 09:23:10 EDT 2020

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.

--- a/src/Backends/Rendering.h
+++ b/src/Backends/Rendering.h
@@ -14,7 +14,7 @@
 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);
--- a/src/Backends/Rendering/WiiU.cpp
+++ b/src/Backends/Rendering/WiiU.cpp
@@ -31,6 +31,7 @@
 	GX2ColorBuffer colour_buffer;
 	unsigned int width;
 	unsigned int height;
+	bool render_target;
 	unsigned char *lock_buffer;	// TODO - Dumb
 } RenderBackend_Surface;
 
@@ -146,7 +147,7 @@
 					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 @@
 	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 @@
 	{
 		surface->width = width;
 		surface->height = height;
+		surface->render_target = render_target;
 
 		// Initialise texture
 		memset(&surface->texture, 0, sizeof(surface->texture));
@@ -374,23 +376,34 @@
 		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)))
-		{
-			// 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);
+		                                                                     GX2R_RESOURCE_USAGE_GPU_WRITE | GX2R_RESOURCE_USAGE_GPU_READ);
 
-			if (GX2RCreateSurfaceUserMemory(&surface->colour_buffer.surface, (uint8_t*)surface->texture.surface.image, (uint8_t*)surface->texture.surface.mipmaps, surface->texture.surface.resourceFlags))
+		resource_flags = (GX2RResourceFlags)(resource_flags | GX2R_RESOURCE_BIND_COLOR_BUFFER);
+
+		if (GX2RCreateSurface(&surface->texture.surface, resource_flags))
+		{
+			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 @@
 {
 	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);
 	}
--- a/src/Draw.cpp
+++ b/src/Draw.cpp
@@ -219,7 +219,7 @@
 	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 @@
 		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 @@
 	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;