Jump to content

  • Log In with Google      Sign In   
  • Create Account

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: 135

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   Crossbones+   -  Reputation: 8276

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   Crossbones+   -  Reputation: 5300

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?



#4 Big Muscle   Members   -  Reputation: 135

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