From dcb58351f0540c06b9399049cf8b603773ddacb4 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Fri, 8 Mar 2019 11:23:03 +1100 Subject: [PATCH] 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);