About pvr_mem_available() , pvr_mem_stats() a bug ?

If you have any questions on programming, this is the place to ask them, whether you're a newbie or an experienced programmer. Discussion on programming in general is also welcome. We will help you with programming homework, but we will not do your work for you! Any porting requests must be made in Developmental Ideas.
Post Reply
User avatar
Newbie
Insane DCEmu
Insane DCEmu
Posts: 171
https://www.artistsworkshop.eu/meble-kuchenne-na-wymiar-warszawa-gdzie-zamowic/
Joined: Sat Jul 27, 2013 1:16 pm
Has thanked: 0
Been thanked: 0

About pvr_mem_available() , pvr_mem_stats() a bug ?

Post by Newbie »

I want to trakc PVR memory consumption so i found the pvr_mem_available() function.

i use this :

Code: Select all


int main(int argc, char* argv[])
{    
	pvr_init_defaults();
	pvr_set_bg_color(1, 1, 1);	
	
	printf("AVAILABLE MEMORY IN PVR IN BYTES IS              :  %u... \n", pvr_mem_available());
			
	pvr_shutdown ();
		 
	return 0;
}

But it reports me 0 ...

Then after some loadings it report me very strange values :
2632
552
1800

Its very weird ....
Last edited by Newbie on Sun Jun 08, 2014 8:45 am, edited 1 time in total.
User avatar
Newbie
Insane DCEmu
Insane DCEmu
Posts: 171
Joined: Sat Jul 27, 2013 1:16 pm
Has thanked: 0
Been thanked: 0

Re: About pvr_mem_available()

Post by Newbie »

I have changed the % thing in printf first to %d (integer display) to %u (unsigned integer display) and finally to %"PRIu32".

Compiler does not complain anymore trying to warn me about incorrect printf display.

So to display uint32 better use %"PRIu32".

I obtain this :

Code: Select all


int main(int argc, char* argv[])
{    
	pvr_init_defaults();
	pvr_set_bg_color(1, 1, 1);	
	
	printf("AT START AVAILABLE MEMORY IN PVR IN BYTES IS              :  %"PRIu32"... \n", pvr_mem_available());
	
	pvr_shutdown ();
		 
	return 0;
}

But it still report 0 .... So there are none memory available in PVR after just init it ? That always weird ...
User avatar
Newbie
Insane DCEmu
Insane DCEmu
Posts: 171
Joined: Sat Jul 27, 2013 1:16 pm
Has thanked: 0
Been thanked: 0

Re: About pvr_mem_available()

Post by Newbie »

As pvr_mem_available() seems to report weird result, i try to use pvr_mem_stats().

I use this :

Code: Select all


int main(int argc, char* argv[])
{    
	pvr_init_defaults();
	pvr_set_bg_color(1, 1, 1);	
	
	pvr_mem_stats();
			
	pvr_shutdown ();
		 
	return 0;
}

Output is :

pvr_mem_stats():
max system bytes = 0
system bytes = 0
in use bytes = 0
max sbrk base: a4396700


the "max system bytes = 0" would mean that there are no bytes available in PVR at start up ?
User avatar
Newbie
Insane DCEmu
Insane DCEmu
Posts: 171
Joined: Sat Jul 27, 2013 1:16 pm
Has thanked: 0
Been thanked: 0

Re: About pvr_mem_available()

Post by Newbie »

I continue my investigations about video memory.
This time, I have an example with a load of 64 per 64 RGB565 textures.

I request the statistics for the first time before any data loading.
Then, after each load, I ask a display memory statistics using pvr_mem_stats() and pvr_mem_available() functions.

Functions GetBlueTexture() GetBlackTexture() GetRedTexture() allow me to place a blue, black, red 64*64 RGB565 texture in video memory.

The main function in my code looks like this :

Code: Select all


