Mipmapping and swizzling

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

Moderators: cheriff, TyRaNiD

Post Reply
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Mipmapping and swizzling

Post by Ghoti »

Hi folks,

I have this problem with my 3D rendering, the textures that are used are to big for the distance :S like when i use a 512x512 it goes really slow with a small object, when i make it 128x128 it does not go slow.
now i know it has to do with mipmapping and with swizzling, which of these has the most impact?

i have seen the texturetool but it is made with some kind of library or something so i can't use that. So i decided to make it myself the swizzling and mipmapping but can i do that with the png lib and the graphics function file (i was told from the lua player) ?

any ideas how i should handle the problem? what should i do first etc. etc. ?

every bit of feedback is welcome,

greets ghoti
Bytrix
Posts: 72
Joined: Wed Sep 14, 2005 7:26 pm
Location: England

Post by Bytrix »

Swizzling makes the most difference. Objects closer and further away will both render faster using swizzled textures. It helps on pretty much everything.

There are plenty of swizzling functions in the SDK examples.

Mipmapping as you know can help greatly if you are rendering alot of objects at various distances. I have yet to add mipmapping to my engine so I don't really know much about how to implement it on the PSP.

Also using different texture formats can greatly increase the speed of rendering. I've just started converting all my 32bit textures to 8bit CLUT (and 4bit would be even better), it has two advantages, less texture memory used and faster rendering.
rapso
Posts: 140
Joined: Mon Mar 28, 2005 6:35 am

Post by rapso »

Mipmaping has most impact on performance on far distances objects with 512*512 textures.

the GU has a cache for texturedata, each cachemiss gives you a very painfull slowdown. if you draw fardistances objects, let's assume an 32*32 pixel quad/sprite with an 512*512 texture on it, then you're mapping every 16th texel to one pixel, obviously the cache does not have read 16 texels ahead, so probably every pixel on screen causes a cachemiss.

swizzling is an optimisation to get more cachehits. the GU reads quads of texels instead of lines, lot of local texelreads like they happen during normal rendering will cause less cachemisses, but this should probably not help you as you dont have localreads, but kinda random texture reads.
swizzling will give you a great improvement used together with mipmaps tho.

I'm using both in my engine and it gives an awesome speed, one important thing to mention is the texture format, using highres textures in RGBA8 gives you half the speed compared to R5G6B5 and nearly no visual advantage. Always try to use as few bits per texel as possible, I always try to use 4bit-palleted textures, then 8bit, then R5G6B5. This is especially important on highres textures as mipmapping does not help if you have pixel:texel of 1:1, then it's just up to the raw bandwitch-power of the psp.
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

Hi where can i find those SDK examples ? my version of the SDk has only some examples but i can't seem to find anything on swizzling :S is it possible to combine the png loading with the swizzle ?

and mipmapping, do i have to implement my own distance to texture algorythm or has the psp some build in functions that automatically detect which texture to render?

any ideas and thoughts are welcome !!

greets ghoti

EDIT: i have found the TexMode function, it allows for swizzling, will test it out., mipmapping have found some info about it but it is not clear to me yet so reaction still welcome !!
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

have read some info but could not find much:

i use this: sceGuTexMode(GU_PSM_8888, 0 ,0 ,0); when i turn the last 0 in a 1, swizzling is turned on. if i do this then the textures are all messed up :S (repeating the texture alot of times for example although it normally is applied only once over the whole object.

if i only change the first parameter into GU_PSM_4444 but then the texture are messed up with al different colors :S

I guess it is not the only thing to get it working so what am i missing ?

greets ghoti
sturatt
Posts: 46
Joined: Thu Jul 13, 2006 4:21 pm

Post by sturatt »

if you turn on swizzling, you need to actually change your texture data, so it knows how to read it.

if you look around the forums, there are plenty of examples on how to swizzle your textures, and i think there are some examples on this site's wiki.
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

Hi agian, i will handle swizzling after i have made mipmapping possible :) I get the idea of mipmapping and i have created multiple images of the texture in the correct sizes. Do i have to make them 512x512 all the way to 2x2?

