From a5394fca8916d3ada33023b86f728834968865b5 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Thu, 24 Jan 2019 17:03:08 +1100 Subject: [PATCH 01/25] wiiu: first attempt at using the render driver instead of WindowFramebuffer --- src/render/wiiu/SDL_rdraw_wiiu.c | 4 +- src/render/wiiu/SDL_render_wiiu.c | 17 +++--- src/render/wiiu/SDL_render_wiiu.h | 1 + src/render/wiiu/SDL_rpresent_wiiu.c | 89 +++++++++++++++++++++++++++++ src/video/wiiu/SDL_wiiuvideo.c | 6 +- 5 files changed, 104 insertions(+), 13 deletions(-) create mode 100644 src/render/wiiu/SDL_rpresent_wiiu.c diff --git a/src/render/wiiu/SDL_rdraw_wiiu.c b/src/render/wiiu/SDL_rdraw_wiiu.c index dd79fd1b1..9f2de1273 100644 --- a/src/render/wiiu/SDL_rdraw_wiiu.c +++ b/src/render/wiiu/SDL_rdraw_wiiu.c @@ -259,7 +259,7 @@ int WIIU_SDL_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, i return 0; } -void WIIU_SDL_RenderPresent(SDL_Renderer * renderer) +/*void WIIU_SDL_RenderPresent(SDL_Renderer * renderer) { WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; SDL_Window *window = renderer->window; @@ -273,7 +273,7 @@ void WIIU_SDL_RenderPresent(SDL_Renderer * renderer) } WIIU_FreeRenderData(data); -} +}*/ int WIIU_SDL_RenderClear(SDL_Renderer * renderer) { diff --git a/src/render/wiiu/SDL_render_wiiu.c b/src/render/wiiu/SDL_render_wiiu.c index 44dbbb8f9..5bc88ec3c 100644 --- a/src/render/wiiu/SDL_render_wiiu.c +++ b/src/render/wiiu/SDL_render_wiiu.c @@ -42,15 +42,9 @@ SDL_RenderDriver WIIU_RenderDriver; SDL_Renderer *WIIU_SDL_CreateRenderer(SDL_Window * window, Uint32 flags) { - SDL_Surface *surface; SDL_Renderer *renderer; WIIU_RenderData *data; - surface = SDL_GetWindowSurface(window); - if (!surface) { - return NULL; - } - renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); if (!renderer) { SDL_OutOfMemory(); @@ -108,6 +102,13 @@ SDL_Renderer *WIIU_SDL_CreateRenderer(SDL_Window * window, Uint32 flags) memset(data->ctx, 0, sizeof(GX2ContextState)); GX2SetupContextStateEx(data->ctx, TRUE); + // Allocate a buffer for the window + data->windowTex = (SDL_Texture) { + .format = SDL_PIXELFORMAT_RGBA8888, + }; + SDL_GetWindowSize(window, &data->windowTex.w, &data->windowTex.h); + WIIU_SDL_CreateTexture(renderer, &data->windowTex); + // Setup colour buffer, rendering to the window WIIU_SDL_SetRenderTarget(renderer, NULL); @@ -126,8 +127,8 @@ int WIIU_SDL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) target = &tdata->texture.surface; } else { // Set window texture as target - WIIU_WindowData *wdata = (WIIU_WindowData *) SDL_GetWindowData(renderer->window, WIIU_WINDOW_DATA); - target = &wdata->texture.surface; + WIIU_TextureData *tdata = (WIIU_TextureData *) data->windowTex.driverdata; + target = &tdata->texture.surface; } // Update color buffer diff --git a/src/render/wiiu/SDL_render_wiiu.h b/src/render/wiiu/SDL_render_wiiu.h index 22726e7da..77a5e5a64 100644 --- a/src/render/wiiu/SDL_render_wiiu.h +++ b/src/render/wiiu/SDL_render_wiiu.h @@ -43,6 +43,7 @@ typedef struct GX2ContextState *ctx; WIIU_RenderAllocData *listfree; float u_viewSize[4]; + SDL_Texture windowTex; } WIIU_RenderData; typedef struct diff --git a/src/render/wiiu/SDL_rpresent_wiiu.c b/src/render/wiiu/SDL_rpresent_wiiu.c new file mode 100644 index 000000000..36b991429 --- /dev/null +++ b/src/render/wiiu/SDL_rpresent_wiiu.c @@ -0,0 +1,89 @@ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_RENDER_WIIU + +#include "../../video/wiiu/SDL_wiiuvideo.h" +#include "../../video/wiiu/wiiu_shaders.h" +#include "../SDL_sysrender.h" +#include "SDL_hints.h" +#include "SDL_render_wiiu.h" + +#include +#include +#include + +#define SCREEN_WIDTH 1280 +#define SCREEN_HEIGHT 720 + +static const float u_viewSize[4] = {(float)SCREEN_WIDTH, (float)SCREEN_HEIGHT}; +static const float u_mod[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + +//TODO +static const float a_position[2 * 4] = { + 0.0f, 0.0f, + 1280.0f, 0.0f, + 1280.0f, 720.0f, + 0.0f, 720.0f, +}; + +static const float a_texCoorssd[] = +{ + 0.0f, (float)SCREEN_HEIGHT, + (float)SCREEN_WIDTH, (float)SCREEN_HEIGHT, + (float)SCREEN_WIDTH, 0.0f, + 0.0f, 0.0f, +}; + +static void render_scene(WIIU_RenderData *data) { + WIIU_TextureData *tdata = (WIIU_TextureData *) data->windowTex.driverdata; + float tex_w = tdata->u_texSize[0]; + float tex_h = tdata->u_texSize[1]; + + float* a_texCoord = WIIU_AllocRenderData(data, sizeof(float) * 2 * 4); + float a_texCoord_vals[] = { + 0.0f, tex_h, + tex_w, tex_h, + tex_w, 0.0f, + 0.0f, 0.0f, + }; + memcpy(a_texCoord, a_texCoord_vals, sizeof(float) * 2 * 4); + + WHBGfxClearColor(0.0f, 0.0f, 0.0f, 1.0f); + wiiuSetTextureShader(); + + GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)u_viewSize); + GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[1].offset, 4, (uint32_t *)tdata->u_texSize); + GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)u_mod); + + GX2SetAttribBuffer(0, sizeof(float) * 8, sizeof(float) * 2, (void*)a_position); + GX2SetAttribBuffer(1, sizeof(float) * 8, sizeof(float) * 2, (void*)a_texCoord); + + GX2SetPixelTexture(&tdata->texture, wiiuTextureShader.pixelShader->samplerVars[0].location); + GX2SetPixelSampler(&tdata->sampler, wiiuTextureShader.pixelShader->samplerVars[0].location); + + GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1); +} + +void WIIU_SDL_RenderPresent(SDL_Renderer * renderer) +{ + WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; + //SDL_Window *window = renderer->window; + + //GX2Flush(); + + WHBGfxBeginRender(); + + WHBGfxBeginRenderTV(); + render_scene(data); + WHBGfxFinishRenderTV(); + + WHBGfxBeginRenderDRC(); + render_scene(data); + WHBGfxFinishRenderDRC(); + + WHBGfxFinishRender(); + + WIIU_FreeRenderData(data); +} + +#endif //SDL_VIDEO_RENDER_WIIU diff --git a/src/video/wiiu/SDL_wiiuvideo.c b/src/video/wiiu/SDL_wiiuvideo.c index 6a8392de7..3ba8abaab 100644 --- a/src/video/wiiu/SDL_wiiuvideo.c +++ b/src/video/wiiu/SDL_wiiuvideo.c @@ -275,9 +275,9 @@ static SDL_VideoDevice *WIIU_CreateDevice(int devindex) device->VideoQuit = WIIU_VideoQuit; device->SetDisplayMode = WIIU_SetDisplayMode; device->PumpEvents = WIIU_PumpEvents; - device->CreateWindowFramebuffer = WIIU_CreateWindowFramebuffer; - device->UpdateWindowFramebuffer = WIIU_UpdateWindowFramebuffer; - device->DestroyWindowFramebuffer = WIIU_DestroyWindowFramebuffer; + //device->CreateWindowFramebuffer = WIIU_CreateWindowFramebuffer; + //device->UpdateWindowFramebuffer = WIIU_UpdateWindowFramebuffer; + //device->DestroyWindowFramebuffer = WIIU_DestroyWindowFramebuffer; device->free = WIIU_DeleteDevice; From 019a3fe80975ae6bee4431d6b2640b9d28f2aff7 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Wed, 20 Feb 2019 21:44:15 +1100 Subject: [PATCH 02/25] video/wiiu: Call SDL_SetKeyboardFocus on window creation --- src/video/wiiu/SDL_wiiuvideo.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/video/wiiu/SDL_wiiuvideo.c b/src/video/wiiu/SDL_wiiuvideo.c index 3ba8abaab..fa8a16383 100644 --- a/src/video/wiiu/SDL_wiiuvideo.c +++ b/src/video/wiiu/SDL_wiiuvideo.c @@ -242,6 +242,11 @@ static void WIIU_DestroyWindowFramebuffer(_THIS, SDL_Window *window) SDL_free(data); } +static int WIIU_CreateSDLWindow(_THIS, SDL_Window *window) { + SDL_SetKeyboardFocus(window); + return 0; +} + static int WIIU_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode) { return 0; @@ -275,6 +280,7 @@ static SDL_VideoDevice *WIIU_CreateDevice(int devindex) device->VideoQuit = WIIU_VideoQuit; device->SetDisplayMode = WIIU_SetDisplayMode; device->PumpEvents = WIIU_PumpEvents; + device->CreateSDLWindow = WIIU_CreateSDLWindow; //device->CreateWindowFramebuffer = WIIU_CreateWindowFramebuffer; //device->UpdateWindowFramebuffer = WIIU_UpdateWindowFramebuffer; //device->DestroyWindowFramebuffer = WIIU_DestroyWindowFramebuffer; From e53b835d790bb75d9e1a39381b52a96f70319ff0 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Wed, 20 Feb 2019 22:37:39 +1100 Subject: [PATCH 03/25] render/wiiu: FLUSH THE CACHE. FLUSH THE CACHE. --- src/render/wiiu/SDL_rpresent_wiiu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/render/wiiu/SDL_rpresent_wiiu.c b/src/render/wiiu/SDL_rpresent_wiiu.c index 36b991429..32d280119 100644 --- a/src/render/wiiu/SDL_rpresent_wiiu.c +++ b/src/render/wiiu/SDL_rpresent_wiiu.c @@ -47,6 +47,7 @@ static void render_scene(WIIU_RenderData *data) { 0.0f, 0.0f, }; memcpy(a_texCoord, a_texCoord_vals, sizeof(float) * 2 * 4); + GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, a_texCoord, sizeof(float) * 2 * 4); WHBGfxClearColor(0.0f, 0.0f, 0.0f, 1.0f); wiiuSetTextureShader(); From 94fca6585d11f02f3c66dc2973dd7e6441ae872c Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Tue, 5 Mar 2019 12:00:41 +1100 Subject: [PATCH 04/25] video/wiiu: Remove the last of the emulated framebuffer --- src/video/wiiu/SDL_wiiuvideo.c | 172 ++------------------------------- 1 file changed, 7 insertions(+), 165 deletions(-) diff --git a/src/video/wiiu/SDL_wiiuvideo.c b/src/video/wiiu/SDL_wiiuvideo.c index fa8a16383..87ad734a7 100644 --- a/src/video/wiiu/SDL_wiiuvideo.c +++ b/src/video/wiiu/SDL_wiiuvideo.c @@ -20,6 +20,13 @@ 3. This notice may not be removed or altered from any source distribution. */ +/* This is basically just a stub at this point - all the magic happens in + * SDL_Render, and the textureframebuffer stuff in SDL_video.c. + * Potentially more could/should be done here, video modes and things. + * Some design work will need to go into the responsibilities of render + * vs video. + */ + #include "../../SDL_internal.h" #if SDL_VIDEO_DRIVER_WIIU @@ -34,16 +41,8 @@ #include "../../events/SDL_keyboard_c.h" #include "SDL_wiiuvideo.h" -#include -#include -#include -#include -#include -#include -#include #include #include -#include #include #include @@ -53,46 +52,13 @@ static int WIIU_VideoInit(_THIS); static int WIIU_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode); static void WIIU_VideoQuit(_THIS); static void WIIU_PumpEvents(_THIS); -static int WIIU_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch); -static int WIIU_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects); -static void WIIU_DestroyWindowFramebuffer(_THIS, SDL_Window *window); #define SCREEN_WIDTH 1280 #define SCREEN_HEIGHT 720 -static const float u_viewSize[4] = {(float)SCREEN_WIDTH, (float)SCREEN_HEIGHT}; -static const float u_texSize[4] = {(float)SCREEN_WIDTH, (float)SCREEN_HEIGHT}; -static const float u_mod[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - -static const float tex_coord_vb[] = -{ - 0.0f, (float)SCREEN_HEIGHT, - (float)SCREEN_WIDTH, (float)SCREEN_HEIGHT, - (float)SCREEN_WIDTH, 0.0f, - 0.0f, 0.0f, -}; - -static GX2RBuffer tex_coord_buffer = { - GX2R_RESOURCE_BIND_VERTEX_BUFFER | - GX2R_RESOURCE_USAGE_CPU_READ | - GX2R_RESOURCE_USAGE_CPU_WRITE | - GX2R_RESOURCE_USAGE_GPU_READ, - 2 * sizeof(float), 4, NULL -}; -static GX2RBuffer position_buffer = { - GX2R_RESOURCE_BIND_VERTEX_BUFFER | - GX2R_RESOURCE_USAGE_CPU_READ | - GX2R_RESOURCE_USAGE_CPU_WRITE | - GX2R_RESOURCE_USAGE_GPU_READ, - 2 * sizeof(float), 4, NULL -}; - -static GX2Sampler sampler = {0}; - static int WIIU_VideoInit(_THIS) { SDL_DisplayMode mode; - void *buffer = NULL; WHBProcInit(); WHBGfxInit(); @@ -100,20 +66,6 @@ static int WIIU_VideoInit(_THIS) // setup shader wiiuInitTextureShader(); - // setup vertex position attribute - GX2RCreateBuffer(&position_buffer); - - // setup vertex texture coordinates attribute - GX2RCreateBuffer(&tex_coord_buffer); - buffer = GX2RLockBufferEx(&tex_coord_buffer, 0); - if (buffer) { - memcpy(buffer, tex_coord_vb, tex_coord_buffer.elemSize * tex_coord_buffer.elemCount); - } - GX2RUnlockBufferEx(&tex_coord_buffer, 0); - - // initialize a sampler - GX2InitSampler(&sampler, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_LINEAR); - // add default mode (1280x720) mode.format = SDL_PIXELFORMAT_RGBA8888; mode.w = SCREEN_WIDTH; @@ -130,118 +82,11 @@ static int WIIU_VideoInit(_THIS) static void WIIU_VideoQuit(_THIS) { - GX2RDestroyBufferEx(&position_buffer, 0); - GX2RDestroyBufferEx(&tex_coord_buffer, 0); wiiuFreeTextureShader(); WHBGfxShutdown(); WHBProcShutdown(); } -static int WIIU_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch) -{ - WIIU_WindowData *data; - - // hold a pointer to our stuff - data = SDL_calloc(1, sizeof(WIIU_WindowData)); - - // create a gx2 texture - data->texture.surface.use = GX2_SURFACE_USE_TEXTURE; - data->texture.surface.width = window->w; - data->texture.surface.height = window->h; - data->texture.surface.dim = GX2_SURFACE_DIM_TEXTURE_2D; - data->texture.surface.depth = 1; - data->texture.surface.mipLevels = 1; - data->texture.surface.format = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8; - data->texture.surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED; - data->texture.viewNumSlices = 1; - data->texture.viewNumMips = 1; - data->texture.compMap = 0x00010203; - GX2CalcSurfaceSizeAndAlignment(&data->texture.surface); - GX2InitTextureRegs(&data->texture); - - data->texture.surface.image = MEMAllocFromDefaultHeapEx(data->texture.surface.imageSize, data->texture.surface.alignment); - - // create sdl surface framebuffer - data->surface = SDL_CreateRGBSurfaceWithFormatFrom( - data->texture.surface.image, // pixels - window->w, window->h, // width, height - 32, window->w * 4, // depth, pitch - SDL_PIXELFORMAT_RGBA8888 // format - ); - - *format = SDL_PIXELFORMAT_RGBA8888; - *pixels = data->surface->pixels; - *pitch = data->surface->pitch; - - SDL_SetWindowData(window, WIIU_WINDOW_DATA, data); - - // inform SDL we're ready to accept inputs - SDL_SetKeyboardFocus(window); - - return 0; -} - -static void render_scene(WIIU_WindowData *data) { - WHBGfxClearColor(0.0f, 0.0f, 0.0f, 1.0f); - wiiuSetTextureShader(); - - GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)u_viewSize); - GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[1].offset, 4, (uint32_t *)u_texSize); - GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)u_mod); - GX2RSetAttributeBuffer(&position_buffer, 0, position_buffer.elemSize, 0); - GX2RSetAttributeBuffer(&tex_coord_buffer, 1, tex_coord_buffer.elemSize, 0); - - GX2SetPixelTexture(&data->texture, wiiuTextureShader.pixelShader->samplerVars[0].location); - GX2SetPixelSampler(&sampler, wiiuTextureShader.pixelShader->samplerVars[0].location); - - GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1); -} - -static int WIIU_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects) -{ - WIIU_WindowData *data = (WIIU_WindowData *) SDL_GetWindowData(window, WIIU_WINDOW_DATA); - float a_position[8]; - float* buffer; - int x, y, w, h; - - SDL_GetWindowPosition(window, &x, &y); - SDL_GetWindowSize(window, &w, &h); - a_position[0] = (float)x; a_position[1] = (float)y; - a_position[2] = (float)(x + w); a_position[3] = (float)y; - a_position[4] = (float)(x + w); a_position[5] = (float)(y + h); - a_position[6] = (float)x; a_position[7] = (float)(y + h); - - buffer = GX2RLockBufferEx(&position_buffer, 0); - if (buffer) { - memcpy(buffer, a_position, position_buffer.elemSize * position_buffer.elemCount); - } - GX2RUnlockBufferEx(&position_buffer, 0); - - GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, data->texture.surface.image, data->texture.surface.imageSize); - - WHBGfxBeginRender(); - - WHBGfxBeginRenderTV(); - render_scene(data); - WHBGfxFinishRenderTV(); - - WHBGfxBeginRenderDRC(); - render_scene(data); - WHBGfxFinishRenderDRC(); - - WHBGfxFinishRender(); - - return 0; -} - -static void WIIU_DestroyWindowFramebuffer(_THIS, SDL_Window *window) -{ - WIIU_WindowData *data = (WIIU_WindowData*) SDL_GetWindowData(window, WIIU_WINDOW_DATA); - SDL_FreeSurface(data->surface); - MEMFreeToDefaultHeap(data->texture.surface.image); - SDL_free(data); -} - static int WIIU_CreateSDLWindow(_THIS, SDL_Window *window) { SDL_SetKeyboardFocus(window); return 0; @@ -281,9 +126,6 @@ static SDL_VideoDevice *WIIU_CreateDevice(int devindex) device->SetDisplayMode = WIIU_SetDisplayMode; device->PumpEvents = WIIU_PumpEvents; device->CreateSDLWindow = WIIU_CreateSDLWindow; - //device->CreateWindowFramebuffer = WIIU_CreateWindowFramebuffer; - //device->UpdateWindowFramebuffer = WIIU_UpdateWindowFramebuffer; - //device->DestroyWindowFramebuffer = WIIU_DestroyWindowFramebuffer; device->free = WIIU_DeleteDevice; From 602abdeca056abd69d97ec0329e10c623c239397 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Tue, 5 Mar 2019 13:07:53 +1100 Subject: [PATCH 05/25] render/wiiu: Use GX2R for texture surfaces Untested at time of commit, hopefully it works hehe --- src/render/wiiu/SDL_rtexture_wiiu.c | 64 +++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/src/render/wiiu/SDL_rtexture_wiiu.c b/src/render/wiiu/SDL_rtexture_wiiu.c index d44338da3..649950c7e 100644 --- a/src/render/wiiu/SDL_rtexture_wiiu.c +++ b/src/render/wiiu/SDL_rtexture_wiiu.c @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include #include @@ -43,6 +45,7 @@ int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) { WIIUPixFmt gx2_fmt; + BOOL res; WIIU_TextureData *tdata = (WIIU_TextureData *) SDL_calloc(1, sizeof(*tdata)); if (!tdata) return SDL_OutOfMemory(); @@ -58,7 +61,8 @@ int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) tdata->texture.surface.depth = 1; //? tdata->texture.surface.dim = GX2_SURFACE_DIM_TEXTURE_2D; tdata->texture.surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED; - tdata->texture.surface.use = GX2_SURFACE_USE_TEXTURE; + tdata->texture.surface.use = + GX2_SURFACE_USE_TEXTURE | GX2_SURFACE_USE_COLOR_BUFFER; tdata->texture.surface.mipLevels = 1; tdata->texture.viewNumMips = 1; tdata->texture.viewNumSlices = 1; @@ -66,15 +70,22 @@ int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) GX2CalcSurfaceSizeAndAlignment(&tdata->texture.surface); GX2InitTextureRegs(&tdata->texture); - tdata->texture.surface.image = memalign(tdata->texture.surface.alignment, tdata->texture.surface.imageSize); - if(!tdata->texture.surface.image) - { +/* Allocate the texture's surface */ + res = GX2RCreateSurface( + &tdata->texture.surface, + GX2R_RESOURCE_BIND_TEXTURE | GX2R_RESOURCE_BIND_COLOR_BUFFER + ); + if (!res) { SDL_free(tdata); return SDL_OutOfMemory(); } tdata->u_texSize[0] = texture->w; tdata->u_texSize[1] = texture->h; + GX2Invalidate( + GX2_INVALIDATE_MODE_CPU, + &tdata->u_texSize, sizeof(tdata->u_texSize) + ); texture->driverdata = tdata; @@ -83,15 +94,27 @@ int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) // Somewhat adapted from SDL_render.c: SDL_LockTextureNative // The app basically wants a pointer to a particular rectangle as well as -// write access to it. We can do that without any special graphics code +// write access to it. Easy GX2R! int WIIU_SDL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, void **pixels, int *pitch) { WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata; Uint32 BytesPerPixel = SDL_BYTESPERPIXEL(texture->format); + void* pixel_buffer; + + pixel_buffer = GX2RLockSurfaceEx( + &tdata->texture.surface, + 0, //mipmap level? + GX2R_RESOURCE_USAGE_CPU_READ | GX2R_RESOURCE_USAGE_CPU_WRITE + ); + if (!pixel_buffer) { + //TODO real error handling + printf("SDL: Couldn't lock surface for texture!\n"); + return -1; + } // Calculate pointer to first pixel in rect - *pixels = (void *) ((Uint8 *) tdata->texture.surface.image + + *pixels = (void *) ((Uint8 *) pixel_buffer + rect->y * (tdata->texture.surface.pitch * BytesPerPixel) + rect->x * BytesPerPixel); *pitch = (tdata->texture.surface.pitch * BytesPerPixel); @@ -104,34 +127,37 @@ int WIIU_SDL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, void WIIU_SDL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) { WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata; - // TODO check this is actually needed - GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, - tdata->texture.surface.image, tdata->texture.surface.imageSize); + + GX2RUnlockSurfaceEx(&tdata->texture.surface, 0, 0); } int WIIU_SDL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch) { - WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata; Uint32 BytesPerPixel; Uint8 *src, *dst; - int row; + int row, dst_pitch, rc; size_t length; BytesPerPixel = SDL_BYTESPERPIXEL(texture->format); src = (Uint8 *) pixels; - dst = (Uint8 *) tdata->texture.surface.image + - rect->y * (tdata->texture.surface.pitch * BytesPerPixel) + - rect->x * BytesPerPixel; length = rect->w * BytesPerPixel; + +/* We write the rules, and we say all textures are streaming */ + rc = WIIU_SDL_LockTexture( + renderer, texture, rect, (void**)&dst, &dst_pitch + ); + if (rc < 0) { + return rc; + } + for (row = 0; row < rect->h; ++row) { SDL_memcpy(dst, src, length); src += pitch; - dst += (tdata->texture.surface.pitch * BytesPerPixel); + dst += dst_pitch; } - GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, - tdata->texture.surface.image, tdata->texture.surface.imageSize); + WIIU_SDL_UnlockTexture(renderer, texture); return 0; } @@ -140,8 +166,10 @@ void WIIU_SDL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) { WIIU_TextureData *tdata; if (texture == NULL || texture->driverdata == NULL) return; + tdata = (WIIU_TextureData *) texture->driverdata; - free(tdata->texture.surface.image); + GX2RDestroySurfaceEx(&tdata->texture.surface, 0); + SDL_free(tdata); } From 78b4e47f6c7e2a8510f5ed5964f89847929902dd Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Tue, 5 Mar 2019 22:27:13 +1100 Subject: [PATCH 06/25] render/wiiu: Convert RenderData to use GX2RBuffers --- src/render/wiiu/SDL_rdraw_wiiu.c | 195 +++++++++++++++++++--------- src/render/wiiu/SDL_render_wiiu.h | 19 ++- src/render/wiiu/SDL_rpresent_wiiu.c | 79 +++++++---- 3 files changed, 200 insertions(+), 93 deletions(-) diff --git a/src/render/wiiu/SDL_rdraw_wiiu.c b/src/render/wiiu/SDL_rdraw_wiiu.c index 9f2de1273..45aaeb0d7 100644 --- a/src/render/wiiu/SDL_rdraw_wiiu.c +++ b/src/render/wiiu/SDL_rdraw_wiiu.c @@ -53,27 +53,48 @@ int WIIU_SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, { WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata; - float *a_position = WIIU_AllocRenderData(data, sizeof(float) * 8); - float *a_texCoord = WIIU_AllocRenderData(data, sizeof(float) * 8); - float *u_mod = WIIU_AllocRenderData(data, sizeof(float) * 4); + GX2RBuffer *a_position, *a_texCoord; + float *a_position_vals, *a_texCoord_vals; + float u_mod[4]; + float x_min, y_min, x_max, y_max; - /* Compute vertex points */ - float x_min = renderer->viewport.x + dstrect->x; - float y_min = renderer->viewport.y + dstrect->y; - float x_max = renderer->viewport.x + dstrect->x + dstrect->w; - float y_max = renderer->viewport.y + dstrect->y + dstrect->h; - a_position[0] = x_min; a_position[1] = y_min; - a_position[2] = x_max; a_position[3] = y_min; - a_position[4] = x_max; a_position[5] = y_max; - a_position[6] = x_min; a_position[7] = y_max; - GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, a_position, sizeof(float) * 8); +/* Allocate attribute buffers */ + a_position = WIIU_AllocRenderData(data, (GX2RBuffer) { + .flags = + GX2R_RESOURCE_BIND_VERTEX_BUFFER | + GX2R_RESOURCE_USAGE_CPU_WRITE, + .elemSize = 2 * sizeof(float), // float x/y for each corner + .elemCount = 4, // 4 corners + }); + a_texCoord = WIIU_AllocRenderData(data, (GX2RBuffer) { + .flags = + GX2R_RESOURCE_BIND_VERTEX_BUFFER | + GX2R_RESOURCE_USAGE_CPU_WRITE, + .elemSize = 2 * sizeof(float), // float x/y for each corner + .elemCount = 4, // 4 corners + }); - /* Compute texture coords */ - a_texCoord[0] = srcrect->x; a_texCoord[1] = srcrect->y + srcrect->h; - a_texCoord[2] = srcrect->x + srcrect->w; a_texCoord[3] = srcrect->y + srcrect->h; - a_texCoord[4] = srcrect->x + srcrect->w; a_texCoord[5] = srcrect->y; - a_texCoord[6] = srcrect->x; a_texCoord[7] = srcrect->y; - GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, a_texCoord, sizeof(float) * 8); +/* Compute vertex points */ + x_min = renderer->viewport.x + dstrect->x; + y_min = renderer->viewport.y + dstrect->y; + x_max = renderer->viewport.x + dstrect->x + dstrect->w; + y_max = renderer->viewport.y + dstrect->y + dstrect->h; + +/* Save them */ + a_position_vals = GX2RLockBufferEx(a_position, 0); + a_position_vals[0] = x_min; a_position_vals[1] = y_min; + a_position_vals[2] = x_max; a_position_vals[3] = y_min; + a_position_vals[4] = x_max; a_position_vals[5] = y_max; + a_position_vals[6] = x_min; a_position_vals[7] = y_max; + GX2RUnlockBufferEx(a_position, 0); + +/* Compute texture coords */ + a_texCoord_vals = GX2RLockBufferEx(a_texCoord, 0); + a_texCoord_vals[0] = srcrect->x; a_texCoord_vals[1] = srcrect->y + srcrect->h; + a_texCoord_vals[2] = srcrect->x + srcrect->w; a_texCoord_vals[3] = srcrect->y + srcrect->h; + a_texCoord_vals[4] = srcrect->x + srcrect->w; a_texCoord_vals[5] = srcrect->y; + a_texCoord_vals[6] = srcrect->x; a_texCoord_vals[7] = srcrect->y; + GX2RUnlockBufferEx(a_position, 0); /* Compute color/alpha mod */ u_mod[0] = (float)texture->r / 255.0f; @@ -86,8 +107,8 @@ int WIIU_SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, wiiuSetTextureShader(); GX2SetPixelTexture(&tdata->texture, 0); GX2SetPixelSampler(&tdata->sampler, 0); - GX2SetAttribBuffer(0, sizeof(float) * 8, sizeof(float) * 2, a_position); - GX2SetAttribBuffer(1, sizeof(float) * 8, sizeof(float) * 2, a_texCoord); + GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0); + GX2RSetAttributeBuffer(a_texCoord, 1, a_texCoord->elemSize, 0); GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)data->u_viewSize); GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[1].offset, 4, (uint32_t *)tdata->u_texSize); GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)u_mod); @@ -104,9 +125,9 @@ int WIIU_SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, { WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata; - float *a_position = WIIU_AllocRenderData(data, sizeof(float) * 8); - float *a_texCoord = WIIU_AllocRenderData(data, sizeof(float) * 8); - float *u_mod = WIIU_AllocRenderData(data, sizeof(float) * 4); + GX2RBuffer *a_position, *a_texCoord; + float *a_position_vals, *a_texCoord_vals; + float u_mod[4]; /* Compute real vertex points */ float x_min = renderer->viewport.x + dstrect->x; @@ -122,18 +143,38 @@ int WIIU_SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, (flip & SDL_FLIP_HORIZONTAL) ? x_min : x_max, (flip & SDL_FLIP_VERTICAL) ? y_min : y_max, (flip & SDL_FLIP_HORIZONTAL) ? x_max : x_min, (flip & SDL_FLIP_VERTICAL) ? y_min : y_max, }; - for (int i = 0; i < 8; i += 2) { - a_position[i+0] = cx + (SDL_cos(r) * (rvb[i+0] - cx) - SDL_sin(r) * (rvb[i+1] - cy)); - a_position[i+1] = cy + (SDL_cos(r) * (rvb[i+1] - cy) + SDL_sin(r) * (rvb[i+0] - cx)); - } - GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, a_position, sizeof(float) * 8); - /* Compute texture coords */ - a_texCoord[0] = srcrect->x; a_texCoord[1] = srcrect->y + srcrect->h; - a_texCoord[2] = srcrect->x + srcrect->w; a_texCoord[3] = srcrect->y + srcrect->h; - a_texCoord[4] = srcrect->x + srcrect->w; a_texCoord[5] = srcrect->y; - a_texCoord[6] = srcrect->x; a_texCoord[7] = srcrect->y; - GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, a_texCoord, sizeof(float) * 8); + /* Allocate attribute buffers */ + a_position = WIIU_AllocRenderData(data, (GX2RBuffer) { + .flags = + GX2R_RESOURCE_BIND_VERTEX_BUFFER | + GX2R_RESOURCE_USAGE_CPU_WRITE, + .elemSize = 2 * sizeof(float), // float x/y for each corner + .elemCount = 4, // 4 corners + }); + a_texCoord = WIIU_AllocRenderData(data, (GX2RBuffer) { + .flags = + GX2R_RESOURCE_BIND_VERTEX_BUFFER | + GX2R_RESOURCE_USAGE_CPU_WRITE, + .elemSize = 2 * sizeof(float), // float x/y for each corner + .elemCount = 4, // 4 corners + }); + + /* Save vertex points */ + a_position_vals = GX2RLockBufferEx(a_position, 0); + for (int i = 0; i < 8; i += 2) { + a_position_vals[i+0] = cx + (SDL_cos(r) * (rvb[i+0] - cx) - SDL_sin(r) * (rvb[i+1] - cy)); + a_position_vals[i+1] = cy + (SDL_cos(r) * (rvb[i+1] - cy) + SDL_sin(r) * (rvb[i+0] - cx)); + } + GX2RUnlockBufferEx(a_position, 0); + + /* Compute texture coords */ + a_texCoord_vals = GX2RLockBufferEx(a_texCoord, 0); + a_texCoord_vals[0] = srcrect->x; a_texCoord_vals[1] = srcrect->y + srcrect->h; + a_texCoord_vals[2] = srcrect->x + srcrect->w; a_texCoord_vals[3] = srcrect->y + srcrect->h; + a_texCoord_vals[4] = srcrect->x + srcrect->w; a_texCoord_vals[5] = srcrect->y; + a_texCoord_vals[6] = srcrect->x; a_texCoord_vals[7] = srcrect->y; + GX2RUnlockBufferEx(a_position, 0); /* Compute color/alpha mod */ u_mod[0] = (float)texture->r / 255.0f; @@ -146,8 +187,8 @@ int WIIU_SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, wiiuSetTextureShader(); GX2SetPixelTexture(&tdata->texture, 0); GX2SetPixelSampler(&tdata->sampler, 0); - GX2SetAttribBuffer(0, sizeof(float) * 8, sizeof(float) * 2, a_position); - GX2SetAttribBuffer(1, sizeof(float) * 8, sizeof(float) * 2, a_texCoord); + GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0); + GX2RSetAttributeBuffer(a_texCoord, 1, a_texCoord->elemSize, 0); GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)data->u_viewSize); GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[1].offset, 4, (uint32_t *)tdata->u_texSize); GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)u_mod); @@ -161,6 +202,8 @@ int WIIU_SDL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points int count) { WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; + GX2RBuffer *a_position; + float *a_position_vals; /* Compute colors */ float u_color[4] = {(float)renderer->r / 255.0f, @@ -168,18 +211,27 @@ int WIIU_SDL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points (float)renderer->b / 255.0f, (float)renderer->a / 255.0f}; - /* Compute vertex pos */ - float *a_position = WIIU_AllocRenderData(data, sizeof(float) * 2 * count); + /* Allocate attribute buffers */ + a_position = WIIU_AllocRenderData(data, (GX2RBuffer) { + .flags = + GX2R_RESOURCE_BIND_VERTEX_BUFFER | + GX2R_RESOURCE_USAGE_CPU_WRITE, + .elemSize = 2 * sizeof(float), // float x/y for each point + .elemCount = count, + }); + + /* Compute vertex positions */ + a_position_vals = GX2RLockBufferEx(a_position, 0); for (int i = 0; i < count; ++i) { - a_position[i*2+0] = (float)renderer->viewport.x + points[i].x; - a_position[i*2+1] = (float)renderer->viewport.y + points[i].y; + a_position_vals[i*2+0] = (float)renderer->viewport.x + points[i].x; + a_position_vals[i*2+1] = (float)renderer->viewport.y + points[i].y; } - GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, a_position, sizeof(float) * 2 * count); + GX2RUnlockBufferEx(a_position, 0); /* Render points */ GX2SetContextState(data->ctx); wiiuSetColorShader(); - GX2SetAttribBuffer(0, sizeof(float) * 2 * count, sizeof(float) * 2, a_position); + GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0); GX2SetVertexUniformReg(wiiuColorShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)data->u_viewSize); GX2SetPixelUniformReg(wiiuColorShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)u_color); WIIU_SDL_SetGX2BlendMode(renderer->blendMode); @@ -193,6 +245,8 @@ int WIIU_SDL_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; + GX2RBuffer *a_position; + float *a_position_vals; /* Compute colors */ float u_color[4] = {(float)renderer->r / 255.0f, @@ -200,18 +254,27 @@ int WIIU_SDL_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, (float)renderer->b / 255.0f, (float)renderer->a / 255.0f}; - /* Compute vertex pos */ - float *a_position = WIIU_AllocRenderData(data, sizeof(float) * 2 * count); + /* Allocate attribute buffers */ + a_position = WIIU_AllocRenderData(data, (GX2RBuffer) { + .flags = + GX2R_RESOURCE_BIND_VERTEX_BUFFER | + GX2R_RESOURCE_USAGE_CPU_WRITE, + .elemSize = 2 * sizeof(float), // float x/y for each point + .elemCount = count, + }); + + /* Compute vertex positions */ + a_position_vals = GX2RLockBufferEx(a_position, 0); for (int i = 0; i < count; ++i) { - a_position[i*2+0] = (float)renderer->viewport.x + points[i].x; - a_position[i*2+1] = (float)renderer->viewport.y + points[i].y; + a_position_vals[i*2+0] = (float)renderer->viewport.x + points[i].x; + a_position_vals[i*2+1] = (float)renderer->viewport.y + points[i].y; } - GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, a_position, sizeof(float) * 2 * count); + GX2RUnlockBufferEx(a_position, 0); /* Render lines */ GX2SetContextState(data->ctx); wiiuSetColorShader(); - GX2SetAttribBuffer(0, sizeof(float) * 2 * count, sizeof(float) * 2, a_position); + GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0); GX2SetVertexUniformReg(wiiuColorShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)data->u_viewSize); GX2SetPixelUniformReg(wiiuColorShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)u_color); WIIU_SDL_SetGX2BlendMode(renderer->blendMode); @@ -223,6 +286,8 @@ int WIIU_SDL_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, int WIIU_SDL_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count) { WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; + GX2RBuffer *a_position; + float *a_position_vals; /* Compute colors */ float u_color[4] = {(float)renderer->r / 255.0f, @@ -234,23 +299,33 @@ int WIIU_SDL_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, i float vx = (float)renderer->viewport.x; float vy = (float)renderer->viewport.y; - float *a_position = WIIU_AllocRenderData(data, sizeof(float) * 8 * count); + /* Allocate attribute buffers */ + a_position = WIIU_AllocRenderData(data, (GX2RBuffer) { + .flags = + GX2R_RESOURCE_BIND_VERTEX_BUFFER | + GX2R_RESOURCE_USAGE_CPU_WRITE, + .elemSize = 8 * sizeof(float), + .elemCount = count, + }); + + /* Compute vertex positions */ + a_position_vals = GX2RLockBufferEx(a_position, 0); for (int i = 0; i < count; ++i) { - a_position[i*8+0] = vx + rects[i].x; - a_position[i*8+1] = vy + rects[i].y; - a_position[i*8+2] = vx + rects[i].x + rects[i].w; - a_position[i*8+3] = vy + rects[i].y; - a_position[i*8+4] = vx + rects[i].x + rects[i].w; - a_position[i*8+5] = vy + rects[i].y + rects[i].h; - a_position[i*8+6] = vx + rects[i].x; - a_position[i*8+7] = vy + rects[i].y + rects[i].h; + a_position_vals[i*8+0] = vx + rects[i].x; + a_position_vals[i*8+1] = vy + rects[i].y; + a_position_vals[i*8+2] = vx + rects[i].x + rects[i].w; + a_position_vals[i*8+3] = vy + rects[i].y; + a_position_vals[i*8+4] = vx + rects[i].x + rects[i].w; + a_position_vals[i*8+5] = vy + rects[i].y + rects[i].h; + a_position_vals[i*8+6] = vx + rects[i].x; + a_position_vals[i*8+7] = vy + rects[i].y + rects[i].h; } - GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, a_position, sizeof(float) * 8 * count); + GX2RUnlockBufferEx(a_position, 0); /* Render rects */ GX2SetContextState(data->ctx); wiiuSetColorShader(); - GX2SetAttribBuffer(0, sizeof(float) * 8 * count, sizeof(float) * 2, a_position); + GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0); GX2SetVertexUniformReg(wiiuColorShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)data->u_viewSize); GX2SetPixelUniformReg(wiiuColorShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)u_color); WIIU_SDL_SetGX2BlendMode(renderer->blendMode); diff --git a/src/render/wiiu/SDL_render_wiiu.h b/src/render/wiiu/SDL_render_wiiu.h index 77a5e5a64..e66fb166c 100644 --- a/src/render/wiiu/SDL_render_wiiu.h +++ b/src/render/wiiu/SDL_render_wiiu.h @@ -29,11 +29,12 @@ #include "SDL_pixels.h" #include #include +#include typedef struct { void *next; - int ptr[]; + GX2RBuffer buffer; } WIIU_RenderAllocData; //Driver internal data structures @@ -53,17 +54,25 @@ typedef struct float u_texSize[4]; } WIIU_TextureData; -static inline void *WIIU_AllocRenderData(WIIU_RenderData *r, size_t size) { - WIIU_RenderAllocData *rdata = SDL_malloc(sizeof(WIIU_RenderAllocData) + size); +static inline GX2RBuffer* WIIU_AllocRenderData(WIIU_RenderData *r, GX2RBuffer buffer) { + WIIU_RenderAllocData *rdata = SDL_malloc(sizeof(WIIU_RenderAllocData)); + + rdata->buffer = buffer; + if (!GX2RCreateBuffer(&rdata->buffer)) { + SDL_free(rdata); + return 0; + } + rdata->next = r->listfree; r->listfree = rdata; - return (void *)rdata->ptr; + return &rdata->buffer; } static inline void WIIU_FreeRenderData(WIIU_RenderData *r) { while (r->listfree) { - void *ptr = r->listfree; + WIIU_RenderAllocData *ptr = r->listfree; r->listfree = r->listfree->next; + GX2RDestroyBufferEx(&ptr->buffer, 0); SDL_free(ptr); } } diff --git a/src/render/wiiu/SDL_rpresent_wiiu.c b/src/render/wiiu/SDL_rpresent_wiiu.c index 32d280119..bd423f166 100644 --- a/src/render/wiiu/SDL_rpresent_wiiu.c +++ b/src/render/wiiu/SDL_rpresent_wiiu.c @@ -11,43 +11,66 @@ #include #include #include +#include +#include #define SCREEN_WIDTH 1280 #define SCREEN_HEIGHT 720 static const float u_viewSize[4] = {(float)SCREEN_WIDTH, (float)SCREEN_HEIGHT}; -static const float u_mod[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - -//TODO -static const float a_position[2 * 4] = { - 0.0f, 0.0f, - 1280.0f, 0.0f, - 1280.0f, 720.0f, - 0.0f, 720.0f, -}; - -static const float a_texCoorssd[] = -{ - 0.0f, (float)SCREEN_HEIGHT, - (float)SCREEN_WIDTH, (float)SCREEN_HEIGHT, - (float)SCREEN_WIDTH, 0.0f, - 0.0f, 0.0f, -}; static void render_scene(WIIU_RenderData *data) { WIIU_TextureData *tdata = (WIIU_TextureData *) data->windowTex.driverdata; float tex_w = tdata->u_texSize[0]; float tex_h = tdata->u_texSize[1]; + GX2RBuffer *a_position, *a_texCoord; + float *a_position_vals, *a_texCoord_vals; + float u_mod[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - float* a_texCoord = WIIU_AllocRenderData(data, sizeof(float) * 2 * 4); - float a_texCoord_vals[] = { - 0.0f, tex_h, - tex_w, tex_h, - tex_w, 0.0f, - 0.0f, 0.0f, - }; - memcpy(a_texCoord, a_texCoord_vals, sizeof(float) * 2 * 4); - GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, a_texCoord, sizeof(float) * 2 * 4); + /* Allocate attribute buffers */ + a_position = WIIU_AllocRenderData(data, (GX2RBuffer) { + .flags = + GX2R_RESOURCE_BIND_VERTEX_BUFFER | + GX2R_RESOURCE_USAGE_CPU_WRITE, + .elemSize = 2 * sizeof(float), // float x/y for each corner + .elemCount = 4, // 4 corners + }); + a_texCoord = WIIU_AllocRenderData(data, (GX2RBuffer) { + .flags = + GX2R_RESOURCE_BIND_VERTEX_BUFFER | + GX2R_RESOURCE_USAGE_CPU_WRITE, + .elemSize = 2 * sizeof(float), // float x/y for each corner + .elemCount = 4, // 4 corners + }); + +/* Save them */ + a_position_vals = GX2RLockBufferEx(a_position, 0); +/* TODO: not 720p. also, this is legal C? */ + memcpy( + a_position_vals, + (float[]) { + 0.0f, 0.0f, + 1280.0f, 0.0f, + 1280.0f, 720.0f, + 0.0f, 720.0f, + }, + a_position->elemSize * a_position->elemCount + ); + GX2RUnlockBufferEx(a_position, 0); + +/* Compute texture coords */ + a_texCoord_vals = GX2RLockBufferEx(a_texCoord, 0); + memcpy( + a_texCoord_vals, + (float[]) { + 0.0f, tex_h, + tex_w, tex_h, + tex_w, 0.0f, + 0.0f, 0.0f, + }, + a_texCoord->elemSize * a_position->elemCount + ); + GX2RUnlockBufferEx(a_position, 0); WHBGfxClearColor(0.0f, 0.0f, 0.0f, 1.0f); wiiuSetTextureShader(); @@ -56,8 +79,8 @@ static void render_scene(WIIU_RenderData *data) { GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[1].offset, 4, (uint32_t *)tdata->u_texSize); GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)u_mod); - GX2SetAttribBuffer(0, sizeof(float) * 8, sizeof(float) * 2, (void*)a_position); - GX2SetAttribBuffer(1, sizeof(float) * 8, sizeof(float) * 2, (void*)a_texCoord); + GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0); + GX2RSetAttributeBuffer(a_texCoord, 1, a_texCoord->elemSize, 0); GX2SetPixelTexture(&tdata->texture, wiiuTextureShader.pixelShader->samplerVars[0].location); GX2SetPixelSampler(&tdata->sampler, wiiuTextureShader.pixelShader->samplerVars[0].location); From 807a8f2519a9881a0ce0c7c806b3f8d4b922bf99 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Tue, 5 Mar 2019 22:27:45 +1100 Subject: [PATCH 07/25] render/wiiu: Fix resource flags on texture creation --- src/render/wiiu/SDL_rtexture_wiiu.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/render/wiiu/SDL_rtexture_wiiu.c b/src/render/wiiu/SDL_rtexture_wiiu.c index 649950c7e..b656f720b 100644 --- a/src/render/wiiu/SDL_rtexture_wiiu.c +++ b/src/render/wiiu/SDL_rtexture_wiiu.c @@ -73,7 +73,9 @@ int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) /* Allocate the texture's surface */ res = GX2RCreateSurface( &tdata->texture.surface, - GX2R_RESOURCE_BIND_TEXTURE | GX2R_RESOURCE_BIND_COLOR_BUFFER + GX2R_RESOURCE_BIND_TEXTURE | GX2R_RESOURCE_BIND_COLOR_BUFFER | + GX2R_RESOURCE_USAGE_CPU_WRITE | GX2R_RESOURCE_USAGE_CPU_READ | + GX2R_RESOURCE_USAGE_GPU_WRITE | GX2R_RESOURCE_USAGE_GPU_READ ); if (!res) { SDL_free(tdata); @@ -102,11 +104,7 @@ int WIIU_SDL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, Uint32 BytesPerPixel = SDL_BYTESPERPIXEL(texture->format); void* pixel_buffer; - pixel_buffer = GX2RLockSurfaceEx( - &tdata->texture.surface, - 0, //mipmap level? - GX2R_RESOURCE_USAGE_CPU_READ | GX2R_RESOURCE_USAGE_CPU_WRITE - ); + pixel_buffer = GX2RLockSurfaceEx(&tdata->texture.surface, 0, 0); if (!pixel_buffer) { //TODO real error handling printf("SDL: Couldn't lock surface for texture!\n"); From f0511443d001f63b0cf5b31e71543bd739538657 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Wed, 6 Mar 2019 09:17:45 +1100 Subject: [PATCH 08/25] render/wiiu: readability - introduce vec* structs for drawing --- src/render/wiiu/SDL_rdraw_wiiu.c | 184 +++++++++++++++++++----------- src/render/wiiu/SDL_render_wiiu.h | 16 +++ 2 files changed, 134 insertions(+), 66 deletions(-) diff --git a/src/render/wiiu/SDL_rdraw_wiiu.c b/src/render/wiiu/SDL_rdraw_wiiu.c index 45aaeb0d7..692dfa720 100644 --- a/src/render/wiiu/SDL_rdraw_wiiu.c +++ b/src/render/wiiu/SDL_rdraw_wiiu.c @@ -54,8 +54,8 @@ int WIIU_SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata; GX2RBuffer *a_position, *a_texCoord; - float *a_position_vals, *a_texCoord_vals; - float u_mod[4]; + WIIUVec2 *a_position_vals, *a_texCoord_vals; + WIIUVec4 u_mod; float x_min, y_min, x_max, y_max; /* Allocate attribute buffers */ @@ -63,14 +63,14 @@ int WIIU_SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, .flags = GX2R_RESOURCE_BIND_VERTEX_BUFFER | GX2R_RESOURCE_USAGE_CPU_WRITE, - .elemSize = 2 * sizeof(float), // float x/y for each corner + .elemSize = sizeof(WIIUVec2), // float x/y for each corner .elemCount = 4, // 4 corners }); a_texCoord = WIIU_AllocRenderData(data, (GX2RBuffer) { .flags = GX2R_RESOURCE_BIND_VERTEX_BUFFER | GX2R_RESOURCE_USAGE_CPU_WRITE, - .elemSize = 2 * sizeof(float), // float x/y for each corner + .elemSize = sizeof(WIIUVec2), .elemCount = 4, // 4 corners }); @@ -82,25 +82,39 @@ int WIIU_SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, /* Save them */ a_position_vals = GX2RLockBufferEx(a_position, 0); - a_position_vals[0] = x_min; a_position_vals[1] = y_min; - a_position_vals[2] = x_max; a_position_vals[3] = y_min; - a_position_vals[4] = x_max; a_position_vals[5] = y_max; - a_position_vals[6] = x_min; a_position_vals[7] = y_max; + a_position_vals[0] = (WIIUVec2){.x = x_min, .y = y_min}; + a_position_vals[1] = (WIIUVec2){.x = x_max, .y = y_min}; + a_position_vals[2] = (WIIUVec2){.x = x_max, .y = y_max}; + a_position_vals[3] = (WIIUVec2){.x = x_min, .y = y_max}; GX2RUnlockBufferEx(a_position, 0); /* Compute texture coords */ a_texCoord_vals = GX2RLockBufferEx(a_texCoord, 0); - a_texCoord_vals[0] = srcrect->x; a_texCoord_vals[1] = srcrect->y + srcrect->h; - a_texCoord_vals[2] = srcrect->x + srcrect->w; a_texCoord_vals[3] = srcrect->y + srcrect->h; - a_texCoord_vals[4] = srcrect->x + srcrect->w; a_texCoord_vals[5] = srcrect->y; - a_texCoord_vals[6] = srcrect->x; a_texCoord_vals[7] = srcrect->y; - GX2RUnlockBufferEx(a_position, 0); + a_texCoord_vals[0] = (WIIUVec2) { + .x = srcrect->x, + .y = srcrect->y + srcrect->h, + }; + a_texCoord_vals[1] = (WIIUVec2) { + .x = srcrect->x + srcrect->w, + .y = srcrect->y + srcrect->h, + }; + a_texCoord_vals[2] = (WIIUVec2) { + .x = srcrect->x + srcrect->w, + .y = srcrect->y, + }; + a_texCoord_vals[3] = (WIIUVec2) { + .x = srcrect->x, + .y = srcrect->y, + }; + GX2RUnlockBufferEx(a_texCoord, 0); /* Compute color/alpha mod */ - u_mod[0] = (float)texture->r / 255.0f; - u_mod[1] = (float)texture->g / 255.0f; - u_mod[2] = (float)texture->b / 255.0f; - u_mod[3] = (float)texture->a / 255.0f; + u_mod = (WIIUVec4) { + .r = (float)texture->r / 255.0f, + .g = (float)texture->g / 255.0f, + .b = (float)texture->b / 255.0f, + .a = (float)texture->a / 255.0f, + }; /* Render */ GX2SetContextState(data->ctx); @@ -111,7 +125,7 @@ int WIIU_SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, GX2RSetAttributeBuffer(a_texCoord, 1, a_texCoord->elemSize, 0); GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)data->u_viewSize); GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[1].offset, 4, (uint32_t *)tdata->u_texSize); - GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)u_mod); + GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)&u_mod); WIIU_SDL_SetGX2BlendMode(texture->blendMode); GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1); @@ -126,8 +140,8 @@ int WIIU_SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata; GX2RBuffer *a_position, *a_texCoord; - float *a_position_vals, *a_texCoord_vals; - float u_mod[4]; + WIIUVec2 *a_position_vals, *a_texCoord_vals; + WIIUVec4 u_mod; /* Compute real vertex points */ float x_min = renderer->viewport.x + dstrect->x; @@ -137,11 +151,23 @@ int WIIU_SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, float cx = x_min + center->x; float cy = y_min + center->y; double r = angle * (M_PI / 180.0); - float rvb[8] = { - (flip & SDL_FLIP_HORIZONTAL) ? x_max : x_min, (flip & SDL_FLIP_VERTICAL) ? y_max : y_min, - (flip & SDL_FLIP_HORIZONTAL) ? x_min : x_max, (flip & SDL_FLIP_VERTICAL) ? y_max : y_min, - (flip & SDL_FLIP_HORIZONTAL) ? x_min : x_max, (flip & SDL_FLIP_VERTICAL) ? y_min : y_max, - (flip & SDL_FLIP_HORIZONTAL) ? x_max : x_min, (flip & SDL_FLIP_VERTICAL) ? y_min : y_max, + WIIUVec2 rvb[4] = { + { + .x = (flip & SDL_FLIP_HORIZONTAL) ? x_max : x_min, + .y = (flip & SDL_FLIP_VERTICAL) ? y_max : y_min, + }, + { + .x = (flip & SDL_FLIP_HORIZONTAL) ? x_min : x_max, + .y = (flip & SDL_FLIP_VERTICAL) ? y_max : y_min, + }, + { + .x = (flip & SDL_FLIP_HORIZONTAL) ? x_min : x_max, + .y = (flip & SDL_FLIP_VERTICAL) ? y_min : y_max, + }, + { + .x = (flip & SDL_FLIP_HORIZONTAL) ? x_max : x_min, + .y = (flip & SDL_FLIP_VERTICAL) ? y_min : y_max, + }, }; /* Allocate attribute buffers */ @@ -149,38 +175,54 @@ int WIIU_SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, .flags = GX2R_RESOURCE_BIND_VERTEX_BUFFER | GX2R_RESOURCE_USAGE_CPU_WRITE, - .elemSize = 2 * sizeof(float), // float x/y for each corner + .elemSize = sizeof(WIIUVec2), // float x/y for each corner .elemCount = 4, // 4 corners }); a_texCoord = WIIU_AllocRenderData(data, (GX2RBuffer) { .flags = GX2R_RESOURCE_BIND_VERTEX_BUFFER | GX2R_RESOURCE_USAGE_CPU_WRITE, - .elemSize = 2 * sizeof(float), // float x/y for each corner + .elemSize = sizeof(WIIUVec2), // float x/y for each corner .elemCount = 4, // 4 corners }); /* Save vertex points */ a_position_vals = GX2RLockBufferEx(a_position, 0); - for (int i = 0; i < 8; i += 2) { - a_position_vals[i+0] = cx + (SDL_cos(r) * (rvb[i+0] - cx) - SDL_sin(r) * (rvb[i+1] - cy)); - a_position_vals[i+1] = cy + (SDL_cos(r) * (rvb[i+1] - cy) + SDL_sin(r) * (rvb[i+0] - cx)); + for (int i = 0; i < 4; i++) { + a_position_vals[i] = (WIIUVec2) { + .x = cx + (SDL_cos(r) * (rvb[i].x - cx) - SDL_sin(r) * (rvb[i].y - cy)), + .y = cy + (SDL_cos(r) * (rvb[i].y - cy) + SDL_sin(r) * (rvb[i].x - cx)), + }; } GX2RUnlockBufferEx(a_position, 0); /* Compute texture coords */ a_texCoord_vals = GX2RLockBufferEx(a_texCoord, 0); - a_texCoord_vals[0] = srcrect->x; a_texCoord_vals[1] = srcrect->y + srcrect->h; - a_texCoord_vals[2] = srcrect->x + srcrect->w; a_texCoord_vals[3] = srcrect->y + srcrect->h; - a_texCoord_vals[4] = srcrect->x + srcrect->w; a_texCoord_vals[5] = srcrect->y; - a_texCoord_vals[6] = srcrect->x; a_texCoord_vals[7] = srcrect->y; - GX2RUnlockBufferEx(a_position, 0); + a_texCoord_vals[0] = (WIIUVec2) { + .x = srcrect->x, + .y = srcrect->y + srcrect->h, + }; + a_texCoord_vals[1] = (WIIUVec2) { + .x = srcrect->x + srcrect->w, + .y = srcrect->y + srcrect->h, + }; + a_texCoord_vals[2] = (WIIUVec2) { + .x = srcrect->x + srcrect->w, + .y = srcrect->y, + }; + a_texCoord_vals[3] = (WIIUVec2) { + .x = srcrect->x, + .y = srcrect->y, + }; + GX2RUnlockBufferEx(a_texCoord, 0); /* Compute color/alpha mod */ - u_mod[0] = (float)texture->r / 255.0f; - u_mod[1] = (float)texture->g / 255.0f; - u_mod[2] = (float)texture->b / 255.0f; - u_mod[3] = (float)texture->a / 255.0f; + u_mod = (WIIUVec4) { + .r = (float)texture->r / 255.0f, + .g = (float)texture->g / 255.0f, + .b = (float)texture->b / 255.0f, + .a = (float)texture->a / 255.0f, + }; /* Render */ GX2SetContextState(data->ctx); @@ -191,7 +233,7 @@ int WIIU_SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, GX2RSetAttributeBuffer(a_texCoord, 1, a_texCoord->elemSize, 0); GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)data->u_viewSize); GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[1].offset, 4, (uint32_t *)tdata->u_texSize); - GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)u_mod); + GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)&u_mod); WIIU_SDL_SetGX2BlendMode(texture->blendMode); GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1); @@ -203,28 +245,32 @@ int WIIU_SDL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points { WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; GX2RBuffer *a_position; - float *a_position_vals; + WIIUVec2 *a_position_vals; - /* Compute colors */ - float u_color[4] = {(float)renderer->r / 255.0f, - (float)renderer->g / 255.0f, - (float)renderer->b / 255.0f, - (float)renderer->a / 255.0f}; + /* Compute colours */ + WIIUVec4 u_colour = { + .r = (float)renderer->r / 255.0f, + .g = (float)renderer->g / 255.0f, + .b = (float)renderer->b / 255.0f, + .a = (float)renderer->a / 255.0f, + }; /* Allocate attribute buffers */ a_position = WIIU_AllocRenderData(data, (GX2RBuffer) { .flags = GX2R_RESOURCE_BIND_VERTEX_BUFFER | GX2R_RESOURCE_USAGE_CPU_WRITE, - .elemSize = 2 * sizeof(float), // float x/y for each point + .elemSize = sizeof(WIIUVec2), // float x/y for each point .elemCount = count, }); /* Compute vertex positions */ a_position_vals = GX2RLockBufferEx(a_position, 0); for (int i = 0; i < count; ++i) { - a_position_vals[i*2+0] = (float)renderer->viewport.x + points[i].x; - a_position_vals[i*2+1] = (float)renderer->viewport.y + points[i].y; + a_position_vals[i] = (WIIUVec2) { + .x = (float)renderer->viewport.x + points[i].x, + .y = (float)renderer->viewport.y + points[i].y, + }; } GX2RUnlockBufferEx(a_position, 0); @@ -233,7 +279,7 @@ int WIIU_SDL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points wiiuSetColorShader(); GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0); GX2SetVertexUniformReg(wiiuColorShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)data->u_viewSize); - GX2SetPixelUniformReg(wiiuColorShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)u_color); + GX2SetPixelUniformReg(wiiuColorShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)&u_colour); WIIU_SDL_SetGX2BlendMode(renderer->blendMode); GX2DrawEx(GX2_PRIMITIVE_MODE_POINTS, count, 0, 1); @@ -246,28 +292,32 @@ int WIIU_SDL_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, { WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; GX2RBuffer *a_position; - float *a_position_vals; + WIIUVec2 *a_position_vals; - /* Compute colors */ - float u_color[4] = {(float)renderer->r / 255.0f, - (float)renderer->g / 255.0f, - (float)renderer->b / 255.0f, - (float)renderer->a / 255.0f}; + /* Compute colours */ + WIIUVec4 u_colour = { + .r = (float)renderer->r / 255.0f, + .g = (float)renderer->g / 255.0f, + .b = (float)renderer->b / 255.0f, + .a = (float)renderer->a / 255.0f, + }; /* Allocate attribute buffers */ a_position = WIIU_AllocRenderData(data, (GX2RBuffer) { .flags = GX2R_RESOURCE_BIND_VERTEX_BUFFER | GX2R_RESOURCE_USAGE_CPU_WRITE, - .elemSize = 2 * sizeof(float), // float x/y for each point + .elemSize = sizeof(WIIUVec2), // float x/y for each point .elemCount = count, }); /* Compute vertex positions */ a_position_vals = GX2RLockBufferEx(a_position, 0); for (int i = 0; i < count; ++i) { - a_position_vals[i*2+0] = (float)renderer->viewport.x + points[i].x; - a_position_vals[i*2+1] = (float)renderer->viewport.y + points[i].y; + a_position_vals[i] = (WIIUVec2) { + .x = (float)renderer->viewport.x + points[i].x, + .y = (float)renderer->viewport.y + points[i].y, + }; } GX2RUnlockBufferEx(a_position, 0); @@ -276,7 +326,7 @@ int WIIU_SDL_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, wiiuSetColorShader(); GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0); GX2SetVertexUniformReg(wiiuColorShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)data->u_viewSize); - GX2SetPixelUniformReg(wiiuColorShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)u_color); + GX2SetPixelUniformReg(wiiuColorShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)&u_colour); WIIU_SDL_SetGX2BlendMode(renderer->blendMode); GX2DrawEx(GX2_PRIMITIVE_MODE_LINE_STRIP, count, 0, 1); @@ -289,11 +339,13 @@ int WIIU_SDL_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, i GX2RBuffer *a_position; float *a_position_vals; - /* Compute colors */ - float u_color[4] = {(float)renderer->r / 255.0f, - (float)renderer->g / 255.0f, - (float)renderer->b / 255.0f, - (float)renderer->a / 255.0f}; + /* Compute colours */ + WIIUVec4 u_colour = { + .r = (float)renderer->r / 255.0f, + .g = (float)renderer->g / 255.0f, + .b = (float)renderer->b / 255.0f, + .a = (float)renderer->a / 255.0f, + }; /* Compute vertex pos */ float vx = (float)renderer->viewport.x; @@ -327,7 +379,7 @@ int WIIU_SDL_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, i wiiuSetColorShader(); GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0); GX2SetVertexUniformReg(wiiuColorShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)data->u_viewSize); - GX2SetPixelUniformReg(wiiuColorShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)u_color); + GX2SetPixelUniformReg(wiiuColorShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)&u_colour); WIIU_SDL_SetGX2BlendMode(renderer->blendMode); GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4 * count, 0, 1); diff --git a/src/render/wiiu/SDL_render_wiiu.h b/src/render/wiiu/SDL_render_wiiu.h index e66fb166c..1cab7f605 100644 --- a/src/render/wiiu/SDL_render_wiiu.h +++ b/src/render/wiiu/SDL_render_wiiu.h @@ -128,6 +128,22 @@ static inline Uint32 TextureNextPow2(Uint32 w) { return n; } +typedef struct { + union { float x, r; }; + union { float y, g; }; +} WIIUVec2; +typedef struct { + union { float x, r; }; + union { float y, g; }; + union { float z, b; }; +} WIIUVec3; +typedef struct { + union { float x, r; }; + union { float y, g; }; + union { float z, b; }; + union { float w, a; }; +} WIIUVec4; + typedef struct WIIUPixFmt { GX2SurfaceFormat fmt; uint32_t compMap; From 4dad50640ac24523abc27734d1765960dca11f0e Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Wed, 6 Mar 2019 15:43:40 +1100 Subject: [PATCH 09/25] render/wiiu: Handle window size changes --- src/render/wiiu/SDL_render_wiiu.c | 22 +++++++++++++++++----- src/render/wiiu/SDL_render_wiiu.h | 3 +++ src/render/wiiu/SDL_rwindow_wiiu.c | 1 + 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/render/wiiu/SDL_render_wiiu.c b/src/render/wiiu/SDL_render_wiiu.c index 5bc88ec3c..da696cc9a 100644 --- a/src/render/wiiu/SDL_render_wiiu.c +++ b/src/render/wiiu/SDL_render_wiiu.c @@ -102,17 +102,29 @@ SDL_Renderer *WIIU_SDL_CreateRenderer(SDL_Window * window, Uint32 flags) memset(data->ctx, 0, sizeof(GX2ContextState)); GX2SetupContextStateEx(data->ctx, TRUE); + // Make a texture for the window + WIIU_SDL_CreateWindowTex(renderer, window); + + // Setup colour buffer, rendering to the window + WIIU_SDL_SetRenderTarget(renderer, NULL); + + return renderer; +} + +void WIIU_SDL_CreateWindowTex(SDL_Renderer * renderer, SDL_Window * window) { + WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; + + if (data->windowTex.driverdata) { + WIIU_SDL_DestroyTexture(renderer, &data->windowTex); + data->windowTex = (SDL_Texture) {0}; + } + // Allocate a buffer for the window data->windowTex = (SDL_Texture) { .format = SDL_PIXELFORMAT_RGBA8888, }; SDL_GetWindowSize(window, &data->windowTex.w, &data->windowTex.h); WIIU_SDL_CreateTexture(renderer, &data->windowTex); - - // Setup colour buffer, rendering to the window - WIIU_SDL_SetRenderTarget(renderer, NULL); - - return renderer; } int WIIU_SDL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) diff --git a/src/render/wiiu/SDL_render_wiiu.h b/src/render/wiiu/SDL_render_wiiu.h index 1cab7f605..aaf4dab1b 100644 --- a/src/render/wiiu/SDL_render_wiiu.h +++ b/src/render/wiiu/SDL_render_wiiu.h @@ -118,6 +118,9 @@ void WIIU_SDL_RenderPresent(SDL_Renderer * renderer); void WIIU_SDL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture); void WIIU_SDL_DestroyRenderer(SDL_Renderer * renderer); +//Driver internal functions +void WIIU_SDL_CreateWindowTex(SDL_Renderer * renderer, SDL_Window * window); + //Utility/helper functions static inline Uint32 TextureNextPow2(Uint32 w) { Uint32 n = 2; diff --git a/src/render/wiiu/SDL_rwindow_wiiu.c b/src/render/wiiu/SDL_rwindow_wiiu.c index 364fb25d3..3005aea00 100644 --- a/src/render/wiiu/SDL_rwindow_wiiu.c +++ b/src/render/wiiu/SDL_rwindow_wiiu.c @@ -41,6 +41,7 @@ void WIIU_SDL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) // Re-init the colour buffer etc. for new window size // TODO check: what if we're rendering to a texture when this happens? // SDL may handle this already, see SDL_render.c: SDL_RendererEventWatch + WIIU_SDL_CreateWindowTex(renderer, renderer->window); WIIU_SDL_SetRenderTarget(renderer, NULL); } } From cf0fc7760411e59de314ec5cd2da31c420092eec Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Wed, 6 Mar 2019 17:52:57 +1100 Subject: [PATCH 10/25] render/wiiu: Respect window sizes --- src/render/wiiu/SDL_rpresent_wiiu.c | 66 +++++++++++++++++------------ 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/src/render/wiiu/SDL_rpresent_wiiu.c b/src/render/wiiu/SDL_rpresent_wiiu.c index bd423f166..6283cf71d 100644 --- a/src/render/wiiu/SDL_rpresent_wiiu.c +++ b/src/render/wiiu/SDL_rpresent_wiiu.c @@ -19,12 +19,15 @@ static const float u_viewSize[4] = {(float)SCREEN_WIDTH, (float)SCREEN_HEIGHT}; -static void render_scene(WIIU_RenderData *data) { +static void render_scene(SDL_Renderer * renderer) { + WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; WIIU_TextureData *tdata = (WIIU_TextureData *) data->windowTex.driverdata; + float tex_w = tdata->u_texSize[0]; float tex_h = tdata->u_texSize[1]; + int win_x, win_y, win_w, win_h; GX2RBuffer *a_position, *a_texCoord; - float *a_position_vals, *a_texCoord_vals; + WIIUVec2 *a_position_vals, *a_texCoord_vals; float u_mod[4] = {1.0f, 1.0f, 1.0f, 1.0f}; /* Allocate attribute buffers */ @@ -32,44 +35,51 @@ static void render_scene(WIIU_RenderData *data) { .flags = GX2R_RESOURCE_BIND_VERTEX_BUFFER | GX2R_RESOURCE_USAGE_CPU_WRITE, - .elemSize = 2 * sizeof(float), // float x/y for each corner + .elemSize = sizeof(WIIUVec2), // float x/y for each corner .elemCount = 4, // 4 corners }); a_texCoord = WIIU_AllocRenderData(data, (GX2RBuffer) { .flags = GX2R_RESOURCE_BIND_VERTEX_BUFFER | GX2R_RESOURCE_USAGE_CPU_WRITE, - .elemSize = 2 * sizeof(float), // float x/y for each corner + .elemSize = sizeof(WIIUVec2), // float x/y for each corner .elemCount = 4, // 4 corners }); -/* Save them */ +/* Calculate and save positions */ + if (SDL_GetWindowFlags(renderer->window) & SDL_WINDOW_FULLSCREEN) { + win_x = 0; + win_y = 0; + win_w = SCREEN_WIDTH; + win_h = SCREEN_HEIGHT; + } else { + /* Center */ + SDL_GetWindowSize(renderer->window, &win_w, &win_h); + win_x = (SCREEN_WIDTH - win_w) / 2; + win_y = (SCREEN_HEIGHT - win_h) / 2; + } + a_position_vals = GX2RLockBufferEx(a_position, 0); -/* TODO: not 720p. also, this is legal C? */ - memcpy( - a_position_vals, - (float[]) { - 0.0f, 0.0f, - 1280.0f, 0.0f, - 1280.0f, 720.0f, - 0.0f, 720.0f, - }, - a_position->elemSize * a_position->elemCount - ); + a_position_vals[0] = (WIIUVec2) { + .x = win_x, .y = win_y + }; + a_position_vals[1] = (WIIUVec2) { + .x = win_x + win_w, .y = win_y + }; + a_position_vals[2] = (WIIUVec2) { + .x = win_x + win_w, .y = win_y + win_h + }; + a_position_vals[3] = (WIIUVec2) { + .x = win_x, .y = win_y + win_h + }; GX2RUnlockBufferEx(a_position, 0); /* Compute texture coords */ a_texCoord_vals = GX2RLockBufferEx(a_texCoord, 0); - memcpy( - a_texCoord_vals, - (float[]) { - 0.0f, tex_h, - tex_w, tex_h, - tex_w, 0.0f, - 0.0f, 0.0f, - }, - a_texCoord->elemSize * a_position->elemCount - ); + a_texCoord_vals[0] = (WIIUVec2) {.x = 0.0f, .y = tex_h}; + a_texCoord_vals[1] = (WIIUVec2) {.x = tex_w, .y = tex_h}; + a_texCoord_vals[2] = (WIIUVec2) {.x = tex_w, .y = 0.0f}; + a_texCoord_vals[3] = (WIIUVec2) {.x = 0.0f, .y = 0.0f}; GX2RUnlockBufferEx(a_position, 0); WHBGfxClearColor(0.0f, 0.0f, 0.0f, 1.0f); @@ -98,11 +108,11 @@ void WIIU_SDL_RenderPresent(SDL_Renderer * renderer) WHBGfxBeginRender(); WHBGfxBeginRenderTV(); - render_scene(data); + render_scene(renderer); WHBGfxFinishRenderTV(); WHBGfxBeginRenderDRC(); - render_scene(data); + render_scene(renderer); WHBGfxFinishRenderDRC(); WHBGfxFinishRender(); From 1b479185edfadecd772539bc5ab7e5eb873b6b93 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Wed, 6 Mar 2019 19:05:58 +1100 Subject: [PATCH 11/25] render/wiiu: Fix present position/texcoord confusion --- src/render/wiiu/SDL_rpresent_wiiu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/wiiu/SDL_rpresent_wiiu.c b/src/render/wiiu/SDL_rpresent_wiiu.c index 6283cf71d..111dd3025 100644 --- a/src/render/wiiu/SDL_rpresent_wiiu.c +++ b/src/render/wiiu/SDL_rpresent_wiiu.c @@ -80,7 +80,7 @@ static void render_scene(SDL_Renderer * renderer) { a_texCoord_vals[1] = (WIIUVec2) {.x = tex_w, .y = tex_h}; a_texCoord_vals[2] = (WIIUVec2) {.x = tex_w, .y = 0.0f}; a_texCoord_vals[3] = (WIIUVec2) {.x = 0.0f, .y = 0.0f}; - GX2RUnlockBufferEx(a_position, 0); + GX2RUnlockBufferEx(a_texCoord, 0); WHBGfxClearColor(0.0f, 0.0f, 0.0f, 1.0f); wiiuSetTextureShader(); From ef1495c9b38d05f02a0af8a44dbdf201bd8c85a7 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Wed, 6 Mar 2019 19:53:43 +1100 Subject: [PATCH 12/25] render/wiiu: Use vec* for FillRects (fixes no-draw bug) --- src/render/wiiu/SDL_rdraw_wiiu.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/render/wiiu/SDL_rdraw_wiiu.c b/src/render/wiiu/SDL_rdraw_wiiu.c index 692dfa720..2f405af96 100644 --- a/src/render/wiiu/SDL_rdraw_wiiu.c +++ b/src/render/wiiu/SDL_rdraw_wiiu.c @@ -337,7 +337,7 @@ int WIIU_SDL_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, i { WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; GX2RBuffer *a_position; - float *a_position_vals; + WIIUVec2 *a_position_vals; /* Compute colours */ WIIUVec4 u_colour = { @@ -356,21 +356,29 @@ int WIIU_SDL_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, i .flags = GX2R_RESOURCE_BIND_VERTEX_BUFFER | GX2R_RESOURCE_USAGE_CPU_WRITE, - .elemSize = 8 * sizeof(float), - .elemCount = count, + .elemSize = sizeof(WIIUVec2), // x/y float per corner + .elemCount = 4 * count, // 4 corners per square }); /* Compute vertex positions */ a_position_vals = GX2RLockBufferEx(a_position, 0); for (int i = 0; i < count; ++i) { - a_position_vals[i*8+0] = vx + rects[i].x; - a_position_vals[i*8+1] = vy + rects[i].y; - a_position_vals[i*8+2] = vx + rects[i].x + rects[i].w; - a_position_vals[i*8+3] = vy + rects[i].y; - a_position_vals[i*8+4] = vx + rects[i].x + rects[i].w; - a_position_vals[i*8+5] = vy + rects[i].y + rects[i].h; - a_position_vals[i*8+6] = vx + rects[i].x; - a_position_vals[i*8+7] = vy + rects[i].y + rects[i].h; + a_position_vals[i*4 + 0] = (WIIUVec2) { + .x = vx + rects[i].x, + .y = vy + rects[i].y, + }; + a_position_vals[i*4 + 1] = (WIIUVec2) { + .x = vx + rects[i].x + rects[i].w, + .y = vy + rects[i].y, + }; + a_position_vals[i*4 + 2] = (WIIUVec2) { + .x = vx + rects[i].x + rects[i].w, + .y = vy + rects[i].y + rects[i].h, + }; + a_position_vals[i*4 + 3] = (WIIUVec2) { + .x = vx + rects[i].x, + .y = vy + rects[i].y + rects[i].h, + }; } GX2RUnlockBufferEx(a_position, 0); From 17c5430eab32678798e1843aa904f1f331dcba7e Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Thu, 7 Mar 2019 21:59:49 +1100 Subject: [PATCH 13/25] video/wiiu: Add support for DRC/TV only windows (#1) --- src/render/wiiu/SDL_rpresent_wiiu.c | 21 ++++---- src/video/wiiu/SDL_wiiuvideo.c | 75 +++++++++++++++++++++++++++++ src/video/wiiu/SDL_wiiuvideo.h | 7 +++ 3 files changed, 94 insertions(+), 9 deletions(-) diff --git a/src/render/wiiu/SDL_rpresent_wiiu.c b/src/render/wiiu/SDL_rpresent_wiiu.c index 111dd3025..421abd30a 100644 --- a/src/render/wiiu/SDL_rpresent_wiiu.c +++ b/src/render/wiiu/SDL_rpresent_wiiu.c @@ -101,19 +101,22 @@ static void render_scene(SDL_Renderer * renderer) { void WIIU_SDL_RenderPresent(SDL_Renderer * renderer) { WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; - //SDL_Window *window = renderer->window; - - //GX2Flush(); + Uint32 flags = SDL_GetWindowFlags(renderer->window); WHBGfxBeginRender(); - WHBGfxBeginRenderTV(); - render_scene(renderer); - WHBGfxFinishRenderTV(); +/* Only render to TV if the window is *not* drc-only */ + if (!(flags & SDL_WINDOW_WIIU_GAMEPAD_ONLY)) { + WHBGfxBeginRenderTV(); + render_scene(renderer); + WHBGfxFinishRenderTV(); + } - WHBGfxBeginRenderDRC(); - render_scene(renderer); - WHBGfxFinishRenderDRC(); + if (!(flags & SDL_WINDOW_WIIU_TV_ONLY)) { + WHBGfxBeginRenderDRC(); + render_scene(renderer); + WHBGfxFinishRenderDRC(); + } WHBGfxFinishRender(); diff --git a/src/video/wiiu/SDL_wiiuvideo.c b/src/video/wiiu/SDL_wiiuvideo.c index 87ad734a7..3a04271ba 100644 --- a/src/video/wiiu/SDL_wiiuvideo.c +++ b/src/video/wiiu/SDL_wiiuvideo.c @@ -88,10 +88,76 @@ static void WIIU_VideoQuit(_THIS) } static int WIIU_CreateSDLWindow(_THIS, SDL_Window *window) { + WIIU_VideoDeviceData* ddata = (WIIU_VideoDeviceData*) _this->driverdata; + + /* If this window wants to be mirrored (no _ONLY flags) */ + if (!(window->flags & + (SDL_WINDOW_WIIU_TV_ONLY | SDL_WINDOW_WIIU_GAMEPAD_ONLY))) { + /* Only one window can exist in this state */ + if (ddata->drc_window_exists || + ddata->tv_window_exists || + ddata->mirrored_window_exists) { + return SDL_SetError( + "WiiU only supports one window when mirroring the TV and " + "Gamepad. https://github.com/yawut/SDL/wiki/Custom-Window-Flags" + ); + } + + /* Okay! */ + ddata->mirrored_window_exists = SDL_TRUE; + + /* If this window wants the TV */ + } else if (window->flags & SDL_WINDOW_WIIU_TV_ONLY) { + /* Check if a TV window already exists */ + if (ddata->tv_window_exists) { + return SDL_SetError( + "WiiU only supports one window on the TV. " + "https://github.com/yawut/SDL/wiki/Custom-Window-Flags" + ); + /* Check if a mirrored window exists */ + } else if (ddata->mirrored_window_exists) { + return SDL_SetError( + "WiiU only supports one window when mirroring the TV and " + "Gamepad. https://github.com/yawut/SDL/wiki/Custom-Window-Flags" + ); + } + + ddata->tv_window_exists = SDL_TRUE; + + /* If this window wants the Gamepad */ + } else if (window->flags & SDL_WINDOW_WIIU_GAMEPAD_ONLY) { + /* Check if a TV window already exists */ + if (ddata->drc_window_exists) { + return SDL_SetError( + "WiiU only supports one window on the Gamepad. " + "https://github.com/yawut/SDL/wiki/Custom-Window-Flags" + ); + /* Check if a mirrored window exists */ + } else if (ddata->mirrored_window_exists) { + return SDL_SetError( + "WiiU only supports one window when mirroring the TV and " + "Gamepad. https://github.com/yawut/SDL/wiki/Custom-Window-Flags" + ); + } + + ddata->drc_window_exists = SDL_TRUE; + } SDL_SetKeyboardFocus(window); return 0; } +static void WIIU_DestroyWindow(_THIS, SDL_Window * window) { + WIIU_VideoDeviceData* ddata = (WIIU_VideoDeviceData*) _this->driverdata; + + if (window->flags & SDL_WINDOW_WIIU_TV_ONLY) { + ddata->tv_window_exists = SDL_FALSE; + } else if (window->flags & SDL_WINDOW_WIIU_GAMEPAD_ONLY) { + ddata->drc_window_exists = SDL_FALSE; + } else { + ddata->mirrored_window_exists = SDL_FALSE; + } +} + static int WIIU_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode) { return 0; @@ -108,6 +174,7 @@ static int WIIU_Available(void) static void WIIU_DeleteDevice(SDL_VideoDevice *device) { + SDL_free(device->driverdata); SDL_free(device); } @@ -121,11 +188,19 @@ static SDL_VideoDevice *WIIU_CreateDevice(int devindex) return NULL; } + device->driverdata = (void*) SDL_calloc(1, sizeof(WIIU_VideoDeviceData)); + if (!device->driverdata) { + SDL_OutOfMemory(); + SDL_free(device); + return NULL; + } + device->VideoInit = WIIU_VideoInit; device->VideoQuit = WIIU_VideoQuit; device->SetDisplayMode = WIIU_SetDisplayMode; device->PumpEvents = WIIU_PumpEvents; device->CreateSDLWindow = WIIU_CreateSDLWindow; + device->DestroyWindow = WIIU_DestroyWindow; device->free = WIIU_DeleteDevice; diff --git a/src/video/wiiu/SDL_wiiuvideo.h b/src/video/wiiu/SDL_wiiuvideo.h index bf5e1a9f7..3cbf3df4c 100644 --- a/src/video/wiiu/SDL_wiiuvideo.h +++ b/src/video/wiiu/SDL_wiiuvideo.h @@ -35,4 +35,11 @@ typedef struct GX2Texture texture; } WIIU_WindowData; +typedef struct +{ + SDL_bool tv_window_exists; + SDL_bool drc_window_exists; + SDL_bool mirrored_window_exists; +} WIIU_VideoDeviceData; + #endif //SDL_wiiuvideo_h From 8264b0bfd542d9cbd929396c223a49dae52df27d Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Thu, 7 Mar 2019 22:10:27 +1100 Subject: [PATCH 14/25] render/wiiu: Use point scaling by default see https://wiki.libsdl.org/SDL_HINT_RENDER_SCALE_QUALITY --- src/render/wiiu/SDL_rtexture_wiiu.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/render/wiiu/SDL_rtexture_wiiu.c b/src/render/wiiu/SDL_rtexture_wiiu.c index b656f720b..26cf5a035 100644 --- a/src/render/wiiu/SDL_rtexture_wiiu.c +++ b/src/render/wiiu/SDL_rtexture_wiiu.c @@ -51,7 +51,12 @@ int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) return SDL_OutOfMemory(); // Setup sampler - GX2InitSampler(&tdata->sampler, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_LINEAR); + if (texture->scaleMode == SDL_ScaleModeNearest) { + GX2InitSampler(&tdata->sampler, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_POINT); + } else { + GX2InitSampler(&tdata->sampler, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_LINEAR); + } + gx2_fmt = SDLFormatToWIIUFormat(texture->format); From e4f10eb2a635e7ec2a2826bce84e150190a36cf9 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Fri, 8 Mar 2019 11:23:03 +1100 Subject: [PATCH 15/25] render/wiiu: Textures keep their own colour buffers --- src/render/wiiu/SDL_rdraw_wiiu.c | 14 +++++++++-- src/render/wiiu/SDL_render_wiiu.c | 36 +++++++++++++---------------- src/render/wiiu/SDL_render_wiiu.h | 9 +++++++- src/render/wiiu/SDL_rtexture_wiiu.c | 24 ++++++++++++++----- 4 files changed, 54 insertions(+), 29 deletions(-) diff --git a/src/render/wiiu/SDL_rdraw_wiiu.c b/src/render/wiiu/SDL_rdraw_wiiu.c index 2f405af96..793f899fc 100644 --- a/src/render/wiiu/SDL_rdraw_wiiu.c +++ b/src/render/wiiu/SDL_rdraw_wiiu.c @@ -58,6 +58,10 @@ int WIIU_SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, WIIUVec4 u_mod; float x_min, y_min, x_max, y_max; + if (texture->access & SDL_TEXTUREACCESS_TARGET) { + GX2RInvalidateSurface(&tdata->texture.surface, 0, 0); + } + /* Allocate attribute buffers */ a_position = WIIU_AllocRenderData(data, (GX2RBuffer) { .flags = @@ -170,6 +174,10 @@ int WIIU_SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, }, }; + if (texture->access & SDL_TEXTUREACCESS_TARGET) { + GX2RInvalidateSurface(&tdata->texture.surface, 0, 0); + } + /* Allocate attribute buffers */ a_position = WIIU_AllocRenderData(data, (GX2RBuffer) { .flags = @@ -412,8 +420,10 @@ int WIIU_SDL_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, i int WIIU_SDL_RenderClear(SDL_Renderer * renderer) { - WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; - GX2ClearColor(&data->cbuf, + SDL_Texture* target = WIIU_GetRenderTarget(renderer); + WIIU_TextureData* tdata = (WIIU_TextureData*) target->driverdata; + + GX2ClearColor(&tdata->cbuf, (float)renderer->r / 255.0f, (float)renderer->g / 255.0f, (float)renderer->b / 255.0f, diff --git a/src/render/wiiu/SDL_render_wiiu.c b/src/render/wiiu/SDL_render_wiiu.c index da696cc9a..20ca64072 100644 --- a/src/render/wiiu/SDL_render_wiiu.c +++ b/src/render/wiiu/SDL_render_wiiu.c @@ -131,37 +131,30 @@ int WIIU_SDL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) { WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; - GX2Surface *target; + GX2ColorBuffer *target; if (texture) { // Set texture as target WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata; - target = &tdata->texture.surface; + target = &tdata->cbuf; } else { // Set window texture as target WIIU_TextureData *tdata = (WIIU_TextureData *) data->windowTex.driverdata; - target = &tdata->texture.surface; + target = &tdata->cbuf; } - // Update color buffer - memset(&data->cbuf, 0, sizeof(data->cbuf)); - memcpy(&data->cbuf.surface, target, sizeof(GX2Surface)); - data->cbuf.surface.use = GX2_SURFACE_USE_TEXTURE | GX2_SURFACE_USE_COLOR_BUFFER; - data->cbuf.viewNumSlices = 1; - GX2InitColorBufferRegs(&data->cbuf); - // Update u_viewSize - data->u_viewSize[0] = data->cbuf.surface.width; - data->u_viewSize[1] = data->cbuf.surface.height; + data->u_viewSize[0] = target->surface.width; + data->u_viewSize[1] = target->surface.height; // Update context state GX2SetContextState(data->ctx); - GX2SetColorBuffer(&data->cbuf, GX2_RENDER_TARGET_0); + GX2SetColorBuffer(target, GX2_RENDER_TARGET_0); // These may be unnecessary - see SDL_render.c: SDL_SetRenderTarget's calls // to UpdateViewport and UpdateClipRect. TODO for once the render is // basically working. - GX2SetViewport(0, 0, (float)data->cbuf.surface.width, (float)data->cbuf.surface.height, 0.0f, 1.0f); - GX2SetScissor(0, 0, (float)data->cbuf.surface.width, (float)data->cbuf.surface.height); + GX2SetViewport(0, 0, (float)target->surface.width, (float)target->surface.height, 0.0f, 1.0f); + GX2SetScissor(0, 0, (float)target->surface.width, (float)target->surface.height); GX2SetAlphaTest(TRUE, GX2_COMPARE_FUNC_GREATER, 0.0f); GX2SetDepthOnlyControl(FALSE, FALSE, GX2_COMPARE_FUNC_NEVER); @@ -194,6 +187,9 @@ int WIIU_SDL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 format, void * pixels, int pitch) { WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; + SDL_Texture* target = WIIU_GetRenderTarget(renderer); + WIIU_TextureData* tdata = (WIIU_TextureData*) target->driverdata; + Uint32 src_format; void *src_pixels; @@ -201,18 +197,18 @@ int WIIU_SDL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, * SDL_RenderReadPixels. */ - if (rect->x < 0 || rect->x+rect->w > data->cbuf.surface.width || - rect->y < 0 || rect->y+rect->h > data->cbuf.surface.height) { + if (rect->x < 0 || rect->x+rect->w > tdata->cbuf.surface.width || + rect->y < 0 || rect->y+rect->h > tdata->cbuf.surface.height) { return SDL_SetError("Tried to read outside of surface bounds"); } src_format = SDL_PIXELFORMAT_RGBA8888; // TODO once working: other formats/checks - src_pixels = (void*)((Uint8 *) data->cbuf.surface.image + - rect->y * data->cbuf.surface.pitch + + src_pixels = (void*)((Uint8 *) tdata->cbuf.surface.image + + rect->y * tdata->cbuf.surface.pitch + rect->x * 4); return SDL_ConvertPixels(rect->w, rect->h, - src_format, src_pixels, data->cbuf.surface.pitch, + src_format, src_pixels, tdata->cbuf.surface.pitch, format, pixels, pitch); } diff --git a/src/render/wiiu/SDL_render_wiiu.h b/src/render/wiiu/SDL_render_wiiu.h index aaf4dab1b..da7b28014 100644 --- a/src/render/wiiu/SDL_render_wiiu.h +++ b/src/render/wiiu/SDL_render_wiiu.h @@ -40,7 +40,6 @@ typedef struct //Driver internal data structures typedef struct { - GX2ColorBuffer cbuf; GX2ContextState *ctx; WIIU_RenderAllocData *listfree; float u_viewSize[4]; @@ -51,6 +50,7 @@ typedef struct { GX2Sampler sampler; GX2Texture texture; + GX2ColorBuffer cbuf; float u_texSize[4]; } WIIU_TextureData; @@ -152,6 +152,13 @@ typedef struct WIIUPixFmt { uint32_t compMap; } WIIUPixFmt; +static inline SDL_Texture* WIIU_GetRenderTarget(SDL_Renderer* renderer) { + WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; + + if (renderer->target) return renderer->target; + return &data->windowTex; +} + static inline WIIUPixFmt SDLFormatToWIIUFormat(Uint32 format) { WIIUPixFmt outFmt = { /* sane defaults? */ .fmt = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8, diff --git a/src/render/wiiu/SDL_rtexture_wiiu.c b/src/render/wiiu/SDL_rtexture_wiiu.c index 26cf5a035..dc36ecc5c 100644 --- a/src/render/wiiu/SDL_rtexture_wiiu.c +++ b/src/render/wiiu/SDL_rtexture_wiiu.c @@ -66,8 +66,6 @@ int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) tdata->texture.surface.depth = 1; //? tdata->texture.surface.dim = GX2_SURFACE_DIM_TEXTURE_2D; tdata->texture.surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED; - tdata->texture.surface.use = - GX2_SURFACE_USE_TEXTURE | GX2_SURFACE_USE_COLOR_BUFFER; tdata->texture.surface.mipLevels = 1; tdata->texture.viewNumMips = 1; tdata->texture.viewNumSlices = 1; @@ -75,6 +73,10 @@ int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) GX2CalcSurfaceSizeAndAlignment(&tdata->texture.surface); GX2InitTextureRegs(&tdata->texture); + tdata->cbuf.surface = tdata->texture.surface; + tdata->cbuf.viewNumSlices = 1; + GX2InitColorBufferRegs(&tdata->cbuf); + /* Allocate the texture's surface */ res = GX2RCreateSurface( &tdata->texture.surface, @@ -87,12 +89,21 @@ int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) return SDL_OutOfMemory(); } +/* Allocate a colour buffer, using the same backing buffer */ + res = GX2RCreateSurfaceUserMemory( + &tdata->cbuf.surface, + tdata->texture.surface.image, + tdata->texture.surface.mipmaps, + tdata->texture.surface.resourceFlags + ); + if (!res) { + GX2RDestroySurfaceEx(&tdata->texture.surface, 0); + SDL_free(tdata); + return SDL_OutOfMemory(); + } + tdata->u_texSize[0] = texture->w; tdata->u_texSize[1] = texture->h; - GX2Invalidate( - GX2_INVALIDATE_MODE_CPU, - &tdata->u_texSize, sizeof(tdata->u_texSize) - ); texture->driverdata = tdata; @@ -171,6 +182,7 @@ void WIIU_SDL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) if (texture == NULL || texture->driverdata == NULL) return; tdata = (WIIU_TextureData *) texture->driverdata; + GX2RDestroySurfaceEx(&tdata->cbuf.surface, 0); GX2RDestroySurfaceEx(&tdata->texture.surface, 0); SDL_free(tdata); From f2133c5bda8835c9ff440ef0db095dc84eaf1a84 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Fri, 8 Mar 2019 11:41:31 +1100 Subject: [PATCH 16/25] render/wiiu: Re-set context state after a clear whb does this, so y'know --- src/render/wiiu/SDL_rdraw_wiiu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/render/wiiu/SDL_rdraw_wiiu.c b/src/render/wiiu/SDL_rdraw_wiiu.c index 793f899fc..113c1fe4e 100644 --- a/src/render/wiiu/SDL_rdraw_wiiu.c +++ b/src/render/wiiu/SDL_rdraw_wiiu.c @@ -420,6 +420,7 @@ int WIIU_SDL_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, i int WIIU_SDL_RenderClear(SDL_Renderer * renderer) { + WIIU_RenderData* data = (WIIU_RenderData*) renderer->driverdata; SDL_Texture* target = WIIU_GetRenderTarget(renderer); WIIU_TextureData* tdata = (WIIU_TextureData*) target->driverdata; @@ -428,6 +429,7 @@ int WIIU_SDL_RenderClear(SDL_Renderer * renderer) (float)renderer->g / 255.0f, (float)renderer->b / 255.0f, (float)renderer->a / 255.0f); + GX2SetContextState(data->ctx); return 0; } From 8b36af565fae81177de7fa20cf4ad47bd9a40b0b Mon Sep 17 00:00:00 2001 From: rw-r-r-0644 Date: Sun, 10 Mar 2019 00:25:10 +0100 Subject: [PATCH 17/25] render/wiiu: Use vec* for u_texSize and u_viewSize --- src/render/wiiu/SDL_rdraw_wiiu.c | 24 ++++++++-------- src/render/wiiu/SDL_render_wiiu.c | 6 ++-- src/render/wiiu/SDL_render_wiiu.h | 44 ++++++++++++++--------------- src/render/wiiu/SDL_rpresent_wiiu.c | 10 +++---- src/render/wiiu/SDL_rtexture_wiiu.c | 6 ++-- 5 files changed, 47 insertions(+), 43 deletions(-) diff --git a/src/render/wiiu/SDL_rdraw_wiiu.c b/src/render/wiiu/SDL_rdraw_wiiu.c index 113c1fe4e..928153e92 100644 --- a/src/render/wiiu/SDL_rdraw_wiiu.c +++ b/src/render/wiiu/SDL_rdraw_wiiu.c @@ -127,9 +127,9 @@ int WIIU_SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, GX2SetPixelSampler(&tdata->sampler, 0); GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0); GX2RSetAttributeBuffer(a_texCoord, 1, a_texCoord->elemSize, 0); - GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)data->u_viewSize); - GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[1].offset, 4, (uint32_t *)tdata->u_texSize); - GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)&u_mod); + GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)&data->u_viewSize); + GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[1].offset, 4, (uint32_t *)&tdata->u_texSize); + GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t *)&u_mod); WIIU_SDL_SetGX2BlendMode(texture->blendMode); GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1); @@ -239,9 +239,9 @@ int WIIU_SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, GX2SetPixelSampler(&tdata->sampler, 0); GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0); GX2RSetAttributeBuffer(a_texCoord, 1, a_texCoord->elemSize, 0); - GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)data->u_viewSize); - GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[1].offset, 4, (uint32_t *)tdata->u_texSize); - GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)&u_mod); + GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)&data->u_viewSize); + GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[1].offset, 4, (uint32_t *)&tdata->u_texSize); + GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t *)&u_mod); WIIU_SDL_SetGX2BlendMode(texture->blendMode); GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1); @@ -286,8 +286,8 @@ int WIIU_SDL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points GX2SetContextState(data->ctx); wiiuSetColorShader(); GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0); - GX2SetVertexUniformReg(wiiuColorShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)data->u_viewSize); - GX2SetPixelUniformReg(wiiuColorShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)&u_colour); + GX2SetVertexUniformReg(wiiuColorShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)&data->u_viewSize); + GX2SetPixelUniformReg(wiiuColorShader.pixelShader->uniformVars[0].offset, 4, (uint32_t *)&u_colour); WIIU_SDL_SetGX2BlendMode(renderer->blendMode); GX2DrawEx(GX2_PRIMITIVE_MODE_POINTS, count, 0, 1); @@ -333,8 +333,8 @@ int WIIU_SDL_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, GX2SetContextState(data->ctx); wiiuSetColorShader(); GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0); - GX2SetVertexUniformReg(wiiuColorShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)data->u_viewSize); - GX2SetPixelUniformReg(wiiuColorShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)&u_colour); + GX2SetVertexUniformReg(wiiuColorShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)&data->u_viewSize); + GX2SetPixelUniformReg(wiiuColorShader.pixelShader->uniformVars[0].offset, 4, (uint32_t *)&u_colour); WIIU_SDL_SetGX2BlendMode(renderer->blendMode); GX2DrawEx(GX2_PRIMITIVE_MODE_LINE_STRIP, count, 0, 1); @@ -394,8 +394,8 @@ int WIIU_SDL_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, i GX2SetContextState(data->ctx); wiiuSetColorShader(); GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0); - GX2SetVertexUniformReg(wiiuColorShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)data->u_viewSize); - GX2SetPixelUniformReg(wiiuColorShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)&u_colour); + GX2SetVertexUniformReg(wiiuColorShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)&data->u_viewSize); + GX2SetPixelUniformReg(wiiuColorShader.pixelShader->uniformVars[0].offset, 4, (uint32_t *)&u_colour); WIIU_SDL_SetGX2BlendMode(renderer->blendMode); GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4 * count, 0, 1); diff --git a/src/render/wiiu/SDL_render_wiiu.c b/src/render/wiiu/SDL_render_wiiu.c index 20ca64072..d683786e2 100644 --- a/src/render/wiiu/SDL_render_wiiu.c +++ b/src/render/wiiu/SDL_render_wiiu.c @@ -144,8 +144,10 @@ int WIIU_SDL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) } // Update u_viewSize - data->u_viewSize[0] = target->surface.width; - data->u_viewSize[1] = target->surface.height; + data->u_viewSize = (WIIUVec4) { + .x = (float)target->surface.width, + .y = (float)target->surface.height, + }; // Update context state GX2SetContextState(data->ctx); diff --git a/src/render/wiiu/SDL_render_wiiu.h b/src/render/wiiu/SDL_render_wiiu.h index da7b28014..54e6da3e5 100644 --- a/src/render/wiiu/SDL_render_wiiu.h +++ b/src/render/wiiu/SDL_render_wiiu.h @@ -31,6 +31,24 @@ #include #include +typedef struct { + union { float x, r; }; + union { float y, g; }; +} WIIUVec2; + +typedef struct { + union { float x, r; }; + union { float y, g; }; + union { float z, b; }; +} WIIUVec3; + +typedef struct { + union { float x, r; }; + union { float y, g; }; + union { float z, b; }; + union { float w, a; }; +} WIIUVec4; + typedef struct { void *next; @@ -38,20 +56,18 @@ typedef struct } WIIU_RenderAllocData; //Driver internal data structures -typedef struct -{ +typedef struct { GX2ContextState *ctx; WIIU_RenderAllocData *listfree; - float u_viewSize[4]; + WIIUVec4 u_viewSize; SDL_Texture windowTex; } WIIU_RenderData; -typedef struct -{ +typedef struct { GX2Sampler sampler; GX2Texture texture; GX2ColorBuffer cbuf; - float u_texSize[4]; + WIIUVec4 u_texSize; } WIIU_TextureData; static inline GX2RBuffer* WIIU_AllocRenderData(WIIU_RenderData *r, GX2RBuffer buffer) { @@ -131,22 +147,6 @@ static inline Uint32 TextureNextPow2(Uint32 w) { return n; } -typedef struct { - union { float x, r; }; - union { float y, g; }; -} WIIUVec2; -typedef struct { - union { float x, r; }; - union { float y, g; }; - union { float z, b; }; -} WIIUVec3; -typedef struct { - union { float x, r; }; - union { float y, g; }; - union { float z, b; }; - union { float w, a; }; -} WIIUVec4; - typedef struct WIIUPixFmt { GX2SurfaceFormat fmt; uint32_t compMap; diff --git a/src/render/wiiu/SDL_rpresent_wiiu.c b/src/render/wiiu/SDL_rpresent_wiiu.c index 421abd30a..c04e4c3fa 100644 --- a/src/render/wiiu/SDL_rpresent_wiiu.c +++ b/src/render/wiiu/SDL_rpresent_wiiu.c @@ -17,14 +17,14 @@ #define SCREEN_WIDTH 1280 #define SCREEN_HEIGHT 720 -static const float u_viewSize[4] = {(float)SCREEN_WIDTH, (float)SCREEN_HEIGHT}; +static const WIIUVec4 u_viewSize = {.x = (float)SCREEN_WIDTH, .y = (float)SCREEN_HEIGHT}; static void render_scene(SDL_Renderer * renderer) { WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; WIIU_TextureData *tdata = (WIIU_TextureData *) data->windowTex.driverdata; - float tex_w = tdata->u_texSize[0]; - float tex_h = tdata->u_texSize[1]; + float tex_w = tdata->u_texSize.x; + float tex_h = tdata->u_texSize.y; int win_x, win_y, win_w, win_h; GX2RBuffer *a_position, *a_texCoord; WIIUVec2 *a_position_vals, *a_texCoord_vals; @@ -85,8 +85,8 @@ static void render_scene(SDL_Renderer * renderer) { WHBGfxClearColor(0.0f, 0.0f, 0.0f, 1.0f); wiiuSetTextureShader(); - GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)u_viewSize); - GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[1].offset, 4, (uint32_t *)tdata->u_texSize); + GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)&u_viewSize); + GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[1].offset, 4, (uint32_t *)&tdata->u_texSize); GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)u_mod); GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0); diff --git a/src/render/wiiu/SDL_rtexture_wiiu.c b/src/render/wiiu/SDL_rtexture_wiiu.c index dc36ecc5c..9b0e2ba68 100644 --- a/src/render/wiiu/SDL_rtexture_wiiu.c +++ b/src/render/wiiu/SDL_rtexture_wiiu.c @@ -102,8 +102,10 @@ int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) return SDL_OutOfMemory(); } - tdata->u_texSize[0] = texture->w; - tdata->u_texSize[1] = texture->h; + tdata->u_texSize = (WIIUVec4) { + .x = texture->w, + .y = texture->h, + }; texture->driverdata = tdata; From 64b9abf590e6926a404c8fc5552c3306c7452b46 Mon Sep 17 00:00:00 2001 From: rw-r-r-0644 Date: Sun, 10 Mar 2019 00:36:38 +0100 Subject: [PATCH 18/25] render/wiiu: Implement SetTextureColorMod/SetTextureAlphaMod --- src/render/wiiu/SDL_rdraw_wiiu.c | 22 ++-------------------- src/render/wiiu/SDL_render_wiiu.c | 5 +++-- src/render/wiiu/SDL_render_wiiu.h | 7 +++---- src/render/wiiu/SDL_rpresent_wiiu.c | 3 +-- src/render/wiiu/SDL_rtexture_wiiu.c | 23 +++++++++++++++++++++++ 5 files changed, 32 insertions(+), 28 deletions(-) diff --git a/src/render/wiiu/SDL_rdraw_wiiu.c b/src/render/wiiu/SDL_rdraw_wiiu.c index 928153e92..c277895eb 100644 --- a/src/render/wiiu/SDL_rdraw_wiiu.c +++ b/src/render/wiiu/SDL_rdraw_wiiu.c @@ -55,7 +55,6 @@ int WIIU_SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata; GX2RBuffer *a_position, *a_texCoord; WIIUVec2 *a_position_vals, *a_texCoord_vals; - WIIUVec4 u_mod; float x_min, y_min, x_max, y_max; if (texture->access & SDL_TEXTUREACCESS_TARGET) { @@ -112,14 +111,6 @@ int WIIU_SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, }; GX2RUnlockBufferEx(a_texCoord, 0); - /* Compute color/alpha mod */ - u_mod = (WIIUVec4) { - .r = (float)texture->r / 255.0f, - .g = (float)texture->g / 255.0f, - .b = (float)texture->b / 255.0f, - .a = (float)texture->a / 255.0f, - }; - /* Render */ GX2SetContextState(data->ctx); wiiuSetTextureShader(); @@ -129,7 +120,7 @@ int WIIU_SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, GX2RSetAttributeBuffer(a_texCoord, 1, a_texCoord->elemSize, 0); GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)&data->u_viewSize); GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[1].offset, 4, (uint32_t *)&tdata->u_texSize); - GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t *)&u_mod); + GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t *)&tdata->u_mod); WIIU_SDL_SetGX2BlendMode(texture->blendMode); GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1); @@ -145,7 +136,6 @@ int WIIU_SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata; GX2RBuffer *a_position, *a_texCoord; WIIUVec2 *a_position_vals, *a_texCoord_vals; - WIIUVec4 u_mod; /* Compute real vertex points */ float x_min = renderer->viewport.x + dstrect->x; @@ -224,14 +214,6 @@ int WIIU_SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, }; GX2RUnlockBufferEx(a_texCoord, 0); - /* Compute color/alpha mod */ - u_mod = (WIIUVec4) { - .r = (float)texture->r / 255.0f, - .g = (float)texture->g / 255.0f, - .b = (float)texture->b / 255.0f, - .a = (float)texture->a / 255.0f, - }; - /* Render */ GX2SetContextState(data->ctx); wiiuSetTextureShader(); @@ -241,7 +223,7 @@ int WIIU_SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, GX2RSetAttributeBuffer(a_texCoord, 1, a_texCoord->elemSize, 0); GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)&data->u_viewSize); GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[1].offset, 4, (uint32_t *)&tdata->u_texSize); - GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t *)&u_mod); + GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t *)&tdata->u_mod); WIIU_SDL_SetGX2BlendMode(texture->blendMode); GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1); diff --git a/src/render/wiiu/SDL_render_wiiu.c b/src/render/wiiu/SDL_render_wiiu.c index d683786e2..f82e36db3 100644 --- a/src/render/wiiu/SDL_render_wiiu.c +++ b/src/render/wiiu/SDL_render_wiiu.c @@ -63,8 +63,8 @@ SDL_Renderer *WIIU_SDL_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->WindowEvent = WIIU_SDL_WindowEvent; renderer->GetOutputSize = WIIU_SDL_GetOutputSize; renderer->CreateTexture = WIIU_SDL_CreateTexture; - //renderer->SetTextureColorMod = WIIU_SDL_SetTextureColorMod; - //renderer->SetTextureAlphaMod = WIIU_SDL_SetTextureAlphaMod; + renderer->SetTextureColorMod = WIIU_SDL_SetTextureColorMod; + renderer->SetTextureAlphaMod = WIIU_SDL_SetTextureAlphaMod; //renderer->SetTextureBlendMode = WIIU_SDL_SetTextureBlendMode; renderer->UpdateTexture = WIIU_SDL_UpdateTexture; renderer->LockTexture = WIIU_SDL_LockTexture; @@ -122,6 +122,7 @@ void WIIU_SDL_CreateWindowTex(SDL_Renderer * renderer, SDL_Window * window) { // Allocate a buffer for the window data->windowTex = (SDL_Texture) { .format = SDL_PIXELFORMAT_RGBA8888, + .r = 255, .g = 255, .b = 255, .a = 255, }; SDL_GetWindowSize(window, &data->windowTex.w, &data->windowTex.h); WIIU_SDL_CreateTexture(renderer, &data->windowTex); diff --git a/src/render/wiiu/SDL_render_wiiu.h b/src/render/wiiu/SDL_render_wiiu.h index 54e6da3e5..106105c53 100644 --- a/src/render/wiiu/SDL_render_wiiu.h +++ b/src/render/wiiu/SDL_render_wiiu.h @@ -68,6 +68,7 @@ typedef struct { GX2Texture texture; GX2ColorBuffer cbuf; WIIUVec4 u_texSize; + WIIUVec4 u_mod; } WIIU_TextureData; static inline GX2RBuffer* WIIU_AllocRenderData(WIIU_RenderData *r, GX2RBuffer buffer) { @@ -99,13 +100,11 @@ void WIIU_SDL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event); int WIIU_SDL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h); int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture); -// SDL changes colour/alpha/blend values internally, this is just to notify us. -// We don't care yet. TODO: could update GX2RBuffers less frequently with these? -/*int WIIU_SDL_SetTextureColorMod(SDL_Renderer * renderer, +int WIIU_SDL_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture); int WIIU_SDL_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture); -int WIIU_SDL_SetTextureBlendMode(SDL_Renderer * renderer, +/*int WIIU_SDL_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture);*/ int WIIU_SDL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, diff --git a/src/render/wiiu/SDL_rpresent_wiiu.c b/src/render/wiiu/SDL_rpresent_wiiu.c index c04e4c3fa..ec9187ca2 100644 --- a/src/render/wiiu/SDL_rpresent_wiiu.c +++ b/src/render/wiiu/SDL_rpresent_wiiu.c @@ -28,7 +28,6 @@ static void render_scene(SDL_Renderer * renderer) { int win_x, win_y, win_w, win_h; GX2RBuffer *a_position, *a_texCoord; WIIUVec2 *a_position_vals, *a_texCoord_vals; - float u_mod[4] = {1.0f, 1.0f, 1.0f, 1.0f}; /* Allocate attribute buffers */ a_position = WIIU_AllocRenderData(data, (GX2RBuffer) { @@ -87,7 +86,7 @@ static void render_scene(SDL_Renderer * renderer) { GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)&u_viewSize); GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[1].offset, 4, (uint32_t *)&tdata->u_texSize); - GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)u_mod); + GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)&tdata->u_mod); GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0); GX2RSetAttributeBuffer(a_texCoord, 1, a_texCoord->elemSize, 0); diff --git a/src/render/wiiu/SDL_rtexture_wiiu.c b/src/render/wiiu/SDL_rtexture_wiiu.c index 9b0e2ba68..01c341006 100644 --- a/src/render/wiiu/SDL_rtexture_wiiu.c +++ b/src/render/wiiu/SDL_rtexture_wiiu.c @@ -107,6 +107,13 @@ int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) .y = texture->h, }; + tdata->u_mod = (WIIUVec4) { + .r = (float)texture->r / 255.0f, + .g = (float)texture->g / 255.0f, + .b = (float)texture->b / 255.0f, + .a = (float)texture->a / 255.0f, + }; + texture->driverdata = tdata; return 0; @@ -178,6 +185,22 @@ int WIIU_SDL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, return 0; } +int WIIU_SDL_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture) +{ + WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata; + /* Compute color mod */ + tdata->u_mod.r = (float)texture->r / 255.0f; + tdata->u_mod.g = (float)texture->g / 255.0f; + tdata->u_mod.b = (float)texture->b / 255.0f; +} + +int WIIU_SDL_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture) +{ + WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata; + /* Compute alpha mod */ + tdata->u_mod.a = (float)texture->a / 255.0f; +} + void WIIU_SDL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) { WIIU_TextureData *tdata; From 64a0a82d0693239a64375a9a366d5f9adb8fbd7d Mon Sep 17 00:00:00 2001 From: rw-r-r-0644 Date: Sun, 10 Mar 2019 00:40:22 +0100 Subject: [PATCH 19/25] render/wiiu: Disable blending for render_scene --- src/render/wiiu/SDL_render_wiiu.c | 1 - src/render/wiiu/SDL_rpresent_wiiu.c | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/render/wiiu/SDL_render_wiiu.c b/src/render/wiiu/SDL_render_wiiu.c index f82e36db3..e97da9cc3 100644 --- a/src/render/wiiu/SDL_render_wiiu.c +++ b/src/render/wiiu/SDL_render_wiiu.c @@ -161,7 +161,6 @@ int WIIU_SDL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) GX2SetAlphaTest(TRUE, GX2_COMPARE_FUNC_GREATER, 0.0f); GX2SetDepthOnlyControl(FALSE, FALSE, GX2_COMPARE_FUNC_NEVER); - GX2SetColorControl(GX2_LOGIC_OP_COPY, 0xFF, FALSE, TRUE); GX2SetCullOnlyControl(GX2_FRONT_FACE_CCW, FALSE, FALSE); return 0; diff --git a/src/render/wiiu/SDL_rpresent_wiiu.c b/src/render/wiiu/SDL_rpresent_wiiu.c index ec9187ca2..1a36b4ebf 100644 --- a/src/render/wiiu/SDL_rpresent_wiiu.c +++ b/src/render/wiiu/SDL_rpresent_wiiu.c @@ -94,6 +94,8 @@ static void render_scene(SDL_Renderer * renderer) { GX2SetPixelTexture(&tdata->texture, wiiuTextureShader.pixelShader->samplerVars[0].location); GX2SetPixelSampler(&tdata->sampler, wiiuTextureShader.pixelShader->samplerVars[0].location); + GX2SetColorControl(GX2_LOGIC_OP_COPY, 0x00, FALSE, TRUE); + GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1); } From 0da66328781775ef6b7c1f774e4a041e816f7ffa Mon Sep 17 00:00:00 2001 From: rw-r-r-0644 Date: Sun, 10 Mar 2019 00:46:05 +0100 Subject: [PATCH 20/25] render/wiiu: Reduce GX2SetContextState calls The function takes a fairly long time to complete --- src/render/wiiu/SDL_rdraw_wiiu.c | 8 +++----- src/render/wiiu/SDL_render_wiiu.c | 11 ++++++----- src/render/wiiu/SDL_rpresent_wiiu.c | 3 +++ 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/render/wiiu/SDL_rdraw_wiiu.c b/src/render/wiiu/SDL_rdraw_wiiu.c index c277895eb..cd7740302 100644 --- a/src/render/wiiu/SDL_rdraw_wiiu.c +++ b/src/render/wiiu/SDL_rdraw_wiiu.c @@ -112,7 +112,6 @@ int WIIU_SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, GX2RUnlockBufferEx(a_texCoord, 0); /* Render */ - GX2SetContextState(data->ctx); wiiuSetTextureShader(); GX2SetPixelTexture(&tdata->texture, 0); GX2SetPixelSampler(&tdata->sampler, 0); @@ -215,7 +214,6 @@ int WIIU_SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, GX2RUnlockBufferEx(a_texCoord, 0); /* Render */ - GX2SetContextState(data->ctx); wiiuSetTextureShader(); GX2SetPixelTexture(&tdata->texture, 0); GX2SetPixelSampler(&tdata->sampler, 0); @@ -265,7 +263,6 @@ int WIIU_SDL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points GX2RUnlockBufferEx(a_position, 0); /* Render points */ - GX2SetContextState(data->ctx); wiiuSetColorShader(); GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0); GX2SetVertexUniformReg(wiiuColorShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)&data->u_viewSize); @@ -312,7 +309,6 @@ int WIIU_SDL_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, GX2RUnlockBufferEx(a_position, 0); /* Render lines */ - GX2SetContextState(data->ctx); wiiuSetColorShader(); GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0); GX2SetVertexUniformReg(wiiuColorShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)&data->u_viewSize); @@ -373,7 +369,6 @@ int WIIU_SDL_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, i GX2RUnlockBufferEx(a_position, 0); /* Render rects */ - GX2SetContextState(data->ctx); wiiuSetColorShader(); GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0); GX2SetVertexUniformReg(wiiuColorShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)&data->u_viewSize); @@ -411,7 +406,10 @@ int WIIU_SDL_RenderClear(SDL_Renderer * renderer) (float)renderer->g / 255.0f, (float)renderer->b / 255.0f, (float)renderer->a / 255.0f); + + /* Restore SDL context state */ GX2SetContextState(data->ctx); + return 0; } diff --git a/src/render/wiiu/SDL_render_wiiu.c b/src/render/wiiu/SDL_render_wiiu.c index e97da9cc3..82944b86c 100644 --- a/src/render/wiiu/SDL_render_wiiu.c +++ b/src/render/wiiu/SDL_render_wiiu.c @@ -101,6 +101,12 @@ SDL_Renderer *WIIU_SDL_CreateRenderer(SDL_Window * window, Uint32 flags) data->ctx = (GX2ContextState *) memalign(GX2_CONTEXT_STATE_ALIGNMENT, sizeof(GX2ContextState)); memset(data->ctx, 0, sizeof(GX2ContextState)); GX2SetupContextStateEx(data->ctx, TRUE); + GX2SetContextState(data->ctx); + + // Setup some context state options + GX2SetAlphaTest(TRUE, GX2_COMPARE_FUNC_GREATER, 0.0f); + GX2SetDepthOnlyControl(FALSE, FALSE, GX2_COMPARE_FUNC_NEVER); + GX2SetCullOnlyControl(GX2_FRONT_FACE_CCW, FALSE, FALSE); // Make a texture for the window WIIU_SDL_CreateWindowTex(renderer, window); @@ -151,7 +157,6 @@ int WIIU_SDL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) }; // Update context state - GX2SetContextState(data->ctx); GX2SetColorBuffer(target, GX2_RENDER_TARGET_0); // These may be unnecessary - see SDL_render.c: SDL_SetRenderTarget's calls // to UpdateViewport and UpdateClipRect. TODO for once the render is @@ -159,10 +164,6 @@ int WIIU_SDL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) GX2SetViewport(0, 0, (float)target->surface.width, (float)target->surface.height, 0.0f, 1.0f); GX2SetScissor(0, 0, (float)target->surface.width, (float)target->surface.height); - GX2SetAlphaTest(TRUE, GX2_COMPARE_FUNC_GREATER, 0.0f); - GX2SetDepthOnlyControl(FALSE, FALSE, GX2_COMPARE_FUNC_NEVER); - GX2SetCullOnlyControl(GX2_FRONT_FACE_CCW, FALSE, FALSE); - return 0; } diff --git a/src/render/wiiu/SDL_rpresent_wiiu.c b/src/render/wiiu/SDL_rpresent_wiiu.c index 1a36b4ebf..ef7074425 100644 --- a/src/render/wiiu/SDL_rpresent_wiiu.c +++ b/src/render/wiiu/SDL_rpresent_wiiu.c @@ -122,6 +122,9 @@ void WIIU_SDL_RenderPresent(SDL_Renderer * renderer) WHBGfxFinishRender(); WIIU_FreeRenderData(data); + +/* Restore SDL context state */ + GX2SetContextState(data->ctx); } #endif //SDL_VIDEO_RENDER_WIIU From fd0fb3211cebc3f97917f0381c20057337a8fc34 Mon Sep 17 00:00:00 2001 From: rw-r-r-0644 Date: Sun, 10 Mar 2019 00:53:02 +0100 Subject: [PATCH 21/25] render/wiiu: Fix compiler warnings --- src/render/wiiu/SDL_rdraw_wiiu.c | 1 + src/render/wiiu/SDL_render_wiiu.c | 1 - src/render/wiiu/SDL_rpresent_wiiu.c | 3 ++- src/render/wiiu/SDL_rtexture_wiiu.c | 6 ++++++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/render/wiiu/SDL_rdraw_wiiu.c b/src/render/wiiu/SDL_rdraw_wiiu.c index cd7740302..b1363ffa6 100644 --- a/src/render/wiiu/SDL_rdraw_wiiu.c +++ b/src/render/wiiu/SDL_rdraw_wiiu.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/src/render/wiiu/SDL_render_wiiu.c b/src/render/wiiu/SDL_render_wiiu.c index 82944b86c..c2654864f 100644 --- a/src/render/wiiu/SDL_render_wiiu.c +++ b/src/render/wiiu/SDL_render_wiiu.c @@ -189,7 +189,6 @@ void WIIU_SDL_DestroyRenderer(SDL_Renderer * renderer) int WIIU_SDL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 format, void * pixels, int pitch) { - WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; SDL_Texture* target = WIIU_GetRenderTarget(renderer); WIIU_TextureData* tdata = (WIIU_TextureData*) target->driverdata; diff --git a/src/render/wiiu/SDL_rpresent_wiiu.c b/src/render/wiiu/SDL_rpresent_wiiu.c index ef7074425..a1a26cafd 100644 --- a/src/render/wiiu/SDL_rpresent_wiiu.c +++ b/src/render/wiiu/SDL_rpresent_wiiu.c @@ -9,8 +9,9 @@ #include "SDL_render_wiiu.h" #include -#include +#include #include +#include #include #include diff --git a/src/render/wiiu/SDL_rtexture_wiiu.c b/src/render/wiiu/SDL_rtexture_wiiu.c index 01c341006..8317ffe7c 100644 --- a/src/render/wiiu/SDL_rtexture_wiiu.c +++ b/src/render/wiiu/SDL_rtexture_wiiu.c @@ -188,17 +188,23 @@ int WIIU_SDL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, int WIIU_SDL_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture) { WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata; + /* Compute color mod */ tdata->u_mod.r = (float)texture->r / 255.0f; tdata->u_mod.g = (float)texture->g / 255.0f; tdata->u_mod.b = (float)texture->b / 255.0f; + + return 0; } int WIIU_SDL_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture) { WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata; + /* Compute alpha mod */ tdata->u_mod.a = (float)texture->a / 255.0f; + + return 0; } void WIIU_SDL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) From 89d33c27cf162917b93d6c511b147025c3dce7f8 Mon Sep 17 00:00:00 2001 From: rw-r-r-0644 Date: Sun, 10 Mar 2019 01:05:18 +0100 Subject: [PATCH 22/25] render/wiiu: Update RenderReadPixels to lock the surface and use the correct texture format --- src/render/wiiu/SDL_render_wiiu.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/render/wiiu/SDL_render_wiiu.c b/src/render/wiiu/SDL_render_wiiu.c index c2654864f..7ebcbe776 100644 --- a/src/render/wiiu/SDL_render_wiiu.c +++ b/src/render/wiiu/SDL_render_wiiu.c @@ -30,6 +30,7 @@ #include "SDL_render_wiiu.h" #include +#include #include #include @@ -191,9 +192,8 @@ int WIIU_SDL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, { SDL_Texture* target = WIIU_GetRenderTarget(renderer); WIIU_TextureData* tdata = (WIIU_TextureData*) target->driverdata; - - Uint32 src_format; - void *src_pixels; + Uint8 *src_image; + int ret; /* NOTE: The rect is already adjusted according to the viewport by * SDL_RenderReadPixels. @@ -204,14 +204,16 @@ int WIIU_SDL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, return SDL_SetError("Tried to read outside of surface bounds"); } - src_format = SDL_PIXELFORMAT_RGBA8888; // TODO once working: other formats/checks - src_pixels = (void*)((Uint8 *) tdata->cbuf.surface.image + - rect->y * tdata->cbuf.surface.pitch + - rect->x * 4); + src_image = GX2RLockSurfaceEx(&tdata->cbuf.surface, 0, GX2R_RESOURCE_LOCKED_READ_ONLY); - return SDL_ConvertPixels(rect->w, rect->h, - src_format, src_pixels, tdata->cbuf.surface.pitch, - format, pixels, pitch); + ret = SDL_ConvertPixels(rect->w, rect->h, target->format, + src_image + rect->y * tdata->cbuf.surface.pitch + rect->x * 4, + tdata->cbuf.surface.pitch, + format, pixels, pitch); + + GX2RUnlockSurfaceEx(&tdata->cbuf.surface, 0, GX2R_RESOURCE_LOCKED_READ_ONLY); + + return ret; } From f5b39a8b2af477673c9289a17f5a25de6ceab1bc Mon Sep 17 00:00:00 2001 From: rw-r-r-0644 Date: Sun, 10 Mar 2019 01:06:15 +0100 Subject: [PATCH 23/25] render/wiiu: Use WIIU_FreeRenderData in DestroyRenderer --- src/render/wiiu/SDL_render_wiiu.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/render/wiiu/SDL_render_wiiu.c b/src/render/wiiu/SDL_render_wiiu.c index 7ebcbe776..4c8323fe4 100644 --- a/src/render/wiiu/SDL_render_wiiu.c +++ b/src/render/wiiu/SDL_render_wiiu.c @@ -172,11 +172,7 @@ void WIIU_SDL_DestroyRenderer(SDL_Renderer * renderer) { WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; - while (data->listfree) { - void *ptr = data->listfree; - data->listfree = data->listfree->next; - SDL_free(ptr); - } + WIIU_FreeRenderData(data); free(data->ctx); From fd92b81847fbe4f8f53ced308f389950e8f1cee2 Mon Sep 17 00:00:00 2001 From: rw-r-r-0644 Date: Sun, 10 Mar 2019 01:58:34 +0100 Subject: [PATCH 24/25] render/wiiu: Code cleanup * Remove unused functions * Remove unneeded checks * Uniform coding style with the rest of SDL --- src/render/wiiu/SDL_rdraw_wiiu.c | 40 +++------- src/render/wiiu/SDL_render_wiiu.c | 86 ++++++++++----------- src/render/wiiu/SDL_render_wiiu.h | 114 ++++++++++++++-------------- src/render/wiiu/SDL_rpresent_wiiu.c | 46 ++++++++--- src/render/wiiu/SDL_rtexture_wiiu.c | 71 +++++++---------- src/render/wiiu/SDL_rwindow_wiiu.c | 42 +++++----- 6 files changed, 187 insertions(+), 212 deletions(-) diff --git a/src/render/wiiu/SDL_rdraw_wiiu.c b/src/render/wiiu/SDL_rdraw_wiiu.c index b1363ffa6..bab0e403c 100644 --- a/src/render/wiiu/SDL_rdraw_wiiu.c +++ b/src/render/wiiu/SDL_rdraw_wiiu.c @@ -62,7 +62,7 @@ int WIIU_SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, GX2RInvalidateSurface(&tdata->texture.surface, 0, 0); } -/* Allocate attribute buffers */ + /* Allocate attribute buffers */ a_position = WIIU_AllocRenderData(data, (GX2RBuffer) { .flags = GX2R_RESOURCE_BIND_VERTEX_BUFFER | @@ -78,13 +78,13 @@ int WIIU_SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, .elemCount = 4, // 4 corners }); -/* Compute vertex points */ + /* Compute vertex points */ x_min = renderer->viewport.x + dstrect->x; y_min = renderer->viewport.y + dstrect->y; x_max = renderer->viewport.x + dstrect->x + dstrect->w; y_max = renderer->viewport.y + dstrect->y + dstrect->h; -/* Save them */ + /* Save them */ a_position_vals = GX2RLockBufferEx(a_position, 0); a_position_vals[0] = (WIIUVec2){.x = x_min, .y = y_min}; a_position_vals[1] = (WIIUVec2){.x = x_max, .y = y_min}; @@ -92,7 +92,7 @@ int WIIU_SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, a_position_vals[3] = (WIIUVec2){.x = x_min, .y = y_max}; GX2RUnlockBufferEx(a_position, 0); -/* Compute texture coords */ + /* Compute texture coords */ a_texCoord_vals = GX2RLockBufferEx(a_texCoord, 0); a_texCoord_vals[0] = (WIIUVec2) { .x = srcrect->x, @@ -168,7 +168,7 @@ int WIIU_SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, GX2RInvalidateSurface(&tdata->texture.surface, 0, 0); } - /* Allocate attribute buffers */ + /* Allocate attribute buffers */ a_position = WIIU_AllocRenderData(data, (GX2RBuffer) { .flags = GX2R_RESOURCE_BIND_VERTEX_BUFFER | @@ -184,7 +184,7 @@ int WIIU_SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, .elemCount = 4, // 4 corners }); - /* Save vertex points */ + /* Save vertex points */ a_position_vals = GX2RLockBufferEx(a_position, 0); for (int i = 0; i < 4; i++) { a_position_vals[i] = (WIIUVec2) { @@ -194,7 +194,7 @@ int WIIU_SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, } GX2RUnlockBufferEx(a_position, 0); - /* Compute texture coords */ + /* Compute texture coords */ a_texCoord_vals = GX2RLockBufferEx(a_texCoord, 0); a_texCoord_vals[0] = (WIIUVec2) { .x = srcrect->x, @@ -244,12 +244,12 @@ int WIIU_SDL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points .a = (float)renderer->a / 255.0f, }; - /* Allocate attribute buffers */ + /* Allocate attribute buffers */ a_position = WIIU_AllocRenderData(data, (GX2RBuffer) { .flags = GX2R_RESOURCE_BIND_VERTEX_BUFFER | GX2R_RESOURCE_USAGE_CPU_WRITE, - .elemSize = sizeof(WIIUVec2), // float x/y for each point + .elemSize = sizeof(WIIUVec2), /* float x/y for each point */ .elemCount = count, }); @@ -295,7 +295,7 @@ int WIIU_SDL_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, .flags = GX2R_RESOURCE_BIND_VERTEX_BUFFER | GX2R_RESOURCE_USAGE_CPU_WRITE, - .elemSize = sizeof(WIIUVec2), // float x/y for each point + .elemSize = sizeof(WIIUVec2), /* float x/y for each point */ .elemCount = count, }); @@ -380,22 +380,6 @@ int WIIU_SDL_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, i return 0; } -/*void WIIU_SDL_RenderPresent(SDL_Renderer * renderer) -{ - WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; - SDL_Window *window = renderer->window; - - GX2Flush(); - GX2DrawDone(); - GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, data->cbuf.surface.image, data->cbuf.surface.imageSize); - - if (window) { - SDL_UpdateWindowSurface(window); - } - - WIIU_FreeRenderData(data); -}*/ - int WIIU_SDL_RenderClear(SDL_Renderer * renderer) { WIIU_RenderData* data = (WIIU_RenderData*) renderer->driverdata; @@ -448,7 +432,7 @@ static void WIIU_SDL_SetGX2BlendMode(SDL_BlendMode mode) /* A = [srcA * 0] + [dstA * 1] */ GX2_BLEND_MODE_ZERO, GX2_BLEND_MODE_ONE, GX2_BLEND_COMBINE_MODE_ADD); - } + } } -#endif //SDL_VIDEO_RENDER_WIIU +#endif /* SDL_VIDEO_RENDER_WIIU */ diff --git a/src/render/wiiu/SDL_render_wiiu.c b/src/render/wiiu/SDL_render_wiiu.c index 4c8323fe4..139136c15 100644 --- a/src/render/wiiu/SDL_render_wiiu.c +++ b/src/render/wiiu/SDL_render_wiiu.c @@ -1,7 +1,7 @@ /* Simple DirectMedia Layer - Copyright (C) 2018-2018 Ash Logan - Copyright (C) 2018-2018 Roberto Van Eeden + Copyright (C) 2018-2019 Ash Logan + Copyright (C) 2018-2019 Roberto Van Eeden This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,18 +26,12 @@ #include "../../video/wiiu/SDL_wiiuvideo.h" #include "../../video/wiiu/wiiu_shaders.h" #include "../SDL_sysrender.h" -#include "SDL_hints.h" #include "SDL_render_wiiu.h" #include #include #include -#include -#include -#include -#include -#include SDL_RenderDriver WIIU_RenderDriver; @@ -59,14 +53,12 @@ SDL_Renderer *WIIU_SDL_CreateRenderer(SDL_Window * window, Uint32 flags) return NULL; } - // See sdl_render_wiiu.h for explanations of commented-out functions - + /* Setup renderer functions */ renderer->WindowEvent = WIIU_SDL_WindowEvent; renderer->GetOutputSize = WIIU_SDL_GetOutputSize; renderer->CreateTexture = WIIU_SDL_CreateTexture; renderer->SetTextureColorMod = WIIU_SDL_SetTextureColorMod; renderer->SetTextureAlphaMod = WIIU_SDL_SetTextureAlphaMod; - //renderer->SetTextureBlendMode = WIIU_SDL_SetTextureBlendMode; renderer->UpdateTexture = WIIU_SDL_UpdateTexture; renderer->LockTexture = WIIU_SDL_LockTexture; renderer->UnlockTexture = WIIU_SDL_UnlockTexture; @@ -87,38 +79,39 @@ SDL_Renderer *WIIU_SDL_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->driverdata = data; renderer->window = window; - // Prepare shaders + /* Prepare shaders */ wiiuInitTextureShader(); wiiuInitColorShader(); - // List of attibutes to free after render + /* List of attibutes to free after render */ data->listfree = NULL; - // Setup line and point size + /* Setup line and point size */ GX2SetLineWidth(1.0f); GX2SetPointSize(1.0f, 1.0f); - // Create a fresh context state + /* Create a fresh context state */ data->ctx = (GX2ContextState *) memalign(GX2_CONTEXT_STATE_ALIGNMENT, sizeof(GX2ContextState)); - memset(data->ctx, 0, sizeof(GX2ContextState)); + SDL_memset(data->ctx, 0, sizeof(GX2ContextState)); GX2SetupContextStateEx(data->ctx, TRUE); GX2SetContextState(data->ctx); - // Setup some context state options + /* Setup some context state options */ GX2SetAlphaTest(TRUE, GX2_COMPARE_FUNC_GREATER, 0.0f); GX2SetDepthOnlyControl(FALSE, FALSE, GX2_COMPARE_FUNC_NEVER); GX2SetCullOnlyControl(GX2_FRONT_FACE_CCW, FALSE, FALSE); - // Make a texture for the window + /* Make a texture for the window */ WIIU_SDL_CreateWindowTex(renderer, window); - // Setup colour buffer, rendering to the window + /* Setup colour buffer, rendering to the window */ WIIU_SDL_SetRenderTarget(renderer, NULL); return renderer; } -void WIIU_SDL_CreateWindowTex(SDL_Renderer * renderer, SDL_Window * window) { +void WIIU_SDL_CreateWindowTex(SDL_Renderer * renderer, SDL_Window * window) +{ WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; if (data->windowTex.driverdata) { @@ -126,12 +119,15 @@ void WIIU_SDL_CreateWindowTex(SDL_Renderer * renderer, SDL_Window * window) { data->windowTex = (SDL_Texture) {0}; } - // Allocate a buffer for the window + /* Allocate a buffer for the window */ data->windowTex = (SDL_Texture) { .format = SDL_PIXELFORMAT_RGBA8888, .r = 255, .g = 255, .b = 255, .a = 255, }; + SDL_GetWindowSize(window, &data->windowTex.w, &data->windowTex.h); + + /* Setup texture and color buffer for the window */ WIIU_SDL_CreateTexture(renderer, &data->windowTex); } @@ -139,31 +135,24 @@ int WIIU_SDL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) { WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; - GX2ColorBuffer *target; + /* Set window or texture as target */ + WIIU_TextureData *tdata = (WIIU_TextureData *)((texture) ? texture->driverdata + : data->windowTex.driverdata); - if (texture) { - // Set texture as target - WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata; - target = &tdata->cbuf; - } else { - // Set window texture as target - WIIU_TextureData *tdata = (WIIU_TextureData *) data->windowTex.driverdata; - target = &tdata->cbuf; - } - - // Update u_viewSize + /* Update u_viewSize */ data->u_viewSize = (WIIUVec4) { - .x = (float)target->surface.width, - .y = (float)target->surface.height, + .x = (float)tdata->cbuf.surface.width, + .y = (float)tdata->cbuf.surface.height, }; - // Update context state - GX2SetColorBuffer(target, GX2_RENDER_TARGET_0); - // These may be unnecessary - see SDL_render.c: SDL_SetRenderTarget's calls - // to UpdateViewport and UpdateClipRect. TODO for once the render is - // basically working. - GX2SetViewport(0, 0, (float)target->surface.width, (float)target->surface.height, 0.0f, 1.0f); - GX2SetScissor(0, 0, (float)target->surface.width, (float)target->surface.height); + /* Update context state */ + GX2SetColorBuffer(&tdata->cbuf, GX2_RENDER_TARGET_0); + + /* These may be unnecessary - see SDL_render.c: SDL_SetRenderTarget's calls + to UpdateViewport and UpdateClipRect. TODO for once the render is + basically working */ + GX2SetViewport(0, 0, (float)tdata->cbuf.surface.width, (float)tdata->cbuf.surface.height, 0.0f, 1.0f); + GX2SetScissor(0, 0, (float)tdata->cbuf.surface.width, (float)tdata->cbuf.surface.height); return 0; } @@ -192,8 +181,7 @@ int WIIU_SDL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, int ret; /* NOTE: The rect is already adjusted according to the viewport by - * SDL_RenderReadPixels. - */ + SDL_RenderReadPixels */ if (rect->x < 0 || rect->x+rect->w > tdata->cbuf.surface.width || rect->y < 0 || rect->y+rect->h > tdata->cbuf.surface.height) { @@ -202,10 +190,11 @@ int WIIU_SDL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, src_image = GX2RLockSurfaceEx(&tdata->cbuf.surface, 0, GX2R_RESOURCE_LOCKED_READ_ONLY); + /* Convert and copy the pixels to target buffer */ ret = SDL_ConvertPixels(rect->w, rect->h, target->format, - src_image + rect->y * tdata->cbuf.surface.pitch + rect->x * 4, - tdata->cbuf.surface.pitch, - format, pixels, pitch); + src_image + rect->y * tdata->cbuf.surface.pitch + rect->x * 4, + tdata->cbuf.surface.pitch, + format, pixels, pitch); GX2RUnlockSurfaceEx(&tdata->cbuf.surface, 0, GX2R_RESOURCE_LOCKED_READ_ONLY); @@ -213,7 +202,8 @@ int WIIU_SDL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, } -SDL_RenderDriver WIIU_RenderDriver = { +SDL_RenderDriver WIIU_RenderDriver = +{ .CreateRenderer = WIIU_SDL_CreateRenderer, .info = { .name = "WiiU GX2", diff --git a/src/render/wiiu/SDL_render_wiiu.h b/src/render/wiiu/SDL_render_wiiu.h index 106105c53..fcf5b3180 100644 --- a/src/render/wiiu/SDL_render_wiiu.h +++ b/src/render/wiiu/SDL_render_wiiu.h @@ -1,7 +1,7 @@ /* Simple DirectMedia Layer - Copyright (C) 2018-2018 Ash Logan - Copyright (C) 2018-2018 Roberto Van Eeden + Copyright (C) 2018-2019 Ash Logan + Copyright (C) 2018-2019 Roberto Van Eeden This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,7 +19,6 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ - #include "../../SDL_internal.h" #ifndef SDL_render_wiiu_h @@ -29,41 +28,54 @@ #include "SDL_pixels.h" #include #include +#include +#include #include -typedef struct { +/* Driver internal data structures */ +typedef struct +{ union { float x, r; }; union { float y, g; }; } WIIUVec2; -typedef struct { +typedef struct +{ union { float x, r; }; union { float y, g; }; union { float z, b; }; } WIIUVec3; -typedef struct { +typedef struct +{ union { float x, r; }; union { float y, g; }; union { float z, b; }; union { float w, a; }; } WIIUVec4; +typedef struct +{ + GX2SurfaceFormat fmt; + uint32_t compMap; +} WIIUPixFmt; + typedef struct { void *next; GX2RBuffer buffer; } WIIU_RenderAllocData; -//Driver internal data structures -typedef struct { +typedef struct +{ GX2ContextState *ctx; WIIU_RenderAllocData *listfree; WIIUVec4 u_viewSize; SDL_Texture windowTex; } WIIU_RenderData; -typedef struct { +typedef struct +{ GX2Sampler sampler; GX2Texture texture; GX2ColorBuffer cbuf; @@ -71,30 +83,7 @@ typedef struct { WIIUVec4 u_mod; } WIIU_TextureData; -static inline GX2RBuffer* WIIU_AllocRenderData(WIIU_RenderData *r, GX2RBuffer buffer) { - WIIU_RenderAllocData *rdata = SDL_malloc(sizeof(WIIU_RenderAllocData)); - - rdata->buffer = buffer; - if (!GX2RCreateBuffer(&rdata->buffer)) { - SDL_free(rdata); - return 0; - } - - rdata->next = r->listfree; - r->listfree = rdata; - return &rdata->buffer; -} - -static inline void WIIU_FreeRenderData(WIIU_RenderData *r) { - while (r->listfree) { - WIIU_RenderAllocData *ptr = r->listfree; - r->listfree = r->listfree->next; - GX2RDestroyBufferEx(&ptr->buffer, 0); - SDL_free(ptr); - } -} - -//SDL_render API implementation +/* SDL_render API implementation */ SDL_Renderer *WIIU_SDL_CreateRenderer(SDL_Window * window, Uint32 flags); void WIIU_SDL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event); @@ -104,8 +93,6 @@ int WIIU_SDL_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture); int WIIU_SDL_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture); -/*int WIIU_SDL_SetTextureBlendMode(SDL_Renderer * renderer, - SDL_Texture * texture);*/ int WIIU_SDL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch); @@ -133,38 +120,55 @@ void WIIU_SDL_RenderPresent(SDL_Renderer * renderer); void WIIU_SDL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture); void WIIU_SDL_DestroyRenderer(SDL_Renderer * renderer); -//Driver internal functions +/* Driver internal functions */ void WIIU_SDL_CreateWindowTex(SDL_Renderer * renderer, SDL_Window * window); -//Utility/helper functions -static inline Uint32 TextureNextPow2(Uint32 w) { - Uint32 n = 2; - if(w == 0) +/* Utility/helper functions */ +static inline GX2RBuffer * WIIU_AllocRenderData(WIIU_RenderData *r, GX2RBuffer buffer) +{ + WIIU_RenderAllocData *rdata = SDL_malloc(sizeof(WIIU_RenderAllocData)); + + rdata->buffer = buffer; + if (!GX2RCreateBuffer(&rdata->buffer)) { + SDL_free(rdata); return 0; - while(w > n) - n <<= 1; - return n; + } + + rdata->next = r->listfree; + r->listfree = rdata; + return &rdata->buffer; } -typedef struct WIIUPixFmt { - GX2SurfaceFormat fmt; - uint32_t compMap; -} WIIUPixFmt; +static inline void WIIU_FreeRenderData(WIIU_RenderData *r) +{ + while (r->listfree) { + WIIU_RenderAllocData *ptr = r->listfree; + r->listfree = r->listfree->next; + GX2RDestroyBufferEx(&ptr->buffer, 0); + SDL_free(ptr); + } +} -static inline SDL_Texture* WIIU_GetRenderTarget(SDL_Renderer* renderer) { +static inline SDL_Texture * WIIU_GetRenderTarget(SDL_Renderer* renderer) +{ WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; - if (renderer->target) return renderer->target; + if (renderer->target) { + return renderer->target; + } + return &data->windowTex; } -static inline WIIUPixFmt SDLFormatToWIIUFormat(Uint32 format) { +static inline WIIUPixFmt SDLFormatToWIIUFormat(Uint32 format) +{ WIIUPixFmt outFmt = { /* sane defaults? */ .fmt = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8, .compMap = 0x00010203, }; + switch (format) { - /* packed16 formats: 4 bits/channel */ + /* packed16 formats: 4 bits/channel */ case SDL_PIXELFORMAT_RGB444: /* aka XRGB4444 */ case SDL_PIXELFORMAT_ARGB4444: { outFmt.fmt = GX2_SURFACE_FORMAT_UNORM_R4_G4_B4_A4; @@ -187,7 +191,7 @@ static inline WIIUPixFmt SDLFormatToWIIUFormat(Uint32 format) { break; } - /* packed16 formats: 5 bits/channel */ + /* packed16 formats: 5 bits/channel */ case SDL_PIXELFORMAT_RGB555: /* aka XRGB1555 */ case SDL_PIXELFORMAT_ARGB1555: { outFmt.fmt = GX2_SURFACE_FORMAT_UNORM_R5_G5_B5_A1; @@ -211,7 +215,7 @@ static inline WIIUPixFmt SDLFormatToWIIUFormat(Uint32 format) { break; } - /* packed16 formats: 565 */ + /* packed16 formats: 565 */ case SDL_PIXELFORMAT_RGB565: { outFmt.fmt = GX2_SURFACE_FORMAT_UNORM_R5_G6_B5; outFmt.compMap = 0x00010203; @@ -223,7 +227,7 @@ static inline WIIUPixFmt SDLFormatToWIIUFormat(Uint32 format) { break; } - /* packed32 formats */ + /* packed32 formats */ case SDL_PIXELFORMAT_RGBA8888: case SDL_PIXELFORMAT_RGBX8888: { outFmt.fmt = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8; @@ -253,7 +257,7 @@ static inline WIIUPixFmt SDLFormatToWIIUFormat(Uint32 format) { break; } default: { - /* TODO return an error */ + /* TODO return an error */ printf("SDL: WiiU format not recognised (SDL: %08X)\n", format); break; } diff --git a/src/render/wiiu/SDL_rpresent_wiiu.c b/src/render/wiiu/SDL_rpresent_wiiu.c index a1a26cafd..6b0274414 100644 --- a/src/render/wiiu/SDL_rpresent_wiiu.c +++ b/src/render/wiiu/SDL_rpresent_wiiu.c @@ -1,11 +1,30 @@ +/* + Simple DirectMedia Layer + Copyright (C) 2018-2019 Ash Logan + Copyright (C) 2018-2019 Roberto Van Eeden + + 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" #if SDL_VIDEO_RENDER_WIIU -#include "../../video/wiiu/SDL_wiiuvideo.h" #include "../../video/wiiu/wiiu_shaders.h" #include "../SDL_sysrender.h" -#include "SDL_hints.h" #include "SDL_render_wiiu.h" #include @@ -20,7 +39,8 @@ static const WIIUVec4 u_viewSize = {.x = (float)SCREEN_WIDTH, .y = (float)SCREEN_HEIGHT}; -static void render_scene(SDL_Renderer * renderer) { +static void render_scene(SDL_Renderer * renderer) +{ WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; WIIU_TextureData *tdata = (WIIU_TextureData *) data->windowTex.driverdata; @@ -30,13 +50,13 @@ static void render_scene(SDL_Renderer * renderer) { GX2RBuffer *a_position, *a_texCoord; WIIUVec2 *a_position_vals, *a_texCoord_vals; - /* Allocate attribute buffers */ + /* Allocate attribute buffers */ a_position = WIIU_AllocRenderData(data, (GX2RBuffer) { .flags = GX2R_RESOURCE_BIND_VERTEX_BUFFER | GX2R_RESOURCE_USAGE_CPU_WRITE, - .elemSize = sizeof(WIIUVec2), // float x/y for each corner - .elemCount = 4, // 4 corners + .elemSize = sizeof(WIIUVec2), /* float x/y for each corner */ + .elemCount = 4, /* 4 corners */ }); a_texCoord = WIIU_AllocRenderData(data, (GX2RBuffer) { .flags = @@ -46,14 +66,14 @@ static void render_scene(SDL_Renderer * renderer) { .elemCount = 4, // 4 corners }); -/* Calculate and save positions */ + /* Calculate and save positions */ if (SDL_GetWindowFlags(renderer->window) & SDL_WINDOW_FULLSCREEN) { win_x = 0; win_y = 0; win_w = SCREEN_WIDTH; win_h = SCREEN_HEIGHT; } else { - /* Center */ + /* Center */ SDL_GetWindowSize(renderer->window, &win_w, &win_h); win_x = (SCREEN_WIDTH - win_w) / 2; win_y = (SCREEN_HEIGHT - win_h) / 2; @@ -74,7 +94,7 @@ static void render_scene(SDL_Renderer * renderer) { }; GX2RUnlockBufferEx(a_position, 0); -/* Compute texture coords */ + /* Compute texture coords */ a_texCoord_vals = GX2RLockBufferEx(a_texCoord, 0); a_texCoord_vals[0] = (WIIUVec2) {.x = 0.0f, .y = tex_h}; a_texCoord_vals[1] = (WIIUVec2) {.x = tex_w, .y = tex_h}; @@ -82,6 +102,7 @@ static void render_scene(SDL_Renderer * renderer) { a_texCoord_vals[3] = (WIIUVec2) {.x = 0.0f, .y = 0.0f}; GX2RUnlockBufferEx(a_texCoord, 0); + /* Render the window */ WHBGfxClearColor(0.0f, 0.0f, 0.0f, 1.0f); wiiuSetTextureShader(); @@ -107,7 +128,7 @@ void WIIU_SDL_RenderPresent(SDL_Renderer * renderer) WHBGfxBeginRender(); -/* Only render to TV if the window is *not* drc-only */ + /* Only render to TV if the window is *not* drc-only */ if (!(flags & SDL_WINDOW_WIIU_GAMEPAD_ONLY)) { WHBGfxBeginRenderTV(); render_scene(renderer); @@ -122,10 +143,11 @@ void WIIU_SDL_RenderPresent(SDL_Renderer * renderer) WHBGfxFinishRender(); + /* Free the list of render data */ WIIU_FreeRenderData(data); -/* Restore SDL context state */ + /* Restore SDL context state */ GX2SetContextState(data->ctx); } -#endif //SDL_VIDEO_RENDER_WIIU +#endif /* SDL_VIDEO_RENDER_WIIU */ diff --git a/src/render/wiiu/SDL_rtexture_wiiu.c b/src/render/wiiu/SDL_rtexture_wiiu.c index 8317ffe7c..6e04e70cd 100644 --- a/src/render/wiiu/SDL_rtexture_wiiu.c +++ b/src/render/wiiu/SDL_rtexture_wiiu.c @@ -1,7 +1,7 @@ /* Simple DirectMedia Layer - Copyright (C) 2018-2018 Ash Logan - Copyright (C) 2018-2018 Roberto Van Eeden + Copyright (C) 2018-2019 Ash Logan + Copyright (C) 2018-2019 Roberto Van Eeden This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,9 +23,7 @@ #if SDL_VIDEO_RENDER_WIIU -#include "../../video/wiiu/SDL_wiiuvideo.h" #include "../SDL_sysrender.h" -#include "SDL_hints.h" #include "SDL_render_wiiu.h" #include @@ -36,21 +34,18 @@ #include #include -#include #include -#include -#include -#include int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) { WIIUPixFmt gx2_fmt; BOOL res; WIIU_TextureData *tdata = (WIIU_TextureData *) SDL_calloc(1, sizeof(*tdata)); - if (!tdata) + if (!tdata) { return SDL_OutOfMemory(); + } - // Setup sampler + /* Setup sampler */ if (texture->scaleMode == SDL_ScaleModeNearest) { GX2InitSampler(&tdata->sampler, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_POINT); } else { @@ -60,10 +55,11 @@ int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) gx2_fmt = SDLFormatToWIIUFormat(texture->format); + /* Setup GX2Texture */ tdata->texture.surface.width = texture->w; tdata->texture.surface.height = texture->h; tdata->texture.surface.format = gx2_fmt.fmt; - tdata->texture.surface.depth = 1; //? + tdata->texture.surface.depth = 1; tdata->texture.surface.dim = GX2_SURFACE_DIM_TEXTURE_2D; tdata->texture.surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED; tdata->texture.surface.mipLevels = 1; @@ -73,11 +69,12 @@ int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) GX2CalcSurfaceSizeAndAlignment(&tdata->texture.surface); GX2InitTextureRegs(&tdata->texture); + /* Setup GX2ColorBuffer */ tdata->cbuf.surface = tdata->texture.surface; tdata->cbuf.viewNumSlices = 1; GX2InitColorBufferRegs(&tdata->cbuf); -/* Allocate the texture's surface */ + /* Allocate the texture's surface */ res = GX2RCreateSurface( &tdata->texture.surface, GX2R_RESOURCE_BIND_TEXTURE | GX2R_RESOURCE_BIND_COLOR_BUFFER | @@ -89,7 +86,7 @@ int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) return SDL_OutOfMemory(); } -/* Allocate a colour buffer, using the same backing buffer */ + /* Allocate a colour buffer, using the same backing buffer */ res = GX2RCreateSurfaceUserMemory( &tdata->cbuf.surface, tdata->texture.surface.image, @@ -102,11 +99,13 @@ int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) return SDL_OutOfMemory(); } + /* Initialize texture size uniform */ tdata->u_texSize = (WIIUVec4) { .x = texture->w, .y = texture->h, }; + /* Initialize color modifier uniform */ tdata->u_mod = (WIIUVec4) { .r = (float)texture->r / 255.0f, .g = (float)texture->g / 255.0f, @@ -119,60 +118,44 @@ int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) return 0; } -// Somewhat adapted from SDL_render.c: SDL_LockTextureNative -// The app basically wants a pointer to a particular rectangle as well as -// write access to it. Easy GX2R! +/* Somewhat adapted from SDL_render.c: SDL_LockTextureNative + The app basically wants a pointer to a particular rectangle as well as + write access to it. Easy GX2R! */ int WIIU_SDL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, void **pixels, int *pitch) { WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata; Uint32 BytesPerPixel = SDL_BYTESPERPIXEL(texture->format); - void* pixel_buffer; + void* pixel_buffer = GX2RLockSurfaceEx(&tdata->texture.surface, 0, 0); - pixel_buffer = GX2RLockSurfaceEx(&tdata->texture.surface, 0, 0); - if (!pixel_buffer) { - //TODO real error handling - printf("SDL: Couldn't lock surface for texture!\n"); - return -1; - } - - // Calculate pointer to first pixel in rect + /* Calculate pointer to first pixel in rect */ *pixels = (void *) ((Uint8 *) pixel_buffer + rect->y * (tdata->texture.surface.pitch * BytesPerPixel) + rect->x * BytesPerPixel); *pitch = (tdata->texture.surface.pitch * BytesPerPixel); - // Not sure we even need to bother keeping track of this + /* Not sure we even need to bother keeping track of this */ texture->locked_rect = *rect; + return 0; } void WIIU_SDL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) { WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata; - GX2RUnlockSurfaceEx(&tdata->texture.surface, 0, 0); } int WIIU_SDL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch) { - Uint32 BytesPerPixel; - Uint8 *src, *dst; - int row, dst_pitch, rc; - size_t length; + Uint32 BytesPerPixel = SDL_BYTESPERPIXEL(texture->format); + size_t length = rect->w * BytesPerPixel; + Uint8 *src = (Uint8 *) pixels, *dst; + int row, dst_pitch; - BytesPerPixel = SDL_BYTESPERPIXEL(texture->format); - src = (Uint8 *) pixels; - length = rect->w * BytesPerPixel; - -/* We write the rules, and we say all textures are streaming */ - rc = WIIU_SDL_LockTexture( - renderer, texture, rect, (void**)&dst, &dst_pitch - ); - if (rc < 0) { - return rc; - } + /* We write the rules, and we say all textures are streaming */ + WIIU_SDL_LockTexture(renderer, texture, rect, (void**)&dst, &dst_pitch); for (row = 0; row < rect->h; ++row) { SDL_memcpy(dst, src, length); @@ -209,10 +192,8 @@ int WIIU_SDL_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture) void WIIU_SDL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) { - WIIU_TextureData *tdata; - if (texture == NULL || texture->driverdata == NULL) return; + WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata; - tdata = (WIIU_TextureData *) texture->driverdata; GX2RDestroySurfaceEx(&tdata->cbuf.surface, 0); GX2RDestroySurfaceEx(&tdata->texture.surface, 0); diff --git a/src/render/wiiu/SDL_rwindow_wiiu.c b/src/render/wiiu/SDL_rwindow_wiiu.c index 3005aea00..fff15be94 100644 --- a/src/render/wiiu/SDL_rwindow_wiiu.c +++ b/src/render/wiiu/SDL_rwindow_wiiu.c @@ -1,7 +1,7 @@ /* Simple DirectMedia Layer - Copyright (C) 2018-2018 Ash Logan - Copyright (C) 2018-2018 Roberto Van Eeden + Copyright (C) 2018-2019 Ash Logan + Copyright (C) 2018-2019 Roberto Van Eeden This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,50 +19,44 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ - #include "../../SDL_internal.h" #if SDL_VIDEO_RENDER_WIIU -#include "../../video/wiiu/SDL_wiiuvideo.h" #include "../SDL_sysrender.h" -#include "SDL_hints.h" #include "SDL_render_wiiu.h" -#include -#include -#include -#include -#include - void WIIU_SDL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) { if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) { - // Re-init the colour buffer etc. for new window size - // TODO check: what if we're rendering to a texture when this happens? - // SDL may handle this already, see SDL_render.c: SDL_RendererEventWatch + /* Re-init the colour buffer etc. for new window size + TODO check: what if we're rendering to a texture when this happens? + SDL may handle this already, see SDL_render.c: SDL_RendererEventWatch */ WIIU_SDL_CreateWindowTex(renderer, renderer->window); WIIU_SDL_SetRenderTarget(renderer, NULL); } } -// We always output at whatever res the window is. -// This may need to change if SDL_wiiuvideo is ever folded into SDL_render - -// see SDL_*WindowTexture from SDL_video.c for how this could be done -int WIIU_SDL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h) { +/* We always output at whatever res the window is. + This may need to change if SDL_wiiuvideo is ever folded into SDL_render - + see SDL_*WindowTexture from SDL_video.c for how this could be done */ +int WIIU_SDL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h) +{ SDL_GetWindowSize(renderer->window, w, h); return 0; } -// We handle all viewport changes in the render functions and shaders, so we -// don't actually have to do anything here. SDL still requires we implement it. -int WIIU_SDL_UpdateViewport(SDL_Renderer * renderer) { +/* We handle all viewport changes in the render functions and shaders, so we + don't actually have to do anything here. SDL still requires we implement it. */ +int WIIU_SDL_UpdateViewport(SDL_Renderer * renderer) +{ return 0; } -// Ideally this should change the GX2SetScissor values, but SetRenderTarget -// needs refactoring first or these get overwritten. -int WIIU_SDL_UpdateClipRect(SDL_Renderer * renderer) { +/* Ideally this should change the GX2SetScissor values, but SetRenderTarget + needs refactoring first or these get overwritten. */ +int WIIU_SDL_UpdateClipRect(SDL_Renderer * renderer) +{ return 0; } From c154dc9208e1a22d6634eb73b5eb3d7c23855474 Mon Sep 17 00:00:00 2001 From: rw-r-r-0644 Date: Mon, 18 Mar 2019 15:18:29 +0100 Subject: [PATCH 25/25] render/wiiu: Fix the remaining graphical glitches! --- src/render/wiiu/SDL_rdraw_wiiu.c | 6 +++ src/render/wiiu/SDL_render_wiiu.c | 3 ++ src/render/wiiu/SDL_render_wiiu.h | 80 +++++++++++++++++++++++------ src/render/wiiu/SDL_rpresent_wiiu.c | 3 +- src/render/wiiu/SDL_rtexture_wiiu.c | 13 ++++- 5 files changed, 88 insertions(+), 17 deletions(-) diff --git a/src/render/wiiu/SDL_rdraw_wiiu.c b/src/render/wiiu/SDL_rdraw_wiiu.c index bab0e403c..310a0d6bc 100644 --- a/src/render/wiiu/SDL_rdraw_wiiu.c +++ b/src/render/wiiu/SDL_rdraw_wiiu.c @@ -62,6 +62,9 @@ int WIIU_SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, GX2RInvalidateSurface(&tdata->texture.surface, 0, 0); } + /* Update texture rendering state */ + WIIU_TextureStartRendering(data, tdata); + /* Allocate attribute buffers */ a_position = WIIU_AllocRenderData(data, (GX2RBuffer) { .flags = @@ -168,6 +171,9 @@ int WIIU_SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, GX2RInvalidateSurface(&tdata->texture.surface, 0, 0); } + /* Update texture rendering state */ + WIIU_TextureStartRendering(data, tdata); + /* Allocate attribute buffers */ a_position = WIIU_AllocRenderData(data, (GX2RBuffer) { .flags = diff --git a/src/render/wiiu/SDL_render_wiiu.c b/src/render/wiiu/SDL_render_wiiu.c index 139136c15..e83dcd362 100644 --- a/src/render/wiiu/SDL_render_wiiu.c +++ b/src/render/wiiu/SDL_render_wiiu.c @@ -139,6 +139,9 @@ int WIIU_SDL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) WIIU_TextureData *tdata = (WIIU_TextureData *)((texture) ? texture->driverdata : data->windowTex.driverdata); + /* Wait for the texture rendering to finish */ + WIIU_TextureCheckWaitRendering(data, tdata); + /* Update u_viewSize */ data->u_viewSize = (WIIUVec4) { .x = (float)tdata->cbuf.surface.width, diff --git a/src/render/wiiu/SDL_render_wiiu.h b/src/render/wiiu/SDL_render_wiiu.h index fcf5b3180..a3480bd36 100644 --- a/src/render/wiiu/SDL_render_wiiu.h +++ b/src/render/wiiu/SDL_render_wiiu.h @@ -26,62 +26,80 @@ #include "../SDL_sysrender.h" #include "SDL_pixels.h" +#include #include #include #include #include -#include +#include /* Driver internal data structures */ -typedef struct +typedef struct WIIUVec2 WIIUVec2; +typedef struct WIIUVec3 WIIUVec3; +typedef struct WIIUVec4 WIIUVec4; +typedef struct WIIUPixFmt WIIUPixFmt; +typedef struct WIIU_RenderAllocData WIIU_RenderAllocData; +typedef struct WIIU_TextureDrawData WIIU_TextureDrawData; +typedef struct WIIU_RenderData WIIU_RenderData; +typedef struct WIIU_TextureData WIIU_TextureData; + +struct WIIUVec2 { union { float x, r; }; union { float y, g; }; -} WIIUVec2; +}; -typedef struct +struct WIIUVec3 { union { float x, r; }; union { float y, g; }; union { float z, b; }; -} WIIUVec3; +}; -typedef struct +struct WIIUVec4 { union { float x, r; }; union { float y, g; }; union { float z, b; }; union { float w, a; }; -} WIIUVec4; +}; -typedef struct +struct WIIUPixFmt { GX2SurfaceFormat fmt; uint32_t compMap; -} WIIUPixFmt; +}; -typedef struct +struct WIIU_RenderAllocData { void *next; GX2RBuffer buffer; -} WIIU_RenderAllocData; +}; -typedef struct +struct WIIU_TextureDrawData +{ + void *next; + WIIU_TextureData *texdata; +}; + +struct WIIU_RenderData { GX2ContextState *ctx; WIIU_RenderAllocData *listfree; + WIIU_TextureDrawData *listdraw; WIIUVec4 u_viewSize; SDL_Texture windowTex; -} WIIU_RenderData; +}; -typedef struct +struct WIIU_TextureData { GX2Sampler sampler; GX2Texture texture; GX2ColorBuffer cbuf; WIIUVec4 u_texSize; WIIUVec4 u_mod; -} WIIU_TextureData; + int isRendering; +}; /* SDL_render API implementation */ SDL_Renderer *WIIU_SDL_CreateRenderer(SDL_Window * window, Uint32 flags); @@ -149,6 +167,38 @@ static inline void WIIU_FreeRenderData(WIIU_RenderData *r) } } +static inline void WIIU_TextureStartRendering(WIIU_RenderData *r, WIIU_TextureData *t) +{ + WIIU_TextureDrawData *d = SDL_malloc(sizeof(WIIU_TextureDrawData)); + t->isRendering = 1; + d->texdata = t; + d->next = r->listdraw; + r->listdraw = d; +} + +static inline void WIIU_TextureDoneRendering(WIIU_RenderData *r) +{ + while (r->listdraw) { + WIIU_TextureDrawData *d = r->listdraw; + r->listdraw = r->listdraw->next; + d->texdata->isRendering = 0; + SDL_free(d); + } +} + +/* If the texture is currently being rendered and we change the content + before the rendering is finished, the GPU will end up partially drawing + the new data, so we wait for the GPU to finish rendering before + updating the texture */ +static inline void WIIU_TextureCheckWaitRendering(WIIU_RenderData *r, WIIU_TextureData *t) +{ + if (t->isRendering) + { + GX2DrawDone(); + WIIU_TextureDoneRendering(r); + } +} + static inline SDL_Texture * WIIU_GetRenderTarget(SDL_Renderer* renderer) { WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; diff --git a/src/render/wiiu/SDL_rpresent_wiiu.c b/src/render/wiiu/SDL_rpresent_wiiu.c index 6b0274414..4e1649ea6 100644 --- a/src/render/wiiu/SDL_rpresent_wiiu.c +++ b/src/render/wiiu/SDL_rpresent_wiiu.c @@ -143,8 +143,9 @@ void WIIU_SDL_RenderPresent(SDL_Renderer * renderer) WHBGfxFinishRender(); - /* Free the list of render data */ + /* Free the list of render and draw data */ WIIU_FreeRenderData(data); + WIIU_TextureDoneRendering(data); /* Restore SDL context state */ GX2SetContextState(data->ctx); diff --git a/src/render/wiiu/SDL_rtexture_wiiu.c b/src/render/wiiu/SDL_rtexture_wiiu.c index 6e04e70cd..e57e5b10b 100644 --- a/src/render/wiiu/SDL_rtexture_wiiu.c +++ b/src/render/wiiu/SDL_rtexture_wiiu.c @@ -113,6 +113,7 @@ int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) .a = (float)texture->a / 255.0f, }; + /* Setup texture driver data */ texture->driverdata = tdata; return 0; @@ -124,9 +125,15 @@ int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) int WIIU_SDL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, void **pixels, int *pitch) { + WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata; Uint32 BytesPerPixel = SDL_BYTESPERPIXEL(texture->format); - void* pixel_buffer = GX2RLockSurfaceEx(&tdata->texture.surface, 0, 0); + void* pixel_buffer; + + /* Wait for the texture rendering to finish */ + WIIU_TextureCheckWaitRendering(data, tdata); + + pixel_buffer = GX2RLockSurfaceEx(&tdata->texture.surface, 0, 0); /* Calculate pointer to first pixel in rect */ *pixels = (void *) ((Uint8 *) pixel_buffer + @@ -192,8 +199,12 @@ int WIIU_SDL_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture) void WIIU_SDL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) { + WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata; + /* Wait for the texture rendering to finish */ + WIIU_TextureCheckWaitRendering(data, tdata); + GX2RDestroySurfaceEx(&tdata->cbuf.surface, 0); GX2RDestroySurfaceEx(&tdata->texture.surface, 0);