int main(int argc, char* argv[])
{    
	pvr_init_defaults();
	pvr_set_bg_color(1, 1, 1);	

	printf("AVAILABLE MEMORY IN PVR IN BYTES IS              :  %"PRIu32" \n", pvr_mem_available());
	pvr_mem_stats();
	
	//LOADING IN PVR A 64 *64 SQUARED 565 BLUE TEXTURE
	Texture blue = GetBlueTexture();
	
	printf("AVAILABLE MEMORY IN PVR IN BYTES IS              :  %"PRIu32" \n", pvr_mem_available());
	pvr_mem_stats();
	
	//LOADING IN PVR A 64 *64 SQUARED 565 BLACK TEXTURE
	Texture black = GetBlackTexture();
	
	printf("AVAILABLE MEMORY IN PVR IN BYTES IS              :  %"PRIu32" \n", pvr_mem_available());
	pvr_mem_stats();
	
	//LOADING IN PVR A 64 *64 SQUARED 565 RED TEXTURE
	Texture red = GetRedTexture();
	
	printf("AVAILABLE MEMORY IN PVR IN BYTES IS              :  %"PRIu32" \n", pvr_mem_available());
	pvr_mem_stats();	

	//LOADING IN PVR A 64 *64 SQUARED 565 RED TEXTURE
	Texture red2 = GetRedTexture();
	
	printf("AVAILABLE MEMORY IN PVR IN BYTES IS              :  %"PRIu32" \n", pvr_mem_available());
	pvr_mem_stats();	
	
	pvr_shutdown ();
		 
	return 0;
}


Here is what I get :

AVAILABLE MEMORY IN PVR IN BYTES IS : 0
pvr_mem_stats():
max system bytes = 0
system bytes = 0
in use bytes = 0
max sbrk base: a4396700

AVAILABLE MEMORY IN PVR IN BYTES IS : 6344
pvr_mem_stats():
max system bytes = 14592
system bytes = 14592
in use bytes = 8248
max sbrk base: a439a000

AVAILABLE MEMORY IN PVR IN BYTES IS : 2216
pvr_mem_stats():
max system bytes = 18688
system bytes = 18688
in use bytes = 16472
max sbrk base: a439b000

AVAILABLE MEMORY IN PVR IN BYTES IS : 2184
pvr_mem_stats():
max system bytes = 26880
system bytes = 26880
in use bytes = 24696
max sbrk base: a439d000

AVAILABLE MEMORY IN PVR IN BYTES IS : 2152
pvr_mem_stats():
max system bytes = 35072
system bytes = 35072
in use bytes = 32920
max sbrk base: a439f000

As I said before, at first time the pvr_mem_available() reports no bytes available in PVR before any loading and after init.
max system bytes and system bytes are 0 : is it a bug ?

After the first load, the bytes available in PVR jump from 0 to 6344 but i don't think that it remains only 6344 bytes after loading a 64*64*2 = 8192 bytes texture. max system bytes and system bytes are the same unknown value 14592. The used bytes are 8248 > 8192 (size of the texture loaded) : 56 bytes exceeding ...

After the second load, the bytes available in PVR jump from 6344 to 2216 but 4128 (6344 - 2216) is not the size of a 64*64*2 = 8192 bytes texture. max system bytes and system bytes are the same unknown value 18688. 18688 - 14592 is 4096 and so not the size of the 64*64 texture. The used bytes are 16472 > 16384 (size of the 2 textures loaded) : 88 bytes exceeding which is not 56*2 if you know what i mean ...

And you could see strange values for the rest of the test ... i am lost ...

Is there another way to have correct values to see at runtime from PVR available memory ?
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5658
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has thanked: 9 times
Been thanked: 69 times
Contact:

Re: About pvr_mem_available() , pvr_mem_stats() a bug ?

Post by BlueCrab »

It does indeed appear to be broken.

I'm not sure what's wrong, but it definitely isn't working properly. I'll try to get a chance to take a look at it over the next few days.
User avatar
Newbie
Insane DCEmu
Insane DCEmu
Posts: 171
Joined: Sat Jul 27, 2013 1:16 pm
Has thanked: 0
Been thanked: 0

Re: About pvr_mem_available() , pvr_mem_stats() a bug ?

Post by Newbie »

Thanks a lot.
User avatar
Newbie
Insane DCEmu
Insane DCEmu
Posts: 171
Joined: Sat Jul 27, 2013 1:16 pm
Has thanked: 0
Been thanked: 0

Re: About pvr_mem_available() , pvr_mem_stats() a bug ?

Post by Newbie »

So ...
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5658
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has thanked: 9 times
Been thanked: 69 times
Contact:

Re: About pvr_mem_available() , pvr_mem_stats() a bug ?

Post by BlueCrab »

Truth be told, I haven't had a chance to look.
User avatar
PH3NOM
DC Developer
DC Developer
Posts: 576
Joined: Fri Jun 18, 2010 9:29 pm
Has thanked: 0
Been thanked: 5 times

