Hi,
I'm currently adding shader instancing to our engine. After I changed the single world matrix in the effect file to a matrix array, I noticed a heavy performance drop. The fps went down by almost 30%. After some investigation I found that the fps changes with the size of the matrix array, so the effect framework seems to always copy all elements of the array, not only those that were actually set.
I then wanted to optimize this using the ID3DXEffect::SetArrayRange method which I guess should then cause the effect to only copy the matrices in the set range. However, I don't see any effect when I use this function. I called it in different places with different ranges, but I always get the same results.
Is ID3DXEffect::SetArrayRange broken Or do I miss something about its usage
I've searched the web on this, but only found a post from a guy having the exact same problem.
BTW, I'm using the latest SDK (Feb06).
Regards

Question on ID3DXEffect::SetArrayRange
Slesh
I don't believe it's intended for SM 3.0 only. I downloaded some older SDKs, and it seems like the method was added in Summer 2004. However, I couldn't find any more information or a sample using it there.
BTW, here's the message I refered to in my first post: http://www.eggheadcafe.com/forumarchives/win32programmerdirectxgraphics/sep2005/post23673419.asp
Actually the same problem as I have. I see a performance drop depending on the number of matrix elements. For instance, I get 44fps with 40 matrix elements, 66fps with 10 elements and 77fps with only 1 element (same fps as without array). The only change I made during this series of measurements was modifing the array size in the FX file. The executable was not altered, all rendering was done the same way. I also couldn't yet see any difference in PIX other than the varying Vector4fCount parameter in the SetVertexShaderConstantF call. That's why I hope to be able to optimize this by somehow telling the effect frameworks which matrix elements are really needed and thus to cause it to only set those to the device. Or is this bogus and the number of constants set can't affect performance
svip
With arrays of float4x3, float4x2 and float4x1 matrices the method works as excepted, only the elements within the set range are passed to the device.
Seems like it also doesn't work with vector arrays either. Maybe someone can confirm this
Regards
JohnFlemming
I saw at least 2 other people who have trouble with the same function
I found another link where the person simply use something else...
In the link they seems to say that previous SDK use that function
I would try to Find an exemple in the SDK that contain that function to see how they use it (or get some older SDK that used this)
Maybe I would check the modification to see if it may be a function that don't work
in new SDK or DirectX
Is this only for Shader 3.0 maybe
I would try to do this in the CPU and just update the array I know have changed
I'm out of idea after that :-)
http://www.gamedev.net/community/forums/topic.asp topic_id=366247
I have had problems with this, even in regular unmanaged D3D. The effect framework allows you to set an array of constants, but not a specific range of them (ie you supply a starting index - if anybody knows of this, I would love to know ). It also allows you to set an array of matrix pointers (very nifty for skinning), but again, not a specific range of them. When all of your data is stored in different arrays (since the constants being instanced are stored in the individual nodes), this is quite annoying.
The way I do it is to just set each member individually. By that, I mean that if I want to set from index 4-8 in the constant array, I just retrieve the handle of the constant at index 4, set it, and repeat. Since ID3DXEffect employs some state change batching, it doesn't really cause a performance hit (other than the CPU overhead from the additional ID3DXEffect::SetValue() calls).
HBN
I checked my app with PIX. CommitChanges really always sets all elements of the array with SetVertexShaderConstantF, no matter how or where SetArrayRange was called.
Is anybody using SetArrayRange (successfully)
Regards
miauru
I found this on GameDev...
(It seems to be for Skinmesh when you have many Bones Array)
Does anyone have experience with the function "ID3DXBaseEffect::SetArrayRange"
It doesn't seem to work and the only google info I've found is on the MSDN site.
I'm using it do try and upload a chunk of matrices into the middle of my vertex shader matrix array.
thanks
Steve.
I actually got it working. The MSDN documentation is very sparse, but I figured it out through trial and error:
Basically you still need to use the "SetMatrixArray" function with the count parameter set to your full array size, but before that call, you use the "SetArrayRange" function to specify which elements of the array will actually be updated.
// Set which elements to update
pSkinEffect->SetArrayRange ( m_hSkinMatrixArray, m_iSkinStartMatrix, m_iSkinEndMatrix );
// Send range of matrices to shader (size of full array is 48 items)
pSkinEffect->SetMatrixArray( m_hSkinMatrixArray, (D3DXMATRIX*)m_SkinMatrixCache, 48 );
-Steve.
anydobbo
uTILLIty
thanks for your response. I know this post on GameDev, and I also already tried to do it like this.
I set a range with SetArrayRange and then called SetMatrixArray expecting to have only the matrices in the set range updated. But SetMatrixArray still updates all matrix elements in the array, and CommitChanges sets all of them to the device.
Also, the documentation states "Set the range of an array to pass to the device." not "Set a range of an array to pass to the effect." So I guess it should actually affect the number of constants in the SetVertexShaderConstantF call.
Regards