Aligning memory to 16 bytes with new operator

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
ddgFFco
Posts: 11
Joined: Tue Sep 20, 2005 5:35 pm

Aligning memory to 16 bytes with new operator

Post by ddgFFco »

Hello again, I’m having a bit of trouble with my images looking slightly ‘corrupted’ when displayed on the PSP. I had a look in pspgu.h and noticed this:

Code: Select all

/**
  * Set current texturemap
  *
  * Textures may reside in main RAM, but it has a huge speed-penalty. Swizzle textures
  * to get maximum speed.
  *
  * @note Data must be aligned to 1 quad word (16 bytes)
  *
  * @param mipmap - Mipmap level
  * @param width - Width of texture (must be a power of 2)
  * @param height - Height of texture (must be a power of 2)
  * @param tbw - Texture Buffer Width (block-aligned)
  * @param tbp - Texture buffer pointer (16 byte aligned)
**/
void sceGuTexImage(int mipmap, int width, int height, int tbw, const void* tbp);

It seams my texture buffer needs to be 16-byte aligned, which it’s currently not and I’m assuming that’s my problem.

I create a texture with something similar to this:

Code: Select all

unsigned int height = 64;
unsigned int width = 64;
unsigned int* pixels = new unsigned int[height*width];
    
for &#40;u32 y = 0;  y < height;  y++&#41; &#123;
    for &#40;u32 x = 0;  x< width;  x++&#41; &#123;
        pixels&#91;y*_width + x&#93; = 0xFF0000FF;
    &#125; 
&#125;
    
pixels = &#40;u32*&#41;&#40;&#40;u32&#41;pixels | 0x40000000&#41;;
But how do I align memory created with the new operator to 16 bytes? I know there is memalign() but that seams to be old C style and I prefer the use of ‘new’, there’s also __attribute__((aligned(16))) but that doesn’t seam to work for memory allocated at runtime.

Thanks for any help.
chp
Posts: 313
Joined: Wed Jun 23, 2004 7:16 am

Post by chp »

There are two solutions to this:

a) Write your own operator new & delete that aligns memory-allocations.

You usually just have to write something like:

Code: Select all

void* operator new&#40;size_t size&#41;
&#123;
 return memalign&#40;16,size&#41;;
&#125;

void operator free&#40;void* p&#41;
&#123;
 free&#40;p&#41;;
&#125;
And the additional for new[], etc.

b) Use a custom allocator for allocations that need to be aligned.

Example:

Code: Select all

class Allocator
&#123;
public&#58;
 virtual void* allocate&#40;size_t size&#41; &#123; return malloc&#40;size&#41;; &#125;
 static Allocator instance;
&#125;

class AlignedAllocator &#58; public Allocator
&#123;
public&#58;
 void* allocate&#40;size_t size&#41; &#123; return memalign&#40;16,size&#41;; &#125;
 static AlignedAllocator instance;
&#125;

void* operator new&#40;size_t size, Allocator& allocator&#41;
&#123;
 return allocator.allocate&#40;size&#41;;
&#125;
Then you can use do something like this:

Code: Select all

char* texture = new &#40;AlignedAllocator&#58;&#58;instance&#41; char&#91;256*256&#93;;
And it will allocate aligned memory. Remember to overload global deletes as well if you start customizing new.
GE Dominator
Post Reply