forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[solved] Issues with Transparent Texture in VRAM

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
centralunit



Joined: 19 Nov 2006
Posts: 4

PostPosted: Sun Nov 19, 2006 12:58 pm    Post subject: [solved] Issues with Transparent Texture in VRAM Reply with quote

Greetings!

When I use a 128x128 transparent texture, staticly allocated in VRAM, I get 5-6 white line artifakts across the texture. However if I use the same texture in system ram it works perfectly. The format Im using is 4444, Ive also tried 8888 but same result.

I dont think it's an texture allocation problem since my other textures work like they should. Im mixing 5650 and 4444 textures. Ive tried to only have my transparent texture in VRAM but I get the same white artifakts.

I also don't think it's a cache flush problem since it's only my transparent texture that get these artifacts.

Im also using the PSPTexTool, created by Henrik Rydgård, to convert my png textures.

here is my code for GU Init
Code:

m_pBackBuffer   = m_VRAM.getStaticVramBuffer( m_BufferWidth, m_ScreenHeight, GU_PSM_5650 );
m_pFrontBuffer   = m_VRAM.getStaticVramBuffer( m_BufferWidth, m_ScreenHeight, GU_PSM_5650 );
m_pZBuffer      = m_VRAM.getStaticVramBuffer( m_BufferWidth, m_ScreenHeight, GU_PSM_4444 );
m_pShadowMapTarget   = m_VRAM.getStaticVramTexture( 128, 128, GU_PSM_4444 );

sceGuInit();
sceGuStart( GU_DIRECT, GetDrawList() );
      
sceGuDrawBuffer( GU_PSM_5650, m_pBackBuffer, m_BufferWidth );
sceGuDispBuffer( m_ScreenWidth, m_ScreenHeight, m_pFrontBuffer, m_BufferWidth );
sceGuDepthBuffer( m_pZBuffer, m_BufferWidth );

sceGuOffset( 2048 - (m_ScreenWidth/2),2048 - (m_ScreenHeight/2) );
sceGuViewport( 2048,2048, m_ScreenWidth, m_ScreenHeight);
sceGuDepthRange( 65535,0 );
sceGuScissor( 0, 0, m_ScreenWidth, m_ScreenHeight );
sceGuEnable(GU_SCISSOR_TEST);
sceGuDepthFunc(GU_GEQUAL);
sceGuEnable(GU_DEPTH_TEST);
sceGuFrontFace(GU_CW);
sceGuShadeModel(GU_SMOOTH);
sceGuEnable(GU_CULL_FACE);
sceGuEnable(GU_TEXTURE_2D);
sceGuEnable(GU_CLIP_PLANES);

//   sceGuClutMode(GU_PSM_4444,0,255,0);
//   sceGuClutLoad(256/8,palette);

sceGuEnable(GU_LIGHTING);
sceGuEnable(GU_LIGHT0);
sceGuEnable(GU_LIGHT1);
      
sceGuFinish();
sceGuSync(0,0);

sceDisplayWaitVblankStart();
sceGuDisplay(GU_TRUE);



here is the code for uploading the texture to vram. Im doing this when I load my level. getStaticVramTexture is the same as in the sdk samples.
Code:

void TextureManager::UploadTexture( unsigned int a_idTexture, bool a_bStatic )
{
   Texture* pTexture = m_vTexturePool[ a_idTexture ];

   if( a_bStatic )
   {
      pTexture->m_pVRAM = m_pVRAM->getStaticVramTexture( pTexture->m_ulCanvasWidth, pTexture->m_ulHeight, pTexture->m_Format );

      sceGuStart( GU_DIRECT, m_pDevice->GetDrawList() );

      sceGuCopyImage( pTexture->m_Format, 0, 0, pTexture->m_ulWidth, pTexture->m_ulHeight, pTexture->m_ulCanvasWidth, pTexture->m_pBuffer, 0, 0, pTexture->m_ulCanvasWidth, pTexture->m_pVRAM );         

      sceGuFinish();
      sceGuSync( 0, 0 );
   }
   else
   {
      pTexture->m_pVRAM = (void*) sceGuGetMemory( (pTexture->m_ulCanvasWidth*pTexture->m_ulCanvasHeight)*pTexture->m_bpp );
      sceGuCopyImage( pTexture->m_Format, 0, 0, pTexture->m_ulWidth, pTexture->m_ulHeight, pTexture->m_ulCanvasWidth, pTexture->m_pBuffer, 0, 0, pTexture->m_ulCanvasWidth, pTexture->m_pVRAM );
      sceGuTexSync();
   }
}



