From ca33399a70de086d4331a33593266570fefad7fb Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Tue, 5 Mar 2019 13:07:53 +1100 Subject: [PATCH] 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); }