- From: Kai Ninomiya <kainino@google.com>
- Date: Tue, 27 Nov 2018 15:03:47 -0800
- To: "Myles C. Maxfield" <mmaxfield@apple.com>
- Cc: public-gpu <public-gpu@w3.org>
- Message-ID: <CANxMeyCFkEHM1VjoaQgTpgw-NC3NpWOjUJkGWHyU4P7R=3E1KA@mail.gmail.com>
Hey Myles, thanks for this report! Great to see things laid out. > Many files in the corpus use HLSL’s syntax for sampler literals, but those aren’t supported in SPIR-V, so I think we can safely ignore those. I don’t know what the SPIR-V Cross guys are doing about that. Just to clarify, by SPIR-V Cross did you mean DXC <https://github.com/Microsoft/DirectXShaderCompiler/blob/master/docs/SPIR-V.rst#samplers>? SPIRV-Cross doesn't compile HLSL to SPIR-V, it compiles SPIR-V to HLSL. On Tue, Nov 27, 2018 at 2:30 PM Myles C. Maxfield <mmaxfield@apple.com> wrote: > Over the past few days, I’ve collected a large corpus of HLSL files so we > can determine what we need to do to be source-compatible with existing HLSL > source. > > *The Corpus* > > I wrote a GitHub crawler which looked for repositories that had many HLSL > files in them. I looked over the results of this crawler and hand-picked a > few repositories that are from respectable sources. In total, we ended up > with 2099 HLSL files. > > The list of repositories: > > - Microsoft/DirectX-Graphics-Samples > - vvvv/vvvv-sdk > - Of limited use, because most of the source is written in another > language (Effects) which includes HLSL snippets. GitHub classifies this as > HLSL. > - Unity-Technologies/ScriptableRenderPipeline > - Of limited use, because most of the source is written in another > language (Shaderlab) which includes HLSL snippets. GitHub classifies this > as HLSL. > - Microsoft/Windows-universal-samples > - OGRECave/ogre > - EpicGames/UnrealEngine > - Of limited use, because most of the source is written in another > language (Unreal Shader Format) which includes HLSL snippets. GitHub > classifies this as HLSL. > - ConfettiFX/The-Forge > - AtomicGameEngine/AtomicGameEngine > - NVIDIAGameWorks/D3DSamples > - EpicGames/UnrealTournament > - Of limited use, because most of the source is written in another > language (Unreal Shader Format) which includes HLSL snippets. GitHub > classifies this as HLSL. > - urho3d/Urho3D > - NVIDIAGameWorks/HairWorks > - NVIDIAGameWorks/WaveWorks > - Of limited use, because most of the source is written in another > language (Effects) which includes HLSL snippets. GitHub classifies this as > HLSL. > - NVIDIAGameWorks/FleX > - Unity-Technologies/PostProcessing > - Of limited use, because most of the source is written in another > language (Shaderlab) which includes HLSL snippets. GitHub classifies this > as HLSL. > - NVIDIAGameWorks/Falcor > - NVIDIAGameWorks/FaceWorks > - NVIDIAGameWorks/HBAOPlus > - GPUOpen-LibrariesAndSDKs/GPUParticles11 > - NVIDIAGameWorks/VolumetricLighting > - GPUOpen-Effects/ShadowFX > - GPUOpen-LibrariesAndSDKs/LiquidVR > - NVIDIAGameWorks/NvCloth > - GPUOpen-Effects/DepthOfFieldFX > - NVIDIAGameWorks/PhysX-3.4 > - GPUOpen-Effects/GeometryFX > - GPUOpen-LibrariesAndSDKs/TiledLighting11 > - NVIDIAGameWorks/Flow > - GPUOpen-LibrariesAndSDKs/ForwardPlus11 > - Microsoft/Win2D > - GPUOpen-LibrariesAndSDKs/SSAA11 > - Microsoft/Win2D-Samples > - PixarAnimationStudios/OpenSubdiv > > We could potentially figure out how to compile Effects, Shaderlab and > Unreal Shader Format to HLSL (because that’s what their engines do). If we > did this, we could grow the repository by 13% + 8% + 15% (respectively) = > 36%. I didn’t want to get bogged down doing this, though. > > *Preprocessor* > > HLSL Source files make heavy use of the preprocessor. Each file includes > an average of 9.61 uses of the preprocessor (lines that begin with “#”) and > the preprocessor is used on average every 11.68 lines. > > > As you can see above, most of the users of the preprocessor are not to > include files, but are instead to enable / disable features. Therefore, > this is a situation where compatibility with existing HLSL source is > directly in conflict with simplicity of the language. > > I proceeded by running the corpus through the Microsoft HLSL preprocessor, > and investigated the preprocessed files. My analysis is just based on the > parsing stage of the language, not name resolution or type checking. > Out-of-the-box, we parse 5.9% of the corpus. > > *Language Features* > > From investigating the source, I found some language features that HLSL > depends on. > > In MSL, if you want to pass some data to your shader, you make a struct, > and pass a reference to that struct as an argument of the main function. > Then, in the main function, you reference the data by saying > theReference.field. This approach is possible in HLSL, but there’s another > more common way to do it. Instead of making a struct, you make a “cbuffer” > which lists a set of fields, but those fields are treated as global > variables. The cbuffer is given a “semantic” so the API can attach memory > to back the cbuffer. > > cbuffer Camera : register(b0) // The API assigns memory to this block by > using the “b0” handle > { > float4x4 viewProjection; > float4x4 projectionInv; > float3 viewPos; > }; > > Output main() { > output.foo = viewProjection; // viewProjection, projectionInv, and > viewPos are in the global scope. > return output; > } > > About 1/3 of the files in the corpus use cbuffers. > > HLSL has two flavors of global variables: > > 1. Resources, like RWTexture2D<float2> dstTexture : register(u0);. > These work just like entry point parameters, except they are in the global > scope and therefore can be accessed from any function, without passing > around a pointer to them. > 2. Literal data, like static const float convolutionWeights[] = {1, 2, > 3};. > > > About 1/5 of the files in the corpus use global variables. > > HLSL supports default arguments in function parameters and cbuffers, so > you can say void foo(int x = 3);. I would imagine specifying this would > be tricky because we have to mention which variables and functions the > initial value can refer to. > > Many files in the corpus use HLSL’s syntax for sampler literals, but those > aren’t supported in SPIR-V, so I think we can safely ignore those. I don’t > know what the SPIR-V Cross guys are doing about that. > > *New Syntax* > > There are lots of changes to the syntax of the language that shouldn’t > have much of an effect on the language itself, but are required if we want > to claim compatibility with lots of HLSL sources. > > > - Removing the entry point keywords (vertex, fragment, compute) is a > requirement for any shader to compile. Instead, we should require that > compilation of a WHLSL file state which function names are the entry points. > - It appears that HLSL allows any arbitrary semantic for stage in/out > parameters. Around 30% of the corpus uses a semantic that WHLSL doesn’t > currently accept. > - Some functions in the HLSL standard library use > member-function-syntax, like texture.Sample(sampler, location) instead > of Sample(texture, sampler, location). > - There are a whole collection of variable modifiers that HLSL sources > use that WHLSL doesn’t accept. E.g. row_major float4x4 mvpMatrix; > - HLSL has a few function modifiers like [ RootSignature(…stuff goes > here…) ] void foo(…) { … } that are irrelevant for WebGPU. This > includes information about the D3D root signature, but also things like how > geometry shaders and tessellation work, which WebGPU doesn’t have. > - HLSL arrays put the brackets after the variable name, like float > myArray[40]; > - Arrays and structs can be initialized using brackets, like float > myArray[3] = { 1.0, 2.0, 3.0 }; > - HLSL has some hints about how the compiler should treat branches and > loops. They look like [ unroll ] for (…) and [ branch ] if ( …). I > don’t think these have semantic meaning so we can probably just swallow > them. > - HLSL uses C-style casts instead of C++-style casts. So, we need to > support (float)x instead of float(x). > - HLSL accepts float literals with exponents, like 1e-3. > - Functions can be forward-declared in HLSL. > > > After doing all that, we get up to around 90% compatibility with parsing > (not resolving names nor type checking) the HLSL corpus. The biggest wins > are member-function syntax, allowing every semantic name, C-style casting, > and C-style array syntax. > > —Myles >
Attachments
- image/jpeg attachment: Screen_Shot_2018-11-13_at_1.03.53_PM.jpeg
- image/jpeg attachment: 02-Screen_Shot_2018-11-13_at_1.03.53_PM.jpeg
- application/pkcs7-signature attachment: S/MIME Cryptographic Signature
Received on Tuesday, 27 November 2018 23:04:25 UTC