@@ -395,75 +395,88 @@ namespace tracy
395395 }
396396
397397 public:
398- static bool SetupDeviceDescriptor (WGPUDeviceDescriptor& deviceDescriptor)
398+ class Requirements
399399 {
400- // TODO: pass features array/size as argument to better allow for repeated calls
401- static constexpr int MaxFeatures = 128 ;
402- static WGPUFeatureName features [MaxFeatures] = {};
403-
404- int n = deviceDescriptor.requiredFeatureCount ;
405- assert (n < MaxFeatures && " Too many required features in WGPUDeviceDescriptor" );
406- if (n > 0 && deviceDescriptor.requiredFeatures )
407- memcpy (features, deviceDescriptor.requiredFeatures , n * sizeof (WGPUFeatureName));
408-
409- features[n++] = WGPUFeatureName_TimestampQuery;
410-
400+ private:
411401# if (TRACY_WEBGPU_DAWN_NATIVE)
412- TracyWebGPUDebug ( fprintf (stderr, " [INFO] [DAWN] ENABLING RAW TIMESTAMP TICKS (disabling ns conversion + quantization)\n " ) );
413- // disable_timestamp_query_conversion: resolve timestamps as raw GPU ticks, not nanoseconds.
414- // timestamp_quantization: disabled defensively (off by default on Metal, but on elsewhere).
415- static const char * dawnDisabledToggles[] = { " timestamp_quantization" };
416- static const char * dawnEnabledToggles[] = { " disable_timestamp_query_conversion" };
417- static WGPUDawnTogglesDescriptor togglesDesc = {};
418- togglesDesc.chain .sType = WGPUSType_DawnTogglesDescriptor;
419- togglesDesc.disabledToggles = dawnDisabledToggles;
420- togglesDesc.disabledToggleCount = 1 ;
421- togglesDesc.enabledToggles = dawnEnabledToggles;
422- togglesDesc.enabledToggleCount = 1 ;
423- togglesDesc.chain .next = deviceDescriptor.nextInChain ;
424- deviceDescriptor.nextInChain = reinterpret_cast <WGPUChainedStruct*>(&togglesDesc);
402+ WGPUDawnTogglesDescriptor dawnTogglesDesc = {};
403+ static constexpr int NumExtras = 0 ;
425404# elif (TRACY_WEBGPU_WGPU_NATIVE)
426- // wgpu-native: passTimestampWrites requires the non-standard
427- // TIMESTAMP_QUERY_INSIDE_PASSES device feature in addition to
428- // the standard TimestampQuery feature.
429- TracyWebGPUDebug ( fprintf (stderr, " [INFO] [WGPU] Requesting TimestampQueryInsidePasses native feature\n " ) );
430- features[n++] = (WGPUFeatureName)WGPUNativeFeature_TimestampQueryInsideEncoders;
405+ static constexpr int NumExtras = 1 ;
431406# endif
432- deviceDescriptor.requiredFeatures = features;
433- deviceDescriptor.requiredFeatureCount = static_cast <uint32_t >(n);
434- return true ;
435- }
436407
437- bool VerifyDevice (WGPUDevice device)
438- {
439- if (device == nullptr )
440- return false ;
441- if (wgpuDeviceHasFeature (device, WGPUFeatureName_TimestampQuery) == WGPU_FALSE )
408+ public:
409+ static constexpr int NumFeatures = 1 + NumExtras;
410+ WGPUFeatureName features [NumFeatures] = {};
411+ WGPUChainedStruct* togglesDesc = nullptr ;
412+
413+ Requirements ()
414+ {
415+ this ->features [0 ] = WGPUFeatureName_TimestampQuery;
416+ # if (TRACY_WEBGPU_WGPU_NATIVE)
417+ this ->features [1 ] = (WGPUFeatureName)WGPUNativeFeature_TimestampQueryInsideEncoders;
418+ # endif
419+ # if (TRACY_WEBGPU_DAWN_NATIVE)
420+ static const char * dawnDisabledToggles[] = { " timestamp_quantization" };
421+ static const char * dawnEnabledToggles[] = { " disable_timestamp_query_conversion" };
422+ this ->dawnTogglesDesc .chain .sType = WGPUSType_DawnTogglesDescriptor;
423+ this ->dawnTogglesDesc .disabledToggles = dawnDisabledToggles;
424+ this ->dawnTogglesDesc .disabledToggleCount = 1 ;
425+ this ->dawnTogglesDesc .enabledToggles = dawnEnabledToggles;
426+ this ->dawnTogglesDesc .enabledToggleCount = 1 ;
427+ this ->togglesDesc = reinterpret_cast <WGPUChainedStruct*>(&this ->dawnTogglesDesc );
428+ # endif
429+ }
430+
431+ static bool VerifyDevice (WGPUDevice device)
432+ {
433+ if (device == nullptr )
434+ return false ;
435+ if (wgpuDeviceHasFeature (device, WGPUFeatureName_TimestampQuery) == WGPU_FALSE )
436+ return false ;
437+ # if (TRACY_WEBGPU_DAWN_NATIVE)
438+ bool hasDisableConversion = false , hasQuantization = false ;
439+ for (const char * t : ::dawn::native::GetTogglesUsed (device))
440+ {
441+ if (strcmp (t, " disable_timestamp_query_conversion" ) == 0 )
442+ hasDisableConversion = true ;
443+ if (strcmp (t, " timestamp_quantization" ) == 0 )
444+ hasQuantization = true ;
445+ }
446+ return hasDisableConversion && !hasQuantization;
447+ # elif (TRACY_WEBGPU_WGPU_NATIVE)
448+ if (wgpuDeviceHasFeature (device, (WGPUFeatureName)WGPUNativeFeature_TimestampQueryInsideEncoders) == WGPU_FALSE )
449+ return false ;
450+ return true ;
451+ # endif
442452 return false ;
443- # if (TRACY_WEBGPU_DAWN_NATIVE)
444- bool hasDisableConversion = false , hasQuantization = false ;
445- for (const char * t : ::dawn::native::GetTogglesUsed (device))
453+ }
454+
455+ void ApplyToDeviceDescriptor (WGPUDeviceDescriptor& deviceDescriptor)
456+ {
457+ uint32_t userCount = deviceDescriptor.requiredFeatureCount ;
458+ uint32_t totalCount = userCount + NumFeatures;
459+ // NOTE: this allocation will leak...
460+ auto * mergedFeatures = static_cast <WGPUFeatureName*>(tracy_malloc (totalCount * sizeof (WGPUFeatureName)));
461+ if (userCount > 0 && deviceDescriptor.requiredFeatures )
462+ memcpy (mergedFeatures, deviceDescriptor.requiredFeatures , userCount * sizeof (WGPUFeatureName));
463+ memcpy (mergedFeatures + userCount, features, NumFeatures * sizeof (WGPUFeatureName));
464+ deviceDescriptor.requiredFeatures = mergedFeatures;
465+ deviceDescriptor.requiredFeatureCount = totalCount;
466+
467+ if (togglesDesc)
446468 {
447- if (strcmp (t, " disable_timestamp_query_conversion" ) == 0 )
448- hasDisableConversion = true ;
449- if (strcmp (t, " timestamp_quantization" ) == 0 )
450- hasQuantization = true ;
469+ togglesDesc->next = deviceDescriptor.nextInChain ;
470+ deviceDescriptor.nextInChain = togglesDesc;
451471 }
452- return hasDisableConversion && !hasQuantization;
453- # elif (TRACY_WEBGPU_WGPU_NATIVE)
454- // wgpu-native also requires TimestampQueryInsideEncoders for ResolveQuerySet.
455- if (wgpuDeviceHasFeature (device, (WGPUFeatureName)WGPUNativeFeature_TimestampQueryInsideEncoders) == WGPU_FALSE )
456- return false ;
457- return true ;
458- # endif
459- return false ;
460- }
472+ }
473+ };
461474
462475 WebGPUQueueCtx (WGPUInstance instance, WGPUDevice device, WGPUQueue queue)
463476 {
464477 ZoneScopedC (Color::Red4);
465478
466- if (!VerifyDevice (device))
479+ if (!Requirements:: VerifyDevice (device))
467480 TracyWebGPUPanic (" GPU profiling disabled because the device did not enable the necessary features." , return )
468481
469482 TracyWebGPUAssert (instance); wgpuInstanceAddRef (instance); m_instance = instance;
@@ -910,7 +923,7 @@ namespace tracy
910923
911924using TracyWebGPUCtx = tracy::WebGPUQueueCtx*;
912925
913- #define TracyWebGPUSetupDeviceDescriptor (deviceDescriptor ) tracy::WebGPUQueueCtx::SetupDeviceDescriptor (deviceDescriptor)
926+ #define TracyWebGPUSetupDeviceDescriptor (deviceDescriptor ) tracy::WebGPUQueueCtx::Requirements TracyConcat (__tracy_wgpu_setup_, TracyLine); TracyConcat(__tracy_wgpu_setup_, TracyLine).ApplyToDeviceDescriptor (deviceDescriptor)
914927
915928#define TracyWebGPUContext (instance, device, queue ) tracy::CreateWebGPUContext(instance, device, queue);
916929#define TracyWebGPUDestroy (ctx ) tracy::DestroyWebGPUContext(ctx);
0 commit comments