Skip to content

Commit a1e7ac1

Browse files
WebGPU: Added support of multi view formats (close #587, close #612)
1 parent 43546a6 commit a1e7ac1

File tree

7 files changed

+152
-31
lines changed

7 files changed

+152
-31
lines changed

Graphics/GraphicsEngineWebGPU/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ set(INCLUDE
3636
include/WebGPUObjectWrappers.hpp
3737
include/WebGPUTypeConversions.hpp
3838
include/WebGPUResourceBase.hpp
39+
include/WebGPUStubs.hpp
3940
)
4041

4142
set(INTERFACE
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2024 Diligent Graphics LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* In no event and under no legal theory, whether in tort (including negligence),
17+
* contract, or otherwise, unless required by applicable law (such as deliberate
18+
* and grossly negligent acts) or agreed to in writing, shall any Contributor be
19+
* liable for any damages, including any direct, indirect, special, incidental,
20+
* or consequential damages of any character arising as a result of this License or
21+
* out of the use or inability to use the software (including but not limited to damages
22+
* for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23+
* all other commercial damages or losses), even if such Contributor has been advised
24+
* of the possibility of such damages.
25+
*/
26+
27+
#pragma once
28+
29+
#if PLATFORM_EMSCRIPTEN
30+
31+
inline constexpr WGPUFeatureName WGPUFeatureName_ChromiumExperimentalTimestampQueryInsidePasses = static_cast<WGPUFeatureName>(0x000003EE);
32+
33+
inline constexpr WGPUFeatureName WGPUFeatureName_Unorm16TextureFormats = static_cast<WGPUFeatureName>(0x000003FB);
34+
35+
inline constexpr WGPUFeatureName WGPUFeatureName_Snorm16TextureFormats = static_cast<WGPUFeatureName>(0x000003FC);
36+
37+
inline constexpr WGPUTextureFormat WGPUTextureFormat_R16Unorm = static_cast<WGPUTextureFormat>(0x00000060);
38+
39+
inline constexpr WGPUTextureFormat WGPUTextureFormat_R16Snorm = static_cast<WGPUTextureFormat>(0x00000063);
40+
41+
inline constexpr WGPUTextureFormat WGPUTextureFormat_RG16Unorm = static_cast<WGPUTextureFormat>(0x00000061);
42+
43+
inline constexpr WGPUTextureFormat WGPUTextureFormat_RG16Snorm = static_cast<WGPUTextureFormat>(0x00000064);
44+
45+
inline constexpr WGPUTextureFormat WGPUTextureFormat_RGBA16Unorm = static_cast<WGPUTextureFormat>(0x00000062);
46+
47+
inline constexpr WGPUTextureFormat WGPUTextureFormat_RGBA16Snorm = static_cast<WGPUTextureFormat>(0x00000065);
48+
49+
#endif

Graphics/GraphicsEngineWebGPU/src/EngineFactoryWebGPU.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "ShaderResourceCacheWebGPU.hpp"
3636
#include "FenceWebGPUImpl.hpp"
3737
#include "DearchiverWebGPUImpl.hpp"
38+
#include "WebGPUStubs.hpp"
3839

3940
#include "StringTools.hpp"
4041
#include "GraphicsAccessories.hpp"
@@ -47,6 +48,7 @@
4748
# include <emscripten.h>
4849
#endif
4950

51+
5052
namespace Diligent
5153
{
5254

@@ -195,9 +197,8 @@ WebGPUDeviceWrapper CreateDeviceForAdapter(EngineWebGPUCreateInfo const& EngineC
195197
if (EngineCI.Features.TimestampQueries && wgpuAdapterHasFeature(wgpuAdapter, WGPUFeatureName_TimestampQuery))
196198
Features.push_back(WGPUFeatureName_TimestampQuery);
197199

198-
// WGPUFeatureName_ChromiumExperimentalTimestampQueryInsidePasses = 0x000003EE,
199-
if (EngineCI.Features.TimestampQueries && wgpuAdapterHasFeature(wgpuAdapter, static_cast<WGPUFeatureName>(0x000003EE)))
200-
Features.push_back(static_cast<WGPUFeatureName>(0x000003EE));
200+
if (EngineCI.Features.TimestampQueries && wgpuAdapterHasFeature(wgpuAdapter, WGPUFeatureName_ChromiumExperimentalTimestampQueryInsidePasses))
201+
Features.push_back(WGPUFeatureName_ChromiumExperimentalTimestampQueryInsidePasses);
201202

202203
if (EngineCI.Features.TextureCompressionBC && wgpuAdapterHasFeature(wgpuAdapter, WGPUFeatureName_TextureCompressionBC))
203204
Features.push_back(WGPUFeatureName_TextureCompressionBC);
@@ -219,6 +220,12 @@ WebGPUDeviceWrapper CreateDeviceForAdapter(EngineWebGPUCreateInfo const& EngineC
219220

220221
if (wgpuAdapterHasFeature(wgpuAdapter, WGPUFeatureName_BGRA8UnormStorage))
221222
Features.push_back(WGPUFeatureName_BGRA8UnormStorage);
223+
224+
if (wgpuAdapterHasFeature(wgpuAdapter, WGPUFeatureName_Unorm16TextureFormats))
225+
Features.push_back(WGPUFeatureName_Unorm16TextureFormats);
226+
227+
if (wgpuAdapterHasFeature(wgpuAdapter, WGPUFeatureName_Snorm16TextureFormats))
228+
Features.push_back(WGPUFeatureName_Snorm16TextureFormats);
222229
}
223230

224231
struct CallbackUserData

Graphics/GraphicsEngineWebGPU/src/GenerateMipsHelperWebGPU.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,7 @@ void GenerateMipsHelperWebGPU::GenerateMips(WGPUCommandEncoder wgpuCmdEncoder, D
711711
VERIFY_EXPR(m_DeviceWebGPU.GetNumImmediateContexts() == 1);
712712

713713
InitializeSampler();
714-
pDeviceContext->EndCommandEncoders(DeviceContextWebGPUImpl::COMMAND_ENCODER_FLAG_ALL & ~DeviceContextWebGPUImpl::COMMAND_ENCODER_FLAG_RENDER);
714+
pDeviceContext->EndCommandEncoders(DeviceContextWebGPUImpl::COMMAND_ENCODER_FLAG_ALL);
715715

716716
const auto& ViewDesc = pTexView->GetDesc();
717717

Graphics/GraphicsEngineWebGPU/src/RenderDeviceWebGPUImpl.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "FenceWebGPUImpl.hpp"
4343
#include "QueryWebGPUImpl.hpp"
4444
#include "AttachmentCleanerWebGPU.hpp"
45+
#include "WebGPUStubs.hpp"
4546

4647
#if !DILIGENT_NO_GLSLANG
4748
# include "GLSLangUtils.hpp"
@@ -421,6 +422,8 @@ void RenderDeviceWebGPUImpl::FindSupportedTextureFormats()
421422
const bool RG11B10UfloatRenderableSupported = wgpuDeviceHasFeature(m_wgpuDevice, WGPUFeatureName_RG11B10UfloatRenderable);
422423
const bool Depth32FloatStencil8Supported = wgpuDeviceHasFeature(m_wgpuDevice, WGPUFeatureName_Depth32FloatStencil8);
423424
const bool TextureCompressionBCSupported = wgpuDeviceHasFeature(m_wgpuDevice, WGPUFeatureName_TextureCompressionBC);
425+
const bool R16UnormSupported = wgpuDeviceHasFeature(m_wgpuDevice, WGPUFeatureName_Unorm16TextureFormats);
426+
const bool R16SnormSupported = wgpuDeviceHasFeature(m_wgpuDevice, WGPUFeatureName_Snorm16TextureFormats);
424427

425428
// https://www.w3.org/TR/webgpu/#texture-format-caps
426429

@@ -456,7 +459,7 @@ void RenderDeviceWebGPUImpl::FindSupportedTextureFormats()
456459
SetTexFormatInfo({TEX_FORMAT_R32_FLOAT}, BIND_SRU, Float32FilterableSupported ? FMT_FLAG_FILTER | FMT_FLAG_MSAA : FMT_FLAG_MSAA);
457460

458461
SetTexFormatInfo({TEX_FORMAT_RG32_UINT, TEX_FORMAT_RG32_SINT, TEX_FORMAT_RG32_TYPELESS}, BIND_SRU, FMT_FLAG_NONE);
459-
SetTexFormatInfo({TEX_FORMAT_RG32_FLOAT}, BIND_SR, Float32FilterableSupported ? FMT_FLAG_FILTER : FMT_FLAG_NONE);
462+
SetTexFormatInfo({TEX_FORMAT_RG32_FLOAT}, BIND_SRU, Float32FilterableSupported ? FMT_FLAG_FILTER : FMT_FLAG_NONE);
460463

461464
SetTexFormatInfo({TEX_FORMAT_RGBA32_UINT, TEX_FORMAT_RGBA32_SINT, TEX_FORMAT_RGBA32_TYPELESS}, BIND_SRU, FMT_FLAG_NONE);
462465
SetTexFormatInfo({TEX_FORMAT_RGBA32_FLOAT}, BIND_SRU, Float32FilterableSupported ? FMT_FLAG_FILTER : FMT_FLAG_NONE);
@@ -502,6 +505,20 @@ void RenderDeviceWebGPUImpl::FindSupportedTextureFormats()
502505
TEX_FORMAT_BC7_UNORM_SRGB},
503506
BIND_S, FMT_FLAG_FILTER);
504507
}
508+
509+
if (R16UnormSupported)
510+
{
511+
SetTexFormatInfo({TEX_FORMAT_R16_UNORM}, BIND_SR, FMT_FLAG_FILTER | FMT_FLAG_MSAA);
512+
SetTexFormatInfo({TEX_FORMAT_RG16_UNORM}, BIND_SR, FMT_FLAG_FILTER | FMT_FLAG_MSAA);
513+
SetTexFormatInfo({TEX_FORMAT_RGBA16_UNORM}, BIND_SR, FMT_FLAG_FILTER | FMT_FLAG_MSAA);
514+
}
515+
516+
if (R16SnormSupported)
517+
{
518+
SetTexFormatInfo({TEX_FORMAT_R16_SNORM}, BIND_SR, FMT_FLAG_FILTER | FMT_FLAG_MSAA);
519+
SetTexFormatInfo({TEX_FORMAT_RG16_SNORM}, BIND_SR, FMT_FLAG_FILTER | FMT_FLAG_MSAA);
520+
SetTexFormatInfo({TEX_FORMAT_RGBA16_SNORM}, BIND_SR, FMT_FLAG_FILTER | FMT_FLAG_MSAA);
521+
}
505522
}
506523

507524
} // namespace Diligent

