![]() |
|
performance issues with al_draw_prim |
Mark Oates
Member #1,146
March 2001
![]() |
My 3D engine relies on using al_draw_indexed_prim to draw the 3D models in my scene, but I have found that there is a severe performance bottleneck with this method. While my actual production code is immensely more complex, this simple example should demonstrate how I typically (and probably not ideally) use the pipeline: In this example, I am drawing 10,000 "Models". Each model is just a 3-vertex triangle and is drawn through al_draw_indexed_prim. (You'll have to hard crash the running program yourself) 1
2
3#include <allegro5/allegro.h>
4#include <allegro5/allegro_primitives.h>
5
6#include <vector>
7
8
9
10float random_float(float min, float max)
11{
12 return ((float) rand()/RAND_MAX)*(max-min) + min;
13}
14
15
16// note: uncomment the commented lines of
17// code in this class to include the random
18// placement of objects (through ALLEGRO_TRANSFORM).
19
20class Model
21{
22public:
23 ALLEGRO_VERTEX vertex[3];
24 //ALLEGRO_TRANSFORM placement;
25 Model()
26 {
27 vertex[0].x = 0;
28 vertex[0].y = 0;
29 vertex[0].z = 0;
30 vertex[0].color = al_map_rgb(255, 255, 128);
31
32 vertex[1].x = 100;
33 vertex[1].y = 100;
34 vertex[1].z = 0;
35 vertex[1].color = al_map_rgb(128, 255, 255);
36
37 vertex[2].x = 100;
38 vertex[2].y = 0;
39 vertex[2].z = 0;
40 vertex[2].color = al_map_rgb(255, 128, 255);
41
42 //al_identity_transform(&placement);
43 //al_scale_transform(&placement, random_float(0.2, 1.5), random_float(0.2, 1.5));
44 //al_rotate_transform(&placement, random_float(0, 1));
45 //al_translate_transform(&placement, random_float(0, 800), random_float(0, 500));
46 }
47 void draw()
48 {
49 int indices[] = { 0, 1, 2 };
50
51 //ALLEGRO_STATE previous_state;
52 //al_store_state(&previous_state, ALLEGRO_STATE_TRANSFORM);
53
54 //al_use_transform(&placement);
55 al_draw_indexed_prim(&vertex[0], NULL, NULL, indices, 3, ALLEGRO_PRIM_TRIANGLE_LIST);
56
57 //al_restore_state(&previous_state);
58 }
59};
60
61
62
63
64int main(int argc, char *argv[])
65{
66 al_init();
67 al_init_primitives_addon();
68 srand(time(NULL));
69
70 ALLEGRO_DISPLAY *disp = al_create_display(800, 500);
71
72 bool done = false;
73 bool strobe = false;
74
75 // create the models
76
77 std::vector<Model> models;
78 for (unsigned i=0; i<10000; i++) // in this example, draw 10000 triangles
79 {
80 Model model;
81 models.push_back(model);
82 }
83
84 // do the loop
85
86 while(!done)
87 {
88 al_clear_to_color(al_map_rgb(0, 64, 0));
89
90 for (unsigned i=0; i<models.size(); i++)
91 models[i].draw();
92
93 // a strobing circle, will alternate on/off between frames
94 // to demonstrate drawing speed
95 if (strobe) al_draw_filled_circle(20, 20, 8, al_map_rgb(255,255,255));
96 strobe = !strobe;
97
98 al_flip_display();
99 }
100}
In my real code, each model is more complex, is projected in 3D, and has textures. Now, in the example program above, I am drawing 10,000 models with 3 vertexes each, so, 30,000 vertexes each loop. It's my understanding that a cheap modern graphics card can push ~500 million vertexes in a second, so what gives? Why is there already such a substantial lag at 30,000 vertexes? What should I be doing instead? Here are some pretty screenshots: |
Arthur Kalliokoski
Second in Command
February 2005
![]() |
I didn't have to do anything to crash it. Program received signal SIGSEGV, Segmentation fault. 0x000000004009fee7 in ?? () (gdb) bt #0 0x000000004009fee7 in ?? () #1 0x00007ffff256f53b in ?? () from /usr/lib64/libnvidia-glcore.so.331.20 #2 0x00007ffff25731ef in ?? () from /usr/lib64/libnvidia-glcore.so.331.20 #3 0x00007ffff21c2012 in ?? () from /usr/lib64/libnvidia-glcore.so.331.20 #4 0x00007ffff78c0cfa in _al_draw_prim_indexed_opengl () from /usr/local/lib64/liballegro_primitives.so.5.1 #5 0x00007ffff78c3a63 in al_draw_indexed_prim () from /usr/local/lib64/liballegro_primitives.so.5.1 #6 0x0000000000401265 in Model::draw (this=0x7fffefb48010) at t.cpp:53 #7 0x0000000000401010 in main (argc=1, argv=0x7fffffffe0c8) at t.cpp:89 (gdb) [EDIT] Well if I use the allegro debug libs I get this instead. t: /home/prog/allegro-5.1.8/addons/primitives/primitives.c:109: al_draw_indexed_prim: Assertion `indices' failed. [EDIT 2] If I put in a line int indices[] = { 0, 1, 2 }; and change line 53 to al_draw_indexed_prim(&vertex[0], NULL, NULL, indices, 3, ALLEGRO_PRIM_TRIANGLE_LIST); it doesn't crash but only shows one triangle with a round thingee. They all watch too much MSNBC... they get ideas. |
Mark Oates
Member #1,146
March 2001
![]() |
Oh so weird, how did I miss that... and how did my program not crash as a result??? OK, I'll edit my first post. |
Trent Gamblin
Member #261
April 2000
![]() |
You should be using VBOs or something, you'll never get anywhere near 500 mil verts without batching them and keeping them on the GPU. It's kind of like al_hold_bitmap_drawing only worse.
|
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
Arthur Kalliokoski said: it doesn't crash but only shows one triangle with a round thingee. You have to uncomment the transform lines with the random_float calls My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
SiegeLord
Member #7,827
October 2006
![]() |
Each al_draw_prim call has some overhead, so if you want to get better performance, you want to minimize the number of those calls. Additionally, as Trent said, if you use vertex buffers, then things will go even faster. There's a vertex buffer API in the primitives addon. There's basically no reason not to use it (even for dynamically updated data, vertex buffers tend to be faster than al_draw_prim). "For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18 |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
I can only use a vertex buffer in OpenGL mode on Vista. Doesn't matter how I create it in D3D it returns 0. And even in OpenGL mode performance isn't much better than al_draw_prim, batched or not. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
SiegeLord
Member #7,827
October 2006
![]() |
That's interesting. Do you have a reasonably modern GPU? But either way, it's good that it's not worse in OpenGL otherwise I'd have to eat my earlier post "For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18 |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
It's a crappy integrated ATI Radeon X1270 on my Gateway Vista laptop. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Mark Oates
Member #1,146
March 2001
![]() |
this is ex_vertex_buffer.c on my computer. As is (Direct3D): with al_set_new_display_flags(ALLEGRO_OPENGL); ... don't know what these numbers represent, but there they are. |
SiegeLord
Member #7,827
October 2006
![]() |
Wow, a second person non-functioning D3D vertex buffers. Is your GPU pretty bad too? Either way, those numbers are frames per second (FPS Incidentally, Mark Oates said: al_set_new_display_flags(ALLEGRO_OPENGL); I prefer to use allegro5.cfg to switch backends for the examples. "For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18 |
Mark Oates
Member #1,146
March 2001
![]() |
That one was a Intel HD Graphics 4000, it's the onboard graphics card on my laptop. It's not a bad chip. I also have an external doc with a "much more powerful" AMD Radeon HD 7670M, but looking at the numbers I don't see much of a change: D3D: with OpenGL: |
SiegeLord
Member #7,827
October 2006
![]() |
I've added some more logging to the D3D side of things in the primitives addon. Could either of you get the latest 5.1 branch, compile in Debug mode and check out the allegro.log? "For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18 |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
SiegeLord said: I prefer to use allegro5.cfg to switch backends for the examples. Is allegro5.cfg documented anywhere? What the various options are, what the syntax is, so on... SiegeLord said: I've added some more logging to the D3D side of things in the primitives addon. Could either of you get the latest 5.1 branch, compile in Debug mode and check out the allegro.log? Here's my allegro.log file. (What I think) the relevant parts are : d3d_primitives W C:\mingw\LIBS\A5GIT\allegro\addons\primitives\prim_directx.cpp:60 is_legacy_card [ 0.27891] Your GPU is considered legacy! Some of the features of the primitives addon will be slower/disabled. d3d_primitives W C:\mingw\LIBS\A5GIT\allegro\addons\primitives\prim_directx.cpp:1022 _al_create_vertex_buffer_directx [ 0.27896] Cannot create vertex buffer for a legacy card. d3d_primitives W C:\mingw\LIBS\A5GIT\allegro\addons\primitives\prim_directx.cpp:1022 _al_create_vertex_buffer_directx [ 0.27898] Cannot create vertex buffer for a legacy card. d3d_primitives W C:\mingw\LIBS\A5GIT\allegro\addons\primitives\prim_directx.cpp:1022 _al_create_vertex_buffer_directx [ 0.27900] Cannot create vertex buffer for a legacy card. d3d_primitives W C:\mingw\LIBS\A5GIT\allegro\addons\primitives\prim_directx.cpp:1022 _al_create_vertex_buffer_directx [ 0.27902] Cannot create vertex buffer for a legacy card. d3d_primitives W C:\mingw\LIBS\A5GIT\allegro\addons\primitives\prim_directx.cpp:1022 _al_create_vertex_buffer_directx [ 0.27903] Cannot create vertex buffer for a legacy card. d3d_primitives W C:\mingw\LIBS\A5GIT\allegro\addons\primitives\prim_directx.cpp:1022 _al_create_vertex_buffer_directx [ 0.27905] Cannot create vertex buffer for a legacy card. d3d_primitives W C:\mingw\LIBS\A5GIT\allegro\addons\primitives\prim_directx.cpp:1069 _al_create_index_buffer_directx [ 0.28117] Cannot create index buffer for a legacy card.
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Trent Gamblin
Member #261
April 2000
![]() |
I've had the legacy card check go wrong on me before with shaders. If you return false from that function does it work?
|
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
To check, I ran it on my desktop with an ATI Radeon 4600 series gfx card, and it created the vertex buffers in dynamic and non-dynamic mode. I get about 1100 frames with a buffer dynamically and about 2300 statically. (I get about 1300 frames dynamically with no buffer, which seems backwards). However, allegro.log says my card is still legacy, which it shouldn't be. It's a fairly decent gpu from about 5 years ago. The allegro log file is attached again. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
SiegeLord
Member #7,827
October 2006
![]() |
Edgar Reynaldo said: Is allegro5.cfg documented anywhere? What the various options are, what the syntax is, so on... There's a prototypical copy inside the root directory of the source distributions. Here it is online: https://github.com/liballeg/allegro5/blob/5.1/allegro5.cfg . I'm adding documentation about this next to al_get_system_config, but I think we can do something better with this... perhaps generate it automatically somehow. "For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18 |
|