Texture Benchmark : pvrmark_texture

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
patbier
DC Developer
DC Developer
Posts: 152
https://www.artistsworkshop.eu/meble-kuchenne-na-wymiar-warszawa-gdzie-zamowic/
Joined: Fri Aug 29, 2003 1:25 am
Has thanked: 0
Been thanked: 0

Texture Benchmark : pvrmark_texture

Post by patbier »

Hello,

In the kos/examples, there are pvrmark benchmarks for strips and strips direct.
I'd like to add a benchmark for textures, so I try to modify the benchmark for strips.
I doesn't work as great as expected, I don't think it really calculates the more textures possible displayable at 60 fps.

Code: Select all

/* KallistiOS ##version##

   pvrmark_texture.c
   (c)2002 Dan Potter
   Patbier - Modified for texture
*/

#include <kos.h>
#include <stdlib.h>
#include <time.h>
#include <kmg/kmg.h>

enum { PHASE_HALVE, PHASE_INCR, PHASE_DECR, PHASE_FINAL };

int textcnt;
pvr_ptr_t apple_tex;
int phase = PHASE_HALVE;
float avgfps = -1;
pvr_poly_cxt_t cxt;
pvr_poly_hdr_t hdr;
pvr_vertex_t vert;

void running_stats() {
    pvr_stats_t stats;
    pvr_get_stats(&stats);

    if(avgfps == -1)
        avgfps = stats.frame_rate;
    else
        avgfps = (avgfps + stats.frame_rate) / 2.0f;
}

void stats() {
    pvr_stats_t stats;

    pvr_get_stats(&stats);
    dbglog(DBG_DEBUG, "3D Stats: %d frames, frame rate ~%f fps\n",
           stats.vbl_count, stats.frame_rate);
}


void apple_init() {
  	kos_img_t img;
	apple_tex = pvr_mem_malloc(128 * 128 * 2);
	kmg_to_img("/rd/apple_128_4444.kmg", &img);
	pvr_txr_load_kimg(&img, apple_tex, 0);
	kos_img_free(&img, 0);	
}

/* draw apple */
void draw_apple(int x,int y,int z,int col) {
    pvr_prim(&hdr, sizeof(hdr));

    vert.argb = col | (col << 8) | (col << 16) | 0xff000000;
    vert.oargb = 0;
    vert.flags = PVR_CMD_VERTEX;

    vert.x = x;
    vert.y = y;
    vert.z = z;
    vert.u = 0.0;
    vert.v = 0.0;
    pvr_prim(&vert, sizeof(vert));

    vert.x = x+128;
    vert.y = y;
    vert.z = z;
    vert.u = 1.0;
    vert.v = 0.0;
    pvr_prim(&vert, sizeof(vert));

    vert.x = x;
    vert.y = y+128;
    vert.z = z;
    vert.u = 0.0;
    vert.v = 1.0;
    pvr_prim(&vert, sizeof(vert));

    vert.x = x+128;
    vert.y = y+128;
    vert.z = z;
    vert.u = 1.0;
    vert.v = 1.0;
    vert.flags = PVR_CMD_VERTEX_EOL;
    pvr_prim(&vert, sizeof(vert));
}
int oldseed = 0xdeadbeef;
/* draw one frame */
void draw_frame(void) {
    int x, y, z;
    int size;
    int i, col;
	
    vid_border_color(0, 0, 0);	
    pvr_wait_ready();
    vid_border_color(255, 0, 0);	
    pvr_scene_begin();

    pvr_list_begin(PVR_LIST_OP_POLY);
    pvr_list_finish();

    pvr_list_begin(PVR_LIST_TR_POLY);

    pvr_poly_cxt_txr(&cxt, PVR_LIST_TR_POLY, PVR_TXRFMT_ARGB4444, 256, 256, apple_tex, PVR_FILTER_BILINEAR);
    pvr_poly_compile(&hdr, &cxt);
    for(i = 0; i < textcnt; i++) {
		x = rand() % 540;
		y = rand() % 380;
		z = rand() % 100 + 1;
        col = rand() % 256;		
		draw_apple(x,y,z,col);
	}
    pvr_list_finish();
    pvr_scene_finish();
    vid_border_color(0, 255, 0);	
}

