shithub: cstory

Download patch

ref: 30ec081d7b0639b89959a78775fab23625578f30
parent: 385b7531ef65be719513a2162523407bfef732b3
author: Clownacy <Clownacy@users.noreply.github.com>
date: Sun Oct 4 08:58:57 EDT 2020

Refactor Wii U renderer in preparation

This is in preparation for an upscaled-framebuffer system like the
OpenGL backend has.

I wonder if it's possible to just use a shader instead, and avoid the
need for an upscaled framebuffer to make the linear filtering not
look terrible.

--- a/src/Backends/Rendering/WiiU.cpp
+++ b/src/Backends/Rendering/WiiU.cpp
@@ -65,7 +65,8 @@
 
 static GX2RBuffer vertex_buffer;
 
-static GX2Sampler sampler;
+static GX2Sampler sampler_point;
+static GX2Sampler sampler_linear;
 
 static RenderBackend_Surface *framebuffer_surface;
 
@@ -159,6 +160,83 @@
 	current_vertex_buffer_slot = 0;
 }
 
+static void Blit(RenderBackend_Surface *source_surface, const RenderBackend_Rect *source_rect, RenderBackend_Surface *destination_surface, const RenderBackend_Rect *destination_rect, bool colour_key, GX2Sampler *sampler)
+{
+	const RenderMode render_mode = (colour_key ? MODE_DRAW_SURFACE_WITH_TRANSPARENCY : MODE_DRAW_SURFACE);
+
+	// Flush vertex data if a context-change is needed
+	if (last_render_mode != render_mode || last_source_texture != &source_surface->texture || last_destination_texture != &destination_surface->texture)
+	{
+		FlushVertexBuffer();
+
+		last_render_mode = render_mode;
+		last_source_texture = &source_surface->texture;
+		last_destination_texture = &destination_surface->texture;
+
+		// Draw to the selected texture, instead of the screen
+		GX2SetColorBuffer(&destination_surface->colour_buffer, GX2_RENDER_TARGET_0);
+		GX2SetViewport(0.0f, 0.0f, (float)destination_surface->colour_buffer.surface.width, (float)destination_surface->colour_buffer.surface.height, 0.0f, 1.0f);
+		GX2SetScissor(0, 0, destination_surface->colour_buffer.surface.width, destination_surface->colour_buffer.surface.height);
+
+		// Select shader
+		WHBGfxShaderGroup *shader = colour_key ? &shader_group_texture_colour_key : &shader_group_texture;
+
+		// Bind it
+		GX2SetFetchShader(&shader->fetchShader);
+		GX2SetVertexShader(shader->vertexShader);
+		GX2SetPixelShader(shader->pixelShader);
+
+		// Set shader uniforms
+		const float vertex_coordinate_transform[4] = {2.0f / destination_surface->texture.surface.width, -2.0f / destination_surface->texture.surface.height, 1.0f, 1.0f};
+		GX2SetVertexUniformReg(shader_group_glyph.vertexShader->uniformVars[0].offset, 4, (uint32_t*)vertex_coordinate_transform);
+
+		const float texture_coordinate_transform[4] = {1.0f / source_surface->texture.surface.width, 1.0f / source_surface->texture.surface.height, 1.0f, 1.0f};
+		GX2SetVertexUniformReg(shader_group_glyph.vertexShader->uniformVars[1].offset, 4, (uint32_t*)texture_coordinate_transform);
+
+		// Bind misc. data
+		GX2SetPixelSampler(sampler, shader->pixelShader->samplerVars[0].location);
+		GX2SetPixelTexture(&source_surface->texture, shader->pixelShader->samplerVars[0].location);
+
+		// Disable blending
+		GX2SetColorControl(GX2_LOGIC_OP_COPY, 0, FALSE, TRUE);
+	}
+
+	VertexBufferSlot *vertex_buffer_slot = GetVertexBufferSlot();
+
+	if (vertex_buffer_slot != NULL)
+	{
+		// Set vertex position buffer
+		const float vertex_left = destination_rect->left;
+		const float vertex_top = destination_rect->top;
+		const float vertex_right = destination_rect->right;
+		const float vertex_bottom = destination_rect->bottom;
+
+		vertex_buffer_slot->vertices[0].position.x = vertex_left;
+		vertex_buffer_slot->vertices[0].position.y = vertex_top;
+		vertex_buffer_slot->vertices[1].position.x = vertex_right;
+		vertex_buffer_slot->vertices[1].position.y = vertex_top;
+		vertex_buffer_slot->vertices[2].position.x = vertex_right;
+		vertex_buffer_slot->vertices[2].position.y = vertex_bottom;
+		vertex_buffer_slot->vertices[3].position.x = vertex_left;
+		vertex_buffer_slot->vertices[3].position.y = vertex_bottom;
+
+		const float texture_left = source_rect->left;
+		const float texture_top = source_rect->top;
+		const float texture_right = source_rect->right;
+		const float texture_bottom = source_rect->bottom;
+
+		// Set texture coordinate buffer
+		vertex_buffer_slot->vertices[0].texture.x = texture_left;
+		vertex_buffer_slot->vertices[0].texture.y = texture_top;
+		vertex_buffer_slot->vertices[1].texture.x = texture_right;
+		vertex_buffer_slot->vertices[1].texture.y = texture_top;
+		vertex_buffer_slot->vertices[2].texture.x = texture_right;
+		vertex_buffer_slot->vertices[2].texture.y = texture_bottom;
+		vertex_buffer_slot->vertices[3].texture.x = texture_left;
+		vertex_buffer_slot->vertices[3].texture.y = texture_bottom;
+	}
+}
+
 RenderBackend_Surface* RenderBackend_Init(const char *window_title, size_t screen_width, size_t screen_height, bool fullscreen)
 {
 	(void)window_title;
@@ -195,8 +273,9 @@
 						WHBGfxInitShaderAttribute(&shader_group_glyph, "input_texture_coordinates", 1, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
 						WHBGfxInitFetchShader(&shader_group_glyph);
 
-						// Initialise sampler
-						GX2InitSampler(&sampler, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_LINEAR);
+						// Initialise samplers
+						GX2InitSampler(&sampler_point, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_POINT);
+						GX2InitSampler(&sampler_linear, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_LINEAR);
 
 						// Initialise vertex buffer
 						vertex_buffer.flags = (GX2RResourceFlags)(GX2R_RESOURCE_BIND_VERTEX_BUFFER |
@@ -366,7 +445,7 @@
 	GX2SetVertexUniformReg(shader_group_texture.vertexShader->uniformVars[1].offset, 4, (uint32_t*)plain_vec4);
 
 	// Bind a few things
-	GX2SetPixelSampler(&sampler, shader_group_texture.pixelShader->samplerVars[0].location);
+	GX2SetPixelSampler(&sampler_point, shader_group_texture.pixelShader->samplerVars[0].location);
 	GX2SetPixelTexture(&framebuffer_surface->texture, shader_group_texture.pixelShader->samplerVars[0].location);
 	GX2RSetAttributeBuffer(&vertex_buffer, 0, sizeof(Vertex), offsetof(Vertex, position));
 	GX2RSetAttributeBuffer(&vertex_buffer, 1, sizeof(Vertex), offsetof(Vertex, texture));
@@ -396,7 +475,7 @@
 	GX2SetVertexUniformReg(shader_group_texture.vertexShader->uniformVars[1].offset, 4, (uint32_t*)plain_vec4);
 
 	// Bind a few things
-	GX2SetPixelSampler(&sampler, shader_group_texture.pixelShader->samplerVars[0].location);
+	GX2SetPixelSampler(&sampler_point, shader_group_texture.pixelShader->samplerVars[0].location);
 	GX2SetPixelTexture(&framebuffer_surface->texture, shader_group_texture.pixelShader->samplerVars[0].location);
 	GX2RSetAttributeBuffer(&vertex_buffer, 0, sizeof(Vertex), offsetof(Vertex, position));
 	GX2RSetAttributeBuffer(&vertex_buffer, 1, sizeof(Vertex), offsetof(Vertex, texture));
@@ -541,79 +620,9 @@
 
 void RenderBackend_Blit(RenderBackend_Surface *source_surface, const RenderBackend_Rect *rect, RenderBackend_Surface *destination_surface, long x, long y, bool colour_key)
 {
-	const RenderMode render_mode = (colour_key ? MODE_DRAW_SURFACE_WITH_TRANSPARENCY : MODE_DRAW_SURFACE);
+	RenderBackend_Rect destination_rect = {x, y, x + (rect->right - rect->left), y + (rect->bottom - rect->top)};
 
-	// Flush vertex data if a context-change is needed
-	if (last_render_mode != render_mode || last_source_texture != &source_surface->texture || last_destination_texture != &destination_surface->texture)
-	{
-		FlushVertexBuffer();
-
-		last_render_mode = render_mode;
-		last_source_texture = &source_surface->texture;
-		last_destination_texture = &destination_surface->texture;
-
-		// Draw to the selected texture, instead of the screen
-		GX2SetColorBuffer(&destination_surface->colour_buffer, GX2_RENDER_TARGET_0);
-		GX2SetViewport(0.0f, 0.0f, (float)destination_surface->colour_buffer.surface.width, (float)destination_surface->colour_buffer.surface.height, 0.0f, 1.0f);
-		GX2SetScissor(0, 0, destination_surface->colour_buffer.surface.width, destination_surface->colour_buffer.surface.height);
-
-		// Select shader
-		WHBGfxShaderGroup *shader = colour_key ? &shader_group_texture_colour_key : &shader_group_texture;
-
-		// Bind it
-		GX2SetFetchShader(&shader->fetchShader);
-		GX2SetVertexShader(shader->vertexShader);
-		GX2SetPixelShader(shader->pixelShader);
-
-		// Set shader uniforms
-		const float vertex_coordinate_transform[4] = {2.0f / destination_surface->texture.surface.width, -2.0f / destination_surface->texture.surface.height, 1.0f, 1.0f};
-		GX2SetVertexUniformReg(shader_group_glyph.vertexShader->uniformVars[0].offset, 4, (uint32_t*)vertex_coordinate_transform);
-
-		const float texture_coordinate_transform[4] = {1.0f / source_surface->texture.surface.width, 1.0f / source_surface->texture.surface.height, 1.0f, 1.0f};
-		GX2SetVertexUniformReg(shader_group_glyph.vertexShader->uniformVars[1].offset, 4, (uint32_t*)texture_coordinate_transform);
-
-		// Bind misc. data
-		GX2SetPixelSampler(&sampler, shader->pixelShader->samplerVars[0].location);
-		GX2SetPixelTexture(&source_surface->texture, shader->pixelShader->samplerVars[0].location);
-
-		// Disable blending
-		GX2SetColorControl(GX2_LOGIC_OP_COPY, 0, FALSE, TRUE);
-	}
-
-	VertexBufferSlot *vertex_buffer_slot = GetVertexBufferSlot();
-
-	if (vertex_buffer_slot != NULL)
-	{
-		// Set vertex position buffer
-		const float vertex_left = x;
-		const float vertex_top = y;
-		const float vertex_right = x + (rect->right - rect->left);
-		const float vertex_bottom = y + (rect->bottom - rect->top);
-
-		vertex_buffer_slot->vertices[0].position.x = vertex_left;
-		vertex_buffer_slot->vertices[0].position.y = vertex_top;
-		vertex_buffer_slot->vertices[1].position.x = vertex_right;
-		vertex_buffer_slot->vertices[1].position.y = vertex_top;
-		vertex_buffer_slot->vertices[2].position.x = vertex_right;
-		vertex_buffer_slot->vertices[2].position.y = vertex_bottom;
-		vertex_buffer_slot->vertices[3].position.x = vertex_left;
-		vertex_buffer_slot->vertices[3].position.y = vertex_bottom;
-
-		const float texture_left = rect->left;
-		const float texture_top = rect->top;
-		const float texture_right = rect->right;
-		const float texture_bottom = rect->bottom;
-
-		// Set texture coordinate buffer
-		vertex_buffer_slot->vertices[0].texture.x = texture_left;
-		vertex_buffer_slot->vertices[0].texture.y = texture_top;
-		vertex_buffer_slot->vertices[1].texture.x = texture_right;
-		vertex_buffer_slot->vertices[1].texture.y = texture_top;
-		vertex_buffer_slot->vertices[2].texture.x = texture_right;
-		vertex_buffer_slot->vertices[2].texture.y = texture_bottom;
-		vertex_buffer_slot->vertices[3].texture.x = texture_left;
-		vertex_buffer_slot->vertices[3].texture.y = texture_bottom;
-	}
+	Blit(source_surface, rect, destination_surface, &destination_rect, colour_key, &sampler_point);
 }
 
 void RenderBackend_ColourFill(RenderBackend_Surface *surface, const RenderBackend_Rect *rect, unsigned char red, unsigned char green, unsigned char blue)
@@ -777,7 +786,7 @@
 		GX2SetPixelUniformReg(shader_group_glyph.pixelShader->uniformVars[0].offset, 4, (uint32_t*)&uniform_colours);
 
 		// Bind misc. data
-		GX2SetPixelSampler(&sampler, shader_group_glyph.pixelShader->samplerVars[0].location);
+		GX2SetPixelSampler(&sampler_point, shader_group_glyph.pixelShader->samplerVars[0].location);
 		GX2SetPixelTexture(&atlas->texture, shader_group_glyph.pixelShader->samplerVars[0].location);
 
 		// Enable blending