Here is what i'm planning to do, read all the textures into memory, then calculating the distance from the current position to the objects position. Then rendering the imagesize belonging to that distance. however this way I don't do anything automatic. how should i do it ?
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

Search for the ODE test application on the forums here and download it. It contains source using hardware mipmapping (though only one level).
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
rapso
Posts: 140
Joined: Mon Mar 28, 2005 6:35 am

Post by rapso »

you should not do it manualy as it would be a waste of ur time and performance and it will probably look worse if you do it just per object (the gu is doing it per triangle afaik, other hardware even per pixel). The psp is selecting the mip-level automatically, you just have to provide all the mipmaps.
swizzling is done pretty easy, look at the speed sample in the sdk, I think there was a simple swizzling function, or look in the yapspd, it's straightforward to implement.
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

Hi, i'll look into the ODE example but where do i get my examples from the SDK ? i don't have the speed example, i don't have the swizzling examples :S where can i get those ? i just have some basic samples which let you see how you can build some basic stuff not these kinds of things :S

greets ghoti
Bytrix
Posts: 72
Joined: Wed Sep 14, 2005 7:26 pm
Location: England

Post by Bytrix »

The SDK is installed with the toolchain in /usr/local/pspdev. The samples are in /usr/local/pspdev/psp/sdk/samples.

You can also find them on SVN:

http://svn.ps2dev.org/listing.php?repna ... rev=0&sc=0
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

whaaaaaaaaaaaaaaaaa why didn't i know that anytime sooner :S I have a pspdev sdk folder on my computer in which also samples are but not as many as these !!! this will help me a lot thank you very much !!!
User avatar
Conflict
Posts: 8
Joined: Wed May 11, 2005 9:00 am
Location: UK, York

Post by Conflict »

Q: How do I swizzle a texture?
>>> http://wiki.ps2dev.org/psp:ge_faq

I don't know why anyone didn't point you to this sooner ;>

gl
<,<;
Bytrix
Posts: 72
Joined: Wed Sep 14, 2005 7:26 pm
Location: England

Post by Bytrix »

As I said in the first reply, there are plenty of swizzling functions in the SDK examples. Anyone developing for the PSP should have the SDK and samples installed, it was the first thing I looked at. It's always better to find things yourself, he just needed to be pointed in the right direction ;-)
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

Hi, back to this problem again, i have found the ODE example. here is what i have found:

Code: Select all

sceGuTexImage&#40;0,64,64,64,metalRibbed_temp&#41;;
		sceGuTexImage&#40;1,32,32,32,metalRibbedMedium_temp&#41;;
		sceGuTexFunc&#40;GU_TFX_REPLACE,GU_TCC_RGB&#41;;
		sceGuTexEnvColor&#40;0xffff00&#41;;
		sceGuTexFilter&#40;GU_LINEAR_MIPMAP_LINEAR,GU_LINEAR_MIPMAP_LINEAR&#41;;
it seems here that it loads a 64 by 64 texture and a 32 by 32 texture for mipmapping. my question is however, i have alot of different objects, is passing each objectrender function 8 textures to the textimage function not expensive ?
Bytrix
Posts: 72
Joined: Wed Sep 14, 2005 7:26 pm
Location: England

Post by Bytrix »

I haven't done much testing, but I wouldn't imagine it would slow it down much as the actual TexImage command simply tells the GU what textures to use at each mipmap level. The actual rendering process will determine which texture to show and I wouldn't imagine it would slow down rendering at all.
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

Hi well i tried to let it work but i have some trouble with it.

Code: Select all