here is the code for activating the texture
Code:

void TextureManager::SetTexture( unsigned int a_idTexture )
{
   Texture* pTexture = m_vTexturePool[ a_idTexture ];

   sceGuEnable( GU_TEXTURE_2D );
   sceGuTexFunc( GU_TFX_MODULATE, GU_TCC_RGBA );
   sceGuTexWrap( GU_REPEAT, GU_REPEAT );
   sceGuTexFilter( GU_LINEAR, GU_LINEAR );
   sceGuTexScale( 1.0f, 1.0f );
   sceGuTexOffset( 0.0f, 0.0f );

   if( pTexture->m_pVRAM != NULL )
   {
      sceGuTexMode( pTexture->m_Format, 0, 0, pTexture->m_bSwizzled );
      sceGuTexImage( 0, pTexture->m_ulCanvasWidth, pTexture->m_ulCanvasHeight, pTexture->m_ulCanvasWidth, pTexture->m_pVRAM );
   }
   else
   {
      sceGuTexMode( pTexture->m_Format, 0, 0, pTexture->m_bSwizzled );
      sceGuTexImage( 0, pTexture->m_ulCanvasWidth, pTexture->m_ulCanvasHeight, pTexture->m_ulCanvasWidth, pTexture->m_pBuffer );
   }
}



this is how I render the transparent objects.
Code:


sceGuStart( GU_DIRECT, GetDrawList() );

sceGuClearColor( 0xff554433 );
sceGuClearDepth( 0 );
sceGuClear( GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT );   

sceGuTexEnvColor( 0xffff00 );
sceGuAmbientColor( 0xffffffff );

sceGuSpecular(12.0f);
sceGuAmbient(0x00222222);

// Update camera
m_pCamera->Update( m_CellSelector.GetPos() );

sceGumMatrixMode(GU_MODEL);

sceGuDisable( GU_LIGHTING );
sceGuEnable( GU_BLEND );
sceGuBlendFunc( GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0 );      
sceGuTexFunc( GU_TFX_MODULATE, GU_TCC_RGBA );      
m_pTextureManager->SetTexture( 4 );

// Draw player X
for( size_t i=0; i<m_PlayerXData.m_vOnCells.size(); i++ )
{
         sceGumLoadIdentity();
   sceGumTranslate( &m_PlayerXData.m_vOnCells[i]->m_vPos );
   sceGumDrawArray( GU_TRIANGLES, GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_NORMAL_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_3D, m_PlayerXMesh.GetNumVerts(), 0, m_PlayerXMesh.GetVertices() );
}

sceGuFinish();
sceGuSync( 0, 0 );   

sceDisplayWaitVblankStart();
m_pBackBuffer = sceGuSwapBuffers();




Hope I have provided you all with usefull information. Tell me if I need to add something. Thanks in advance.

PS. Ill try to get a screenshot.

// CentralUnit


Last edited by centralunit on Mon Nov 20, 2006 10:45 pm; edited 1 time in total
Back to top
View user's profile Send private message
Raphael



Joined: 17 Jan 2006
Posts: 646
Location: Germany

PostPosted: Sun Nov 19, 2006 10:58 pm    Post subject: Re: Issues with Transparent Texture in VRAM Reply with quote

