mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-10 07:49:57 -04:00
Vita: Use swizzled/twiddled textures
This commit is contained in:
parent
6b8daad36d
commit
ecbe04bebe
@ -545,16 +545,17 @@ GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags,
|
|||||||
if (!tex->data) { Platform_LogConst("Out of PVR VRAM!"); return NULL; }
|
if (!tex->data) { Platform_LogConst("Out of PVR VRAM!"); return NULL; }
|
||||||
cc_uint16* dst = tex->data;
|
cc_uint16* dst = tex->data;
|
||||||
|
|
||||||
|
int width = bmp->width, height = bmp->height;
|
||||||
unsigned maskX, maskY;
|
unsigned maskX, maskY;
|
||||||
TwiddleCalcFactors(bmp->width, bmp->height, &maskX, &maskY);
|
|
||||||
unsigned X = 0, Y = 0;
|
unsigned X = 0, Y = 0;
|
||||||
|
TwiddleCalcFactors(width, height, &maskX, &maskY);
|
||||||
|
|
||||||
for (int y = 0; y < bmp->height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
cc_uint8* src = (cc_uint8*)(bmp->scan0 + y * rowWidth);
|
cc_uint8* src = (cc_uint8*)(bmp->scan0 + y * rowWidth);
|
||||||
X = 0;
|
X = 0;
|
||||||
|
|
||||||
for (int x = 0; x < bmp->width; x++, src += 4)
|
for (int x = 0; x < width; x++, src += 4)
|
||||||
{
|
{
|
||||||
dst[X | Y] = BGRA8_to_BGRA4(src);
|
dst[X | Y] = BGRA8_to_BGRA4(src);
|
||||||
X = (X - maskX) & maskX;
|
X = (X - maskX) & maskX;
|
||||||
@ -567,9 +568,10 @@ GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags,
|
|||||||
void Gfx_UpdateTexture(GfxResourceID texId, int originX, int originY, struct Bitmap* part, int rowWidth, cc_bool mipmaps) {
|
void Gfx_UpdateTexture(GfxResourceID texId, int originX, int originY, struct Bitmap* part, int rowWidth, cc_bool mipmaps) {
|
||||||
TextureObject* tex = (TextureObject*)texId;
|
TextureObject* tex = (TextureObject*)texId;
|
||||||
|
|
||||||
|
int width = part->width, height = part->height;
|
||||||
unsigned maskX, maskY;
|
unsigned maskX, maskY;
|
||||||
TwiddleCalcFactors(tex->width, tex->height, &maskX, &maskY);
|
|
||||||
unsigned X = 0, Y = 0;
|
unsigned X = 0, Y = 0;
|
||||||
|
TwiddleCalcFactors(tex->width, tex->height, &maskX, &maskY);
|
||||||
|
|
||||||
// Calculate start twiddled X and Y values
|
// Calculate start twiddled X and Y values
|
||||||
for (int x = 0; x < originX; x++) { X = (X - maskX) & maskX; }
|
for (int x = 0; x < originX; x++) { X = (X - maskX) & maskX; }
|
||||||
@ -577,12 +579,12 @@ void Gfx_UpdateTexture(GfxResourceID texId, int originX, int originY, struct Bit
|
|||||||
unsigned startX = X;
|
unsigned startX = X;
|
||||||
cc_uint16* dst = tex->data;
|
cc_uint16* dst = tex->data;
|
||||||
|
|
||||||
for (int y = 0; y < part->height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
cc_uint8* src = (cc_uint8*)(part->scan0 + rowWidth * y);
|
cc_uint8* src = (cc_uint8*)(part->scan0 + rowWidth * y);
|
||||||
X = startX;
|
X = startX;
|
||||||
|
|
||||||
for (int x = 0; x < part->width; x++, src += 4)
|
for (int x = 0; x < width; x++, src += 4)
|
||||||
{
|
{
|
||||||
dst[X | Y] = BGRA8_to_BGRA4(src);
|
dst[X | Y] = BGRA8_to_BGRA4(src);
|
||||||
X = (X - maskX) & maskX;
|
X = (X - maskX) & maskX;
|
||||||
|
@ -673,6 +673,32 @@ static void GPUTextures_DeleteUnreferenced(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See Graphics_Dreamcast.c for twiddling explanation
|
||||||
|
static CC_INLINE void TwiddleCalcFactors(unsigned w, unsigned h,
|
||||||
|
unsigned* maskX, unsigned* maskY) {
|
||||||
|
*maskX = 0;
|
||||||
|
*maskY = 0;
|
||||||
|
int shift = 0;
|
||||||
|
|
||||||
|
for (; w > 1 || h > 1; w >>= 1, h >>= 1)
|
||||||
|
{
|
||||||
|
if (w > 1 && h > 1) {
|
||||||
|
// Add interleaved X and Y bits
|
||||||
|
*maskY += 0x01 << shift;
|
||||||
|
*maskX += 0x02 << shift;
|
||||||
|
shift += 2;
|
||||||
|
} else if (w > 1) {
|
||||||
|
// Add a linear X bit
|
||||||
|
*maskX += 0x01 << shift;
|
||||||
|
shift += 1;
|
||||||
|
} else if (h > 1) {
|
||||||
|
// Add a linear Y bit
|
||||||
|
*maskY += 0x01 << shift;
|
||||||
|
shift += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*---------------------------------------------------------Textures--------------------------------------------------------*
|
*---------------------------------------------------------Textures--------------------------------------------------------*
|
||||||
@ -680,27 +706,64 @@ static void GPUTextures_DeleteUnreferenced(void) {
|
|||||||
GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags, cc_bool mipmaps) {
|
GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags, cc_bool mipmaps) {
|
||||||
int size = bmp->width * bmp->height * 4;
|
int size = bmp->width * bmp->height * 4;
|
||||||
struct GPUTexture* tex = GPUTexture_Alloc(size);
|
struct GPUTexture* tex = GPUTexture_Alloc(size);
|
||||||
CopyTextureData(tex->data, bmp->width * BITMAPCOLOR_SIZE,
|
cc_uint32* dst = tex->data;
|
||||||
bmp, rowWidth * BITMAPCOLOR_SIZE);
|
|
||||||
|
|
||||||
sceGxmTextureInitLinear(&tex->texture, tex->data,
|
int width = bmp->width, height = bmp->height;
|
||||||
SCE_GXM_TEXTURE_FORMAT_A8B8G8R8, bmp->width, bmp->height, 0);
|
unsigned maskX, maskY;
|
||||||
|
unsigned X = 0, Y = 0;
|
||||||
|
TwiddleCalcFactors(width, height, &maskX, &maskY);
|
||||||
|
|
||||||
|
for (int y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
cc_uint32* src = bmp->scan0 + y * rowWidth;
|
||||||
|
X = 0;
|
||||||
|
|
||||||
|
for (int x = 0; x < width; x++, src++)
|
||||||
|
{
|
||||||
|
dst[X | Y] = *src;
|
||||||
|
X = (X - maskX) & maskX;
|
||||||
|
}
|
||||||
|
Y = (Y - maskY) & maskY;
|
||||||
|
}
|
||||||
|
|
||||||
|
sceGxmTextureInitSwizzled(&tex->texture, dst,
|
||||||
|
SCE_GXM_TEXTURE_FORMAT_A8B8G8R8, width, height, 0);
|
||||||
|
|
||||||
sceGxmTextureSetUAddrMode(&tex->texture, SCE_GXM_TEXTURE_ADDR_REPEAT);
|
sceGxmTextureSetUAddrMode(&tex->texture, SCE_GXM_TEXTURE_ADDR_REPEAT);
|
||||||
sceGxmTextureSetVAddrMode(&tex->texture, SCE_GXM_TEXTURE_ADDR_REPEAT);
|
sceGxmTextureSetVAddrMode(&tex->texture, SCE_GXM_TEXTURE_ADDR_REPEAT);
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_UpdateTexture(GfxResourceID texId, int x, int y, struct Bitmap* part, int rowWidth, cc_bool mipmaps) {
|
void Gfx_UpdateTexture(GfxResourceID texId, int originX, int originY, struct Bitmap* part, int rowWidth, cc_bool mipmaps) {
|
||||||
struct GPUTexture* tex = (struct GPUTexture*)texId;
|
struct GPUTexture* tex = (struct GPUTexture*)texId;
|
||||||
int texWidth = sceGxmTextureGetWidth(&tex->texture);
|
int texWidth = sceGxmTextureGetWidth(&tex->texture);
|
||||||
|
int texHeight = sceGxmTextureGetHeight(&tex->texture);
|
||||||
|
cc_uint32* dst = tex->data;
|
||||||
|
|
||||||
// NOTE: Only valid for LINEAR textures
|
int width = part->width, height = part->height;
|
||||||
BitmapCol* dst = (tex->data + x) + y * texWidth;
|
unsigned maskX, maskY;
|
||||||
|
unsigned X = 0, Y = 0;
|
||||||
|
TwiddleCalcFactors(texWidth, texHeight, &maskX, &maskY);
|
||||||
|
|
||||||
CopyTextureData(dst, texWidth * BITMAPCOLOR_SIZE,
|
// Calculate start twiddled X and Y values
|
||||||
part, rowWidth * BITMAPCOLOR_SIZE);
|
for (int x = 0; x < originX; x++) { X = (X - maskX) & maskX; }
|
||||||
// TODO: Do line by line and only invalidate the actually changed parts of lines?
|
for (int y = 0; y < originY; y++) { Y = (Y - maskY) & maskY; }
|
||||||
|
unsigned startX = X;
|
||||||
|
|
||||||
|
for (int y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
cc_uint32* src = part->scan0 + rowWidth * y;
|
||||||
|
X = startX;
|
||||||
|
|
||||||
|
for (int x = 0; x < width; x++, src++)
|
||||||
|
{
|
||||||
|
dst[X | Y] = *src;
|
||||||
|
X = (X - maskX) & maskX;
|
||||||
|
}
|
||||||
|
Y = (Y - maskY) & maskY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: is it necessary to invalidate? probably just everything?
|
||||||
//sceKernelDcacheWritebackInvalidateRange(dst, (tex->width * part->height) * 4);
|
//sceKernelDcacheWritebackInvalidateRange(dst, (tex->width * part->height) * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,16 +181,17 @@ GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags,
|
|||||||
tex->height = bmp->height;
|
tex->height = bmp->height;
|
||||||
cc_uint32* dst = tex->pixels;
|
cc_uint32* dst = tex->pixels;
|
||||||
|
|
||||||
|
int width = bmp->width, height = bmp->height;
|
||||||
unsigned maskX, maskY;
|
unsigned maskX, maskY;
|
||||||
TwiddleCalcFactors(bmp->width, bmp->height, &maskX, &maskY);
|
|
||||||
unsigned X = 0, Y = 0;
|
unsigned X = 0, Y = 0;
|
||||||
|
TwiddleCalcFactors(width, height, &maskX, &maskY);
|
||||||
|
|
||||||
for (int y = 0; y < bmp->height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
cc_uint32* src = bmp->scan0 + y * rowWidth;
|
cc_uint32* src = bmp->scan0 + y * rowWidth;
|
||||||
X = 0;
|
X = 0;
|
||||||
|
|
||||||
for (int x = 0; x < bmp->width; x++, src++)
|
for (int x = 0; x < width; x++, src++)
|
||||||
{
|
{
|
||||||
dst[X | Y] = *src;
|
dst[X | Y] = *src;
|
||||||
X = (X - maskX) & maskX;
|
X = (X - maskX) & maskX;
|
||||||
@ -204,21 +205,22 @@ void Gfx_UpdateTexture(GfxResourceID texId, int originX, int originY, struct Bit
|
|||||||
CCTexture* tex = (CCTexture*)texId;
|
CCTexture* tex = (CCTexture*)texId;
|
||||||
cc_uint32* dst = tex->pixels;
|
cc_uint32* dst = tex->pixels;
|
||||||
|
|
||||||
|
int width = part->width, height = part->height;
|
||||||
unsigned maskX, maskY;
|
unsigned maskX, maskY;
|
||||||
TwiddleCalcFactors(tex->width, tex->height, &maskX, &maskY);
|
|
||||||
unsigned X = 0, Y = 0;
|
unsigned X = 0, Y = 0;
|
||||||
|
TwiddleCalcFactors(tex->width, tex->height, &maskX, &maskY);
|
||||||
|
|
||||||
// Calculate start twiddled X and Y values
|
// Calculate start twiddled X and Y values
|
||||||
for (int x = 0; x < originX; x++) { X = (X - maskX) & maskX; }
|
for (int x = 0; x < originX; x++) { X = (X - maskX) & maskX; }
|
||||||
for (int y = 0; y < originY; y++) { Y = (Y - maskY) & maskY; }
|
for (int y = 0; y < originY; y++) { Y = (Y - maskY) & maskY; }
|
||||||
unsigned startX = X;
|
unsigned startX = X;
|
||||||
|
|
||||||
for (int y = 0; y < part->height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
cc_uint32* src = part->scan0 + rowWidth * y;
|
cc_uint32* src = part->scan0 + rowWidth * y;
|
||||||
X = startX;
|
X = startX;
|
||||||
|
|
||||||
for (int x = 0; x < part->width; x++, src++)
|
for (int x = 0; x < width; x++, src++)
|
||||||
{
|
{
|
||||||
dst[X | Y] = *src;
|
dst[X | Y] = *src;
|
||||||
X = (X - maskX) & maskX;
|
X = (X - maskX) & maskX;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user