sceGuTexImage&#40;0, ObjMeshParts&#91;i&#93;.texture&#91;0&#93;->textureWidth, ObjMeshParts&#91;i&#93;.texture&#91;0&#93;->textureHeight, ObjMeshParts&#91;i&#93;.texture&#91;0&#93;->textureWidth, &#40;void*&#41;ObjMeshParts&#91;i&#93;.texture&#91;0&#93;->data&#41;;
sceGuTexImage&#40;1, ObjMeshParts&#91;i&#93;.texture&#91;1&#93;->textureWidth, ObjMeshParts&#91;i&#93;.texture&#91;1&#93;->textureHeight, ObjMeshParts&#91;i&#93;.texture&#91;1&#93;->textureWidth, &#40;void*&#41;ObjMeshParts&#91;i&#93;.texture&#91;1&#93;->data&#41;;
sceGuTexImage&#40;2, ObjMeshParts&#91;i&#93;.texture&#91;2&#93;->textureWidth, ObjMeshParts&#91;i&#93;.texture&#91;2&#93;->textureHeight, ObjMeshParts&#91;i&#93;.texture&#91;2&#93;->textureWidth, &#40;void*&#41;ObjMeshParts&#91;i&#93;.texture&#91;2&#93;->data&#41;;
This should load 3 texture to the mipmap function right ? Well it does not work I get a data error (psplink) when i remove the third mipmaplevel so commenting the sceGuTexImage(2,... it works fine (well my level is rendered.)

the way i load my textures in an array is as follows:

Code: Select all

sprintf&#40;sBuffer, "%s",Textures&#91;iNumberOfGroups&#93;&#41;; 
					ObjMeshParts&#91;iNumberOfGroups&#93;.texture&#91;0&#93; = loadImage&#40;sBuffer&#41;;
					if &#40;ObjMeshParts&#91;iNumberOfGroups&#93;.texture&#91;0&#93; == NULL&#41; &#123; return -4; &#125;
					
					char * pch;
					pch = strtok&#40;sBuffer,"."&#41;;

					// add the other files.
					sprintf&#40;sBuffer, "%s1.png",pch&#41;; 
					ObjMeshParts&#91;iNumberOfGroups&#93;.texture&#91;1&#93; = loadImage&#40;sBuffer&#41;;
					sprintf&#40;sBuffer, "%s2.png",pch&#41;; 
					ObjMeshParts&#91;iNumberOfGroups&#93;.texture&#91;2&#93; = loadImage&#40;sBuffer&#41;;
the texturestring is loaded from a material, lets say "texture.png"
then i create the names of the two levels extra "texture1.png" and "texture2.png" all these files are in the folder I specify and it works for the "texture.png" and the "texture1.png" but as soon as i add the "texture2.png" I get the error in my rendering sub (because when i load three texture but only use 2 of them in the rendering function it does not crash, so i guess there is a problem that the third texture is not loaded correctly or that the file can't be located. however i have gone through my dir and everything is as it should :S

any ideas ?? (i hope i have explained it correctly and clearly
Bytrix
Posts: 72
Joined: Wed Sep 14, 2005 7:26 pm
Location: England

Post by Bytrix »

The only thing I can think is that you have not allowed enough mipmap levels in your sceGuTexMode call? The second parameter is the number of mipmap levels (so you should set it to 2).

eg:

Code: Select all

sceGuTexMode&#40;GU_PSM_8888,2,0,0&#41;; // 2 levels mipmap
sceGuTexImage&#40;0,128,128,128,texture128&#41;;
sceGuTexImage&#40;1,64,64,64,texture64&#41;;
sceGuTexImage&#40;2,32,32,32,texture32&#41;;
sceGuTexFunc&#40;GU_TFX_REPLACE,GU_TCC_RGB&#41;;
from: http://forums.ps2dev.org/viewtopic.php? ... 3616da57ec
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

Hmmm thats too bad :S (thanks for the reply though) I already had that :S
here is what i have entirely:

Code: Select all

	void Obj&#58;&#58;Render&#40;float x, float y, float z, float turn&#41; &#123;

		matrix_identity&#40;&#40;float*&#41;&world&#41;;


		if &#40;turn != 0&#41; &#123; 
			matrix_identity&#40;&#40;float*&#41;&tmpworld&#41;;
			matrix_rotate&#40;&#40;float*&#41;&tmpworld,0,turn,0&#41;; 
			matrix_multiply&#40;&#40;float*&#41;&world, &#40;float*&#41;&world, &#40;float*&#41;&tmpworld&#41;; 
		&#125;

		matrix_identity&#40;&#40;float*&#41;&tmpworld&#41;;
		matrix_translate&#40;&#40;float*&#41;&tmpworld,x,y,z&#41;;
		matrix_multiply&#40;&#40;float*&#41;&world, &#40;float*&#41;&tmpworld, &#40;float*&#41;&world&#41;; 

		
		sceGuSetMatrix&#40;GU_MODEL,&world&#41;;
		
		sceGuTexMode&#40;GU_PSM_8888, 2 ,0 ,0&#41;;				// 2 mipmaplevels
		sceGuTexFunc&#40;GU_TFX_REPLACE, GU_TCC_RGB&#41;;
		//sceGuTexFilter&#40;GU_LINEAR, GU_LINEAR&#41;;
		sceGuTexFilter&#40;GU_LINEAR_MIPMAP_LINEAR,GU_LINEAR_MIPMAP_LINEAR&#41;;
		sceGuTexScale&#40;1.0f, 1.0f&#41;;
		//sceGuTexOffset&#40;0.0f, 0.0f&#41;;
		

		int i;


		for &#40;i=0;i<iNumberOfParts;i++&#41;
		&#123;
			sceGuTexImage&#40;0, ObjMeshParts&#91;i&#93;.texture&#91;0&#93;->textureWidth, ObjMeshParts&#91;i&#93;.texture&#91;0&#93;->textureHeight, ObjMeshParts&#91;i&#93;.texture&#91;0&#93;->textureWidth, &#40;void*&#41;ObjMeshParts&#91;i&#93;.texture&#91;0&#93;->data&#41;;
			sceGuTexImage&#40;1, ObjMeshParts&#91;i&#93;.texture&#91;1&#93;->textureWidth, ObjMeshParts&#91;i&#93;.texture&#91;1&#93;->textureHeight, ObjMeshParts&#91;i&#93;.texture&#91;1&#93;->textureWidth, &#40;void*&#41;ObjMeshParts&#91;i&#93;.texture&#91;1&#93;->data&#41;;
			sceGuTexImage&#40;2, ObjMeshParts&#91;i&#93;.texture&#91;2&#93;->textureWidth, ObjMeshParts&#91;i&#93;.texture&#91;2&#93;->textureHeight, ObjMeshParts&#91;i&#93;.texture&#91;2&#93;->textureWidth, &#40;void*&#41;ObjMeshParts&#91;i&#93;.texture&#91;2&#93;->data&#41;;
			sceGuDrawArray&#40;GU_TRIANGLES,GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_3D,ObjMeshParts&#91;i&#93;.iFaces*3,0,ObjMeshParts&#91;i&#93;.Vertices&#41;;
		&#125;

		return;
	&#125;;
maybe someone can get the error from this :S
Bytrix
Posts: 72
Joined: Wed Sep 14, 2005 7:26 pm
Location: England

Post by Bytrix »

Try putting in some debugging lines to check if (void*)ObjMeshParts.texture[2]->data is null ? and check the rest of ObjMeshParts.texture[2] to see that it's width and height are set properly..

Also, are the textures all 32bit?
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

hi, well not all textures are physically 32 bit, most of them are 24 bit but that does not seem to be a problem because using 1 level of mipmap works fine also 24 and 32 bit mixed.

Both checking wheter the data of the texture is null when loaded and when used seems not to be the problem. :S

I have tried to just load the zero texture as the zero mipmap, the first texture to the first AND the second mipmap but that also gave an error (also bus error data)

I have not looked into the width of the textures but speaking of that, i have a question about it. Every texture has a different starting dimension. Some start at 512x512, some at 256x256 and some other 128x128. So this results in different stage on example:

0: 512x512
1: 256x256
2: 128x128

and some other

0:128x128
1:64x64
2:32x32

does this have any bad influence ?
Post Reply