Quote:
here is the code for uploading the texture to vram. Im doing this when I load my level. getStaticVramTexture is the same as in the sdk samples.
Code:

void TextureManager::UploadTexture( unsigned int a_idTexture, bool a_bStatic )
{
   Texture* pTexture = m_vTexturePool[ a_idTexture ];

   if( a_bStatic )
   {
      pTexture->m_pVRAM = m_pVRAM->getStaticVramTexture( pTexture->m_ulCanvasWidth, pTexture->m_ulHeight, pTexture->m_Format );

      sceGuStart( GU_DIRECT, m_pDevice->GetDrawList() );

      sceGuCopyImage( pTexture->m_Format, 0, 0, pTexture->m_ulWidth, pTexture->m_ulHeight, pTexture->m_ulCanvasWidth, pTexture->m_pBuffer, 0, 0, pTexture->m_ulCanvasWidth, pTexture->m_pVRAM );         

      sceGuFinish();
      sceGuSync( 0, 0 );
   }
   else
   {
      pTexture->m_pVRAM = (void*) sceGuGetMemory( (pTexture->m_ulCanvasWidth*pTexture->m_ulCanvasHeight)*pTexture->m_bpp );
      sceGuCopyImage( pTexture->m_Format, 0, 0, pTexture->m_ulWidth, pTexture->m_ulHeight, pTexture->m_ulCanvasWidth, pTexture->m_pBuffer, 0, 0, pTexture->m_ulCanvasWidth, pTexture->m_pVRAM );
      sceGuTexSync();
   }
}


I think you got something wrong about sceGuGetMemory and it's usage. It does not allocate memory in VRAM or sth alike. All it does is return a pointer into your drawlist of the given size (which lies in system memory and not in VRAM). This pointer then is only legal during the one sceGuStart/sceGuFinish block (unless you have a double-buffered drawlist). After that, the memory in that area is very probable overwritten by commands for GU (which could lead to artifacts), so it's generally bad to store your textures there. Apart from that, you waste a lot of time (and memory) copying your texture from one position in sysram to another one, which you anyway would need to do every frame.

