summaryrefslogtreecommitdiffstats
path: root/source/slang-glslang/slang-glslang.cpp
Commit message (Collapse)AuthorAge
* Use glslang public API (#8369)Jeremy Hayes2025-10-01
| | | | | Stop including private header (see #8333). Co-authored-by: Yong He <yonghe@outlook.com>
* Rewriting the lower-buffer-element-type pass to avoid unnecessary ↵Yong He2025-09-30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | packing/unpacking. (#8526) Part of the effort to improve the performance of generated SPIRV code. The existing lower-buffer-element-type pass works by loading the entire buffer element content from memory, and translate it to logical type stored in a local variable at the earliest reference of a buffer handle. This means that is can generate inefficient code that reads more than necessary. Consider this example: ``` struct BigStruct { bool values[1024]; } ConstantBuffer<BigStruct> cb; void test(BigStruct v) { if (v.values[0]) { printf("ok"); } } [numthreads(1,1,1)] void computeMain() { test(cb); } ``` In IR, the `computeMain` function before lower-buffer-element-type pass is something like following: ``` func test: %v = param : BigStruct %barr = fieldExtract(%v, "values") %element = elementExtract(%barr, 0) ... // uses %element func computeMain: %v = load(cb) call %test %v ``` The existing lower-buffer-element-type pass will rewrite the bool array in `BigStruct` into `int` array so it is legal in SPIRV. However, it does so by inserting the translation on the first `load` of the constant buffer: ``` struct BigStruct_std430 { int values[1024]; } var cb : ConstantBuffer<BigStruct_std430>; func computeMain: %tmpVar : var<BigStruct> call %unpackStorage(%tmpVar, cb) %v : BigStruct = load %tmpVar call %test %v ``` This means that the entire array will be loaded and translated to int, before calling `test`, which only uses one element. It turns out that the downstream compiler isn't always able to optimize out this inefficient translation/copy. This PR completely rewrites the way buffer-element-type lowering is handled to avoid producing this inefficient code. It works in two parts: first we turn on the `transformParamsToConstRef` pass for SPIRV target as well, so we will translate the `test` function to take the `v` parameter as `constref`. The second part is a redesigned buffer-element-type pass that defers the storage-type to logical-type translation until a value is actually used by a `load` instruction. In this example, after `transformParamsToConstRef`, the IR is: ``` func test: %v = param : ConstRef<BigStruct> %barr = fieldAddr(%v, "values") %elementPtr = elementAddr(%barr, 0) %element = load(%elementPtr) ... // uses %element func computeMain: call %test %cb ``` The new `buffer-element-type-lowering` pass will take this IR, and insert translation at latest possible time across the entire call graph, and translate the IR into: ``` func test: %v = param : ConstRef<BigStruct_std430> %barr = fieldAddr(%v, "values") %elementPtr : ptr<int> = elementAddr(%barr, 0) %element_int = load(%elementPtr) %element = cast(%element_int) : %bool ... // uses %element func computeMain: call %test %cb ``` In this new IR, there is no longer a load and conversion of the entire array. See new comment in `slang-ir-lower-buffer-element-type.cpp` for more details of how the pass works. This PR also address many other issues surfaced by turning on `transformParamsToConstRef` pass on SPIRV backend. --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Fix spurious vk::binding warnings when attribute is present (#7581)Copilot2025-07-02
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Initial plan * Fix spurious vk::binding warnings when attribute is present - Modified _maybeDiagnoseMissingVulkanLayoutModifier to check for GLSLBindingAttribute before warning - Changed function to return bool indicating if warning was actually issued - Updated call sites to properly track warning state to reduce duplicates - Tested fix resolves the issue while preserving correct warnings when needed Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> * Add test case for vk::binding spurious warning fix Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> * Update test to use filecheck format as requested Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> * Remove full file path from CHECK directives as requested Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> * Fix code formatting with clang-format Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> * Fix behavioral regression in vk-bindings test caused by warning flag logic Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> Co-authored-by: Yong He <yonghe@outlook.com>
* Update spirv-tools to for SDK v2025.2 (#6893)Gangzheng Tong2025-04-25
| | | | | | | | | | | | | | | | | | | | * Update spirv-tools to for SDK v2025.2 Fixes: #6850 * bump spirv version to 1.4 for op linkage * skip-spirv-validation for coop mat * add skip-spirv-validation option to slang session desc * use SPV_ENV_UNIVERSAL_1_6 for spirv-tool env target Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> --------- Co-authored-by: slangbot <ellieh+slangbot@nvidia.com> Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* IR: Add SPIR-V disassembly for embedded downstream IR dumps (#6529)Mukund Keshava2025-03-11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | * IR: Add SPIR-V disassembly for embedded downstream IR dumps When dumping IR that contains embedded downstream SPIR-V code (via EmbeddedDownstreamIR instructions), display the disassembled SPIR-V instead of just showing "<binary blob>". This CL also does: - Adds a new interface for disassembly and get result. - Modify export-library-generics.slang test test to check for the disassembled SPIR-V Fixes #6513 * Add module-dual-target-verify test Fixes #6517 Adds a new test to verify that dxil and spirv targets are stored separately in the precompiled blob. * Fix review comments from cheneym2 * format code --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* UseHighestVersion when calling spirv-link (#6559)cheneym22025-03-10
| | | | | | | | | | Precompiled SPIR-V bits can independently resolve to different versions of SPIR-V. To avoid a linker error about mismatched versions, use a linker feature to automatically use the highest version listed in the modules. Fixes #6548
* Support SPIR-V deferred linking option (#6500)cheneym22025-03-05
| | | | | | | | | | | | | | | | | | | | | | | The new option "SkipDownstreamLinking" will defer final downstream IR linking to the user application. This option only has an effect if there are modules that were precompiled to the target IR using precompileForTarget(). Until now, the default behavior for SPIR-V was to use deferred linking, and the default behavior for DXIL was to use immediate/internal linking in Slang. This change only affects the SPIR-V behavior such that both deferred and non-deferred linking is supported based on the new option. To support the non-deferred option, Slang will internally call into SPIRV-Tools-link to reconstitute a complete SPIR-V shader program when necessary (due to modules having been precompiled to target IR). Otherwise, if SkipDownstreamLinking is enabled, the shader returned by e.g. getTargetCode() or getEntryPointCode() may have import linkage to the SPIR-V embedded in the constituent modules. Closes #4994 Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Fix precompiledTargetModule tests (#6455)cheneym22025-02-26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Fix precompiledTargetModule tests Add SPIRV-Tool linker support to gfx unit tests and use the linker in precompileModule tests that use precompiled modules to reconstitute SPIRV shaders that were modularly compiled. Fix a Slang reference count bug in the precompile service. * Use sm_6_6 New DXC requires higher version for linkability. * Rename helper function, pass by reference * Link through slang-glslang * Add missing files * Fix metal * format code --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> Co-authored-by: Yong He <yonghe@outlook.com>
* Enable friendly-name option for SPIRV dump and validation (#6465)Jay Kwak2025-02-26
|
* Use disassemble API from SPIRV-Tools (#6001)Jay Kwak2025-01-07
| | | | | | | | | | | | | | | | | | | | | | | | | | * Use disassemble API from SPIRV-Tools This commit uses C API version of SPIRV disassemble function rather than calling spirv-dis.exe. This allows us to use a correct version of SPIRV disassble function that Slangc.exe is using. The implementation is mostly copied from external/spirv-tools/tools/dis/dis.cpp, which is a source file for building spirv-dis.exe. This commit also includes a fix for a bug in RPC communication to `test-server`. When an RPC connection to `test-server.exe` is reused and the second test abruptly fails due to a compile error or SPIRV validation error, the output from the first test run was incorrectly reused as the output for the second test. This commit resets the RPC result before waiting for the response so that even when the RPC connection is erratically disconnected, the result from the previous run will not be reused incorrectly. Some of the tests appear to be relying on this type of behavior. By using an option, `-skip-spirv-validation`, the RPC connection will continue without an interruption.
* Bump spirv-header/tools/glslang (#5834)Ellie Hermaszewska2024-12-12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Back out "Update SPIRV submodules (#5815)" This backs out commit e50aac13e2c161d672b137a62f6d66820d0f9ff1. * Use upstream spirv-tools * Fix bump-glslang.sh for newer versions of spirv-tools * Use upstream glslang * Add --do-fetch option to bump glslang * Bump glslang and friends Supersedes https://github.com/shader-slang/slang/pull/5815 * Regenerate glslang and spirv-tools outputs * Fixes to slang-glslang * Correct spirv intrinsic for OpImageSampleFootprintNV Note that this currently fails validation with the following error: ``` error: line 145: Result <id> from OpSampledImage instruction must not appear as operand for OpImageSampleFootprintNV, since it is not specified as taking an OpTypeSampledImage. Found result <id> '55[%sampledImage]' as an operand of <id> '56[%resultVal]'. %sampledImage = OpSampledImage %54 %51 %40 ``` This seems to be in error as the spec for *SPV_NV_shader_image_footprint* states that "Sampled Image must be an object whose type is OpTypeSampledImage" https://refined-github-html-preview.kidonng.workers.dev/KhronosGroup/SPIRV-Registry/raw/refs/heads/main/extensions/NV/SPV_NV_shader_image_footprint.html glslang also seems to fail with the same validation error * Fix spv storage class test
* Move switch statement bodies to their own lines (#5493)Ellie Hermaszewska2024-11-05
| | | | | | | | | * Move switch statement bodies to their own lines * format --------- Co-authored-by: Yong He <yonghe@outlook.com>
* formatEllie Hermaszewska2024-10-29
| | | | | | | * format * Minor test fixes * enable checking cpp format in ci
* Remove includes of glslang private headers (#5059)arcady-lunarg2024-09-15
|
* Print SPIRV validation error message (#4697)Jay Kwak2024-07-23
| | | | | | | Closes #4692 This is a quick fix for the issue that SPIR-V validation error message is not printed. A more proper way is to return the error messages to the application and let the application handle it.
* Use slang-glslang.dll for spirv-validation (#4642)Jay Kwak2024-07-17
| | | | | | | | | * Use slang-glslang.dll for spirv-validation This change replaces the use of "spirv-val.exe" with an API call to "spvtools::SpirvTools::Validate()". Closes #4610
* Move the file public header files to `include` dir (#4636)kaizhangNV2024-07-17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Move the file public header files to `include` dir Close the issue (#4635). Move the following headers files to a `include` dir located at root dir of slang repo: slang-com-helper.h -> include/slang-com-helper.h slang-com-ptr.h -> include/slang-com-ptr.h slang-gfx.h -> include/slang-gfx.h slang.h -> include/slang.h Change cmake/SlangTarget.cmake to add include path to every target, and change the source file to use "#include <slang.h>" to include the public headers. The source code update is by the script like follow: ``` fileNames_slang=$(grep -r "\".*slang\.h\"" source/ -l) for fileName in "${fileNames_slang[@]}" do echo "$fileName" sed -i "s/\".*slang\.h\"/\"slang\.h\"/" $fileName done ``` * Fix the test issues * Fix cpu test issues by adding include seach path * Update cmake to not add include path for every target Also change "#include <slang.h>" to "include "slang.h" " to make the coding style consistent with other slang code. * Change public include to private include for unit-test and slang-glslang
* Fix the build when you try to build slang-glslang (#3599)Jay Kwak2024-02-17
|
* Update prebuilt glslang binaries. (#3267)Yong He2023-10-09
| | | | | | | | | * Update prebuilt glslang binaries. * Update spirv-disassembling logic in slang-glslang. --------- Co-authored-by: Yong He <yhe@nvidia.com>
* Run curated spirv-opt passes through slang-glslang. (#3266)Yong He2023-10-09
| | | | | | | | | | | | | * Run curated spirv-opt passes through slang-glslang. * Cleanup. * Replace spirv-dis downstream compiler with glslang. * delete slang-spirv-opt.cpp. --------- Co-authored-by: Yong He <yhe@nvidia.com>
* Support per field matrix layout (#3101)Yong He2023-08-14
| | | | | | | | | | | | | | | | | | | | | | | | | | | * Support per field matrix layout * Fix warnings. * Fix. * Fix tests. * Fix spiv gen. * Fix. * More test fixes. * Fix. * Run only GPU tests on self-hosted servers. * Remove -use-glsl-matrix-layout-modifier. * Fix. --------- Co-authored-by: Yong He <yhe@nvidia.com>
* Make sure glsl source in spirv is included when compiling with -g3 (#3099)Yong He2023-08-11
| | | | | | | | | | | * Make sure glsl source in spirv is included when compiling with -g3. * Exclude vulkan tests on github linux CI. * Fix. --------- Co-authored-by: Yong He <yhe@nvidia.com>
* Fix -fvk-use-entrypoint-name. (#3066)Yong He2023-08-07
| | | | | | | | | * Fix -fvk-use-entrypoint-name. * Remove irrelevant changes. --------- Co-authored-by: Yong He <yhe@nvidia.com>
* Add option to use original entrypoint in spirv output. (#3047)Yong He2023-08-04
| | | | | | | | | * Add option to use original entrypoint in spirv output. * Fix. --------- Co-authored-by: Yong He <yhe@nvidia.com>
* Include NonSemanticDebugInfo when calling glslang (#3030)Yong He2023-07-27
| | | Co-authored-by: Yong He <yhe@nvidia.com>
* Some small fixes with Windows/DX usage (#2797)Ellie Hermaszewska2023-04-14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Correct case of windows.h includes * Use Slang::SharedLibrary to load directx dlls * s/max/std::max/ * Factor common OS code in calcHasApi * Add DXIL test for compute/simple * s/false/FALSE for calls to WinAPI functions * Factor common OS code in gfxGetAdapters * 2 missing headers d3d12sdklayers for ID3DDebug climits for UINT_MAX * Define out unused function on Linux * Only try to load Vulkan and CUDA on Windows or Linux * simplify D3DUtil::getDxgiModule * Remove WIN32_LEAN_AND_MEAN &co from source files Add a global define * Set WIN32_LEAN_AND_MEAN &friends in headers Restore previous state also * regenerate vs projects
* Add mesh and amplification shaders to slang-glslang (#2516)Ellie Hermaszewska2022-11-15
|
* glslang: 11.10.0-16-g42398c93 -> 11.12.0-32-gf74f37c5 (#2507)Ellie Hermaszewska2022-11-14
|
* Upgrade to glslang 11.10.0+ (#2306)jsmall-nvidia2022-07-01
| | | | | | | * #include an absolute path didn't work - because paths were taken to always be relative. * Upgrade to glslang 11.10.0 Co-authored-by: Yong He <yonghe@outlook.com>
* Add SPIR-V debug information via GLSLANG (#2142)jsmall-nvidia2022-02-23
| | | | | | | | | * #include an absolute path didn't work - because paths were taken to always be relative. * Switch on generateDebugInfo on glslang i s any debug level is set. * Take copy of SpvOptions. Co-authored-by: Theresa Foley <10618364+tangent-vector@users.noreply.github.com>
* SPIR-V fixes (#1992)jsmall-nvidia2021-10-27
| | | | | | | | | | | | | | | | | | * #include an absolute path didn't work - because paths were taken to always be relative. * Use updated slang-binaries that have SPIR-V diagnostics improvements. * Re-enable nv-ray-tracing-motion-blur, because with SPIR-V diagnostic fixes in glslang - there shouldn't be spurious errors from glslang compilation. * If optimization fails use the SPIR-V we have. * Update SPIR-V headers and generated files. Updated documentation. * Update spirv-headers/tools. Revert slang-binaries. * Remove hack around spir-v optimization as no longer needed. disable nv-ray-tracing-motion-blur.slang
* SPIR-V optimization diagnostics (#1989)jsmall-nvidia2021-10-26
| | | | | | | | | | | | | | | | | | | | | | | * #include an absolute path didn't work - because paths were taken to always be relative. * WIP fixing glslang error reporting. * SPIR-V opt diagnostics. * Small formatting tidy up. * Disable nv-ray-tracing-motion-blur.slang for now, until merged and can rebuild slang-glslang. * Formatting improvements. * Some small improvements around optimizing in glslang. * Make clear if calling optimize with 'non' in glslang no work is done (such as a pointless copy). * Small formatting change - mainly to kick off a build. * Upgrade slang-binaries to fix git fetch issue on TC. * Small formatting edits. Kick build.
* Improving glslang -O1 passes (#1926)jsmall-nvidia2021-09-01
| | | | | | | * #include an absolute path didn't work - because paths were taken to always be relative. * Improve passes used for -O1 option with glslang. * Set sourceManager when serializing container.
* Improvements around glslang optimization (#1916)jsmall-nvidia2021-07-29
| | | | | | | | | | | * #include an absolute path didn't work - because paths were taken to always be relative. * Improvements to how glslang optimizations are handled. Increasing the amount of ids to allow for optimizing more complex shaders, and compacting to try and keep ids within range for usage. * Add other optimizations from current glslang. * Improved -O1/default GLSLANG passes improves output SPIR-V size (Can be more that 1/3 of the size), for a modest increase in compilation time. * Improve comments.
* Update glslang to 11.1.0 (#1662)Tim Foley2021-01-20
| | | | | | | | | * Update glslang to 11.1.0 This change pulls new versions of glslang, spirv-headers, and spirv-tools as submodules, and makes the necessary changes to other files in the repository to get it all building (at least on Windows). This change also enables building of glslang from source by default, so that we can easily generate new binaries for inclusion in the `slang-binaries` repository. * fixup: missing file
* Removed use of pthreads in glslang (#1517)jsmall-nvidia2020-08-27
| | | | | | | * Try removing pthreads from glslang. * Update slang-binaries to use glslang that doesn't use pthreads. Co-authored-by: Tim Foley <tfoleyNV@users.noreply.github.com>
* Bugfix: WaveActiveCountBits on glsl output. (#1488)jsmall-nvidia2020-08-11
| | | | | | | | | | * Fix WaveActiveCountBits on glsl output. * Fix warning `could not be inlined because the return instruction is not at the end of the function. This could be fixed by running merge-return before inlining.` from glslang - because we weren't including the CreateMergeReturnPasss on default optimization, and it's assumed in InlineExhaustivePass. * Keep WaveActiveCountBits use the default WaveMask impl. * Fix WaveCountBits calculation. Use WaveActiveBallot instead of the _WaveActiveBallot.
* Glslang texel offset bug fix (#1485)jsmall-nvidia2020-08-10
| | | | | * Fix the minProgramTexelOffset should be -. * Improve comments.
* Upgrade to Glslang 11.0.0 (#1466)jsmall-nvidia2020-07-31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Fix premake5.lua so it uses the new path needed for OpenCLDebugInfo100.h * Keep including the includes directory. * Added the spirv-tools-generated files. * We don't need to include the spirv/unified1 path because the files needed are actually in the spirv-tools-generated folder. * Put the build_info.h glslang generated files in external/glslang-generated. Alter premake5.lua to pick up that header. * First pass at documenting how to build glslang and spirv-tools. * Improved glsl/spir-v tools README.md * Added revision.h * Change how gResources is calculated. Update about revision.h * Update docs a little. * Split out spirv-tools into a separate project for building glslang. This was not necessary on linux, but *is* necessary on windows, because there is a file disassemble.cpp in spirv-tools and in glslang, and this leads to VS choosing only one. With the separate library, the problem is resolved. * Fix direct-spirv-emit output. * Update to latest version of spirv headers and spirv-tools. * Upgrade submodule version of glslang in external. * Add fPIC to build options of slang-spirv-tools * Upgrade slang-binaries to have new glslang. * Fix issues with Windows slang-glslang binaries, via update of slang-binaries used. * Small improvements to glslang building process documentation. Co-authored-by: Tim Foley <tfoleyNV@users.noreply.github.com>
* Safer binary compatibilty betwee 1.0 and 1.1 versions, without using struct ↵jsmall-nvidia2020-03-05
| | | | embedding. (#1257)
* Feature/glslang spirv version (#1256)jsmall-nvidia2020-03-05
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * WIP add support for __spirv_version . * Added IRRequireSPIRVVersionDecoration * SPIR-V version passed to glslang. Enable VK wave tests. Split ExtensionTracker out, so can be cast and used externally to emit. Added SourceResult. * Fix warning on Clang. * Missing hlsl.meta.h * Refactor communication/parsing of __spirv_version with glslang. * Fix some debug typos. Be more precise in handling of substring handling. * Make glslang forwards and backwards binary compatible. * Small comment improvements. * Added slang-spirv-target-info.h/cpp * Fix for major/minor on gcc. * Another fix for gcc/clang. * VS projects include slang-spirv-target-info.h/cpp * Removed SPIRVTargetInfo Added SemanticVersion. Don't bother with passing a target to glslang. Should be separate from 'version'. * Renamed slang-emit-glsl-extension-tracker.cpp/.h -> slang-glsl-extension-tracker.cpp/.h Fixed some VS project issues. * Fix a comment. * Added slang-semantic-version.cpp/.h * Added slang-glsl-extension-tracker.cpp/.h * Added split that can check for input has all been parsed. * Fix problem on x86 win build.
* Enable spriv-opt on spirv (#1076)Robert Stepinski2019-10-17
| | | | | | | | | | | | | | | | | | | * Add spirv-tools module and set ENABLE_OPT to be true * Add spirv-headers dependency * Build spirv-opt into glslang project * Add optimization pass * Add generated spirv-opt files Modify solution to avoid obj file conflicts * Add optimization pass to SPIR-V generation * Don't pass additional optimizer options to glslang * Build spirv-opt in Linux
* Allow multiple threads to call glslang (#1046)jsmall-nvidia2019-09-04
| | | | | | | | | | | * Allow multiple threads to be able to call into glslang by * Having a single call to glslang::InitializeProcess() per process (in our case dll load) * Explicitly call glslang::InitThread * Fix problem with case in path for linux. * Rename s_processInitializer to g_processInitializer. Move into the function.
* Add callable shader support for Vulkan ray tracing (#718)Tim Foley2018-11-12
| | | | | | | | | | | | | | | | | | * Add callable shader support for Vulkan ray tracing This change extends the previous work to update Vulkan ray tracing support for the finished `GL_NV_ray_tracing` spec. One of the features missing in the experimental extension that was added to the final spec is "callable shaders," which allow ray tracing shaders to call other shaders as general-purpose subroutines. Most of the implementation work here mirrors what was done for the `TraceRay()` function to map it to `traceNV()`. We map the generic `CallShader<P>` function to the non-generic `executeCallableNV`, with a payload identifier that indicates a specific global variable of type `P` (the global variable being generated from a `static` local in `CallShader`). A new modifier is added to identify the payload structure, and the parameter binding/layout logic introduces a new resource kind for callable-shader payload data (where previously the logic had assumed ray and callable payloads should use the same resource kind). Two test shaders are included: one for the callable shader (`callable.slang`) and one for a ray generation shader that calls it (`callable-caller.slang`). Just for kicks, the payload data type is defined in a shared file so that we can be sure the two agree (trying to emulate what might be good practice, and ensure that ray tracing support works together with other Slang mechanisms). * Typo fix: assocaited->associated One instance was found in review, but I went ahead and fixed a bunch since I seem to make this typo a lot. * Typo fix: defintiion->definition
* Support cross-compilation of ray tracing shaders to Vulkan (#663)Tim Foley2018-10-04
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Move to newer glslang * Support cross-compilation of ray tracing shaders to Vulkan This change allows HLSL shaders authored for DirectX Raytracing (DXR) to be cross-compiled to run with the experimental `GL_NVX_raytracing` extension (aka "VKRay"). * The GLSL extension spec is marked as experimental, so that any shaders written using this support should be ready for breaking changes when the spec is finalized. * "Callable shaders" are not exposed throug the GLSL extension, so this feature of DXR will not be cross-compiled. * The experimental Vulkan raytracing extension does not have an equivalent to DXR's "local root signature" concept. This does not visibly impact shader translation (because the local/global root signature mapping is handled outside of the HLSL code), but in practice it means that applications which rely on local root signatures on their DXR path will not be able to use the translation in this change as-is; more work will be needed. The simplest part of the implementation was to go into the Slang standard library and start adding GLSL translations for the various DXR operations. In some cases, like mapping `IgnoreHit()` to `ignoreIntersectionNVX()` this is almost trivial. The various functions to query system-provided values (e.g., `RayTMin()`) were also easy, with the only gotcha being that they map to variables rather than function calls in GLSL, and our handling of `__target_intrinsic` assumes that a bare identifier represents a replacement function name, and not a full expression, so we have to wrap these definitions in parentheses. The tricky operations are then `TraceRay<P>()` and `ReportHit<A>()`, because these two are generics/templates in HLSL. GLSL doesn't support generics, even for "standard library" functions, so the raytracing extension implements a slightly complex workaround: the matching operations `traceNVX()` and `reportIntersectionNVX()` pass the payload/attributes argument data via a global variable. That is, shader code for the GLSL extensions writes to the global variable and then calls the intrinsic function. The linkage between the call site and the global is established by a modifier keyword (`rayPayloadNVX` and `hitAttributeNVX`, respectively) and in the case of ray payload also uses `location` number to identify which payload global to use (since a single shader can trace rays with multiple payload types). Our translation strategy in Slang tries to leverage standard language mechanisms instead of special-case logic. For example, to translate the `ReportHit<A>()` function, we provide both a default declaration that will work for HLSL (where the operation is built-in with the signature given), and a *definition* marked with the `__specialized_for_target(glsl)` modifier. The GLSL definition declares a function `static` variable that will fill the role of the required global, and then does what the GLSL spec requires: assigns to the global, and then calls the `reportIntersectionNVX` builtin (which we declare as a separate builtin). Our ordinary lowering process will turn that `static` variable into an ordinary global in the IR, and the `[__vulkanHitAttributes]` attribute on the variable will be emitted as `hitAttributeNVX` in the output. There is no additional cross-compilation logic in Slang specific to `ReportHit<A>()` - the target-specific definition in the standard library Just Works. The case for `TraceRay<P>()` is a bit more complicated, simply because the GLSL `traceNVX()` function needs to be passed the `location` for the payload global. We implement the payload global as a function-`static` variable, with the knowledge that every unique specialization of `TraceRay<P>()` will generate a unique global variable of type `P` to implement our function-`static` variable. We then add a slightly magical builtin function `__rayPayloadLocation()` that can map such a variable to its generated `location`; the logic for this is implemented in `emit.cpp` and described below. We also changed the `RayDesc` and `BuiltinTriangleIntersectionAttributes` types from "magic" intrinsic types over to ordinary types (because the GLSL output needs to declare them as ordinary `struct` types). This ends up removing some cases in the AST and IR type representations. By itself this change would break HLSL emit, because in that case the types really are intrinsic. We added a `__target_intrinsic` modifier to these types to make them intrinsic for HLSL, and then updated the downstream passes to handle the notion of target-intrinsic types. The logic for binding/layout of entry point inputs and outputs was updated so that raytracing stages don't follow the default logic for varying input/output parameters. This is because the input/output parameters of a raytracing entry point aren't really "varying" in the same sense as those in the rasterization pipeline. In particular, the SPIR-V model for raytracing input and output treats "ray payload" and "hit attributes" parameters as being in a distinct storage class from `in` or `out` parameters. We also detect cases where a ray tracing stage declares inputs/outputs that it shouldn't have. This logic could conceivably be extended to other stages (e.g., to give an error on a compute shader with user-defined varying input/output). The type layout logic added cases for handling raytracing payload and hit-attribute data, but this is currently just a stub implementation that follows the same logic as for varying `in` and `out` parameters (it cannot give meaningful byte sizes/offsets right now). To my knowledge the GLSL spec doesn't currently specify anything about layout, and I haven't read the DXR spec language carefully enough to know what it says about layout. A future change should update the layout logic to allow for byte-based layout of ray payloads, etc. so that we can query this information via reflection. The GLSL legalization logic in `ir.cpp` was updated to factor out the per-entry-point-parameter code into its own function, and then that function was updated to special-case the input/output of a ray-tracing shader. While for rasterization stages we typically want to take the user-declared input/output and "scalarize" it for use in GLSL (in part to deal with language limitations, and in part to tease system values apart from user-defined input/output), the GLSL spec for raytracing requires payload and hit attribute parameters to be declared as single variables. There is also the issue that even for an `in out` parameter, a ray payload parameter should only turn into a single global, whereas the handling for varying `in out` parameters generates both an `in` and an `out` global for the GLSL case. Other than the handling of entry point parameters, the GLSL legalization pass doesn't need to do anything special for ray tracing shaders. The trickiest change in the `emit.cpp` logic is that we now generate `location`s for ray payload arguments (the outgoing from a `TraceRay()` call) on demand during code generation. This is a bit hacky, and it would be nice to handle it as a separate pass on the IR rather than clutter up the emit logic, but this approach was expedient. Basically, any of the global variables that got generated from the `static` declarations in the standard library implementation of `TraceRay()` will trigger the logic to assign them a `location`. The logic for emitting intrinsic operations added a few new `$`-based escape sequences. The `$XP` case handles emitting the location of a generated ray payload variable; this is how we emit the matching location at the site where we call `traceNVX`. The `$XT` case emits the appropriate translation for `RayTCurrent()` in HLSL, because it maps to something different depending on the target stage. All of the test cases here consist of a pair of an HLSL/Slang shader written to the DXR spec, plus a matching GLSL shader for a baseline. The GLSL shaders are carefully designed so that when fed into glslang they will produce the same SPIR-V as our cross-compilation process. This kind of testing is quite fragile, but it seems to be the best we can do until our testing framework code supports *both* DXR and VKRay. A bunch of the core changes ended up being blocked on issues in the rest of the compiler, so some additional features go implemented or fixed along the way: The first big wall this work ran into was that the `__specialized_for_target` modifier hasn't actually been working correctly for a while. It turns out that for the one function that is using it, `saturate()`, we have been outputting the workaround GLSL function in *all* cases (including for HLSL output) rather than only on GLSL targets. The problem here is that for a generic function with a `__specialized_for_target` modifier or a `__target_intrinsic` modifier, the IR-level decoration will end up attached to the `IRFunc` instruction nested in the `IRGeneric`, but the logic for comparing IR declarations to see which is more specialized (via `getTargetSpecializationLevel()`) was looking only at decorations on the top-level value (the generic). The quick (hacky) fix here is to make `getTargetSpecializationLevel()` try to look at the return value of a generic rather than the generic itself, so that it can see the decorations that indicate target-specific functions. A more refined fix would be to attach target-specificity decorations to the outer-most generic (to simplify the "linking" logic). The only reason not to fold that into the current fix is that the `__target_intrinsic` modifier currently serves double-duty as a marker of target specialization *and* information to drive emit logic. The latter (the emit-related stuff) currently needs to live on the `IRFunc`, and moving it to the generic could easily break a lot of code. This needs more work in a follow-on fix, but for now target specialization should again be working. The other big gotcha that the simple "just use the standard library" strategy ran into was that function-`static` variables weren't actually implemented yet, and in particular function-`static` variables inside of generic functions required some careful coding. The logic in `lower-to-ir.cpp` has this `emitOuterGenerics()` function that is supposed to take a declaration that might be nested inside of zero or more levels of AST generics, and emit corresponding IR generics for all those levels. This is needed because two different AST functions nested inside a single generic `struct` declaration should turn into distinct `IRFunc`s nested in distinct `IRGeneric`s. The tricky bit to making that all work is that the same AST-level generic type parameter will then map to *different* IR-level instructions (the parameters of distinct `IRGeneric`s) when lowering each function. The existing logic handled this in an idiomatic way by making "sub-builders" and "sub-contexts." This change refactors some of the repeated logic into a `NestedContext` type to help simplify the pattern, and applies it consistently throughout the `lower-to-ir.cpp` file. Besides that cleanup, the major change is `lowerFunctionStaticVarDecl` which, unsurprisingly, handles lower of function-`static` variables to IR globals. The careful handling of nested contexts here is needed because if we are in the middle of lowering a generic function, then a `static` variable should turn into its *own* `IRGeneric` wrapping an `IRGlobalVar`. The body of the function should refer to the global variable by specializing the global variable's `IRGeneric` to the parameters of the *functions* `IRGeneric`. This tricky detail is handled by `defaultSpecializeOuterGenerics`. An additional subtlety not actually required for this raytracing work (and thus not properly tested right now) is handling function-`static` variables with initializers. These can't just be lowered to globals with initializers, because HLSL follows the C rule that function-`static` variables are initialized when the declaration statement is first executed (and this could be visible in the presence of side-effects). The lowering strategy here translates any `static` variable with an initializer into *two* globals: one for the actual storage, plus a second `bool` variable to track whether it has been initialized yet. There are some opportunities to optimize this case, especially for `static const` data, but that will need to wait for future changes. We've slowly been shifting away from the model where a user thinks of a "profile" as including both a stage and a feature level. Instead, the user should think about selecting a profile that only describes a feature level (e.g., `sm_6_1`, `glsl_450`, etc.), and then separately specifying a stage (`vertex`, `raygeneration, etc.) for each entry point. The challenge here is that the command-line processing still only had a single `-profile` switch, and no way to specify the stage. Adding the `-stage` option was relatively easy, but making it work with the existing validation logic for command-line arguments was tricky, because of the complex model that `slangc` supports for compiling multiple entry points in a single pass. * In `slang.h` add new reflection parameter categories for ray payloads and hit attributes, as part of entry point input/output signatures. * A previous change already updated our copy of glslang to one that supports the `GL_NVX_raytracing` extension, so in `slang-glslang.cpp` we just needed to map Slang's `enum` values for the raytracing stage names to their equivalents in the glslang code. * Moved the logic for looking up a stage by name (`findStageByName()`) out of `check.cpp` and into `compiler.cpp`, with a declaration in `profile.h` * Added a `$z` suffix to the GLSL translation of `Texture*.SampleLevel()`, to handle cases where the texture element type is not a 4-component vector. Note that this fix should actually be applied to *all* these texture-sampling operations, but I didn't want to add a bunch of changes that are (clearly) not being tested right now. * The layout logic for entry points was updated to correctly skip producing a `TypeLayout` for an entry point result of type `void`, which meant that the related emit logic now needs to guard against a null value for the result layout. * In `ir.cpp`, dump decorations on every instruction instead of just selected ones, so that our IR dump output is more complete. * Added a command-line `-line-directive-mode` option so that we can easily turn off `#line` directives in the output when debugging. Not all cases where plumbed through because the `none` case is realistically the most important. * Parser was fixed to properly initialize parent links for "scope" declarations used for statements, so that we can walk backwards from a function-scope variable (including a `static`) and see the outer function/generics/etc. * Added GLSL 460 profile, since it is required for ray tracing. Also updated the logic for computing the "effective" profile to use to recognize that GLSL raytracing stages require GLSL 460. * Added some conventional ray-tracing shader suffixes to the handling in `slang-test`. This code isn't actually used, but was relevant when I started by copy-pasting some existing VKRay shaders as the starting point for my testing. * Fixup: typos
* Remove the "hack sampler" workaround (#648)Tim Foley2018-09-21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Update glslang version * Fix build for new glslang The latest glslang required a few changes to our manual build for their code (because we are *not* taking a dependency on CMake). * Rebuild project files using premake, which picks up a few files added to glslang, but also a few diffs in Slang's own project files in cases where they were edited manually instead of using premake. * Fix up the declaration our our device limits (which are inentionally set to *not* limit what code passes through our glslang), because the underlying structure definition in glslang has changed. This is a kludgy bit of glslang's design, but it doesn't make sense for us to invest in a more serious workaround. * Remove the "hack sampler" workaround When the `GL_KHR_vulkan_glsl` spec was introduced to allow GLSL to be compiled for Vulkan SPIR-V, it made an annoying mistake by leaving a few builtins as taking `sampler2D`, etc. when the equivalent SPIR-V operations only require a `texture2D`, etc. The relevant builtins are: * `textureSize` * `textureQueryLevels` * `textureSamples` * `texelFetch` * `texelFetchOffset` This means that shader code that wanted to use those operations needed to conspire to have a `sampler` handy so they could write, e.g.: ```glsl vec4 val = texelFetch(sampler2D(myTexture, someRandomSampler), p, lod); ``` when what they really wanted was this: ```glsl vec4 val = texelFetch(myTexture, p, lod); ``` That is annoying but probably something each to work around for a GLSL programmer, but when cross-compiling from HLSL, you might have an operation like: ```hlsl float4 val = myTexure.Load(p); ``` in which case a cross-compiler needs to manufacture a sampler out of thin air. If the shader happened to use a sampler for something else you could snag that, but in the worse case you had to cross-compile to GLSL that declared a new sampler. Slang did this by declaring a sampler called `SLANG_hack_samplerForTexelFetch` (because `texelFetch` is the operation that first surfaced the issue). For complex reasons we *always* define this sampler, even if we turn out not to need it in a particular output kernel. This choice has a bunch of annoying consequences: * There is *always* a sampler defined in descriptor set zero, because that's where we put the hack sampler, so a user-defined parameter block always has a set number of 1 or greater (see #646). * The hack sampler shows up in reflection output because users need to size their descriptor sets appropriately to pass along this sampler that won't actually be used if they don't want to get debug spew from the validation layers. We filed an issue on glslang about this problem, and eventually some kind folks from the gamedev community (who also saw the same problem) defined an extension spec (`GL_EXT_samplerless_texture_functions`) to fix the underlying issue and contributed a patch to glslang to make it support that extension. This change just backs the hack out of Slang now that we have a glslang version that supports the extension to get past the defect in the original GLSL-for-Vulkan definition. Besides yanking out the code for the hack, we also change the relevant builtins to declare that they require this new GLSL extension (so that we properly request it from glslang when the builtins are used), and fix some reflection test cases that exposed the existence of the "hack sampler." * Fixup: syntax error in stdlib generator files * Remove more code for hack sampler There was logic to ensure we always have a "default" register space/set when cross-compiling, because the hack sampler would need it. This is no longer necessary once we remove the hack sampler. * Fix expected test output. Fixing the root cause of issue #646 means that one of our test cases that tickles that issue now produces different output (luckily it can now be used as a regression test for the issue).
* Get tests running/passing under Linux (#194)Tim Foley2017-09-29
| | | | | | | | | | | | | | | | | | | | | | | | | | * Get tests running/passing under Linux - Fix up `dlopen` abstraction - Fix up some test cases to request hlsl (rather than default to dxbc) so they can run on non-Windows targets - Fix up test runner ignore tests that can't run on current platform (and not count those as failure) - Fix file handle leeak in process spawner absttraction - Get additional test-related applications building - More tweaks to Travis script; in theory deployment is set up now (yeah, right) * fixup * fixup: Travis environment variable syntax * fixup: Buffer->begin * fixup: actually run full tests on one config * fixup: add build status badge for Travis
* First attempt at a Linux build (#193)Tim Foley2017-09-27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * First attempt at a Linux build - Fix up places where C++ idioms were written assuming lenient behavior of Microsoft's compiler - Add a few more alternatives for platform-specific behavior where Windows was the only platform accounted for. - Add a basic Makefile that can at least invoke our build, even if it isn't going good dependency tracking, etc. - Build `libslang.so` and `slangc` that depends on it, using a relative `RPATH` to make the binary portable (I hope) - Add an initial `.travis.yml` to see if we can trigger their build process. * Fixup: const bug in `List::Sort` I'm not clear why this gets picked up by the gcc *and* clang that Travis uses, but not the (newer) gcc I'm using on Ubuntu here, but I'm hoping it is just some missing `const` qualifiers. * Fixup: reorder specialization of "class info" Clang complains about things being specialized after being instantiated (implicilty), and I hope it is just the fact that I generate the class info for the roots of the hierarchy after the other cases. We'll see. * Fixup: add `platform.cpp` to unified/lumped build * Fixup: Windows uses `FreeLibrary` and not `UnloadLibrary` * Fixup: fix Windows project file to include new source file This obviously points to the fact that we are going to need to be generating these files sooner or later.
* Build a dynamic library for SlangTim Foley2017-07-19
- Change the `slang` project from a static library to a dynamic one - Add some details around `slang.h` to make sure DLL export stuff is working - Make the `slangc` executable use the dynamic library - Rename the `glslang` sub-project to `slang-glslang` and move it into the main source hierarchy - This reflects the fact that it isn't a stand-alone tool, and isn't in any way a standard binary of glslang, but rather just an artifact of how Slang uses glslang