Re: About pvr_mem_available()

Post by PH3NOM »

Newbie wrote:I continue my investigations about video memory.
This time, I have an example with a load of 64 per 64 RGB565 textures.

I request the statistics for the first time before any data loading.
Then, after each load, I ask a display memory statistics using pvr_mem_stats() and pvr_mem_available() functions.

Functions GetBlueTexture() GetBlackTexture() GetRedTexture() allow me to place a blue, black, red 64*64 RGB565 texture in video memory.

Is there another way to have correct values to see at runtime from PVR available memory ?
Hi there.
I just had a quick look into this for you! Yes it is possible.

It is easy to keep track of PVR texture memory used yourself.

The size of the PVR's memory bank is 1024*1024*8 bytes, or 0x800000 bytes.

Keep in mind, that memory bank is used for:
-PVR Vertex Buffer
-PVR Frame Buffer
-PVR Texture Data

You can set the size of the Vertex Buffer when initializing the PVR by using pvr_init(...).
Using pvr_init_defaults() will use a relatively small Vertex Buffer of size 512 * 1024 bytes.

Using pvr_init_defaults() will give you exactly 4626688 bytes left for texture data.
How did I figure that number?
Looking at pvr_buffers.c in KOS, I saw this line of code:

Code: Select all

    dbglog(DBG_KDEBUG, "Free texture memory: %ld bytes\n",
           0x800000 - pvr_state.texture_base);
So I turned that into a function!
All you need to do is copy pvr_internal.h from KOS into your source directory.

Code: Select all

#include "pvr_internal.h"

static size_t PVR_TEX_MALLOC = 0;

unsigned int pvr_texture_memory_total()
{
    return 0x800000 - pvr_state.texture_base;
}

unsigned int pvr_texture_memory_free()
{
	return pvr_texture_memory_total() - PVR_TEX_MALLOC;
}

pvr_ptr_t pvr_malloc(size_t size)
{
	PVR_TEX_MALLOC += size;
	return pvr_mem_malloc(size);
}

void pvr_free(pvr_ptr_t chunk, size_t size)
{
	PVR_TEX_MALLOC -= size;
	return pvr_mem_free(chunk);
}
A little test code for those pvr wrappers confirms everything is legit:

Code: Select all

	pvr_init_defaults();

	printf("PVR: Total Texture Memory: %i\n", pvr_texture_memory_total());
	printf("PVR: Free Texture Memory: %i\n", pvr_texture_memory_free());
	printf("PVR: Malloc() Space for 128*128 texture....\n");
	
	pvr_ptr_t *tex = NULL;
	tex = pvr_malloc(128*128*2);

	printf("PVR: Free Texture Memory: %i\n", pvr_texture_memory_free());

	printf("PVR: Free() Space for 128*128 texture...\n");

	if(tex != NULL)
	    pvr_free(tex, 128*128*2);

	printf("PVR: Free Texture Memory: %i\n", pvr_texture_memory_free());
Another thing I was going to mention, it is not necessary to use a texture ( and should be avoided for many reasons ), if you are using a solid color.
Using gouraud shading, you can submit colors per-vertex to the PVR, so it would be better to submit a quad, or a 'sprite', un-textured, with each vertex being the desired color.

Good luck friend!
User avatar
Newbie
Insane DCEmu
Insane DCEmu
Posts: 171
Joined: Sat Jul 27, 2013 1:16 pm
Has thanked: 0
Been thanked: 0

Re: About pvr_mem_available() , pvr_mem_stats() a bug ?

Post by Newbie »

First thing, thanks a lot to have a look at my question. You are a very gentle person.

Second thing, i follow up all the threads you talking about.

Your 3D work is impressive, especially the one with light maps !

For our memory investigation :

I followed what you wrote. I saw the line in pvr_internal.h introducing the pvr_state_t structure.

Code: Select all


uint32	texture_base;	// Start of texture RAM

The field texture_base is the starting texture PVR memory address location.
This is why the value of this field never change, even after loading a bunch of textures.
It 's certainly populated in init function depending the init parameters.

FIRST TEST

Code: Select all