time_t start;
void switch_tests(int ppf) {
    printf("Beginning new test: %d textures per frame (%d per second at 60fps)\n",
           ppf, ppf * 60);
    avgfps = -1;
    textcnt = ppf;
}

void check_switch() {
    time_t now;

    now = time(NULL);

    if(now >= (start + 5)) {
        start = time(NULL);
        printf("  Average Frame Rate: ~%f fps (%d text => %d pps)\n", avgfps, (int)(textcnt * avgfps), (int)(textcnt * 4 * avgfps));

        switch(phase) {
            case PHASE_HALVE:

                if(avgfps < 55) {
                    switch_tests(textcnt / 2);
                }
                else {
                    printf("  Entering PHASE_INCR\n");
                    phase = PHASE_INCR;
                }

                break;
            case PHASE_INCR:

                if(avgfps >= 55) {
                    switch_tests(textcnt + 10);
                }
                else {
                    printf("  Entering PHASE_DECR\n");
                    phase = PHASE_DECR;
                }

                break;
            case PHASE_DECR:

                if(avgfps < 55) {
                    switch_tests(textcnt - 10);
                }
                else {
                    printf("  Entering PHASE_FINAL\n");
                    phase = PHASE_FINAL;
                }

                break;
            case PHASE_FINAL:
                break;
        }
    }
}

/* romdisk */
extern uint8 romdisk_boot[];
KOS_INIT_ROMDISK(romdisk_boot);

int main(void) {
	int done = 0;
    /* init kos  */
    pvr_init_defaults();

    apple_init();
    /* Start off with something obscene */
    switch_tests(6000 / 60);
    start = time(NULL);	
    /* keep drawing frames until start is pressed */
    while(!done) {
        MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)

        if(st->buttons & CONT_START)
            done = 1;

        MAPLE_FOREACH_END()
        printf(" \r");
        draw_frame();
        running_stats();
        check_switch();		
    }
    stats();
	pvr_mem_free(apple_tex);	
    return 0;
}

I attach the complete files (pvrmark_texture.c, makefile and romdisk_boot)
Attachments
pvrmark_texture.zip
(8.42 KiB) Downloaded 62 times
ImageAlice Dreams Tournament Dreamcast fans : http://www.facebook.com/alicedreamst
In August 2015, we had to change "Dynamite Dreams" name to "Alice Dreams Tournament"
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: Texture Benchmark : pvrmark_texture

Post by BlueCrab »

Well, doing everything in the translucent list cuts down on the number of polygons you're going to be able to display by quite a bit (probably by half or more). Have you tried with an opaque polygon instead?

Also, you probably want filtering turned off for any "benchmark" program. Texture filtering isn't free, even if the texture is already twiddled (and is quite expensive if the texture is not twiddled).
patbier
DC Developer
DC Developer
Posts: 152
Joined: Fri Aug 29, 2003 1:25 am
Has thanked: 0
Been thanked: 0

Re: Texture Benchmark : pvrmark_texture

Post by patbier »

Yes, you're right ! And I will modify the code to select OP/TR and with/without filtering to see the differences.
But, I'm not sure if the stats.frame_rate from pvr_get_stats(&stats) is accurate.
ImageAlice Dreams Tournament Dreamcast fans : http://www.facebook.com/alicedreamst
In August 2015, we had to change "Dynamite Dreams" name to "Alice Dreams Tournament"
User avatar
bogglez
Moderator
Moderator
Posts: 578
Joined: Sun Apr 20, 2014 9:45 am
Has thanked: 0
Been thanked: 0

Re: Texture Benchmark : pvrmark_texture

Post by bogglez »

