render/wiiu: Textures keep their own colour buffers

This commit is contained in:
Ash Logan 2019-03-08 11:23:03 +11:00
parent 8c4b5c066e
commit dcb58351f0
4 changed files with 54 additions and 29 deletions

View File

@ -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,

View File

@ -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);
}

View File

@ -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,

View File

@ -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);