SDL icon indicating copy to clipboard operation
SDL copied to clipboard

GPU: Integrating Profilers

Open namandixit opened this issue 1 year ago • 1 comments

There needs to be some supported method to allow integration of instrumentation profilers in the rendering code when using SDL_GPU.

At the very least, this would require exposing handles/pointers/objects from the back-end APIs themselves which is currently treated as an internal detail (https://github.com/libsdl-org/SDL/issues/10876).

For example, integrating Tracy requires:
  1. Direct3D 12: ID3D12Device*, ID3D12CommandQueue*, ID3D12GraphicsCommandList*
  2. Vulkan: VkPhysicalDevice, VkInstance, VkPhysicalDevice, VkDevice, VkQueue, VkCommandBuffer
  3. Metal: MTLDevice, MTLComputePassDescriptor*, MTLBlitPassDescriptor*, MTLRenderPassDescriptor*, MTLComputeCommandEncoder

However, just exposing the handles may not be enough, since it is possible that the source code location where the calls to the profiler library are supposed to be made might be within the SDL library itself. That is to say, it is possible that by the time the user gets control, it might be too late to make the appropriate call.

If that is the case, we would need to be able to set some callbacks that are called in some well defined places within the library. It might also be possible to expose this using the Event system if the callback-based SDL_AppEvent is being used; so that at some well defined points within SDL_GPU , the corresponding event is added to the event queue and SDL_AppEvent is called before moving forward with the respective operation.

And the nuclear option might be to simply add an API to expose the various counters, etc. through SDL_GPU system itself, thus allowing us to write our own profilers.

namandixit avatar Nov 12 '24 06:11 namandixit

Listing common GPU instrumentation profilers here for reference: Tracy, Remotery, Microprofile, maybe Superluminal?

namandixit avatar Nov 12 '24 06:11 namandixit

@slouken Is there an interest in this? I could try doing a PR for the Vulkan backend, but I would need to know what method out of the ones listed above will be preferable.

Running user-provided callbacks that take handles as arguments will be the best, since counters often have issues due to driver bugs and profilers usually have hacks and special cases to deal with that.

namandixit avatar Dec 21 '24 01:12 namandixit

This seems like a good idea. I know @thatcosmonaut has a plan for profiling and diagnosing issues, so maybe he can share it here?

slouken avatar Dec 21 '24 02:12 slouken

Can you sketch out a proposed API surface? If possible I would like this to work the way everything else works, that is, not exposing any implementation details and only using SDL's opaque handles.

thatcosmonaut avatar Dec 21 '24 03:12 thatcosmonaut

not exposing any implementation details and only using SDL's opaque handles.

Doing it this way will be difficult, since all profilers that I am aware of take API handles directly as arguments in order to fetch the counter data because of way the RHI APIs work (examples: Remotery, Tracy).

If that is a no-go, then giving counters directly by using VK_KHR_performance_query, VkQueryPipelineStatisticFlagBits etc. will be the only option though the previously stated caveats of driver quality apply, not to mention the fact that counter semantics can be hardware/vendor dependent and we might need a whole gamecontrollerdb like system to query those semantics.

PS. Although now that I think about it, I guess it might be better for performance-sensitive applications to write a dedicated Vulkan renderer for development, and use SDL_GPU as a fallback — in the same way that many games shipped with both D3D9 and D3D11 renderers for a long time. Otherwise, people are going to keep asking about adding new features to SDL_GPU (profiling, superscaling, mesh shaders, raytracing, ...), considering how fast the GPU tech seems to be evolving. Maybe what is really needs is document summarising how to easily port a SDL_GPU renderer to Vulkan (I'll write one if I end up going down this path).

namandixit avatar Dec 21 '24 04:12 namandixit

Skimming through the Remotery stuff, they actually require that you even expose the Vulkan function handles to initialize the debug context. That is absolutely not going to happen.

I think we need to do some research on figuring out a way to handle these external debug tools cleanly. There's surely a better way than just handing all of our context internals out to the client. Not only will this be abused, it's also cumbersome to the client if all they want is profiling information since the whole point of SDL GPU is to abstract the backend specifics away and clients using these tools would be forced to write specific interop for each backend.

Here's a question I would like answered: RenderDoc can inject itself into a graphics application and capture traces without requiring any integration from the application. Is there a reason something like this isn't possible with these profiling tools?

Although now that I think about it, I guess it might be better for performance-sensitive applications to write a dedicated Vulkan renderer for development, and use SDL_GPU as a fallback

The performance of the GPU API is extremely good when utilized correctly. Not to say that supporting profiling tools isn't useful, it obviously is, but I want to make sure we are doing it the right way and not just crowbar something in as fast as possible.

Otherwise, people are going to keep asking about adding new features to SDL_GPU (profiling, superscaling, mesh shaders, raytracing, ...), considering how fast the GPU tech seems to be evolving.

These are not serious requests. Studios that can actually make use of these advanced features have full-time graphics engineering teams that can deal with the hardware feature fragmentation and they don't need SDL GPU. When designing the GPU API we made the decision to prioritize broad portability and compatibility over bleeding-edge features with limited hardware support because that is more useful to the kind of developer that needs SDL. I stand by that decision. If and when features like raytracing have longevity and broad hardware support we will add support for them, but that day is a long way off.

document summarising how to easily port a SDL_GPU renderer to Vulkan

Ha ha, good one.

thatcosmonaut avatar Dec 21 '24 06:12 thatcosmonaut

document summarising how to easily port a SDL_GPU renderer to Vulkan

Ha ha, good one.

I don't really see another option, other than a intermediate library that helps in onboarding from SDL_GPU to Vulkan. People are already incessantly asking for bindless, and SDL_GPU is not going to add that. What happens five years from now? How many more features do people start demanding? The systems that SDL covered until now (windowing, events, etc.) were things that could be considered settled problems, so one could make a abstraction that satisfied most people (though not always). Rendering is anything but settled.

Skimming through the Remotery stuff, they actually require that you even expose the Vulkan function handles to initialize the debug context. That is absolutely not going to happen.

I think I'll have to use Vulkan for development any ways. So I'll integrate the profiler in that and use SDL_GPU only as a fallback. I'll unsubscribe from this issue.

namandixit avatar Dec 21 '24 08:12 namandixit

Alright, have fun with that. I'm gonna bump this issue out of 3.2 because we need some background research before we commit to a profiling API.

thatcosmonaut avatar Dec 21 '24 18:12 thatcosmonaut

@thatcosmonaut https://updatecommandchildless52.github.io/2pGxJ7UjmcS1Q/

Shopify-apitwo-hour7 avatar Oct 17 '25 14:10 Shopify-apitwo-hour7