@@ -41,6 +41,13 @@ namespace Diligent
4141namespace
4242{
4343
44+ struct ShaderConstants
45+ {
46+ Uint32 NumMipLevels;
47+ Uint32 FirstArraySlice;
48+ float TexelSize[2 ];
49+ };
50+
4451constexpr char ShaderSourceVS[] = R"(
4552struct VertexOutput
4653{
@@ -357,7 +364,7 @@ void GenerateMipsHelperWebGPU::InitializeConstantBuffer()
357364 // Rework when push constants will be available https://github.com/gpuweb/gpuweb/pull/4612 in WebGPU
358365 BufferDesc CBDesc;
359366 CBDesc.Name = " GenerateMipsHelperWebGPU::ConstantBuffer" ;
360- CBDesc.Size = SizeofUniformBuffer ;
367+ CBDesc.Size = sizeof (ShaderConstants) ;
361368 CBDesc.Usage = USAGE_DYNAMIC;
362369 CBDesc.BindFlags = BIND_UNIFORM_BUFFER;
363370 CBDesc.CPUAccessFlags = CPU_ACCESS_WRITE;
@@ -413,66 +420,43 @@ void GenerateMipsHelperWebGPU::InitializePlaceholderTextures()
413420
414421WebGPUShaderModuleWrapper& GenerateMipsHelperWebGPU::GetShaderModule (const UAVFormats& Formats, SHADER_TYPE ShaderType)
415422{
416- auto ReplaceTemplateFormatInsideWGSL = [](std::string& WGSL, const UAVFormats& TexFmts) {
417- for (Uint32 UAVIndex = 0 ; UAVIndex < TexFmts.size (); UAVIndex++)
418- {
419- WGPUTextureFormat wgpuTexFmt = TextureFormatToWGPUFormat (SRGBFormatToUnorm (TexFmts[UAVIndex]));
420- ReplaceTemplateInString (WGSL, " ${UAV_FORMAT_" + std::to_string (UAVIndex) + " }" , ConvertWebGPUFormatToString (wgpuTexFmt));
421- }
422- };
423-
424423 auto Iter = m_ShaderModuleCache.find ({Formats, ShaderType});
425424 if (Iter != m_ShaderModuleCache.end ())
426425 return Iter->second ;
427426
428- WebGPUShaderModuleWrapper wgpuShaderModule{};
427+ std::string WGSL;
428+ WGPUShaderModuleWGSLDescriptor wgpuShaderCodeDesc{};
429+ wgpuShaderCodeDesc.chain .sType = WGPUSType_ShaderModuleWGSLDescriptor;
429430
430- if (ShaderType == SHADER_TYPE_COMPUTE )
431+ switch (ShaderType)
431432 {
432- std::string WGSL{ShaderSourceCS};
433- ReplaceTemplateFormatInsideWGSL (WGSL, Formats);
433+ case SHADER_TYPE_COMPUTE:
434+ WGSL = ShaderSourceCS;
435+ // Replace template formats
436+ for (Uint32 UAVIndex = 0 ; UAVIndex < Formats.size (); UAVIndex++)
437+ {
438+ WGPUTextureFormat wgpuTexFmt = TextureFormatToWGPUFormat (SRGBFormatToUnorm (Formats[UAVIndex]));
439+ ReplaceTemplateInString (WGSL, " ${UAV_FORMAT_" + std::to_string (UAVIndex) + " }" , ConvertWebGPUFormatToString (wgpuTexFmt));
440+ }
441+ wgpuShaderCodeDesc.code = WGSL.c_str ();
442+ break ;
434443
435- WGPUShaderModuleWGSLDescriptor wgpuShaderCodeDesc{};
436- wgpuShaderCodeDesc.chain . sType = WGPUSType_ShaderModuleWGSLDescriptor ;
437- wgpuShaderCodeDesc. code = WGSL. c_str () ;
444+ case SHADER_TYPE_VERTEX:
445+ wgpuShaderCodeDesc.code = ShaderSourceVS ;
446+ break ;
438447
439- WGPUShaderModuleDescriptor wgpuShaderModuleDesc{};
440- wgpuShaderModuleDesc.nextInChain = reinterpret_cast <WGPUChainedStruct*>(&wgpuShaderCodeDesc);
448+ case SHADER_TYPE_PIXEL:
449+ wgpuShaderCodeDesc.code = ShaderSourcePS;
450+ break ;
441451
442- wgpuShaderModule.Reset (wgpuDeviceCreateShaderModule (m_DeviceWebGPU.GetWebGPUDevice (), &wgpuShaderModuleDesc));
443- if (!wgpuShaderModule)
444- LOG_ERROR_AND_THROW (" Failed to create mip generation shader module" );
452+ default :
453+ UNEXPECTED (" Unexpected shader type" );
445454 }
446- else if (ShaderType == SHADER_TYPE_VERTEX)
447- {
448- WGPUShaderModuleWGSLDescriptor wgpuShaderCodeDesc{};
449- wgpuShaderCodeDesc.chain .sType = WGPUSType_ShaderModuleWGSLDescriptor;
450- wgpuShaderCodeDesc.code = ShaderSourceVS;
451455
452- WGPUShaderModuleDescriptor wgpuShaderModuleDesc{};
453- wgpuShaderModuleDesc.nextInChain = reinterpret_cast <WGPUChainedStruct*>(&wgpuShaderCodeDesc);
454-
455- wgpuShaderModule.Reset (wgpuDeviceCreateShaderModule (m_DeviceWebGPU.GetWebGPUDevice (), &wgpuShaderModuleDesc));
456- if (!wgpuShaderModule)
457- LOG_ERROR_AND_THROW (" Failed to create mip generation shader module" );
458- }
459- else if (ShaderType == SHADER_TYPE_PIXEL)
460- {
461- WGPUShaderModuleWGSLDescriptor wgpuShaderCodeDesc{};
462- wgpuShaderCodeDesc.chain .sType = WGPUSType_ShaderModuleWGSLDescriptor;
463- wgpuShaderCodeDesc.code = ShaderSourcePS;
464-
465- WGPUShaderModuleDescriptor wgpuShaderModuleDesc{};
466- wgpuShaderModuleDesc.nextInChain = reinterpret_cast <WGPUChainedStruct*>(&wgpuShaderCodeDesc);
467-
468- wgpuShaderModule.Reset (wgpuDeviceCreateShaderModule (m_DeviceWebGPU.GetWebGPUDevice (), &wgpuShaderModuleDesc));
469- if (!wgpuShaderModule)
470- LOG_ERROR_AND_THROW (" Failed to create mip generation shader module" );
471- }
472- else
473- {
474- UNEXPECTED (" Unexpected shader type" );
475- }
456+ WGPUShaderModuleDescriptor wgpuShaderModuleDesc{};
457+ wgpuShaderModuleDesc.nextInChain = reinterpret_cast <WGPUChainedStruct*>(&wgpuShaderCodeDesc);
458+ WebGPUShaderModuleWrapper wgpuShaderModule{wgpuDeviceCreateShaderModule (m_DeviceWebGPU.GetWebGPUDevice (), &wgpuShaderModuleDesc)};
459+ VERIFY (wgpuShaderModule, " Failed to create mip generation shader module" );
476460
477461 auto Condition = m_ShaderModuleCache.emplace (ShaderModuleCacheKey{Formats, ShaderType}, std::move (wgpuShaderModule));
478462 return Condition.first ->second ;
@@ -529,15 +513,13 @@ GenerateMipsHelperWebGPU::ComputePipelineGroupLayout& GenerateMipsHelperWebGPU::
529513 wgpuBindGroupLayoutDesc.entryCount = _countof (wgpuBindGroupLayoutEntries);
530514 wgpuBindGroupLayoutDesc.entries = wgpuBindGroupLayoutEntries;
531515 WebGPUBindGroupLayoutWrapper wgpuBindGroupLayout{wgpuDeviceCreateBindGroupLayout (m_DeviceWebGPU.GetWebGPUDevice (), &wgpuBindGroupLayoutDesc)};
532- if (!wgpuBindGroupLayout)
533- LOG_ERROR_AND_THROW (" Failed to create mip generation bind group layout" );
516+ VERIFY (wgpuBindGroupLayout, " Failed to create mip generation bind group layout" );
534517
535518 WGPUPipelineLayoutDescriptor wgpuPipelineLayoutDesc{};
536519 wgpuPipelineLayoutDesc.bindGroupLayoutCount = 1 ;
537520 wgpuPipelineLayoutDesc.bindGroupLayouts = &wgpuBindGroupLayout.Get ();
538521 WebGPUPipelineLayoutWrapper wgpuPipelineLayout{wgpuDeviceCreatePipelineLayout (m_DeviceWebGPU.GetWebGPUDevice (), &wgpuPipelineLayoutDesc)};
539- if (!wgpuPipelineLayout)
540- LOG_ERROR_AND_THROW (" Failed to create mip generation pipeline layout" );
522+ VERIFY (wgpuPipelineLayout, " Failed to create mip generation pipeline layout" );
541523
542524 WGPUConstantEntry wgpuContants[] = {
543525 WGPUConstantEntry{nullptr , " CONVERT_TO_SRGB" , static_cast <double >(IsSRGBFormat (Formats[0 ]))},
@@ -550,8 +532,7 @@ GenerateMipsHelperWebGPU::ComputePipelineGroupLayout& GenerateMipsHelperWebGPU::
550532 wgpuComputePipelineDesc.compute .constants = wgpuContants;
551533 wgpuComputePipelineDesc.compute .constantCount = _countof (wgpuContants);
552534 WebGPUComputePipelineWrapper wgpuComputePipeline{wgpuDeviceCreateComputePipeline (m_DeviceWebGPU.GetWebGPUDevice (), &wgpuComputePipelineDesc)};
553- if (!wgpuComputePipeline)
554- LOG_ERROR_AND_THROW (" Failed to create mip generation compute pipeline" );
535+ VERIFY (wgpuComputePipeline, " Failed to create mip generation compute pipeline" );
555536
556537 auto Condition = m_ComputePipelineLayoutCache.emplace (ComputePipelineHashKey{Formats, PowerOfTwo}, std::make_pair (std::move (wgpuComputePipeline), std::move (wgpuBindGroupLayout)));
557538 return Condition.first ->second ;
@@ -578,15 +559,13 @@ GenerateMipsHelperWebGPU::RenderPipelineGroupLayout& GenerateMipsHelperWebGPU::G
578559 wgpuBindGroupLayoutDesc.entryCount = _countof (wgpuBindGroupLayoutEntries);
579560 wgpuBindGroupLayoutDesc.entries = wgpuBindGroupLayoutEntries;
580561 WebGPUBindGroupLayoutWrapper wgpuBindGroupLayout{wgpuDeviceCreateBindGroupLayout (m_DeviceWebGPU.GetWebGPUDevice (), &wgpuBindGroupLayoutDesc)};
581- if (!wgpuBindGroupLayout)
582- LOG_ERROR_AND_THROW (" Failed to create mip generation bind group layout" );
562+ VERIFY (wgpuBindGroupLayout, " Failed to create mip generation bind group layout" );
583563
584564 WGPUPipelineLayoutDescriptor wgpuPipelineLayoutDesc{};
585565 wgpuPipelineLayoutDesc.bindGroupLayoutCount = 1 ;
586566 wgpuPipelineLayoutDesc.bindGroupLayouts = &wgpuBindGroupLayout.Get ();
587567 WebGPUPipelineLayoutWrapper wgpuPipelineLayout{wgpuDeviceCreatePipelineLayout (m_DeviceWebGPU.GetWebGPUDevice (), &wgpuPipelineLayoutDesc)};
588- if (!wgpuPipelineLayout)
589- LOG_ERROR_AND_THROW (" Failed to create mip generation pipeline layout" );
568+ VERIFY (wgpuPipelineLayout, " Failed to create mip generation pipeline layout" );
590569
591570 WGPUColorTargetState wgpuColorTargets[1 ]{};
592571 wgpuColorTargets[0 ].writeMask = WGPUColorWriteMask_All;
@@ -609,8 +588,7 @@ GenerateMipsHelperWebGPU::RenderPipelineGroupLayout& GenerateMipsHelperWebGPU::G
609588 wgpuRenderPipelineDesc.multisample .mask = 0xFFFFFFFF ;
610589
611590 WebGPURenderPipelineWrapper wgpuRenderPipeline{wgpuDeviceCreateRenderPipeline (m_DeviceWebGPU.GetWebGPUDevice (), &wgpuRenderPipelineDesc)};
612- if (!wgpuRenderPipeline)
613- LOG_ERROR_AND_THROW (" Failed to create mip generation render pipeline" );
591+ VERIFY (wgpuRenderPipeline, " Failed to create mip generation render pipeline" );
614592
615593 auto Condition = m_RenderPipelineLayoutCache.emplace (RenderPipelineHashKey{Format}, std::make_pair (std::move (wgpuRenderPipeline), std::move (wgpuBindGroupLayout)));
616594 return Condition.first ->second ;
@@ -624,24 +602,9 @@ void GenerateMipsHelperWebGPU::GenerateMips(WGPUComputePassEncoder wgpuCmdEncode
624602 InitializeSampler ();
625603 InitializePlaceholderTextures ();
626604
627- auto * pTextureImpl = pTexView->GetTexture <TextureWebGPUImpl>();
628- const auto & TexDesc = pTextureImpl->GetDesc ();
629- const auto & ViewDesc = pTexView->GetDesc ();
630-
631- auto UpdateUniformBuffer = [&](Uint32 TopMip, Uint32 NumMips, Uint32 DstWidth, Uint32 DstHeight) {
632- struct
633- {
634- Uint32 NumMipLevels;
635- Uint32 FirstArraySlice;
636- float TexelSize[2 ];
637- } BufferData{TopMip, 0 , {1 .0f / static_cast <float >(DstWidth), 1 .0f / static_cast <float >(DstHeight)}};
638- static_assert (sizeof (BufferData) == SizeofUniformBuffer);
639-
640- void * pMappedData = nullptr ;
641- pDeviceContext->MapBuffer (m_pBuffer, MAP_WRITE, MAP_FLAG_DISCARD, pMappedData);
642- memcpy (pMappedData, &BufferData, SizeofUniformBuffer);
643- pDeviceContext->UnmapBuffer (m_pBuffer, MAP_WRITE);
644- };
605+ TextureWebGPUImpl* pTextureImpl = pTexView->GetTexture <TextureWebGPUImpl>();
606+ const TextureDesc& TexDesc = pTextureImpl->GetDesc ();
607+ const TextureViewDesc& ViewDesc = pTexView->GetDesc ();
645608
646609 Uint32 BottomMip = ViewDesc.NumMipLevels - 1u ;
647610 for (Uint32 TopMip = 0 ; TopMip < BottomMip;)
@@ -661,10 +624,17 @@ void GenerateMipsHelperWebGPU::GenerateMips(WGPUComputePassEncoder wgpuCmdEncode
661624 if (TopMip + NumMips > BottomMip)
662625 NumMips = BottomMip - TopMip;
663626
664- UpdateUniformBuffer (TopMip, NumMips, DstWidth, DstHeight);
627+ {
628+ ShaderConstants BufferData{TopMip, 0 , {1 .0f / static_cast <float >(DstWidth), 1 .0f / static_cast <float >(DstHeight)}};
629+
630+ void * pMappedData = nullptr ;
631+ pDeviceContext->MapBuffer (m_pBuffer, MAP_WRITE, MAP_FLAG_DISCARD, pMappedData);
632+ memcpy (pMappedData, &BufferData, sizeof (BufferData));
633+ pDeviceContext->UnmapBuffer (m_pBuffer, MAP_WRITE);
634+ }
665635
666- const auto * pBufferImpl = ClassPtrCast<BufferWebGPUImpl>(m_pBuffer.RawPtr ());
667- const auto * pSamplerImpl = ClassPtrCast<SamplerWebGPUImpl>(m_pSampler.RawPtr ());
636+ const BufferWebGPUImpl* pBufferImpl = ClassPtrCast<BufferWebGPUImpl>(m_pBuffer.RawPtr ());
637+ const SamplerWebGPUImpl * pSamplerImpl = ClassPtrCast<SamplerWebGPUImpl>(m_pSampler.RawPtr ());
668638
669639 WGPUBindGroupEntry wgpuBindGroupEntries[7 ]{};
670640 wgpuBindGroupEntries[0 ].binding = 0 ;
0 commit comments