From 24be4a38d0bb76aa14bafb714816a831abdbbf82 Mon Sep 17 00:00:00 2001 From: Hugo Amnov Date: Wed, 21 Apr 2021 05:18:49 +0200 Subject: [PATCH] WebGPU: Add texture format to shaderc (bin version 10) + streamline storage Images in shaders (#2482) * WebGPU: Add texture format (shaderc bin version 10) * WebGPU: Simplify storage images + Fix format decorations * Shaderc: Cleanup Texture name assumption in textures --- src/bgfx_compute.sh | 299 ++++++++++++++------------------ src/bgfx_p.h | 6 + src/renderer_d3d11.cpp | 6 + src/renderer_d3d12.cpp | 6 + src/renderer_d3d9.cpp | 6 + src/renderer_gl.cpp | 6 + src/renderer_mtl.mm | 6 + src/renderer_vk.cpp | 7 + src/renderer_webgpu.cpp | 14 +- src/shader.cpp | 14 +- src/shader.h | 2 + tools/shaderc/shaderc.cpp | 2 +- tools/shaderc/shaderc.h | 1 + tools/shaderc/shaderc_glsl.cpp | 1 + tools/shaderc/shaderc_hlsl.cpp | 1 + tools/shaderc/shaderc_metal.cpp | 29 ++-- tools/shaderc/shaderc_spirv.cpp | 187 ++++++++++++-------- 17 files changed, 336 insertions(+), 257 deletions(-) diff --git a/src/bgfx_compute.sh b/src/bgfx_compute.sh index 556972ebd..d05b23280 100644 --- a/src/bgfx_compute.sh +++ b/src/bgfx_compute.sh @@ -15,9 +15,11 @@ #endif // BGFX_SHADER_LANGUAGE_HLSL #if BGFX_SHADER_LANGUAGE_METAL || BGFX_SHADER_LANGUAGE_SPIRV -# define ANNOTATION(_format) [[spv::format_ ## _format]] +# define FORMAT(_format) [[spv::format_ ## _format]] +# define WRITEONLY [[spv::nonreadable]] #else -# define ANNOTATION(_format) +# define FORMAT(_format) +# define WRITEONLY #endif // BGFX_SHADER_LANGUAGE_METAL || BGFX_SHADER_LANGUAGE_SPIRV #if BGFX_SHADER_LANGUAGE_GLSL @@ -74,65 +76,68 @@ #define SHARED groupshared -#define r32ui uint -#define rg32ui uint2 -#define rgba32ui uint4 -#define r32f float -#define r16f float -#define rg16f float2 -#define rgba16f float4 +#define COMP_r32ui uint +#define COMP_rg32ui uint2 +#define COMP_rgba32ui uint4 +#define COMP_r32f float +#define COMP_r16f float +#define COMP_rg16f float2 +#define COMP_rgba16f float4 #if BGFX_SHADER_LANGUAGE_HLSL -# define rgba8 unorm float4 -# define rg8 unorm float2 -# define r8 unorm float +# define COMP_rgba8 unorm float4 +# define COMP_rg8 unorm float2 +# define COMP_r8 unorm float #else -# define rgba8 float4 -# define rg8 float2 -# define r8 float +# define COMP_rgba8 float4 +# define COMP_rg8 float2 +# define COMP_r8 float #endif // BGFX_SHADER_LANGUAGE_HLSL -#define rgba32f float4 +#define COMP_rgba32f float4 -#define IMAGE2D_RO( _name, _format, _reg) \ - Texture2D<_format> _name ## Texture : REGISTER(t, _reg); \ - static BgfxROImage2D_ ## _format _name = { _name ## Texture } +#define IMAGE2D_RO( _name, _format, _reg) \ + FORMAT(_format) Texture2D _name : REGISTER(t, _reg); \ #define UIMAGE2D_RO(_name, _format, _reg) IMAGE2D_RO(_name, _format, _reg) -#define IMAGE2D_RW( _name, _format, _reg) \ - ANNOTATION(_format) RWTexture2D<_format> _name ## Texture : REGISTER(u, _reg); \ - static BgfxRWImage2D_ ## _format _name = { _name ## Texture } +#define IMAGE2D_WR( _name, _format, _reg) \ + WRITEONLY FORMAT(_format) RWTexture2D _name : REGISTER(u, _reg); \ + +#define UIMAGE2D_WR(_name, _format, _reg) IMAGE2D_WR(_name, _format, _reg) + +#define IMAGE2D_RW( _name, _format, _reg) \ + FORMAT(_format) RWTexture2D _name : REGISTER(u, _reg); \ -#define IMAGE2D_WR( _name, _format, _reg) IMAGE2D_RW(_name, _format, _reg) -#define UIMAGE2D_WR(_name, _format, _reg) IMAGE2D_RW(_name, _format, _reg) #define UIMAGE2D_RW(_name, _format, _reg) IMAGE2D_RW(_name, _format, _reg) -#define IMAGE2D_ARRAY_RO(_name, _format, _reg) \ - Texture2DArray<_format> _name ## Texture : REGISTER(t, _reg); \ - static BgfxROImage2DArray_ ## _format _name = { _name ## Texture } +#define IMAGE2D_ARRAY_RO(_name, _format, _reg) \ + FORMAT(_format) Texture2DArray _name : REGISTER(t, _reg); \ #define UIMAGE2D_ARRAY_RO(_name, _format, _reg) IMAGE2D_ARRAY_RO(_name, _format, _reg) -#define IMAGE2D_ARRAY_RW(_name, _format, _reg) \ - ANNOTATION(_format) RWTexture2DArray<_format> _name ## Texture : REGISTER(u, _reg); \ - static BgfxRWImage2DArray_ ## _format _name = { _name ## Texture } +#define IMAGE2D_ARRAY_WR( _name, _format, _reg) \ + WRITEONLY FORMAT(_format) RWTexture2DArray _name : REGISTER(u, _reg); \ + +#define UIMAGE2D_ARRAY_WR(_name, _format, _reg) IMAGE2D_ARRAY_WR(_name, _format, _reg) + +#define IMAGE2D_ARRAY_RW(_name, _format, _reg) \ + FORMAT(_format) RWTexture2DArray _name : REGISTER(u, _reg); \ #define UIMAGE2D_ARRAY_RW(_name, _format, _reg) IMAGE2D_ARRAY_RW(_name, _format, _reg) -#define IMAGE2D_ARRAY_WR( _name, _format, _reg) IMAGE2D_ARRAY_RW(_name, _format, _reg) -#define UIMAGE2D_ARRAY_WR(_name, _format, _reg) IMAGE2D_ARRAY_RW(_name, _format, _reg) -#define IMAGE3D_RO( _name, _format, _reg) \ - Texture3D<_format> _name ## Texture : REGISTER(t, _reg); \ - static BgfxROImage3D_ ## _format _name = { _name ## Texture } +#define IMAGE3D_RO( _name, _format, _reg) \ + FORMAT(_format) Texture3D _name : REGISTER(t, _reg); #define UIMAGE3D_RO(_name, _format, _reg) IMAGE3D_RO(_name, _format, _reg) -#define IMAGE3D_RW( _name, _format, _reg) \ - ANNOTATION(_format) RWTexture3D<_format> _name ## Texture : REGISTER(u, _reg); \ - static BgfxRWImage3D_ ## _format _name = { _name ## Texture } +#define IMAGE3D_WR( _name, _format, _reg) \ + WRITEONLY FORMAT(_format) RWTexture3D _name : REGISTER(u, _reg); + +#define UIMAGE3D_WR(_name, _format, _reg) IMAGE3D_RW(_name, _format, _reg) + +#define IMAGE3D_RW( _name, _format, _reg) \ + FORMAT(_format) RWTexture3D _name : REGISTER(u, _reg); \ #define UIMAGE3D_RW(_name, _format, _reg) IMAGE3D_RW(_name, _format, _reg) -#define IMAGE3D_WR( _name, _format, _reg) IMAGE3D_RW(_name, _format, _reg) -#define UIMAGE3D_WR(_name, _format, _reg) IMAGE3D_RW(_name, _format, _reg) #if BGFX_SHADER_LANGUAGE_METAL || BGFX_SHADER_LANGUAGE_SPIRV #define BUFFER_RO(_name, _struct, _reg) StructuredBuffer<_struct> _name : REGISTER(t, _reg) @@ -146,154 +151,118 @@ #define NUM_THREADS(_x, _y, _z) [numthreads(_x, _y, _z)] -#define __IMAGE_IMPL_S(_format, _storeComponents, _type, _loadComponents) \ +#define __IMAGE_IMPL_A(_format, _storeComponents, _type, _loadComponents) \ + _type imageLoad(Texture2D<_format> _image, ivec2 _uv) \ + { \ + return _image[_uv]._loadComponents; \ + } \ \ - struct BgfxROImage2D_ ## _format \ - { \ - Texture2D<_format> m_texture; \ - }; \ + ivec2 imageSize(Texture2D<_format> _image) \ + { \ + uvec2 result; \ + _image.GetDimensions(result.x, result.y); \ + return ivec2(result); \ + } \ \ - struct BgfxRWImage2D_ ## _format \ - { \ - ANNOTATION(_format) RWTexture2D<_format> m_texture; \ - }; \ + _type imageLoad(RWTexture2D<_format> _image, ivec2 _uv) \ + { \ + return _image[_uv]._loadComponents; \ + } \ \ - struct BgfxROImage2DArray_ ## _format \ - { \ - Texture2DArray<_format> m_texture; \ - }; \ + void imageStore(RWTexture2D<_format> _image, ivec2 _uv, _type _value) \ + { \ + _image[_uv] = _value._storeComponents; \ + } \ \ - struct BgfxRWImage2DArray_ ## _format \ - { \ - ANNOTATION(_format) RWTexture2DArray<_format> m_texture; \ - }; \ + ivec2 imageSize(RWTexture2D<_format> _image) \ + { \ + uvec2 result; \ + _image.GetDimensions(result.x, result.y); \ + return ivec2(result); \ + } \ \ - struct BgfxROImage3D_ ## _format \ - { \ - Texture3D<_format> m_texture; \ - }; \ + _type imageLoad(Texture2DArray<_format> _image, ivec3 _uvw) \ + { \ + return _image[_uvw]._loadComponents; \ + } \ \ - struct BgfxRWImage3D_ ## _format \ - { \ - ANNOTATION(_format) RWTexture3D<_format> m_texture; \ - }; \ - -#define __IMAGE_IMPL_A(_format, _storeComponents, _type, _loadComponents) \ - __IMAGE_IMPL_S(_format, _storeComponents, _type, _loadComponents) \ + ivec3 imageSize(Texture2DArray<_format> _image) \ + { \ + uvec3 result; \ + _image.GetDimensions(result.x, result.y, result.z); \ + return ivec3(result); \ + } \ \ - _type imageLoad(BgfxROImage2D_ ## _format _image, ivec2 _uv) \ - { \ - return _image.m_texture[_uv]._loadComponents; \ - } \ + _type imageLoad(RWTexture2DArray<_format> _image, ivec3 _uvw) \ + { \ + return _image[_uvw]._loadComponents; \ + } \ \ - ivec2 imageSize(BgfxROImage2D_ ## _format _image) \ - { \ - uvec2 result; \ - _image.m_texture.GetDimensions(result.x, result.y); \ - return ivec2(result); \ - } \ + void imageStore(RWTexture2DArray<_format> _image, ivec3 _uvw, _type _value) \ + { \ + _image[_uvw] = _value._storeComponents; \ + } \ \ - _type imageLoad(BgfxRWImage2D_ ## _format _image, ivec2 _uv) \ - { \ - return _image.m_texture[_uv]._loadComponents; \ - } \ + ivec3 imageSize(RWTexture2DArray<_format> _image) \ + { \ + uvec3 result; \ + _image.GetDimensions(result.x, result.y, result.z); \ + return ivec3(result); \ + } \ \ - ivec2 imageSize(BgfxRWImage2D_ ## _format _image) \ - { \ - uvec2 result; \ - _image.m_texture.GetDimensions(result.x, result.y); \ - return ivec2(result); \ - } \ + _type imageLoad(Texture3D<_format> _image, ivec3 _uvw) \ + { \ + return _image[_uvw]._loadComponents; \ + } \ \ - void imageStore(BgfxRWImage2D_ ## _format _image, ivec2 _uv, _type _value) \ - { \ - _image.m_texture[_uv] = _value._storeComponents; \ - } \ + ivec3 imageSize(Texture3D<_format> _image) \ + { \ + uvec3 result; \ + _image.GetDimensions(result.x, result.y, result.z); \ + return ivec3(result); \ + } \ \ - _type imageLoad(BgfxROImage2DArray_ ## _format _image, ivec3 _uvw) \ - { \ - return _image.m_texture[_uvw]._loadComponents; \ - } \ + _type imageLoad(RWTexture3D<_format> _image, ivec3 _uvw) \ + { \ + return _image[_uvw]._loadComponents; \ + } \ \ - ivec3 imageSize(BgfxROImage2DArray_ ## _format _image) \ - { \ - uvec3 result; \ - _image.m_texture.GetDimensions(result.x, result.y, result.z); \ - return ivec3(result); \ - } \ + void imageStore(RWTexture3D<_format> _image, ivec3 _uvw, _type _value) \ + { \ + _image[_uvw] = _value._storeComponents; \ + } \ \ - _type imageLoad(BgfxRWImage2DArray_ ## _format _image, ivec3 _uvw) \ - { \ - return _image.m_texture[_uvw]._loadComponents; \ - } \ - \ - void imageStore(BgfxRWImage2DArray_ ## _format _image, ivec3 _uvw, _type _value) \ - { \ - _image.m_texture[_uvw] = _value._storeComponents; \ - } \ - \ - ivec3 imageSize(BgfxRWImage2DArray_ ## _format _image) \ - { \ - uvec3 result; \ - _image.m_texture.GetDimensions(result.x, result.y, result.z); \ - return ivec3(result); \ - } \ - \ - _type imageLoad(BgfxROImage3D_ ## _format _image, ivec3 _uvw) \ - { \ - return _image.m_texture[_uvw]._loadComponents; \ - } \ - \ - ivec3 imageSize(BgfxROImage3D_ ## _format _image) \ - { \ - uvec3 result; \ - _image.m_texture.GetDimensions(result.x, result.y, result.z); \ - return ivec3(result); \ - } \ - \ - _type imageLoad(BgfxRWImage3D_ ## _format _image, ivec3 _uvw) \ - { \ - return _image.m_texture[_uvw]._loadComponents; \ - } \ - \ - ivec3 imageSize(BgfxRWImage3D_ ## _format _image) \ - { \ - uvec3 result; \ - _image.m_texture.GetDimensions(result.x, result.y, result.z); \ - return ivec3(result); \ - } \ - \ - void imageStore(BgfxRWImage3D_ ## _format _image, ivec3 _uvw, _type _value) \ - { \ - _image.m_texture[_uvw] = _value._storeComponents; \ + ivec3 imageSize(RWTexture3D<_format> _image) \ + { \ + uvec3 result; \ + _image.GetDimensions(result.x, result.y, result.z); \ + return ivec3(result); \ } #define __IMAGE_IMPL_ATOMIC(_format, _storeComponents, _type, _loadComponents) \ \ - void imageAtomicAdd(BgfxRWImage2D_ ## _format _image, ivec2 _uv, _type _value) \ + void imageAtomicAdd(RWTexture2D<_format> _image, ivec2 _uv, _type _value) \ { \ - InterlockedAdd(_image.m_texture[_uv], _value._storeComponents); \ + InterlockedAdd(_image[_uv], _value._storeComponents); \ } \ -__IMAGE_IMPL_A(rgba8, xyzw, vec4, xyzw) -__IMAGE_IMPL_A(rg8, xy, vec4, xyyy) -__IMAGE_IMPL_A(r8, x, vec4, xxxx) -__IMAGE_IMPL_A(rg16f, xy, vec4, xyyy) -#if BGFX_SHADER_LANGUAGE_HLSL -__IMAGE_IMPL_S(rgba16f, xyzw, vec4, xyzw) -__IMAGE_IMPL_S(r16f, x, vec4, xxxx) -#else -__IMAGE_IMPL_A(rgba16f, xyzw, vec4, xyzw) -__IMAGE_IMPL_A(r16f, x, vec4, xxxx) -#endif // BGFX_SHADER_LANGUAGE_HLSL -__IMAGE_IMPL_A(r32f, x, vec4, xxxx) -__IMAGE_IMPL_A(rgba32f, xyzw, vec4, xyzw) -__IMAGE_IMPL_A(r32ui, x, uvec4, xxxx) -__IMAGE_IMPL_A(rg32ui, xy, uvec4, xyyy) -__IMAGE_IMPL_A(rgba32ui, xyzw, uvec4, xyzw) +__IMAGE_IMPL_A(float, x, vec4, xxxx) +__IMAGE_IMPL_A(float2, xy, vec4, xyyy) +__IMAGE_IMPL_A(float4, xyzw, vec4, xyzw) + +__IMAGE_IMPL_A(uint, x, uvec4, xxxx) +__IMAGE_IMPL_A(uint2, xy, uvec4, xyyy) +__IMAGE_IMPL_A(uint4, xyzw, uvec4, xyzw) + +#if BGFX_SHADER_LANGUAGE_HLSL +__IMAGE_IMPL_A(unorm float, x, vec4, xxxx) +__IMAGE_IMPL_A(unorm float2, xy, vec4, xyyy) +__IMAGE_IMPL_A(unorm float4, xyzw, vec4, xyzw) +#endif + +__IMAGE_IMPL_ATOMIC(uint, x, uvec4, xxxx) -__IMAGE_IMPL_ATOMIC(r32ui, x, uvec4, xxxx) #define atomicAdd(_mem, _data) InterlockedAdd(_mem, _data) #define atomicAnd(_mem, _data) InterlockedAnd(_mem, _data) diff --git a/src/bgfx_p.h b/src/bgfx_p.h index 5012d2c97..b25ce8117 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -4040,6 +4040,12 @@ namespace bgfx bx::read(&reader, texInfo); } + if (!isShaderVerLess(magic, 10) ) + { + uint16_t texFormat = 0; + bx::read(&reader, texFormat); + } + PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name); if (PredefinedUniform::Count == predefined && UniformType::End != UniformType::Enum(type) ) { diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index ea000c8ba..4cceecd03 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -4139,6 +4139,12 @@ namespace bgfx { namespace d3d11 bx::read(&reader, texInfo); } + if (!isShaderVerLess(magic, 10) ) + { + uint16_t texFormat = 0; + bx::read(&reader, texFormat); + } + const char* kind = "invalid"; PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name); diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index dae3f7f6d..622b98bbe 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -4554,6 +4554,12 @@ namespace bgfx { namespace d3d12 bx::read(&reader, texInfo); } + if (!isShaderVerLess(magic, 10) ) + { + uint16_t texFormat = 0; + bx::read(&reader, texFormat); + } + const char* kind = "invalid"; PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name); diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index d9bb68b4b..588b7d8dd 100644 --- a/src/renderer_d3d9.cpp +++ b/src/renderer_d3d9.cpp @@ -2454,6 +2454,12 @@ namespace bgfx { namespace d3d9 bx::read(&reader, texInfo); } + if (!isShaderVerLess(magic, 10) ) + { + uint16_t texFormat = 0; + bx::read(&reader, texFormat); + } + const char* kind = "invalid"; PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name); diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 716feba61..0ad2459c0 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -5924,6 +5924,12 @@ namespace bgfx { namespace gl uint16_t texInfo = 0; bx::read(&reader, texInfo); } + + if (!isShaderVerLess(magic, 10) ) + { + uint16_t texFormat = 0; + bx::read(&reader, texFormat); + } } uint32_t shaderSize; diff --git a/src/renderer_mtl.mm b/src/renderer_mtl.mm index cedeb596d..7636385ce 100644 --- a/src/renderer_mtl.mm +++ b/src/renderer_mtl.mm @@ -2488,6 +2488,12 @@ namespace bgfx { namespace mtl uint16_t texInfo = 0; bx::read(&reader, texInfo); } + + if (!isShaderVerLess(magic, 10) ) + { + uint16_t texFormat = 0; + bx::read(&reader, texFormat); + } } if (isShaderType(magic, 'C')) diff --git a/src/renderer_vk.cpp b/src/renderer_vk.cpp index dcc72720c..9b6c3ad72 100644 --- a/src/renderer_vk.cpp +++ b/src/renderer_vk.cpp @@ -4413,14 +4413,21 @@ VK_DESTROY bx::read(&reader, regCount); const bool hasTexData = !isShaderVerLess(magic, 8); + const bool hasTexFormat = !isShaderVerLess(magic, 10); uint8_t texComponent = 0; uint8_t texDimension = 0; + uint16_t texFormat = 0; if (hasTexData) { bx::read(&reader, texComponent); bx::read(&reader, texDimension); } + if (hasTexFormat) + { + bx::read(&reader, texFormat); + } + const char* kind = "invalid"; BX_UNUSED(num); diff --git a/src/renderer_webgpu.cpp b/src/renderer_webgpu.cpp index 485b7b9d2..994cf8c8b 100644 --- a/src/renderer_webgpu.cpp +++ b/src/renderer_webgpu.cpp @@ -1379,6 +1379,13 @@ namespace bgfx { namespace webgpu wgpu::BindGroupEntry& entry = b.m_entries[b.numEntries++]; entry.binding = bindInfo.m_binding; entry.textureView = texture.getTextureMipLevel(bind.m_mip); + + if (Access::Read == bind.m_access) + { + wgpu::BindGroupEntry& samplerEntry = b.m_entries[b.numEntries++]; + samplerEntry.binding = bindInfo.m_binding + 16; + samplerEntry.sampler = texture.m_sampler; + } } break; @@ -2515,7 +2522,7 @@ namespace bgfx { namespace webgpu const bool fragment = isShaderType(magic, 'F'); uint8_t fragmentBit = fragment ? kUniformFragmentBit : 0; - BX_ASSERT(!isShaderVerLess(magic, 7), "WebGPU backend supports only shader binary version >= 7"); + BX_ASSERT(!isShaderVerLess(magic, 10), "WebGPU backend supports only shader binary version >= 10"); if (0 < count) { @@ -2546,6 +2553,9 @@ namespace bgfx { namespace webgpu uint8_t texDimension; bx::read(&reader, texDimension); + uint16_t texFormat = 0; + bx::read(&reader, texFormat); + const char* kind = "invalid"; PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name); @@ -2584,6 +2594,8 @@ namespace bgfx { namespace webgpu m_buffers[m_numBuffers].storageTexture.access = readonly ? wgpu::StorageTextureAccess::ReadOnly : wgpu::StorageTextureAccess::WriteOnly; + + m_buffers[m_numBuffers].storageTexture.format = s_textureFormat[texFormat].m_fmt; } m_numBuffers++; diff --git a/src/shader.cpp b/src/shader.cpp index 3ae98a4ab..8f7473749 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -53,9 +53,11 @@ namespace bgfx static TextureComponentTypeToId s_textureComponentTypeToId[] = { // see comment in s_descriptorTypeToId - { TextureComponentType::Float, 0x00 }, - { TextureComponentType::Int, 0x01 }, - { TextureComponentType::Uint, 0x02 }, + { TextureComponentType::Float, 0x00 }, + { TextureComponentType::Int, 0x01 }, + { TextureComponentType::Uint, 0x02 }, + { TextureComponentType::Depth, 0x03 }, + { TextureComponentType::UnfilterableFloat, 0x04 }, }; BX_STATIC_ASSERT(BX_COUNTOF(s_textureComponentTypeToId) == TextureComponentType::Count); @@ -229,6 +231,12 @@ namespace bgfx uint16_t texInfo; bx::read(_reader, texInfo, _err); } + + if (!isShaderVerLess(magic, 10) ) + { + uint16_t texFormat = 0; + bx::read(_reader, texFormat, _err); + } } uint32_t shaderSize; diff --git a/src/shader.h b/src/shader.h index 6f082d4aa..c79339c81 100644 --- a/src/shader.h +++ b/src/shader.h @@ -31,6 +31,8 @@ namespace bgfx Float, Int, Uint, + Depth, + UnfilterableFloat, Count }; diff --git a/tools/shaderc/shaderc.cpp b/tools/shaderc/shaderc.cpp index 895678273..c99fac48b 100644 --- a/tools/shaderc/shaderc.cpp +++ b/tools/shaderc/shaderc.cpp @@ -13,7 +13,7 @@ extern "C" #include } // extern "C" -#define BGFX_SHADER_BIN_VERSION 9 +#define BGFX_SHADER_BIN_VERSION 10 #define BGFX_CHUNK_MAGIC_CSH BX_MAKEFOURCC('C', 'S', 'H', BGFX_SHADER_BIN_VERSION) #define BGFX_CHUNK_MAGIC_FSH BX_MAKEFOURCC('F', 'S', 'H', BGFX_SHADER_BIN_VERSION) #define BGFX_CHUNK_MAGIC_VSH BX_MAKEFOURCC('V', 'S', 'H', BGFX_SHADER_BIN_VERSION) diff --git a/tools/shaderc/shaderc.h b/tools/shaderc/shaderc.h index 3e5d6cbfb..789128005 100644 --- a/tools/shaderc/shaderc.h +++ b/tools/shaderc/shaderc.h @@ -101,6 +101,7 @@ namespace bgfx uint16_t regCount; uint8_t texComponent; uint8_t texDimension; + uint16_t texFormat; }; struct Options diff --git a/tools/shaderc/shaderc_glsl.cpp b/tools/shaderc/shaderc_glsl.cpp index cf0a444a9..ea27f2345 100644 --- a/tools/shaderc/shaderc_glsl.cpp +++ b/tools/shaderc/shaderc_glsl.cpp @@ -346,6 +346,7 @@ namespace bgfx { namespace glsl bx::write(_writer, un.regCount); bx::write(_writer, un.texComponent); bx::write(_writer, un.texDimension); + bx::write(_writer, un.texFormat); BX_TRACE("%s, %s, %d, %d, %d" , un.name.c_str() diff --git a/tools/shaderc/shaderc_hlsl.cpp b/tools/shaderc/shaderc_hlsl.cpp index 9e13acec9..3edf14dba 100644 --- a/tools/shaderc/shaderc_hlsl.cpp +++ b/tools/shaderc/shaderc_hlsl.cpp @@ -747,6 +747,7 @@ namespace bgfx { namespace hlsl bx::write(_writer, un.regCount); bx::write(_writer, un.texComponent); bx::write(_writer, un.texDimension); + bx::write(_writer, un.texFormat); BX_TRACE("%s, %s, %d, %d, %d" , un.name.c_str() diff --git a/tools/shaderc/shaderc_metal.cpp b/tools/shaderc/shaderc_metal.cpp index d4c8765bc..f180edab0 100644 --- a/tools/shaderc/shaderc_metal.cpp +++ b/tools/shaderc/shaderc_metal.cpp @@ -607,6 +607,7 @@ namespace bgfx { namespace metal bx::write(_writer, un.regCount); bx::write(_writer, un.texComponent); bx::write(_writer, un.texDimension); + bx::write(_writer, un.texFormat); BX_TRACE("%s, %s, %d, %d, %d" , un.name.c_str() @@ -890,20 +891,20 @@ namespace bgfx { namespace metal for (auto &resource : resourcesrefl.separate_images) { std::string name = refl.get_name(resource.id); - if (name.size() > 7 && 0 == bx::strCmp(name.c_str() + name.length() - 7, "Texture") ) + if (name.size() > 7 && 0 == bx::strCmp(name.c_str() + name.length() - 7, "Texture")) { - auto uniform_name = name.substr(0, name.length() - 7); - - Uniform un; - un.name = uniform_name; - un.type = UniformType::Sampler; - - un.num = 0; // needed? - un.regIndex = 0; // needed? - un.regCount = 0; // needed? - - uniforms.push_back(un); + name = name.substr(0, name.length() - 7); } + + Uniform un; + un.name = name; + un.type = UniformType::Sampler; + + un.num = 0; // needed? + un.regIndex = 0; // needed? + un.regCount = 0; // needed? + + uniforms.push_back(un); } uint16_t size = writeUniformArray( _writer, uniforms, _options.shaderType == 'f'); @@ -979,10 +980,6 @@ namespace bgfx { namespace metal for (auto &resource : resources.storage_images) { std::string name = msl.get_name(resource.id); - if (name.size() > 7 && 0 == bx::strCmp(name.c_str() + name.length() - 7, "Texture") ) - { - msl.set_name(resource.id, name.substr(0, name.length() - 7) ); - } unsigned set = msl.get_decoration( resource.id, spv::DecorationDescriptorSet ); unsigned binding = msl.get_decoration( resource.id, spv::DecorationBinding ); diff --git a/tools/shaderc/shaderc_spirv.cpp b/tools/shaderc/shaderc_spirv.cpp index 8ba9bde9a..03dce482a 100644 --- a/tools/shaderc/shaderc_spirv.cpp +++ b/tools/shaderc/shaderc_spirv.cpp @@ -180,9 +180,12 @@ namespace bgfx { namespace spirv return true; } - bgfx::TextureComponentType::Enum SpirvCrossBaseTypeToFormatType(spirv_cross::SPIRType::BaseType _type) + bgfx::TextureComponentType::Enum SpirvCrossBaseTypeToFormatType(spirv_cross::SPIRType::BaseType spirvBaseType, bool depth) { - switch (_type) + if (depth) + return bgfx::TextureComponentType::Depth; + + switch (spirvBaseType) { case spirv_cross::SPIRType::Float: return bgfx::TextureComponentType::Float; @@ -219,6 +222,52 @@ namespace bgfx { namespace spirv } } + static bgfx::TextureFormat::Enum s_textureFormats[] = + { + bgfx::TextureFormat::Unknown, // spv::ImageFormatUnknown = 0 + bgfx::TextureFormat::RGBA32F, // spv::ImageFormatRgba32f = 1 + bgfx::TextureFormat::RGBA16F, // spv::ImageFormatRgba16f = 2 + bgfx::TextureFormat::R32F, // spv::ImageFormatR32f = 3 + bgfx::TextureFormat::RGBA8, // spv::ImageFormatRgba8 = 4 + bgfx::TextureFormat::RGBA8S, // spv::ImageFormatRgba8Snorm = 5 + bgfx::TextureFormat::RG32F, // spv::ImageFormatRg32f = 6 + bgfx::TextureFormat::RG16F, // spv::ImageFormatRg16f = 7 + bgfx::TextureFormat::RG11B10F, // spv::ImageFormatR11fG11fB10f = 8 + bgfx::TextureFormat::R16F, // spv::ImageFormatR16f = 9 + bgfx::TextureFormat::RGBA16, // spv::ImageFormatRgba16 = 10 + bgfx::TextureFormat::RGB10A2, // spv::ImageFormatRgb10A2 = 11 + bgfx::TextureFormat::RG16, // spv::ImageFormatRg16 = 12 + bgfx::TextureFormat::RG8, // spv::ImageFormatRg8 = 13 + bgfx::TextureFormat::R16, // spv::ImageFormatR16 = 14 + bgfx::TextureFormat::R8, // spv::ImageFormatR8 = 15 + bgfx::TextureFormat::RGBA16S, // spv::ImageFormatRgba16Snorm = 16 + bgfx::TextureFormat::RG16S, // spv::ImageFormatRg16Snorm = 17 + bgfx::TextureFormat::RG8S, // spv::ImageFormatRg8Snorm = 18 + bgfx::TextureFormat::R16S, // spv::ImageFormatR16Snorm = 19 + bgfx::TextureFormat::R8S, // spv::ImageFormatR8Snorm = 20 + bgfx::TextureFormat::RGBA32I, // spv::ImageFormatRgba32i = 21 + bgfx::TextureFormat::RGBA16I, // spv::ImageFormatRgba16i = 22 + bgfx::TextureFormat::RGBA8I, // spv::ImageFormatRgba8i = 23 + bgfx::TextureFormat::R32I, // spv::ImageFormatR32i = 24 + bgfx::TextureFormat::RG32I, // spv::ImageFormatRg32i = 25 + bgfx::TextureFormat::RG16I, // spv::ImageFormatRg16i = 26 + bgfx::TextureFormat::RG8I, // spv::ImageFormatRg8i = 27 + bgfx::TextureFormat::R16I, // spv::ImageFormatR16i = 28 + bgfx::TextureFormat::R8I, // spv::ImageFormatR8i = 29 + bgfx::TextureFormat::RGBA32U, // spv::ImageFormatRgba32ui = 30 + bgfx::TextureFormat::RGBA16U, // spv::ImageFormatRgba16ui = 31 + bgfx::TextureFormat::RGBA8U, // spv::ImageFormatRgba8ui = 32 + bgfx::TextureFormat::R32U, // spv::ImageFormatR32ui = 33 + bgfx::TextureFormat::Unknown, // spv::ImageFormatRgb10a2ui = 34 + bgfx::TextureFormat::RG32U, // spv::ImageFormatRg32ui = 35 + bgfx::TextureFormat::RG16U, // spv::ImageFormatRg16ui = 36 + bgfx::TextureFormat::RG8U, // spv::ImageFormatRg8ui = 37 + bgfx::TextureFormat::R16U, // spv::ImageFormatR16ui = 38 + bgfx::TextureFormat::R8U, // spv::ImageFormatR8ui = 39 + bgfx::TextureFormat::Unknown, // spv::ImageFormatR64ui = 40 + bgfx::TextureFormat::Unknown, // spv::ImageFormatR64i = 41 + }; + struct SpvReflection { struct TypeId @@ -668,6 +717,7 @@ namespace bgfx { namespace spirv bx::write(_writer, un.regCount); bx::write(_writer, un.texComponent); bx::write(_writer, un.texDimension); + bx::write(_writer, un.texFormat); BX_TRACE("%s, %s, %d, %d, %d" , un.name.c_str() @@ -979,8 +1029,7 @@ namespace bgfx { namespace spirv break; default: - un.type = UniformType::End; - break; + continue; } uniforms.push_back(un); @@ -1050,41 +1099,44 @@ namespace bgfx { namespace spirv for (auto &resource : resourcesrefl.separate_images) { std::string name = refl.get_name(resource.id); + if (name.size() > 7 && 0 == bx::strCmp(name.c_str() + name.length() - 7, "Texture") ) { - std::string uniform_name = name.substr(0, name.length() - 7); - uint32_t binding_index = refl.get_decoration(resource.id, spv::Decoration::DecorationBinding); - - auto imageType = refl.get_type(resource.base_type_id).image; - auto componentType = refl.get_type(imageType.type).basetype; - - bool isCompareSampler = false; - for (auto& sampler : resourcesrefl.separate_samplers) - { - if (binding_index + 16 == refl.get_decoration(sampler.id, spv::Decoration::DecorationBinding) ) - { - std::string samplerName = refl.get_name(sampler.id); - isCompareSampler = refl.variable_is_depth_or_compare(sampler.id) || samplerName.find("Comparison") != std::string::npos; - break; - } - } - - Uniform un; - un.name = uniform_name; - un.type = UniformType::Enum(UniformType::Sampler - | kUniformSamplerBit - | (isCompareSampler ? kUniformCompareBit : 0) - ); - - un.texComponent = textureComponentTypeToId(SpirvCrossBaseTypeToFormatType(componentType) ); - un.texDimension = textureDimensionToId(SpirvDimToTextureViewDimension(imageType.dim, imageType.arrayed) ); - - un.regIndex = binding_index; - un.regCount = 0; // unused - - uniforms.push_back(un); + name = name.substr(0, name.length() - 7); } + + uint32_t binding_index = refl.get_decoration(resource.id, spv::Decoration::DecorationBinding); + + auto imageType = refl.get_type(resource.base_type_id).image; + auto componentType = refl.get_type(imageType.type).basetype; + + bool isCompareSampler = false; + for (auto& sampler : resourcesrefl.separate_samplers) + { + if (binding_index + 16 == refl.get_decoration(sampler.id, spv::Decoration::DecorationBinding) ) + { + std::string samplerName = refl.get_name(sampler.id); + isCompareSampler = refl.variable_is_depth_or_compare(sampler.id) || samplerName.find("Comparison") != std::string::npos; + break; + } + } + + Uniform un; + un.name = name; + un.type = UniformType::Enum(UniformType::Sampler + | kUniformSamplerBit + | (isCompareSampler ? kUniformCompareBit : 0) + ); + + un.texComponent = textureComponentTypeToId(SpirvCrossBaseTypeToFormatType(componentType, imageType.depth) ); + un.texDimension = textureDimensionToId(SpirvDimToTextureViewDimension(imageType.dim, imageType.arrayed) ); + un.texFormat = uint16_t(s_textureFormats[imageType.format]); + + un.regIndex = binding_index; + un.regCount = 0; // unused + + uniforms.push_back(un); } // Loop through the storage_images, and extract the uniform names: @@ -1092,56 +1144,49 @@ namespace bgfx { namespace spirv { std::string name = refl.get_name(resource.id); - if (name.size() > 7 - && 0 == bx::strCmp(name.c_str() + name.length() - 7, "Texture") ) - { - std::string uniform_name = name.substr(0, name.length() - 7); - uint32_t binding_index = refl.get_decoration(resource.id, spv::Decoration::DecorationBinding); + uint32_t binding_index = refl.get_decoration(resource.id, spv::Decoration::DecorationBinding); - auto imageType = refl.get_type(resource.base_type_id).image; - auto componentType = refl.get_type(imageType.type).basetype; + auto imageType = refl.get_type(resource.base_type_id).image; + auto componentType = refl.get_type(imageType.type).basetype; - spirv_cross::Bitset flags = refl.get_buffer_block_flags(resource.id); - UniformType::Enum type = flags.get(spv::DecorationNonWritable) - ? UniformType::Enum(kUniformReadOnlyBit | UniformType::End) - : UniformType::End; + spirv_cross::Bitset flags = refl.get_decoration_bitset(resource.id); + UniformType::Enum type = flags.get(spv::DecorationNonWritable) + ? UniformType::Enum(kUniformReadOnlyBit | UniformType::End) + : UniformType::End; - Uniform un; - un.name = uniform_name; - un.type = type; + Uniform un; + un.name = name; + un.type = type; - un.texComponent = textureComponentTypeToId(SpirvCrossBaseTypeToFormatType(componentType) ); - un.texDimension = textureDimensionToId(SpirvDimToTextureViewDimension(imageType.dim, imageType.arrayed) ); + un.texComponent = textureComponentTypeToId(SpirvCrossBaseTypeToFormatType(componentType, imageType.depth) ); + un.texDimension = textureDimensionToId(SpirvDimToTextureViewDimension(imageType.dim, imageType.arrayed) ); + un.texFormat = uint16_t(s_textureFormats[imageType.format]); - un.regIndex = binding_index; - un.regCount = descriptorTypeToId(DescriptorType::StorageImage); + un.regIndex = binding_index; + un.regCount = descriptorTypeToId(DescriptorType::StorageImage); - uniforms.push_back(un); - } + uniforms.push_back(un); } // Loop through the storage buffer, and extract the uniform names: for (auto& resource : resourcesrefl.storage_buffers) { std::string name = refl.get_name(resource.id); + uint32_t binding_index = refl.get_decoration(resource.id, spv::Decoration::DecorationBinding); - for (auto& uniform : uniforms) - { - if (!bx::strFind(uniform.name.c_str(), name.c_str() ).isEmpty() ) - { - spirv_cross::Bitset flags = refl.get_buffer_block_flags(resource.id); - UniformType::Enum type = flags.get(spv::DecorationNonWritable) - ? UniformType::Enum(kUniformReadOnlyBit | UniformType::End) - : UniformType::End; + spirv_cross::Bitset flags = refl.get_buffer_block_flags(resource.id); + UniformType::Enum type = flags.get(spv::DecorationNonWritable) + ? UniformType::Enum(kUniformReadOnlyBit | UniformType::End) + : UniformType::End; - uint32_t binding_index = refl.get_decoration(resource.id, spv::Decoration::DecorationBinding); - uniform.name = name; - uniform.type = type; - uniform.regIndex = binding_index; - uniform.regCount = descriptorTypeToId(DescriptorType::StorageBuffer); - break; - } - } + Uniform un; + un.name = name; + un.type = type; + un.num = 0; + un.regIndex = binding_index; + un.regCount = descriptorTypeToId(DescriptorType::StorageBuffer); + + uniforms.push_back(un); } uint16_t size = writeUniformArray( _writer, uniforms, _options.shaderType == 'f');