@@ -237,51 +237,45 @@ static void UncapturedErrorCallback2(WGPUDevice const* device,
237237}
238238#endif
239239
240- WebGPUDeviceWrapper CreateDeviceForAdapter (EngineWebGPUCreateInfo const & EngineCI , WGPUInstance wgpuInstance, WGPUAdapter wgpuAdapter)
240+ WebGPUDeviceWrapper CreateDeviceForAdapter (const DeviceFeatures& Features , WGPUInstance wgpuInstance, WGPUAdapter wgpuAdapter)
241241{
242242 WGPUSupportedLimits SupportedLimits{};
243243 wgpuAdapterGetLimits (wgpuAdapter, &SupportedLimits);
244244
245- std::vector<WGPUFeatureName> Features {};
245+ std::vector<WGPUFeatureName> wgpuFeatures {};
246246 {
247- if (EngineCI.Features .DepthBiasClamp && wgpuAdapterHasFeature (wgpuAdapter, WGPUFeatureName_DepthClipControl))
248- Features.push_back (WGPUFeatureName_DepthClipControl);
249-
250- if (EngineCI.Features .TimestampQueries && wgpuAdapterHasFeature (wgpuAdapter, WGPUFeatureName_TimestampQuery))
251- Features.push_back (WGPUFeatureName_TimestampQuery);
252-
253- if (EngineCI.Features .TimestampQueries && wgpuAdapterHasFeature (wgpuAdapter, WGPUFeatureName_ChromiumExperimentalTimestampQueryInsidePasses))
254- Features.push_back (WGPUFeatureName_ChromiumExperimentalTimestampQueryInsidePasses);
255-
256- if (EngineCI.Features .TextureCompressionBC && wgpuAdapterHasFeature (wgpuAdapter, WGPUFeatureName_TextureCompressionBC))
257- Features.push_back (WGPUFeatureName_TextureCompressionBC);
258-
259- if (EngineCI.Features .TextureCompressionETC2 && wgpuAdapterHasFeature (wgpuAdapter, WGPUFeatureName_TextureCompressionETC2))
260- Features.push_back (WGPUFeatureName_TextureCompressionETC2);
247+ auto AddWGPUFeature = [wgpuAdapter, &wgpuFeatures](DEVICE_FEATURE_STATE FeatureState, WGPUFeatureName wgpuFeature) {
248+ if (FeatureState && wgpuAdapterHasFeature (wgpuAdapter, wgpuFeature))
249+ wgpuFeatures.push_back (wgpuFeature);
250+ };
261251
262- if (EngineCI.Features .ShaderFloat16 && wgpuAdapterHasFeature (wgpuAdapter, WGPUFeatureName_ShaderF16))
263- Features.push_back (WGPUFeatureName_ShaderF16);
252+ AddWGPUFeature (Features.DepthBiasClamp , WGPUFeatureName_DepthClipControl);
253+ AddWGPUFeature (Features.TimestampQueries , WGPUFeatureName_TimestampQuery);
254+ AddWGPUFeature (Features.DurationQueries , WGPUFeatureName_ChromiumExperimentalTimestampQueryInsidePasses);
255+ AddWGPUFeature (Features.TextureCompressionBC , WGPUFeatureName_TextureCompressionBC);
256+ AddWGPUFeature (Features.TextureCompressionETC2 , WGPUFeatureName_TextureCompressionETC2);
257+ AddWGPUFeature (Features.ShaderFloat16 , WGPUFeatureName_ShaderF16);
264258
265259 if (wgpuAdapterHasFeature (wgpuAdapter, WGPUFeatureName_Depth32FloatStencil8))
266- Features .push_back (WGPUFeatureName_Depth32FloatStencil8);
260+ wgpuFeatures .push_back (WGPUFeatureName_Depth32FloatStencil8);
267261
268262 if (wgpuAdapterHasFeature (wgpuAdapter, WGPUFeatureName_Float32Filterable))
269- Features .push_back (WGPUFeatureName_Float32Filterable);
263+ wgpuFeatures .push_back (WGPUFeatureName_Float32Filterable);
270264
271265 if (wgpuAdapterHasFeature (wgpuAdapter, WGPUFeatureName_IndirectFirstInstance))
272- Features .push_back (WGPUFeatureName_IndirectFirstInstance);
266+ wgpuFeatures .push_back (WGPUFeatureName_IndirectFirstInstance);
273267
274268 if (wgpuAdapterHasFeature (wgpuAdapter, WGPUFeatureName_RG11B10UfloatRenderable))
275- Features .push_back (WGPUFeatureName_RG11B10UfloatRenderable);
269+ wgpuFeatures .push_back (WGPUFeatureName_RG11B10UfloatRenderable);
276270
277271 if (wgpuAdapterHasFeature (wgpuAdapter, WGPUFeatureName_BGRA8UnormStorage))
278- Features .push_back (WGPUFeatureName_BGRA8UnormStorage);
272+ wgpuFeatures .push_back (WGPUFeatureName_BGRA8UnormStorage);
279273
280274 if (wgpuAdapterHasFeature (wgpuAdapter, WGPUFeatureName_Unorm16TextureFormats))
281- Features .push_back (WGPUFeatureName_Unorm16TextureFormats);
275+ wgpuFeatures .push_back (WGPUFeatureName_Unorm16TextureFormats);
282276
283277 if (wgpuAdapterHasFeature (wgpuAdapter, WGPUFeatureName_Snorm16TextureFormats))
284- Features .push_back (WGPUFeatureName_Snorm16TextureFormats);
278+ wgpuFeatures .push_back (WGPUFeatureName_Snorm16TextureFormats);
285279 }
286280
287281 struct CallbackUserData
@@ -320,8 +314,8 @@ WebGPUDeviceWrapper CreateDeviceForAdapter(EngineWebGPUCreateInfo const& EngineC
320314
321315 WGPUDeviceDescriptor DeviceDesc{};
322316 DeviceDesc.requiredLimits = &RequiredLimits;
323- DeviceDesc.requiredFeatureCount = Features .size ();
324- DeviceDesc.requiredFeatures = Features .data ();
317+ DeviceDesc.requiredFeatureCount = wgpuFeatures .size ();
318+ DeviceDesc.requiredFeatures = wgpuFeatures .data ();
325319#if PLATFORM_EMSCRIPTEN
326320 DeviceDesc.deviceLostCallback = DeviceLostCallback;
327321#else
@@ -340,7 +334,88 @@ WebGPUDeviceWrapper CreateDeviceForAdapter(EngineWebGPUCreateInfo const& EngineC
340334 return WebGPUDeviceWrapper{UserData.Device };
341335}
342336
343- GraphicsAdapterInfo GetGraphicsAdapterInfo (WGPUAdapter wgpuAdapter, WGPUDevice wgpuDevice = nullptr /* Hack for Emscripten*/ )
337+ bool FeatureSupported (WGPUAdapter wgpuAdapter, WGPUDevice wgpuDevice, WGPUFeatureName Feature)
338+ {
339+ if (wgpuAdapter != nullptr )
340+ {
341+ return wgpuAdapterHasFeature (wgpuAdapter, Feature);
342+ }
343+ else if (wgpuDevice != nullptr )
344+ {
345+ return wgpuDeviceHasFeature (wgpuDevice, Feature);
346+ }
347+ else
348+ {
349+ UNEXPECTED (" Either adapter or device must not be null" );
350+ return DEVICE_FEATURE_STATE_DISABLED;
351+ }
352+ }
353+
354+ DeviceFeatures GetSupportedFeatures (WGPUAdapter wgpuAdapter, WGPUDevice wgpuDevice = nullptr )
355+ {
356+ auto CheckFeature = [wgpuAdapter, wgpuDevice](WGPUFeatureName Feature) {
357+ return FeatureSupported (wgpuAdapter, wgpuDevice, Feature) ? DEVICE_FEATURE_STATE_ENABLED : DEVICE_FEATURE_STATE_DISABLED;
358+ };
359+
360+ DeviceFeatures Features;
361+ Features.SeparablePrograms = DEVICE_FEATURE_STATE_ENABLED;
362+ Features.ShaderResourceQueries = DEVICE_FEATURE_STATE_ENABLED;
363+ Features.WireframeFill = DEVICE_FEATURE_STATE_DISABLED;
364+ Features.MultithreadedResourceCreation = DEVICE_FEATURE_STATE_DISABLED;
365+ Features.ComputeShaders = DEVICE_FEATURE_STATE_ENABLED;
366+ Features.GeometryShaders = DEVICE_FEATURE_STATE_DISABLED;
367+ Features.Tessellation = DEVICE_FEATURE_STATE_DISABLED;
368+ Features.MeshShaders = DEVICE_FEATURE_STATE_DISABLED;
369+ Features.RayTracing = DEVICE_FEATURE_STATE_DISABLED;
370+ Features.BindlessResources = DEVICE_FEATURE_STATE_DISABLED;
371+ Features.OcclusionQueries = DEVICE_FEATURE_STATE_ENABLED;
372+ Features.BinaryOcclusionQueries = DEVICE_FEATURE_STATE_DISABLED;
373+ Features.PipelineStatisticsQueries = DEVICE_FEATURE_STATE_DISABLED;
374+ Features.DepthBiasClamp = DEVICE_FEATURE_STATE_ENABLED;
375+ Features.DepthClamp = CheckFeature (WGPUFeatureName_DepthClipControl);
376+ Features.IndependentBlend = DEVICE_FEATURE_STATE_ENABLED;
377+ Features.DualSourceBlend = CheckFeature (WGPUFeatureName_DualSourceBlending);
378+ Features.MultiViewport = DEVICE_FEATURE_STATE_DISABLED;
379+ Features.TextureCompressionBC = CheckFeature (WGPUFeatureName_TextureCompressionBC);
380+ Features.TextureCompressionETC2 = CheckFeature (WGPUFeatureName_TextureCompressionETC2);
381+ Features.VertexPipelineUAVWritesAndAtomics = DEVICE_FEATURE_STATE_ENABLED;
382+ Features.PixelUAVWritesAndAtomics = DEVICE_FEATURE_STATE_ENABLED;
383+ Features.TextureUAVExtendedFormats = DEVICE_FEATURE_STATE_ENABLED;
384+ Features.ShaderFloat16 = CheckFeature (WGPUFeatureName_ShaderF16);
385+ Features.ResourceBuffer16BitAccess = DEVICE_FEATURE_STATE_DISABLED;
386+ Features.UniformBuffer16BitAccess = DEVICE_FEATURE_STATE_DISABLED;
387+ Features.ShaderInputOutput16 = DEVICE_FEATURE_STATE_DISABLED;
388+ Features.ShaderInt8 = DEVICE_FEATURE_STATE_DISABLED;
389+ Features.ResourceBuffer8BitAccess = DEVICE_FEATURE_STATE_DISABLED;
390+ Features.UniformBuffer8BitAccess = DEVICE_FEATURE_STATE_DISABLED;
391+ Features.ShaderResourceStaticArrays = DEVICE_FEATURE_STATE_DISABLED;
392+ Features.ShaderResourceRuntimeArrays = DEVICE_FEATURE_STATE_DISABLED;
393+ Features.WaveOp = DEVICE_FEATURE_STATE_DISABLED;
394+ Features.InstanceDataStepRate = DEVICE_FEATURE_STATE_DISABLED;
395+ Features.NativeFence = DEVICE_FEATURE_STATE_DISABLED;
396+ Features.TileShaders = DEVICE_FEATURE_STATE_DISABLED;
397+ Features.TransferQueueTimestampQueries = DEVICE_FEATURE_STATE_DISABLED;
398+ Features.VariableRateShading = DEVICE_FEATURE_STATE_DISABLED;
399+ Features.SparseResources = DEVICE_FEATURE_STATE_DISABLED;
400+ Features.SubpassFramebufferFetch = DEVICE_FEATURE_STATE_DISABLED;
401+ Features.TextureComponentSwizzle = DEVICE_FEATURE_STATE_DISABLED;
402+ Features.TextureSubresourceViews = DEVICE_FEATURE_STATE_ENABLED;
403+ Features.NativeMultiDraw = DEVICE_FEATURE_STATE_DISABLED;
404+ Features.AsyncShaderCompilation = DEVICE_FEATURE_STATE_ENABLED;
405+ Features.FormattedBuffers = DEVICE_FEATURE_STATE_DISABLED;
406+
407+ Features.TimestampQueries = CheckFeature (WGPUFeatureName_TimestampQuery);
408+ Features.DurationQueries = Features.TimestampQueries ?
409+ CheckFeature (WGPUFeatureName_ChromiumExperimentalTimestampQueryInsidePasses) :
410+ DEVICE_FEATURE_STATE_DISABLED;
411+
412+ ASSERT_SIZEOF (DeviceFeatures, 47 , " Did you add a new feature to DeviceFeatures? Please handle its status here." );
413+
414+ return Features;
415+ }
416+
417+
418+ GraphicsAdapterInfo GetGraphicsAdapterInfo (WGPUAdapter wgpuAdapter, WGPUDevice wgpuDevice = nullptr )
344419{
345420 WGPUAdapterInfo wgpuAdapterInfo{};
346421 if (wgpuAdapter)
@@ -377,68 +452,7 @@ GraphicsAdapterInfo GetGraphicsAdapterInfo(WGPUAdapter wgpuAdapter, WGPUDevice w
377452 AdapterInfo.NumOutputs = 0 ;
378453 }
379454
380- auto CheckWebGPUFeature = [wgpuAdapter, wgpuDevice](WGPUFeatureName Feature) {
381- return ((wgpuAdapter != nullptr && wgpuAdapterHasFeature (wgpuAdapter, Feature)) ||
382- (wgpuDevice != nullptr && wgpuDeviceHasFeature (wgpuDevice, Feature))) ?
383- DEVICE_FEATURE_STATE_ENABLED :
384- DEVICE_FEATURE_STATE_DISABLED;
385- };
386-
387- // Enable features
388- {
389- DeviceFeatures& Features{AdapterInfo.Features };
390- Features.SeparablePrograms = DEVICE_FEATURE_STATE_ENABLED;
391- Features.ShaderResourceQueries = DEVICE_FEATURE_STATE_ENABLED;
392- Features.WireframeFill = DEVICE_FEATURE_STATE_DISABLED;
393- Features.MultithreadedResourceCreation = DEVICE_FEATURE_STATE_DISABLED;
394- Features.ComputeShaders = DEVICE_FEATURE_STATE_ENABLED;
395- Features.GeometryShaders = DEVICE_FEATURE_STATE_DISABLED;
396- Features.Tessellation = DEVICE_FEATURE_STATE_DISABLED;
397- Features.MeshShaders = DEVICE_FEATURE_STATE_DISABLED;
398- Features.RayTracing = DEVICE_FEATURE_STATE_DISABLED;
399- Features.BindlessResources = DEVICE_FEATURE_STATE_DISABLED;
400- Features.OcclusionQueries = DEVICE_FEATURE_STATE_ENABLED;
401- Features.BinaryOcclusionQueries = DEVICE_FEATURE_STATE_DISABLED;
402- Features.PipelineStatisticsQueries = DEVICE_FEATURE_STATE_DISABLED;
403- Features.DepthBiasClamp = DEVICE_FEATURE_STATE_ENABLED;
404- Features.DepthClamp = CheckWebGPUFeature (WGPUFeatureName_DepthClipControl);
405- Features.IndependentBlend = DEVICE_FEATURE_STATE_ENABLED;
406- Features.DualSourceBlend = CheckWebGPUFeature (WGPUFeatureName_DualSourceBlending);
407- Features.MultiViewport = DEVICE_FEATURE_STATE_DISABLED;
408- Features.TextureCompressionBC = CheckWebGPUFeature (WGPUFeatureName_TextureCompressionBC);
409- Features.TextureCompressionETC2 = CheckWebGPUFeature (WGPUFeatureName_TextureCompressionETC2);
410- Features.VertexPipelineUAVWritesAndAtomics = DEVICE_FEATURE_STATE_ENABLED;
411- Features.PixelUAVWritesAndAtomics = DEVICE_FEATURE_STATE_ENABLED;
412- Features.TextureUAVExtendedFormats = DEVICE_FEATURE_STATE_ENABLED;
413- Features.ShaderFloat16 = CheckWebGPUFeature (WGPUFeatureName_ShaderF16);
414- Features.ResourceBuffer16BitAccess = DEVICE_FEATURE_STATE_DISABLED;
415- Features.UniformBuffer16BitAccess = DEVICE_FEATURE_STATE_DISABLED;
416- Features.ShaderInputOutput16 = DEVICE_FEATURE_STATE_DISABLED;
417- Features.ShaderInt8 = DEVICE_FEATURE_STATE_DISABLED;
418- Features.ResourceBuffer8BitAccess = DEVICE_FEATURE_STATE_DISABLED;
419- Features.UniformBuffer8BitAccess = DEVICE_FEATURE_STATE_DISABLED;
420- Features.ShaderResourceStaticArrays = DEVICE_FEATURE_STATE_DISABLED;
421- Features.ShaderResourceRuntimeArrays = DEVICE_FEATURE_STATE_DISABLED;
422- Features.WaveOp = DEVICE_FEATURE_STATE_DISABLED;
423- Features.InstanceDataStepRate = DEVICE_FEATURE_STATE_DISABLED;
424- Features.NativeFence = DEVICE_FEATURE_STATE_DISABLED;
425- Features.TileShaders = DEVICE_FEATURE_STATE_DISABLED;
426- Features.TransferQueueTimestampQueries = DEVICE_FEATURE_STATE_DISABLED;
427- Features.VariableRateShading = DEVICE_FEATURE_STATE_DISABLED;
428- Features.SparseResources = DEVICE_FEATURE_STATE_DISABLED;
429- Features.SubpassFramebufferFetch = DEVICE_FEATURE_STATE_DISABLED;
430- Features.TextureComponentSwizzle = DEVICE_FEATURE_STATE_DISABLED;
431- Features.TextureSubresourceViews = DEVICE_FEATURE_STATE_ENABLED;
432- Features.NativeMultiDraw = DEVICE_FEATURE_STATE_DISABLED;
433- Features.AsyncShaderCompilation = DEVICE_FEATURE_STATE_ENABLED;
434- Features.FormattedBuffers = DEVICE_FEATURE_STATE_DISABLED;
435-
436- Features.TimestampQueries = CheckWebGPUFeature (WGPUFeatureName_TimestampQuery);
437- Features.DurationQueries = Features.TimestampQueries ?
438- CheckWebGPUFeature (WGPUFeatureName_ChromiumExperimentalTimestampQueryInsidePasses) :
439- DEVICE_FEATURE_STATE_DISABLED;
440- }
441- ASSERT_SIZEOF (DeviceFeatures, 47 , " Did you add a new feature to DeviceFeatures? Please handle its status here." );
455+ AdapterInfo.Features = GetSupportedFeatures (wgpuAdapter, wgpuDevice);
442456
443457 WGPUSupportedLimits wgpuSupportedLimits{};
444458 if (wgpuAdapter)
@@ -459,7 +473,7 @@ GraphicsAdapterInfo GetGraphicsAdapterInfo(WGPUAdapter wgpuAdapter, WGPUDevice w
459473 DrawCommandInfo.MaxDrawIndirectCount = ~0u ;
460474 DrawCommandInfo.CapFlags = DRAW_COMMAND_CAP_FLAG_DRAW_INDIRECT;
461475
462- if (CheckWebGPUFeature ( WGPUFeatureName_IndirectFirstInstance))
476+ if (FeatureSupported (wgpuAdapter, wgpuDevice, WGPUFeatureName_IndirectFirstInstance))
463477 DrawCommandInfo.CapFlags |= DRAW_COMMAND_CAP_FLAG_DRAW_INDIRECT_FIRST_INSTANCE;
464478 }
465479
@@ -581,7 +595,7 @@ void EngineFactoryWebGPUImpl::CreateDeviceAndContextsWebGPU(const EngineWebGPUCr
581595 SpecificAdapter = std::move (wgpuAdapters[0 ]);
582596 }
583597
584- WebGPUDeviceWrapper Device = CreateDeviceForAdapter (EngineCI, wgpuInstance. Get () , SpecificAdapter. Get () );
598+ WebGPUDeviceWrapper Device = CreateDeviceForAdapter (EngineCI. Features , wgpuInstance, SpecificAdapter);
585599 AttachToWebGPUDevice (wgpuInstance.Detach (), SpecificAdapter.Detach (), Device.Detach (), EngineCI, ppDevice, ppImmediateContext);
586600 }
587601 catch (const std::runtime_error&)
@@ -659,12 +673,23 @@ void EngineFactoryWebGPUImpl::AttachToWebGPUDevice(void*
659673 const GraphicsAdapterInfo AdapterInfo = GetGraphicsAdapterInfo (static_cast <WGPUAdapter>(wgpuAdapter), static_cast <WGPUDevice>(wgpuDevice));
660674 VerifyEngineCreateInfo (EngineCI, AdapterInfo);
661675
676+ const DeviceFeatures EnabledFeatures = GetSupportedFeatures (nullptr , static_cast <WGPUDevice>(wgpuDevice));
677+
662678 SetRawAllocator (EngineCI.pRawMemAllocator );
663679 IMemoryAllocator& RawMemAllocator = GetRawAllocator ();
664680
665681 RenderDeviceWebGPUImpl* pRenderDeviceWebGPU{
666682 NEW_RC_OBJ (RawMemAllocator, " RenderDeviceWebGPUImpl instance" , RenderDeviceWebGPUImpl)(
667- RawMemAllocator, this , EngineCI, AdapterInfo, static_cast <WGPUInstance>(wgpuInstance), static_cast <WGPUAdapter>(wgpuAdapter), static_cast <WGPUDevice>(wgpuDevice))};
683+ RenderDeviceWebGPUImpl::CreateInfo{
684+ RawMemAllocator,
685+ this ,
686+ EngineCI,
687+ AdapterInfo,
688+ EnabledFeatures,
689+ static_cast <WGPUInstance>(wgpuInstance),
690+ static_cast <WGPUAdapter>(wgpuAdapter),
691+ static_cast <WGPUDevice>(wgpuDevice),
692+ })};
668693 pRenderDeviceWebGPU->QueryInterface (IID_RenderDevice, reinterpret_cast <IObject**>(ppDevice));
669694
670695 DeviceContextWebGPUImpl* pDeviceContextWebGPU{
0 commit comments