void TestTextureLoading()
{	
	printf("AVAILABLE MEMORY IN PVR AT START IN BYTES IS     :  %"PRIu32" \n", PVRMemoryAvailableAtStart());
		
	printf("LOADING IN PVR A 64 *64 SQUARED 565 BLUE TEXTURE\n");
	Texture blue = GetBlueTexture();
	
	printf("AVAILABLE MEMORY IN PVR IN BYTES IS              :  %"PRIu32" \n", PVRFreeMemoryAvailable());
	printf("USED MEMORY IN PVR IN BYTES IS                   :  %"PRIu32" \n", PVR_TEX_BYTES_ALLOCATED);
	
	printf("LOADING IN PVR A 64 *64 SQUARED 565 BLACK TEXTURE\n");
	Texture black = GetBlackTexture();
	
	printf("AVAILABLE MEMORY IN PVR IN BYTES IS              :  %"PRIu32" \n", PVRFreeMemoryAvailable());
	printf("USED MEMORY IN PVR IN BYTES IS                   :  %"PRIu32" \n", PVR_TEX_BYTES_ALLOCATED);
	
	printf("LOADING IN PVR A 64 *64 SQUARED 565 RED TEXTURE\n");
	Texture red = GetRedTexture();
	
	printf("AVAILABLE MEMORY IN PVR IN BYTES IS              :  %"PRIu32" \n", PVRFreeMemoryAvailable());
	printf("USED MEMORY IN PVR IN BYTES IS                   :  %"PRIu32" \n", PVR_TEX_BYTES_ALLOCATED);
	
	printf("LOADING IN PVR A 64 *64 SQUARED 565 RED TEXTURE\n");
	Texture red2 = GetRedTexture();
	
	printf("AVAILABLE MEMORY IN PVR IN BYTES IS              :  %"PRIu32" \n", PVRFreeMemoryAvailable());
	printf("USED MEMORY IN PVR IN BYTES IS                   :  %"PRIu32" \n", PVR_TEX_BYTES_ALLOCATED);
}

AVAILABLE MEMORY IN PVR AT START IN BYTES IS : 4626688
LOADING IN PVR A 64 *64 SQUARED 565 BLUE TEXTURE
AVAILABLE MEMORY IN PVR IN BYTES IS : 4618496
USED MEMORY IN PVR IN BYTES IS : 8192
LOADING IN PVR A 64 *64 SQUARED 565 BLACK TEXTURE
AVAILABLE MEMORY IN PVR IN BYTES IS : 4610304
USED MEMORY IN PVR IN BYTES IS : 16384
LOADING IN PVR A 64 *64 SQUARED 565 RED TEXTURE
AVAILABLE MEMORY IN PVR IN BYTES IS : 4602112
USED MEMORY IN PVR IN BYTES IS : 24576
LOADING IN PVR A 64 *64 SQUARED 565 RED TEXTURE
AVAILABLE MEMORY IN PVR IN BYTES IS : 4593920
USED MEMORY IN PVR IN BYTES IS : 32768
I just made the same code you provided to see effectively the "magic number" appears 4626688.
It means that after the default init (16*16 tiles size + Vertex Buffer of size 512 * 1024 byte), it remains in PVR 4626688 bytes for texture according to KOS

formula's : 0x800000 - pvr_state.texture_base.

It's rather strange for me because 4626688 represents 4518,25 KB or 4,412353515625 MB : it's not a round number ...


According to what you said we have :

PVR Vertex Buffer = 512 * 1024 = 524288
+
PVR Frame Buffer = 3237632
+
PVR Texture Data = 4626688

= Total PVR Memory = 1024*1024*8 = 8388608

So Frame buffer is 3,087646484375 MB wide.
We can image its' a a melting, something like N * 640 * 320 * 2 bytes (N * 614400 bytes) :
in this case N is more than 5.

As the free memory, used memory values are calculated by ourselves refering to what KOS say, the code works as expected.

SECOND TEST

I start a loop to load all the textures i can to fill up the 4626688 bytes magic number.
Purpose is simple, verify that this space is really to be filled as the lenght expected.

I used as one month ago the same 64*64 RGB565 texture wich means 8192 bytes to be used each load time.

So we expect 4626688 / 8192 = 564 textures to be loaded !

A simple for loop is used.

Code: Select all


