mirror of
https://github.com/yawut/SDL.git
synced 2026-08-19 23:34:04 -05:00
render/wiiu: Use GX2R for texture surfaces
Untested at time of commit, hopefully it works hehe
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user