So basically, your whole "non-static" case is ambigious and should be removed.
If you want dynamic textures in VRAM, you need a dynamic memory manager for it. Fortunately, I already wrote one quite some time ago (http://www.fx-world.org/wordpress/?p=13). You need to exchange your getStaticVramTexture and getStaticVramBuffer with valloc for it to work properly. Your texture then will stay 'static' as long as you don't vfree the pointer. Only problem left with dynamic VRAM textures then is to free their pointer after every drawing cycle (and catch the cases when the valloc fails because of insufficient VRAM), so you need to manage that properly.

Regards,
Raphael
_________________
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
Back to top
View user's profile Send private message Visit poster's website
centralunit



Joined: 19 Nov 2006
Posts: 4

PostPosted: Sun Nov 19, 2006 11:23 pm    Post subject: Reply with quote

Hi Raphael, Thanks for your reply.

Yeah I know sceGuGetMemory only copy the texture to the displaylist. I only implemented this for test purpuse. I do not upload my textures during the game loop. I upload them (a_bStatic = true) when I load the level. Since I don't have that many textures this works for now.

Ive looked at your memory manager and good work on it. Ill probably use this when I have a more complex world that needs lots of textures.

But I still find it odd that only transparent textures get artifakts.
Ill try to find a host for my textures and screens so that I can show you.

// CentralUnit
Back to top
View user's profile Send private message
centralunit



Joined: 19 Nov 2006
Posts: 4

PostPosted: Mon Nov 20, 2006 2:54 am    Post subject: Reply with quote

Here is some screens.

Only have 1 transparent texture in VRAM, also using the posted code to draw it.


All textures in VRAM


All textures in VRAM except the transparent one


Only transparent texture in VRAM rest in system.



png of the transparent texture


ptx file of the texture. non swizzled.
http://www.starman.nu/centralunit/MarkerX.ptx
Back to top
View user's profile Send private message
rapso



Joined: 28 Mar 2005
Posts: 147

PostPosted: Mon Nov 20, 2006 6:58 pm    Post subject: Reply with quote

try to copy the texture back to sysmem after some frames and use it, to see if it has been modified.
Back to top
View user's profile Send private message
Raphael



Joined: 17 Jan 2006
Posts: 646
Location: Germany

PostPosted: Mon Nov 20, 2006 7:34 pm    Post subject: Reply with quote

centralunit wrote:
Hi Raphael, Thanks for your reply.

Yeah I know sceGuGetMemory only copy the texture to the displaylist. I only implemented this for test purpuse. I do not upload my textures during the game loop. I upload them (a_bStatic = true) when I load the level. Since I don't have that many textures this works for now.

So I am right to suppose that your textures don't end up in the drawlist, but atm only in VRAM (only the a_bStatic = true case occurs)?

Looking from the cases you showed, it seems that the upload to VRAM somehow creates those white lines in your transparent texture (3rd picture with trans texture not in VRAM does not show those lines).
I can not see any real reason for this, but I noticed you don't have a sceGuTexSync call after your static upload case. In theory this shouldn't be a problem, because the texture upload should be finished at least after the first few frames, but still it would be good habit to make sure all copying has finished before you make use of the textures.
Best would be to follow rapso's tip to check back the texture by downloading it back again from VRAM and check for consistency.
The white edges around your texture however seem independant of location of the texture, so it's more likely that your (transparent) image loader or the image converter is the source of the problem (though it's hard to see a pattern that could be caused by a faulty loader - the pattern is hardly resembled by any functional algorithm that could be used there).
BTW: Are the faces of the boxes all made up of two triangles, or more? IE, could the white corners be triangles that do not get textured due to some cause?
_________________
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
Back to top
View user's profile Send private message Visit poster's website
rapso



Joined: 28 Mar 2005
Posts: 147

PostPosted: Mon Nov 20, 2006 7:43 pm    Post subject: Reply with quote

Raphael wrote:

The white edges around your texture however seem independant of location of the texture,

probably they're kinda selection markers :)
Back to top
View user's profile Send private message
centralunit



Joined: 19 Nov 2006
Posts: 4

PostPosted: Mon Nov 20, 2006 9:48 pm    Post subject: Reply with quote

Thanks for all the replys.

Quote:

try to copy the texture back to sysmem after some frames and use it, to see if it has been modified.


Good stuff Rapso, thanks for the tip.


Quote:

So I am right to suppose that your textures don't end up in the drawlist, but atm only in VRAM (only the a_bStatic = true case occurs)?

Yes, you are right. Sorry If I confused you. I should have removed that code when I posted.

Quote:

The white edges around your texture however seem independant of location of the texture, so it's more likely that your (transparent) image loader or the image converter is the source of the problem (though it's hard to see a pattern that could be caused by a faulty loader - the pattern is hardly resembled by any functional algorithm that could be used there).

zomg.. yeah, It was the image loader for png files that was the root of all evil.

Quote:

BTW: Are the faces of the boxes all made up of two triangles, or more? IE, could the white corners be triangles that do not get textured due to some cause?

All the faces have two triangles. The white corners are actially a untextured separate mesh. I use it for selecting and moving around in the world. The X texture was a X shaped mesh from the beginning, so that I could create a shadowmap and project it on the ground but it didn't looked that good so I tossed that idea and that's when I started to use transparent textures intead.


----------

Last night I took a break from debugging and instead continued developing. I added more textures, meshes and gameplay. I also started to notice that the texture white lines started to spread to other non transparent textures.

I went through all my textures and loaders and found out that it was my font texture that I use for on-screen debugging that had been faulty allocated in the system ram. So it was only a freaky coincidence that it started to affekt transparent textures and nothing else.


Thanks Raphael and Rapso you all your work.

// CentralUnit.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group