Graphics/GraphicsEngineWebGPU/src/TextureWebGPUImpl.cpp

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@ namespace Diligent
3838
namespace
3939
{
4040

41-
WGPUTextureDescriptor TextureDescToWGPUTextureDescriptor(const TextureDesc& Desc,
42-
RenderDeviceWebGPUImpl* pRenderDevice) noexcept
41+
WGPUTextureDescriptor TextureDescToWGPUTextureDescriptor(const TextureDesc& Desc,
42+
RenderDeviceWebGPUImpl* pRenderDevice,
43+
std::vector<WGPUTextureFormat>& TextureViewFormats) noexcept
4344
{
4445
WGPUTextureDescriptor wgpuTextureDesc{};
4546

@@ -48,7 +49,7 @@ WGPUTextureDescriptor TextureDescToWGPUTextureDescriptor(const TextureDesc&
4849
if (Desc.Type == RESOURCE_DIM_TEX_CUBE_ARRAY)
4950
DEV_CHECK_ERR(Desc.ArraySize % 6 == 0, "Cube texture arrays are expected to have a number of array slices that is a multiple of 6");
5051

51-
const auto& FmtInfo = pRenderDevice->GetTextureFormatInfoExt(SRGBFormatToUnorm(Desc.Format));
52+
const TextureFormatInfoExt& FmtInfo = pRenderDevice->GetTextureFormatInfoExt(SRGBFormatToUnorm(Desc.Format));
5253

5354
if (Desc.IsArray())
5455
wgpuTextureDesc.size.depthOrArrayLayers = Desc.ArraySize;
@@ -86,16 +87,53 @@ WGPUTextureDescriptor TextureDescToWGPUTextureDescriptor(const TextureDesc&
8687
LOG_ERROR_AND_THROW("Automatic mipmap generation isn't supported for ", GetTextureFormatAttribs(Desc.Format).Name, " as the format doesn't support linear filtering");
8788
}
8889

89-
if (IsSRGBFormat(Desc.Format) && wgpuTextureDesc.usage & WGPUTextureUsage_StorageBinding)
90-
wgpuTextureDesc.format = TextureFormatToWGPUFormat(SRGBFormatToUnorm(Desc.Format));
91-
else
92-
wgpuTextureDesc.format = TextureFormatToWGPUFormat(Desc.Format);
90+
const TextureFormatAttribs& FmtAttribs = GetTextureFormatAttribs(Desc.Format);
91+
92+
std::unordered_set<TEXTURE_FORMAT> ViewFormatSet;
93+
if (FmtAttribs.IsTypeless)
94+
{
95+
auto InsertViewFormat = [&](TEXTURE_VIEW_TYPE ViewType) {
96+
TEXTURE_FORMAT Format = GetDefaultTextureViewFormat(Desc, ViewType);
97+
ViewFormatSet.insert(Format);
98+
if (ViewType == TEXTURE_VIEW_RENDER_TARGET || ViewType == TEXTURE_VIEW_SHADER_RESOURCE)
99+
ViewFormatSet.insert(UnormFormatToSRGB(Format));
100+
};
101+
102+
if (Desc.BindFlags & BIND_DEPTH_STENCIL)
103+
LOG_ERROR_AND_THROW("Depth-stencil textures must have a specific format and cannot be typeless in WebGPU");
104+
if (Desc.BindFlags & BIND_UNORDERED_ACCESS)
105+
InsertViewFormat(TEXTURE_VIEW_UNORDERED_ACCESS);
106+
if (Desc.BindFlags & BIND_RENDER_TARGET)
107+
InsertViewFormat(TEXTURE_VIEW_RENDER_TARGET);
108+
if (Desc.BindFlags & BIND_SHADER_RESOURCE)
109+
InsertViewFormat(TEXTURE_VIEW_SHADER_RESOURCE);
110+
}
111+
112+
const bool IsSRGBWithMipsAndStorageBinding =
113+
IsSRGBFormat(Desc.Format) &&
114+
(Desc.MiscFlags & MISC_TEXTURE_FLAG_GENERATE_MIPS) &&
115+
(wgpuTextureDesc.usage & WGPUTextureUsage_StorageBinding);
93116

94-
wgpuTextureDesc.mipLevelCount = Desc.MipLevels;
95-
wgpuTextureDesc.sampleCount = Desc.SampleCount;
96-
wgpuTextureDesc.size.width = Desc.GetWidth();
97-
wgpuTextureDesc.size.height = Desc.GetHeight();
98-
wgpuTextureDesc.label = Desc.Name;
117+
wgpuTextureDesc.format = IsSRGBWithMipsAndStorageBinding ?
118+
TextureFormatToWGPUFormat(SRGBFormatToUnorm(Desc.Format)) :
119+
TextureFormatToWGPUFormat(Desc.Format);
120+
121+
if (IsSRGBWithMipsAndStorageBinding)
122+
{
123+
ViewFormatSet.insert(Desc.Format);
124+
ViewFormatSet.insert(SRGBFormatToUnorm(Desc.Format));
125+
}
126+
127+
for (const auto& TextureViewFmt : ViewFormatSet)
128+
TextureViewFormats.push_back(TextureFormatToWGPUFormat(TextureViewFmt));
129+
130+
wgpuTextureDesc.viewFormats = TextureViewFormats.data();
131+
wgpuTextureDesc.viewFormatCount = TextureViewFormats.size();
132+
wgpuTextureDesc.mipLevelCount = Desc.MipLevels;
133+
wgpuTextureDesc.sampleCount = Desc.SampleCount;
134+
wgpuTextureDesc.size.width = Desc.GetWidth();
135+
wgpuTextureDesc.size.height = Desc.GetHeight();
136+
wgpuTextureDesc.label = Desc.Name;
99137

100138
return wgpuTextureDesc;
101139
}
@@ -120,6 +158,8 @@ WGPUTextureViewDescriptor TextureViewDescToWGPUTextureViewDescriptor(const Textu
120158
wgpuTextureViewDesc.dimension = ResourceDimensionToWGPUTextureViewDimension(ViewDesc.TextureDim);
121159
wgpuTextureViewDesc.baseMipLevel = ViewDesc.MostDetailedMip;
122160
wgpuTextureViewDesc.mipLevelCount = ViewDesc.NumMipLevels;
161+
if (!(TexDesc.BindFlags & BIND_DEPTH_STENCIL))
162+
wgpuTextureViewDesc.format = TextureFormatToWGPUFormat(ViewDesc.Format);
123163

124164
if (IsTextureArray(ViewDesc))
125165
{
@@ -133,7 +173,6 @@ WGPUTextureViewDescriptor TextureViewDescToWGPUTextureViewDescriptor(const Textu
133173
}
134174

135175
const TextureFormatAttribs& FmtAttribs = GetTextureFormatAttribs(ViewDesc.Format);
136-
137176
if (ViewDesc.ViewType == TEXTURE_VIEW_DEPTH_STENCIL || ViewDesc.ViewType == TEXTURE_VIEW_READ_ONLY_DEPTH_STENCIL)
138177
{
139178
if (FmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH)
@@ -263,7 +302,8 @@ TextureWebGPUImpl::TextureWebGPUImpl(IReferenceCounters* pRefCounters,
263302

264303
if (m_Desc.Usage == USAGE_IMMUTABLE || m_Desc.Usage == USAGE_DEFAULT || m_Desc.Usage == USAGE_DYNAMIC)
265304
{
266-
WGPUTextureDescriptor wgpuTextureDesc = TextureDescToWGPUTextureDescriptor(m_Desc, pDevice);
305+
std::vector<WGPUTextureFormat> TextureViewFormats;
306+
WGPUTextureDescriptor wgpuTextureDesc = TextureDescToWGPUTextureDescriptor(m_Desc, pDevice, TextureViewFormats);
267307
m_wgpuTexture.Reset(wgpuDeviceCreateTexture(pDevice->GetWebGPUDevice(), &wgpuTextureDesc));
268308
if (!m_wgpuTexture)
269309
LOG_ERROR_AND_THROW("Failed to create WebGPU texture ", " '", m_Desc.Name ? m_Desc.Name : "", '\'');

0 commit comments

Comments
 (0)