1) Your polygons may overlap. I think this will make performance seem better than it actually is, since the TA will first gather all polygons and avoid filling out all the polygons, unlike a forward rasterizer.
2) No need to recompile hdr all the time. Compile it during initialization and reuse it in the loop.
3) No need for pvr_list_finish(), it will be called implicitly.
Wiki & tutorials: http://dcemulation.org/?title=Development
Wiki feedback: viewtopic.php?f=29&t=103940
My libgl playground (not for production): https://bitbucket.org/bogglez/libgl15
My lxdream fork (with small fixes): https://bitbucket.org/bogglez/lxdream
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: Texture Benchmark : pvrmark_texture

Post by BlueCrab »

bogglez wrote:1) Your polygons may overlap. I think this will make performance seem better than it actually is, since the TA will first gather all polygons and avoid filling out all the polygons, unlike a forward rasterizer.
2) No need to recompile hdr all the time. Compile it during initialization and reuse it in the loop.
3) No need for pvr_list_finish(), it will be called implicitly.
patbier has simply taken an existing example and added texturing to it. All of the stuff you've said here is also in the example programs. :wink:

As for #3, I doubt it'll have any real measurable impact on framerate. We're more worried about the fill rate of the hardware here, rather than the CPU bounds. #2 might have an impact, but with the number of polygons the program should push, I have a feeling it's a similar situation to #3. As for #1, the normal situation in any case is that many polygons overlap. There's no way to put up reasonable polygons that aren't going to overlap at all, especially with the number of polygons that are being pushed in this example.
patbier wrote:Yes, you're right ! And I will modify the code to select OP/TR and with/without filtering to see the differences.
But, I'm not sure if the stats.frame_rate from pvr_get_stats(&stats) is accurate.
What are you getting that makes you think it is inaccurate, if you don't mind me asking?
User avatar
bogglez
Moderator
Moderator
Posts: 578
Joined: Sun Apr 20, 2014 9:45 am
Has thanked: 0
Been thanked: 0

Re: Texture Benchmark : pvrmark_texture

Post by bogglez »

BlueCrab wrote:
bogglez wrote:1) Your polygons may overlap. I think this will make performance seem better than it actually is, since the TA will first gather all polygons and avoid filling out all the polygons, unlike a forward rasterizer.
2) No need to recompile hdr all the time. Compile it during initialization and reuse it in the loop.
3) No need for pvr_list_finish(), it will be called implicitly.
patbier has simply taken an existing example and added texturing to it. All of the stuff you've said here is also in the example programs. :wink:

As for #3, I doubt it'll have any real measurable impact on framerate. We're more worried about the fill rate of the hardware here, rather than the CPU bounds. #2 might have an impact, but with the number of polygons the program should push, I have a feeling it's a similar situation to #3.
Just pointing out unnecessary code, no biggie.
BlueCrab wrote: As for #1, the normal situation in any case is that many polygons overlap. There's no way to put up reasonable polygons that aren't going to overlap at all, especially with the number of polygons that are being pushed in this example.
You will have much more overlap in this benchmark because it is entirely random and the rectangles are large.
In a real scene this would mean that
A) you perform extremely poor visibility detection
B) polygons would be really close to the near plane, since they are very large in this benchmark (dimensions of 128). Many of the overlapping polygons would actually be much smaller since they're further away.

Another flaw is that you could artificially increase the fillrate to infinity (or until you reach another bottleneck) by just drawing polygons that are behind other polygons.

BTW I don't think the randomness is usefull for a fillrate test to begin with. Just draw a fullscreen rectangle and fill the whole screen.
And again, since this is a raycaster, drawing multiple fullscreen rectangles would not actually test the fillrate any further, which makes the whole test flawed, in my opinion.
Wiki & tutorials: http://dcemulation.org/?title=Development
Wiki feedback: viewtopic.php?f=29&t=103940
My libgl playground (not for production): https://bitbucket.org/bogglez/libgl15
My lxdream fork (with small fixes): https://bitbucket.org/bogglez/lxdream
Post Reply