1
\$\begingroup\$

I'm rendering to a texture via DrawIndexedPrimitive (SharpDx). In some specific situations, the framerate drops significantly when doing this render. The framerate can be improved by rendering to a smaller texture.

I want to gracefully degrade the quality of the graphics performance at runtime by measuring the impact of this particular pass and rendering to a smaller texture if the framerate would be impacted by this pass. Later, when the impact of this pass is smaller I want to restore the larger texture size.

Is there some way to measure at runtime the impact of a particular draw on the gpu? It's ok if the results of the measurement are delayed to the next frame.

\$\endgroup\$
10
  • \$\begingroup\$ Need more info, how many milliseconds does it take to draw your frame? What else are you doing because I have never seen a single render to texture call bog down the frames?, are you updating it from the CPU?, are you using a shader to render to the texture? Are you using directX9, 10, 11 or 12? It looks like DX9 but I could be wrong, are you using the toolkit or sharpDX 3.0.2 without the toolkit. If you are using anything under v3 then you should think about an upgrade. You can use GPU query's to find out how much time the call is taking but these will be 3-5 frames behind realtime. \$\endgroup\$ Commented Jan 24, 2017 at 22:55
  • \$\begingroup\$ @justin-william-stanley-bryant Please tell me about the GPU query's. I do not mind that the values are delayed. \$\endgroup\$ Commented Jan 24, 2017 at 23:10
  • \$\begingroup\$ (a) I've seen as bad as ~900ms to draw one frame on average (b) There's quite a bit going on unrelated, but this draw is responsible. I'll make a second comment to follow with more information (c) I'm not sure what you mean, but I'm not streaming significant amount of data to from the cpu (d) directX9 (e) Looks like a custom fork with the toolkit. I'll have to dig further about this - original devs are long gone. \$\endgroup\$ Commented Jan 24, 2017 at 23:12
  • \$\begingroup\$ @JustinWilliamStanleyBryant The reason for the extreme time to render the texture is that the texture is the same size as the screen (without downsampling, which improves performance) and the content being rendered aggregates several transparent polygons on top of each other. The framerate drops when the camera is such that tens of thousands of polygons draw on top of each other, when each covers a large portion of screen real-estate (like overdraw, but necessary overdraw) \$\endgroup\$ Commented Jan 24, 2017 at 23:16
  • \$\begingroup\$ I see now, I haven't done much work with performance query's and from what I can see they are very different from DX9-DX11 so I'm not really game to make an answer just yet but the best place to start would be msdn.microsoft.com/en-us/library/windows/desktop/… and then maybe get one of the older DX sdk's so you can look at a code sample. SharpDX and native DirectX are almost 1:1 so I always start with the c++ samples, if you can wrangle SharpDX well then you should be fine. Could also try sorting and drawing your alpha objects front to back with depth testing on \$\endgroup\$ Commented Jan 24, 2017 at 23:27

1 Answer 1

1
\$\begingroup\$

First up the best place to start is the MSDN docs about GPU queries

The basic idea is to wrap your calls in a queries begin and end functions and then wait a few frames to read the info back from the GPU.

I haven't done much query work in DX9 so I cant help much more than showing you how I setup DX11 occlusion queries.

Best bet would be to do this in a none blocking way something like this every frame to check if the query has returned

  //Setup Query
  Dim qdesc As QueryDescription
  qdesc.Flags = QueryFlags.None
  qdesc.Type = QueryType.Occlusion
  g_pPredicate = New Query(_device, qdesc)

  //Running the Query
 _context.ImmediateContext.Begin(g_pPredicate)
 BoundingBoxRenderer.DrawEX(_device, Bounding, _camera, Color.Red, _context)
 _context.ImmediateContext.End(g_pPredicate)

 // Checking If The Query Has Returned
 HasData = _context.IsDataAvailable(g_pPredicate)
 If HasData then
   return pPredicate
 end if

 //Using The Query Data
 If HasData Then
  Dim value As UInt64 = _context.ImmediateContext.GetData(Of UInt64)(g_pPredicate)
    If value > 0 Then
      IsVisible = True
    Else
      IsVisible = False
    End If
   HasData = False
 End If

  

There are several types of queries which are designed to query the status of resources. The status of a given resource includes graphics processing unit (GPU) status, driver status, or runtime status. To understand the difference between the different query types, you need to understand the query states. The following state transition diagram explains each of the query states.

enter image description here

The diagram shows three states, each defined by circles. Each of the solid lines are application-driven events that cause a state transition. The dashed line is a resource-driven event that switches a query from the issued state to the signaled state. Each of these states has a different purpose:

•The signaled state is like an idle state. The query object has been generated and is waiting for the application to issue the query. Once a query has completed and transitioned back to the signaled state, the answer to the query can be retrieved.

•The building state is like a staging area for a query. From the building state, a query has been issued (by calling D3DISSUE_BEGIN) but has not yet transitioned to the issued state. When an application issues a query end (by calling D3DISSUE_END), the query transitions to the issued state.

•The issued state means that the resource being queried has control of the query. Once the resource finishes its work, the resource transitions the state machine to the signaled state. During the issued state, the application must poll to detect the transition to the signaled state. Once the transition to the signaled state occurs, GetData returns the query result (through an argument) to the application.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .