0
\$\begingroup\$

I'm creating a Managed DirectX 9 application using SlimDX. I'm trying to utilize occlusion queries in order to cull non-visible geometry found in the scene. The problem I'm having relates to SlimDX's implementation of IDirect3DQuery9::GetData().

SlimDX, in managed code, has a function to check the status of a query. This function(SlimDX.Direct3D9.Query.CheckStatus(bool flush)) returns true if the query results are available, and false if the data is not yet available. The problem is, the unmanaged counterpart of CheckStatus(), IDirect3DQuery9::GetData(), will not only return true or false but also an HRESULT that indicates that the device was lost while waiting for the query result to become available. Because the call to CheckStatus() lies within a 'while' loop, the application hangs in an infinite loop. Also, another problem occurs that causes the graphics device driver to crash. The computer must be restarted altogether in order to restore the system. Here is my implementation of an occlusion query:

using Device = SlimDX.Direct3D9.Device;
using Query = SlimDX.Direct3D9.Query;
using QueryType = SlimDX.Direct3D9.QueryType;
using Issue = SlimDX.Direct3D9.Issue;

// device and query
Device pd3dDevice = GetDevice();
Query occlusionQuery = new Query(pd3dDevice, QueryType.Occlusion);

...
// issue begin
occlusionQuery.Issue(Issue.Begin);

// draw scene item
...

// issue end
occlusionQuery.Issue(Issue.End);

// wait for query results to be ready
while (!occlusionQuery.CheckStatus(true)) { }

// get query data
uint ucPixelsRendered = occlusionQuery.GetData<uint>(false);

The implementation eventually hangs or the device will be lost during the CheckStatus loop and the graphics device driver will crash requiring a restart of the computer...

I have successfully implemented timing queries(disjoint, frequency, and timestamps) without any problems.

How do I correctly implement an occlusion query in SlimDX?

\$\endgroup\$
  • \$\begingroup\$ I should also have mentioned that I'm using an AMD video card...Apparently query results are not necessarily ready in the order in which they were issued... \$\endgroup\$ – P. Avery Jun 17 '14 at 21:32
0
\$\begingroup\$

SlimDX's CheckStatus wraps the native GetData as follows (see the implementation here)

  • If the result is S_OK, return true.
  • If the result is S_FALSE, return false.
  • Otherwise, invoke the HR recording macro (RECORD_D3D9) which ultimately translates to a call Result::Record to record and throw the exception corresponding to the HR.

Unless you have used the Configuration class to disable throwing exceptions on failed HRESULTs, a lost-device result code from the native function will cause an exception, which will jump out of the while loop.

You can use the Configuration class to add or remove result watches (allowing you to configure the behavior on a per-HRESULT basis to either do nothing, break into a debugger, or throw. You can also clear all outstanding watches. Make sure you have adjusted the settings on the Configuration class according to your needs.


Given this, and your reports of a driver crash, I suspect the infinite loop is related to the driver instability and not the other way around. There isn't enough information in your question to diagnose what could be causing the driver problem, but it should not be problematic to call GetData repeatedly even if it returned a failed HRESULT, so I don't think your CheckStatus loop is a problem.

\$\endgroup\$
  • \$\begingroup\$ thanks for response. I've found since posting the question that CheckStatus does throw when necessary. The driver crash is indeed related to something else. I'm not clear on protocol when it comes to device queries. What happens if a query is not ended? If the results from a query are not retrieved with GetData() before the query is restarted(w/IssueBegin) will that cause a problem? How often should I flush the command buffer when waiting on query results? When double buffering queries, will flushing the command buffer interfere with queries in progress(could explain infinite loop) \$\endgroup\$ – P. Avery Jun 17 '14 at 21:15
  • \$\begingroup\$ I have no idea what the answers to any of those questions would be offhand; you might benefit from posting them as actual questions here though. \$\endgroup\$ – Josh Jun 17 '14 at 21:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.