render/wiiu: Use GX2R for texture surfaces

Untested at time of commit, hopefully it works hehe
This commit is contained in:
Ash Logan
2019-03-05 13:07:53 +11:00
parent fa157dbcaa
commit ca33399a70

View File

@@ -32,6 +32,8 @@
#include <gx2/texture.h>
#include <gx2/sampler.h>
#include <gx2/mem.h>
#include <gx2r/surface.h>
#include <gx2r/resource.h>
#include <malloc.h>
#include <stdio.h>
@@ -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);
}