mirror of https://github.com/encounter/SDL.git
Vita: add native YUV textures support.
* Fail if texture init fails. * Refactor and cleanup.
This commit is contained in:
parent
0af2db6f29
commit
eadc064e2c
|
@ -61,6 +61,11 @@ static int VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * text
|
||||||
const Uint8 *Uplane, int Upitch,
|
const Uint8 *Uplane, int Upitch,
|
||||||
const Uint8 *Vplane, int Vpitch);
|
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,
|
static int VITA_GXM_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||||
const SDL_Rect *rect, void **pixels, int *pitch);
|
const SDL_Rect *rect, void **pixels, int *pitch);
|
||||||
|
|
||||||
|
@ -105,12 +110,16 @@ SDL_RenderDriver VITA_GXM_RenderDriver = {
|
||||||
.info = {
|
.info = {
|
||||||
.name = "VITA gxm",
|
.name = "VITA gxm",
|
||||||
.flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE,
|
.flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE,
|
||||||
.num_texture_formats = 4,
|
.num_texture_formats = 8,
|
||||||
.texture_formats = {
|
.texture_formats = {
|
||||||
[0] = SDL_PIXELFORMAT_ABGR8888,
|
[0] = SDL_PIXELFORMAT_ABGR8888,
|
||||||
[1] = SDL_PIXELFORMAT_ARGB8888,
|
[1] = SDL_PIXELFORMAT_ARGB8888,
|
||||||
[2] = SDL_PIXELFORMAT_RGB565,
|
[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_width = 4096,
|
||||||
.max_texture_height = 4096,
|
.max_texture_height = 4096,
|
||||||
|
@ -133,6 +142,15 @@ PixelFormatToVITAFMT(Uint32 format)
|
||||||
return SCE_GXM_TEXTURE_FORMAT_U5U6U5_RGB;
|
return SCE_GXM_TEXTURE_FORMAT_U5U6U5_RGB;
|
||||||
case SDL_PIXELFORMAT_BGR565:
|
case SDL_PIXELFORMAT_BGR565:
|
||||||
return SCE_GXM_TEXTURE_FORMAT_U5U6U5_BGR;
|
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:
|
default:
|
||||||
return SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR;
|
return SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR;
|
||||||
}
|
}
|
||||||
|
@ -228,6 +246,7 @@ VITA_GXM_CreateRenderer(SDL_Window *window, Uint32 flags)
|
||||||
renderer->UpdateTexture = VITA_GXM_UpdateTexture;
|
renderer->UpdateTexture = VITA_GXM_UpdateTexture;
|
||||||
#if SDL_HAVE_YUV
|
#if SDL_HAVE_YUV
|
||||||
renderer->UpdateTextureYUV = VITA_GXM_UpdateTextureYUV;
|
renderer->UpdateTextureYUV = VITA_GXM_UpdateTextureYUV;
|
||||||
|
renderer->UpdateTextureNV = VITA_GXM_UpdateTextureNV;
|
||||||
#endif
|
#endif
|
||||||
renderer->LockTexture = VITA_GXM_LockTexture;
|
renderer->LockTexture = VITA_GXM_LockTexture;
|
||||||
renderer->UnlockTexture = VITA_GXM_UnlockTexture;
|
renderer->UnlockTexture = VITA_GXM_UnlockTexture;
|
||||||
|
@ -295,7 +314,17 @@ VITA_GXM_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||||
return SDL_OutOfMemory();
|
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) {
|
if (!vita_texture->tex) {
|
||||||
SDL_free(vita_texture);
|
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_GXM_SetTextureScaleMode(renderer, texture, texture->scaleMode);
|
||||||
|
|
||||||
vita_texture->w = gxm_texture_get_width(vita_texture->tex);
|
#if SDL_HAVE_YUV
|
||||||
vita_texture->h = gxm_texture_get_height(vita_texture->tex);
|
vita_texture->yuv = ((texture->format == SDL_PIXELFORMAT_IYUV) || (texture->format == SDL_PIXELFORMAT_YV12));
|
||||||
vita_texture->pitch = gxm_texture_get_stride(vita_texture->tex);
|
vita_texture->nv12 = ((texture->format == SDL_PIXELFORMAT_NV12) || (texture->format == SDL_PIXELFORMAT_NV21));
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
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
|
static int
|
||||||
VITA_GXM_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
VITA_GXM_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||||
const SDL_Rect *rect, const void *pixels, int pitch)
|
const SDL_Rect *rect, const void *pixels, int pitch)
|
||||||
{
|
{
|
||||||
const Uint8 *src;
|
VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) texture->driverdata;
|
||||||
Uint8 *dst;
|
Uint8 *dst;
|
||||||
int row, length, dpitch;
|
int row, length, dpitch;
|
||||||
src = pixels;
|
|
||||||
|
#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);
|
VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch);
|
||||||
length = rect->w * SDL_BYTESPERPIXEL(texture->format);
|
length = rect->w * SDL_BYTESPERPIXEL(texture->format);
|
||||||
if (length == pitch && length == dpitch) {
|
if (length == pitch && length == dpitch) {
|
||||||
SDL_memcpy(dst, src, length*rect->h);
|
SDL_memcpy(dst, pixels, length*rect->h);
|
||||||
} else {
|
} else {
|
||||||
for (row = 0; row < rect->h; ++row) {
|
for (row = 0; row < rect->h; ++row) {
|
||||||
SDL_memcpy(dst, src, length);
|
SDL_memcpy(dst, pixels, length);
|
||||||
src += pitch;
|
pixels += pitch;
|
||||||
dst += dpitch;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SDL_HAVE_YUV
|
||||||
static int
|
static int
|
||||||
VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
|
VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||||
const SDL_Rect * rect,
|
const SDL_Rect * rect,
|
||||||
|
@ -345,9 +465,133 @@ VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||||
const Uint8 *Uplane, int Upitch,
|
const Uint8 *Uplane, int Upitch,
|
||||||
const Uint8 *Vplane, int Vpitch)
|
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;
|
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
|
static int
|
||||||
VITA_GXM_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
VITA_GXM_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||||
const SDL_Rect *rect, void **pixels, int *pitch)
|
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)
|
float scale_x, float scale_y)
|
||||||
{
|
{
|
||||||
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
|
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
|
||||||
|
VITA_GXM_TextureData* vita_texture = (VITA_GXM_TextureData*) texture->driverdata;
|
||||||
int i;
|
int i;
|
||||||
int count = indices ? num_indices : num_vertices;
|
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].x = xy_[0] * scale_x;
|
||||||
vertices[i].y = xy_[1] * scale_y;
|
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].v = uv_[1];
|
||||||
vertices[i].color = col_;
|
vertices[i].color = col_;
|
||||||
}
|
}
|
||||||
|
@ -730,14 +975,6 @@ SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd)
|
||||||
return 0;
|
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
|
static int
|
||||||
VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
|
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;
|
nextcmd = nextcmd->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thistexture) {
|
|
||||||
ret = SetCopyState(renderer, cmd);
|
|
||||||
} else {
|
|
||||||
ret = SetDrawState(data, cmd);
|
ret = SetDrawState(data, cmd);
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
int op = SCE_GXM_PRIMITIVE_TRIANGLES;
|
int op = SCE_GXM_PRIMITIVE_TRIANGLES;
|
||||||
|
|
|
@ -117,6 +117,8 @@ tex_format_to_bytespp(SceGxmTextureFormat format)
|
||||||
case SCE_GXM_TEXTURE_BASE_FORMAT_U8:
|
case SCE_GXM_TEXTURE_BASE_FORMAT_U8:
|
||||||
case SCE_GXM_TEXTURE_BASE_FORMAT_S8:
|
case SCE_GXM_TEXTURE_BASE_FORMAT_S8:
|
||||||
case SCE_GXM_TEXTURE_BASE_FORMAT_P8:
|
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;
|
return 1;
|
||||||
case SCE_GXM_TEXTURE_BASE_FORMAT_U4U4U4U4:
|
case SCE_GXM_TEXTURE_BASE_FORMAT_U4U4U4U4:
|
||||||
case SCE_GXM_TEXTURE_BASE_FORMAT_U8U3U3U2:
|
case SCE_GXM_TEXTURE_BASE_FORMAT_U8U3U3U2:
|
||||||
|
@ -995,25 +997,6 @@ gxm_texture_get_format(const gxm_texture *texture)
|
||||||
return sceGxmTextureGetFormat(&texture->gxm_tex);
|
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 *
|
void *
|
||||||
gxm_texture_get_datap(const gxm_texture *texture)
|
gxm_texture_get_datap(const gxm_texture *texture)
|
||||||
{
|
{
|
||||||
|
@ -1021,15 +1004,34 @@ gxm_texture_get_datap(const gxm_texture *texture)
|
||||||
}
|
}
|
||||||
|
|
||||||
gxm_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));
|
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;
|
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)
|
if (!texture)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
*return_w = w;
|
||||||
|
*return_h = h;
|
||||||
|
*return_pitch = aligned_w * tex_format_to_bytespp(format);
|
||||||
|
|
||||||
/* Allocate a GPU buffer for the texture */
|
/* Allocate a GPU buffer for the texture */
|
||||||
texture_data = mem_gpu_alloc(
|
texture_data = mem_gpu_alloc(
|
||||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
|
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);
|
SDL_memset(texture_data, 0, tex_size);
|
||||||
|
|
||||||
/* Create the gxm texture */
|
/* 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) {
|
if (isRenderTarget) {
|
||||||
void *depthBufferData;
|
void *depthBufferData;
|
||||||
|
@ -1084,7 +1091,7 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
||||||
|
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
free_gxm_texture(texture);
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1107,7 +1114,7 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
||||||
|
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
free_gxm_texture(texture);
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1132,7 +1139,7 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
||||||
|
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
free_gxm_texture(texture);
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,15 +48,12 @@ void unset_clip_rectangle(VITA_GXM_RenderData *data);
|
||||||
int gxm_init(SDL_Renderer *renderer);
|
int gxm_init(SDL_Renderer *renderer);
|
||||||
void gxm_finish(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 free_gxm_texture(gxm_texture *texture);
|
||||||
|
|
||||||
void gxm_texture_set_filters(gxm_texture *texture, SceGxmTextureFilter min_filter, SceGxmTextureFilter mag_filter);
|
void gxm_texture_set_filters(gxm_texture *texture, SceGxmTextureFilter min_filter, SceGxmTextureFilter mag_filter);
|
||||||
SceGxmTextureFormat gxm_texture_get_format(const gxm_texture *texture);
|
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_texture_get_datap(const gxm_texture *texture);
|
||||||
|
|
||||||
void gxm_minimal_init_for_common_dialog(void);
|
void gxm_minimal_init_for_common_dialog(void);
|
||||||
|
|
|
@ -194,6 +194,9 @@ typedef struct
|
||||||
unsigned int pitch;
|
unsigned int pitch;
|
||||||
unsigned int w;
|
unsigned int w;
|
||||||
unsigned int h;
|
unsigned int h;
|
||||||
|
float wscale;
|
||||||
|
SDL_bool yuv;
|
||||||
|
SDL_bool nv12;
|
||||||
} VITA_GXM_TextureData;
|
} VITA_GXM_TextureData;
|
||||||
|
|
||||||
#endif /* SDL_RENDER_VITA_GXM_TYPES_H */
|
#endif /* SDL_RENDER_VITA_GXM_TYPES_H */
|
||||||
|
|
Loading…
Reference in New Issue