Directx limits?

Blitz3D Forums/Blitz3D Beginners Area/Directx limits?

mindstorms(Posted 2007) [#1]
I thought that there was a universal limit to how many triangles you could stuff into a single surface before getting a memory access violation. I have tried different things, and have gotten different caps for each amount of triangles that I add per frame.

+50 tris per frame caps out at 15700 triangles
+100 tris per frame caps out at 20900 triangles
+20 tris per frame caps out at 21280 triangles
+1000 tris per frame caps out at 17000 triangles

It is interesting that if one runs the program with any of these triangle counts, the crash will come at the same point, but changing the amount of triangles created seems to make directx complain at different points.

Is there a way to tell exactly how many triangles directx will complain about?


GfK(Posted 2007) [#2]
I think the limit is vertices rather than triangles.


mindstorms(Posted 2007) [#3]
Well, it still does not explain why it changes...All a triangle is is three vertecies, so you can multiply all the values above by three to get the vertex info...


b32(Posted 2007) [#4]
Maybe it has to do with the amount of triangles that are rendered ?


mindstorms(Posted 2007) [#5]
The big numbers are the result of TrisRendered() after the memory violation...How could I get more accurate data than that?


mindstorms(Posted 2007) [#6]
Here is an example to clarify:
Graphics3D 800,600,0,2

Local surf = CreateSurface(CreateMesh())

Local cam = CreateCamera()
MoveEntity cam,0,0,-100

Const num = 50
Local i,k
While Not KeyDown(1)
	For i = 1 To num
		k = AddVertex(surf,Rnd(-10,10),Rnd(-10,10),Rnd(-10,10))
		AddVertex(surf,Rnd(-10,10),Rnd(-10,10),Rnd(-10,10))
		AddVertex(surf,Rnd(-10,10),Rnd(-10,10),Rnd(-10,10))
		AddTriangle(surf,k,k+1,k+2)
	Next
	RenderWorld()
	Text 0,0,TrisRendered()
	Flip
Wend


change the number to different values to change how many triangles are created each loop.


b32(Posted 2007) [#7]
I got the same outcome. It seems like the number of vertices on the surface matter, and not the TrisRendered(). Still, it varies depending on the 'num' value. It varies between 48k and 64. Strange.
It seems to be discussed before:
http://www.blitzbasic.com/Community/posts.php?topic=48359
http://www.blitzbasic.com/Community/posts.php?topic=47912


mindstorms(Posted 2007) [#8]
It is not that it is a big problem, I just stumbled on it and it seems weird that directx (or blitz) wigs out after different amount of vertexes...


Shambler(Posted 2007) [#9]
I've not noticed this before and always experienced 64K as the limit.

I thought that 64K was the limit for vertices on a surface because the surface was a vertexbuffer and the DX7 limit for a vertexbuffer is 64K verts.

Looks like a bug to me.


Gabriel(Posted 2007) [#10]
Well, it still does not explain why it changes...All a triangle is is three vertecies, so you can multiply all the values above by three to get the vertex info...

No, that's incorrect. It may be correct for the code example you gave later, but that's not automatically how it works. You don't automatically have to create three new vertices to create a triangle. You can share 1, 2 or even three previously created vertices, thus the shape of mesh you create will determine whether you have many vertices or relatively few. A long thin flat plane would have many more vertices than a sphere with the same number of triangles, for example, because the sphere shares more vertices.

Like the others, I've never experienced a fluctuating maximum number of vertices. It's always been 64k for me. I can only assume that a recent updatate ( perhaps to fix one of the recent incompatibility issues ) has interfered with this somehow.


mindstorms(Posted 2007) [#11]
Should I move this into a bug forum then?

edit: I have, see the bug reports for more info...


jfk EO-11110(Posted 2007) [#12]
did you try to add updateworld?

Does this MAV also happen when you create everything before you branch into the main loop?

I never experienced such problems so far. If it's a new bug then it must be very new.

It may have something to do with a lack of synchronisation between renderworld and surface manipulation that forces a download and upload of the mesh data from/to the vram, someone correct me if I'm wrong.


Robert Cummings(Posted 2007) [#13]
This isn't a bug

The amount of verts per surface is what has a limit, not per scene.


jfk EO-11110(Posted 2007) [#14]
Please read the original post.


mindstorms(Posted 2007) [#15]
I tried adding updateworld, to no effect, as well as makeing it flip false which had no effect too.

To make the triangles before the loop, how many should be made? I don't think that anything will happen until renderworld, because that is where an error is being thrown now.


jfk EO-11110(Posted 2007) [#16]
Yes, but only when the limit was hit, that may differ on certain cards, but should be at least:

31000 Triangles per surface, as well as 31000 Vertices (some may use signed 16 bit words to index internally) Surprisingly it even isn't exactly $7FFF, but a few hundred less sometimes.

You may however use a max of 31000 to be on the (yet) save side.

In your test loop with additions per frame - will the results differ if you add for example delay 50 in the main loop?


mindstorms(Posted 2007) [#17]
No, the delay does nothing but slow down program execution. You are saying that the max limit is 31000 vertices, how come the cap for 50 tris is just over half that at 15700?


D4NM4N(Posted 2007) [#18]
. "so you can multiply all the values above by three to get the vertex info."

not if theyre not welded, if you have 2 triangles it would be 6 verts unwelded and 4 if welded (I had this problem when designing the max block size for my terrain prog. i seem to remember each surface had a vertex limit)

It seems weird you get different results as to how many you add per frame though...

prehaps if you dump the vertex count to the debug log on each step of the loop(could take a while :), when it crashes you can see if somehow its exceeded the surface limit by looking the last debug entry. Then you will know if its the code behaving weird or something more odd.


mindstorms(Posted 2007) [#19]
The debug log shows nicely exactly the same thing...Each log is whatever num is higher than the rest, stopping at the exact same places as above.


D4NM4N(Posted 2007) [#20]
yeah i tried it and got the same thing, odd.


mindstorms(Posted 2007) [#21]
Is this a directx thing, or is blitz for whatever reason getting mad?


D4NM4N(Posted 2007) [#22]
.
I moved the renderworld into the loop and put a > in to save time

theres defo something strange, the marked value, when changed for 44000 it gets a mav almost straight away. But, start renderworld at 43500 and it carries on way past this!!!

Graphics3D 10,10,16,2

Local surf = CreateSurface(CreateMesh())

Local cam = CreateCamera()
MoveEntity cam,0,0,-100

Const num = 50
Local i,k
Repeat
	For i = 1 To num
		k = AddVertex(surf,Rnd(-10,10),Rnd(-10,10),Rnd(-10,10))
		AddVertex(surf,Rnd(-10,10),Rnd(-10,10),Rnd(-10,10))
		AddVertex(surf,Rnd(-10,10),Rnd(-10,10),Rnd(-10,10))
		AddTriangle(surf,k,k+1,k+2)
;               WEIRD! change below to 44000 (MAV) then change back to 43500, it works > 44000
 		If CountVertices (surf)>43500  

			DebugLog CountVertices (surf)
			RenderWorld():
		EndIf
		
	Next

Forever
.


i remember in ted, the max size of a terrain block could be 64x64 quads of welded triangles, go 1 over and mav. Prehaps theres some kind of power of 2 pattern it need to follow when adding them or something odd like that???


jfk EO-11110(Posted 2007) [#23]
64*64=4096
A mav with more?!?
I take it you have several alpha layers on the mesh-terrain, do yo?

64*64*2*8 is exactly $FFFF, the max on even the most tolerant cards under DirectX. Tell me are there 8 alpha layers for the vertexalpha stuff?

Anyway, the fact that renderworld is directly involved is really strange. What happens if you completely remark the renderworld call?


D4NM4N(Posted 2007) [#24]
Ah yes thats right, i do. theres 6 layers.
6x4096=24576 (still not near the expected 64k)

That makes sense JFK thanks. It is weird tho the example above isnt it.

hmmm the plot thickens

I did actually discover you can add tris to the mesh forever until you run out of ram (i guess) but its when its rendered that causes the problem.


jfk EO-11110(Posted 2007) [#25]
quote
(still not near the expected 64k)

since a gird of welded quads takes one more row of vertices than there are quads (eg: 64*64 quads = 65*65 vertices) you may have used more than 32000 vertices, or tris, the max when the card or directx is using signed words internally. And it does, afaik.


Bobysait(Posted 2007) [#26]
You can add vertices up to 65536 per surface.
But problems occures with the graphics card when we build the triangles in real time. as they are all in a cube of 10 units area, it 's more and more difficult for the graphgics to draw each one of the triangles.

But there is a bug that i can't explain.
If vertices are added but not rendered by the camera, we can add as many as we want vertices to the surface.
=> I added 1 000 000 vertices with no problems, but i can't add more than 60 000 vertices if they are rendered by the camera.

Graphics3D 800,600,0,2
SetBuffer BackBuffer()


Const num%	=	64
Local i%,v%,t%
Local area%	=	250

Local m%	=	CreateMesh		()
Local s%	=	CreateSurface	(m)
Local c%	=	CreateCamera	()


For State= 0 To 1
	Select State
		Case 0
			PositionEntity		(c,-2000,0,-1000)
		Case 1
			PositionEntity		(c,0,0,-1000)
			ClearSurface		s,1,1
			v=0
			t=0
			k=0
	End Select

	Repeat
		For i = 1 To num
			v = AddVertex(s,Rnd(-area,area),Rnd(-area,area),Rnd(-area,area))
				AddVertex(s,Rnd(-area,area),Rnd(-area,area),Rnd(-area,area))
				AddVertex(s,Rnd(-area,area),Rnd(-area,area),Rnd(-area,area))
				AddTriangle(s,v+0,v+1,v+2)
				t=t+1
		Next
		RenderWorld()
			Text 10,20,"vrts ;"+v+" / "+65536
			Text 10,40,"tris ;"+t
		Flip
		If V>100000 Exit
	Forever
Next

ClearWorld 1,1,1
EndGraphics()
End



As you'll can test, you 'll be abble to add 100 000 vertices easily but you won't be abble to render them.


Canardian(Posted 2007) [#27]
I think the difference in your tests comes from the fact that some vertices are not rendered at all, since they are out of the camera range. You create the vertices using random coordinates, including negative numbers, so some vertices will be out of sight for the camera.

EDIT: Nm, your camera is at -100, so all vertices are visible :)
But perhaps overlapping vertices cause the vertices behind not to be rendered?
Hmm, SeedRnd Millisecs() still makes it error out at 15700, so it has nothing to do with the random vertices.


Dreamora(Posted 2007) [#28]
DX7 Capabilities:
64 * 1024 Tris and Vertices per Mesh

BUT:

GF4 MX and similar hardware (TnL only hardware) only accepts 16*1024 tris (vertices seem to be larger than 32*1024 so most likely 64)


RemiD(Posted 2016) [#29]
Just to say (necro style :P) that on the computer i have here, the maximum is rather around 32000 vertices per surface and around 64000 triangles per surface... more and i get a MAV



RemiD(Posted 2016) [#30]
i have tested this code on 3 computers :
it works well with up to 32000 vertices and up to 64000 triangles per surface on 2 computers, more i get a MAV
it works well with up to 32000 vertices and up to 20000 triangles on 1 computer, more i don't get a MAV but the surface disappears ! (low end netbook power !)

i can have more than 32000 vertices on my 2 recent enough computers but since the MAV is sometimes at around 40000, sometimes at around 50000, sometimes at around 60000, i prefer to stay safe at 32000...


jfk EO-11110(Posted 2016) [#31]
I once wrote a function that would take a loaded mesh, if neccessary split the surfaces up into less than 31k Verts and Tris by using cloned blank surfaces (actually by cloning the brushes), all before any Renderworld was called, which practically eliminated these limits. Wasn't a big deal, at least for static meshes.