VAR - Abnormal program termination

Last night I was playing around with VAR and at one point I was getting an “Abnormal program termination”. After hunting around I found it occurred when I called glVertexArrayRangeNV() but didn’t actually use the memory (ie. I was testing that my Memory handler was working OK without drawing my primitives from the VAR memory).

Is this normal?

The error occurred when ever I tried to use glDrawElements with the Vertex/TexCoord/Normal arrays not in the VAR range. So, for example, if I moved a single mesh into VAR and tried to draw my scene, it would bomb, if I didn’t move any into VAR and didn’t call glVertexArrayRangeNV() it’d work fine.

If I want to do something like this (not saying that I would but for testing sake) should I enable/disable VAR before and after the specific meshes are drawn? (At present I alloc AGP mem, enable VAR then call glVARNV() at the beginning of the app)

Another thing I noticed, when I got VAR working, was that there wasn’t any increase in speed at all. I am doing the following…

  1. Alloc Mem (single large chunk)
  2. Enable VAR/glVARNV
  3. Move all Verts/Normals/TexCoords to VAR
    (Each mesh has it’s own section of the large VAR block)
  4. Draw the scene using glDrawElements()
  5. glFlush()/wglSwapBuffers()
  6. Repeat 4 & 5

I have also inserted a FlushVAR() at step 5 with no change in the frame rate. Am I doing something wrong? I only have a couple of thousand verts so do I not have enough to actually see an increase in performance? Should I use fences? (How?)

Thanks All.

SS.

If VAR is enabled, your vertices must be in the VAR.

  • Matt

Surely not while compiling a display list, or emitting immediate mode vertices, right?

A couple of thousand vertices isn’t very many, you’re likely to be fill rate or CPU limited.

Have a look at the VAR demo on the NVIDIA site, their example uses fences.

Originally posted by mcraighead:
If VAR is enabled, your vertices must be in the VAR.

This makes sense. Wouldn’t there be a better way of handling the misuse of this than an “Abnormal program termination”?

Originally posted by Adrian:
A couple of thousand vertices isn’t very many, you’re likely to be fill rate or CPU limited.

Definitely not CPU. I recently upgraded from a PIII 733 to a 2400+ XP with no increase in frame rate. I also went from 2x AGP to 4x AGP so I guess it must be fill rate limited (irrespective of whether I use VAR or not the change in AGP rates should point that out - I think).

The number of vert’s will increase now that I’ve nailed down the VAR pathway etc. (Maybe then I’ll revisit the need for fences)

Have a look at the VAR demo on the NVIDIA site, their example uses fences.

I have looked at that before and I’ll have to do it again because I read the VAR doc from the GL SDK last night and it still didn’t seem clear to me when & why you use fences.

It appears to be when you need to reuse VAR memory? What if I, say, allocate a meg of AGP and can store all my verts in that Meg? Then presumably I don’t need fences…

For vertex array calls, yes, they must. Immediate mode, no. Vertex array into a display list, the spec would imply yes.

The driver can’t efficiently check this condition, and program termination is an acceptable way to handle this error, so we do in fact kill the app.

  • Matt

Kill the app? In what version driver? We currently rely on the feature of display list compilation out of system RAM being OK (and, in fact, faster than turning off the VAR). It seems like very useful behavior, and works fine up to and including version 41 drivers.

You can disable the VAR without flushing, so there’s no excuse for leaving it turned on when you are playing your vertex arrays into a display list, if those vertices are in the VAR.

But why in the world would you play vertex arrays inside a VAR into a display list??? You’d have to read from uncached memory, and it would be horribly slow. For that matter, there is no good reason to play vertex arrays, rather than immediate mode, into a display list.

  • Matt

Originally posted by jwatte:
Kill the app? In what version driver?

40.72 - Win2k Sp3

What sort of frame rates and triangle rates are you getting, what card do you have?

glFlushVertexArrayRangeNV blocks until all vertices have been processed.

glFinishFenceNV blocks until the vertices sent to the gpu, at the point the corresponding glSetFenceNV was called, have been processed.

If you only need to call glFlushVertexArrayRangeNV before you swap buffers then I can’t see that fences will benefit you. It sounds from your description that you don’t need fences.

I think fences are useful when you are using the same VAR memory for different geometry. Without fences you would need to call FlushVAR before you updated the vertex data each time. By breaking the VAR memory up into a number of buffers and using Fences you could minimise the amount of blocking.

This document has some more information on fences http://developer.nvidia.com/docs/IO/1295/ATT/GDC01_Performance.pdf

[This message has been edited by Adrian (edited 02-13-2003).]

Originally posted by Adrian:
What sort of frame rates and triangle rates are you getting, what card do you have?

I’m getting around 300fps on my system with a gf3 Ti200 (around 150 if I enable shadow volumes). Not sure of actual triangle rates, I’ll have to measure it (I tend to focus on raw fps). On a geforce 256 (with an AMD 1.33) Im getting around 30fps with shadows.

These rates aren’t too unreasonable but if I can squeeze anymore out I will. Perhaps when I increase the number of verts etc. I will see some benefit from VAR. I have given myself the option to turn it on/off through a cfg file so I’ll be able to check.

Thanks for your description of fences, I now understand how they work (They stop you from clobbering VAR memory that is still being used by the GPU). My initial thought was that they did the opposite, that they told the GPU to go off and start drawing (DER - that’s why they’re called fences!).

When testing the difference VAR makes you could reduce your screen res to 640x480 and turn off any FSAA to minimise the fill rate. Like you say increasing the number of vertices should make any performance difference show up better.

We establish and enable the vertex array range at program start-up, and don’t really turn it off after that (except for screen mode changes and stuff).

However, as some machines are low on VAR memory (empirically determined), we only use VAR for dynamic or pseudo-dynamic geometry. Static models (like, say, a palm tree) will get compiled into a display list the first time it’s drawn. The code looks something like (very pseudo-code):

drawGeometry:
if( hasDisplayList )
glCallList
return
if( isDynamic )
if( !alreadyIsInVAR )
copyIntoVAR
else
glBeginList
glVertexPointer
glDrawRangeElements
if( !isDynamic )
glEndList
delete systemRAMCopy
glCallList

There are some more gnarls (like “copyIntoAGP” applying software skinning :slight_smile: but that’s the general structure. While we could add enables/disables in the case VAR2 is supported, less code change means less QA time means more time for otherpieces of the application.