Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

Why there is more D3D10/11Device::Draw (and some other functions) implementations?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 Big Muscle   Members   -  Reputation: 123

Like
0Likes
Like

Posted 26 February 2013 - 10:04 AM

Hello,

 

I have a problem which I am trying to solve for a longer time and have not found a correct solution yet. I need to hook certain functions in Direct3D and replace them with my own implementation. Hooking itself is not the problem. The problem is that Direct3D library uses more implementations for some functions and "randomly" switches between them. So if I hook e.g. Draw function, it works only for a while and then the function is replaced with another implementation so my hook is not called until I rehook this another implementation too.

 

After debugging Direct3D library, I noticed it really happens. I have found functions such as: D3D10Device1::Draw_<0>, D3D10Device1::Draw_<1>, D3D10Device1::Draw_<2> etc. It is much worse for D3D11Device as there is 8 different implementation of Draw function.

 

Does anybody know the technical details why (or when) each of the <0>, <1> etc.. is called? What is the difference between them?

My current solution for hooks is to periodically check Draw pointer and if it changes then rehook it again. It works but I don't see it as good solution (just because it requires additional code which can slow the things down).



Sponsor:

#2 mhagain   Members   -  Reputation: 3827

Like
1Likes
Like

Posted 26 February 2013 - 01:09 PM

This would be non-public info about something that's internal to the DX runtimes so speculation is all I can personally offer, unless/until someone who knows more comes along.

 

So - I'm guessing that there are fast-paths, slow-paths, special cases, etc, and depending on the current states, which shader stages are active, etc a different Draw function may be called.  It may make sense to - for example - have a separate Draw function for when a GS is active versus when one is not.


It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.


#3 Jason Z   GDNet+   -  Reputation: 2370

Like
0Likes
Like

Posted 26 February 2013 - 06:04 PM

This would be non-public info about something that's internal to the DX runtimes so speculation is all I can personally offer, unless/until someone who knows more comes along.

 

So - I'm guessing that there are fast-paths, slow-paths, special cases, etc, and depending on the current states, which shader stages are active, etc a different Draw function may be called.  It may make sense to - for example - have a separate Draw function for when a GS is active versus when one is not.

I also don't have any specific information, but this would make sense.  Have you tried to track when the changes occur?  What is happening between calls when you see the changes?  I would imagine that it has something to do with the input configuration of the pipeline, such as the number of vertex buffers bound, or perhaps limited by the system values needed by the pipeline.

 

Do you ever see one of the old functions come back after it has been replaced?


Jason Zink :: DirectX MVP
Check out our (now available) D3D11 book: Practical Rendering and Computation with Direct3D 11
Check out my Direct3D 11 engine on CodePlex: Hieroglyph 3
Check out our free online D3D10 book: Programming Vertex, Geometry, and Pixel Shaders
Lunar Rift :: Dual-Paraboloid Mapping Article :: Parallax Occlusion Mapping Article :: Fast Silhouettes Article

#4 Big Muscle   Members   -  Reputation: 123

Like
0Likes
Like

Posted 28 February 2013 - 09:12 AM

 Yes, the old functions come back (as I remember correctly it was something like Draw<0> is executed e.g. 500x, then function was swapped). Weird thing is that it does not happen always. Currently I wanted to track down how often the functions are swapped but it does not occur now :-/

 

However, some time ago, I was using following snippet running as background thread:

 

while(true)
{
   if(device->Draw != myDraw)
      rehook();

   Sleep(xxx);
}

 

it just hooks Draw function still around. If sleep is not used then it works "correctly" (there is still possible race condition but very rare) - but consumes 100% CPU.. When there is Sleep (with > 0 ms) then it does not work, so the functions are swapped very often. Also, it is not something like "if(some_condition_is_true) Draw<0> else Draw<1>", The function pointer is changed directly in the device object's virtual address table.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS