From eadc064e2c5f18a6d1cfd1b5bbd436c8945ae722 Mon Sep 17 00:00:00 2001
From: Ivan Epifanov <[EMAIL REDACTED]>
Date: Wed, 23 Mar 2022 19:14:28 +0300
Subject: [PATCH] Vita: add native YUV textures support.
* Fail if texture init fails.
* Refactor and cleanup.
---
src/render/vitagxm/SDL_render_vita_gxm.c | 285 ++++++++++++++++--
.../vitagxm/SDL_render_vita_gxm_tools.c | 57 ++--
.../vitagxm/SDL_render_vita_gxm_tools.h | 5 +-
.../vitagxm/SDL_render_vita_gxm_types.h | 9 +-
4 files changed, 298 insertions(+), 58 deletions(-)
diff --git a/src/render/vitagxm/SDL_render_vita_gxm.c b/src/render/vitagxm/SDL_render_vita_gxm.c
index 8a887784950..4d5530443c8 100644
--- a/src/render/vitagxm/SDL_render_vita_gxm.c
+++ b/src/render/vitagxm/SDL_render_vita_gxm.c
@@ -61,6 +61,11 @@ static int VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * text
const Uint8 *Uplane, int Upitch,
const Uint8 *Vplane, int Vpitch);
+static int VITA_GXM_UpdateTextureNV(SDL_Renderer * renderer, SDL_Texture * texture,
+ const SDL_Rect * rect,
+ const Uint8 *Yplane, int Ypitch,
+ const Uint8 *UVplane, int UVpitch);
+
static int VITA_GXM_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
const SDL_Rect *rect, void **pixels, int *pitch);
@@ -105,12 +110,16 @@ SDL_RenderDriver VITA_GXM_RenderDriver = {
.info = {
.name = "VITA gxm",
.flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE,
- .num_texture_formats = 4,
+ .num_texture_formats = 8,
.texture_formats = {
[0] = SDL_PIXELFORMAT_ABGR8888,
[1] = SDL_PIXELFORMAT_ARGB8888,
[2] = SDL_PIXELFORMAT_RGB565,
- [3] = SDL_PIXELFORMAT_BGR565
+ [3] = SDL_PIXELFORMAT_BGR565,
+ [4] = SDL_PIXELFORMAT_YV12,
+ [5] = SDL_PIXELFORMAT_IYUV,
+ [6] = SDL_PIXELFORMAT_NV12,
+ [7] = SDL_PIXELFORMAT_NV21,
},
.max_texture_width = 4096,
.max_texture_height = 4096,
@@ -133,6 +142,15 @@ PixelFormatToVITAFMT(Uint32 format)
return SCE_GXM_TEXTURE_FORMAT_U5U6U5_RGB;
case SDL_PIXELFORMAT_BGR565:
return SCE_GXM_TEXTURE_FORMAT_U5U6U5_BGR;
+ case SDL_PIXELFORMAT_YV12:
+ return SCE_GXM_TEXTURE_FORMAT_YVU420P3_CSC0;
+ case SDL_PIXELFORMAT_IYUV:
+ return SCE_GXM_TEXTURE_FORMAT_YUV420P3_CSC0;
+ // should be the other way around. looks like SCE bug.
+ case SDL_PIXELFORMAT_NV12:
+ return SCE_GXM_TEXTURE_FORMAT_YVU420P2_CSC0;
+ case SDL_PIXELFORMAT_NV21:
+ return SCE_GXM_TEXTURE_FORMAT_YUV420P2_CSC0;
default:
return SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR;
}
@@ -228,6 +246,7 @@ VITA_GXM_CreateRenderer(SDL_Window *window, Uint32 flags)
renderer->UpdateTexture = VITA_GXM_UpdateTexture;
#if SDL_HAVE_YUV
renderer->UpdateTextureYUV = VITA_GXM_UpdateTextureYUV;
+ renderer->UpdateTextureNV = VITA_GXM_UpdateTextureNV;
#endif
renderer->LockTexture = VITA_GXM_LockTexture;
renderer->UnlockTexture = VITA_GXM_UnlockTexture;
@@ -295,7 +314,17 @@ VITA_GXM_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
return SDL_OutOfMemory();
}
- vita_texture->tex = create_gxm_texture(data, texture->w, texture->h, PixelFormatToVITAFMT(texture->format), (texture->access == SDL_TEXTUREACCESS_TARGET));
+ vita_texture->tex = create_gxm_texture(
+ data,
+ texture->w,
+ texture->h,
+ PixelFormatToVITAFMT(texture->format),
+ (texture->access == SDL_TEXTUREACCESS_TARGET),
+ &(vita_texture->w),
+ &(vita_texture->h),
+ &(vita_texture->pitch),
+ &(vita_texture->wscale)
+ );
if (!vita_texture->tex) {
SDL_free(vita_texture);
@@ -306,38 +335,129 @@ VITA_GXM_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
VITA_GXM_SetTextureScaleMode(renderer, texture, texture->scaleMode);
- vita_texture->w = gxm_texture_get_width(vita_texture->tex);
- vita_texture->h = gxm_texture_get_height(vita_texture->tex);
- vita_texture->pitch = gxm_texture_get_stride(vita_texture->tex);
+#if SDL_HAVE_YUV
+ vita_texture->yuv = ((texture->format == SDL_PIXELFORMAT_IYUV) || (texture->format == SDL_PIXELFORMAT_YV12));
+ vita_texture->nv12 = ((texture->format == SDL_PIXELFORMAT_NV12) || (texture->format == SDL_PIXELFORMAT_NV21));
+#endif
return 0;
}
+static void VITA_GXM_SetYUVProfile(SDL_Renderer * renderer, SDL_Texture *texture)
+{
+ VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
+ int ret = 0;
+ switch (SDL_GetYUVConversionModeForResolution(texture->w, texture->h)) {
+ case SDL_YUV_CONVERSION_BT601:
+ ret = sceGxmSetYuvProfile(data->gxm_context, 0, SCE_GXM_YUV_PROFILE_BT601_STANDARD);
+ break;
+ case SDL_YUV_CONVERSION_BT709:
+ ret = sceGxmSetYuvProfile(data->gxm_context, 0, SCE_GXM_YUV_PROFILE_BT709_STANDARD);
+ break;
+ case SDL_YUV_CONVERSION_JPEG:
+ default:
+ SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Unsupported YUV profile: %d\n", SDL_GetYUVConversionModeForResolution(texture->w, texture->h));
+ break;
+ }
+
+ if (ret < 0) {
+ SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Setting YUV profile failed: %x\n", ret);
+ }
+}
static int
VITA_GXM_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
const SDL_Rect *rect, const void *pixels, int pitch)
{
- const Uint8 *src;
+ VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) texture->driverdata;
Uint8 *dst;
- int row, length,dpitch;
- src = pixels;
+ int row, length, dpitch;
+
+#if SDL_HAVE_YUV
+ if (vita_texture->yuv || vita_texture->nv12) {
+ VITA_GXM_SetYUVProfile(renderer, texture);
+ }
+#endif
VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch);
length = rect->w * SDL_BYTESPERPIXEL(texture->format);
if (length == pitch && length == dpitch) {
- SDL_memcpy(dst, src, length*rect->h);
+ SDL_memcpy(dst, pixels, length*rect->h);
} else {
for (row = 0; row < rect->h; ++row) {
- SDL_memcpy(dst, src, length);
- src += pitch;
+ SDL_memcpy(dst, pixels, length);
+ pixels += pitch;
dst += dpitch;
}
}
+#if SDL_HAVE_YUV
+ if (vita_texture->yuv) {
+ void *Udst;
+ void *Vdst;
+ int uv_pitch = (dpitch+1) / 2;
+ int uv_src_pitch = (pitch+1) / 2;
+ SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2};
+
+ // skip Y plane
+ Uint8 *Dpixels = gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h);
+
+ Udst = Dpixels + (UVrect.y * uv_pitch) + UVrect.x;
+ Vdst = Dpixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x;
+
+ length = UVrect.w;
+
+ // U plane
+ if (length == uv_src_pitch && length == uv_pitch) {
+ SDL_memcpy(Udst, pixels, length*UVrect.h);
+ } else {
+ for (row = 0; row < UVrect.h; ++row) {
+ SDL_memcpy(Udst, pixels, length);
+ pixels += uv_src_pitch;
+ Udst += uv_pitch;
+ }
+ }
+
+ // V plane
+ if (length == uv_src_pitch && length == uv_pitch) {
+ SDL_memcpy(Vdst, pixels, length*UVrect.h);
+ } else {
+ for (row = 0; row < UVrect.h; ++row) {
+ SDL_memcpy(Vdst, pixels, length);
+ pixels += uv_src_pitch;
+ Vdst += uv_pitch;
+ }
+ }
+
+ } else if (vita_texture->nv12) {
+ void *UVdst;
+ int uv_pitch = 2 * ((dpitch+1) / 2);
+ int uv_src_pitch = 2 * ((pitch+1) / 2);
+ SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2 , (rect->h + 1) / 2};
+
+ // skip Y plane
+ void *Dpixels = (void *) ((Uint8 *) gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h));
+ UVdst = Dpixels + (UVrect.y * uv_pitch) + UVrect.x;
+
+ length = UVrect.w*2;
+
+ // UV plane
+ if (length == uv_src_pitch && length == uv_pitch) {
+ SDL_memcpy(UVdst, pixels, length*UVrect.h);
+ } else {
+ for (row = 0; row < UVrect.h; ++row) {
+ SDL_memcpy(UVdst, pixels, length);
+ pixels += uv_src_pitch;
+ UVdst += uv_pitch;
+ }
+ }
+ }
+#endif
+
return 0;
}
+#if SDL_HAVE_YUV
static int
VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect,
@@ -345,9 +465,133 @@ VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
const Uint8 *Uplane, int Upitch,
const Uint8 *Vplane, int Vpitch)
{
+ Uint8 *dst;
+ int row, length, dpitch;
+ SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2};
+
+ VITA_GXM_SetYUVProfile(renderer, texture);
+
+ // copy Y plane
+ // obtain pixels via locking so that texture is flushed
+ VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch);
+
+ length = rect->w;
+
+ if (length == Ypitch && length == dpitch) {
+ SDL_memcpy(dst, Yplane, length*rect->h);
+ } else {
+ for (row = 0; row < rect->h; ++row) {
+ SDL_memcpy(dst, Yplane, length);
+ Yplane += Ypitch;
+ dst += dpitch;
+ }
+ }
+
+ // U/V planes
+ {
+ void *Udst;
+ void *Vdst;
+ VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) texture->driverdata;
+ int uv_pitch = (dpitch+1) / 2;
+
+ // skip Y plane
+ void *pixels = (void *) ((Uint8 *) gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h));
+
+ if (texture->format == SDL_PIXELFORMAT_YV12) { // YVU
+ Vdst = pixels + (UVrect.y * uv_pitch) + UVrect.x;
+ Udst = pixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x;
+ } else { // YUV
+ Udst = pixels + (UVrect.y * uv_pitch) + UVrect.x;
+ Vdst = pixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x;
+ }
+
+ length = UVrect.w;
+
+ // U plane
+ if (length == Upitch && length == uv_pitch) {
+ SDL_memcpy(Udst, Uplane, length*UVrect.h);
+ } else {
+ for (row = 0; row < UVrect.h; ++row) {
+ SDL_memcpy(Udst, Uplane, length);
+ Uplane += Upitch;
+ Udst += uv_pitch;
+ }
+ }
+
+ // V plane
+ if (length == Vpitch && length == uv_pitch) {
+ SDL_memcpy(Vdst, Vplane, length*UVrect.h);
+ } else {
+ for (row = 0; row < UVrect.h; ++row) {
+ SDL_memcpy(Vdst, Vplane, length);
+ Vplane += Vpitch;
+ Vdst += uv_pitch;
+ }
+ }
+
+ }
+
+ return 0;
+}
+
+static int
+VITA_GXM_UpdateTextureNV(SDL_Renderer * renderer, SDL_Texture * texture,
+ const SDL_Rect * rect,
+ const Uint8 *Yplane, int Ypitch,
+ const Uint8 *UVplane, int UVpitch)
+{
+
+ Uint8 *dst;
+ int row, length, dpitch;
+ SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2};
+
+ VITA_GXM_SetYUVProfile(renderer, texture);
+
+ // copy Y plane
+ VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch);
+
+ length = rect->w * SDL_BYTESPERPIXEL(texture->format);
+
+ if (length == Ypitch && length == dpitch) {
+ SDL_memcpy(dst, Yplane, length*rect->h);
+ } else {
+ for (row = 0; row < rect->h; ++row) {
+ SDL_memcpy(dst, Yplane, length);
+ Yplane += Ypitch;
+ dst += dpitch;
+ }
+ }
+
+ // UV plane
+ {
+ void *UVdst;
+ VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) texture->driverdata;
+ int uv_pitch = 2 * ((dpitch+1) / 2);
+
+ // skip Y plane
+ void *pixels = (void *) ((Uint8 *) gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h));
+
+ UVdst = pixels + (UVrect.y * uv_pitch) + UVrect.x;
+
+ length = UVrect.w * 2;
+
+ // UV plane
+ if (length == UVpitch && length == uv_pitch) {
+ SDL_memcpy(UVdst, UVplane, length*UVrect.h);
+ } else {
+ for (row = 0; row < UVrect.h; ++row) {
+ SDL_memcpy(UVdst, UVplane, length);
+ UVplane += UVpitch;
+ UVdst += uv_pitch;
+ }
+ }
+ }
+
return 0;
}
+#endif
+
static int
VITA_GXM_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
const SDL_Rect *rect, void **pixels, int *pitch)
@@ -512,6 +756,7 @@ VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Textu
float scale_x, float scale_y)
{
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
+ VITA_GXM_TextureData* vita_texture = (VITA_GXM_TextureData*) texture->driverdata;
int i;
int count = indices ? num_indices : num_vertices;
@@ -551,7 +796,7 @@ VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Textu
vertices[i].x = xy_[0] * scale_x;
vertices[i].y = xy_[1] * scale_y;
- vertices[i].u = uv_[0];
+ vertices[i].u = uv_[0] * vita_texture->wscale;
vertices[i].v = uv_[1];
vertices[i].color = col_;
}
@@ -730,14 +975,6 @@ SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd)
return 0;
}
-static int
-SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd)
-{
- VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
-
- return SetDrawState(data, cmd);
-}
-
static int
VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
{
@@ -824,11 +1061,7 @@ VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *
nextcmd = nextcmd->next;
}
- if (thistexture) {
- ret = SetCopyState(renderer, cmd);
- } else {
- ret = SetDrawState(data, cmd);
- }
+ ret = SetDrawState(data, cmd);
if (ret == 0) {
int op = SCE_GXM_PRIMITIVE_TRIANGLES;
diff --git a/src/render/vitagxm/SDL_render_vita_gxm_tools.c b/src/render/vitagxm/SDL_render_vita_gxm_tools.c
index e043b55ab18..0ecae38394c 100644
--- a/src/render/vitagxm/SDL_render_vita_gxm_tools.c
+++ b/src/render/vitagxm/SDL_render_vita_gxm_tools.c
@@ -117,6 +117,8 @@ tex_format_to_bytespp(SceGxmTextureFormat format)
case SCE_GXM_TEXTURE_BASE_FORMAT_U8:
case SCE_GXM_TEXTURE_BASE_FORMAT_S8:
case SCE_GXM_TEXTURE_BASE_FORMAT_P8:
+ case SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P2: // YUV actually uses 12 bits per pixel. UV planes bits/mem are handled elsewhere
+ case SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3:
return 1;
case SCE_GXM_TEXTURE_BASE_FORMAT_U4U4U4U4:
case SCE_GXM_TEXTURE_BASE_FORMAT_U8U3U3U2:
@@ -995,25 +997,6 @@ gxm_texture_get_format(const gxm_texture *texture)
return sceGxmTextureGetFormat(&texture->gxm_tex);
}
-unsigned int
-gxm_texture_get_width(const gxm_texture *texture)
-{
- return sceGxmTextureGetWidth(&texture->gxm_tex);
-}
-
-unsigned int
-gxm_texture_get_height(const gxm_texture *texture)
-{
- return sceGxmTextureGetHeight(&texture->gxm_tex);
-}
-
-unsigned int
-gxm_texture_get_stride(const gxm_texture *texture)
-{
- return ((gxm_texture_get_width(texture) + 7) & ~7)
- * tex_format_to_bytespp(gxm_texture_get_format(texture));
-}
-
void *
gxm_texture_get_datap(const gxm_texture *texture)
{
@@ -1021,15 +1004,34 @@ gxm_texture_get_datap(const gxm_texture *texture)
}
gxm_texture *
-create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget)
+create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget, unsigned int *return_w, unsigned int *return_h, unsigned int *return_pitch, float *return_wscale)
{
gxm_texture *texture = SDL_calloc(1, sizeof(gxm_texture));
- const int tex_size = ((w + 7) & ~ 7) * h * tex_format_to_bytespp(format);
+ int aligned_w = ALIGN(w, 8);
+ int texture_w = w;
+ int tex_size = aligned_w * h * tex_format_to_bytespp(format);
void *texture_data;
+ int ret;
+
+ *return_wscale = 1.0f;
+
+ // SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3/P2 based formats require width aligned to 16
+ if ( (format & 0x9f000000U) == SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3 || (format & 0x9f000000U) == SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P2) {
+ aligned_w = ALIGN(w, 16);
+ texture_w = aligned_w;
+ tex_size = aligned_w * h * tex_format_to_bytespp(format);
+ *return_wscale = (float) (w) / texture_w;
+ // add storage for UV planes
+ tex_size += (((aligned_w + 1) / 2) * ((h + 1) / 2)) * 2;
+ }
if (!texture)
return NULL;
+ *return_w = w;
+ *return_h = h;
+ *return_pitch = aligned_w * tex_format_to_bytespp(format);
+
/* Allocate a GPU buffer for the texture */
texture_data = mem_gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
@@ -1060,7 +1062,12 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
SDL_memset(texture_data, 0, tex_size);
/* Create the gxm texture */
- sceGxmTextureInitLinear( &texture->gxm_tex, texture_data, format, w, h, 0);
+ ret = sceGxmTextureInitLinear( &texture->gxm_tex, texture_data, format, texture_w, h, 0);
+ if (ret < 0) {
+ free_gxm_texture(texture);
+ SDL_LogError(SDL_LOG_CATEGORY_RENDER, "texture init failed: %x\n", ret);
+ return NULL;
+ }
if (isRenderTarget) {
void *depthBufferData;
@@ -1084,7 +1091,7 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
if (err < 0) {
free_gxm_texture(texture);
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "color surface init failed: %d\n", err);
+ SDL_LogError(SDL_LOG_CATEGORY_RENDER, "color surface init failed: %x\n", err);
return NULL;
}
@@ -1107,7 +1114,7 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
if (err < 0) {
free_gxm_texture(texture);
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "depth stencil init failed: %d\n", err);
+ SDL_LogError(SDL_LOG_CATEGORY_RENDER, "depth stencil init failed: %x\n", err);
return NULL;
}
@@ -1132,7 +1139,7 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
if (err < 0) {
free_gxm_texture(texture);
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create render target failed: %d\n", err);
+ SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create render target failed: %x\n", err);
return NULL;
}
}
diff --git a/src/render/vitagxm/SDL_render_vita_gxm_tools.h b/src/render/vitagxm/SDL_render_vita_gxm_tools.h
index 351bdc2e669..8e9caeb2102 100644
--- a/src/render/vitagxm/SDL_render_vita_gxm_tools.h
+++ b/src/render/vitagxm/SDL_render_vita_gxm_tools.h
@@ -48,15 +48,12 @@ void unset_clip_rectangle(VITA_GXM_RenderData *data);
int gxm_init(SDL_Renderer *renderer);
void gxm_finish(SDL_Renderer *renderer);
-gxm_texture *create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget);
+gxm_texture *create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget, unsigned int *return_w, unsigned int *return_h, unsigned int *return_pitch, float *return_wscale);
void free_gxm_texture(gxm_texture *texture);
void gxm_texture_set_filters(gxm_texture *texture, SceGxmTextureFilter min_filter, SceGxmTextureFilter mag_filter);
SceGxmTextureFormat gxm_texture_get_format(const gxm_texture *texture);
-unsigned int gxm_texture_get_width(const gxm_texture *texture);
-unsigned int gxm_texture_get_height(const gxm_texture *texture);
-unsigned int gxm_texture_get_stride(const gxm_texture *texture);
void *gxm_texture_get_datap(const gxm_texture *texture);
void gxm_minimal_init_for_common_dialog(void);
diff --git a/src/render/vitagxm/SDL_render_vita_gxm_types.h b/src/render/vitagxm/SDL_render_vita_gxm_types.h
index 898a92d9c81..2bf8d358505 100644
--- a/src/render/vitagxm/SDL_render_vita_gxm_types.h
+++ b/src/render/vitagxm/SDL_render_vita_gxm_types.h
@@ -191,9 +191,12 @@ typedef struct
typedef struct
{
gxm_texture *tex;
- unsigned int pitch;
- unsigned int w;
- unsigned int h;
+ unsigned int pitch;
+ unsigned int w;
+ unsigned int h;
+ float wscale;
+ SDL_bool yuv;
+ SDL_bool nv12;
} VITA_GXM_TextureData;
#endif /* SDL_RENDER_VITA_GXM_TYPES_H */