void TestMassTextureLoading(int round)
{	
	printf("AVAILABLE MEMORY IN PVR AT START IN BYTES IS     :  %"PRIu32" \n", PVRMemoryAvailableAtStart());
	
	int index;

	for(index = 0; index < round; ++index)
	{
		printf("PASS %d\n", index);
		
		GetBlueTexture();
		
		printf("AVAILABLE MEMORY IN PVR IN BYTES IS          :  %"PRIu32" \n", PVRFreeMemoryAvailable());
		printf("USED MEMORY IN PVR IN BYTES IS               :  %"PRIu32" \n", PVR_TEX_BYTES_ALLOCATED);		
	}
}

AVAILABLE MEMORY IN PVR AT START IN BYTES IS : 4626688
PASS 0
AVAILABLE MEMORY IN PVR IN BYTES IS : 4618496
USED MEMORY IN PVR IN BYTES IS : 8192
....

PASS 561
AVAILABLE MEMORY IN PVR IN BYTES IS : 22784
USED MEMORY IN PVR IN BYTES IS : 4603904
PASS 562
pvr_mem: ERROR -- out of PVR memory; texture heap probably corrupted
But it does not work ... PASS 562 IE 563th texture allocation fails ....

So we can only allocate 562 * 8192 = 4603904.

There is something using 4626688 - 4603904 = 22784 bytes for 562 allocations.

Some 40 bytes each allocation ...perhaps for internal reason ?

So we do not have the whole 4626688 / 4518,25 KB / 4,412353515625 MB for textures.

THIRD TEST

I have make it for default, but for non default inits ?
There is a function to do so :

Code: Select all


int pvr_init (pvr_init_params_t *  params) 	

I use these struct to init :

Code: Select all

pvr_init_params_t params = 
 {
  /* Enable opaque and translucent polygons with size 16 */
   { PVR_BINSIZE_16, PVR_BINSIZE_0, PVR_BINSIZE_16, PVR_BINSIZE_0, PVR_BINSIZE_0 },

  /* Vertex buffer size 1024K */
    1024* 1024,

  /* No DMA */
        0,

  /* No FSAA */
        0    
 };

AVAILABLE MEMORY IN PVR AT START IN BYTES IS : 3578112
LOADING IN PVR A 64 *64 SQUARED 565 BLUE TEXTURE
AVAILABLE MEMORY IN PVR IN BYTES IS : 3569920
USED MEMORY IN PVR IN BYTES IS : 8192
LOADING IN PVR A 64 *64 SQUARED 565 BLACK TEXTURE
AVAILABLE MEMORY IN PVR IN BYTES IS : 3561728
USED MEMORY IN PVR IN BYTES IS : 16384
LOADING IN PVR A 64 *64 SQUARED 565 RED TEXTURE
AVAILABLE MEMORY IN PVR IN BYTES IS : 3553536
USED MEMORY IN PVR IN BYTES IS : 24576
LOADING IN PVR A 64 *64 SQUARED 565 RED TEXTURE
AVAILABLE MEMORY IN PVR IN BYTES IS : 3545344
USED MEMORY IN PVR IN BYTES IS : 32768
The magic number is now 3578112 bytes for a vertex buffer enhanced by 512KB.

But, 3578112 (custom mode) + 524288 (512 * 1024) = 4102400 wich is not 4626688 (of default mode)


So the function reports less texture ram size because we have enhanced vertex buffer but there is something more consumming ram ....
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5658
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has thanked: 9 times
Been thanked: 69 times
Contact:

Re: About pvr_mem_available() , pvr_mem_stats() a bug ?

Post by BlueCrab »

There are more buffers than just the vertex buffer and the frame buffer in the PVR's memory. Look at the function pvr_allocate_buffers() in kernel/arch/dreamcast/hardware/pvr/pvr_buffers.c to see what kinds of things need to be allocated for the PVR to do its thing.
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5658
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has thanked: 9 times
Been thanked: 69 times
Contact:

Re: About pvr_mem_available() , pvr_mem_stats() a bug ?

Post by BlueCrab »

I know it has been a while, but I actually did fix this today... I apologize that it took this long, but I kinda completely forgot about it. :oops:
User avatar
Newbie
Insane DCEmu
Insane DCEmu
Posts: 171
Joined: Sat Jul 27, 2013 1:16 pm
Has thanked: 0
Been thanked: 0

Re: About pvr_mem_available() , pvr_mem_stats() a bug ?

Post by Newbie »

Thanks a lot !
I will next week download fixed KOS version, compile it and test it with my "test code routine".
Post Reply