render/wiiu: Fix the remaining graphical glitches!

This commit is contained in:
rw-r-r-0644
2019-03-18 15:18:29 +01:00
committed by Ash Logan
parent d4f823db47
commit 4388bea3ad
5 changed files with 88 additions and 17 deletions

View File

@@ -62,6 +62,9 @@ int WIIU_SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
GX2RInvalidateSurface(&tdata->texture.surface, 0, 0);
}
/* Update texture rendering state */
WIIU_TextureStartRendering(data, tdata);
/* Allocate attribute buffers */
a_position = WIIU_AllocRenderData(data, (GX2RBuffer) {
.flags =
@@ -168,6 +171,9 @@ int WIIU_SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
GX2RInvalidateSurface(&tdata->texture.surface, 0, 0);
}
/* Update texture rendering state */
WIIU_TextureStartRendering(data, tdata);
/* Allocate attribute buffers */
a_position = WIIU_AllocRenderData(data, (GX2RBuffer) {
.flags =

View File

@@ -139,6 +139,9 @@ int WIIU_SDL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
WIIU_TextureData *tdata = (WIIU_TextureData *)((texture) ? texture->driverdata
: data->windowTex.driverdata);
/* Wait for the texture rendering to finish */
WIIU_TextureCheckWaitRendering(data, tdata);
/* Update u_viewSize */
data->u_viewSize = (WIIUVec4) {
.x = (float)tdata->cbuf.surface.width,

View File

@@ -26,62 +26,80 @@
#include "../SDL_sysrender.h"
#include "SDL_pixels.h"
#include <gx2r/buffer.h>
#include <gx2/context.h>
#include <gx2/sampler.h>
#include <gx2/texture.h>
#include <gx2/surface.h>
#include <gx2r/buffer.h>
#include <gx2/event.h>
/* Driver internal data structures */
typedef struct
typedef struct WIIUVec2 WIIUVec2;
typedef struct WIIUVec3 WIIUVec3;
typedef struct WIIUVec4 WIIUVec4;
typedef struct WIIUPixFmt WIIUPixFmt;
typedef struct WIIU_RenderAllocData WIIU_RenderAllocData;
typedef struct WIIU_TextureDrawData WIIU_TextureDrawData;
typedef struct WIIU_RenderData WIIU_RenderData;
typedef struct WIIU_TextureData WIIU_TextureData;
struct WIIUVec2
{
union { float x, r; };
union { float y, g; };
} WIIUVec2;
};
typedef struct
struct WIIUVec3
{
union { float x, r; };
union { float y, g; };
union { float z, b; };
} WIIUVec3;
};
typedef struct
struct WIIUVec4
{
union { float x, r; };
union { float y, g; };
union { float z, b; };
union { float w, a; };
} WIIUVec4;
};
typedef struct
struct WIIUPixFmt
{
GX2SurfaceFormat fmt;
uint32_t compMap;
} WIIUPixFmt;
};
typedef struct
struct WIIU_RenderAllocData
{
void *next;
GX2RBuffer buffer;
} WIIU_RenderAllocData;
};
typedef struct
struct WIIU_TextureDrawData
{
void *next;
WIIU_TextureData *texdata;
};
struct WIIU_RenderData
{
GX2ContextState *ctx;
WIIU_RenderAllocData *listfree;
WIIU_TextureDrawData *listdraw;
WIIUVec4 u_viewSize;
SDL_Texture windowTex;
} WIIU_RenderData;
};
typedef struct
struct WIIU_TextureData
{
GX2Sampler sampler;
GX2Texture texture;
GX2ColorBuffer cbuf;
WIIUVec4 u_texSize;
WIIUVec4 u_mod;
} WIIU_TextureData;
int isRendering;
};
/* SDL_render API implementation */
SDL_Renderer *WIIU_SDL_CreateRenderer(SDL_Window * window, Uint32 flags);
@@ -149,6 +167,38 @@ static inline void WIIU_FreeRenderData(WIIU_RenderData *r)
}
}
static inline void WIIU_TextureStartRendering(WIIU_RenderData *r, WIIU_TextureData *t)
{
WIIU_TextureDrawData *d = SDL_malloc(sizeof(WIIU_TextureDrawData));
t->isRendering = 1;
d->texdata = t;
d->next = r->listdraw;
r->listdraw = d;
}
static inline void WIIU_TextureDoneRendering(WIIU_RenderData *r)
{
while (r->listdraw) {
WIIU_TextureDrawData *d = r->listdraw;
r->listdraw = r->listdraw->next;
d->texdata->isRendering = 0;
SDL_free(d);
}
}
/* If the texture is currently being rendered and we change the content
before the rendering is finished, the GPU will end up partially drawing
the new data, so we wait for the GPU to finish rendering before
updating the texture */
static inline void WIIU_TextureCheckWaitRendering(WIIU_RenderData *r, WIIU_TextureData *t)
{
if (t->isRendering)
{
GX2DrawDone();
WIIU_TextureDoneRendering(r);
}
}
static inline SDL_Texture * WIIU_GetRenderTarget(SDL_Renderer* renderer)
{
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;

View File

@@ -143,8 +143,9 @@ void WIIU_SDL_RenderPresent(SDL_Renderer * renderer)
WHBGfxFinishRender();
/* Free the list of render data */
/* Free the list of render and draw data */
WIIU_FreeRenderData(data);
WIIU_TextureDoneRendering(data);
/* Restore SDL context state */
GX2SetContextState(data->ctx);

View File

@@ -113,6 +113,7 @@ int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
.a = (float)texture->a / 255.0f,
};
/* Setup texture driver data */
texture->driverdata = tdata;
return 0;
@@ -124,9 +125,15 @@ int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
int WIIU_SDL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, void **pixels, int *pitch)
{
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;
WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata;
Uint32 BytesPerPixel = SDL_BYTESPERPIXEL(texture->format);
void* pixel_buffer = GX2RLockSurfaceEx(&tdata->texture.surface, 0, 0);
void* pixel_buffer;
/* Wait for the texture rendering to finish */
WIIU_TextureCheckWaitRendering(data, tdata);
pixel_buffer = GX2RLockSurfaceEx(&tdata->texture.surface, 0, 0);
/* Calculate pointer to first pixel in rect */
*pixels = (void *) ((Uint8 *) pixel_buffer +
@@ -192,8 +199,12 @@ int WIIU_SDL_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture)
void WIIU_SDL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;
WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata;
/* Wait for the texture rendering to finish */
WIIU_TextureCheckWaitRendering(data, tdata);
GX2RDestroySurfaceEx(&tdata->cbuf.surface, 0);
GX2RDestroySurfaceEx(&tdata->texture.surface, 0);