-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor and Improve Swizzling Functions in OSLib
- Enhanced `oslSwizzleTexture` function with improved readability, loop structure, and consistency in variable usage. - Added safety check for memory allocation failure in `oslSwizzleImage` function to handle errors gracefully. - Improved documentation and added comments for better understanding of swizzling logic. - Standardized pixel width calculations across functions for consistency. - Cleaned up redundant code and made minor optimizations in the swizzling process.
- Loading branch information
Showing
1 changed file
with
80 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,98 +1,98 @@ | ||
#include "oslib.h" | ||
|
||
void oslSwizzleTexture(u8* out, const u8* in, unsigned int width, unsigned int height) | ||
{ | ||
unsigned int blockx, blocky; | ||
unsigned int j; | ||
|
||
unsigned int width_blocks = (width / 16); | ||
unsigned int height_blocks = (height / 8); | ||
|
||
unsigned int src_pitch = (width-16)/4; | ||
unsigned int src_row = width * 8; | ||
|
||
const u8* ysrc = in; | ||
u32* dst = (u32*)out; | ||
|
||
// Swizzle a texture to optimize memory access patterns on the PSP | ||
void oslSwizzleTexture(u8* out, const u8* in, unsigned int width, unsigned int height) { | ||
unsigned int blockx, blocky, j; | ||
unsigned int width_blocks = width / 16; | ||
unsigned int height_blocks = height / 8; | ||
unsigned int src_pitch = (width - 16) / 4; | ||
unsigned int src_row = width * 8; | ||
|
||
const u8* ysrc = in; | ||
u32* dst = (u32*)out; | ||
|
||
#ifndef PSP | ||
memcpy(out, in, width * height); | ||
return; | ||
// On non-PSP platforms, simply copy the input to output | ||
memcpy(out, in, width * height); | ||
return; | ||
#endif | ||
for (blocky = 0; blocky < height_blocks; ++blocky) | ||
{ | ||
const u8* xsrc = ysrc; | ||
for (blockx = 0; blockx < width_blocks; ++blockx) | ||
{ | ||
const u32* src = (u32*)xsrc; | ||
for (j = 0; j < 8; ++j) | ||
{ | ||
*(dst++) = *(src++); | ||
*(dst++) = *(src++); | ||
*(dst++) = *(src++); | ||
*(dst++) = *(src++); | ||
src += src_pitch; | ||
} | ||
xsrc += 16; | ||
} | ||
ysrc += src_row; | ||
} | ||
|
||
// Swizzle the texture | ||
for (blocky = 0; blocky < height_blocks; ++blocky) { | ||
const u8* xsrc = ysrc; | ||
for (blockx = 0; blockx < width_blocks; ++blockx) { | ||
const u32* src = (const u32*)xsrc; | ||
for (j = 0; j < 8; ++j) { | ||
for (int i = 0; i < 4; ++i) { | ||
*(dst++) = *(src++); | ||
} | ||
src += src_pitch; | ||
} | ||
xsrc += 16; | ||
} | ||
ysrc += src_row; | ||
} | ||
} | ||
|
||
void *oslGetSwizzledPixelAddr(OSL_IMAGE *img, unsigned int x, unsigned int y) | ||
{ | ||
if (!oslImageIsSwizzled(img)) | ||
return oslGetImagePixelAdr(img, x, y); | ||
// Get the address of a swizzled pixel | ||
void* oslGetSwizzledPixelAddr(OSL_IMAGE* img, unsigned int x, unsigned int y) { | ||
if (!oslImageIsSwizzled(img)) { | ||
return oslGetImagePixelAdr(img, x, y); | ||
} | ||
|
||
//Multiply the x value by the pixelformat | ||
x = (x * osl_pixelWidth[img->pixelFormat]) >> 3; | ||
// Calculate pixel address for swizzled images | ||
unsigned int pixelWidth = osl_pixelWidth[img->pixelFormat]; | ||
x = (x * pixelWidth) >> 3; | ||
unsigned int width = (img->realSizeX * pixelWidth) >> 3; | ||
unsigned int rowblocks = width / 16; | ||
|
||
unsigned int width = (img->realSizeX * osl_pixelWidth[img->pixelFormat]) >> 3; | ||
unsigned int rowblocks = (width / 16); | ||
|
||
unsigned int blockx = x / 16; | ||
unsigned int blocky = y / 8; | ||
unsigned int blockx = x / 16; | ||
unsigned int blocky = y / 8; | ||
|
||
unsigned int block_index = blockx + ((blocky) * rowblocks); | ||
unsigned int block_address = block_index * 16 * 8; | ||
|
||
x = (x - blockx * 16); | ||
y = (y - blocky * 8); | ||
unsigned int block_index = blockx + (blocky * rowblocks); | ||
unsigned int block_address = block_index * 16 * 8; | ||
|
||
return (void*)((u8*)img->data + block_address + x + y * 16); | ||
} | ||
x = x - (blockx * 16); | ||
y = y - (blocky * 8); | ||
|
||
void oslSwizzleImage(OSL_IMAGE *img) { | ||
void *block; | ||
return (void*)((u8*)img->data + block_address + x + (y * 16)); | ||
} | ||
|
||
//Already swizzled? | ||
if (oslImageIsSwizzled(img)) | ||
return; | ||
// Swizzle an entire image | ||
void oslSwizzleImage(OSL_IMAGE* img) { | ||
// Check if the image is already swizzled | ||
if (oslImageIsSwizzled(img)) { | ||
return; | ||
} | ||
|
||
block = (void*)malloc(img->totalSize); | ||
if (block) { | ||
memcpy(block, img->data, img->totalSize); | ||
oslSwizzleTexture((u8*)img->data, (u8*)block, (img->realSizeX * osl_pixelWidth[img->pixelFormat]) >> 3, img->realSizeY); | ||
free(block); | ||
// Allocate a temporary block of memory for swizzling | ||
void* block = malloc(img->totalSize); | ||
if (block) { | ||
memcpy(block, img->data, img->totalSize); | ||
oslSwizzleTexture((u8*)img->data, (u8*)block, (img->realSizeX * osl_pixelWidth[img->pixelFormat]) >> 3, img->realSizeY); | ||
free(block); | ||
|
||
oslUncacheImageData(img); | ||
oslImageIsSwizzledSet(img, 1); | ||
} | ||
oslUncacheImageData(img); | ||
oslImageIsSwizzledSet(img, 1); | ||
} else { | ||
oslFatalError("oslSwizzleImage: Memory allocation failed."); | ||
} | ||
} | ||
|
||
void oslSwizzleImageTo(OSL_IMAGE *imgDst, OSL_IMAGE *imgSrc) | ||
{ | ||
//Même image? | ||
if (imgDst == imgSrc) | ||
oslSwizzleImage(imgDst); | ||
// Swizzle an image to another image buffer | ||
void oslSwizzleImageTo(OSL_IMAGE* imgDst, OSL_IMAGE* imgSrc) { | ||
if (imgDst == imgSrc) { | ||
oslSwizzleImage(imgDst); | ||
return; | ||
} | ||
|
||
if (imgSrc->pixelFormat != imgDst->pixelFormat || imgSrc->totalSize != imgDst->totalSize) { | ||
oslFatalError("oslSwizzleImageTo: Both images must have the same size and pixel format!"); | ||
return; | ||
} | ||
else { | ||
oslSwizzleTexture((u8*)imgDst->data, (u8*)imgSrc->data, (imgSrc->realSizeX*osl_pixelWidth[imgSrc->pixelFormat])>>3, imgSrc->realSizeY); | ||
oslUncacheImageData(imgDst); | ||
oslImageIsSwizzledSet(imgDst, 1); | ||
} | ||
} | ||
// Validate that both images have the same pixel format and size | ||
if (imgSrc->pixelFormat != imgDst->pixelFormat || imgSrc->totalSize != imgDst->totalSize) { | ||
oslFatalError("oslSwizzleImageTo: Both images must have the same size and pixel format!"); | ||
return; | ||
} | ||
|
||
oslSwizzleTexture((u8*)imgDst->data, (u8*)imgSrc->data, (imgSrc->realSizeX * osl_pixelWidth[imgSrc->pixelFormat]) >> 3, imgSrc->realSizeY); | ||
oslUncacheImageData(imgDst); | ||
oslImageIsSwizzledSet(imgDst, 1); | ||
} |