Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Etnu

DrawIndexedPrimitive() performance.

This topic is 5222 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

From the SDK Docs:
quote:
HRESULT DrawIndexedPrimitive(D3DPRIMITIVETYPE Type, INT BaseVertexIndex, UINT MinIndex, UINT NumVertices, UINT StartIndex, UINT PrimitiveCount );
Does this mean that the call actually transforms every vertex from BaseVertexIndex up through NumVertices, even if they aren''t in the index list? If that''s the case, is there any way to force the call to only transform vertices that are actually indexed, or would I be saving time (since the vertices are completely disorganized) by just calling DrawPrimitive() with a seperate vertex buffer for each item that''s currently in the one large buffer?

Share this post


Link to post
Share on other sites
Advertisement
quote:
Original post by RenderTarget
Only indexed vertices are transformed.

My spoon is too big.


That is incorrect. DIP transforms all vertices in the range of MinIndex up through NumVertices. This is done primarily for vertex reuse where some of the indices may reference the same vertices and thus would avoid another transform. Don't be alarmed by this behaviour, it is implemented to improve effiency. On top of that you get cache effiency from quickly reused vertices (ie those that are reused by the next index value etc) as vertices that have just been used are held in the cache in case they are to be used shortly thereafter.
Your best bet would be to reorganise your vb so that vertices for the draw calls will be tightly grouped in the Numvertices range.

[edit] had to change BaseVertexIndex to MinIndex, right argument, wrong variable
MinIndex is the lowest valued index that will be used in the call
BaseVertexIndex is an offset that is applied to the index stream an minindex.
quote:

from dx sdk
"MinIndex and all the indices in the index stream are relative to the BaseVertexIndex"



[edited by - SoulSpectre on June 3, 2004 10:42:28 PM]

Share this post


Link to post
Share on other sites
I''m assuming, then, that the video card''s "MaxVertexIndex" cap is relevant here as well, meaning that I''d still have to use multiple vertex buffers if I want more than 1,048,576 vertices? Or is that cap on a per-call basis?

I can certainly see why it''s more efficient to transform every vertex in the stream from MinIndex to MinIndex+NumVertices, but unfortunately my indices aren''t necessarily in line with the vertex buffer (each sector has, on average, 7000 indices, but these might range from 0 all the way up to the highest vertex in the list).

Blah, guess I''m back to using multiple VB''s.

Share this post


Link to post
Share on other sites
Both are correct.

In software transform, all vertices from MinIndex to MinIndex+NumVertices-1 are transformed.

In hardware transform, there''s no law about it, but generally only the indexed primitives are transformed (since the post T&L cache is only a dozen vertices or so, not enough for the entire model).

Share this post


Link to post
Share on other sites
the max size of a ib is defined in D3DCAPS9 Structure.

quote:

MaxVertexIndex
Maximum size of indices supported for hardware vertex processing. It is possible to create 32-bit index buffers by specifying D3DFMT_INDEX32; however, you will not be able to render with the index buffer unless this value is greater than 0x0000FFFF.



use IDirect3DDevice9::GetDeviceCaps to get the capabilites of your system.
[sorry that should be ib not vb]

[edited by - SoulSpectre on June 3, 2004 11:09:09 PM]

Share this post


Link to post
Share on other sites
Yes, the maximum size is 1048576 (24 bits, at best) on any card presently available (possibly higher on a Geforce6 or Radeonx800, as I haven''t seen the caps of those). That''s where it sits on the geforce5xxx / radeon 9xxx.

It would just make a lot more sense for me to have 1 big vertex buffer. 1,048,576 vertices only takes up about 32MB of ram (position, normal, texture coordinates), and the program I''m working on doesn''t use very many textures (no more than 32MB or so, max). It would make a lot of sense to have 32-128MB of video memory to hold all of the vertices, in a single buffer.

Oh well.

Namethatnobodyelsetook:

I''m not really concerned about software transform, but that''s useful to know when I''m debugging shaders. Thanks.

Share this post


Link to post
Share on other sites
quotes drom dx sdk.
quote:

Draw using indexed primitives. This can allow for more efficient vertex caching within hardware.



..and..
quote:

The MinIndex and NumVertices parameters specify the range of vertex indices used for each IDirect3DDevice9::DrawIndexedPrimitive call. These are used to optimize vertex processing of indexed primitives by processing a sequential range of vertices prior to indexing into these vertices. It is invalid for any indices used during this call to reference any vertices outside of this range.



The SDK says that the range specified is processed PRIOR to indexing into that range.


[edited by - SoulSpectre on June 3, 2004 11:15:33 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by SoulSpectre
The SDK says that the range specified is processed PRIOR to indexing into that range.


Which is true only during software rendering. nVidia cards ignore these values on hardware transform (to the point where in the XBox headers they''re labelled unused). I''ve used completely invalid values on PC due to a bug, and until we started testing with older hardware everything was fine. I''ve heard that ATI cards need these values to be accurate, but without any explaination as to why they must be accurate. I doubt they pre-transform everything, so it''s probably more of an error check.

Since they''re easy to calculate, and since software needs them, and possible ATI hardware, why not just calculate them correctly and not worry about it again.

The OP says he''s only worried about hardware transform, so it''s not a big deal. Just specify the values and ignore what it may do for software mode. If, on the other hand, you''re worried about the performance hit of transforming vertices from all over your buffer, perhaps you should revisit how your buffer is built, and throw in an optimizing step. Duplicating a few vertices along material seams is much better than reusing the same vertices and causing software to transform way too much data.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!